def delValue(self, key, value=None): if value is None: del self[key] else: self.attrs.table.deleteRows('ID_REF = ' + sqlise(self.nodeid) + ' AND ATTR = ' + sqlise(key) + ' AND VALUE = ' + sqlise(value))
def nodesByAttr(self, attr, value): nodeids = set( row['ID_REF'] for row in self.attrs.table.selectRows("ATTR = " + sqlise(attr) + " AND VALUE = " + sqlise(str(value)))) return self.nodesFromIds(nodeids)
def preloadForNodeids(self, nodeids=None): if self.__preloaded: return where = None if nodeids is not None: if len(nodeids) == 0: return where = "ID_REF IN (%s)" % ",".join(sqlise(id) for id in nodeids) NV = {} for row in self.table.selectRows(where): id = row.key nodeid = row['ID_REF'] if nodeid not in NV: nv = NV[nodeid] = {} else: nv = NV[nodeid] attr = row['ATTR'] v = (row['VALUE'], row['IS_IDREF']) if attr in nv: nv[attr].append(v) else: nv[attr] = [v] for nodeid in NV: self.store(AttrSet(self.__direct, nodeid, NV[nodeid]), nodeid)
def referringNodeids(self): ''' Returns a list of node ids which refer to this node. ''' return [row[0] for row in SQLQuery(self.digraph.attrs.table.conn, 'SELECT DISTINCT(ID_REF+0) FROM '+self.digraph.attrs.table.name \ +' WHERE IS_IDREF AND VALUE = '+sqlise(str(self.id)))]
def nodesLike(self, like, types=(), where=None): likewhere = "NAME LIKE " + sqlise(like) if len(types) > 0: likewhere = likewhere + " AND " + SQLtestType(*types) if where is not None: likewhere = likewhere + " AND (" + where + ")" return self.nodesWhere(likewhere)
def nodesByNameAndType(self, name, *types): if len(types) == 1: key = (name, types[0]) if key in self.__typeMap: return tuple(self.__typeMap[key]) return self.nodesWhere('NAME = ' + sqlise(name) + ' AND ' + SQLtestType(*types))
def values(self): if self.__values is None: A = {} for row in self.attrs.table.selectRows('ID_REF = ' + sqlise(self.nodeid)): key = row['ATTR'] value = (row['VALUE'], row['IS_IDREF']) if key in A: A[key].append(value) else: A[key] = [value] self.__values = A return self.__values
def detach(self): assert self.TYPE == 'EDGE', "not an EDGE: " + str(self) # detach upstream dosql( self.digraph.attrs.table.conn, "DELETE FROM " + self.digraph.attrs.table.name + " WHERE IS_IDREF AND ATTR = 'EDGES' AND VALUE = " + sqlise(self.id)) self.digraph.attrs.table.bump() if self.NAME is None: # anonymous edge - discard the whole thing self.delete() else: # just detach downstream del self['EDGES']
def __delitem__(self, key): del self.values()[key] self.attrs.table.deleteRows('ID_REF = ' + sqlise(self.nodeid) + ' AND ATTR = ' + sqlise(key))
def __setitem__(self, key, values): self.attrs.table.deleteRows('ID_REF = ' + sqlise(self.nodeid) + ' AND ATTR = ' + sqlise(key)) self.values()[key] = [] self.addValues(key, values)
def deleteAll(self): import inspect for frame in inspect.stack(): warning("stack:", frame[1] + ":" + str(frame[2])) self.attrs.table.deleteRows('ID_REF = ' + sqlise(self.nodeid)) self.__values = {}
def SQLtestType(*types): assert len(types) > 0 if len(types) == 1: return "TYPE = " + sqlise(types[0]) return "TYPE IN (" + string.join([sqlise(type) for type in types], ",") + ")"