docs: def match(self, subj=None, pred=None, obj=None, attrs=None):
          '''
          Retrieve an iterator of relationship IDs that match a pattern of components
  
          subj - optional subject or origin of the relationship, an IRI coded as a unicode object. If omitted any subject will be matched.
          pred - optional predicate or type of the relationship, an IRI coded as a unicode object. If omitted any predicate will be matched.
          obj - optional object of the relationship, a boolean, floating point or unicode object. If omitted any object will be matched.
          attrs - optional attribute mapping of relationship metadata, i.e. {attrname1: attrval1, attrname2: attrval2}. If any attribute is specified, an exact match is made (i.e. the attribute name and value must match).
  
          '''
          cur = self._conn.cursor()
          conditions = u""
          and_placeholder = u""
          tables = u"relationship"
          params = []
          if subj:
              conditions += u"relationship.subj = ?"
              params.append(subj)
              and_placeholder = u" AND "
          if obj:
              conditions += and_placeholder + u"relationship.obj = ?"
              params.append(obj)
              and_placeholder = u" AND "
          if pred:
              conditions += and_placeholder + u"relationship.pred = ?"
              params.append(pred)
              and_placeholder = u" AND "
          if attrs:
              tables = u"relationship, attribute"
              for a_name, a_val in attrs.iteritems():
                  conditions += and_placeholder + u"EXISTS (SELECT 1 from attribute AS subattr WHERE subattr.rawid = relationship.rawid AND subattr.name = ? AND subattr.value = ?)"
                  params.extend((a_name, a_val))
                  and_placeholder = u" AND "
          #querystr = u"SELECT relationship.rawid, relationship.subj, relationship.pred, relationship.obj, attribute.name, attribute.value FROM {0} WHERE {1} ORDER BY relationship.rawid;".format(tables, conditions)
          #SELECT relationship.rawid, attribute.rawid, relationship.subj, relationship.pred, relationship.obj, attribute.name, attribute.value FROM relationship FULL JOIN attribute ON relationship.rawid = attribute.rawid WHERE relationship.subj = 'http://uche.ogbuji.net' AND EXISTS (SELECT 1 from attribute AS subattr WHERE subattr.rawid = relationship.rawid AND subattr.name = '@context' AND subattr.value = 'http://uche.ogbuji.net#_metadata') AND EXISTS (SELECT 1 from attribute AS subattr WHERE subattr.rawid = relationship.rawid AND subattr.name = '@lang' AND subattr.value = 'ig') ORDER BY relationship.rawid;
          #querystr = u"SELECT relationship.rawid, relationship.subj, relationship.pred, relationship.obj, attribute.name, attribute.value FROM relationship FULL JOIN attribute ON relationship.rawid = attribute.rawid WHERE {1} ORDER BY relationship.rawid;".format(tables, conditions)
          #Need to simulate a FULL OUTER JOIN
          querystr = u"""\
  SELECT relationship.rawid, relationship.subj, relationship.pred, relationship.obj, attribute.name, attribute.value
  FROM relationship LEFT JOIN attribute ON relationship.rawid = attribute.rawid
  UNION ALL
  SELECT relationship.rawid, relationship.subj, relationship.pred, relationship.obj, attribute.name, attribute.value
  FROM relationship LEFT JOIN attribute ON relationship.rawid = attribute.rawid
  WHERE {1}
  ORDER BY relationship.rawid;""".format(tables, conditions)
          #self._logger.debug(x.format(url))
          self._logger.debug(repr((querystr, params)))
          cur.execute(querystr, params)
          #Use groupby to batch up the returning statements acording to rawid then rol up the attributes
          #return ( (s, p, o, dict([(n,v) for n,v in xxx])) for s, p, o in yyy)
          #cur.fetchone()
          #cur.close()
          return self._process_db_rows_iter(cur)