home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / python-support / python-rdflib / rdflib / store / REGEXMatching.py < prev    next >
Encoding:
Python Source  |  2007-04-04  |  5.7 KB  |  134 lines

  1. """
  2. This wrapper intercepts calls through the store interface which  make use of
  3. The REGEXTerm class to represent matches by REGEX instead of literal comparison
  4. Implemented for stores that don't support this and essentially provides the support
  5. by replacing the REGEXTerms by wildcards (None) and matching against the results
  6. from the store it's wrapping
  7. """
  8.  
  9. from rdflib.store import Store
  10. from pprint import pprint
  11. from rdflib.Graph import Graph, QuotedGraph, ConjunctiveGraph, BackwardCompatGraph
  12. import re
  13.  
  14. #Store is capable of doing it's own REGEX matching
  15. NATIVE_REGEX = 0
  16. #Store uses python's re module internally for REGEX matching (SQLite for instance)
  17. PYTHON_REGEX = 1
  18.  
  19. #REGEXTerm can be used in any term slot and is interpreted as
  20. #a request to perform a REGEX match (not a string comparison) using the value
  21. #(pre-compiled) for checkin rdf:type matches
  22. class REGEXTerm(unicode):
  23.     def __init__(self,expr):
  24.         self.compiledExpr = re.compile(expr)
  25.  
  26.     def __reduce__(self):
  27.         return (REGEXTerm, (unicode(''),))
  28.  
  29. def regexCompareQuad(quad,regexQuad):
  30.     for index in range(4):
  31.         if isinstance(regexQuad[index],REGEXTerm) and not regexQuad[index].compiledExpr.match(quad[index]):
  32.             return False
  33.     return True
  34.  
  35. class REGEXMatching(Store):
  36.     def __init__(self, storage):
  37.         self.storage = storage
  38.         self.context_aware = storage.context_aware
  39.         #NOTE: this store can't be formula_aware as it doesn't have enough info to reverse
  40.         #The removal of a quoted statement
  41.         self.formula_aware = storage.formula_aware
  42.         self.transaction_aware = storage.transaction_aware
  43.  
  44.     def open(self, configuration, create=True):
  45.         return self.storage.open(configuration,create)
  46.  
  47.     def close(self, commit_pending_transaction=False):
  48.         self.storage.close()
  49.  
  50.     def destroy(self, configuration):
  51.         self.storage.destroy(configuration)
  52.  
  53.     def add(self, (subject, predicate, object_), context, quoted=False):
  54.         self.storage.add((subject, predicate, object_), context, quoted)
  55.  
  56.     def remove(self, (subject, predicate, object_), context=None):
  57.         if isinstance(subject,REGEXTerm) or \
  58.            isinstance(predicate,REGEXTerm) or \
  59.            isinstance(object_,REGEXTerm) or \
  60.            (context is not None and isinstance(context.identifier,REGEXTerm)):
  61.             #One or more of the terms is a REGEX expression, so we must replace it / them with wildcard(s)
  62.             #and match after we query
  63.             s = not isinstance(subject,REGEXTerm) and subject or None
  64.             p = not isinstance(predicate,REGEXTerm) and predicate or None
  65.             o = not isinstance(object_,REGEXTerm) and object_ or None
  66.             c = (context is not None and not isinstance(context.identifier,REGEXTerm)) and context or None
  67.  
  68.             removeQuadList = []
  69.             for (s1,p1,o1),cg in self.storage.triples((s,p,o),c):
  70.                 for ctx in cg:
  71.                     ctx = ctx.identifier
  72.                     if regexCompareQuad((s1,p1,o1,ctx),(subject,predicate,object_,context is not None and context.identifier or context)):
  73.                         removeQuadList.append((s1,p1,o1,ctx))
  74.             for s,p,o,c in removeQuadList:
  75.                 self.storage.remove((s,p,o),c and Graph(self,c) or c)
  76.         else:
  77.             self.storage.remove((subject,predicate,object_),context)
  78.  
  79.     def triples(self, (subject, predicate, object_), context=None):
  80.         if isinstance(subject,REGEXTerm) or \
  81.            isinstance(predicate,REGEXTerm) or \
  82.            isinstance(object_,REGEXTerm) or \
  83.            (context is not None and isinstance(context.identifier,REGEXTerm)):
  84.             #One or more of the terms is a REGEX expression, so we must replace it / them with wildcard(s)
  85.             #and match after we query
  86.             s = not isinstance(subject,REGEXTerm) and subject or None
  87.             p = not isinstance(predicate,REGEXTerm) and predicate or None
  88.             o = not isinstance(object_,REGEXTerm) and object_ or None
  89.             c = (context is not None and not isinstance(context.identifier,REGEXTerm)) and context or None
  90.             for (s1,p1,o1),cg in self.storage.triples((s,p,o),c):
  91.                 matchingCtxs = []
  92.                 for ctx in cg:
  93.                     if c is None:
  94.                         if context is None or context.identifier.compiledExpr.match(ctx.identifier):
  95.                             matchingCtxs.append(ctx)
  96.                     else:
  97.                         matchingCtxs.append(ctx)
  98.                 if matchingCtxs and regexCompareQuad((s1,p1,o1,None),(subject,predicate,object_,None)):
  99.                     yield (s1,p1,o1),(c for c in matchingCtxs)
  100.         else:
  101.             for (s1,p1,o1),cg in self.storage.triples((subject, predicate, object_), context):
  102.                 yield (s1,p1,o1),cg
  103.  
  104.     def __len__(self, context=None):
  105.         #NOTE: If the context is a REGEX this could be an expensive proposition
  106.         return self.storage.__len__(context)
  107.  
  108.     def contexts(self, triple=None):
  109.         #NOTE: There is no way to control REGEX matching for this method at this level
  110.         #(as it only returns the contexts, not the matching triples
  111.         for ctx in self.storage.contexts(triple):
  112.             yield ctx
  113.  
  114.     def remove_context(self, identifier):
  115.         self.storage.remove((None,None,None),identifier)
  116.  
  117.     def bind(self, prefix, namespace):
  118.         self.storage.bind(prefix, namespace)
  119.  
  120.     def prefix(self, namespace):
  121.         return self.storage.prefix(namespace)
  122.  
  123.     def namespace(self, prefix):
  124.         return self.storage.namespace(prefix)
  125.  
  126.     def namespaces(self):
  127.         return self.storage.namespaces()
  128.  
  129.     def commit(self):
  130.         self.storage.commit()
  131.  
  132.     def rollback(self):
  133.         self.storage.rollback()
  134.