Author: phd
Date: 2007-01-09 09:30:12 -0700 (Tue, 09 Jan 2007)
New Revision: 2181
Modified:
home/phd/SQLObject/paramstyles/sqlobject/main.py
home/phd/SQLObject/paramstyles/sqlobject/versioning/__init__.py
home/phd/SQLObject/paramstyles/sqlobject/versioning/test/test_version.py
Log:
Merged patches from the revisions 2171:2180 from the trunk
Modified: home/phd/SQLObject/paramstyles/sqlobject/main.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/main.py 2007-01-09 16:28:16 UTC (rev 2180)
+++ home/phd/SQLObject/paramstyles/sqlobject/main.py 2007-01-09 16:30:12 UTC (rev 2181)
@@ -787,10 +787,6 @@
if connection and not hasattr(cls, '_connection'):
cls.setConnection(connection)
- # Now the class is in an essentially OK-state, so we can
- # set up any magic attributes:
- declarative.setup_attributes(cls, new_attrs)
-
# We have to check if there are columns in the inherited
# _columns where the attribute has been set to None in this
# class. If so, then we need to remove that column from
@@ -806,6 +802,10 @@
for column in implicitColumns:
cls.sqlmeta.addColumn(column)
+ # Now the class is in an essentially OK-state, so we can
+ # set up any magic attributes:
+ declarative.setup_attributes(cls, new_attrs)
+
if cls.sqlmeta.fromDatabase:
cls.sqlmeta.addColumnsFromDatabase()
Modified: home/phd/SQLObject/paramstyles/sqlobject/versioning/__init__.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/versioning/__init__.py 2007-01-09 16:28:16 UTC (rev 2180)
+++ home/phd/SQLObject/paramstyles/sqlobject/versioning/__init__.py 2007-01-09 16:30:12 UTC (rev 2181)
@@ -9,10 +9,36 @@
del values['dateArchived']
self.masterClass.get(self.masterID).set(**values)
+ def nextVersion(self):
+ version = self.select(AND(self.q.masterID == self.masterID, self.q.id > self.id), limit=1, orderBy=self.q.id)
+ if version.count():
+ return version[0]
+ else:
+ return self.master
+
+ def getChangedFields(self):
+ next = self.nextVersion()
+ columns = self.__class__.sqlmeta.columns
+ fields = []
+ for column in columns:
+ if column not in ["dateArchived", "id", "masterID"]:
+ if getattr(self, column) != getattr(next, column):
+ fields.append(column.title())
+
+ return fields
+
+ def select(cls, clause=None, *args, **kw):
+ if not getattr(cls, '_connection', None):
+ cls._connection = cls.masterClass._connection
+ return super(Version, cls).select(clause, *args, **kw)
+ select = classmethod(select)
+
def getColumns(columns, cls):
for column, defi in cls.sqlmeta.columnDefinitions.items():
- columns[column] = defi.__class__()
-
+ if column.endswith("ID") and isinstance(defi, ForeignKey):
+ column = column[:-2]
+ columns[column] = defi.__class__(**defi._kw)
+
#ascend heirarchy
if cls.sqlmeta.parentClass:
getColumns(columns, cls.sqlmeta.parentClass)
@@ -21,29 +47,30 @@
class Versioning(object):
def __init__(self):
pass
+
def __addtoclass__(self, soClass, name):
self.name = name
self.soClass = soClass
- self.versionClass = None
+
+ attrs = {'dateArchived': DateTimeCol(default=datetime.now),
+ 'master': ForeignKey(self.soClass.__name__),
+ 'masterClass' : self.soClass,
+ }
+
+ getColumns (attrs, self.soClass)
+
+ self.versionClass = type(self.soClass.__name__+'Versions',
+ (Version,),
+ attrs)
+
events.listen(self.createTable,
soClass, events.CreateTableSignal)
events.listen(self.rowUpdate, soClass,
events.RowUpdateSignal)
def createVersionTable(self, cls, conn):
- columns = {'dateArchived': DateTimeCol(default=datetime.now),
- 'masterID': IntCol(),
- 'masterClass' : self.soClass,
- }
+ self.versionClass.createTable(ifNotExists=True, connection=conn)
- getColumns (columns, self.soClass)
-
- self.versionClass = type(self.soClass.__name__+'Versions',
- (Version,),
- columns)
-
- self.versionClass.createTable(connection=conn)
-
def createTable(self, soClass, connection, extra_sql, post_funcs):
assert soClass is self.soClass
post_funcs.append(self.createVersionTable)
Modified: home/phd/SQLObject/paramstyles/sqlobject/versioning/test/test_version.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/versioning/test/test_version.py 2007-01-09 16:28:16 UTC (rev 2180)
+++ home/phd/SQLObject/paramstyles/sqlobject/versioning/test/test_version.py 2007-01-09 16:30:12 UTC (rev 2181)
@@ -1,43 +1,55 @@
from py.test import raises
from sqlobject import *
-from sqlobject.tests.dbtest import *
+try:
+ sorted
+except NameError:
+ # For Python 2.2 and 2.3:
+ from sqlobject.events import sorted
from sqlobject.inheritance import InheritableSQLObject
from sqlobject.versioning import Versioning
+from sqlobject.tests.dbtest import *
from datetime import datetime
-def setup():
- setupClass(MyClass)
- setupClass(Base)
- setupClass(Child)
- setupClass(Government)
- setupClass(Monarchy)
- setupClass(VChild)
-
class MyClass(SQLObject):
- name = StringCol()
- versions = Versioning()
+ name = StringCol()
+ versions = Versioning()
class Base(InheritableSQLObject):
- name = StringCol()
- versions = Versioning()
+ name = StringCol()
+ value = IntCol(default=0)
+ versions = Versioning()
class Child(Base):
- toy = StringCol()
+ toy = StringCol()
-
class Government(InheritableSQLObject):
- name = StringCol()
+ name = StringCol()
class Monarchy(Government):
- monarch = StringCol()
- versions = Versioning()
+ monarch = StringCol()
+ versions = Versioning()
class VChild(Base):
weapon = StringCol()
versions = Versioning()
+class HasForeign(SQLObject):
+ foreign = ForeignKey("Base")
+ versions = Versioning()
+
+def setup():
+ for cls in [MyClass, Base, Child, Government, Monarchy, VChild, HasForeign]:
+ if hasattr(cls, 'versions') and hasattr(cls, "_connection") and \
+ cls._connection.tableExists(cls.sqlmeta.table):
+ setupClass(cls.versions.versionClass)
+ setupClass(cls)
+ if hasattr(cls, 'versions'):
+ setupClass(cls.versions.versionClass)
+ for version in cls.versions.versionClass.select():
+ version.destroySelf()
+
def test_versioning():
#the simple case
@@ -95,3 +107,28 @@
monarchy.versions[0].restore()
assert monarchy.name == "USA"
assert monarchy.monarch == "Emperor Norton I"
+
+def test_next():
+ setup()
+ base = Base(name='first', value=1)
+ base.set(name='second')
+ base.set(name='third', value=2)
+ version = base.versions[0]
+ assert version.nextVersion() == base.versions[1]
+ assert version.nextVersion().nextVersion() == base
+
+def test_get_changed():
+ setup()
+ base = Base(name='first', value=1)
+ base.set(name='second')
+ base.set(name='third', value=2)
+ assert base.versions[0].getChangedFields() == ['Name']
+ assert sorted(base.versions[1].getChangedFields()) == ['Name', 'Value']
+
+def test_foreign_keys():
+ setup()
+ base1 = Base(name='first', value=1)
+ base2 = Base(name='first', value=1)
+ has_foreign = HasForeign(foreign = base1)
+ has_foreign.foreign = base2
+ assert has_foreign.versions[0].foreign == base1
|