| | 191 | class rdflibList(rdflibMultiple): |
| | 192 | '''This is a Discriptor |
| | 193 | Expects to return a list of values (could be a list of one)''' |
| | 194 | def __init__(self, pred, cacheName=None, range_type=None): |
| | 195 | super(rdflibMultiple, self).__init__(pred, cacheName, range_type) |
| | 196 | |
| | 197 | def __get__(self, obj, cls): |
| | 198 | if obj is None: |
| | 199 | return self |
| | 200 | #log.debug("Geting %s for %s"%(obj.db.qname(self.pred),obj.db.qname(obj.resUri))) |
| | 201 | log.debug("Geting %s for %s"%(self.pred,obj.resUri)) |
| | 202 | base = obj.db.value(obj.resUri,self.pred) |
| | 203 | if not base: |
| | 204 | return [] |
| | 205 | members=[] |
| | 206 | first = obj.db.value(base, RDF.first) |
| | 207 | # OK let's work at returning a list if there is an RDF.first |
| | 208 | if not first: |
| | 209 | raise AttributeError, ("expected node [%s] to be a list but it's not" %base.n3()) |
| | 210 | while first: |
| | 211 | members.append(first) |
| | 212 | base = db.value(base, RDF.rest) |
| | 213 | first = db.value(base, RDF.first) |
| | 214 | |
| | 215 | val=[((isinstance(v,BNode) or isinstance(v,URIRef)) and self.range_class(v) or v) for v in members] |
| | 216 | setattr(obj, self.name, members) |
| | 217 | return members |
| | 218 | |
| | 219 | class rdflibContainer(rdflibMultiple): |
| | 220 | '''This is a Discriptor |
| | 221 | Expects to return a list of values (could be a list of one)''' |
| | 222 | def __init__(self, pred, cacheName=None, range_type=None): |
| | 223 | super(rdflibMultiple, self).__init__(pred, cacheName, range_type) |
| | 224 | |
| | 225 | def __get__(self, obj, cls): |
| | 226 | if obj is None: |
| | 227 | return self |
| | 228 | #log.debug("Geting %s for %s"%(obj.db.qname(self.pred),obj.db.qname(obj.resUri))) |
| | 229 | log.debug("Geting %s for %s"%(self.pred,obj.resUri)) |
| | 230 | base = obj.db.value(obj.resUri,self.pred) |
| | 231 | if not base: |
| | 232 | return [] |
| | 233 | members=[] |
| | 234 | i=1 |
| | 235 | first=db.value(base, RDF._1) |
| | 236 | if not first: |
| | 237 | raise AttributeError, ("expected node [%s] to be a list but it's not" % base.n3()) |
| | 238 | while first: |
| | 239 | members.append(first) |
| | 240 | i += 1 |
| | 241 | first=db.value(base, RDF['_%d'%i]) |
| | 242 | |
| | 243 | val=[((isinstance(v,BNode) or isinstance(v,URIRef)) and self.range_class(v) or v) for v in members] |
| | 244 | setattr(obj, self.name, members) |
| | 245 | return members |
| | 246 | |
| | 247 | |
| | 379 | def remove(self, node=None, db=None, cascade = 'bnode', bnodeCheck=True): |
| | 380 | """remove all triples where this rdfObject is the subject of the triple |
| | 381 | db -- limit the remove operation to this graph |
| | 382 | node -- node to remove from the graph defaults to self |
| | 383 | cascade -- must be one of: |
| | 384 | * none -- remove none |
| | 385 | * bnode -- (default) remove all unreferenced bnodes |
| | 386 | * all -- remove all unreferenced bnode(s) AND uri(s) |
| | 387 | bnodeCheck -- boolean |
| | 388 | * True -- (default) check bnodes and raise exception if there are |
| | 389 | still references to this node |
| | 390 | * False -- do not check. This can leave orphaned object reference |
| | 391 | in triples. Use only if you are resetting the value in |
| | 392 | the same transaction |
| | 393 | """ |
| | 394 | if not node: |
| | 395 | node = self.resUri |
| | 396 | log.debug("Called remove on %s" % node) |
| | 397 | if not db: |
| | 398 | db = self.db |
| | 399 | # we cannot delete a bnode if it is still referenced, |
| | 400 | # i.e. if it is the o of a s,p,o |
| | 401 | if bnodeCheck and isinstance(node,BNode): |
| | 402 | for s,p,o in db.triples((None,None,node)): |
| | 403 | raise RDFAlchemyError("Cannot delete a bnode %s becuase %s still references it" % (node.n3(), s.n3())) |
| | 404 | # determine an appropriate test for cascade decisions |
| | 405 | if cascade == 'bnode': |
| | 406 | #we cannot delete a bnode if there are still references to it |
| | 407 | def test(node): |
| | 408 | if not isinstance(node,BNode): |
| | 409 | return False |
| | 410 | for s,p,o in db.triples((None,None,node)): |
| | 411 | return False |
| | 412 | return True |
| | 413 | elif cascade == 'none': |
| | 414 | def test(node): |
| | 415 | return False |
| | 416 | elif cascade == 'all': |
| | 417 | def test(node): |
| | 418 | if not (isinstance(node,BNode) or isinstance(node,URIRef)): |
| | 419 | return False |
| | 420 | for s,p,o in db.triples((None,None,node)): |
| | 421 | return False |
| | 422 | return True |
| | 423 | else: |
| | 424 | raise AttributeError, "unknown cascade argument" |
| | 425 | for s,p,o in db.triples((node, None, None)): |
| | 426 | db.remove((s,p,o)) |
| | 427 | if test(o): |
| | 428 | self.remove(node=o, db=db,cascade=cascade) |
| | 429 | |
| | 430 | def rename(self, name, db=None): |
| | 431 | """rename a node """ |
| | 432 | if not db: |
| | 433 | db = self.db |
| | 434 | if not (isinstance(name,BNode) or isinstance(name,URIRef)): |
| | 435 | raise AttributeError, ("cannot rename to %s" % name) |
| | 436 | for s,p,o in db.triples((self.resUri,None,None)): |
| | 437 | db.set((name, p, o)) |
| | 438 | for s,p,o in db.triples((None,None,self.resUri)): |
| | 439 | db.set((s, p, name)) |
| | 440 | |
| | 441 | |
| | 442 | |
| | 443 | |
| | 444 | |