Changeset 87

Show
Ignore:
Timestamp:
01/27/08 16:22:38 (4 years ago)
Author:
phil
Message:

added remove(), rename() and an excpetions file

Location:
rdfalchemy/trunk/rdfalchemy
Files:
1 added
1 modified

Legend:

Unmodified
Added
Removed
  • rdfalchemy/trunk/rdfalchemy/rdfalchemy.py

    r86 r87  
    3737import logging 
    3838 
    39 console = logging.StreamHandler() 
     39##console = logging.StreamHandler() 
    4040## console.setLevel(logging.DEBUG)    ## <- the debug level goes here 
    41 formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') 
    42 console.setFormatter(formatter) 
     41##formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') 
     42##console.setFormatter(formatter) 
    4343log=logging.getLogger('rdfalchemy') 
    4444##log.setLevel(logging.DEBUG) 
    45 log.addHandler(console) 
     45##log.addHandler(console) 
    4646 
    4747RDF  =Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#") 
     
    5151re_ns_n = re.compile('(.*[/#])(.*)') 
    5252 
     53from exceptions import * 
     54     
    5355# Look into caching as in: 
    5456# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/276643 
     
    187189        return val 
    188190 
     191class 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         
     219class 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 
    189248 
    190249class rdfObject(object): 
     
    318377        return val 
    319378         
     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         
    320445    def ppo(self,db=None): 
    321446        """Like pretty print...