]> git.jsancho.org Git - mojodb.git/blobdiff - cursor.py
New database scheme, storing key name inside tables for improving searching
[mojodb.git] / cursor.py
index e07f237e792f0da9ab0005ab2a3bd327faea930a..6246872c35ab3c66c2d1d5c32c949deb22565864 100644 (file)
--- 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: