Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Saller <bcsaller@objectrealms.net>2007-07-02 19:45:28 (GMT)
committer Benjamin Saller <bcsaller@objectrealms.net>2007-07-02 19:45:28 (GMT)
commit12a564c450f75121dc59919496290cbfe4c2704b (patch)
treea7cf9c24757084c6555e1760333b20cbfd8c37ac
parent07a88e504b544552915815e04bef235aca247aa2 (diff)
propertys via the create/update dict
key:kind -> value see test/properties.txt
-rw-r--r--src/olpc/datastore/backingstore.py5
-rw-r--r--src/olpc/datastore/datastore.py14
-rw-r--r--src/olpc/datastore/model.py25
-rw-r--r--src/olpc/datastore/query.py27
4 files changed, 60 insertions, 11 deletions
diff --git a/src/olpc/datastore/backingstore.py b/src/olpc/datastore/backingstore.py
index 04a9fa8..03cc54a 100644
--- a/src/olpc/datastore/backingstore.py
+++ b/src/olpc/datastore/backingstore.py
@@ -96,8 +96,10 @@ class BackingStore(object):
def id(self): return self.descriptor()['id']
@property
def title(self): return self.descriptor()['title']
+
+
class FileBackingStore(BackingStore):
""" A backing store that directs maps the storage of content
objects to an available filesystem.
@@ -370,6 +372,8 @@ class FileBackingStore(BackingStore):
if not allowMissing:
raise KeyError("object for uid:%s missing" % uid)
+ def get_uniquevaluesfor(self, propertyname):
+ return self.querymanager.get_uniquevaluesfor(propertyname)
def find(self, query):
@@ -470,3 +474,4 @@ class InplaceFileBackingStore(FileBackingStore):
if os.path.exists(path):
os.unlink(path)
+
diff --git a/src/olpc/datastore/datastore.py b/src/olpc/datastore/datastore.py
index b743e2c..a133dfe 100644
--- a/src/olpc/datastore/datastore.py
+++ b/src/olpc/datastore/datastore.py
@@ -331,6 +331,20 @@ class DataStore(dbus.service.Object):
dictionary[prop.key] = prop.marshall()
return dictionary
+ @dbus.service.method(DS_DBUS_INTERFACE,
+ in_signature='sa{sv}',
+ out_signature='as')
+ def get_uniquevaluesfor(self, propertyname, query=None):
+ if not query: query = {}
+ mountpoints = query.pop('mountpoints', self.mountpoints)
+ mountpoints = [self.mountpoints[str(m)] for m in mountpoints]
+ results = set()
+
+ for mp in mountpoints:
+ result = mp.get_uniquevaluesfor(propertyname)
+ results = results.union(result)
+ return results
+
#@utils.sanitize_dbus
@dbus.service.method(DS_DBUS_INTERFACE,
diff --git a/src/olpc/datastore/model.py b/src/olpc/datastore/model.py
index f70e68f..d678b59 100644
--- a/src/olpc/datastore/model.py
+++ b/src/olpc/datastore/model.py
@@ -11,7 +11,7 @@ __copyright__ = 'Copyright ObjectRealms, LLC, 2007'
__license__ = 'The GNU Public License V2+'
from sqlalchemy import Table, Column, UniqueConstraint
-from sqlalchemy import String, Integer, Unicode, PickleType
+from sqlalchemy import String, Integer, Unicode
from sqlalchemy import ForeignKey, Sequence, Index
from sqlalchemy import mapper, relation
from sqlalchemy import create_session
@@ -31,11 +31,15 @@ import time
# we have a global thread local session factory
context = {}
+propertyTypes = {}
+_marker = object()
def get_session(backingstore):
return context[backingstore]
-_marker = object()
+def registerPropertyType(kind, class_): propertyTypes[kind] = class_
+def propertyByKind(kind): return propertyTypes[kind]
+
class Content(object):
def __repr__(self):
@@ -56,7 +60,6 @@ class Content(object):
query = session.query(Property)
return query.select_by(content_id=self.id, **kwargs)
-
# Backingstore dependent bindings
def get_file(self):
@@ -206,6 +209,15 @@ class NumberProperty(Property):
value = property(get_value, set_value)
+class BinaryProperty(Property):
+ # base64 encode binary data
+ def __init__(self, key, value, type="binary"):
+ Property.__init__(self, key, value, type)
+
+ def get_value(self): return self._value.decode('base64')
+ def set_value(self, value): self._value = value.encode('base64')
+ value = property(get_value, set_value)
+
class Model(object):
""" Manages the global state of the metadata model index. This is
@@ -259,7 +271,7 @@ class Model(object):
Column('id', Integer, Sequence('property_id_seq'), primary_key=True),
Column('content_id', Integer, ForeignKey('content.id')),
Column('key', Unicode, ),
- Column('value', PickleType, ),
+ Column('value', Unicode, ),
Column('type', Unicode, ),
# unique key to content mapping
UniqueConstraint('content_id', 'key',
@@ -325,7 +337,7 @@ class Model(object):
self.addPropertyType(DateProperty, 'date')
self.addPropertyType(NumberProperty, 'number')
self.addPropertyType(TextProperty, 'text')
-
+ self.addPropertyType(BinaryProperty, 'binary')
@@ -355,3 +367,6 @@ class Model(object):
polymorphic_identity=typename,
properties=properties
)
+
+ registerPropertyType(typename, PropertyClass)
+
diff --git a/src/olpc/datastore/query.py b/src/olpc/datastore/query.py
index 03d24de..c2e534d 100644
--- a/src/olpc/datastore/query.py
+++ b/src/olpc/datastore/query.py
@@ -16,7 +16,7 @@ from datetime import datetime
from lemur.xapian.sei import DocumentStore, DocumentPiece, SortableValue
from olpc.datastore.converter import converter
from olpc.datastore.model import DateProperty, TextProperty
-from olpc.datastore.model import Model, Content, Property
+from olpc.datastore.model import Model, Content, Property, propertyByKind
from olpc.datastore.utils import create_uid
from sqlalchemy import create_engine, BoundMetaData
@@ -35,7 +35,14 @@ class SugarDomain(object):
"""resolves property names to the factory type that supports
them in the model
"""
- return {
+ # key may be a two part form directly indicating the property
+ # type
+ if ':' in key:
+ key, kind = key.split(':', 1)
+ # now resolve the kind to a property class
+ return key, propertyByKind(kind)
+
+ return key, {
'ctime' : DateProperty,
'mtime' : DateProperty,
'author' : Property,
@@ -45,10 +52,10 @@ class SugarDomain(object):
}.get(key, Property)
def propertyFactory(self, key, value='', dict=None):
- k = self.kind_by_key(key)
- p = k(key, value)
+ key, kind = self.kind_by_key(key)
+ p = kind(key, value)
if dict is not None: dict[key] = p
- return k
+ return kind
def _automaticProperties(self):
d = {}
@@ -74,7 +81,7 @@ class SugarDomain(object):
# convert it into a dict of Property objects
d = {}
for k,v in props.iteritems():
- kind = self.kind_by_key(k)
+ k, kind = self.kind_by_key(k)
p = kind(k, v)
d[k] = p
if creating and include_defaults:
@@ -246,6 +253,14 @@ class QueryManager(SugarDomain):
content_id=c.id)
+ def get_uniquevaluesfor(self, propertyname):
+ properties = self.model.tables['properties']
+ return [r[0] for r in select([properties.c.value],
+ properties.c.key==propertyname,
+ distinct=True).execute().fetchall()]
+
+
+
def delete(self, content_or_uid):
c = self._resolve(content_or_uid)
s = self.model.session