Changeset 89

Show
Ignore:
Timestamp:
01/30/08 11:07:59 (4 years ago)
Author:
phil
Message:

get_by and filter_by will now work for inherited classes
This adds _getdescriptor to rdfObject and fixes ticket:9

Files:
1 modified

Legend:

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

    r88 r89  
    2929SOFTWARE. 
    3030""" 
    31 __version__ = "0.1dev" 
     31__version__ = "0.2dev" 
    3232 
    3333from rdflib import ConjunctiveGraph 
     
    122122             
    123123    def __delete__(self, obj): 
    124         # if this is a bnode like a list or a container a lot more should  
     124        """deletes or removes from the database triples with: 
     125          obj.resUri as subject and self.pred as predicate 
     126          if the object of that triple is a Literal that stop 
     127          if the object of that triple is a BNode  
     128          then cascade the delete if that BNode has no further references to it 
     129          i.e. it is not the object in any other triples. 
     130        """  
    125131        # be done ala getList above 
    126132        log.debug("DELETE with descriptor for %s on %s"%(self.pred, obj.resUri))         
     
    167173        elif isinstance(value,rdfObject): 
    168174            o = value.resUri 
    169         elif isinstance(value,str) or isinstance(value,unicode): 
    170             o = Literal(value,) 
    171         elif isinstance(value,int) or isinstance(value,float): 
    172             o = Literal(str(value),) 
    173         else: 
    174             raise NotImplimented 
     175        else: 
     176            o = Literal(value) 
    175177        obj.db.set((obj.resUri,self.pred, o)) 
    176178        #return None 
     
    298300        return self.resUri.n3() 
    299301                 
     302 
     303    @classmethod 
     304    def _getdescriptor(cls, key): 
     305        """__get_descriptor returns the descriptor for the key. 
     306        It essentially cls.__dict__[key] with recursive calls to super""" 
     307        #log.debug("Getting descriptor for class: %s with key: %s" % (cls,key)) 
     308        # NOT SURE if mro is the way to do this or if we should call super or bases? 
     309        for kls in cls.mro(): 
     310            if key in kls.__dict__: 
     311                return kls.__dict__[key] 
     312        raise AttributeError("descriptor %s not found for class %s" % (key,cls)) 
     313         
     314 
     315    @classmethod 
    300316    def get_by(cls, **kwargs): 
    301317        """Class Method, returns a single instance of the class 
     
    315331        else: 
    316332            o = Literal(value) 
    317         pred=cls.__dict__[key].pred 
     333        pred=cls._getdescriptor(key).pred 
    318334        uri=cls.db.value(None,pred,o) 
    319335        if uri: 
     
    321337        else: 
    322338            raise LookupError("%s = %s not found"%(key,value)) 
    323     get_by=classmethod(get_by) 
    324339    #short term hack.  Need to go to a sqlalchemy 0.4 style query method 
    325340    query_get_by=get_by 
    326341         
     342 
     343    @classmethod 
    327344    def filter_by(cls, **kwargs): 
    328345        """Class method returns a generator over classs instances 
     
    337354        filters = [] 
    338355        for key,value in kwargs.items(): 
    339             try: 
    340                 pred=cls.__dict__[key].pred 
    341             except LookupError : 
    342                 raise LookupError ("%s not a valid descriptor for %s" % (key,cls)) 
     356            pred = cls._getdescriptor(key).pred 
    343357            # try to make the value be OK for the triple query as an object 
    344358            if isinstance(value, rdfObject): 
     
    362376                    continue 
    363377            yield cls(sub) 
    364     filter_by=classmethod(filter_by) 
    365          
     378         
     379    @classmethod 
    366380    def ClassInstances(cls): 
    367381        """return a generator for instances of this rdf:type 
     
    369383        for i in cls.db.subjects(RDF.type, cls.rdf_type): 
    370384            yield cls(i) 
    371     ClassInstances=classmethod(ClassInstances) 
    372  
     385 
     386    @classmethod 
    373387    def GetRandom(cls): 
    374388        """for develoment just returns a random instance of this class""" 
     
    376390        xii=list(cls.ClassInstances()) 
    377391        return xii[randint(0,len(xii)-1)] 
    378     GetRandom=classmethod(GetRandom) 
    379392         
    380393    def __repr__(self): 
     
    386399        val=self.db.value(self.resUri,pred) 
    387400        if isinstance(val,Literal): 
    388             val =  val.datatype and val.toPython() or unicode(val)  
     401            val =  val.toPython()  
    389402        elif isinstance(val, BNode) or isinstance(val,URIRef):  
    390403            val=rdfObject(val)