X-Git-Url: https://git.jsancho.org/?p=mojodb.git;a=blobdiff_plain;f=cursor.py;fp=cursor.py;h=6246872c35ab3c66c2d1d5c32c949deb22565864;hp=e07f237e792f0da9ab0005ab2a3bd327faea930a;hb=aa509ddc8574e0a5220c94a2b72f4d5a798d6e8a;hpb=2c1872fd5004c8464e146081b61783de47b87e2d diff --git a/cursor.py b/cursor.py index e07f237..6246872 100644 --- a/cursor.py +++ b/cursor.py @@ -26,6 +26,12 @@ class Cursor(object): 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(): @@ -74,41 +80,53 @@ class Cursor(object): 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, 'value')] + 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) - if type(v) in (int, float): - field_name = 'number' - field_v = v - else: - field_name = 'value' - field_v = msgpack.dumps(v) - if k == '_id': - field_q = (table_id, field_name) - else: - field_q = self._get_cursor_field(table_id, table_f, field_name=field_name) - query['where'].append((field_q, '=', field_v)) - - return self.collection.database.connection._get_cursor(self.collection.database.db_name, query) - - def _get_cursor_field(self, table_id, table_field, field_name='value'): - return { - 'select': [(table_field, field_name)], - 'from': [table_field], - 'where': [((table_field, 'id'), '=', (table_id, 'id'))], - } + 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) + + 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)), + ] + + return self.Constraint('in', self.Field(table_id, 'id'), self.Query(fields, tables, constraints)) def next(self): if self.cursor is None: