Changeset 94

Show
Ignore:
Timestamp:
02/05/08 22:22:57 (4 years ago)
Author:
phil
Message:

ROLLED-BACK the rdfSubject as a subclass of Identifier
this fixed a bun in changeset:91
modified docstrings to be epydoc compliant
Added another unittest

Location:
rdfalchemy/trunk
Files:
2 added
7 modified

Legend:

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

    r91 r94  
    6565    """suitable for a triple takes a value and returns a Literal, URIRef or BNode  
    6666    suitable for a triple""" 
    67     if isinstance(value,Identifier): 
     67    if isinstance(value, rdfSubject): 
     68        return value.resUri 
     69    elif isinstance(value, Identifier): 
    6870        return value 
    6971    else: 
     
    143145        obj.__dict__[self.name]= value 
    144146        o =value2object(value) 
    145         obj.db.set((obj, self.pred, o)) 
     147        obj.db.set((obj.resUri, self.pred, o)) 
    146148        #return None 
    147149     
     
    185187        for value in oldvals: 
    186188            if value not in newvals: 
    187                 obj.db.remove((obj,self.pred, value2object(value))) 
     189                obj.db.remove((obj.resUri,self.pred, value2object(value))) 
    188190                log.debug("removing: %s, %s, %s"%(obj.n3(),self.pred,value)) 
    189191        for value in newvals: 
    190192            if value not in oldvals: 
    191                 obj.db.add((obj, self.pred, value2object(value))) 
     193                obj.db.add((obj.resUri, self.pred, value2object(value))) 
    192194                log.debug("adding: %s, %s, %s"%(obj.n3(),self.pred,value)) 
    193195        obj.__dict__[self.name] = copy(newvals) 
     
    234236            oldvals = [] 
    235237            obj.__dict__[self.name] = oldvals 
    236         oldhead = obj.db.value(obj,self.pred) 
     238        oldhead = obj.db.value(obj.resUri,self.pred) 
    237239##          # This is a stack style where retrevial is oppisite of how it starts out 
    238240##         newnode = RDF.nil 
     
    255257                newtail = BNode() 
    256258            obj.db.add((oldtail, RDF.rest, RDF.nil)) 
    257         obj.db.set((obj, self.pred, newhead)) 
     259        obj.db.set((obj.resUri, self.pred, newhead)) 
    258260        if oldhead: 
    259261            rdfSubject(oldhead)._remove(db=obj.db) 
     
    278280        #log.debug("Geting %s for %s"%(obj.db.qname(self.pred),obj.db.qname(obj.resUri))) 
    279281        log.debug("Geting %s for %s"%(self.pred,obj.n3())) 
    280         base = obj.db.value(obj, self.pred) 
     282        base = obj.db.value(obj.resUri, self.pred) 
    281283        if not base: 
    282284            return [] 
     
    299301        if not isinstance(newvals, list): 
    300302            raise AttributeError("to set a rdflibList you must pass in a list (it can be a list of one)") 
    301         seq = obj.db.value(obj, self.pred) 
     303        seq = obj.db.value(obj.resUri, self.pred) 
    302304        if not seq: 
    303305            seq = BNode() 
    304             obj.db.add((obj, self.pred, seq)) 
     306            obj.db.add((obj.resUri, self.pred, seq)) 
    305307            obj.db.add((seq, RDF.type, RDF.Seq)) 
    306308        for s,p,o in obj.db.triples((seq, None, None)): 
  • rdfalchemy/trunk/rdfalchemy/engine/__init__.py

    r91 r94  
    88    rdflib ConjunctiveGraph 
    99    e.g.: 
    10        create_engine('mysql://myname@localhost/rdflibdb') 
    11        create_engine('sleepycat://~/working/rdf_db') 
    12        create_engine('zodb:///var/rdflib/Data.fs') 
    13        create_engine('zodb://localhost:8672') 
     10       
     11      - create_engine('mysql://myname@localhost/rdflibdb') 
     12      - create_engine('sleepycat://~/working/rdf_db') 
     13      - create_engine('zodb:///var/rdflib/Data.fs') 
     14      - create_engine('zodb://localhost:8672') 
     15     
    1416    for zodb: 
     17     
    1518       the key in the Zope database is hardcoded as 'rdflib' 
    1619       urls ending in `.fs` indicate FileStorage 
  • rdfalchemy/trunk/rdfalchemy/rdfalchemy.py

    r92 r94  
    6868 
    6969#class rdfSubject(object): 
    70 class rdfSubject(Identifier): 
     70class rdfSubject(object): 
    7171    db=ConjunctiveGraph() 
    7272    """Default graph for access to instances of this type""" 
    7373    rdf_type=None 
    7474    """rdf:type of instances of this class""" 
    75     def __new__(cls, resUri = None, **kwargs): 
    76         """docstring for __new__""" 
    77         if not resUri or isinstance(resUri, BNode): 
    78             sub = BNode.__new__(cls, resUri) 
    79             sub.node_type = 'bnode' 
    80         elif isinstance(resUri, (str, unicode)) and resUri.startswith("_:"): 
    81             sub = BNode.__new__(cls, resUri[2:]) 
    82             sub.node_type = 'bnode' 
    83         elif isinstance(resUri, URIRef): 
    84             sub = URIRef.__new__(cls, resUri) 
    85             sub.node_type = 'uri' 
    86         elif isinstance(resUri, (str, unicode)) and resUri[0]=="<" and resUri[-1]==">": 
    87             sub = URIRef.__new__(cls, resUri[1:-1]) 
    88             sub.node_type = 'uri' 
     75##  
     76##     def __new__(cls, resUri = None, **kwargs): 
     77##         obj = object.__new__(cls) 
     78##         obj.resUri = resUri 
     79##         return obj.__init__(resUri, **kwargs) 
     80         
     81 
     82    def __init__(self, resUri = None, **kwargs): 
     83        """The constructor tries hard to do return you an rdfSubject 
     84 
     85        :param resUri: can be one of 
     86 
     87           * an instance of an rdfSubject 
     88           * an instance of a BNode or a URIRef 
     89           * an n3 uriref string like: <urn:isbn:1234567890> 
     90           * an n3 bnode string like _:xyz1234  
     91         
     92        :param resUri: if None then create an instance with a BNode resUri 
     93        :param kwargs: is a set of values that will be set using the keys to find the appropriate descriptor""" 
     94         
     95        if not resUri: 
     96            self.resUri = BNode() 
     97            if self.rdf_type: 
     98                self.db.add((self.resUri,RDF.type,self.rdf_type)) 
     99        elif isinstance(resUri, (BNode, URIRef)): 
     100            self.resUri=resUri 
    89101        elif isinstance(resUri, rdfSubject): 
    90             sub = Identifier.__new__(cls, resUri)  
    91             sub.node_type = resUri.node_type 
    92             if sub.db != resUri.db: 
    93                sub.db = resUri.db 
     102            self.resUri=resUri.resUri  
     103            self.db=resUri.db 
     104        elif instance(resUri, (str, unicode)): 
     105            if resUri[0]=="<" and resUri[-1]==">": 
     106                self.resUri=URIRef(resUri[1:-1]) 
     107            elif resUri.startswith("_:"): 
     108                self.resUri=BNode(resUri[2:]) 
    94109        else: 
    95110            raise AttributeError("cannot construct rdfSubject from %s"%(str(resUri))) 
    96         return sub 
    97  
    98     def __init__(self, resUri = None, **kwargs): 
    99         """The constructor tries hard to do return you an rdfSubject 
    100         the parameter resUri can be: 
    101          * an instance of an rdfSubject 
    102          * an instance of a BNode or a URIRef 
    103          * an n3 uriref string like: <urn:isbn:1234567890> 
    104          * an n3 bnode string like _:xyz1234  
    105         a null resUri will cause a new one created of  
    106         this classes rdf_type 
    107          `kwargs` is a set of values that will be set""" 
     111         
    108112        if kwargs: 
    109113            self._set_with_dict(kwargs) 
     
    112116            # lets create a new one 
    113117            if self.rdf_type: 
    114                 self.db.set((self,RDF.type, self.rdf_type)) 
     118                self.db.set((self.resUri,RDF.type, self.rdf_type)) 
    115119        # lets get a default namespace for this  
    116120        # ??obsolete ??? 
    117         rdftype = list(self.db.objects(self, RDF.type)) 
     121        rdftype = list(self.db.objects(self.resUri, RDF.type)) 
    118122        if len(rdftype)==1: 
    119123            self.namespace, trash = re_ns_n.match(rdftype[0]).groups() 
    120124            self.namespace=Namespace(self.namespace) 
    121         elif isinstance(self,URIRef): 
    122             ns_n =  re_ns_n.match(self) 
     125        elif isinstance(self.resUri, URIRef): 
     126            ns_n =  re_ns_n.match(self.resUri) 
    123127            if ns_n: 
    124128                self.namespace, self.name = ns_n.groups() 
     
    127131    def n3(self): 
    128132        """n3 repr of this node""" 
    129         if self.node_type == 'bnode': 
    130             return "_:%s"%self 
    131         elif self.node_type == 'uri': 
    132             return "<%s>"%self 
    133         else: 
    134             raise AttributeError("Unknown node type for %s"(self)) 
     133        return self.resUri.n3() 
    135134         
    136135 
     
    158157        class. 
    159158        example: 
     159         
    160160            bigBlue = Company.get_by(symbol='IBM') 
    161161 
    162         OWL Note: 
     162        :Note: 
    163163            the keyword should map to an rdf predicate 
    164164            that is of type owl:InverseFunctional""" 
     
    234234        #log.debug("Getting with __getitem__ %s for %s"%(self.db.qname(pred),self.db.qname(self.resUri))) 
    235235        log.debug("Getting with __getitem__ %s for %s"%(pred,self.n3())) 
    236         val=self.db.value(self,pred) 
     236        val=self.db.value(self.resUri, pred) 
    237237        if isinstance(val,Literal): 
    238238            val =  val.toPython()  
     
    247247        #log.debug("Deleting with __delitem__ %s for %s"%(self.db.qname(pred),self.db.qname(self.resUri))) 
    248248        log.debug("Deleting with __delitem__ %s for %s"%(pred,self)) 
    249         for s,p,o in self.db.triples((self, pred, None)): 
     249        for s,p,o in self.db.triples((self.resUri, pred, None)): 
    250250            self.db.remove((s,p,o)) 
    251251            #finally if the object in the triple was a bnode  
    252252            #cascade delete the thing it referenced 
    253253            # ?? FIXME Do we really want to cascade if it's an rdfSubject?? 
    254             if isinstance(o,BNode) or isinstance(o,rdfSubject) and o.node_type == 'bnode': 
     254            if isinstance(o, (BNode, rdfSubject)): 
    255255                rdfSubject(o)._remove(db=self.db,cascade='bnode') 
    256256         
    257257    def _set_with_dict(self, kv): 
    258         """for each key,value pair in dict kv 
    259                set self.key = value""" 
     258        """ 
     259        :param kv: a dict :: 
     260         
     261          for each key,value pair in dict kv 
     262               set self.key = value 
     263                
     264        """ 
    260265        for key,value in kv.items(): 
    261266            #item.__class__._getdescriptor('authors').__get__(item, item.__class__) 
     
    264269         
    265270         
    266     def _remove(self, node=None, db=None, cascade = 'bnode', bnodeCheck=True): 
     271    def _remove(self, db=None, cascade = 'bnode', bnodeCheck=True): 
    267272        """remove all triples where this rdfSubject is the subject of the triple 
    268         db -- limit the remove operation to this graph 
    269         node -- node to remove from the graph defaults to self 
    270         cascade -- must be one of: 
    271                     * none -- remove none 
     273         
     274        :param db: limit the remove operation to this graph 
     275        :param cascade: must be one of: 
     276         
     277                    * none --  remove none 
    272278                    * bnode -- (default) remove all unreferenced bnodes 
    273279                    * all -- remove all unreferenced bnode(s) AND uri(s) 
    274         bnodeCheck -- boolean  
     280         
     281        :param bnodeCheck: boolean  
     282         
    275283                    * True -- (default) check bnodes and raise exception if there are 
    276                               still references to this node 
    277                     * False -- do not check.  This can leave orphaned object reference  
    278                                in triples.  Use only if you are resetting the value in 
    279                                the same transaction 
     284                      still references to this node 
     285                    * False --  do not check.  This can leave orphaned object reference  
     286                      in triples.  Use only if you are resetting the value in 
     287                      the same transaction 
    280288        """ 
    281         if not node: 
    282             node = self 
    283         log.debug("Called remove on %s" % node) 
     289        noderef = self.resUri             
     290        log.debug("Called remove on %s" % self) 
    284291        if not db: 
    285292            db = self.db 
     293         
    286294        # we cannot delete a bnode if it is still referenced,  
    287295        # i.e. if it is the o of a s,p,o  
    288296        if bnodeCheck: 
    289             if isinstance(node,BNode) or isinstance(node,rdfSubject) and node.node_type=='bnode': 
    290                 for s,p,o in db.triples((None,None,node)): 
    291                     raise RDFAlchemyError("Cannot delete a bnode %s becuase %s still references it" % (node.n3(), s.n3())) 
     297            if isinstance(noderef ,BNode): 
     298                for s,p,o in db.triples((None,None,noderef)): 
     299                    raise RDFAlchemyError("Cannot delete a bnode %s becuase %s still references it" % (noderef.n3(), s.n3())) 
    292300        # determine an appropriate test for cascade decisions 
    293301        if cascade == 'bnode': 
    294302            #we cannot delete a bnode if there are still references to it 
    295303            def test(node): 
    296                 if isinstance(node,(URIRef,Literal)) \ 
    297                    or isinstance(node,rdfSubject) and node.node_type <> 'bnode': 
     304                if isinstance(node,(URIRef,Literal)): 
    298305                    return False 
    299306                for s,p,o in db.triples((None,None,node)): 
     
    305312        elif cascade == 'all': 
    306313            def test(node): 
    307                 if not (isinstance(node,BNode) or isinstance(node,URIRef)): 
     314                if isinstance(node, Literal): 
    308315                    return False 
    309316                for s,p,o in db.triples((None,None,node)): 
     
    312319        else: 
    313320            raise AttributeError, "unknown cascade argument" 
    314         for s,p,o in db.triples((node, None, None)): 
     321        for s,p,o in db.triples((noderef, None, None)): 
    315322            db.remove((s,p,o)) 
    316323            if test(o): 
    317                 self._remove(node=o, db=db,cascade=cascade) 
     324                rdfSubject(o)._remove(db=db,cascade=cascade) 
     325 
    318326                 
    319327    def _rename(self, name, db=None): 
     
    321329        if not db: 
    322330            db = self.db 
    323         if not (isinstance(name,BNode) or isinstance(name,URIRef)): 
     331        if not (isinstance(name, (BNode,URIRef))): 
    324332            raise AttributeError, ("cannot rename to %s" % name) 
    325         for s,p,o in db.triples((self,None,None)): 
     333        for s,p,o in db.triples((self.resUri,None,None)): 
    326334            db.set((name, p, o)) 
    327         for s,p,o in db.triples((None,None,self)): 
     335        for s,p,o in db.triples((None,None,self.resUri)): 
    328336            db.set((s, p, name)) 
    329337        self.resUri = name 
     
    335343        returning all predicate object pairs with qnames""" 
    336344        db = db or self.db 
    337         for p,o in db.predicate_objects(self): 
     345        for p,o in db.predicate_objects(self.resUri): 
    338346            print "%20s = %s"% (db.qname(p),str(o)) 
    339347        print " " 
  • rdfalchemy/trunk/rdfalchemy/samples/example.py

    r91 r94  
    99 
    1010class Company(rdfSubject): 
    11     owlType = OV.Company 
     11    rdf_type = OV.Company 
    1212    symbol = rdflibSingle(OV.symbol,'symbol') 
    1313    cik = rdflibSingle(OV.secCik,'cik') 
  • rdfalchemy/trunk/rdfalchemy/sesame2.py

    r92 r94  
    3131    """openrdf-sesame graph via http 
    3232    Uses the sesame2 HTTP communication protocol 
    33     to provide rdflib type api 
    34     constructor takes http endpoint and repository name 
    35     e.g. 
    36       SesameGraph('http://www.openvest.org:8080/sesame/repositories/Test')""" 
     33    to provide rdflib type api constructor takes http endpoint and repository name 
     34    e.g. SesameGraph('http://www.openvest.org:8080/sesame/repositories/Test')""" 
    3735     
    3836    def __init__(self, url, context=None): 
     
    163161 
    164162    def parse(self, source, publicID=None, format="xml", method='POST'): 
    165         """ Parse source into Graph 
     163        """ 
     164        Parse source into Graph 
    166165 
    167166        Graph will get loaded into it's own context (sub graph).  
    168167        Format defaults to xml (AKA rdf/xml).  
    169         The publicID argument is for specifying the logical URI  
    170         for the case that it's different from the physical source URI.  
    171         Returns the context into which  the source was parsed. 
    172           POST method adds data in a context 
    173           PUT method replaces data in a context 
     168         
     169        :param publicID: *optional* the logical URI if it's different from the physical source URI.  
     170        :returns: Returns the context into which  the source was parsed. 
     171        :param method: must be one of 
     172         
     173          'POST' -- method adds data to a context 
     174          'PUT' -- method replaces data in a context 
    174175        """ 
    175176        url = self.url+'/statements' 
  • rdfalchemy/trunk/rdfalchemy/sparql.py

    r71 r94  
    2828    gives 'read-only' access to the graph 
    2929    constructor takes http endpoint and repository name 
    30     e.g. 
    31       SPARQLGraph('http://localhost:2020/sparql')""" 
     30    e.g.  SPARQLGraph('http://localhost:2020/sparql')""" 
    3231     
    3332    def __init__(self, url, context=None): 
     
    3938        Executes a SPARQL Construct 
    4039        strOrTriple - can be either: 
    41           a string in which case it it considered a CONSTRUCT query 
    42           a triple in which case it acts as the rdflib `triples((s,p,o))` 
     40         
     41          * a string in which case it it considered a CONSTRUCT query 
     42          * a triple in which case it acts as the rdflib `triples((s,p,o))` 
     43         
    4344        initBindings - A mapping from a Variable to an RDFLib term (used as initial bindings for SPARQL query) 
    4445        initNS - A mapping from a namespace prefix to a namespace 
     
    6667         
    6768    def triples(self, (s,p,o), method='CONSTRUCT'): 
    68         """returns a generator over triples matching the pattern 
    69         method must be 'CONSTRUCT' or 'SELECT' 
    70                CONSTRUCT calls CONSTRUCT query and returns a Graph result  
    71                SELECT calls a SELECT query and returns an interator streaming over the results 
     69        """ 
     70        :returns: a generator over triples matching the pattern 
     71        :param method: must be 'CONSTRUCT' or 'SELECT' 
     72         
     73             * CONSTRUCT calls CONSTRUCT query and returns a Graph result  
     74             * SELECT calls a SELECT query and returns an interator streaming over the results 
     75         
    7276        Use SELECT if you expect a large result set or may consume less than the entire result""" 
    7377        if method == 'CONSTRUCT': 
     
    124128 
    125129 
    126     def value(self, subject=None, predicate=RDF.value, object=None, 
    127               default=None, any=True): 
     130    def value(self, subject=None, predicate=RDF.value, object=None, default=None, any=True): 
    128131        """Get a value for a pair of two criteria 
    129132 
     
    131134        knows that there may only be one value. 
    132135 
    133         It is one of those situations that occur a lot, hence this 
    134         'macro' like utility 
    135  
    136         Parameters: 
    137         ----------- 
    138         subject, predicate, object  -- exactly one must be None 
    139         default -- value to be returned if no values found 
    140         any -- if True: 
    141                  return any value in the case there is more than one 
    142                else: 
    143                  raise UniquenessError 
     136        It is one of those situations that occur a lot, hence this *macro* like utility 
     137 
     138        :param  subject, predicate, object: exactly one must be None 
     139        :param default: value to be returned if no values found 
     140        :param any:     if more than one answer return **any one** answer, otherwise `raise UniquenessError` 
    144141        """ 
    145142        retval = default 
     
    217214        """ 
    218215        Executes a SPARQL query against this Graph 
    219         strOrQuery - Is either a string consisting of the SPARQL query  
    220         initBindings - optional mapping from a Variable to an RDFLib term (used as initial bindings for SPARQL query) 
    221         initNS - optional mapping from a namespace prefix to a namespace 
    222         resultMethod - results query requested (must be 'xml' or 'json')  
    223                        xml streams over the result set and json must read the entire set  to succeed  
    224         processor - The kind of RDF query (must be 'sparql' or 'serql') 
     216         
     217        :param strOrQuery: Is either a string consisting of the SPARQL query  
     218        :param initBindings: *optional* mapping from a Variable to an RDFLib term (used as initial bindings for SPARQL query) 
     219        :param initNs: optional mapping from a namespace prefix to a namespace 
     220        :param resultMethod: results query requested (must be 'xml' or 'json')  
     221         xml streams over the result set and json must read the entire set  to succeed  
     222        :param processor: The kind of RDF query (must be 'sparql' or 'serql') 
    225223        """ 
    226224        query = strOrQuery 
     
    305303        """ 
    306304        Executes a SPARQL describe of resource 
    307         s_or_po is either: 
     305         
     306        :param s_or_po:  is either 
    308307         
    309308          * a subject ... should be a URIRef 
     
    311310          * a describe query string 
    312311           
    313         initBindings - A mapping from a Variable to an RDFLib term (used as initial bindings for SPARQL query) 
    314         initNS - A mapping from a namespace prefix to a namespace 
     312        :param initBindings: A mapping from a Variable to an RDFLib term (used as initial bindings for SPARQL query) 
     313        :param initNs: A mapping from a namespace prefix to a namespace 
    315314        """ 
    316315        if isinstance(s_or_po, str): 
  • rdfalchemy/trunk/setup.py

    r61 r94  
    1717    packages=find_packages(exclude=['ez_setup']), 
    1818    include_package_data=True, 
     19    platforms = ["any"], 
     20    classifiers = ["Programming Language :: Python", 
     21                   "License :: OSI Approved :: BSD License", 
     22                   "Topic :: Software Development :: Libraries :: Python Modules", 
     23                   "Operating System :: OS Independent", 
     24                   "Natural Language :: English", 
     25                   ], 
     26 
    1927)