#
##############################################################################
-import cPickle
+import msgpack
class Cursor(object):
def __init__(self, collection, spec=None, fields=None, **kwargs):
if spec and not type(spec) is dict:
raise Exception("spec must be an instance of dict")
+ self.Query = collection.database.connection.Query
+ self.Field = collection.database.connection.Field
+ self.Table = collection.database.connection.Table
+ self.Constraint = collection.database.connection.Constraint
+ self.Literal = collection.database.connection.Literal
+
self.collection = collection
self.spec = spec
if self.collection.exists():
return res_fields
def _get_cursor(self):
- query = {}
- table_id = '%s$_id' % self.collection.table_name
+ table_id = self.Table(self.collection.database.db_name, '%s$_id' % self.collection.table_name)
- query['select'] = [(table_id, 'id')]
+ fields = [self.Field(table_id, 'value')]
for f in filter(lambda x: x != '_id', self.fields):
- table_f = '%s$%s' % (self.collection.table_name, f)
- q = self._get_cursor_field(table_id, table_f)
- query['select'].append(q)
+ fields.append(self._get_cursor_field(f))
- query['from'] = [table_id]
+ tables = [table_id]
+ constraints = [self.Constraint('=', self.Field(table_id, 'name'), self.Literal('_id'))]
if self.spec:
- query['where'] = []
for k, v in self.spec.iteritems():
- table_f = '%s$%s' % (self.collection.table_name, k)
- field_q = self._get_cursor_field(table_id, table_f)
- query['where'].append((field_q, '=', v))
+ constraints.append(self._get_cursor_constraint(k, v))
+
+ query = self.Query(fields, tables, constraints)
+ return self.collection.database.connection._get_cursor(query)
+
+ def _get_cursor_field(self, field_name):
+ table_id = self.Table(self.collection.database.db_name, '%s$_id' % self.collection.table_name)
+ table_field = self.Table(self.collection.database.db_name, '%s$%s' % (self.collection.table_name, field_name.split(".")[0]))
+
+ fields = [self.Field(table_field, 'value')]
+ tables = [table_field]
+ constraints = [
+ self.Constraint('=', self.Field(table_field, 'id'), self.Field(table_id, 'id')),
+ self.Constraint('=', self.Field(table_field, 'name'), self.Literal(field_name)),
+ ]
+ return self.Query(fields, tables, constraints)
+
+ def _get_cursor_constraint(self, field_name, field_value):
+ table_id = self.Table(self.collection.database.db_name, '%s$_id' % self.collection.table_name)
+ table_field = self.Table(self.collection.database.db_name, '%s$%s' % (self.collection.table_name, field_name.split(".")[0]))
+
+ if type(field_value) in (int, float):
+ field_type = 'number'
+ else:
+ field_type = 'value'
+ field_value = msgpack.dumps(field_value)
- return self.collection.database.connection._get_cursor(self.collection.database.db_name, query)
+ fields = [self.Field(table_field, 'id')]
+ tables = [table_field]
+ constraints = [
+ self.Constraint('or', self.Constraint('=', self.Field(table_field, 'name'), self.Literal(field_name)),
+ self.Constraint('starts', self.Field(table_field, 'name'), self.Literal('%s..' % field_name))),
+ self.Constraint('=', self.Field(table_field, field_type), self.Literal(field_value)),
+ ]
- def _get_cursor_field(self, table_id, table_field):
- return {
- 'select': [(table_field, 'value')],
- 'from': [table_field],
- 'where': [((table_field, 'id'), '=', (table_id, 'id'))],
- }
+ return self.Constraint('in', self.Field(table_id, 'id'), self.Query(fields, tables, constraints))
def next(self):
if self.cursor is None:
else:
document = {}
if '_id' in self.fields:
- document['_id'] = res[0]
+ document['_id'] = msgpack.loads(res[0])
fields_without_id = filter(lambda x: x != '_id', self.fields)
for i in xrange(len(fields_without_id)):
if not res[i + 1] is None:
- document[fields_without_id[i]] = cPickle.loads(res[i + 1])
+ document[fields_without_id[i]] = msgpack.loads(res[i + 1])
return document
else:
return None