Viewing file: Memory.py (11.54 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
######################################################################## # $Header: /var/local/cvsroot/4Suite/Ft/Rdf/Drivers/Memory.py,v 1.21 2005/03/04 16:32:49 mbrown Exp $ """ A non-persistent RDF model driver
Copyright 2005 Fourthought, Inc. (USA). Detailed license and copyright information: http://4suite.org/COPYRIGHT Project home, documentation, distributions: http://4suite.org/ """
import re
from Ft.Rdf import Model, RdfException from Ft.Rdf import OBJECT_TYPE_RESOURCE, OBJECT_TYPE_UNKNOWN from Ft.Rdf.Drivers import PROPERTIES from Ft.Rdf.Statement import Statement
def InitializeModule(): """ Post-import hook to initialize module's runtime variables that are not required at import time, but will be needed before the module-level functions are called. """ pass
def CreateDb(dbName, modelName='default'): return DbAdapter(dbName, modelName)
#Identical function for Memory driver GetDb = CreateDb
def DestroyDb(dbName, modelName='default'): """ Does nothing in this driver (there is no persistent data store) """ pass
def ExistsDb(dbName, modelName='default'): """ Returns False in this driver (there is no persistent data store) """ return False
def ForceUnicode(*args): #Especially needed because of what seems to be a weird bug in Python 2.2 #that can cause failed compares between identical strings & unicode objs #in certain obscure cases we run into in this driver (nested functions, etc.) return tuple([ a and unicode(a) or a for a in args ])
class DbAdapter: def __init__(self, name, modelName='default'): self._acl = {} self._statements = {modelName: []} self._bound = {} self._modelName = modelName self.props = {PROPERTIES.OBJECT_TYPE_SUPPORTED: 1} return
### Transactional Interface ###
def begin(self): """ Does nothing in this driver (transactions are not supported) """ return
def commit(self): """ Does nothing in this driver (transactions are not supported) """ return
def rollback(self): """ Does nothing in this driver (transactions are not supported) """ return
### Operations ###
def add(self, statements): # stored statements -> statement tuple self._statements[self._modelName].extend(statements) return
def remove(self, statements): for s in statements: self.removePattern(s[0], s[1], s[2], s[3], s[4], {}) return
def removePattern(self, subject, predicate, object_, statementUri, scope, flags): (subject, predicate, object_, statementUri, scope) = ForceUnicode( subject, predicate, object_, statementUri, scope ) # we use not not because '' and None are equivalent to us command = g_removes[(not not subject, not not predicate, not not object_, not not statementUri, not not scope, )] operators = (g_operators[flags.get('subjectFlags')](subject or ''), g_operators[flags.get('predicateFlags')](predicate or ''), g_operators[flags.get('objectFlags')](object_ or ''), g_operators[flags.get('statementUriFlags')](statementUri or ''), g_operators[flags.get('scopeFlags')](scope or ''), ) self._statements[self._modelName] = filter(lambda s, f=command, o=operators: not f(o, s), self._statements[self._modelName]) return
### Queries
def properties(self, scope): stmts = self.complete(None, None, None, None, scope, {}) pdict = {} for s in stmts: pdict[s[1]] = None return pdict.keys()
def resources(self, scope): stmts = self.complete(None, None, None, None, scope, {}) rdict = {} for s in stmts: rdict[s[0]] = None rdict[s[1]] = None return rdict.keys()
def complete(self, subject, predicate, object_, statementUri, scope, flags): (subject, predicate, object_, statementUri, scope) = ForceUnicode( subject, predicate, object_, statementUri, scope ) command = g_completes[(not not subject, not not predicate, not not object_, not not statementUri, not not scope, )] operators = (g_operators[flags.get('subjectFlags')](subject or ''), g_operators[flags.get('predicateFlags')](predicate or ''), g_operators[flags.get('objectFlags')](object_ or ''), g_operators[flags.get('statementUriFlags')](statementUri or ''), g_operators[flags.get('scopeFlags')](scope or ''), )
return filter(lambda s, f=command, o=operators: f(o, s), self._statements[self._modelName])
def size(self, scope): if scope: return reduce(lambda r, s, u=scope: r + (s[4] == u), self._statements[self._modelName], 0) else: return len(self._statements[self._modelName])
def contains(self, subject, predicate, object_, statementUri, scope, flags): (subject, predicate, object_, statementUri, scope) = ForceUnicode( subject, predicate, object_, statementUri, scope ) command = g_contains[(not not subject, not not predicate, not not object_, not not statementUri, not not scope, )] operators = (g_operators[flags.get('subjectFlags')](subject or ''), g_operators[flags.get('predicateFlags')](predicate or ''), g_operators[flags.get('objectFlags')](object_ or ''), g_operators[flags.get('statementUriFlags')](statementUri or ''), g_operators[flags.get('scopeFlags')](scope or ''), )
size = reduce(lambda r, s, f=command, o=operators: r + (f(o, s) and 1 or 0), self._statements[self._modelName], 0) return size > 0
def bind(self, object_, name, scope): if scope not in self._bound: self._bound[scope] = {} self._bound[scope][name] = object_ return
def unbind(self, name, scope): if scope not in self._bound: return info = self._bound[scope].get(name) if info: del self._bound[scope][name] return
def lookup(self, name, scope): if scope not in self._bound: return None return self._bound[scope].get(name)
def keys(self, scope): if not scope: result = [] for bindings in self._bound.values(): result.extend(bindings.keys()) return result else: if self._bound.has_key(scope): result = self._bound[scope].keys() else: result = [] return result
def has_key(self, name, scope): if not scope: result = reduce(lambda a, b, n=name: a + b.has_key(n), self._bound.values(), False) else: if self._bound.has_key(scope): result = name in self._bound[scope] else: result = False
return result
## Utilities for performance, primarily in Versa ## def subjectsFromPredAndObjs(self, predicate, objects, scope): """ Get a list of subjects with the given predicate and objects """ resDict = {} if predicate is not None: for object_ in objects: for s in self.complete(None, predicate, object_, None, scope, {}): resDict[s[0]] = True else: #FIXME: for purposes of Versa, we should not be using null as a wildcard, it seems for s in self._statements[self._modelName]: resDict[s[0]] = True return resDict.keys()
def subjectsFromPredsAndObj(self, predicates, object_, scope): """ Get a list of subjects with the given predicates and object """ resDict = {} if object_ is not None: for p in predicates: for s in self.complete(None, p, object_, None, scope, {}): resDict[s[0]] = True else: #FIXME: for purposes of Versa, we should not be using null as a wildcard, it seems for s in self._statements[self._modelName]: resDict[s[0]] = True return resDict.keys()
def objectsFromSubAndPreds(self, subject, predicates, scope): """ Get a list of objects with the given predicates and subject """ resDict = {} if subject is not None: for predicate in predicates: for s in self.complete(subject, predicate, None, None, scope, {}): resDict[(s[2], s[5])] = True else: #FIXME: for purposes of Versa, we should not be using null as a wildcard, it seems for s in self._statements[self._modelName]: resDict[(s[2], s[5])] = True return resDict.keys()
def isResource(self, res): #return [ s for s in self._statements[self._modelName] if res == s[0] or res == s[1] ] r = False for s in self._statements[self._modelName]: if res == s[0]: r = True break return r
def _regexCompile(cmd): try: return re.compile(cmd).match except re.error, e: raise RdfException(RdfException.INVALID_REGEX_STATEMENT, cmd, str(e))
def _regexICCompile(cmd): try: return re.compile(cmd,re.IGNORECASE).match except re.error, e: raise RdfException(RdfException.INVALID_REGEX_STATEMENT, cmd, str(e))
g_operators = { None : lambda s: lambda a, b=s: a == b, Model.NORMAL : lambda s: lambda a, b=s: a == b, Model.IGNORE_CASE : lambda s: lambda a, b=s.lower(): a.lower() == b, Model.REGEX : _regexCompile, Model.IGNORE_CASE + Model.REGEX : _regexICCompile, }
g_completes = {} g_removes = {} g_contains = {}
for bits in range(32): key = (bits & 16 > 0, bits & 8 > 0, bits & 4 > 0, bits & 2 > 0, bits & 1)
# where f = comparison function for each item of a statement tuple # s = the statement tuple
parts = [] if bits & 16: parts.append('f[0](s[0])') if bits & 8: parts.append('f[1](s[1])') if bits & 4: parts.append('f[2](s[2])') if bits & 2: parts.append('f[3](s[3])') if bits & 1: parts.append('f[4](s[4])')
if parts: body = ' and '.join(parts) else: body = '1'
g_completes[key] = eval('lambda f, s: %s' % body) g_removes[key] = eval('lambda f, s: %s' % body)
if parts: body = ' and '.join(parts) else: body = '1' g_contains[key] = eval('lambda f, s: %s' % body)
|