def _process(self): self._classes = [] self._props = [] for item in self.select: info = classInfo(item) keys = sorted(info.attributes.values()) self._props.extend(keys) self._classes.append(item)
def test_table(self): """ You can get the table a class maps to. """ class Foo(object): __sql_table__ = 'foo' info = classInfo(Foo) self.assertEqual(info.table, 'foo')
def test_primary(self): """ You can find primary keys """ class Foo(object): a = Property(primary=True) b = Property() info = classInfo(Foo) self.assertEqual(info.primaries, [Foo.a])
def test_object(self): """ You can get the class info from an instance. """ class Foo(object): __sql_table__ = 'foo' a = Property(primary=True) foo = Foo() info = classInfo(foo) self.assertEqual(info.table, 'foo') self.assertEqual(info.primaries, [Foo.a])
def test_multiPrimary(self): """ You can find multiple primary keys """ class Foo(object): a = Property(primary=True) b = Property(primary=True) c = Property() d = Property(primary=True) info = classInfo(Foo) self.assertEqual(set(info.primaries), set([Foo.a, Foo.b, Foo.d]))
def test_properties(self): """ You can list the properties on a class """ class Foo(object): a = Property('foo') b = Property() class Bar(object): c = Property() a = Property() info = classInfo(Foo) self.assertEqual(info.columns['foo'], [Foo.a]) self.assertEqual(info.columns['b'], [Foo.b]) self.assertEqual(info.attributes['a'], Foo.a) self.assertEqual(info.attributes['b'], Foo.b) info = classInfo(Bar) self.assertEqual(info.columns['c'], [Bar.c]) self.assertEqual(info.columns['a'], [Bar.a]) self.assertEqual(info.attributes['c'], Bar.c) self.assertEqual(info.attributes['a'], Bar.a)
def insert(self, cursor, obj): """ Insert a row into the database. This function expects to be run in an asynchronous interaction. """ info = objectInfo(obj) cls_info = classInfo(obj) changed = info.changed() # insert insert = [] insert_args = [] if not changed: # no changes insert = ['INSERT INTO %s DEFAULT VALUES' % (cls_info.table,)] else: # changes columns = [] for prop in changed: columns.append(prop.column_name) value = toDB.convert(prop.__class__, prop.toDatabase(obj)) insert_args.append(value) value_placeholders = ['?'] * len(columns) insert = ['INSERT INTO %s (%s) VALUES (%s)' % (cls_info.table, ','.join(columns), ','.join(value_placeholders))] # returning columns = cls_info.columns.keys() returning = ['RETURNING %s' % (','.join(columns),)] sql = ' '.join(insert + returning) args = tuple(insert_args) d = cursor.execute(sql, args) d.addCallback(lambda _: cursor.fetchone()) d.addCallback(self._updateObject, obj) return d
def insert(self, cursor, obj): """ Insert a row into the database. This function expects to be run in an asynchronous interaction. """ info = objectInfo(obj) cls_info = classInfo(obj) changed = info.changed() # insert insert = '' insert_args = [] if not changed: # no changes insert = 'INSERT INTO %s DEFAULT VALUES' % (cls_info.table,) else: # changes columns = [] for prop in changed: columns.append(prop.column_name) value = self.toDB.convert(prop.__class__, prop.toDatabase(obj)) insert_args.append(value) value_placeholders = ['?'] * len(columns) insert = 'INSERT INTO %s (%s) VALUES (%s)' % (cls_info.table, ','.join(columns), ','.join(value_placeholders)) # select columns = cls_info.columns.keys() select = 'SELECT %s FROM %s WHERE rowid=?' % (','.join(columns), cls_info.table) d = cursor.execute(insert, tuple(insert_args)) d.addCallback(lambda _: cursor.lastRowId()) d.addCallback(lambda rowid: cursor.execute(select, (rowid,))) d.addCallback(lambda _: cursor.fetchone()) d.addCallback(self._updateObject, obj) return d
def compile_Join(x, state): table = classInfo(x.cls).table alias = state.tableAlias(x.cls) on_sql, on_args = state.compile(x.on) return ('JOIN %s AS %s ON %s' % (table, alias, on_sql), on_args)
def compile_Table(table, state): info = classInfo(table.cls) return '%s AS %s' % (info.table, state.tableAlias(table.cls)), ()