sqlobject-cvs Mailing List for SQLObject (Page 67)
SQLObject is a Python ORM.
Brought to you by:
ianbicking,
phd
You can subscribe to this list here.
2003 |
Jan
|
Feb
|
Mar
(9) |
Apr
(74) |
May
(29) |
Jun
(16) |
Jul
(28) |
Aug
(10) |
Sep
(57) |
Oct
(9) |
Nov
(29) |
Dec
(12) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
(7) |
Feb
(14) |
Mar
(6) |
Apr
(3) |
May
(12) |
Jun
(34) |
Jul
(9) |
Aug
(29) |
Sep
(22) |
Oct
(2) |
Nov
(15) |
Dec
(52) |
2005 |
Jan
(47) |
Feb
(78) |
Mar
(14) |
Apr
(35) |
May
(33) |
Jun
(16) |
Jul
(26) |
Aug
(63) |
Sep
(40) |
Oct
(96) |
Nov
(96) |
Dec
(123) |
2006 |
Jan
(159) |
Feb
(144) |
Mar
(64) |
Apr
(31) |
May
(88) |
Jun
(48) |
Jul
(16) |
Aug
(64) |
Sep
(87) |
Oct
(92) |
Nov
(56) |
Dec
(76) |
2007 |
Jan
(94) |
Feb
(103) |
Mar
(126) |
Apr
(123) |
May
(85) |
Jun
(11) |
Jul
(130) |
Aug
(47) |
Sep
(65) |
Oct
(70) |
Nov
(12) |
Dec
(11) |
2008 |
Jan
(30) |
Feb
(55) |
Mar
(88) |
Apr
(20) |
May
(50) |
Jun
|
Jul
(38) |
Aug
(1) |
Sep
(9) |
Oct
(5) |
Nov
(6) |
Dec
(39) |
2009 |
Jan
(8) |
Feb
(16) |
Mar
(3) |
Apr
(33) |
May
(44) |
Jun
(1) |
Jul
(10) |
Aug
(33) |
Sep
(74) |
Oct
(22) |
Nov
|
Dec
(15) |
2010 |
Jan
(28) |
Feb
(22) |
Mar
(46) |
Apr
(29) |
May
(1) |
Jun
(1) |
Jul
(27) |
Aug
(8) |
Sep
(5) |
Oct
(33) |
Nov
(24) |
Dec
(41) |
2011 |
Jan
(4) |
Feb
(12) |
Mar
(35) |
Apr
(29) |
May
(19) |
Jun
(16) |
Jul
(32) |
Aug
(25) |
Sep
(5) |
Oct
(11) |
Nov
(21) |
Dec
(12) |
2012 |
Jan
(3) |
Feb
(4) |
Mar
(20) |
Apr
(4) |
May
(25) |
Jun
(13) |
Jul
|
Aug
|
Sep
(2) |
Oct
(25) |
Nov
(9) |
Dec
(1) |
2013 |
Jan
(6) |
Feb
(8) |
Mar
|
Apr
(10) |
May
(31) |
Jun
(7) |
Jul
(18) |
Aug
(33) |
Sep
(4) |
Oct
(16) |
Nov
|
Dec
(27) |
2014 |
Jan
(2) |
Feb
|
Mar
|
Apr
(11) |
May
(39) |
Jun
(8) |
Jul
(11) |
Aug
(4) |
Sep
|
Oct
(27) |
Nov
|
Dec
(71) |
2015 |
Jan
(17) |
Feb
(47) |
Mar
(33) |
Apr
|
May
|
Jun
(9) |
Jul
(7) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(8) |
2016 |
Jan
(4) |
Feb
(4) |
Mar
|
Apr
|
May
(12) |
Jun
(7) |
Jul
(9) |
Aug
(31) |
Sep
(8) |
Oct
(3) |
Nov
(15) |
Dec
(1) |
2017 |
Jan
(13) |
Feb
(7) |
Mar
(14) |
Apr
(8) |
May
(10) |
Jun
(4) |
Jul
(2) |
Aug
(1) |
Sep
|
Oct
(8) |
Nov
(4) |
Dec
(5) |
2018 |
Jan
(2) |
Feb
(8) |
Mar
|
Apr
(4) |
May
|
Jun
(6) |
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
(1) |
Dec
|
2019 |
Jan
(1) |
Feb
(16) |
Mar
(1) |
Apr
(3) |
May
(5) |
Jun
(1) |
Jul
|
Aug
|
Sep
(2) |
Oct
|
Nov
(1) |
Dec
(3) |
2020 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
(1) |
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
(2) |
Nov
|
Dec
(2) |
2021 |
Jan
|
Feb
(2) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
(1) |
Dec
|
2022 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(6) |
Oct
(1) |
Nov
(1) |
Dec
(4) |
2023 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
(3) |
Sep
(2) |
Oct
(2) |
Nov
(4) |
Dec
|
2024 |
Jan
|
Feb
(2) |
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
(9) |
2025 |
Jan
|
Feb
(4) |
Mar
(2) |
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
|
From: <sub...@co...> - 2008-05-22 10:53:13
|
Author: phd Date: 2008-05-22 04:53:09 -0600 (Thu, 22 May 2008) New Revision: 3462 Modified: SQLObject/trunk/docs/News.txt Log: Small Features Modified: SQLObject/trunk/docs/News.txt =================================================================== --- SQLObject/trunk/docs/News.txt 2008-05-22 10:51:17 UTC (rev 3461) +++ SQLObject/trunk/docs/News.txt 2008-05-22 10:53:09 UTC (rev 3462) @@ -117,15 +117,21 @@ SQLObject 0.9.7 =============== +Small Features +-------------- + * Use VARCHAR(MAX) and VARBINARY(MAX) for MSSQL >= 9.0. +* Run post_funcs after RowDestroySignal. + +Bug Fixes +--------- + * Fixed a minor bug in Set column. * A bug fixed for RowCreatedSignal together with InheritableSQLObject: run post_funcs after the entire hierarchy has been created. -* Run post_funcs after RowDestroySignal. - * Aggregate functions now honors 'distinct'. SQLObject 0.9.6 |
From: <sub...@co...> - 2008-05-22 10:51:23
|
Author: phd Date: 2008-05-22 04:51:17 -0600 (Thu, 22 May 2008) New Revision: 3461 Modified: SQLObject/branches/0.10/docs/News.txt Log: Small Features Modified: SQLObject/branches/0.10/docs/News.txt =================================================================== --- SQLObject/branches/0.10/docs/News.txt 2008-05-22 10:49:22 UTC (rev 3460) +++ SQLObject/branches/0.10/docs/News.txt 2008-05-22 10:51:17 UTC (rev 3461) @@ -94,15 +94,21 @@ SQLObject 0.9.7 =============== +Small Features +-------------- + * Use VARCHAR(MAX) and VARBINARY(MAX) for MSSQL >= 9.0. +* Run post_funcs after RowDestroySignal. + +Bug Fixes +--------- + * Fixed a minor bug in Set column. * A bug fixed for RowCreatedSignal together with InheritableSQLObject: run post_funcs after the entire hierarchy has been created. -* Run post_funcs after RowDestroySignal. - * Aggregate functions now honors 'distinct'. SQLObject 0.9.6 |
From: <sub...@co...> - 2008-05-22 10:49:27
|
Author: phd Date: 2008-05-22 04:49:22 -0600 (Thu, 22 May 2008) New Revision: 3460 Modified: SQLObject/branches/0.9/docs/News.txt Log: Small Features Modified: SQLObject/branches/0.9/docs/News.txt =================================================================== --- SQLObject/branches/0.9/docs/News.txt 2008-05-22 10:44:38 UTC (rev 3459) +++ SQLObject/branches/0.9/docs/News.txt 2008-05-22 10:49:22 UTC (rev 3460) @@ -10,15 +10,21 @@ SQLObject 0.9.7 =============== +Small Features +-------------- + * Use VARCHAR(MAX) and VARBINARY(MAX) for MSSQL >= 9.0. +* Run post_funcs after RowDestroySignal. + +Bug Fixes +--------- + * Fixed a minor bug in Set column. * A bug fixed for RowCreatedSignal together with InheritableSQLObject: run post_funcs after the entire hierarchy has been created. -* Run post_funcs after RowDestroySignal. - * Aggregate functions now honors 'distinct'. SQLObject 0.9.6 |
From: SourceForge.net <no...@so...> - 2008-05-22 10:45:20
|
Bugs item #1969417, was opened at 2008-05-22 12:36 Message generated for change (Comment added) made by phd You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1969417&group_id=74338 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None >Status: Closed >Resolution: Fixed Priority: 5 Private: No Submitted By: Nobody/Anonymous (nobody) >Assigned to: Oleg Broytmann (phd) Summary: typo in variable name in col.py Initial Comment: in: SQLObject-0.10.0b1-py2.5.egg/sqlobject/col.py line 611: if self.zerofill: _ret = _reg + " ZEROFILL" "_reg" should be replaced by "_ret" submitted by: ori...@gm... ---------------------------------------------------------------------- >Comment By: Oleg Broytmann (phd) Date: 2008-05-22 14:45 Message: Logged In: YES user_id=4799 Originator: NO Fixed in the revisions 3457-3459 (branched 0.9, 0.10 and the trunk). Thank you! ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1969417&group_id=74338 |
From: <sub...@co...> - 2008-05-22 10:44:42
|
Author: phd Date: 2008-05-22 04:44:38 -0600 (Thu, 22 May 2008) New Revision: 3459 Modified: SQLObject/trunk/sqlobject/col.py Log: Fixed a bug N 1969417: typo in variable name. Modified: SQLObject/trunk/sqlobject/col.py =================================================================== --- SQLObject/trunk/sqlobject/col.py 2008-05-22 10:43:49 UTC (rev 3458) +++ SQLObject/trunk/sqlobject/col.py 2008-05-22 10:44:38 UTC (rev 3459) @@ -612,7 +612,7 @@ if self.unsigned: _ret = _ret + " UNSIGNED" if self.zerofill: - _ret = _reg + " ZEROFILL" + _ret = _ret + " ZEROFILL" return _ret def _sqlType(self): |
From: <sub...@co...> - 2008-05-22 10:43:54
|
Author: phd Date: 2008-05-22 04:43:49 -0600 (Thu, 22 May 2008) New Revision: 3458 Modified: SQLObject/branches/0.10/sqlobject/col.py Log: Fixed a bug N 1969417: typo in variable name. Modified: SQLObject/branches/0.10/sqlobject/col.py =================================================================== --- SQLObject/branches/0.10/sqlobject/col.py 2008-05-22 10:42:12 UTC (rev 3457) +++ SQLObject/branches/0.10/sqlobject/col.py 2008-05-22 10:43:49 UTC (rev 3458) @@ -612,7 +612,7 @@ if self.unsigned: _ret = _ret + " UNSIGNED" if self.zerofill: - _ret = _reg + " ZEROFILL" + _ret = _ret + " ZEROFILL" return _ret def _sqlType(self): |
From: <sub...@co...> - 2008-05-22 10:42:19
|
Author: phd Date: 2008-05-22 04:42:12 -0600 (Thu, 22 May 2008) New Revision: 3457 Modified: SQLObject/branches/0.9/sqlobject/col.py Log: Fixed a bug N 1969417: typo in variable name. Modified: SQLObject/branches/0.9/sqlobject/col.py =================================================================== --- SQLObject/branches/0.9/sqlobject/col.py 2008-05-21 14:54:05 UTC (rev 3456) +++ SQLObject/branches/0.9/sqlobject/col.py 2008-05-22 10:42:12 UTC (rev 3457) @@ -627,7 +627,7 @@ if self.unsigned: _ret = _ret + " UNSIGNED" if self.zerofill: - _ret = _reg + " ZEROFILL" + _ret = _ret + " ZEROFILL" return _ret def _sqlType(self): |
From: SourceForge.net <no...@so...> - 2008-05-22 08:36:05
|
Bugs item #1969417, was opened at 2008-05-22 01:36 Message generated for change (Tracker Item Submitted) made by Item Submitter You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1969417&group_id=74338 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None Status: Open Resolution: None Priority: 5 Private: No Submitted By: Nobody/Anonymous (nobody) Assigned to: Nobody/Anonymous (nobody) Summary: typo in variable name in col.py Initial Comment: in: SQLObject-0.10.0b1-py2.5.egg/sqlobject/col.py line 611: if self.zerofill: _ret = _reg + " ZEROFILL" "_reg" should be replaced by "_ret" submitted by: ori...@gm... ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1969417&group_id=74338 |
From: <sub...@co...> - 2008-05-21 21:54:37
|
Author: phd Date: 2008-05-21 08:53:32 -0600 (Wed, 21 May 2008) New Revision: 3455 Modified: SQLObject/branches/0.10/docs/News.txt SQLObject/branches/0.10/sqlobject/col.py SQLObject/branches/0.10/sqlobject/mssql/mssqlconnection.py Log: Use VARCHAR(MAX) and VARBINARY(MAX) for MSSQL >= 9.0. Modified: SQLObject/branches/0.10/docs/News.txt =================================================================== --- SQLObject/branches/0.10/docs/News.txt 2008-05-21 14:52:25 UTC (rev 3454) +++ SQLObject/branches/0.10/docs/News.txt 2008-05-21 14:53:32 UTC (rev 3455) @@ -94,6 +94,8 @@ SQLObject 0.9.7 =============== +* Use VARCHAR(MAX) and VARBINARY(MAX) for MSSQL >= 9.0. + * Fixed a minor bug in Set column. * A bug fixed for RowCreatedSignal together with InheritableSQLObject: Modified: SQLObject/branches/0.10/sqlobject/col.py =================================================================== --- SQLObject/branches/0.10/sqlobject/col.py 2008-05-21 14:52:25 UTC (rev 3454) +++ SQLObject/branches/0.10/sqlobject/col.py 2008-05-21 14:53:32 UTC (rev 3455) @@ -333,7 +333,8 @@ def sybaseCreateSQL(self): return ' '.join([self.dbName, self._sybaseType()] + self._extraSQL()) - def mssqlCreateSQL(self): + def mssqlCreateSQL(self, connection=None): + self.connection = connection return ' '.join([self.dbName, self._mssqlType()] + self._extraSQL()) def firebirdCreateSQL(self): @@ -478,7 +479,10 @@ if self.customSQLType is not None: return self.customSQLType if not self.length: - type = 'varchar(4000)' + if self.connection and self.connection.can_use_max_types: + type = 'VARCHAR(MAX)' + else: + type = 'varchar(4000)' elif self.varchar: type = 'VARCHAR(%i)' % self.length else: @@ -868,8 +872,8 @@ # @@: Code from above should be moved here return None - def mssqlCreateSQL(self): - sql = SOKeyCol.mssqlCreateSQL(self) + def mssqlCreateSQL(self, connection=None): + sql = SOKeyCol.mssqlCreateSQL(self, connection) other = findClass(self.foreignKey, self.soClass.sqlmeta.registry) tName = other.sqlmeta.table idName = other.sqlmeta.idName @@ -1405,7 +1409,10 @@ return 'BYTEA' def _mssqlType(self): - return "IMAGE" + if self.connection and self.connection.can_use_max_types: + return 'VARBINARY(MAX)' + else: + return "IMAGE" class BLOBCol(StringCol): baseClass = SOBLOBCol Modified: SQLObject/branches/0.10/sqlobject/mssql/mssqlconnection.py =================================================================== --- SQLObject/branches/0.10/sqlobject/mssql/mssqlconnection.py 2008-05-21 14:52:25 UTC (rev 3454) +++ SQLObject/branches/0.10/sqlobject/mssql/mssqlconnection.py 2008-05-21 14:53:32 UTC (rev 3455) @@ -158,7 +158,7 @@ return col.mssqlCreateReferenceConstraint() def createColumn(self, soClass, col): - return col.mssqlCreateSQL() + return col.mssqlCreateSQL(self) def createIDColumn(self, soClass): key_type = {int: "INT", str: "TEXT"}[soClass.sqlmeta.idType] @@ -180,7 +180,7 @@ def addColumn(self, tableName, column): self.query('ALTER TABLE %s ADD %s' % (tableName, - column.mssqlCreateSQL())) + column.mssqlCreateSQL(self))) def delColumn(self, sqlmeta, column): self.query('ALTER TABLE %s DROP COLUMN %s' % (tableName.table, column.dbName)) @@ -276,3 +276,21 @@ 'precision': scale} else: return col.Col, {} + + @property + def server_version(self): + try: + server_version = self.queryAll("SELECT SERVERPROPERTY('productversion')")[0][0] + server_version = server_version.split('.')[0] + server_version = int(server_version) + except: + server_version = None # unknown + self.server_version = server_version # cache it forever + return server_version + + @property + def can_use_max_types(self): + server_version = self.server_version + self.can_use_max_types = can_use_max_types = \ + (server_version is not None) and (server_version >= 9) + return can_use_max_types |
From: <sub...@co...> - 2008-05-21 19:17:28
|
Author: phd Date: 2008-05-21 08:54:05 -0600 (Wed, 21 May 2008) New Revision: 3456 Modified: SQLObject/trunk/docs/News.txt SQLObject/trunk/sqlobject/col.py SQLObject/trunk/sqlobject/mssql/mssqlconnection.py Log: Use VARCHAR(MAX) and VARBINARY(MAX) for MSSQL >= 9.0. Modified: SQLObject/trunk/docs/News.txt =================================================================== --- SQLObject/trunk/docs/News.txt 2008-05-21 14:53:32 UTC (rev 3455) +++ SQLObject/trunk/docs/News.txt 2008-05-21 14:54:05 UTC (rev 3456) @@ -117,6 +117,8 @@ SQLObject 0.9.7 =============== +* Use VARCHAR(MAX) and VARBINARY(MAX) for MSSQL >= 9.0. + * Fixed a minor bug in Set column. * A bug fixed for RowCreatedSignal together with InheritableSQLObject: Modified: SQLObject/trunk/sqlobject/col.py =================================================================== --- SQLObject/trunk/sqlobject/col.py 2008-05-21 14:53:32 UTC (rev 3455) +++ SQLObject/trunk/sqlobject/col.py 2008-05-21 14:54:05 UTC (rev 3456) @@ -333,7 +333,8 @@ def sybaseCreateSQL(self): return ' '.join([self.dbName, self._sybaseType()] + self._extraSQL()) - def mssqlCreateSQL(self): + def mssqlCreateSQL(self, connection=None): + self.connection = connection return ' '.join([self.dbName, self._mssqlType()] + self._extraSQL()) def firebirdCreateSQL(self): @@ -478,7 +479,10 @@ if self.customSQLType is not None: return self.customSQLType if not self.length: - type = 'varchar(4000)' + if self.connection and self.connection.can_use_max_types: + type = 'VARCHAR(MAX)' + else: + type = 'varchar(4000)' elif self.varchar: type = 'VARCHAR(%i)' % self.length else: @@ -868,8 +872,8 @@ # @@: Code from above should be moved here return None - def mssqlCreateSQL(self): - sql = SOKeyCol.mssqlCreateSQL(self) + def mssqlCreateSQL(self, connection=None): + sql = SOKeyCol.mssqlCreateSQL(self, connection) other = findClass(self.foreignKey, self.soClass.sqlmeta.registry) tName = other.sqlmeta.table idName = other.sqlmeta.idName @@ -1402,7 +1406,10 @@ return 'BYTEA' def _mssqlType(self): - return "IMAGE" + if self.connection and self.connection.can_use_max_types: + return 'VARBINARY(MAX)' + else: + return "IMAGE" class BLOBCol(StringCol): baseClass = SOBLOBCol Modified: SQLObject/trunk/sqlobject/mssql/mssqlconnection.py =================================================================== --- SQLObject/trunk/sqlobject/mssql/mssqlconnection.py 2008-05-21 14:53:32 UTC (rev 3455) +++ SQLObject/trunk/sqlobject/mssql/mssqlconnection.py 2008-05-21 14:54:05 UTC (rev 3456) @@ -158,7 +158,7 @@ return col.mssqlCreateReferenceConstraint() def createColumn(self, soClass, col): - return col.mssqlCreateSQL() + return col.mssqlCreateSQL(self) def createIDColumn(self, soClass): key_type = {int: "INT", str: "TEXT"}[soClass.sqlmeta.idType] @@ -180,7 +180,7 @@ def addColumn(self, tableName, column): self.query('ALTER TABLE %s ADD %s' % (tableName, - column.mssqlCreateSQL())) + column.mssqlCreateSQL(self))) def delColumn(self, sqlmeta, column): self.query('ALTER TABLE %s DROP COLUMN %s' % (tableName.table, column.dbName)) @@ -276,3 +276,21 @@ 'precision': scale} else: return col.Col, {} + + @property + def server_version(self): + try: + server_version = self.queryAll("SELECT SERVERPROPERTY('productversion')")[0][0] + server_version = server_version.split('.')[0] + server_version = int(server_version) + except: + server_version = None # unknown + self.server_version = server_version # cache it forever + return server_version + + @property + def can_use_max_types(self): + server_version = self.server_version + self.can_use_max_types = can_use_max_types = \ + (server_version is not None) and (server_version >= 9) + return can_use_max_types |
From: <sub...@co...> - 2008-05-21 14:52:41
|
Author: phd Date: 2008-05-21 08:52:25 -0600 (Wed, 21 May 2008) New Revision: 3454 Modified: SQLObject/branches/0.9/docs/News.txt SQLObject/branches/0.9/sqlobject/col.py SQLObject/branches/0.9/sqlobject/mssql/mssqlconnection.py Log: Use VARCHAR(MAX) and VARBINARY(MAX) for MSSQL >= 9.0. Modified: SQLObject/branches/0.9/docs/News.txt =================================================================== --- SQLObject/branches/0.9/docs/News.txt 2008-05-20 21:20:24 UTC (rev 3453) +++ SQLObject/branches/0.9/docs/News.txt 2008-05-21 14:52:25 UTC (rev 3454) @@ -10,6 +10,8 @@ SQLObject 0.9.7 =============== +* Use VARCHAR(MAX) and VARBINARY(MAX) for MSSQL >= 9.0. + * Fixed a minor bug in Set column. * A bug fixed for RowCreatedSignal together with InheritableSQLObject: Modified: SQLObject/branches/0.9/sqlobject/col.py =================================================================== --- SQLObject/branches/0.9/sqlobject/col.py 2008-05-20 21:20:24 UTC (rev 3453) +++ SQLObject/branches/0.9/sqlobject/col.py 2008-05-21 14:52:25 UTC (rev 3454) @@ -345,7 +345,8 @@ def sybaseCreateSQL(self): return ' '.join([self.dbName, self._sybaseType()] + self._extraSQL()) - def mssqlCreateSQL(self): + def mssqlCreateSQL(self, connection=None): + self.connection = connection return ' '.join([self.dbName, self._mssqlType()] + self._extraSQL()) def firebirdCreateSQL(self): @@ -490,7 +491,10 @@ if self.customSQLType is not None: return self.customSQLType if not self.length: - type = 'varchar(4000)' + if self.connection and self.connection.can_use_max_types: + type = 'VARCHAR(MAX)' + else: + type = 'varchar(4000)' elif self.varchar: type = 'VARCHAR(%i)' % self.length else: @@ -883,8 +887,8 @@ # @@: Code from above should be moved here return None - def mssqlCreateSQL(self): - sql = SOKeyCol.mssqlCreateSQL(self) + def mssqlCreateSQL(self, connection=None): + sql = SOKeyCol.mssqlCreateSQL(self, connection) other = findClass(self.foreignKey, self.soClass.sqlmeta.registry) tName = other.sqlmeta.table idName = other.sqlmeta.idName @@ -1423,7 +1427,10 @@ return 'BYTEA' def _mssqlType(self): - return "IMAGE" + if self.connection and self.connection.can_use_max_types: + return 'VARBINARY(MAX)' + else: + return "IMAGE" class BLOBCol(StringCol): baseClass = SOBLOBCol Modified: SQLObject/branches/0.9/sqlobject/mssql/mssqlconnection.py =================================================================== --- SQLObject/branches/0.9/sqlobject/mssql/mssqlconnection.py 2008-05-20 21:20:24 UTC (rev 3453) +++ SQLObject/branches/0.9/sqlobject/mssql/mssqlconnection.py 2008-05-21 14:52:25 UTC (rev 3454) @@ -157,7 +157,7 @@ return col.mssqlCreateReferenceConstraint() def createColumn(self, soClass, col): - return col.mssqlCreateSQL() + return col.mssqlCreateSQL(self) def createIDColumn(self, soClass): key_type = {int: "INT", str: "TEXT"}[soClass.sqlmeta.idType] @@ -179,7 +179,7 @@ def addColumn(self, tableName, column): self.query('ALTER TABLE %s ADD %s' % (tableName, - column.mssqlCreateSQL())) + column.mssqlCreateSQL(self))) def delColumn(self, sqlmeta, column): self.query('ALTER TABLE %s DROP COLUMN %s' % (tableName.table, column.dbName)) @@ -275,3 +275,21 @@ 'precision': scale} else: return col.Col, {} + + @property + def server_version(self): + try: + server_version = self.queryAll("SELECT SERVERPROPERTY('productversion')")[0][0] + server_version = server_version.split('.')[0] + server_version = int(server_version) + except: + server_version = None # unknown + self.server_version = server_version # cache it forever + return server_version + + @property + def can_use_max_types(self): + server_version = self.server_version + self.can_use_max_types = can_use_max_types = \ + (server_version is not None) and (server_version >= 9) + return can_use_max_types |
From: <sub...@co...> - 2008-05-20 14:18:35
|
Author: phd Date: 2008-05-20 08:18:29 -0600 (Tue, 20 May 2008) New Revision: 3446 Modified: SQLObject/trunk/docs/News.txt SQLObject/trunk/sqlobject/col.py Log: Fixed a minor bug in Set column. Modified: SQLObject/trunk/docs/News.txt =================================================================== --- SQLObject/trunk/docs/News.txt 2008-05-20 14:17:16 UTC (rev 3445) +++ SQLObject/trunk/docs/News.txt 2008-05-20 14:18:29 UTC (rev 3446) @@ -117,6 +117,8 @@ SQLObject 0.9.7 =============== +* Fixed a minor bug in Set column. + * A bug fixed for RowCreatedSignal together with InheritableSQLObject: run post_funcs after the entire hierarchy has been created. Modified: SQLObject/trunk/sqlobject/col.py =================================================================== --- SQLObject/trunk/sqlobject/col.py 2008-05-20 14:17:16 UTC (rev 3445) +++ SQLObject/trunk/sqlobject/col.py 2008-05-20 14:18:29 UTC (rev 3446) @@ -905,6 +905,21 @@ def __init__(self, foreignKey=None, **kw): super(ForeignKey, self).__init__(foreignKey=foreignKey, **kw) + +class EnumValidator(validators.Validator): + + def to_python(self, value, state): + if value in self.enumValues: + return value + elif not self.notNone and value is None: + return None + else: + raise validators.Invalid("expected a member of %r in the EnumCol '%s', got %r instead" % \ + (self.enumValues, self.name, value), value, state) + + def from_python(self, value, state): + return self.to_python(value, state) + class SOEnumCol(SOCol): def __init__(self, **kw): @@ -963,20 +978,6 @@ else: return len(obj) -class EnumValidator(validators.Validator): - - def to_python(self, value, state): - if value in self.enumValues: - return value - elif not self.notNone and value is None: - return None - else: - raise validators.Invalid("expected a member of %r in the EnumCol '%s', got %r instead" % \ - (self.enumValues, self.name, value), value, state) - - def from_python(self, value, state): - return self.to_python(value, state) - class EnumCol(Col): baseClass = SOEnumCol @@ -1012,7 +1013,7 @@ super(SOSetCol, self).createValidators() def _mysqlType(self): - return "SET(%s)" % ', '.join([sqlbuilder.sqlrepr(v, 'mysql') for v in self.enumValues]) + return "SET(%s)" % ', '.join([sqlbuilder.sqlrepr(v, 'mysql') for v in self.setValues]) class SetCol(Col): baseClass = SOSetCol |
From: <sub...@co...> - 2008-05-20 14:17:26
|
Author: phd Date: 2008-05-20 08:17:16 -0600 (Tue, 20 May 2008) New Revision: 3445 Modified: SQLObject/branches/0.10/docs/News.txt SQLObject/branches/0.10/sqlobject/col.py Log: Fixed a minor bug in Set column. Modified: SQLObject/branches/0.10/docs/News.txt =================================================================== --- SQLObject/branches/0.10/docs/News.txt 2008-05-20 14:14:49 UTC (rev 3444) +++ SQLObject/branches/0.10/docs/News.txt 2008-05-20 14:17:16 UTC (rev 3445) @@ -94,6 +94,8 @@ SQLObject 0.9.7 =============== +* Fixed a minor bug in Set column. + * A bug fixed for RowCreatedSignal together with InheritableSQLObject: run post_funcs after the entire hierarchy has been created. Modified: SQLObject/branches/0.10/sqlobject/col.py =================================================================== --- SQLObject/branches/0.10/sqlobject/col.py 2008-05-20 14:14:49 UTC (rev 3444) +++ SQLObject/branches/0.10/sqlobject/col.py 2008-05-20 14:17:16 UTC (rev 3445) @@ -905,6 +905,21 @@ def __init__(self, foreignKey=None, **kw): super(ForeignKey, self).__init__(foreignKey=foreignKey, **kw) + +class EnumValidator(validators.Validator): + + def to_python(self, value, state): + if value in self.enumValues: + return value + elif not self.notNone and value is None: + return None + else: + raise validators.Invalid("expected a member of %r in the EnumCol '%s', got %r instead" % \ + (self.enumValues, self.name, value), value, state) + + def from_python(self, value, state): + return self.to_python(value, state) + class SOEnumCol(SOCol): def __init__(self, **kw): @@ -963,20 +978,6 @@ else: return len(obj) -class EnumValidator(validators.Validator): - - def to_python(self, value, state): - if value in self.enumValues: - return value - elif not self.notNone and value is None: - return None - else: - raise validators.Invalid("expected a member of %r in the EnumCol '%s', got %r instead" % \ - (self.enumValues, self.name, value), value, state) - - def from_python(self, value, state): - return self.to_python(value, state) - class EnumCol(Col): baseClass = SOEnumCol @@ -1012,7 +1013,7 @@ super(SOSetCol, self).createValidators() def _mysqlType(self): - return "SET(%s)" % ', '.join([sqlbuilder.sqlrepr(v, 'mysql') for v in self.enumValues]) + return "SET(%s)" % ', '.join([sqlbuilder.sqlrepr(v, 'mysql') for v in self.setValues]) class SetCol(Col): baseClass = SOSetCol |
From: <sub...@co...> - 2008-05-20 14:14:54
|
Author: phd Date: 2008-05-20 08:14:49 -0600 (Tue, 20 May 2008) New Revision: 3444 Modified: SQLObject/branches/0.9/docs/News.txt SQLObject/branches/0.9/sqlobject/col.py Log: Fixed a minor bug in Set column. Modified: SQLObject/branches/0.9/docs/News.txt =================================================================== --- SQLObject/branches/0.9/docs/News.txt 2008-05-20 13:52:57 UTC (rev 3443) +++ SQLObject/branches/0.9/docs/News.txt 2008-05-20 14:14:49 UTC (rev 3444) @@ -10,6 +10,8 @@ SQLObject 0.9.7 =============== +* Fixed a minor bug in Set column. + * A bug fixed for RowCreatedSignal together with InheritableSQLObject: run post_funcs after the entire hierarchy has been created. Modified: SQLObject/branches/0.9/sqlobject/col.py =================================================================== --- SQLObject/branches/0.9/sqlobject/col.py 2008-05-20 13:52:57 UTC (rev 3443) +++ SQLObject/branches/0.9/sqlobject/col.py 2008-05-20 14:14:49 UTC (rev 3444) @@ -920,6 +920,21 @@ def __init__(self, foreignKey=None, **kw): super(ForeignKey, self).__init__(foreignKey=foreignKey, **kw) + +class EnumValidator(validators.Validator): + + def to_python(self, value, state): + if value in self.enumValues: + return value + elif not self.notNone and value is None: + return None + else: + raise validators.Invalid("expected a member of %r in the EnumCol '%s', got %r instead" % \ + (self.enumValues, self.name, value), value, state) + + def from_python(self, value, state): + return self.to_python(value, state) + class SOEnumCol(SOCol): def __init__(self, **kw): @@ -978,20 +993,6 @@ else: return len(obj) -class EnumValidator(validators.Validator): - - def to_python(self, value, state): - if value in self.enumValues: - return value - elif not self.notNone and value is None: - return None - else: - raise validators.Invalid("expected a member of %r in the EnumCol '%s', got %r instead" % \ - (self.enumValues, self.name, value), value, state) - - def from_python(self, value, state): - return self.to_python(value, state) - class EnumCol(Col): baseClass = SOEnumCol @@ -1027,7 +1028,7 @@ super(SOSetCol, self).createValidators() def _mysqlType(self): - return "SET(%s)" % ', '.join([sqlbuilder.sqlrepr(v, 'mysql') for v in self.enumValues]) + return "SET(%s)" % ', '.join([sqlbuilder.sqlrepr(v, 'mysql') for v in self.setValues]) class SetCol(Col): baseClass = SOSetCol |
From: <sub...@co...> - 2008-05-20 13:53:14
|
Author: phd Date: 2008-05-20 07:52:57 -0600 (Tue, 20 May 2008) New Revision: 3443 Modified: SQLObject/trunk/docs/DeveloperGuide.txt SQLObject/trunk/docs/News.txt SQLObject/trunk/sqlobject/events.py SQLObject/trunk/sqlobject/main.py SQLObject/trunk/sqlobject/tests/test_events.py Log: Merged patches by Diez B. Roggisch from revisions 3439-3440: A bug fixed for RowCreatedSignal together with InheritableSQLObject: run post_funcs after the entire hierarchy has been created; run post_funcs after RowDestroySignal. Modified: SQLObject/trunk/docs/DeveloperGuide.txt =================================================================== --- SQLObject/trunk/docs/DeveloperGuide.txt 2008-05-20 13:51:18 UTC (rev 3442) +++ SQLObject/trunk/docs/DeveloperGuide.txt 2008-05-20 13:52:57 UTC (rev 3443) @@ -185,7 +185,8 @@ tests. So please, write tests; everything at least needs to be exercised, even if the tests are absolutely complete. -Documentation ======= +Documentation +============= Please write documentation. Documentation should live in the docs/ directory. Pudge converts documentation from Restructured Text to Modified: SQLObject/trunk/docs/News.txt =================================================================== --- SQLObject/trunk/docs/News.txt 2008-05-20 13:51:18 UTC (rev 3442) +++ SQLObject/trunk/docs/News.txt 2008-05-20 13:52:57 UTC (rev 3443) @@ -117,6 +117,11 @@ SQLObject 0.9.7 =============== +* A bug fixed for RowCreatedSignal together with InheritableSQLObject: + run post_funcs after the entire hierarchy has been created. + +* Run post_funcs after RowDestroySignal. + * Aggregate functions now honors 'distinct'. SQLObject 0.9.6 Modified: SQLObject/trunk/sqlobject/events.py =================================================================== --- SQLObject/trunk/sqlobject/events.py 2008-05-20 13:51:18 UTC (rev 3442) +++ SQLObject/trunk/sqlobject/events.py 2008-05-20 13:52:57 UTC (rev 3443) @@ -97,16 +97,16 @@ class RowDestroySignal(Signal): """ Called before an instance is deleted. Sender is the instance's - class. Arguments are ``(instance, post_funcs)``. + class. Arguments are ``(instance, post_funcs)``. ``post_funcs`` is a list of callbacks, intended to have - functions appended to it, and are called without arguments. If + functions appended to it, and are called without arguments. If any of the post_funcs raises an exception, the deletion is only affected if this will prevent a commit. - You cannot cancel the delete, - but you can raise an exception (which will probably cancel the - delete, but also cause an uncaught exception if not expected). + You cannot cancel the delete, but you can raise an exception (which will + probably cancel the delete, but also cause an uncaught exception if not + expected). Note: this is not called when an instance is destroyed through garbage collection. Modified: SQLObject/trunk/sqlobject/main.py =================================================================== --- SQLObject/trunk/sqlobject/main.py 2008-05-20 13:51:18 UTC (rev 3442) +++ SQLObject/trunk/sqlobject/main.py 2008-05-20 13:52:57 UTC (rev 3443) @@ -41,11 +41,19 @@ import events from sresults import SelectResults from formencode import schema, compound +from util.threadinglocal import local import sys if sys.version_info[:3] < (2, 2, 0): raise ImportError, "SQLObject requires Python 2.2.0 or later" +""" +This thread-local storage is needed for RowCreatedSignals. It gathers +code-blocks to execute _after_ the whole hierachy of inherited SQLObjects +is created. See SQLObject._create +""" +_postponed_local = local() + NoDefault = sqlbuilder.NoDefault class SQLObjectNotFound(LookupError): pass @@ -1154,37 +1162,60 @@ return joinClass.get(id) def __init__(self, **kw): - # We shadow the sqlmeta class with an instance of sqlmeta - # that points to us (our sqlmeta buddy object; where the - # sqlmeta class is our class's buddy class) - self.sqlmeta = self.__class__.sqlmeta(self) - # The get() classmethod/constructor uses a magic keyword - # argument when it wants an empty object, fetched from the - # database. So we have nothing more to do in that case: - if kw.has_key('_SO_fetch_no_create'): - return + # If we are the outmost constructor of a hiearchy of + # InheritableSQLObjects (or simlpy _the_ constructor of a "normal" + # SQLObject), we create a threadlocal list that collects the + # RowCreatedSignals, and executes them if this very constructor is left + try: + _postponed_local.postponed_calls + postponed_created = False + except AttributeError: + _postponed_local.postponed_calls = [] + postponed_created = True - post_funcs = [] - self.sqlmeta.send(events.RowCreateSignal, kw, post_funcs) + try: + # We shadow the sqlmeta class with an instance of sqlmeta + # that points to us (our sqlmeta buddy object; where the + # sqlmeta class is our class's buddy class) + self.sqlmeta = self.__class__.sqlmeta(self) + # The get() classmethod/constructor uses a magic keyword + # argument when it wants an empty object, fetched from the + # database. So we have nothing more to do in that case: + if kw.has_key('_SO_fetch_no_create'): + return - # Pass the connection object along if we were given one. - if kw.has_key('connection'): - self._connection = kw['connection'] - self.sqlmeta._perConnection = True - del kw['connection'] + post_funcs = [] + self.sqlmeta.send(events.RowCreateSignal, kw, post_funcs) - self._SO_writeLock = threading.Lock() + # Pass the connection object along if we were given one. + if kw.has_key('connection'): + self._connection = kw['connection'] + self.sqlmeta._perConnection = True + del kw['connection'] - if kw.has_key('id'): - id = self.sqlmeta.idType(kw['id']) - del kw['id'] - else: - id = None + self._SO_writeLock = threading.Lock() - self._create(id, **kw) - for func in post_funcs: - func(self) + if kw.has_key('id'): + id = self.sqlmeta.idType(kw['id']) + del kw['id'] + else: + id = None + self._create(id, **kw) + + for func in post_funcs: + func(self) + finally: + # if we are the creator of the tl-storage, we + # have to exectute and under all circumstances + # remove the tl-storage + if postponed_created: + try: + for func in _postponed_local.postponed_calls: + func() + finally: + del _postponed_local.postponed_calls + def _create(self, id, **kw): self.sqlmeta._creating = True @@ -1248,9 +1279,11 @@ self._init(id) post_funcs = [] kw = dict([('class', self.__class__), ('id', id)]) - self.sqlmeta.send(events.RowCreatedSignal, kw, post_funcs) - for func in post_funcs: - func(self) + def _send_RowCreatedSignal(): + self.sqlmeta.send(events.RowCreatedSignal, kw, post_funcs) + for func in post_funcs: + func(self) + _postponed_local.postponed_calls.append(_send_RowCreatedSignal) def _SO_getID(self, obj): return getID(obj) Modified: SQLObject/trunk/sqlobject/tests/test_events.py =================================================================== --- SQLObject/trunk/sqlobject/tests/test_events.py 2008-05-20 13:51:18 UTC (rev 3442) +++ SQLObject/trunk/sqlobject/tests/test_events.py 2008-05-20 13:52:57 UTC (rev 3443) @@ -1,6 +1,7 @@ from sqlobject import * from sqlobject.tests.dbtest import * from sqlobject import events +from sqlobject.inheritance import InheritableSQLObject import sys class EventTester(SQLObject): @@ -32,7 +33,7 @@ assert watcher.log[0][1] == (EventTester,) assert isinstance(watcher.log[0][2], dict) assert isinstance(watcher.log[0][3], list) - + def test_row_create(): setupClass(EventTester) watcher = make_listen(events.RowCreateSignal) @@ -48,7 +49,7 @@ assert not watcher.log f.destroySelf() assert watcher.log == [(f, [])] - + def test_row_update(): setupClass(EventTester) watcher = make_listen(events.RowUpdateSignal) @@ -59,7 +60,7 @@ assert watcher.log == [ (f, {'name': 'bar2'}), (f, {'name': 'bar3'})] - + def test_add_column(): setupClass(EventTester) watcher = make_listen(events.AddColumnSignal) @@ -72,3 +73,30 @@ False, []) print zip(watcher.log[1], expect) assert watcher.log[1] == expect + + +class A(InheritableSQLObject): + a = IntCol() + +class B(A): + b = IntCol() + +class C(B): + c = IntCol() + + +def test_inheritance_row_created(): + setupClass(A) + setupClass(B) + setupClass(C) + + def test_query(instance): + id = instance.id + A.get(id) + + def signal(kwargs, postfuncs): + postfuncs.append(test_query) + + events.listen(signal, A, events.RowCreatedSignal) + + C(a=1, b=2, c=3) |
From: <sub...@co...> - 2008-05-20 13:51:43
|
Author: phd Date: 2008-05-20 07:50:55 -0600 (Tue, 20 May 2008) New Revision: 3441 Modified: SQLObject/branches/0.10/docs/DeveloperGuide.txt SQLObject/branches/0.10/docs/News.txt SQLObject/branches/0.10/sqlobject/events.py SQLObject/branches/0.10/sqlobject/main.py SQLObject/branches/0.10/sqlobject/tests/test_events.py Log: Merged patches by Diez B. Roggisch from revisions 3439-3440: A bug fixed for RowCreatedSignal together with InheritableSQLObject: run post_funcs after the entire hierarchy has been created; run post_funcs after RowDestroySignal. Modified: SQLObject/branches/0.10/docs/DeveloperGuide.txt =================================================================== --- SQLObject/branches/0.10/docs/DeveloperGuide.txt 2008-05-20 13:46:30 UTC (rev 3440) +++ SQLObject/branches/0.10/docs/DeveloperGuide.txt 2008-05-20 13:50:55 UTC (rev 3441) @@ -185,7 +185,8 @@ tests. So please, write tests; everything at least needs to be exercised, even if the tests are absolutely complete. -Documentation ======= +Documentation +============= Please write documentation. Documentation should live in the docs/ directory. Pudge converts documentation from Restructured Text to Modified: SQLObject/branches/0.10/docs/News.txt =================================================================== --- SQLObject/branches/0.10/docs/News.txt 2008-05-20 13:46:30 UTC (rev 3440) +++ SQLObject/branches/0.10/docs/News.txt 2008-05-20 13:50:55 UTC (rev 3441) @@ -94,6 +94,11 @@ SQLObject 0.9.7 =============== +* A bug fixed for RowCreatedSignal together with InheritableSQLObject: + run post_funcs after the entire hierarchy has been created. + +* Run post_funcs after RowDestroySignal. + * Aggregate functions now honors 'distinct'. SQLObject 0.9.6 Modified: SQLObject/branches/0.10/sqlobject/events.py =================================================================== --- SQLObject/branches/0.10/sqlobject/events.py 2008-05-20 13:46:30 UTC (rev 3440) +++ SQLObject/branches/0.10/sqlobject/events.py 2008-05-20 13:50:55 UTC (rev 3441) @@ -97,16 +97,16 @@ class RowDestroySignal(Signal): """ Called before an instance is deleted. Sender is the instance's - class. Arguments are ``(instance, post_funcs)``. + class. Arguments are ``(instance, post_funcs)``. ``post_funcs`` is a list of callbacks, intended to have - functions appended to it, and are called without arguments. If + functions appended to it, and are called without arguments. If any of the post_funcs raises an exception, the deletion is only affected if this will prevent a commit. - You cannot cancel the delete, - but you can raise an exception (which will probably cancel the - delete, but also cause an uncaught exception if not expected). + You cannot cancel the delete, but you can raise an exception (which will + probably cancel the delete, but also cause an uncaught exception if not + expected). Note: this is not called when an instance is destroyed through garbage collection. Modified: SQLObject/branches/0.10/sqlobject/main.py =================================================================== --- SQLObject/branches/0.10/sqlobject/main.py 2008-05-20 13:46:30 UTC (rev 3440) +++ SQLObject/branches/0.10/sqlobject/main.py 2008-05-20 13:50:55 UTC (rev 3441) @@ -41,11 +41,19 @@ import events from sresults import SelectResults from formencode import schema, compound +from util.threadinglocal import local import sys if sys.version_info[:3] < (2, 2, 0): raise ImportError, "SQLObject requires Python 2.2.0 or later" +""" +This thread-local storage is needed for RowCreatedSignals. It gathers +code-blocks to execute _after_ the whole hierachy of inherited SQLObjects +is created. See SQLObject._create +""" +_postponed_local = local() + NoDefault = sqlbuilder.NoDefault class SQLObjectNotFound(LookupError): pass @@ -1153,37 +1161,60 @@ return joinClass.get(id) def __init__(self, **kw): - # We shadow the sqlmeta class with an instance of sqlmeta - # that points to us (our sqlmeta buddy object; where the - # sqlmeta class is our class's buddy class) - self.sqlmeta = self.__class__.sqlmeta(self) - # The get() classmethod/constructor uses a magic keyword - # argument when it wants an empty object, fetched from the - # database. So we have nothing more to do in that case: - if kw.has_key('_SO_fetch_no_create'): - return + # If we are the outmost constructor of a hiearchy of + # InheritableSQLObjects (or simlpy _the_ constructor of a "normal" + # SQLObject), we create a threadlocal list that collects the + # RowCreatedSignals, and executes them if this very constructor is left + try: + _postponed_local.postponed_calls + postponed_created = False + except AttributeError: + _postponed_local.postponed_calls = [] + postponed_created = True - post_funcs = [] - self.sqlmeta.send(events.RowCreateSignal, kw, post_funcs) + try: + # We shadow the sqlmeta class with an instance of sqlmeta + # that points to us (our sqlmeta buddy object; where the + # sqlmeta class is our class's buddy class) + self.sqlmeta = self.__class__.sqlmeta(self) + # The get() classmethod/constructor uses a magic keyword + # argument when it wants an empty object, fetched from the + # database. So we have nothing more to do in that case: + if kw.has_key('_SO_fetch_no_create'): + return - # Pass the connection object along if we were given one. - if kw.has_key('connection'): - self._connection = kw['connection'] - self.sqlmeta._perConnection = True - del kw['connection'] + post_funcs = [] + self.sqlmeta.send(events.RowCreateSignal, kw, post_funcs) - self._SO_writeLock = threading.Lock() + # Pass the connection object along if we were given one. + if kw.has_key('connection'): + self._connection = kw['connection'] + self.sqlmeta._perConnection = True + del kw['connection'] - if kw.has_key('id'): - id = self.sqlmeta.idType(kw['id']) - del kw['id'] - else: - id = None + self._SO_writeLock = threading.Lock() - self._create(id, **kw) - for func in post_funcs: - func(self) + if kw.has_key('id'): + id = self.sqlmeta.idType(kw['id']) + del kw['id'] + else: + id = None + self._create(id, **kw) + + for func in post_funcs: + func(self) + finally: + # if we are the creator of the tl-storage, we + # have to exectute and under all circumstances + # remove the tl-storage + if postponed_created: + try: + for func in _postponed_local.postponed_calls: + func() + finally: + del _postponed_local.postponed_calls + def _create(self, id, **kw): self.sqlmeta._creating = True @@ -1247,9 +1278,11 @@ self._init(id) post_funcs = [] kw = dict([('class', self.__class__), ('id', id)]) - self.sqlmeta.send(events.RowCreatedSignal, kw, post_funcs) - for func in post_funcs: - func(self) + def _send_RowCreatedSignal(): + self.sqlmeta.send(events.RowCreatedSignal, kw, post_funcs) + for func in post_funcs: + func(self) + _postponed_local.postponed_calls.append(_send_RowCreatedSignal) def _SO_getID(self, obj): return getID(obj) Modified: SQLObject/branches/0.10/sqlobject/tests/test_events.py =================================================================== --- SQLObject/branches/0.10/sqlobject/tests/test_events.py 2008-05-20 13:46:30 UTC (rev 3440) +++ SQLObject/branches/0.10/sqlobject/tests/test_events.py 2008-05-20 13:50:55 UTC (rev 3441) @@ -1,6 +1,7 @@ from sqlobject import * from sqlobject.tests.dbtest import * from sqlobject import events +from sqlobject.inheritance import InheritableSQLObject import sys class EventTester(SQLObject): @@ -32,7 +33,7 @@ assert watcher.log[0][1] == (EventTester,) assert isinstance(watcher.log[0][2], dict) assert isinstance(watcher.log[0][3], list) - + def test_row_create(): setupClass(EventTester) watcher = make_listen(events.RowCreateSignal) @@ -48,7 +49,7 @@ assert not watcher.log f.destroySelf() assert watcher.log == [(f, [])] - + def test_row_update(): setupClass(EventTester) watcher = make_listen(events.RowUpdateSignal) @@ -59,7 +60,7 @@ assert watcher.log == [ (f, {'name': 'bar2'}), (f, {'name': 'bar3'})] - + def test_add_column(): setupClass(EventTester) watcher = make_listen(events.AddColumnSignal) @@ -72,3 +73,30 @@ False, []) print zip(watcher.log[1], expect) assert watcher.log[1] == expect + + +class A(InheritableSQLObject): + a = IntCol() + +class B(A): + b = IntCol() + +class C(B): + c = IntCol() + + +def test_inheritance_row_created(): + setupClass(A) + setupClass(B) + setupClass(C) + + def test_query(instance): + id = instance.id + A.get(id) + + def signal(kwargs, postfuncs): + postfuncs.append(test_query) + + events.listen(signal, A, events.RowCreatedSignal) + + C(a=1, b=2, c=3) |
From: <sub...@co...> - 2008-05-20 13:47:22
|
Author: phd Date: 2008-05-20 07:46:30 -0600 (Tue, 20 May 2008) New Revision: 3440 Modified: SQLObject/branches/0.9/docs/DeveloperGuide.txt SQLObject/branches/0.9/docs/News.txt Log: Documentation update. Modified: SQLObject/branches/0.9/docs/DeveloperGuide.txt =================================================================== --- SQLObject/branches/0.9/docs/DeveloperGuide.txt 2008-05-20 13:43:34 UTC (rev 3439) +++ SQLObject/branches/0.9/docs/DeveloperGuide.txt 2008-05-20 13:46:30 UTC (rev 3440) @@ -149,7 +149,7 @@ its `getting started`_ document for more. .. __: http://codespeak.net/py/current/doc/test.html -.. _getting started: http://codespeak.net/py/current/doc/getting-started.html +.. _getting started: http://codespeak.net/py/dist/test.html#starting-point-py-test-command-line-tool To actually run the test, you have to give it a database to connect to. You do this with the ``TESTDB`` environmental variable (right now @@ -163,7 +163,7 @@ the test module ``tests/test_modulename.py`` -- only modules that start with ``test_`` will be picked up by py.test. -The "framework" for testing is in ``tests/dbtest``. There's a couple +The "framework" for testing is in ``tests/dbtest``. There's a couple of important functions: ``setupClass(soClass)`` creates the tables for the class. It tries to @@ -185,7 +185,8 @@ tests. So please, write tests; everything at least needs to be exercised, even if the tests are absolutely complete. -Documentation ======= +Documentation +============= Please write documentation. Documentation should live in the docs/ directory. Pudge converts documentation from Restructured Text to Modified: SQLObject/branches/0.9/docs/News.txt =================================================================== --- SQLObject/branches/0.9/docs/News.txt 2008-05-20 13:43:34 UTC (rev 3439) +++ SQLObject/branches/0.9/docs/News.txt 2008-05-20 13:46:30 UTC (rev 3440) @@ -10,6 +10,11 @@ SQLObject 0.9.7 =============== +* A bug fixed for RowCreatedSignal together with InheritableSQLObject: + run post_funcs after the entire hierarchy has been created. + +* Run post_funcs after RowDestroySignal. + * Aggregate functions now honors 'distinct'. SQLObject 0.9.6 |
From: <sub...@co...> - 2008-05-20 13:44:41
|
Author: phd Date: 2008-05-20 07:43:34 -0600 (Tue, 20 May 2008) New Revision: 3439 Modified: SQLObject/branches/0.9/sqlobject/events.py SQLObject/branches/0.9/sqlobject/main.py SQLObject/branches/0.9/sqlobject/tests/test_events.py Log: Two patches by Diez B. Roggisch: one for RowCreatedSignal together with InheritableSQLObject, the other to run post_funcs after RowDestroySignal. Modified: SQLObject/branches/0.9/sqlobject/events.py =================================================================== --- SQLObject/branches/0.9/sqlobject/events.py 2008-05-20 13:22:12 UTC (rev 3438) +++ SQLObject/branches/0.9/sqlobject/events.py 2008-05-20 13:43:34 UTC (rev 3439) @@ -97,7 +97,14 @@ class RowDestroySignal(Signal): """ Called before an instance is deleted. Sender is the instance's - class. Arguments are ``(instance)``. You cannot cancel the delete, + class. Arguments are ``(instance, post_funcs)``. + + ``post_funcs`` is a list of callbacks, intended to have + functions appended to it, and are called without arguments. If + any of the post_funcs raises an exception, the deletion is only + affected if this will prevent a commit. + + You cannot cancel the delete, but you can raise an exception (which will probably cancel the delete, but also cause an uncaught exception if not expected). Modified: SQLObject/branches/0.9/sqlobject/main.py =================================================================== --- SQLObject/branches/0.9/sqlobject/main.py 2008-05-20 13:22:12 UTC (rev 3438) +++ SQLObject/branches/0.9/sqlobject/main.py 2008-05-20 13:43:34 UTC (rev 3439) @@ -41,11 +41,19 @@ import events from sresults import SelectResults from formencode import schema, compound +from util.threadinglocal import local import sys if sys.version_info[:3] < (2, 2, 0): raise ImportError, "SQLObject requires Python 2.2.0 or later" +""" +This thread-local storage is needed for RowCreatedSignals. It gathers +code-blocks to execute _after_ the whole hierachy of inherited SQLObjects +is created. See SQLObject._create +""" +_postponed_local = local() + NoDefault = sqlbuilder.NoDefault class SQLObjectNotFound(LookupError): pass @@ -1182,37 +1190,60 @@ return joinClass.get(id) def __init__(self, **kw): - # We shadow the sqlmeta class with an instance of sqlmeta - # that points to us (our sqlmeta buddy object; where the - # sqlmeta class is our class's buddy class) - self.sqlmeta = self.__class__.sqlmeta(self) - # The get() classmethod/constructor uses a magic keyword - # argument when it wants an empty object, fetched from the - # database. So we have nothing more to do in that case: - if kw.has_key('_SO_fetch_no_create'): - return + # If we are the outmost constructor of a hiearchy of + # InheritableSQLObjects (or simlpy _the_ constructor of a "normal" + # SQLObject), we create a threadlocal list that collects the + # RowCreatedSignals, and executes them if this very constructor is left + try: + _postponed_local.postponed_calls + postponed_created = False + except AttributeError: + _postponed_local.postponed_calls = [] + postponed_created = True - post_funcs = [] - self.sqlmeta.send(events.RowCreateSignal, kw, post_funcs) + try: + # We shadow the sqlmeta class with an instance of sqlmeta + # that points to us (our sqlmeta buddy object; where the + # sqlmeta class is our class's buddy class) + self.sqlmeta = self.__class__.sqlmeta(self) + # The get() classmethod/constructor uses a magic keyword + # argument when it wants an empty object, fetched from the + # database. So we have nothing more to do in that case: + if kw.has_key('_SO_fetch_no_create'): + return - # Pass the connection object along if we were given one. - if kw.has_key('connection'): - self._connection = kw['connection'] - self.sqlmeta._perConnection = True - del kw['connection'] + post_funcs = [] + self.sqlmeta.send(events.RowCreateSignal, kw, post_funcs) - self._SO_writeLock = threading.Lock() + # Pass the connection object along if we were given one. + if kw.has_key('connection'): + self._connection = kw['connection'] + self.sqlmeta._perConnection = True + del kw['connection'] - if kw.has_key('id'): - id = self.sqlmeta.idType(kw['id']) - del kw['id'] - else: - id = None + self._SO_writeLock = threading.Lock() - self._create(id, **kw) - for func in post_funcs: - func(self) + if kw.has_key('id'): + id = self.sqlmeta.idType(kw['id']) + del kw['id'] + else: + id = None + self._create(id, **kw) + + for func in post_funcs: + func(self) + finally: + # if we are the creator of the tl-storage, we + # have to exectute and under all circumstances + # remove the tl-storage + if postponed_created: + try: + for func in _postponed_local.postponed_calls: + func() + finally: + del _postponed_local.postponed_calls + def _create(self, id, **kw): self.sqlmeta._creating = True @@ -1276,9 +1307,11 @@ self._init(id) post_funcs = [] kw = dict([('class', self.__class__), ('id', id)]) - self.sqlmeta.send(events.RowCreatedSignal, kw, post_funcs) - for func in post_funcs: - func(self) + def _send_RowCreatedSignal(): + self.sqlmeta.send(events.RowCreatedSignal, kw, post_funcs) + for func in post_funcs: + func(self) + _postponed_local.postponed_calls.append(_send_RowCreatedSignal) def _SO_getID(self, obj): return getID(obj) @@ -1490,7 +1523,8 @@ clearTable = classmethod(clearTable) def destroySelf(self): - self.sqlmeta.send(events.RowDestroySignal, self) + post_funcs = [] + self.sqlmeta.send(events.RowDestroySignal, self, post_funcs) # Kills this object. Kills it dead! klass = self.__class__ @@ -1552,6 +1586,9 @@ self._connection._SO_delete(self) self._connection.cache.expire(self.id, self.__class__) + for func in post_funcs: + func() + def delete(cls, id, connection=None): obj = cls.get(id, connection=connection) obj.destroySelf() Modified: SQLObject/branches/0.9/sqlobject/tests/test_events.py =================================================================== --- SQLObject/branches/0.9/sqlobject/tests/test_events.py 2008-05-20 13:22:12 UTC (rev 3438) +++ SQLObject/branches/0.9/sqlobject/tests/test_events.py 2008-05-20 13:43:34 UTC (rev 3439) @@ -1,6 +1,7 @@ from sqlobject import * from sqlobject.tests.dbtest import * from sqlobject import events +from sqlobject.inheritance import InheritableSQLObject import sys class EventTester(SQLObject): @@ -32,7 +33,7 @@ assert watcher.log[0][1] == (EventTester,) assert isinstance(watcher.log[0][2], dict) assert isinstance(watcher.log[0][3], list) - + def test_row_create(): setupClass(EventTester) watcher = make_listen(events.RowCreateSignal) @@ -41,14 +42,14 @@ assert len(watcher.log) == 2 assert watcher.log[0] == ({'name': 'foo'}, []) -def test_row_destrow(): +def test_row_destroy(): setupClass(EventTester) watcher = make_listen(events.RowDestroySignal) f = EventTester(name='foo') assert not watcher.log f.destroySelf() - assert watcher.log == [(f,)] - + assert watcher.log == [(f, [])] + def test_row_update(): setupClass(EventTester) watcher = make_listen(events.RowUpdateSignal) @@ -59,7 +60,7 @@ assert watcher.log == [ (f, {'name': 'bar2'}), (f, {'name': 'bar3'})] - + def test_add_column(): setupClass(EventTester) watcher = make_listen(events.AddColumnSignal) @@ -72,3 +73,30 @@ False, []) print zip(watcher.log[1], expect) assert watcher.log[1] == expect + + +class A(InheritableSQLObject): + a = IntCol() + +class B(A): + b = IntCol() + +class C(B): + c = IntCol() + + +def test_inheritance_row_created(): + setupClass(A) + setupClass(B) + setupClass(C) + + def test_query(instance): + id = instance.id + A.get(id) + + def signal(kwargs, postfuncs): + postfuncs.append(test_query) + + events.listen(signal, A, events.RowCreatedSignal) + + C(a=1, b=2, c=3) |
From: SourceForge.net <no...@so...> - 2008-05-19 15:02:21
|
Bugs item #1872669, was opened at 2008-01-16 14:00 Message generated for change (Comment added) made by phd You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1872669&group_id=74338 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: General Group: SQLObject release (specify) >Status: Closed >Resolution: Fixed Priority: 5 Private: No Submitted By: Nobody/Anonymous (nobody) >Assigned to: Oleg Broytmann (phd) Summary: When using sum() distinct=True is ignored Initial Comment: This is on SQLObject 0.6.1. When using sum() on a result set, the distinct=True clause is ignored. ---------------------------------------------------------------------- >Comment By: Oleg Broytmann (phd) Date: 2008-05-19 19:01 Message: Logged In: YES user_id=4799 Originator: NO Fixed in the revisions 3433-3435 (branches 0.9, 0.10 and the trunk). The fix will be available in the releases 0.9.7, 0.10.2, 0.11.0. Thank you! ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1872669&group_id=74338 |
From: <sub...@co...> - 2008-05-19 15:00:59
|
Author: phd Date: 2008-05-19 09:00:23 -0600 (Mon, 19 May 2008) New Revision: 3435 Added: SQLObject/trunk/sqlobject/tests/test_aggregates.py Removed: SQLObject/trunk/sqlobject/tests/test_minmax.py Modified: SQLObject/trunk/docs/News.txt SQLObject/trunk/sqlobject/sresults.py Log: Aggregate functions now honors 'distinct'. Modified: SQLObject/trunk/docs/News.txt =================================================================== --- SQLObject/trunk/docs/News.txt 2008-05-19 14:58:03 UTC (rev 3434) +++ SQLObject/trunk/docs/News.txt 2008-05-19 15:00:23 UTC (rev 3435) @@ -30,9 +30,11 @@ * Use reversed() in manager/command.py instead of .__reversed__(). -Bug Fixes ---------- +SQLObject 0.10.2 +================ +* A number of changes ported from `SQLObject 0.9.7`_. + SQLObject 0.10.1 ================ @@ -112,6 +114,11 @@ * Under MySQL, PickleCol no longer used TEXT column types; the smallest column is now BLOB - it is not possible to create TINYBLOB column. +SQLObject 0.9.7 +=============== + +* Aggregate functions now honors 'distinct'. + SQLObject 0.9.6 =============== Modified: SQLObject/trunk/sqlobject/sresults.py =================================================================== --- SQLObject/trunk/sqlobject/sresults.py 2008-05-19 14:58:03 UTC (rev 3434) +++ SQLObject/trunk/sqlobject/sresults.py 2008-05-19 15:00:23 UTC (rev 3435) @@ -229,11 +229,15 @@ or a dot-q attribute (like Table.q.aColumn) """ expressions = [] + conn = self._getConnection() + if self.ops.get('distinct'): + distinct = 'DISTINCT ' + else: + distinct = '' for func_name, attribute in attributes: - if isinstance(attribute, str): - expression = '%s(%s)' % (func_name, attribute) - else: - expression = getattr(sqlbuilder.func, func_name)(attribute) + if not isinstance(attribute, str): + attribute = conn.sqlrepr(attribute) + expression = '%s(%s%s)' % (func_name, distinct, attribute) expressions.append(expression) return self.accumulate(*expressions) Copied: SQLObject/trunk/sqlobject/tests/test_aggregates.py (from rev 3434, SQLObject/branches/0.10/sqlobject/tests/test_aggregates.py) =================================================================== --- SQLObject/trunk/sqlobject/tests/test_aggregates.py (rev 0) +++ SQLObject/trunk/sqlobject/tests/test_aggregates.py 2008-05-19 15:00:23 UTC (rev 3435) @@ -0,0 +1,67 @@ +from sqlobject import * +from sqlobject.tests.dbtest import * + +# Test MIN, AVG, MAX, COUNT, SUM + + +class IntAccumulator(SQLObject): + value = IntCol() + + +class FloatAccumulator(SQLObject): + value = FloatCol() + + +def test_integer(): + setupClass(IntAccumulator) + IntAccumulator(value=1) + IntAccumulator(value=2) + IntAccumulator(value=3) + + assert IntAccumulator.select().min(IntAccumulator.q.value) == 1 + assert IntAccumulator.select().avg(IntAccumulator.q.value) == 2 + assert IntAccumulator.select().max(IntAccumulator.q.value) == 3 + assert IntAccumulator.select().sum(IntAccumulator.q.value) == 6 + + assert IntAccumulator.select(IntAccumulator.q.value > 1).max(IntAccumulator.q.value) == 3 + assert IntAccumulator.select(IntAccumulator.q.value > 1).sum(IntAccumulator.q.value) == 5 + + +def floatcmp(f1, f2): + if abs(f1-f2) < 0.1: + return 0 + if f1 < f2: + return 1 + return -1 + +def test_float(): + setupClass(FloatAccumulator) + FloatAccumulator(value=1.2) + FloatAccumulator(value=2.4) + FloatAccumulator(value=3.8) + + assert floatcmp(FloatAccumulator.select().min(FloatAccumulator.q.value), 1.2) == 0 + assert floatcmp(FloatAccumulator.select().avg(FloatAccumulator.q.value), 2.5) == 0 + assert floatcmp(FloatAccumulator.select().max(FloatAccumulator.q.value), 3.8) == 0 + assert floatcmp(FloatAccumulator.select().sum(FloatAccumulator.q.value), 7.4) == 0 + + +def test_many(): + setupClass(IntAccumulator) + IntAccumulator(value=1) + IntAccumulator(value=1) + IntAccumulator(value=2) + IntAccumulator(value=2) + IntAccumulator(value=3) + IntAccumulator(value=3) + + attribute = IntAccumulator.q.value + assert IntAccumulator.select().accumulateMany( + ("MIN", attribute), ("AVG", attribute), ("MAX", attribute), + ("COUNT", attribute), ("SUM", attribute) + ) == (1, 2, 3, 6, 12) + + assert IntAccumulator.select(distinct=True).accumulateMany( + ("MIN", attribute), ("AVG", attribute), ("MAX", attribute), + ("COUNT", attribute), ("SUM", attribute) + ) == (1, 2, 3, 3, 6) Deleted: SQLObject/trunk/sqlobject/tests/test_minmax.py =================================================================== --- SQLObject/trunk/sqlobject/tests/test_minmax.py 2008-05-19 14:58:03 UTC (rev 3434) +++ SQLObject/trunk/sqlobject/tests/test_minmax.py 2008-05-19 15:00:23 UTC (rev 3435) @@ -1,59 +0,0 @@ -from sqlobject import * -from sqlobject.tests.dbtest import * - -# Test MIN, AVG, MAX, SUM - - -class IntAccumulator(SQLObject): - value = IntCol() - - -class FloatAccumulator(SQLObject): - value = FloatCol() - - -def test_integer(): - setupClass(IntAccumulator) - IntAccumulator(value=1) - IntAccumulator(value=2) - IntAccumulator(value=3) - - assert IntAccumulator.select().min(IntAccumulator.q.value) == 1 - assert IntAccumulator.select().avg(IntAccumulator.q.value) == 2 - assert IntAccumulator.select().max(IntAccumulator.q.value) == 3 - assert IntAccumulator.select().sum(IntAccumulator.q.value) == 6 - - assert IntAccumulator.select(IntAccumulator.q.value > 1).max(IntAccumulator.q.value) == 3 - assert IntAccumulator.select(IntAccumulator.q.value > 1).sum(IntAccumulator.q.value) == 5 - - -def floatcmp(f1, f2): - if abs(f1-f2) < 0.1: - return 0 - if f1 < f2: - return 1 - return -1 - -def test_float(): - setupClass(FloatAccumulator) - FloatAccumulator(value=1.2) - FloatAccumulator(value=2.4) - FloatAccumulator(value=3.8) - - assert floatcmp(FloatAccumulator.select().min(FloatAccumulator.q.value), 1.2) == 0 - assert floatcmp(FloatAccumulator.select().avg(FloatAccumulator.q.value), 2.5) == 0 - assert floatcmp(FloatAccumulator.select().max(FloatAccumulator.q.value), 3.8) == 0 - assert floatcmp(FloatAccumulator.select().sum(FloatAccumulator.q.value), 7.4) == 0 - - -def test_many(): - setupClass(IntAccumulator) - IntAccumulator(value=1) - IntAccumulator(value=2) - IntAccumulator(value=3) - - select = IntAccumulator.select() - attribute = IntAccumulator.q.value - assert select.accumulateMany( - ("MIN", attribute), ("AVG", attribute), ("MAX", attribute) - ) == (1, 2, 3) |
From: <sub...@co...> - 2008-05-19 14:59:27
|
Author: phd Date: 2008-05-19 08:58:03 -0600 (Mon, 19 May 2008) New Revision: 3434 Added: SQLObject/branches/0.10/sqlobject/tests/test_aggregates.py Removed: SQLObject/branches/0.10/sqlobject/tests/test_minmax.py Modified: SQLObject/branches/0.10/docs/News.txt SQLObject/branches/0.10/sqlobject/sresults.py Log: Aggregate functions now honors 'distinct'. Modified: SQLObject/branches/0.10/docs/News.txt =================================================================== --- SQLObject/branches/0.10/docs/News.txt 2008-05-19 14:53:49 UTC (rev 3433) +++ SQLObject/branches/0.10/docs/News.txt 2008-05-19 14:58:03 UTC (rev 3434) @@ -7,6 +7,11 @@ .. _start: +SQLObject 0.10.2 +================ + +* A number of changes ported from `SQLObject 0.9.7`_. + SQLObject 0.10.1 ================ @@ -86,6 +91,11 @@ * Under MySQL, PickleCol no longer uses TEXT column types; the smallest column is now BLOB - it is not possible to create TINYBLOB column. +SQLObject 0.9.7 +=============== + +* Aggregate functions now honors 'distinct'. + SQLObject 0.9.6 =============== Modified: SQLObject/branches/0.10/sqlobject/sresults.py =================================================================== --- SQLObject/branches/0.10/sqlobject/sresults.py 2008-05-19 14:53:49 UTC (rev 3433) +++ SQLObject/branches/0.10/sqlobject/sresults.py 2008-05-19 14:58:03 UTC (rev 3434) @@ -229,11 +229,15 @@ or a dot-q attribute (like Table.q.aColumn) """ expressions = [] + conn = self._getConnection() + if self.ops.get('distinct'): + distinct = 'DISTINCT ' + else: + distinct = '' for func_name, attribute in attributes: - if isinstance(attribute, str): - expression = '%s(%s)' % (func_name, attribute) - else: - expression = getattr(sqlbuilder.func, func_name)(attribute) + if not isinstance(attribute, str): + attribute = conn.sqlrepr(attribute) + expression = '%s(%s%s)' % (func_name, distinct, attribute) expressions.append(expression) return self.accumulate(*expressions) Copied: SQLObject/branches/0.10/sqlobject/tests/test_aggregates.py (from rev 3433, SQLObject/branches/0.9/sqlobject/tests/test_aggregates.py) =================================================================== --- SQLObject/branches/0.10/sqlobject/tests/test_aggregates.py (rev 0) +++ SQLObject/branches/0.10/sqlobject/tests/test_aggregates.py 2008-05-19 14:58:03 UTC (rev 3434) @@ -0,0 +1,67 @@ +from sqlobject import * +from sqlobject.tests.dbtest import * + +# Test MIN, AVG, MAX, COUNT, SUM + + +class IntAccumulator(SQLObject): + value = IntCol() + + +class FloatAccumulator(SQLObject): + value = FloatCol() + + +def test_integer(): + setupClass(IntAccumulator) + IntAccumulator(value=1) + IntAccumulator(value=2) + IntAccumulator(value=3) + + assert IntAccumulator.select().min(IntAccumulator.q.value) == 1 + assert IntAccumulator.select().avg(IntAccumulator.q.value) == 2 + assert IntAccumulator.select().max(IntAccumulator.q.value) == 3 + assert IntAccumulator.select().sum(IntAccumulator.q.value) == 6 + + assert IntAccumulator.select(IntAccumulator.q.value > 1).max(IntAccumulator.q.value) == 3 + assert IntAccumulator.select(IntAccumulator.q.value > 1).sum(IntAccumulator.q.value) == 5 + + +def floatcmp(f1, f2): + if abs(f1-f2) < 0.1: + return 0 + if f1 < f2: + return 1 + return -1 + +def test_float(): + setupClass(FloatAccumulator) + FloatAccumulator(value=1.2) + FloatAccumulator(value=2.4) + FloatAccumulator(value=3.8) + + assert floatcmp(FloatAccumulator.select().min(FloatAccumulator.q.value), 1.2) == 0 + assert floatcmp(FloatAccumulator.select().avg(FloatAccumulator.q.value), 2.5) == 0 + assert floatcmp(FloatAccumulator.select().max(FloatAccumulator.q.value), 3.8) == 0 + assert floatcmp(FloatAccumulator.select().sum(FloatAccumulator.q.value), 7.4) == 0 + + +def test_many(): + setupClass(IntAccumulator) + IntAccumulator(value=1) + IntAccumulator(value=1) + IntAccumulator(value=2) + IntAccumulator(value=2) + IntAccumulator(value=3) + IntAccumulator(value=3) + + attribute = IntAccumulator.q.value + assert IntAccumulator.select().accumulateMany( + ("MIN", attribute), ("AVG", attribute), ("MAX", attribute), + ("COUNT", attribute), ("SUM", attribute) + ) == (1, 2, 3, 6, 12) + + assert IntAccumulator.select(distinct=True).accumulateMany( + ("MIN", attribute), ("AVG", attribute), ("MAX", attribute), + ("COUNT", attribute), ("SUM", attribute) + ) == (1, 2, 3, 3, 6) Deleted: SQLObject/branches/0.10/sqlobject/tests/test_minmax.py =================================================================== --- SQLObject/branches/0.10/sqlobject/tests/test_minmax.py 2008-05-19 14:53:49 UTC (rev 3433) +++ SQLObject/branches/0.10/sqlobject/tests/test_minmax.py 2008-05-19 14:58:03 UTC (rev 3434) @@ -1,59 +0,0 @@ -from sqlobject import * -from sqlobject.tests.dbtest import * - -# Test MIN, AVG, MAX, SUM - - -class IntAccumulator(SQLObject): - value = IntCol() - - -class FloatAccumulator(SQLObject): - value = FloatCol() - - -def test_integer(): - setupClass(IntAccumulator) - IntAccumulator(value=1) - IntAccumulator(value=2) - IntAccumulator(value=3) - - assert IntAccumulator.select().min(IntAccumulator.q.value) == 1 - assert IntAccumulator.select().avg(IntAccumulator.q.value) == 2 - assert IntAccumulator.select().max(IntAccumulator.q.value) == 3 - assert IntAccumulator.select().sum(IntAccumulator.q.value) == 6 - - assert IntAccumulator.select(IntAccumulator.q.value > 1).max(IntAccumulator.q.value) == 3 - assert IntAccumulator.select(IntAccumulator.q.value > 1).sum(IntAccumulator.q.value) == 5 - - -def floatcmp(f1, f2): - if abs(f1-f2) < 0.1: - return 0 - if f1 < f2: - return 1 - return -1 - -def test_float(): - setupClass(FloatAccumulator) - FloatAccumulator(value=1.2) - FloatAccumulator(value=2.4) - FloatAccumulator(value=3.8) - - assert floatcmp(FloatAccumulator.select().min(FloatAccumulator.q.value), 1.2) == 0 - assert floatcmp(FloatAccumulator.select().avg(FloatAccumulator.q.value), 2.5) == 0 - assert floatcmp(FloatAccumulator.select().max(FloatAccumulator.q.value), 3.8) == 0 - assert floatcmp(FloatAccumulator.select().sum(FloatAccumulator.q.value), 7.4) == 0 - - -def test_many(): - setupClass(IntAccumulator) - IntAccumulator(value=1) - IntAccumulator(value=2) - IntAccumulator(value=3) - - select = IntAccumulator.select() - attribute = IntAccumulator.q.value - assert select.accumulateMany( - ("MIN", attribute), ("AVG", attribute), ("MAX", attribute) - ) == (1, 2, 3) |
From: <sub...@co...> - 2008-05-19 14:54:37
|
Author: phd Date: 2008-05-19 08:53:49 -0600 (Mon, 19 May 2008) New Revision: 3433 Added: SQLObject/branches/0.9/sqlobject/tests/test_aggregates.py Removed: SQLObject/branches/0.9/sqlobject/tests/test_minmax.py Modified: SQLObject/branches/0.9/docs/News.txt SQLObject/branches/0.9/sqlobject/sresults.py Log: Aggregate functions now honors 'distinct'. Modified: SQLObject/branches/0.9/docs/News.txt =================================================================== --- SQLObject/branches/0.9/docs/News.txt 2008-05-16 19:07:12 UTC (rev 3432) +++ SQLObject/branches/0.9/docs/News.txt 2008-05-19 14:53:49 UTC (rev 3433) @@ -7,6 +7,11 @@ .. _start: +SQLObject 0.9.7 +=============== + +* Aggregate functions now honors 'distinct'. + SQLObject 0.9.6 =============== Modified: SQLObject/branches/0.9/sqlobject/sresults.py =================================================================== --- SQLObject/branches/0.9/sqlobject/sresults.py 2008-05-16 19:07:12 UTC (rev 3432) +++ SQLObject/branches/0.9/sqlobject/sresults.py 2008-05-19 14:53:49 UTC (rev 3433) @@ -209,11 +209,15 @@ or a dot-q attribute (like Table.q.aColumn) """ expressions = [] + conn = self._getConnection() + if self.ops.get('distinct'): + distinct = 'DISTINCT ' + else: + distinct = '' for func_name, attribute in attributes: - if type(attribute) == StringType: - expression = '%s(%s)' % (func_name, attribute) - else: - expression = getattr(sqlbuilder.func, func_name)(attribute) + if not isinstance(attribute, str): + attribute = conn.sqlrepr(attribute) + expression = '%s(%s%s)' % (func_name, distinct, attribute) expressions.append(expression) return self.accumulate(*expressions) Copied: SQLObject/branches/0.9/sqlobject/tests/test_aggregates.py (from rev 3406, SQLObject/branches/0.9/sqlobject/tests/test_minmax.py) =================================================================== --- SQLObject/branches/0.9/sqlobject/tests/test_aggregates.py (rev 0) +++ SQLObject/branches/0.9/sqlobject/tests/test_aggregates.py 2008-05-19 14:53:49 UTC (rev 3433) @@ -0,0 +1,67 @@ +from sqlobject import * +from sqlobject.tests.dbtest import * + +# Test MIN, AVG, MAX, COUNT, SUM + + +class IntAccumulator(SQLObject): + value = IntCol() + + +class FloatAccumulator(SQLObject): + value = FloatCol() + + +def test_integer(): + setupClass(IntAccumulator) + IntAccumulator(value=1) + IntAccumulator(value=2) + IntAccumulator(value=3) + + assert IntAccumulator.select().min(IntAccumulator.q.value) == 1 + assert IntAccumulator.select().avg(IntAccumulator.q.value) == 2 + assert IntAccumulator.select().max(IntAccumulator.q.value) == 3 + assert IntAccumulator.select().sum(IntAccumulator.q.value) == 6 + + assert IntAccumulator.select(IntAccumulator.q.value > 1).max(IntAccumulator.q.value) == 3 + assert IntAccumulator.select(IntAccumulator.q.value > 1).sum(IntAccumulator.q.value) == 5 + + +def floatcmp(f1, f2): + if abs(f1-f2) < 0.1: + return 0 + if f1 < f2: + return 1 + return -1 + +def test_float(): + setupClass(FloatAccumulator) + FloatAccumulator(value=1.2) + FloatAccumulator(value=2.4) + FloatAccumulator(value=3.8) + + assert floatcmp(FloatAccumulator.select().min(FloatAccumulator.q.value), 1.2) == 0 + assert floatcmp(FloatAccumulator.select().avg(FloatAccumulator.q.value), 2.5) == 0 + assert floatcmp(FloatAccumulator.select().max(FloatAccumulator.q.value), 3.8) == 0 + assert floatcmp(FloatAccumulator.select().sum(FloatAccumulator.q.value), 7.4) == 0 + + +def test_many(): + setupClass(IntAccumulator) + IntAccumulator(value=1) + IntAccumulator(value=1) + IntAccumulator(value=2) + IntAccumulator(value=2) + IntAccumulator(value=3) + IntAccumulator(value=3) + + attribute = IntAccumulator.q.value + assert IntAccumulator.select().accumulateMany( + ("MIN", attribute), ("AVG", attribute), ("MAX", attribute), + ("COUNT", attribute), ("SUM", attribute) + ) == (1, 2, 3, 6, 12) + + assert IntAccumulator.select(distinct=True).accumulateMany( + ("MIN", attribute), ("AVG", attribute), ("MAX", attribute), + ("COUNT", attribute), ("SUM", attribute) + ) == (1, 2, 3, 3, 6) Deleted: SQLObject/branches/0.9/sqlobject/tests/test_minmax.py =================================================================== --- SQLObject/branches/0.9/sqlobject/tests/test_minmax.py 2008-05-16 19:07:12 UTC (rev 3432) +++ SQLObject/branches/0.9/sqlobject/tests/test_minmax.py 2008-05-19 14:53:49 UTC (rev 3433) @@ -1,59 +0,0 @@ -from sqlobject import * -from sqlobject.tests.dbtest import * - -# Test MIN, AVG, MAX, SUM - - -class IntAccumulator(SQLObject): - value = IntCol() - - -class FloatAccumulator(SQLObject): - value = FloatCol() - - -def test_integer(): - setupClass(IntAccumulator) - IntAccumulator(value=1) - IntAccumulator(value=2) - IntAccumulator(value=3) - - assert IntAccumulator.select().min(IntAccumulator.q.value) == 1 - assert IntAccumulator.select().avg(IntAccumulator.q.value) == 2 - assert IntAccumulator.select().max(IntAccumulator.q.value) == 3 - assert IntAccumulator.select().sum(IntAccumulator.q.value) == 6 - - assert IntAccumulator.select(IntAccumulator.q.value > 1).max(IntAccumulator.q.value) == 3 - assert IntAccumulator.select(IntAccumulator.q.value > 1).sum(IntAccumulator.q.value) == 5 - - -def floatcmp(f1, f2): - if abs(f1-f2) < 0.1: - return 0 - if f1 < f2: - return 1 - return -1 - -def test_float(): - setupClass(FloatAccumulator) - FloatAccumulator(value=1.2) - FloatAccumulator(value=2.4) - FloatAccumulator(value=3.8) - - assert floatcmp(FloatAccumulator.select().min(FloatAccumulator.q.value), 1.2) == 0 - assert floatcmp(FloatAccumulator.select().avg(FloatAccumulator.q.value), 2.5) == 0 - assert floatcmp(FloatAccumulator.select().max(FloatAccumulator.q.value), 3.8) == 0 - assert floatcmp(FloatAccumulator.select().sum(FloatAccumulator.q.value), 7.4) == 0 - - -def test_many(): - setupClass(IntAccumulator) - IntAccumulator(value=1) - IntAccumulator(value=2) - IntAccumulator(value=3) - - select = IntAccumulator.select() - attribute = IntAccumulator.q.value - assert select.accumulateMany( - ("MIN", attribute), ("AVG", attribute), ("MAX", attribute) - ) == (1, 2, 3) |
From: <sub...@co...> - 2008-05-04 14:08:40
|
Author: phd Date: 2008-05-04 08:08:34 -0600 (Sun, 04 May 2008) New Revision: 3413 Modified: SQLObject/tags/0.10.1/setup.cfg SQLObject/tags/0.10.1/setup.py SQLObject/tags/0.10.1/sqlobject/__init__.py SQLObject/tags/0.10.1/sqlobject/main.py Log: Version 0.10.1, stable. Modified: SQLObject/tags/0.10.1/setup.cfg =================================================================== --- SQLObject/tags/0.10.1/setup.cfg 2008-05-04 14:07:14 UTC (rev 3412) +++ SQLObject/tags/0.10.1/setup.cfg 2008-05-04 14:08:34 UTC (rev 3413) @@ -5,10 +5,6 @@ [easy_install] #find_links = http://svn.pythonpaste.org/package_index.html -[egg_info] -tag_build = dev -tag_svn_revision = true - [pudge] theme = pythonpaste.org docs = docs/index.txt docs/Authors.txt docs/DeveloperGuide.txt docs/FAQ.txt Modified: SQLObject/tags/0.10.1/setup.py =================================================================== --- SQLObject/tags/0.10.1/setup.py 2008-05-04 14:07:14 UTC (rev 3412) +++ SQLObject/tags/0.10.1/setup.py 2008-05-04 14:08:34 UTC (rev 3413) @@ -21,7 +21,7 @@ """ setup(name="SQLObject", - version="0.10", + version="0.10.1", description="Object-Relational Manager, aka database wrapper", long_description="""\ SQLObject is a popular *Object Relational Manager* for providing an @@ -49,7 +49,7 @@ author="Ian Bicking", author_email="ia...@co...", url="http://sqlobject.org/", - download_url="http://cheeseshop.python.org/pypi/SQLObject/0.10", + download_url="http://cheeseshop.python.org/pypi/SQLObject/0.10.1", license="LGPL", packages=["sqlobject"] + ['sqlobject.%s' % package for package in subpackages], scripts=["scripts/sqlobject-admin"], Modified: SQLObject/tags/0.10.1/sqlobject/__init__.py =================================================================== --- SQLObject/tags/0.10.1/sqlobject/__init__.py 2008-05-04 14:07:14 UTC (rev 3412) +++ SQLObject/tags/0.10.1/sqlobject/__init__.py 2008-05-04 14:08:34 UTC (rev 3413) @@ -1,5 +1,5 @@ """ -SQLObject 0.10 +SQLObject 0.10.1 """ from main import * Modified: SQLObject/tags/0.10.1/sqlobject/main.py =================================================================== --- SQLObject/tags/0.10.1/sqlobject/main.py 2008-05-04 14:07:14 UTC (rev 3412) +++ SQLObject/tags/0.10.1/sqlobject/main.py 2008-05-04 14:08:34 UTC (rev 3413) @@ -1,6 +1,6 @@ """ -SQLObject 0.10 --------------- +SQLObject 0.10.1 +---------------- :author: Ian Bicking <ia...@co...> |
From: <sub...@co...> - 2008-05-04 14:07:21
|
Author: phd Date: 2008-05-04 08:07:14 -0600 (Sun, 04 May 2008) New Revision: 3412 Added: SQLObject/tags/0.10.1/ Log: Tagging 0.10.1 Copied: SQLObject/tags/0.10.1 (from rev 3411, SQLObject/branches/0.10) |
From: <sub...@co...> - 2008-05-04 14:06:55
|
Author: phd Date: 2008-05-04 08:06:48 -0600 (Sun, 04 May 2008) New Revision: 3411 Modified: SQLObject/trunk/docs/News.txt Log: SQLObject 0.10.1 released 4 May 2008. Modified: SQLObject/trunk/docs/News.txt =================================================================== --- SQLObject/trunk/docs/News.txt 2008-05-04 14:05:46 UTC (rev 3410) +++ SQLObject/trunk/docs/News.txt 2008-05-04 14:06:48 UTC (rev 3411) @@ -36,6 +36,8 @@ SQLObject 0.10.1 ================ +Released 4 May 2008. + * Fixed a bug: limit doesn't work in sqlbuilder.Select. * A number of changes ported from `SQLObject 0.9.6`_. |