sqlobject-cvs Mailing List for SQLObject (Page 165)
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
(2) |
Dec
(2) |
|
From: <sub...@co...> - 2005-06-03 21:53:39
|
Author: ianb
Date: 2005-06-03 21:53:30 +0000 (Fri, 03 Jun 2005)
New Revision: 811
Modified:
trunk/SQLObject/sqlobject/manager/command.py
Log:
Note failing upgrade script filename
Modified: trunk/SQLObject/sqlobject/manager/command.py
===================================================================
--- trunk/SQLObject/sqlobject/manager/command.py 2005-06-03 16:13:48 UTC (rev 810)
+++ trunk/SQLObject/sqlobject/manager/command.py 2005-06-03 21:53:30 UTC (rev 811)
@@ -910,7 +910,11 @@
print sql
print '-'*60
if not sim:
- conn.query(sql)
+ try:
+ conn.query(sql)
+ except:
+ print "Error in script: %s" % upgrader
+ raise
self.update_db(next_version, conn)
print 'Done.'
|
|
From: <sub...@co...> - 2005-06-03 16:13:57
|
Author: phd
Date: 2005-06-03 16:13:48 +0000 (Fri, 03 Jun 2005)
New Revision: 810
Added:
trunk/SQLObject/sqlobject/inheritance/tests/test_inherited_foreignKey.py
Modified:
trunk/SQLObject/sqlobject/inheritance/__init__.py
trunk/SQLObject/sqlobject/main.py
Log:
Added a class method _notifyFinishClassCreation(). The method is used
in InheritableSQLObject to propagate columns and joins from parent classes
to children if it hasn't been done already. Added a test for that propagation.
Modified: trunk/SQLObject/sqlobject/inheritance/__init__.py
===================================================================
--- trunk/SQLObject/sqlobject/inheritance/__init__.py 2005-06-01 13:48:41 UTC (rev 809)
+++ trunk/SQLObject/sqlobject/inheritance/__init__.py 2005-06-03 16:13:48 UTC (rev 810)
@@ -108,7 +108,8 @@
makeProperties(cls)
return
- super(InheritableSQLObject, cls).addColumn(columnDef, changeSchema, connection)
+ if columnDef:
+ super(InheritableSQLObject, cls).addColumn(columnDef, changeSchema, connection)
#DSM: Update each child class if needed and existing (only for new
#DSM: dynamic column as no child classes exists at object creation)
@@ -148,7 +149,8 @@
makeProperties(cls)
return
- super(InheritableSQLObject, cls).addJoin(joinDef)
+ if joinDef:
+ super(InheritableSQLObject, cls).addJoin(joinDef)
#DSM: Update each child class if needed and existing (only for new
#DSM: dynamic join as no child classes exists at object creation)
@@ -167,6 +169,17 @@
delJoin = classmethod(delJoin)
+ def _notifyFinishClassCreation(cls):
+ if not cls._columns:
+ # There are no columns - call addColumn to propagate columns
+ # from parent classes to children
+ cls.addColumn(None)
+ if not cls._joins:
+ # There are no joins - call addJoin to propagate joins
+ # from parent classes to children
+ cls.addJoin(None)
+ _notifyFinishClassCreation = classmethod(_notifyFinishClassCreation)
+
def _create(self, id, **kw):
#DSM: If we were called by a children class,
Added: trunk/SQLObject/sqlobject/inheritance/tests/test_inherited_foreignKey.py
===================================================================
--- trunk/SQLObject/sqlobject/inheritance/tests/test_inherited_foreignKey.py 2005-06-01 13:48:41 UTC (rev 809)
+++ trunk/SQLObject/sqlobject/inheritance/tests/test_inherited_foreignKey.py 2005-06-03 16:13:48 UTC (rev 810)
@@ -0,0 +1,37 @@
+from sqlobject import *
+from sqlobject.tests.dbtest import *
+from sqlobject.inheritance import InheritableSQLObject
+
+
+class Note(SQLObject):
+ text = StringCol()
+
+class PersonWithNotes(InheritableSQLObject):
+ firstName = StringCol()
+ lastName = StringCol()
+ note = ForeignKey("Note", default=None)
+
+class EmployeeWithNotes(PersonWithNotes):
+ _inheritable = False
+
+def setup():
+ setupClass(Note)
+ setupClass(PersonWithNotes)
+ setupClass(EmployeeWithNotes)
+
+ note = Note(text="person")
+ PersonWithNotes(firstName='Oneof', lastName='Authors', note=note)
+ note = Note(text="employee")
+ EmployeeWithNotes(firstName='Project', lastName='Leader', note=note)
+
+
+def test_inheritance():
+ setup()
+
+ person = PersonWithNotes.get(1)
+ assert isinstance(person, PersonWithNotes) and not isinstance(person, EmployeeWithNotes)
+ assert person.note.text == "person"
+
+ employee = EmployeeWithNotes.get(2)
+ assert isinstance(employee, EmployeeWithNotes)
+ assert employee.note.text == "employee"
Modified: trunk/SQLObject/sqlobject/main.py
===================================================================
--- trunk/SQLObject/sqlobject/main.py 2005-06-01 13:48:41 UTC (rev 809)
+++ trunk/SQLObject/sqlobject/main.py 2005-06-03 16:13:48 UTC (rev 810)
@@ -475,6 +475,7 @@
# We don't setup the properties until we're finished with the
# batch adding of all the columns...
+ cls._notifyFinishClassCreation()
cls._SO_finishedClassCreation = True
makeProperties(cls)
@@ -796,6 +797,10 @@
delJoin = classmethod(delJoin)
+ def _notifyFinishClassCreation(cls):
+ pass
+ _notifyFinishClassCreation = classmethod(_notifyFinishClassCreation)
+
def _init(self, id, connection=None, selectResults=None):
assert id is not None
# This function gets called only when the object is
|
|
From: <sub...@co...> - 2005-06-01 13:48:47
|
Author: phd
Date: 2005-06-01 13:48:41 +0000 (Wed, 01 Jun 2005)
New Revision: 809
Added:
trunk/SQLObject/sqlobject/tests/test_SingleJoin.py
Modified:
trunk/SQLObject/docs/SQLObjectRelationships.txt
trunk/SQLObject/sqlobject/joins.py
Log:
Added SingleJoin. Thanks to michelts <mic...@gm...>.
Modified: trunk/SQLObject/docs/SQLObjectRelationships.txt
===================================================================
--- trunk/SQLObject/docs/SQLObjectRelationships.txt 2005-05-30 17:08:10 UTC (rev 808)
+++ trunk/SQLObject/docs/SQLObjectRelationships.txt 2005-06-01 13:48:41 UTC (rev 809)
@@ -9,7 +9,7 @@
~~~~~~~~~~~~~~~~~~~~~~~~~
See `One-to-Many Relationships`_ for an example of one-to-many
-relationships.
+relationships.
Several keyword arguments are allowed to the `MultipleJoin` constructor:
@@ -77,3 +77,8 @@
name = StringCol(length=50, alternateID=True)
roles = RelatedJoin('Person', joinColumn='role', otherColumn='person',
intermediateTable='assigned_roles')
+
+SingleJoin: One-to-One
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Similar to `MultipleJoin`, but returns just one object, not a list.
Modified: trunk/SQLObject/sqlobject/joins.py
===================================================================
--- trunk/SQLObject/sqlobject/joins.py 2005-05-30 17:08:10 UTC (rev 808)
+++ trunk/SQLObject/sqlobject/joins.py 2005-06-01 13:48:41 UTC (rev 809)
@@ -4,7 +4,7 @@
import classregistry
from col import popKey
-__all__ = ['MultipleJoin', 'SQLMultipleJoin', 'RelatedJoin', 'SQLRelatedJoin']
+__all__ = ['MultipleJoin', 'SQLMultipleJoin', 'RelatedJoin', 'SQLRelatedJoin', 'SingleJoin']
def getID(obj):
try:
@@ -133,17 +133,17 @@
conn = None
return self._applyOrderBy([self.otherClass.get(id, conn) for (id,) in ids if id is not None], self.otherClass)
+class MultipleJoin(Join):
+ baseClass = SOMultipleJoin
+
class SOSQLMultipleJoin(SOMultipleJoin):
def performJoin(self, inst):
- results=self.otherClass.select(getattr(self.otherClass.q, self.soClass.sqlmeta.style.dbColumnToPythonAttr(self.joinColumn))==inst.id)
+ results = self.otherClass.select(getattr(self.otherClass.q, self.soClass.sqlmeta.style.dbColumnToPythonAttr(self.joinColumn)) == inst.id)
if self.orderBy is NoDefault:
self.orderBy = self.otherClass.sqlmeta.defaultOrder
return results.orderBy(self.orderBy)
-class MultipleJoin(Join):
- baseClass = SOMultipleJoin
-
class SQLMultipleJoin(Join):
baseClass = SOSQLMultipleJoin
@@ -202,6 +202,9 @@
self.otherColumn,
getID(other))
+class RelatedJoin(MultipleJoin):
+ baseClass = SORelatedJoin
+
class SOSQLRelatedJoin(SORelatedJoin):
def performJoin(self, inst):
options={
@@ -225,11 +228,33 @@
# TODO (michelts), apply order by on the selection
return results
-class RelatedJoin(MultipleJoin):
- baseClass = SORelatedJoin
-
class SQLRelatedJoin(RelatedJoin):
baseClass = SOSQLRelatedJoin
def capitalize(name):
return name[0].capitalize() + name[1:]
+
+class SOSingleJoin(SOMultipleJoin):
+
+ def __init__(self, makeDefault=False, **kw):
+ SOMultipleJoin.__init__(self, **kw)
+ self.makeDefault = makeDefault
+
+ def performJoin(self, inst):
+ pythonColumn = self.soClass.sqlmeta.style.dbColumnToPythonAttr(self.joinColumn)
+ results = self.otherClass.select(getattr(self.otherClass.q, pythonColumn) == inst.id)
+ if results.count() == 0:
+ if not self.makeDefault:
+ return None
+ else:
+ kw = {pythonColumn[:-2]: inst} # skipping the ID (from foreignkeyID)
+ return self.otherClass(**kw) # instanciating the otherClass with all
+ # values to their defaults, except the foreign key
+ # TODO I don't think this is the best way to know the column as foreignKey
+ # reather than foreignKeyID, but I don't found a sqlmeta.style function
+ # to do the work, if there isn't such function, I must create it.
+ else:
+ return results[0]
+
+class SingleJoin(Join):
+ baseClass = SOSingleJoin
Added: trunk/SQLObject/sqlobject/tests/test_SingleJoin.py
===================================================================
--- trunk/SQLObject/sqlobject/tests/test_SingleJoin.py 2005-05-30 17:08:10 UTC (rev 808)
+++ trunk/SQLObject/sqlobject/tests/test_SingleJoin.py 2005-06-01 13:48:41 UTC (rev 809)
@@ -0,0 +1,25 @@
+from sqlobject import *
+from sqlobject.tests.dbtest import *
+
+class PersonWithAlbum(SQLObject):
+ name = StringCol()
+ # albumNone returns the album or none
+ albumNone = SingleJoin('PhotoAlbum', joinColumn='person_id')
+ # albumInstance returns the album or an default album instance
+ albumInstance = SingleJoin('PhotoAlbum', makeDefault=True, joinColumn='person_id')
+
+class PhotoAlbum(SQLObject):
+ color = StringCol(default='red')
+ person = ForeignKey('PersonWithAlbum')
+
+def test_1():
+ setupClass([PersonWithAlbum, PhotoAlbum])
+
+ person = PersonWithAlbum(name='Gokou (Kakarouto)')
+ assert not person.albumNone # I don't created an album, this way it returns None
+ assert isinstance(person.albumInstance, PhotoAlbum)
+
+ album = PhotoAlbum(person=person)
+ assert person.albumNone
+ assert isinstance(person.albumNone, PhotoAlbum)
+ assert isinstance(person.albumInstance, PhotoAlbum)
|
|
From: <sub...@co...> - 2005-05-26 22:22:47
|
Author: ianb
Date: 2005-05-26 22:22:34 +0000 (Thu, 26 May 2005)
New Revision: 807
Modified:
trunk/SQLObject/sqlobject/col.py
trunk/SQLObject/sqlobject/main.py
trunk/SQLObject/sqlobject/tests/test_basic.py
Log:
Fixed cascade='null', which was cascading deletes, instead of setting columns to null
Modified: trunk/SQLObject/sqlobject/col.py
===================================================================
--- trunk/SQLObject/sqlobject/col.py 2005-05-26 13:59:05 UTC (rev 806)
+++ trunk/SQLObject/sqlobject/col.py 2005-05-26 22:22:34 UTC (rev 807)
@@ -122,6 +122,10 @@
# None: no constraint is generated
# True: a CASCADE constraint is generated
# False: a RESTRICT constraint is generated
+ # 'null': a SET NULL trigger is generated
+ if isinstance(cascade, str):
+ assert cascade == 'null', (
+ "The only string value allowed for cascade is 'null' (you gave: %r)" % cascade)
self.cascade = cascade
if type(constraints) not in (type([]), type(())):
Modified: trunk/SQLObject/sqlobject/main.py
===================================================================
--- trunk/SQLObject/sqlobject/main.py 2005-05-26 13:59:05 UTC (rev 806)
+++ trunk/SQLObject/sqlobject/main.py 2005-05-26 22:22:34 UTC (rev 807)
@@ -1205,19 +1205,22 @@
connection=conn)
createTable = classmethod(createTable)
- def createTableSQL(cls, createJoinTables=True, connection=None):
+ def createTableSQL(cls, createJoinTables=True, connection=None,
+ createIndexes=True):
conn = connection or cls._connection
sql = conn.createTableSQL(cls)
if createJoinTables:
sql += '\n' + cls.createJoinTablesSQL(connection=conn)
+ if createIndexes:
+ sql += '\n' + cls.createIndexesSQL(connection=conn)
return sql
createTableSQL = classmethod(createTableSQL)
def createJoinTables(cls, ifNotExists=False, connection=None):
conn = connection or cls._connection
for join in cls._getJoinsToCreate():
- if ifNotExists and \
- conn.tableExists(join.intermediateTable):
+ if (ifNotExists and
+ conn.tableExists(join.intermediateTable)):
continue
conn._SO_createJoinTable(join)
createJoinTables = classmethod(createJoinTables)
@@ -1238,6 +1241,16 @@
conn._SO_createIndex(cls, index)
createIndexes = classmethod(createIndexes)
+ def createIndexesSQL(cls, connection=None):
+ conn = connection or cls._connection
+ sql = []
+ for index in cls.sqlmeta._indexList:
+ if not index:
+ continue
+ sql.append(conn.createIndexSQL(cls, index))
+ return '\n'.join(sql)
+ createIndexesSQL = classmethod(createIndexesSQL)
+
def _getJoinsToCreate(cls):
joins = []
for join in cls.sqlmeta._joinList:
@@ -1282,23 +1295,37 @@
for k in depends:
cols = findDependantColumns(klass.__name__, k)
query = []
- restrict = False
+ delete = setnull = restrict = False
for col in cols:
if col.cascade == False:
# Found a restriction
restrict = True
query.append("%s = %s" % (col.dbName, self.id))
+ if col.cascade == 'null':
+ setnull = col.name
+ elif col.cascade:
+ delete = True
+ assert delete or setnull or restrict, (
+ "Class %s depends on %s accoriding to "
+ "findDependantColumns, but this seems inaccurate"
+ % (k, klass))
query = ' OR '.join(query)
results = k.select(query, connection=self._connection)
- if restrict and results.count():
- # Restrictions only apply if there are
- # matching records on the related table
- raise SQLObjectIntegrityError, (
- "Tried to delete %s::%s but "
- "table %s has a restriction against it" %
- (klass.__name__, self.id, k.__name__))
- for row in results:
- row.destroySelf()
+ if restrict:
+ if results.count():
+ # Restrictions only apply if there are
+ # matching records on the related table
+ raise SQLObjectIntegrityError, (
+ "Tried to delete %s::%s but "
+ "table %s has a restriction against it" %
+ (klass.__name__, self.id, k.__name__))
+ else:
+ for row in results:
+ if delete:
+ row.destroySelf()
+ else:
+ row.set(**{setnull: None})
+
self.sqlmeta._obsolete = True
self._connection._SO_delete(self)
self._connection.cache.expire(self.id, self.__class__)
Modified: trunk/SQLObject/sqlobject/tests/test_basic.py
===================================================================
--- trunk/SQLObject/sqlobject/tests/test_basic.py 2005-05-26 13:59:05 UTC (rev 806)
+++ trunk/SQLObject/sqlobject/tests/test_basic.py 2005-05-26 22:22:34 UTC (rev 807)
@@ -120,7 +120,6 @@
assert TestSO3.selectBy(otherID=tc4.id)[0] == tc3
assert list(TestSO3.selectBy(otherID=tc4.id)[:10]) == [tc3]
assert list(TestSO3.selectBy(other=tc4)[:10]) == [tc3]
- assert 0
class TestSO5(SQLObject):
name = StringCol(length=10, dbName='name_col')
@@ -242,3 +241,27 @@
tc9a.destroySelf()
assert TestSO8.select().count() == 0
assert TestSO9.select().count() == 0
+
+class TestSO10(SQLObject):
+ name = StringCol()
+
+class TestSO11(SQLObject):
+ name = StringCol()
+ other = ForeignKey('TestSO10', default=None, cascade='null')
+
+def testForeignKeySetNull():
+ setupClass([TestSO10, TestSO11])
+ obj1 = TestSO10(name='foo')
+ obj2 = TestSO10(name='bar')
+ dep1 = TestSO11(name='xxx', other=obj1)
+ dep2 = TestSO11(name='yyy', other=obj1)
+ dep3 = TestSO11(name='zzz', other=obj2)
+ for name in 'xxx', 'yyy', 'zzz':
+ assert len(list(TestSO11.selectBy(name=name))) == 1
+ obj1.destroySelf()
+ for name in 'xxx', 'yyy', 'zzz':
+ assert len(list(TestSO11.selectBy(name=name))) == 1
+ assert dep1.other is None
+ assert dep2.other is None
+ assert dep3.other is obj2
+
|
|
From: <sub...@co...> - 2005-05-26 13:59:14
|
Author: phd Date: 2005-05-26 13:59:05 +0000 (Thu, 26 May 2005) New Revision: 806 Modified: trunk/SQLObject/sqlobject/include/validators.py Log: Applied the patch https://sourceforge.net/tracker/index.php?func=detail&aid=1198775&group_id=74338&atid=540674 . Modified: trunk/SQLObject/sqlobject/include/validators.py =================================================================== --- trunk/SQLObject/sqlobject/include/validators.py 2005-05-25 15:42:17 UTC (rev 805) +++ trunk/SQLObject/sqlobject/include/validators.py 2005-05-26 13:59:05 UTC (rev 806) @@ -994,7 +994,7 @@ except ValueError: return {self._ccNumberField: self.message('invalidNumber', "Please enter only the number, no other characters")} - assert _cardInfo.has_key(ccType), "I can't validate that type of credit card" + assert self._cardInfo.has_key(ccType), "I can't validate that type of credit card" foundValid = False validLength = False for prefix, length in self._cardInfo[ccType]: @@ -1009,7 +1009,7 @@ if not foundValid: return {self._ccNumberField: self.message('invalidNumber', "That number is not valid")} - if not _validateMod10(number): + if not self._validateMod10(number): return {self._ccNumberField: self.message('invalidNumber', "That number is not valid")} return None |
|
From: <sub...@co...> - 2005-05-22 19:32:11
|
Author: ianb
Date: 2005-05-22 19:32:05 +0000 (Sun, 22 May 2005)
New Revision: 796
Modified:
trunk/SQLObject/sqlobject/manager/command.py
Log:
Give a proper error message when using -f and paste.pyconfig cannot be found
Modified: trunk/SQLObject/sqlobject/manager/command.py
===================================================================
--- trunk/SQLObject/sqlobject/manager/command.py 2005-05-20 23:21:26 UTC (rev 795)
+++ trunk/SQLObject/sqlobject/manager/command.py 2005-05-22 19:32:05 UTC (rev 796)
@@ -9,7 +9,7 @@
try:
from paste import pyconfig
from paste import CONFIG
-except ImportError:
+except ImportError, e:
pyconfig = None
CONFIG = {}
import time
@@ -131,11 +131,10 @@
help="The database connection URI",
metavar='URI',
dest='connection_uri')
- if pyconfig:
- parser.add_option('-f', '--config-file',
- help="The Paste config file that contains the database URI (in the database key)",
- metavar="FILE",
- dest="config_file")
+ parser.add_option('-f', '--config-file',
+ help="The Paste config file that contains the database URI (in the database key)",
+ metavar="FILE",
+ dest="config_file")
if find_modules:
parser.add_option('-m', '--module',
help="Module in which to find SQLObject classes",
@@ -287,8 +286,10 @@
def config(self):
if getattr(self.options, 'config_file', None):
- assert pyconfig, (
- "The --config-file option should not be available without paste.pyconfig installed")
+ if not pyconfig:
+ print "You must have Python Paste installed (and on your $PYTHONPATH)"
+ print "to use the -f/--config-file option."
+ sys.exit(2)
config = pyconfig.Config(with_default=True)
config.load(self.options.config_file)
CONFIG.push_process_config(config)
|
|
From: <sub...@co...> - 2005-05-20 23:21:33
|
Author: ianb
Date: 2005-05-20 23:21:26 +0000 (Fri, 20 May 2005)
New Revision: 795
Modified:
trunk/SQLObject/sqlobject/manager/command.py
Log:
Added --edit option to record, so you can immediately create an upgrade script
Modified: trunk/SQLObject/sqlobject/manager/command.py
===================================================================
--- trunk/SQLObject/sqlobject/manager/command.py 2005-05-20 22:54:07 UTC (rev 794)
+++ trunk/SQLObject/sqlobject/manager/command.py 2005-05-20 23:21:26 UTC (rev 795)
@@ -5,6 +5,7 @@
import os
import sys
import textwrap
+import warnings
try:
from paste import pyconfig
from paste import CONFIG
@@ -18,6 +19,14 @@
from sqlobject.util import moduleloader
from sqlobject.declarative import DeclarativeMeta
+# It's not very unsafe to use tempnam like we are doing:
+warnings.filterwarnings(
+ 'ignore', 'tempnam is a potential security risk.*',
+ RuntimeWarning, '.*command', 28)
+
+def nowarning_tempnam(*args, **kw):
+ return os.tempnam(*args, **kw)
+
class SQLObjectVersionTable(sqlobject.SQLObject):
"""
This table is used to store information about the database and
@@ -321,6 +330,28 @@
fn = fn[len(os.getcwd())+1:]
return fn
+ def open_editor(self, pretext, breaker=None, extension='.txt'):
+ """
+ Open an editor with the given text. Return the new text,
+ or None if no edits were made. If given, everything after
+ `breaker` will be ignored.
+ """
+ fn = nowarning_tempnam() + extension
+ f = open(fn, 'w')
+ f.write(pretext)
+ f.close()
+ print '$EDITOR %s' % fn
+ os.system('$EDITOR %s' % fn)
+ f = open(fn, 'r')
+ content = f.read()
+ f.close()
+ if breaker:
+ content = content.split(breaker)[0]
+ pretext = pretext.split(breaker)[0]
+ if content == pretext or not content.strip():
+ return None
+ return content
+
class CommandSQL(Command):
name = 'sql'
@@ -617,6 +648,11 @@
"this tool, to create a 'beginning' revision.",
metavar="VERSION_NAME",
dest="force_db_version")
+ parser.add_option('--edit',
+ help="Open an editor for the upgrader in the last "
+ "version (using $EDITOR).",
+ action="store_true",
+ dest="open_editor")
version_regex = re.compile(r'^\d\d\d\d-\d\d-\d\d')
@@ -721,6 +757,24 @@
elif self.options.db_record:
for conn in conns:
self.update_db(version, conn)
+ if self.options.open_editor:
+ if not last_version_dir:
+ print ("Cannot edit upgrader because there is no "
+ "previous version")
+ else:
+ breaker = ('-'*20 + ' lines below this will be ignored '
+ + '-'*20)
+ pre_text = breaker + '\n' + '\n'.join(all_diffs)
+ text = self.open_editor('\n\n' + pre_text, breaker=breaker,
+ extension='.sql')
+ if text is not None:
+ fn = os.path.join(last_version_dir,
+ 'upgrade_%s_%s.sql' %
+ (dbName, version))
+ f = open(fn, 'w')
+ f.write(text)
+ f.close()
+ print 'Wrote to %s' % fn
def update_db(self, version, conn):
v = self.options.verbose
@@ -910,7 +964,7 @@
dbname, target_dbname)
continue
if version > dest:
- if self.verbose > 1:
+ if self.options.verbose > 1:
print 'Version too new: %s (only want %s)' % (
version, dest)
upgraders.append((version, os.path.join(current_dir, fn)))
|
|
From: <sub...@co...> - 2005-05-20 22:54:15
|
Author: ianb
Date: 2005-05-20 22:54:07 +0000 (Fri, 20 May 2005)
New Revision: 794
Modified:
trunk/SQLObject/sqlobject/manager/command.py
Log:
Fixed typo
Modified: trunk/SQLObject/sqlobject/manager/command.py
===================================================================
--- trunk/SQLObject/sqlobject/manager/command.py 2005-05-20 21:25:57 UTC (rev 793)
+++ trunk/SQLObject/sqlobject/manager/command.py 2005-05-20 22:54:07 UTC (rev 794)
@@ -905,7 +905,7 @@
dbname = match.group(1)
version = match.group(2)
if dbname != target_dbname:
- if self.verbose > 1:
+ if self.options.verbose > 1:
print 'Not for this database: %s (want %s)' % (
dbname, target_dbname)
continue
|
|
From: <sub...@co...> - 2005-05-20 21:26:04
|
Author: ianb
Date: 2005-05-20 21:25:57 +0000 (Fri, 20 May 2005)
New Revision: 793
Modified:
trunk/SQLObject/sqlobject/manager/command.py
Log:
Fixed typo
Modified: trunk/SQLObject/sqlobject/manager/command.py
===================================================================
--- trunk/SQLObject/sqlobject/manager/command.py 2005-05-18 20:32:19 UTC (rev 792)
+++ trunk/SQLObject/sqlobject/manager/command.py 2005-05-20 21:25:57 UTC (rev 793)
@@ -899,7 +899,7 @@
for fn in os.listdir(current_dir):
match = self.upgrade_regex.search(fn)
if not match:
- if self.verbose > 1:
+ if self.options.verbose > 1:
print 'Not an upgrade script: %s' % fn
continue
dbname = match.group(1)
|
|
From: <sub...@co...> - 2005-05-13 18:20:39
|
Author: ianb
Date: 2005-05-13 18:20:29 +0000 (Fri, 13 May 2005)
New Revision: 790
Modified:
trunk/SQLObject/sqlobject/tests/test_basic.py
Log:
Added some more tests of selectBy and stuff (that already passed anyway)
Modified: trunk/SQLObject/sqlobject/tests/test_basic.py
===================================================================
--- trunk/SQLObject/sqlobject/tests/test_basic.py 2005-05-10 19:27:15 UTC (rev 789)
+++ trunk/SQLObject/sqlobject/tests/test_basic.py 2005-05-13 18:20:29 UTC (rev 790)
@@ -23,6 +23,8 @@
bob = TestSO1.selectBy(name='bob')[0]
assert bob.name == 'bob'
assert bob.passwd == 'god'.encode('rot13')
+ bobs = TestSO1.selectBy(name='bob')[:10]
+ assert len(list(bobs)) == 1
def test_newline():
setupGetters(TestSO1)
@@ -107,6 +109,19 @@
tcc2 = TestSO3(name='c', other=tc4a.id)
assert tcc2.other == tc4a
+def test_selectBy():
+ setupClass([TestSO4, TestSO3])
+ tc4 = TestSO4(me='another')
+ tc3 = TestSO3(name='sel', other=tc4)
+ anothertc3 = TestSO3(name='not joined')
+ assert tc3.other == tc4
+ assert list(TestSO3.selectBy(other=tc4)) == [tc3]
+ assert list(TestSO3.selectBy(otherID=tc4.id)) == [tc3]
+ assert TestSO3.selectBy(otherID=tc4.id)[0] == tc3
+ assert list(TestSO3.selectBy(otherID=tc4.id)[:10]) == [tc3]
+ assert list(TestSO3.selectBy(other=tc4)[:10]) == [tc3]
+ assert 0
+
class TestSO5(SQLObject):
name = StringCol(length=10, dbName='name_col')
other = ForeignKey('TestSO6', default=None, cascade=True)
|
|
From: <sub...@co...> - 2005-05-10 19:27:26
|
Author: ianb
Date: 2005-05-10 19:27:15 +0000 (Tue, 10 May 2005)
New Revision: 789
Modified:
trunk/SQLObject/sqlobject/dbconnection.py
Log:
New method to retrieve db description with rows
Modified: trunk/SQLObject/sqlobject/dbconnection.py
===================================================================
--- trunk/SQLObject/sqlobject/dbconnection.py 2005-05-10 17:38:24 UTC (rev 788)
+++ trunk/SQLObject/sqlobject/dbconnection.py 2005-05-10 19:27:15 UTC (rev 789)
@@ -312,6 +312,23 @@
def queryAll(self, s):
return self._runWithConnection(self._queryAll, s)
+ def _queryAllDescription(self, conn, s):
+ """
+ Like queryAll, but returns (description, rows), where the
+ description is cursor.description (which gives row types)
+ """
+ if self.debug:
+ self.printDebug(conn, s, 'QueryAllDesc')
+ c = conn.cursor()
+ self._executeRetry(conn, c, s)
+ value = c.fetchall()
+ if self.debugOutput:
+ self.printDebug(conn, value, 'QueryAll', 'result')
+ return c.description, value
+
+ def queryAllDescription(self, s):
+ return self._runWithConnection(self._queryAllDescription, s)
+
def _queryOne(self, conn, s):
if self.debug:
self.printDebug(conn, s, 'QueryOne')
|
|
From: <sub...@co...> - 2005-05-10 17:38:30
|
Author: ianb
Date: 2005-05-10 17:38:24 +0000 (Tue, 10 May 2005)
New Revision: 788
Modified:
trunk/SQLObject/sqlobject/tests/test_selectBy_foreignKey.py
Log:
Fixed (another) duplicate name
Modified: trunk/SQLObject/sqlobject/tests/test_selectBy_foreignKey.py
===================================================================
--- trunk/SQLObject/sqlobject/tests/test_selectBy_foreignKey.py 2005-05-10 17:37:43 UTC (rev 787)
+++ trunk/SQLObject/sqlobject/tests/test_selectBy_foreignKey.py 2005-05-10 17:38:24 UTC (rev 788)
@@ -4,30 +4,30 @@
class TestComposerKey(SQLObject):
name = StringCol()
-class TestWork(SQLObject):
+class TestWorkKey(SQLObject):
class sqlmeta:
idName = "work_id"
- composer = ForeignKey('TestComposer')
+ composer = ForeignKey('TestComposerKey')
title = StringCol()
def test1():
setupClass([TestComposerKey,
- TestWork])
+ TestWorkKey])
c = TestComposerKey(name='Mahler, Gustav')
- w1 = TestWork(composer=c, title='Symphony No. 9')
- w2 = TestWork(composer=None, title=None)
+ w1 = TestWorkKey(composer=c, title='Symphony No. 9')
+ w2 = TestWorkKey(composer=None, title=None)
# Select by usual way
- s = TestWork.selectBy(composerID=c.id, title='Symphony No. 9')
+ s = TestWorkKey.selectBy(composerID=c.id, title='Symphony No. 9')
assert s[0]==w1
# selectBy object
- s = TestWork.selectBy(composer=c, title='Symphony No. 9')
+ s = TestWorkKey.selectBy(composer=c, title='Symphony No. 9')
assert s[0]==w1
# selectBy id
- s = TestWork.selectBy(id=w1.id)
+ s = TestWorkKey.selectBy(id=w1.id)
assert s[0]==w1
# is None handled correctly?
- s = TestWork.selectBy(composer=None, title=None)
+ s = TestWorkKey.selectBy(composer=None, title=None)
assert s[0]==w2
|
|
From: <sub...@co...> - 2005-05-10 17:37:49
|
Author: ianb
Date: 2005-05-10 17:37:43 +0000 (Tue, 10 May 2005)
New Revision: 787
Modified:
trunk/SQLObject/sqlobject/tests/test_selectBy_foreignKey.py
Log:
Fixed duplicate name
Modified: trunk/SQLObject/sqlobject/tests/test_selectBy_foreignKey.py
===================================================================
--- trunk/SQLObject/sqlobject/tests/test_selectBy_foreignKey.py 2005-05-10 17:36:37 UTC (rev 786)
+++ trunk/SQLObject/sqlobject/tests/test_selectBy_foreignKey.py 2005-05-10 17:37:43 UTC (rev 787)
@@ -1,7 +1,7 @@
from sqlobject import *
from sqlobject.tests.dbtest import *
-class TestComposer(SQLObject):
+class TestComposerKey(SQLObject):
name = StringCol()
class TestWork(SQLObject):
@@ -12,10 +12,10 @@
title = StringCol()
def test1():
- setupClass(TestComposer)
- setupClass(TestWork)
+ setupClass([TestComposerKey,
+ TestWork])
- c = TestComposer(name='Mahler, Gustav')
+ c = TestComposerKey(name='Mahler, Gustav')
w1 = TestWork(composer=c, title='Symphony No. 9')
w2 = TestWork(composer=None, title=None)
|
|
From: <sub...@co...> - 2005-05-10 17:36:44
|
Author: ianb
Date: 2005-05-10 17:36:37 +0000 (Tue, 10 May 2005)
New Revision: 786
Modified:
trunk/SQLObject/sqlobject/tests/test_enum.py
Log:
Postgres raises a different exception than MySQL
Modified: trunk/SQLObject/sqlobject/tests/test_enum.py
===================================================================
--- trunk/SQLObject/sqlobject/tests/test_enum.py 2005-05-10 17:35:09 UTC (rev 785)
+++ trunk/SQLObject/sqlobject/tests/test_enum.py 2005-05-10 17:36:37 UTC (rev 786)
@@ -16,4 +16,7 @@
for l in ['a', 'bcd', 'a', 'e']:
Enum1(l=l)
if supports('restrictedEnum'):
- raises(Enum1._connection.module.IntegrityError, Enum1, l='b')
+ raises(
+ (Enum1._connection.module.IntegrityError,
+ Enum1._connection.module.ProgrammingError),
+ Enum1, l='b')
|
|
From: <sub...@co...> - 2005-05-10 17:35:17
|
Author: ianb
Date: 2005-05-10 17:35:09 +0000 (Tue, 10 May 2005)
New Revision: 785
Modified:
trunk/SQLObject/sqlobject/tests/dbtest.py
Log:
Make sure not to clear or drop a table that doesn't exist
Modified: trunk/SQLObject/sqlobject/tests/dbtest.py
===================================================================
--- trunk/SQLObject/sqlobject/tests/dbtest.py 2005-05-10 17:31:29 UTC (rev 784)
+++ trunk/SQLObject/sqlobject/tests/dbtest.py 2005-05-10 17:35:09 UTC (rev 785)
@@ -127,10 +127,11 @@
any_drops = True
break
for soClass in reversed:
- if any_drops:
- cls.drop(soClass)
- else:
- cls.clear(soClass)
+ if soClass._connection.tableExists(soClass.sqlmeta.table):
+ if any_drops:
+ cls.drop(soClass)
+ else:
+ cls.clear(soClass)
for soClass in soClasses:
table = soClass.sqlmeta.table
if not soClass._connection.tableExists(table):
|
|
From: <sub...@co...> - 2005-05-10 17:31:34
|
Author: ianb
Date: 2005-05-10 17:31:29 +0000 (Tue, 10 May 2005)
New Revision: 784
Modified:
trunk/SQLObject/sqlobject/conftest.py
trunk/SQLObject/sqlobject/tests/dbtest.py
Log:
Added option to show query output
Modified: trunk/SQLObject/sqlobject/conftest.py
===================================================================
--- trunk/SQLObject/sqlobject/conftest.py 2005-05-10 17:25:13 UTC (rev 783)
+++ trunk/SQLObject/sqlobject/conftest.py 2005-05-10 17:31:29 UTC (rev 784)
@@ -33,7 +33,11 @@
Option('-S', '--SQL',
action="store_true", dest="show_sql", default=False,
help="Show SQL from statements (when capturing stdout the "
- "SQL is only displayed when a test fails)"))
+ "SQL is only displayed when a test fails)"),
+ Option('-O', '--SQL-output',
+ action="store_true", dest="show_sql_output", default=False,
+ help="Show output from SQL statements (when capturing "
+ "stdout the output is only displayed when a test fails)"))
class SQLObjectClass(py.test.collect.Class):
def run(self):
Modified: trunk/SQLObject/sqlobject/tests/dbtest.py
===================================================================
--- trunk/SQLObject/sqlobject/tests/dbtest.py 2005-05-10 17:25:13 UTC (rev 783)
+++ trunk/SQLObject/sqlobject/tests/dbtest.py 2005-05-10 17:31:29 UTC (rev 784)
@@ -83,6 +83,8 @@
conn = sqlobject.connectionForURI(name, **kw)
if conftest.option.show_sql:
conn.debug = True
+ if conftest.option.show_sql_output:
+ conn.debugOutput = True
return conn
connection = getConnection()
|
|
From: <sub...@co...> - 2005-05-10 17:25:20
|
Author: ianb
Date: 2005-05-10 17:25:13 +0000 (Tue, 10 May 2005)
New Revision: 783
Modified:
trunk/SQLObject/sqlobject/tests/test_NoneValuedResultItem.py
trunk/SQLObject/sqlobject/tests/test_SQLMultipleJoin.py
Log:
Make sure all of a set of related classes are created/dropped in the right order
Modified: trunk/SQLObject/sqlobject/tests/test_NoneValuedResultItem.py
===================================================================
--- trunk/SQLObject/sqlobject/tests/test_NoneValuedResultItem.py 2005-05-10 17:24:54 UTC (rev 782)
+++ trunk/SQLObject/sqlobject/tests/test_NoneValuedResultItem.py 2005-05-10 17:25:13 UTC (rev 783)
@@ -14,8 +14,8 @@
title = StringCol()
def test1():
- setupClass(TestComposer)
- setupClass(TestWork)
+ setupClass([TestComposer,
+ TestWork])
c = TestComposer(name='Mahler, Gustav')
w = TestWork(composer=c, title='Symphony No. 9')
Modified: trunk/SQLObject/sqlobject/tests/test_SQLMultipleJoin.py
===================================================================
--- trunk/SQLObject/sqlobject/tests/test_SQLMultipleJoin.py 2005-05-10 17:24:54 UTC (rev 782)
+++ trunk/SQLObject/sqlobject/tests/test_SQLMultipleJoin.py 2005-05-10 17:25:13 UTC (rev 783)
@@ -12,8 +12,7 @@
power = IntCol()
def createAllTables():
- setupClass(RFighter)
- setupClass(Race)
+ setupClass([Race, RFighter])
def test_1():
createAllTables()
|
|
From: <sub...@co...> - 2005-05-10 17:25:00
|
Author: ianb
Date: 2005-05-10 17:24:54 +0000 (Tue, 10 May 2005)
New Revision: 782
Modified:
trunk/SQLObject/sqlobject/tests/dbtest.py
Log:
If any classes must be dropped, they all must be dropped
Modified: trunk/SQLObject/sqlobject/tests/dbtest.py
===================================================================
--- trunk/SQLObject/sqlobject/tests/dbtest.py 2005-05-10 17:20:20 UTC (rev 781)
+++ trunk/SQLObject/sqlobject/tests/dbtest.py 2005-05-10 17:24:54 UTC (rev 782)
@@ -104,6 +104,8 @@
cls.setup()
reversed = list(soClasses)[:]
reversed.reverse()
+ # If anything needs to be dropped, they all must be dropped
+ any_drops = False
for soClass in reversed:
table = soClass.sqlmeta.table
if not soClass._connection.tableExists(table):
@@ -120,6 +122,10 @@
if sql != newSQL:
if sql is not None:
instance.destroySelf()
+ any_drops = True
+ break
+ for soClass in reversed:
+ if any_drops:
cls.drop(soClass)
else:
cls.clear(soClass)
|
|
From: <sub...@co...> - 2005-05-10 17:20:34
|
Author: ianb
Date: 2005-05-10 17:20:20 +0000 (Tue, 10 May 2005)
New Revision: 781
Modified:
trunk/SQLObject/sqlobject/conftest.py
trunk/SQLObject/sqlobject/tests/dbtest.py
Log:
Added test option to show SQL
Modified: trunk/SQLObject/sqlobject/conftest.py
===================================================================
--- trunk/SQLObject/sqlobject/conftest.py 2005-05-10 17:10:27 UTC (rev 780)
+++ trunk/SQLObject/sqlobject/conftest.py 2005-05-10 17:20:20 UTC (rev 781)
@@ -29,7 +29,11 @@
action="store", dest="Database", default='sqlite',
help="The database to run the tests under (default sqlite). "
"Can also use an alias from: %s"
- % (', '.join(connectionShortcuts.keys()))))
+ % (', '.join(connectionShortcuts.keys()))),
+ Option('-S', '--SQL',
+ action="store_true", dest="show_sql", default=False,
+ help="Show SQL from statements (when capturing stdout the "
+ "SQL is only displayed when a test fails)"))
class SQLObjectClass(py.test.collect.Class):
def run(self):
Modified: trunk/SQLObject/sqlobject/tests/dbtest.py
===================================================================
--- trunk/SQLObject/sqlobject/tests/dbtest.py 2005-05-10 17:10:27 UTC (rev 780)
+++ trunk/SQLObject/sqlobject/tests/dbtest.py 2005-05-10 17:20:20 UTC (rev 781)
@@ -80,7 +80,10 @@
name = conftest.option.Database
if conftest.connectionShortcuts.has_key(name):
name = conftest.connectionShortcuts[name]
- return sqlobject.connectionForURI(name, **kw)
+ conn = sqlobject.connectionForURI(name, **kw)
+ if conftest.option.show_sql:
+ conn.debug = True
+ return conn
connection = getConnection()
|
|
From: <sub...@co...> - 2005-05-10 17:10:45
|
Author: ianb
Date: 2005-05-10 17:10:27 +0000 (Tue, 10 May 2005)
New Revision: 780
Modified:
trunk/SQLObject/sqlobject/conftest.py
Log:
Don't collect SQLObject Test* classes
Modified: trunk/SQLObject/sqlobject/conftest.py
===================================================================
--- trunk/SQLObject/sqlobject/conftest.py 2005-05-10 17:02:35 UTC (rev 779)
+++ trunk/SQLObject/sqlobject/conftest.py 2005-05-10 17:10:27 UTC (rev 780)
@@ -9,6 +9,7 @@
import py
import os
+import sqlobject
connectionShortcuts = {
'mysql': 'mysql://test@localhost/test',
@@ -29,3 +30,12 @@
help="The database to run the tests under (default sqlite). "
"Can also use an alias from: %s"
% (', '.join(connectionShortcuts.keys()))))
+
+class SQLObjectClass(py.test.collect.Class):
+ def run(self):
+ if (isinstance(self.obj, type)
+ and issubclass(self.obj, sqlobject.SQLObject)):
+ return []
+ return super(SQLObjectClass, self).run()
+
+Class = SQLObjectClass
|
|
From: <sub...@co...> - 2005-05-10 17:02:44
|
Author: ianb
Date: 2005-05-10 17:02:35 +0000 (Tue, 10 May 2005)
New Revision: 779
Added:
trunk/SQLObject/sqlobject/conftest.py
Modified:
trunk/SQLObject/sqlobject/tests/dbtest.py
Log:
Use py.test conftest file to add a --Database option (instead of postgres)... more customization upcoming
Added: trunk/SQLObject/sqlobject/conftest.py
===================================================================
--- trunk/SQLObject/sqlobject/conftest.py 2005-05-07 05:54:12 UTC (rev 778)
+++ trunk/SQLObject/sqlobject/conftest.py 2005-05-10 17:02:35 UTC (rev 779)
@@ -0,0 +1,31 @@
+"""
+This module is used by py.test to configure testing for this
+application.
+"""
+
+# Override some options (doesn't override command line):
+verbose = 0
+exitfirst = True
+
+import py
+import os
+
+connectionShortcuts = {
+ 'mysql': 'mysql://test@localhost/test',
+ 'dbm': 'dbm:///data',
+ 'postgres': 'postgres:///test',
+ 'postgresql': 'postgres:///test',
+ 'pygresql': 'pygresql://localhost/test',
+ 'sqlite': 'sqlite:///%s/data/sqlite.data' % os.getcwd(),
+ 'sybase': 'sybase://test:test123@sybase/test?autoCommit=0',
+ 'firebird': 'firebird://sysdba:masterkey@localhost/var/lib/firebird/data/test.gdb',
+ }
+
+Option = py.test.Config.Option
+option = py.test.Config.addoptions(
+ "SQLObject options",
+ Option('-D', '--Database',
+ action="store", dest="Database", default='sqlite',
+ help="The database to run the tests under (default sqlite). "
+ "Can also use an alias from: %s"
+ % (', '.join(connectionShortcuts.keys()))))
Modified: trunk/SQLObject/sqlobject/tests/dbtest.py
===================================================================
--- trunk/SQLObject/sqlobject/tests/dbtest.py 2005-05-07 05:54:12 UTC (rev 778)
+++ trunk/SQLObject/sqlobject/tests/dbtest.py 2005-05-10 17:02:35 UTC (rev 779)
@@ -5,8 +5,10 @@
import sys
import os
import re
-import sqlobject
from py.test import raises
+import py
+import sqlobject
+import sqlobject.conftest as conftest
if sys.platform[:3] == "win":
def getcwd():
@@ -14,17 +16,6 @@
else:
getcwd = os.getcwd
-connectionShortcuts = {
- 'mysql': 'mysql://test@localhost/test',
- 'dbm': 'dbm:///data',
- 'postgres': 'postgres:///test',
- 'postgresql': 'postgres:///test',
- 'pygresql': 'pygresql://localhost/test',
- 'sqlite': 'sqlite:///%s/data/sqlite.data' % getcwd(),
- 'sybase': 'sybase://test:test123@sybase/test?autoCommit=0',
- 'firebird': 'firebird://sysdba:masterkey@localhost/var/lib/firebird/data/test.gdb',
- }
-
"""
supportsMatrix defines what database backends support what features.
Each feature has a name, if you see a key like '+featureName' then
@@ -86,17 +77,16 @@
'sqlite:///' + installedDBFilename)
def getConnection(**kw):
- name = os.environ.get('TESTDB')
- assert name, 'You must set $TESTDB to do database operations'
- if connectionShortcuts.has_key(name):
- name = connectionShortcuts[name]
+ name = conftest.option.Database
+ if conftest.connectionShortcuts.has_key(name):
+ name = conftest.connectionShortcuts[name]
return sqlobject.connectionForURI(name, **kw)
connection = getConnection()
class InstalledTestDatabase(sqlobject.SQLObject):
"""
- This table is set up in SQLite (always, regardless of $TESTDB) and
+ This table is set up in SQLite (always, regardless of --Database) and
tracks what tables have been set up in the 'real' database. This
way we don't keep recreating the tables over and over when there
are multiple tests that use a table.
|
|
From: <sub...@co...> - 2005-05-07 05:54:17
|
Author: daverz
Date: 2005-05-07 05:54:12 +0000 (Sat, 07 May 2005)
New Revision: 778
Modified:
trunk/SQLObject/sqlobject/dbconnection.py
Log:
In Iteration.next(), handle the case where the id is None by returning None.
With outer joins this is a common case, e.g.
Contact.select(join=LEFTJOINOn(Customer, Contact,
Customer.q.id==Contact.q.customerID))
where some customers have no contacts.
Modified: trunk/SQLObject/sqlobject/dbconnection.py
===================================================================
--- trunk/SQLObject/sqlobject/dbconnection.py 2005-05-07 05:38:05 UTC (rev 777)
+++ trunk/SQLObject/sqlobject/dbconnection.py 2005-05-07 05:54:12 UTC (rev 778)
@@ -665,6 +665,8 @@
if result is None:
self._cleanup()
raise StopIteration
+ if result[0] is None:
+ return None
if self.select.ops.get('lazyColumns', 0):
obj = self.select.sourceClass.get(result[0], connection=self.dbconn)
return obj
|
|
From: <sub...@co...> - 2005-05-07 05:38:11
|
Author: daverz
Date: 2005-05-07 05:38:05 +0000 (Sat, 07 May 2005)
New Revision: 777
Added:
trunk/SQLObject/sqlobject/tests/test_NoneValuedResultItem.py
Log:
Test that query results with None IDs (e.g. some outer join cases)
are handled correctly, i.e. return None for that object.
Added: trunk/SQLObject/sqlobject/tests/test_NoneValuedResultItem.py
===================================================================
--- trunk/SQLObject/sqlobject/tests/test_NoneValuedResultItem.py 2005-05-06 17:07:38 UTC (rev 776)
+++ trunk/SQLObject/sqlobject/tests/test_NoneValuedResultItem.py 2005-05-07 05:38:05 UTC (rev 777)
@@ -0,0 +1,28 @@
+'''Test that selectResults handle NULL values
+from, for example, outer joins.'''
+from sqlobject import *
+from sqlobject.tests.dbtest import *
+
+class TestComposer(SQLObject):
+ name = StringCol()
+
+class TestWork(SQLObject):
+ class sqlmeta:
+ idName = "work_id"
+
+ composer = ForeignKey('TestComposer')
+ title = StringCol()
+
+def test1():
+ setupClass(TestComposer)
+ setupClass(TestWork)
+
+ c = TestComposer(name='Mahler, Gustav')
+ w = TestWork(composer=c, title='Symphony No. 9')
+ c2 = TestComposer(name='Bruckner, Anton')
+ # but don't add any works for Bruckner
+
+ # do a left join, a common use case that often involves NULL results
+ s = TestWork.select(join=sqlbuilder.LEFTJOINOn(TestComposer, TestWork,
+ TestComposer.q.id==TestWork.q.composerID))
+ assert tuple(s)==(w, None)
|
|
From: <sub...@co...> - 2005-05-06 17:07:52
|
Author: ianb
Date: 2005-05-06 17:07:38 +0000 (Fri, 06 May 2005)
New Revision: 776
Modified:
trunk/SQLObject/sqlobject/tests/test_aliases.py
Log:
py.test was catching class named Test*
Modified: trunk/SQLObject/sqlobject/tests/test_aliases.py
===================================================================
--- trunk/SQLObject/sqlobject/tests/test_aliases.py 2005-05-06 17:02:42 UTC (rev 775)
+++ trunk/SQLObject/sqlobject/tests/test_aliases.py 2005-05-06 17:07:38 UTC (rev 776)
@@ -6,22 +6,22 @@
## Table aliases and self-joins
########################################
-class TestJoinAlias(SQLObject):
+class JoinAlias(SQLObject):
name = StringCol()
parent = StringCol()
def test_1syntax():
- setupClass(TestJoinAlias)
- alias = Alias(TestJoinAlias)
- select = TestJoinAlias.select(TestJoinAlias.q.parent == alias.q.name)
+ setupClass(JoinAlias)
+ alias = Alias(JoinAlias)
+ select = JoinAlias.select(JoinAlias.q.parent == alias.q.name)
assert str(select) == \
- "SELECT test_join_alias.id, test_join_alias.name, test_join_alias.parent FROM test_join_alias, test_join_alias AS test_join_alias_alias1 WHERE (test_join_alias.parent = test_join_alias_alias1.name)"
+ "SELECT join_alias.id, join_alias.name, join_alias.parent FROM join_alias AS join_alias_alias1, join_alias WHERE (join_alias.parent = join_alias_alias1.name)"
def test_2perform_join():
- setupClass(TestJoinAlias)
- TestJoinAlias(name="grandparent", parent=None)
- TestJoinAlias(name="parent", parent="grandparent")
- TestJoinAlias(name="child", parent="parent")
- alias = Alias(TestJoinAlias)
- select = TestJoinAlias.select(TestJoinAlias.q.parent == alias.q.name)
+ setupClass(JoinAlias)
+ JoinAlias(name="grandparent", parent=None)
+ JoinAlias(name="parent", parent="grandparent")
+ JoinAlias(name="child", parent="parent")
+ alias = Alias(JoinAlias)
+ select = JoinAlias.select(JoinAlias.q.parent == alias.q.name)
assert select.count() == 2
|
|
From: <sub...@co...> - 2005-05-06 17:02:50
|
Author: ianb
Date: 2005-05-06 17:02:42 +0000 (Fri, 06 May 2005)
New Revision: 775
Modified:
trunk/SQLObject/sqlobject/tests/test_SQLMultipleJoin.py
Log:
Create database in wrong order
Modified: trunk/SQLObject/sqlobject/tests/test_SQLMultipleJoin.py
===================================================================
--- trunk/SQLObject/sqlobject/tests/test_SQLMultipleJoin.py 2005-05-06 16:29:30 UTC (rev 774)
+++ trunk/SQLObject/sqlobject/tests/test_SQLMultipleJoin.py 2005-05-06 17:02:42 UTC (rev 775)
@@ -12,8 +12,8 @@
power = IntCol()
def createAllTables():
+ setupClass(RFighter)
setupClass(Race)
- setupClass(RFighter)
def test_1():
createAllTables()
|