sqlobject-cvs Mailing List for SQLObject (Page 188)
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: <ian...@us...> - 2003-06-04 05:19:08
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject
In directory sc8-pr-cvs1:/tmp/cvs-serv11549/SQLObject
Modified Files:
Join.py
Log Message:
Trim null values from joins
Index: Join.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Join.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** Join.py 30 May 2003 02:22:51 -0000 1.2
--- Join.py 4 Jun 2003 05:19:05 -0000 1.3
***************
*** 82,86 ****
self.joinColumn,
inst.id)
! return self._applyOrderBy([self.otherClass(id) for (id,) in ids], self.otherClass)
class MultipleJoin(Join):
--- 82,86 ----
self.joinColumn,
inst.id)
! return self._applyOrderBy([self.otherClass(id) for (id,) in ids if id is not None], self.otherClass)
class MultipleJoin(Join):
***************
*** 118,122 ****
self.joinColumn,
inst.id)
! return self._applyOrderBy([self.otherClass(id) for (id,) in ids], self.otherClass)
def remove(self, inst, other):
--- 118,122 ----
self.joinColumn,
inst.id)
! return self._applyOrderBy([self.otherClass(id) for (id,) in ids if id is not None], self.otherClass)
def remove(self, inst, other):
|
|
From: <ian...@us...> - 2003-05-31 02:00:42
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject
In directory sc8-pr-cvs1:/tmp/cvs-serv14543
Modified Files:
SQLObject.py
Log Message:
More foreignKey fixes
Index: SQLObject.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/SQLObject.py,v
retrieving revision 1.43
retrieving revision 1.44
diff -C2 -d -r1.43 -r1.44
*** SQLObject.py 30 May 2003 03:24:53 -0000 1.43
--- SQLObject.py 31 May 2003 02:00:39 -0000 1.44
***************
*** 85,90 ****
cls = findClass(needClass, registry=registryName)
for obj, attr in q:
! if callable(getattr(obj, attr, None)):
! getattr(obj, attr)(cls)
else:
setattr(obj, attr, cls)
--- 85,93 ----
cls = findClass(needClass, registry=registryName)
for obj, attr in q:
! curr = getattr(obj, attr, None)
! if curr is cls:
! pass
! elif callable(curr):
! curr(cls)
else:
setattr(obj, attr, cls)
***************
*** 469,473 ****
# self._SO_class_className is a reference
# to the class in question.
! getter = eval('lambda self: self._SO_foreignKey(self.%s and self._SO_class_%s)' % (instanceName(name), column.foreignKey))
else:
# Same non-caching version as above.
--- 472,476 ----
# self._SO_class_className is a reference
# to the class in question.
! getter = eval('lambda self: self._SO_foreignKey(self.%s, self._SO_class_%s)' % (instanceName(name), column.foreignKey))
else:
# Same non-caching version as above.
|
|
From: <ian...@us...> - 2003-05-31 02:00:30
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject
In directory sc8-pr-cvs1:/tmp/cvs-serv14448
Modified Files:
Col.py
Log Message:
Made *ID keys names more permissive -- if you don't add the ID,
it gets added for you.
Index: Col.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Col.py,v
retrieving revision 1.22
retrieving revision 1.23
diff -C2 -d -r1.22 -r1.23
*** Col.py 26 May 2003 21:48:54 -0000 1.22
--- Col.py 31 May 2003 02:00:27 -0000 1.23
***************
*** 89,94 ****
self.foreignKey = foreignKey
if self.foreignKey:
! assert self.name.upper().endswith('ID'), "All foreign key columns must end with 'ID' (%s)" % repr(self.name)
! self.foreignName = self.name[:-2]
else:
self.foreignName = None
--- 89,98 ----
self.foreignKey = foreignKey
if self.foreignKey:
! #assert self.name.upper().endswith('ID'), "All foreign key columns must end with 'ID' (%s)" % repr(self.name)
! if not self.name.upper().endswith('ID'):
! self.foreignName = self.name
! self.name = self.name + "ID"
! else:
! self.foreignName = self.name[:-2]
else:
self.foreignName = None
|
|
From: <ian...@us...> - 2003-05-31 01:59:48
|
Update of /cvsroot/sqlobject/SQLObject/tests
In directory sc8-pr-cvs1:/tmp/cvs-serv14231/tests
Modified Files:
test.py
Log Message:
Proper test of foreign keys
Index: test.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/tests/test.py,v
retrieving revision 1.15
retrieving revision 1.16
diff -C2 -d -r1.15 -r1.16
*** test.py 24 May 2003 20:48:51 -0000 1.15
--- test.py 31 May 2003 01:59:45 -0000 1.16
***************
*** 55,58 ****
--- 55,98 ----
MyClass = TestSO2
+ class TestSO3(SQLObject):
+ name = StringCol(length=10)
+ other = ForeignKey('TestSO4', default=None)
+ other2 = KeyCol(foreignKey='TestSO4', default=None)
+
+ class TestSO4(SQLObject):
+ me = StringCol(length=10)
+
+ class TestCase34(SQLObjectTest):
+
+ classes = [TestSO3, TestSO4]
+
+ def testForeignKey(self):
+ tc3 = TestSO3.new(name='a')
+ self.assertEqual(tc3.other, None)
+ self.assertEqual(tc3.other2, None)
+ self.assertEqual(tc3.otherID, None)
+ self.assertEqual(tc3.other2ID, None)
+ tc4a = TestSO4.new(me='1')
+ tc3.other = tc4a
+ self.assertEqual(tc3.other, tc4a)
+ self.assertEqual(tc3.otherID, tc4a.id)
+ tc4b = TestSO4.new(me='2')
+ tc3.other = tc4b.id
+ self.assertEqual(tc3.other, tc4b)
+ self.assertEqual(tc3.otherID, tc4b.id)
+ tc4c = TestSO4.new(me='3')
+ tc3.other2 = tc4c
+ self.assertEqual(tc3.other2, tc4c)
+ self.assertEqual(tc3.other2ID, tc4c.id)
+ tc4d = TestSO4.new(me='4')
+ tc3.other2 = tc4d.id
+ self.assertEqual(tc3.other2, tc4d)
+ self.assertEqual(tc3.other2ID, tc4d.id)
+
+
+
+
+
+
########################################
## Delete during select
|
|
From: <ian...@us...> - 2003-05-30 03:49:03
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject
In directory sc8-pr-cvs1:/tmp/cvs-serv2322/SQLObject
Modified Files:
SQLObject.py
Log Message:
Continued fix for foreignKey
Index: SQLObject.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/SQLObject.py,v
retrieving revision 1.42
retrieving revision 1.43
diff -C2 -d -r1.42 -r1.43
*** SQLObject.py 30 May 2003 02:22:51 -0000 1.42
--- SQLObject.py 30 May 2003 03:24:53 -0000 1.43
***************
*** 469,476 ****
# self._SO_class_className is a reference
# to the class in question.
! getter = eval('lambda self: self._SO_foreignKey(self.%s and self._SO_class_%s)' % (column.foreignKey, instanceName(name)))
else:
# Same non-caching version as above.
! getter = eval('lambda self: self._SO_class_%s(self._SO_getValue(%s))' % (column.foreignKey, repr(name)))
setattr(cls, rawGetterName(name)[:-2], getter)
--- 469,476 ----
# self._SO_class_className is a reference
# to the class in question.
! getter = eval('lambda self: self._SO_foreignKey(self.%s and self._SO_class_%s)' % (instanceName(name), column.foreignKey))
else:
# Same non-caching version as above.
! getter = eval('lambda self: self._SO_foreignKey(self._SO_getValue(%s), self._SO_class_%s)' % (repr(name), column.foreignKey))
setattr(cls, rawGetterName(name)[:-2], getter)
|
|
From: <ian...@us...> - 2003-05-30 02:49:39
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject
In directory sc8-pr-cvs1:/tmp/cvs-serv3787
Modified Files:
Join.py SQLObject.py
Log Message:
* More addNeedSet jazz
* foreignKey objects inherit the connection
Index: Join.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Join.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** Join.py 26 May 2003 21:48:54 -0000 1.1
--- Join.py 30 May 2003 02:22:51 -0000 1.2
***************
*** 94,108 ****
intermediateTable=None, **kw):
SOMultipleJoin.__init__(self, **kw)
! if not otherColumn:
! self.otherColumn = self.soClass._style.pythonClassToDBTableReference(self.otherClassName)
! else:
! self.otherColumn = otherColumn
! if not intermediateTable:
names = [self.soClass._table,
! self.soClass._style.pythonClassToDBTable(self.otherClassName)]
names.sort()
self.intermediateTable = '%s_%s' % (names[0], names[1])
! else:
! self.intermediateTable = intermediateTable
def hasIntermediateTable(self):
--- 94,111 ----
intermediateTable=None, **kw):
SOMultipleJoin.__init__(self, **kw)
! self.intermediateTable = intermediateTable
! self.otherColumn = otherColumn
! SQLObject.addNeedSet(self, self.otherClassName,
! self.soClass._registry, '_setOtherClass')
!
! def _setOtherClass(self, otherClass):
! if not self.intermediateTable:
names = [self.soClass._table,
! otherClass._table]
names.sort()
self.intermediateTable = '%s_%s' % (names[0], names[1])
! if not self.otherColumn:
! self.otherColumn = self.soClass._style.tableReference(otherClass._table)
!
def hasIntermediateTable(self):
Index: SQLObject.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/SQLObject.py,v
retrieving revision 1.41
retrieving revision 1.42
diff -C2 -d -r1.41 -r1.42
*** SQLObject.py 30 May 2003 02:18:45 -0000 1.41
--- SQLObject.py 30 May 2003 02:22:51 -0000 1.42
***************
*** 727,730 ****
--- 727,732 ----
if id is None:
return None
+ elif self._SO_perConnection:
+ return joinClass(id, connection=self._connection)
else:
return joinClass(id)
|
|
From: <ian...@us...> - 2003-05-30 02:39:32
|
Update of /cvsroot/sqlobject/SQLObject/docs
In directory sc8-pr-cvs1:/tmp/cvs-serv2648
Modified Files:
Authors.txt News.txt
Log Message:
Noted bugfix
Added author attribution
Index: Authors.txt
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/docs/Authors.txt,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** Authors.txt 19 Apr 2003 00:02:57 -0000 1.1
--- Authors.txt 30 May 2003 02:20:22 -0000 1.2
***************
*** 7,11 ****
Contributions have been made by:
! Frank Barknecht <fb...@fo...>
! Bud P. Bruegger <bu...@si...>
! David M. Cook <da...@da...>
--- 7,12 ----
Contributions have been made by:
! * Frank Barknecht <fb...@fo...>
! * Bud P. Bruegger <bu...@si...>
! * David M. Cook <da...@da...>
! * Luke Opperman <lu...@me...>
Index: News.txt
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/docs/News.txt,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** News.txt 25 May 2003 06:03:45 -0000 1.6
--- News.txt 30 May 2003 02:20:22 -0000 1.7
***************
*** 24,27 ****
--- 24,29 ----
_columns = [Col('someColumn')]
+ Ditto joins.
+
* Cache objects have a clear method, which empties all objects.
However, weak references to objects *are* maintained, so the
***************
*** 125,128 ****
--- 127,133 ----
* Trying to use ``Col('id')`` or ``id = Col()`` will raise an
exception, instead of just acting funky.
+
+ * ``ForeignKey`` columns return None if the associated column is
+ NULL in the database (used to just act weird).
Internal
|
|
From: <ian...@us...> - 2003-05-30 02:19:34
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject
In directory sc8-pr-cvs1:/tmp/cvs-serv1697
Modified Files:
SQLObject.py
Log Message:
* Minor fixed to addNeedSet stuff
* foreignKey columns return None when the associated ID column is NULL
Index: SQLObject.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/SQLObject.py,v
retrieving revision 1.40
retrieving revision 1.41
diff -C2 -d -r1.40 -r1.41
*** SQLObject.py 26 May 2003 21:48:54 -0000 1.40
--- SQLObject.py 30 May 2003 02:18:45 -0000 1.41
***************
*** 85,104 ****
cls = findClass(needClass, registry=registryName)
for obj, attr in q:
! setattr(obj, attr, cls)
except KeyError:
newNeedClassDict[needClass] = q
needSet[registryName] = newNeedClassDict
-
-
-
- def addNeedSet(needClass, setCls):
- needSet.setdefault(needClass.__name__, []).append(
- (needClass.__name__, setCls))
-
def addNeedSet(obj, setCls, registry, attr):
try:
cls = findClass(setCls, registry=registry)
! setattr(obj, attr, cls)
return
except KeyError:
--- 85,103 ----
cls = findClass(needClass, registry=registryName)
for obj, attr in q:
! if callable(getattr(obj, attr, None)):
! getattr(obj, attr)(cls)
! else:
! setattr(obj, attr, cls)
except KeyError:
newNeedClassDict[needClass] = q
needSet[registryName] = newNeedClassDict
def addNeedSet(obj, setCls, registry, attr):
try:
cls = findClass(setCls, registry=registry)
! if callable(getattr(obj, attr, None)):
! getattr(obj, attr)(cls)
! else:
! setattr(obj, attr, cls)
return
except KeyError:
***************
*** 470,474 ****
# self._SO_class_className is a reference
# to the class in question.
! getter = eval('lambda self: self._SO_class_%s(self.%s)' % (column.foreignKey, instanceName(name)))
else:
# Same non-caching version as above.
--- 469,473 ----
# self._SO_class_className is a reference
# to the class in question.
! getter = eval('lambda self: self._SO_foreignKey(self.%s and self._SO_class_%s)' % (column.foreignKey, instanceName(name)))
else:
# Same non-caching version as above.
***************
*** 724,727 ****
--- 723,732 ----
% (self.__class__.__name__, self.id)
return results[0]
+
+ def _SO_foreignKey(self, id, joinClass):
+ if id is None:
+ return None
+ else:
+ return joinClass(id)
def new(cls, **kw):
|
|
From: <ian...@us...> - 2003-05-26 21:48:58
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject
In directory sc8-pr-cvs1:/tmp/cvs-serv3682
Modified Files:
Col.py SQLObject.py __init__.py
Added Files:
Join.py
Log Message:
* Moved joins to their own module
* Created SOJoin/Join distinction
* Joins can be defined like columns, i.e., without using _joins.
--- NEW FILE: Join.py ---
from SQLBuilder import NoDefault
import Style
import SQLObject
__all__ = ['MultipleJoin', 'RelatedJoin']
class Join(object):
def __init__(self, otherClass=None, **kw):
kw['otherClass'] = otherClass
kw['joinDef'] = self
self.kw = kw
def setName(self, value):
assert self.kw.get('joinMethodName') is None or self.kw['joinMethodName'] == value, "You have already given an explicit joinMethodName (%s), and you are now setting it to %s" % (self.kw['joinMethodName'], value)
self.kw['joinMethodName'] = value
def withClass(self, soClass):
return self.baseClass(soClass=soClass, **self.kw)
# A join is separate from a foreign key, i.e., it is
# many-to-many, or one-to-many where the *other* class
# has the foreign key.
class SOJoin(object):
def __init__(self,
soClass=None,
otherClass=None,
joinColumn=None,
joinMethodName=None,
orderBy=NoDefault,
joinDef=None):
self.soClass = soClass
self.otherClassName = otherClass
SQLObject.addNeedSet(self, otherClass, soClass._registry,
'otherClass')
self.joinColumn = joinColumn
self.joinMethodName = joinMethodName
self.orderBy = orderBy
if not self.joinColumn:
# Here we set up the basic join, which is
# one-to-many, where the other class points to
# us.
self.joinColumn = Style.getStyle(self.soClass).tableReference(self.soClass._table)
def hasIntermediateTable(self):
return False
def _applyOrderBy(self, results, defaultSortClass):
if self.orderBy is NoDefault:
self.orderBy = defaultSortClass._defaultOrder
if self.orderBy is not None:
def sorter(a, b, attr=self.orderBy):
return cmp(getattr(a, attr),
getattr(b, attr))
results.sort(sorter)
return results
# This is a one-to-many
class SOMultipleJoin(SOJoin):
def __init__(self, addRemoveName=None, **kw):
# addRemovePrefix is something like @@
SOJoin.__init__(self, **kw)
# Here we generate the method names
if not self.joinMethodName:
name = self.otherClassName[0].lower() + self.otherClassName[1:]
if name.endswith('s'):
name = name + "es"
else:
name = name + "s"
self.joinMethodName = name
if not addRemoveName:
self.addRemoveName = capitalize(self.otherClassName)
else:
self.addRemoveName = addRemoveName
def performJoin(self, inst):
ids = inst._connection._SO_selectJoin(
self.otherClass,
self.joinColumn,
inst.id)
return self._applyOrderBy([self.otherClass(id) for (id,) in ids], self.otherClass)
class MultipleJoin(Join):
baseClass = SOMultipleJoin
# This is a many-to-many join, with an intermediary table
class SORelatedJoin(SOMultipleJoin):
def __init__(self,
otherColumn=None,
intermediateTable=None, **kw):
SOMultipleJoin.__init__(self, **kw)
if not otherColumn:
self.otherColumn = self.soClass._style.pythonClassToDBTableReference(self.otherClassName)
else:
self.otherColumn = otherColumn
if not intermediateTable:
names = [self.soClass._table,
self.soClass._style.pythonClassToDBTable(self.otherClassName)]
names.sort()
self.intermediateTable = '%s_%s' % (names[0], names[1])
else:
self.intermediateTable = intermediateTable
def hasIntermediateTable(self):
return True
def performJoin(self, inst):
ids = inst._connection._SO_intermediateJoin(
self.intermediateTable,
self.otherColumn,
self.joinColumn,
inst.id)
return self._applyOrderBy([self.otherClass(id) for (id,) in ids], self.otherClass)
def remove(self, inst, other):
inst._connection._SO_intermediateDelete(
self.intermediateTable,
self.joinColumn,
SQLObject.getID(inst),
self.otherColumn,
SQLObject.getID(other))
def add(self, inst, other):
inst._connection._SO_intermediateInsert(
self.intermediateTable,
self.joinColumn,
SQLObject.getID(inst),
self.otherColumn,
SQLObject.getID(other))
class RelatedJoin(MultipleJoin):
baseClass = SORelatedJoin
def capitalize(name):
return name[0].capitalize() + name[1:]
Index: Col.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Col.py,v
retrieving revision 1.21
retrieving revision 1.22
diff -C2 -d -r1.21 -r1.22
*** Col.py 12 May 2003 01:58:21 -0000 1.21
--- Col.py 26 May 2003 21:48:54 -0000 1.22
***************
*** 177,181 ****
def setName(self, value):
! assert self.kw['name'] is None, "You cannot change a name after it has already been set"
self.kw['name'] = value
--- 177,181 ----
def setName(self, value):
! assert self.kw['name'] is None, "You cannot change a name after it has already been set (from %s to %s)" % (self.kw['name'], value)
self.kw['name'] = value
Index: SQLObject.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/SQLObject.py,v
retrieving revision 1.39
retrieving revision 1.40
diff -C2 -d -r1.39 -r1.40
*** SQLObject.py 25 May 2003 02:39:45 -0000 1.39
--- SQLObject.py 26 May 2003 21:48:54 -0000 1.40
***************
*** 28,31 ****
--- 28,32 ----
import types
import warnings
+ import Join
import sys
***************
*** 75,78 ****
--- 76,94 ----
newNeedList.append((needClass, setCls))
needSet[registryName] = newNeedList
+
+ def setNeedSet():
+ global needSet
+ for registryName, needClassDict in needSet.items():
+ newNeedClassDict = {}
+ for needClass, q in needClassDict.items():
+ try:
+ cls = findClass(needClass, registry=registryName)
+ for obj, attr in q:
+ setattr(obj, attr, cls)
+ except KeyError:
+ newNeedClassDict[needClass] = q
+ needSet[registryName] = newNeedClassDict
+
+
def addNeedSet(needClass, setCls):
***************
*** 80,83 ****
--- 96,111 ----
(needClass.__name__, setCls))
+
+ def addNeedSet(obj, setCls, registry, attr):
+ try:
+ cls = findClass(setCls, registry=registry)
+ setattr(obj, attr, cls)
+ return
+ except KeyError:
+ pass
+ q = needSet.setdefault(registry, {}).setdefault(setCls, [])
+ q.append((obj, attr))
+
+
# This is the metaclass. It essentially takes a dictionary
# of all the attributes (and thus methods) defined in the
***************
*** 103,106 ****
--- 131,135 ----
implicitColumns = []
+ implicitJoins = []
for attr, value in d.items():
if isinstance(value, Col.Col):
***************
*** 108,111 ****
--- 137,146 ----
implicitColumns.append(value)
del d[attr]
+ continue
+ if isinstance(value, Join.Join):
+ value.setName(attr)
+ implicitJoins.append(value)
+ del d[attr]
+ continue
# We *don't* want to inherit _table, so we make sure it
***************
*** 134,137 ****
--- 169,175 ----
newClass._columns = newClass._columns[:]
newClass._columns.extend(implicitColumns)
+ if not d.has_key('_joins'):
+ newClass._joins = newClass._joins[:]
+ newClass._joins.extend(implicitJoins)
######################################################
***************
*** 201,204 ****
--- 239,243 ----
# putting them in this list.
newClass._SO_joinList = []
+ newClass._SO_joinDict = {}
for join in newClass._joins:
***************
*** 278,282 ****
def findClass(name, registry=None):
! assert classRegistry.get(registry, {}).has_key(name), "No class by the name %s found (I have %s)" % (repr(name), ', '.join(classRegistry.keys()))
return classRegistry[registry][name]
--- 317,321 ----
def findClass(name, registry=None):
! #assert classRegistry.get(registry, {}).has_key(name), "No class by the name %s found (I have %s)" % (repr(name), ', '.join(map(str, classRegistry.keys())))
return classRegistry[registry][name]
***************
*** 454,458 ****
# some point. See needSet at the top of the
# file for more on this.
! addNeedSet(cls, column.foreignKey)
if column.alternateMethodName:
--- 493,498 ----
# some point. See needSet at the top of the
# file for more on this.
! addNeedSet(cls, column.foreignKey, cls._registry,
! '_SO_class_%s' % column.foreignKey)
if column.alternateMethodName:
***************
*** 516,539 ****
delColumn = classmethod(delColumn)
! def addJoin(cls, join):
# The name of the method we'll create. If it's
# automatically generated, it's generated by the
# join class.
meth = join.joinMethodName
- if join not in cls._joins:
- cls._joins.append(join)
-
- # The method name for adding a joined object:
- appendMeth = meth[0].upper() + meth[1:]
-
- # The join sometimes needs to know who we are,
- # mostly to generate some internal names:
- join.initCallingClass(cls)
-
- # Now that the join is set up, we add it to our
- # list of joins:
cls._SO_joinList.append(join)
index = len(cls._SO_joinList)-1
# The function fetches the join by index, and
--- 556,571 ----
delColumn = classmethod(delColumn)
! def addJoin(cls, joinDef):
# The name of the method we'll create. If it's
# automatically generated, it's generated by the
# join class.
+ join = joinDef.withClass(cls)
meth = join.joinMethodName
+ cls._SO_joinDict[joinDef] = join
cls._SO_joinList.append(join)
index = len(cls._SO_joinList)-1
+ if joinDef not in cls._joins:
+ cls._joins.append(joinDef)
# The function fetches the join by index, and
***************
*** 555,561 ****
# standard naming trick.
func = eval('lambda self, obj: self._SO_joinList[%i].remove(self, obj)' % index)
! setattr(cls, '_SO_remove' + join.addRemovePrefix, func)
! if not hasattr(cls, 'remove' + appendMeth):
! setattr(cls, 'remove' + join.addRemovePrefix, func)
cls._SO_plainJoinRemovers[meth] = 1
--- 587,593 ----
# standard naming trick.
func = eval('lambda self, obj: self._SO_joinList[%i].remove(self, obj)' % index)
! setattr(cls, '_SO_remove' + join.addRemoveName, func)
! if not hasattr(cls, 'remove' + join.addRemoveName):
! setattr(cls, 'remove' + join.addRemoveName, func)
cls._SO_plainJoinRemovers[meth] = 1
***************
*** 565,571 ****
# And again...
func = eval('lambda self, obj: self._SO_joinList[%i].add(self, obj)' % (len(cls._SO_joinList)-1))
! setattr(cls, '_SO_add' + join.addRemovePrefix, func)
! if not hasattr(cls, 'add' + appendMeth):
! setattr(cls, 'add' + join.addRemovePrefix, func)
cls._SO_plainJoinAdders[meth] = 1
--- 597,603 ----
# And again...
func = eval('lambda self, obj: self._SO_joinList[%i].add(self, obj)' % (len(cls._SO_joinList)-1))
! setattr(cls, '_SO_add' + join.addRemoveName, func)
! if not hasattr(cls, 'add' + join.addRemoveName):
! setattr(cls, 'add' + join.addRemoveName, func)
cls._SO_plainJoinAdders[meth] = 1
***************
*** 575,583 ****
addJoin = classmethod(addJoin)
! def delJoin(cls, join):
meth = join.joinMethodName
! cls._joins.remove(join)
for i in range(len(cls._SO_joinList)):
! if cls._SO_joinList[i] is join:
cls._SO_joinList[i] = None
delattr(cls, rawGetterName(meth))
--- 607,619 ----
addJoin = classmethod(addJoin)
! def delJoin(cls, joinDef):
! join = cls._SO_joinDict[joinDef]
meth = join.joinMethodName
! cls._joins.remove(joinDef)
! del cls._SO_joinDict[joinDef]
for i in range(len(cls._SO_joinList)):
! if cls._SO_joinList[i] is joinDef:
! # Have to leave None, because we refer to joins
! # by index.
cls._SO_joinList[i] = None
delattr(cls, rawGetterName(meth))
***************
*** 825,829 ****
def createJoinTables(cls, ifNotExists=False):
! for join in cls._joins:
if not join.hasIntermediateTable():
continue
--- 861,867 ----
def createJoinTables(cls, ifNotExists=False):
! for join in cls._SO_joinList:
! if not join:
! continue
if not join.hasIntermediateTable():
continue
***************
*** 832,836 ****
# arbitrarily create it while we're creating the
# alphabetically earlier class.
! if join.callingClass > join.otherClass:
continue
if ifNotExists and \
--- 870,874 ----
# arbitrarily create it while we're creating the
# alphabetically earlier class.
! if join.soClass.__name__ > join.otherClass.__name__:
continue
if ifNotExists and \
***************
*** 842,849 ****
def dropJoinTables(cls, ifExists=False):
! for join in cls._joins:
if not join.hasIntermediateTable():
continue
! if join.callingClass > join.otherClass:
continue
if ifExists and \
--- 880,889 ----
def dropJoinTables(cls, ifExists=False):
! for join in cls._SO_joinList:
! if not join:
! continue
if not join.hasIntermediateTable():
continue
! if join.soClass.__name__ > join.otherClass.__name__:
continue
if ifExists and \
***************
*** 904,1035 ****
- ########################################
- ## Joins
- ########################################
-
- # A join is separate from a foreign key, i.e., it is
- # many-to-many, or one-to-many where the *other* class
- # has the foreign key.
- class Join(object):
-
- def __init__(self, otherClass, joinColumn=None, joinMethodName=None,
- orderBy=NoDefault):
- self.otherClass = otherClass
- self.joinColumn = joinColumn
- self.joinMethodName = joinMethodName
- self.orderBy = orderBy
-
- def initCallingClass(self, callingClass):
- # Since some of the automatic generation of the names
- # depends on the class/table to which this join belongs,
- # we can only resolve some of this after the class
- # has been created, which is after this join has
- # been created.
- self.callingClass = callingClass
- self.callingClassDBName = callingClass._table
- if not self.joinColumn:
- # Here we set up the basic join, which is
- # one-to-many, where the other class points to
- # us.
- self.joinColumn = Style.getStyle(callingClass).tableReference(callingClass._table)
-
- def hasIntermediateTable(self):
- return False
-
- def _applyOrderBy(self, results, defaultSortClass):
- if self.orderBy is NoDefault:
- self.orderBy = defaultSortClass._defaultOrder
- if self.orderBy is not None:
- def sorter(a, b, attr=self.orderBy):
- return cmp(getattr(a, attr),
- getattr(b, attr))
- results.sort(sorter)
- return results
-
- # This is a one-to-many
- class MultipleJoin(Join):
-
- def __init__(self, *args, **kw):
- # addRemovePrefix is something like @@
- if kw.has_key('addRemovePrefix'):
- self.addRemovePrefix = kw['addRemovePrefix']
- del kw['addRemovePrefix']
- else:
- self.addRemovePrefix = None
- Join.__init__(self, *args, **kw)
-
- # Here we generate the method names
- if not self.joinMethodName:
- name = self.otherClass[0].lower() + self.otherClass[1:]
- if name.endswith('s'):
- name = name + "es"
- else:
- name = name + "s"
- self.joinMethodName = name
- if not self.addRemovePrefix:
- self.addRemovePrefix = capitalize(self.otherClass)
-
- def performJoin(self, inst):
- # We only have names of classes a lot of the time,
- # so we have to fetch the actual class definition:
- cls = findClass(self.otherClass, registry=inst._registry)
- ids = inst._connection._SO_selectJoin(
- cls,
- self.joinColumn,
- inst.id)
- return self._applyOrderBy([cls(id) for (id,) in ids], cls)
-
- # This is a many-to-many join, with an intermediary table
- class RelatedJoin(MultipleJoin):
-
- def __init__(self, otherClass,
- otherColumn=None,
- intermediateTable=None, **kw):
- MultipleJoin.__init__(self, otherClass, **kw)
- self.intermediateTable = intermediateTable
- self.otherColumn = otherColumn
-
- def hasIntermediateTable(self):
- return True
-
- def initCallingClass(self, callingClass):
- MultipleJoin.initCallingClass(self, callingClass)
- if not self.otherColumn:
- self.otherColumn = Style.getStyle(
- callingClass.__name__).pythonClassToDBTableReference(self.otherClass)
- if not self.intermediateTable:
- names = [callingClass._table,
- Style.getStyle(callingClass).pythonClassToDBTable(self.otherClass)]
- names.sort()
- self.intermediateTable = "%s_%s" % (names[0], names[1])
-
- def performJoin(self, inst):
- cls = findClass(self.otherClass, registry=inst._registry)
- me = self.callingClass
- ids = inst._connection._SO_intermediateJoin(
- self.intermediateTable,
- self.otherColumn,
- self.joinColumn,
- inst.id)
- return self._applyOrderBy([cls(id) for (id,) in ids], cls)
-
- def remove(self, inst, other):
- me = self.callingClass
- inst._connection._SO_intermediateDelete(
- self.intermediateTable,
- self.joinColumn,
- getID(inst),
- self.otherColumn,
- getID(other))
-
- def add(self, inst, other):
- me = self.callingClass
- inst._connection._SO_intermediateInsert(
- self.intermediateTable,
- self.joinColumn,
- getID(inst),
- self.otherColumn,
- getID(other))
-
class SelectResults(object):
--- 944,947 ----
***************
*** 1162,1165 ****
__all__ = ['NoDefault', 'SQLObject',
! 'MultipleJoin', 'RelatedJoin', 'getID', 'getObject',
'SQLObjectNotFound']
--- 1074,1077 ----
__all__ = ['NoDefault', 'SQLObject',
! 'getID', 'getObject',
'SQLObjectNotFound']
Index: __init__.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/__init__.py,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** __init__.py 21 Apr 2003 22:50:09 -0000 1.3
--- __init__.py 26 May 2003 21:48:54 -0000 1.4
***************
*** 4,5 ****
--- 4,6 ----
from DBConnection import *
from Style import *
+ from Join import *
|
|
From: <ian...@us...> - 2003-05-25 06:03:49
|
Update of /cvsroot/sqlobject/SQLObject/docs
In directory sc8-pr-cvs1:/tmp/cvs-serv21723
Modified Files:
News.txt
Log Message:
Documented the new features.
Index: News.txt
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/docs/News.txt,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** News.txt 7 Apr 2003 20:11:28 -0000 1.5
--- News.txt 25 May 2003 06:03:45 -0000 1.6
***************
*** 8,11 ****
--- 8,138 ----
.. _start:
+ SQLObject 0.4
+ =============
+
+ Features
+ --------
+
+ * You can specify columns in a new, preferred manner::
+
+ class SomeObject(SQLObject):
+ someColumn = Col()
+
+ Equivalent to::
+
+ class SomeObject(SQLObject):
+ _columns = [Col('someColumn')]
+
+ * Cache objects have a clear method, which empties all objects.
+ However, weak references to objects *are* maintained, so the
+ integrity of the cache can be ensured.
+
+ * SQLObject subclasses can be further subclassed, adding or removing
+ column definitions (as well as changing settings like connection,
+ style, etc). Each class still refers to a single concrete table in
+ the database -- the class hierarchy is not represented in the
+ database.
+
+ * Each SQLObject subclass can have an associated style, as given in
+ the `_style` attribute. This object is used to map between Python
+ and database names (e.g., the column name for a Python attribute).
+ Some samples are available in the `Style` module.
+
+ * Postgres support for `_fromDatabase` (reading a table definition from
+ the database, and creating a class from that).
+
+ * Postgres id columns more permissive, you don't have to create a
+ specially named sequence (or implicitly create that sequence through
+ ``SERIAL``). lastoid is used instead.
+
+ * MySQL uses ``localhost`` as the default host, and the empty string
+ as the default password.
+
+ * Added functions for use with queries: `ISNULL`, `ISNOTNULL`. ``==``
+ and ``!=`` can be used with None, and is translated into `ISNULL`,
+ `ISNOTNULL`.
+
+ * Classes can be part of a specific registry. Since classes are
+ referred to by name in several places, the names have to be unique.
+ This can be problematic, so you can add a class variable `_registry`,
+ the value of which should be a string. Classes references are
+ assumed to be inside that registry, and class names need only be
+ unique among classes in that registry.
+
+ * ``SomeClass.select()`` selects all, instead of using
+ ``SomeClass.select('all')``. You can also use None instead of
+ ``'all'``.
+
+ * Trying to fetch non-existent objects raises `SQLObjectNotFound`,
+ which is a subclass of the builtin exception `LookupError`.
+ This may not be raised if `_cacheValues` is False and you use
+ the ID to fetch an object (but alternateID fetches will raise
+ the exception in either case).
+
+ Col and Join
+ ~~~~~~~~~~~~
+
+ * `Join` constructors have an argument `orderBy`, which is the name
+ of a Python attribute to sort results by. If not given, the
+ appropriate class's `_defaultOrder` will be used. None implies
+ no sorting (and ``orderBy=None`` will override `_defaultOrder`).
+
+ * `ForeignKey` class (subclass of `Col`), for somewhat easier/clearer
+ declaration of foreign keys.
+
+ * `Col` (and subclasses) can take a `sqlType` argument, which is used
+ in table definitions. E.g., ``Col(sqlType="BOOLEAN")`` can be used
+ to create a ``BOOLEAN`` column, even though no `BooleanCol` exists.
+
+ * `alternateID` (a specifier for columns) implies ``NOT NULL``. Also
+ implies ``UNIQUE``.
+
+ * `unique` (a specifier for columns) added.
+
+ * `DecimalCol` and `CurrencyCol` added.
+
+ * `EnumCol` uses constraints on Postgres (if you use `createTable`).
+
+ Bugs
+ ----
+
+ * `DateTimeCol` uses ``TIMESTAMP`` for Postgres. Note that the
+ Python type name is used for column names, not necessarily the
+ SQL standard name.
+
+ * Foreign key column names are slightly more permissive. They still
+ need to end in ``id``, but it's case insensitive.
+
+ * _defaultOrder should be the python attribute's name, not the database
+ name.
+
+ * SomeClass.q.colName uses proper Python attributes for colName, and
+ proper database names when executed in the database.
+
+ * SQLite select results back to being proper iterator.
+
+ * SomeClass.q.colName now does proper translation to database names,
+ using dbName, etc., instead of being entirely algorithm-driven.
+
+ * Raise `TypeError` if you pass an unknown argument to the `new`
+ method.
+
+ * You can override the _get_* or _set_* version of a property without
+ overriding the other.
+
+ * Python 2.3 compatible.
+
+ * Trying to use ``Col('id')`` or ``id = Col()`` will raise an
+ exception, instead of just acting funky.
+
+ Internal
+ --------
+
+ * `Col` class separated into `Col` and `SOCol` (and same for all other
+ `*Col` classes). `Col` defines a column, `SOCol` is that definition
+ bound to a particular SQLObject class.
+
+ * Instance variable ``_SO_columns`` holds the `SOCol` instances.
+
SQLObject 0.3
=============
|
|
From: <ian...@us...> - 2003-05-25 02:39:48
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject
In directory sc8-pr-cvs1:/tmp/cvs-serv26546/SQLObject
Modified Files:
SQLObject.py
Log Message:
Used proper DB name mappings, not the style, for orderBy
Index: SQLObject.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/SQLObject.py,v
retrieving revision 1.38
retrieving revision 1.39
diff -C2 -d -r1.38 -r1.39
*** SQLObject.py 24 May 2003 21:17:17 -0000 1.38
--- SQLObject.py 25 May 2003 02:39:45 -0000 1.39
***************
*** 1052,1056 ****
orderBy = self.ops['orderBy']
if orderBy is not None:
! self.ops['dbOrderBy'] = sourceClass._style.pythonAttrToDBColumn(orderBy)
def clone(self, **newOps):
--- 1052,1057 ----
orderBy = self.ops['orderBy']
if orderBy is not None:
! if sourceClass._SO_columnDict.has_key(orderBy):
! self.ops['dbOrderBy'] = sourceClass._SO_columnDict[orderBy].dbName
def clone(self, **newOps):
|
|
From: <ian...@us...> - 2003-05-24 21:24:04
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject
In directory sc8-pr-cvs1:/tmp/cvs-serv12102/SQLObject
Modified Files:
DBConnection.py SQLObject.py
Log Message:
* Joins now take an orderBy argument, and use the class's _defaultOrder
if no argument is given.
* defaultOrder/orderBy takes python attribute names, not DB names.
Index: DBConnection.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/DBConnection.py,v
retrieving revision 1.33
retrieving revision 1.34
diff -C2 -d -r1.33 -r1.34
*** DBConnection.py 6 May 2003 22:43:34 -0000 1.33
--- DBConnection.py 24 May 2003 21:17:17 -0000 1.34
***************
*** 189,194 ****
if order and ops.get('groupBy'):
q = "%s GROUP BY %s" % (q, ", ".join(clauseList(ops['groupBy'])))
! if order and ops.get('orderBy'):
! q = "%s ORDER BY %s" % (q, ", ".join(clauseList(ops['orderBy'])))
start = ops.get('start', 0)
--- 189,194 ----
if order and ops.get('groupBy'):
q = "%s GROUP BY %s" % (q, ", ".join(clauseList(ops['groupBy'])))
! if order and ops.get('dbOrderBy'):
! q = "%s ORDER BY %s" % (q, ", ".join(clauseList(ops['dbOrderBy'])))
start = ops.get('start', 0)
Index: SQLObject.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/SQLObject.py,v
retrieving revision 1.37
retrieving revision 1.38
diff -C2 -d -r1.37 -r1.38
*** SQLObject.py 24 May 2003 20:53:36 -0000 1.37
--- SQLObject.py 24 May 2003 21:17:17 -0000 1.38
***************
*** 913,920 ****
class Join(object):
! def __init__(self, otherClass, joinColumn=None, joinMethodName=None):
self.otherClass = otherClass
self.joinColumn = joinColumn
self.joinMethodName = joinMethodName
def initCallingClass(self, callingClass):
--- 913,922 ----
class Join(object):
! def __init__(self, otherClass, joinColumn=None, joinMethodName=None,
! orderBy=NoDefault):
self.otherClass = otherClass
self.joinColumn = joinColumn
self.joinMethodName = joinMethodName
+ self.orderBy = orderBy
def initCallingClass(self, callingClass):
***************
*** 935,938 ****
--- 937,950 ----
return False
+ def _applyOrderBy(self, results, defaultSortClass):
+ if self.orderBy is NoDefault:
+ self.orderBy = defaultSortClass._defaultOrder
+ if self.orderBy is not None:
+ def sorter(a, b, attr=self.orderBy):
+ return cmp(getattr(a, attr),
+ getattr(b, attr))
+ results.sort(sorter)
+ return results
+
# This is a one-to-many
class MultipleJoin(Join):
***************
*** 966,970 ****
self.joinColumn,
inst.id)
! return [cls(id) for (id,) in ids]
# This is a many-to-many join, with an intermediary table
--- 978,982 ----
self.joinColumn,
inst.id)
! return self._applyOrderBy([cls(id) for (id,) in ids], cls)
# This is a many-to-many join, with an intermediary table
***************
*** 1000,1004 ****
self.joinColumn,
inst.id)
! return [cls(id) for (id,) in ids]
def remove(self, inst, other):
--- 1012,1016 ----
self.joinColumn,
inst.id)
! return self._applyOrderBy([cls(id) for (id,) in ids], cls)
def remove(self, inst, other):
***************
*** 1038,1041 ****
--- 1050,1056 ----
if self.ops.get('orderBy', NoDefault) is NoDefault:
self.ops['orderBy'] = sourceClass._defaultOrder
+ orderBy = self.ops['orderBy']
+ if orderBy is not None:
+ self.ops['dbOrderBy'] = sourceClass._style.pythonAttrToDBColumn(orderBy)
def clone(self, **newOps):
|
|
From: <ian...@us...> - 2003-05-24 20:53:40
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject
In directory sc8-pr-cvs1:/tmp/cvs-serv3719/SQLObject
Modified Files:
SQLObject.py
Log Message:
* Use the instance's connection in joins.
* Allow connection option to selects.
Index: SQLObject.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/SQLObject.py,v
retrieving revision 1.36
retrieving revision 1.37
diff -C2 -d -r1.36 -r1.37
*** SQLObject.py 24 May 2003 20:48:50 -0000 1.36
--- SQLObject.py 24 May 2003 20:53:36 -0000 1.37
***************
*** 995,999 ****
cls = findClass(self.otherClass, registry=inst._registry)
me = self.callingClass
! ids = me._connection._SO_intermediateJoin(
self.intermediateTable,
self.otherColumn,
--- 995,999 ----
cls = findClass(self.otherClass, registry=inst._registry)
me = self.callingClass
! ids = inst._connection._SO_intermediateJoin(
self.intermediateTable,
self.otherColumn,
***************
*** 1004,1008 ****
def remove(self, inst, other):
me = self.callingClass
! me._connection._SO_intermediateDelete(
self.intermediateTable,
self.joinColumn,
--- 1004,1008 ----
def remove(self, inst, other):
me = self.callingClass
! inst._connection._SO_intermediateDelete(
self.intermediateTable,
self.joinColumn,
***************
*** 1013,1017 ****
def add(self, inst, other):
me = self.callingClass
! me._connection._SO_intermediateInsert(
self.intermediateTable,
self.joinColumn,
--- 1013,1017 ----
def add(self, inst, other):
me = self.callingClass
! inst._connection._SO_intermediateInsert(
self.intermediateTable,
self.joinColumn,
***************
*** 1051,1054 ****
--- 1051,1057 ----
return self.clone(groupBy=groupBy)
+ def connection(self, conn):
+ return self.clone(connection=conn)
+
def limit(self, limit):
return self[:limit]
***************
*** 1098,1105 ****
def __iter__(self):
! return self.sourceClass._connection.iterSelect(self)
def __len__(self):
! count = self.sourceClass._connection.countSelect(self)
if self.ops.get('start'):
count -= self.ops['start']
--- 1101,1110 ----
def __iter__(self):
! conn = self.ops.get('connection', self.sourceClass._connection)
! return conn.iterSelect(self)
def __len__(self):
! conn = self.ops.get('connection', self.sourceClass._connection)
! count = conn.countSelect(self)
if self.ops.get('start'):
count -= self.ops['start']
|
|
From: <ian...@us...> - 2003-05-24 20:52:37
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject
In directory sc8-pr-cvs1:/tmp/cvs-serv1901/SQLObject
Modified Files:
SQLObject.py
Log Message:
Added registries for classes, so that class names only have to be
unique within their registry.
Index: SQLObject.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/SQLObject.py,v
retrieving revision 1.35
retrieving revision 1.36
diff -C2 -d -r1.35 -r1.36
*** SQLObject.py 12 May 2003 01:59:42 -0000 1.35
--- SQLObject.py 24 May 2003 20:48:50 -0000 1.36
***************
*** 47,59 ****
# actual classes.
! # Here we keep a dictionary of class names to classes -- note
# that the classes might be spread among different modules, so
# since we pile them together names need to be globally unique,
# not just module unique.
classRegistry = {}
! # This is the list of (cls, needClass) pairs, where cls has
! # a reference to the class named needClass.
! needSet = []
# Here's what we call after each class is created, to fix up
--- 47,62 ----
# actual classes.
! # Here we keep a dictionaries of class names to classes -- note
# that the classes might be spread among different modules, so
# since we pile them together names need to be globally unique,
# not just module unique.
+ # Like needSet below, the container dictionary is keyed by the
+ # "class registry".
classRegistry = {}
! # This contains the list of (cls, needClass) pairs, where cls has
! # a reference to the class named needClass. It is keyed by "class
! # registries", which are disjunct sets of classes.
! needSet = {}
# Here's what we call after each class is created, to fix up
***************
*** 62,72 ****
def setNeedSet():
global needSet
! newNeedSet = []
! for needClass, setCls in needSet:
! if classRegistry.has_key(setCls):
! setattr(findClass(needClass), '_SO_class_%s' % setCls, findClass(setCls))
! else:
! newNeedSet.append((needClass, setCls))
! needSet = newNeedSet
# This is the metaclass. It essentially takes a dictionary
--- 65,82 ----
def setNeedSet():
global needSet
! for registryName, needList in needSet.items():
! newNeedList = []
! for needClass, setCls in needList:
! if classRegistry.get(registryName, {}).has_key(setCls):
! setattr(findClass(needClass, registry=registryName),
! '_SO_class_%s' % setCls,
! findClass(setCls, registry=registryName))
! else:
! newNeedList.append((needClass, setCls))
! needSet[registryName] = newNeedList
!
! def addNeedSet(needClass, setCls):
! needSet.setdefault(needClass.__name__, []).append(
! (needClass.__name__, setCls))
# This is the metaclass. It essentially takes a dictionary
***************
*** 104,116 ****
d['_table'] = None
- # needSet stuff (see top of module) would get messed
- # up if more than one SQLObject class has the same
- # name.
- assert not classRegistry.has_key(className), "A database object by the name %s has already been created" % repr(className)
-
# We actually create the class.
newClass = type.__new__(cls, className, bases, d)
newClass._SO_finishedClassCreation = False
# We append to _columns, but we don't want to change the
# superclass's _columns list, so we make a copy if necessary
--- 114,132 ----
d['_table'] = None
# We actually create the class.
newClass = type.__new__(cls, className, bases, d)
newClass._SO_finishedClassCreation = False
+ # needSet stuff (see top of module) would get messed
+ # up if more than one SQLObject class has the same
+ # name.
+ registry = newClass._registry
+ assert not classRegistry.get(registry, {}).has_key(className), "A database object by the name %s has already been created" % repr(className)
+
+ # Register it, for use with needSet
+ if not classRegistry.has_key(registry):
+ classRegistry[registry] = {}
+ classRegistry[registry][className] = newClass
+
# We append to _columns, but we don't want to change the
# superclass's _columns list, so we make a copy if necessary
***************
*** 194,199 ****
makeProperties(newClass)
- # Register it, for use with needSet
- classRegistry[className] = newClass
# Call needSet
setNeedSet()
--- 210,213 ----
***************
*** 263,269 ****
break
! def findClass(name):
! assert classRegistry.has_key(name), "No class by the name %s found (I have %s)" % (repr(name), ', '.join(classRegistry.keys()))
! return classRegistry[name]
--- 277,283 ----
break
! def findClass(name, registry=None):
! assert classRegistry.get(registry, {}).has_key(name), "No class by the name %s found (I have %s)" % (repr(name), ', '.join(classRegistry.keys()))
! return classRegistry[registry][name]
***************
*** 311,314 ****
--- 325,330 ----
_style = None
+ _registry = None
+
def __new__(cls, id, connection=None, selectResults=None):
***************
*** 438,442 ****
# some point. See needSet at the top of the
# file for more on this.
! needSet.append((cls.__name__, column.foreignKey))
if column.alternateMethodName:
--- 454,458 ----
# some point. See needSet at the top of the
# file for more on this.
! addNeedSet(cls, column.foreignKey)
if column.alternateMethodName:
***************
*** 945,949 ****
# We only have names of classes a lot of the time,
# so we have to fetch the actual class definition:
! cls = findClass(self.otherClass)
ids = inst._connection._SO_selectJoin(
cls,
--- 961,965 ----
# We only have names of classes a lot of the time,
# so we have to fetch the actual class definition:
! cls = findClass(self.otherClass, registry=inst._registry)
ids = inst._connection._SO_selectJoin(
cls,
***************
*** 977,981 ****
def performJoin(self, inst):
! cls = findClass(self.otherClass)
me = self.callingClass
ids = me._connection._SO_intermediateJoin(
--- 993,997 ----
def performJoin(self, inst):
! cls = findClass(self.otherClass, registry=inst._registry)
me = self.callingClass
ids = me._connection._SO_intermediateJoin(
|
|
From: <ian...@us...> - 2003-05-24 20:52:35
|
Update of /cvsroot/sqlobject/SQLObject/tests
In directory sc8-pr-cvs1:/tmp/cvs-serv1901/tests
Modified Files:
test.py
Log Message:
Added registries for classes, so that class names only have to be
unique within their registry.
Index: test.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/tests/test.py,v
retrieving revision 1.14
retrieving revision 1.15
diff -C2 -d -r1.14 -r1.15
*** test.py 12 May 2003 01:58:21 -0000 1.14
--- test.py 24 May 2003 20:48:51 -0000 1.15
***************
*** 261,267 ****
return
import sys
- reg = sys.modules[SQLObject.__module__].classRegistry
- if reg.has_key('AutoTest'):
- del reg['AutoTest']
class AutoTest(SQLObject):
_fromDatabase = True
--- 261,264 ----
***************
*** 275,278 ****
--- 272,277 ----
happy='N',
created=DateTime.now())
+ reg = sys.modules[SQLObject.__module__].classRegistry[AutoTest._registry]
+ del reg['AutoTest']
########################################
|
|
From: <ian...@us...> - 2003-05-12 01:59:45
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject
In directory sc8-pr-cvs1:/tmp/cvs-serv23391/SQLObject
Modified Files:
SQLObject.py
Log Message:
make SomeClass.select() mean select all
Index: SQLObject.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/SQLObject.py,v
retrieving revision 1.34
retrieving revision 1.35
diff -C2 -d -r1.34 -r1.35
*** SQLObject.py 10 May 2003 21:37:18 -0000 1.34
--- SQLObject.py 12 May 2003 01:59:42 -0000 1.35
***************
*** 777,781 ****
# 3-03 @@: Should this have a connection argument?
! def select(cls, clause, clauseTables=None,
orderBy=NoDefault, groupBy=None, limit=None,
lazyColumns=False):
--- 777,781 ----
# 3-03 @@: Should this have a connection argument?
! def select(cls, clause=None, clauseTables=None,
orderBy=NoDefault, groupBy=None, limit=None,
lazyColumns=False):
***************
*** 1009,1013 ****
**ops):
self.sourceClass = sourceClass
! if isinstance(clause, str) and clause == 'all':
clause = SQLBuilder.SQLTrueClause
self.clause = clause
--- 1009,1013 ----
**ops):
self.sourceClass = sourceClass
! if clause is None or isinstance(clause, str) and clause == 'all':
clause = SQLBuilder.SQLTrueClause
self.clause = clause
|
|
From: <ian...@us...> - 2003-05-12 01:58:24
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject
In directory sc8-pr-cvs1:/tmp/cvs-serv22955/SQLObject
Modified Files:
Col.py Style.py
Log Message:
ForeignKey class that is easier to specify
Index: Col.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Col.py,v
retrieving revision 1.20
retrieving revision 1.21
diff -C2 -d -r1.20 -r1.21
*** Col.py 12 May 2003 01:15:16 -0000 1.20
--- Col.py 12 May 2003 01:58:21 -0000 1.21
***************
*** 257,261 ****
--- 257,281 ----
class KeyCol(Col):
+
baseClass = SOKeyCol
+
+ class SOForeignKey(SOKeyCol):
+
+ def __init__(self, **kw):
+ foreignKey = kw['foreignKey']
+ style = kw['soClass']._style
+ if not kw.get('name'):
+ kw['name'] = style.instanceAttrToIDAttr(style.pythonClassToAttr(foreignKey))
+ else:
+ if not kw['name'].upper().endswith('ID'):
+ kw['name'] = style.instanceAttrToIDAttr(kw['name'])
+ SOKeyCol.__init__(self, **kw)
+
+ class ForeignKey(KeyCol):
+
+ baseClass = SOForeignKey
+
+ def __init__(self, foreignKey=None, **kw):
+ KeyCol.__init__(self, foreignKey=foreignKey, **kw)
class SOEnumCol(SOCol):
Index: Style.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Style.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** Style.py 5 May 2003 17:55:48 -0000 1.2
--- Style.py 12 May 2003 01:58:21 -0000 1.3
***************
*** 43,46 ****
--- 43,54 ----
return 'id'
+ def pythonClassToAttr(self, className):
+ return className[0].lower() + className[1:]
+
+ def instanceAttrToIDAttr(self, attr):
+ # @@: Right now, because of how names are created for foreign
+ # keys, you can't really change this style.
+ return attr + "ID"
+
class MixedCaseUnderscoreStyle(Style):
|
|
From: <ian...@us...> - 2003-05-12 01:58:24
|
Update of /cvsroot/sqlobject/SQLObject/tests
In directory sc8-pr-cvs1:/tmp/cvs-serv22955/tests
Modified Files:
test.py
Log Message:
ForeignKey class that is easier to specify
Index: test.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/tests/test.py,v
retrieving revision 1.13
retrieving revision 1.14
diff -C2 -d -r1.13 -r1.14
*** test.py 12 May 2003 01:22:48 -0000 1.13
--- test.py 12 May 2003 01:58:21 -0000 1.14
***************
*** 329,333 ****
_columns = [StringCol('zip', length=5),
! KeyCol('personJoiner2ID', foreignKey='PersonJoiner2')]
class JoinTest2(SQLObjectTest):
--- 329,334 ----
_columns = [StringCol('zip', length=5),
! ForeignKey('PersonJoiner2')]
! # KeyCol('personJoiner2ID', foreignKey='PersonJoiner2')]
class JoinTest2(SQLObjectTest):
|
|
From: <ian...@us...> - 2003-05-12 01:22:51
|
Update of /cvsroot/sqlobject/SQLObject/tests
In directory sc8-pr-cvs1:/tmp/cvs-serv12846/tests
Modified Files:
test.py
Log Message:
Test for new-style column definitions.
Index: test.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/tests/test.py,v
retrieving revision 1.12
retrieving revision 1.13
diff -C2 -d -r1.12 -r1.13
*** test.py 6 May 2003 22:43:35 -0000 1.12
--- test.py 12 May 2003 01:22:48 -0000 1.13
***************
*** 20,23 ****
--- 20,24 ----
classes = [TestSO1]
+ MyClass = TestSO1
info = [('bob', 'god'), ('sally', 'sordid'),
***************
*** 26,33 ****
def inserts(self):
for name, passwd in self.info:
! TestSO1.new(name=name, passwd=passwd)
def testGet(self):
! bob = TestSO1.selectBy(name='bob')[0]
self.assertEqual(bob.name, 'bob')
self.assertEqual(bob.passwd, 'god'.encode('rot13'))
--- 27,34 ----
def inserts(self):
for name, passwd in self.info:
! self.MyClass.new(name=name, passwd=passwd)
def testGet(self):
! bob = self.MyClass.selectBy(name='bob')[0]
self.assertEqual(bob.name, 'bob')
self.assertEqual(bob.passwd, 'god'.encode('rot13'))
***************
*** 41,44 ****
--- 42,57 ----
self.assertEqual(bob.name, 'joe')
+
+ class TestSO2(SQLObject):
+ name = StringCol(length=10)
+ passwd = StringCol(length=10)
+
+ def _set_passwd(self, passwd):
+ self._SO_set_passwd(passwd.encode('rot13'))
+
+ class TestCase2(TestCase1):
+
+ classes = [TestSO2]
+ MyClass = TestSO2
########################################
|
|
From: <ian...@us...> - 2003-05-12 01:15:19
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject
In directory sc8-pr-cvs1:/tmp/cvs-serv10803/SQLObject
Modified Files:
Col.py
Log Message:
fixed typo
Index: Col.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Col.py,v
retrieving revision 1.19
retrieving revision 1.20
diff -C2 -d -r1.19 -r1.20
*** Col.py 6 May 2003 22:43:34 -0000 1.19
--- Col.py 12 May 2003 01:15:16 -0000 1.20
***************
*** 177,181 ****
def setName(self, value):
! assert kw['name'] is None, "You cannot change a name after it has already been set"
self.kw['name'] = value
--- 177,181 ----
def setName(self, value):
! assert self.kw['name'] is None, "You cannot change a name after it has already been set"
self.kw['name'] = value
|
|
From: <ian...@us...> - 2003-05-10 21:37:21
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject
In directory sc8-pr-cvs1:/tmp/cvs-serv21770/SQLObject
Modified Files:
SQLObject.py
Log Message:
Added a warning for when a method shadows a column name (which
leads to weird bugs)
Index: SQLObject.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/SQLObject.py,v
retrieving revision 1.33
retrieving revision 1.34
diff -C2 -d -r1.33 -r1.34
*** SQLObject.py 6 May 2003 22:43:35 -0000 1.33
--- SQLObject.py 10 May 2003 21:37:18 -0000 1.34
***************
*** 26,29 ****
--- 26,31 ----
import Col
import Style
+ import types
+ import warnings
import sys
***************
*** 237,240 ****
--- 239,245 ----
continue
if d.has_key(var):
+ if isinstance(d[var], types.MethodType) \
+ or isinstance(d[var], types.FunctionType):
+ warnings.warn("""I tried to set the property "%s", but it was already set, as a method. Methods have significantly different semantics than properties, and this may be a sign of a bug in your code.""" % var)
continue
setFunc(var,
|
|
From: <ian...@us...> - 2003-05-06 22:43:40
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject
In directory sc8-pr-cvs1:/tmp/cvs-serv9293/SQLObject
Modified Files:
Col.py DBConnection.py SQLObject.py
Log Message:
* Col objects are more like definitions/factories, SO* classes
do the actual work (to the degree there is work there)
* SQLObject classes can inherit from each other
* New ._SO_columns attribute that holds the non-factory columns
Index: Col.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Col.py,v
retrieving revision 1.18
retrieving revision 1.19
diff -C2 -d -r1.18 -r1.19
*** Col.py 5 May 2003 17:37:19 -0000 1.18
--- Col.py 6 May 2003 22:43:34 -0000 1.19
***************
*** 16,23 ****
# Col is essentially a column definition, it doesn't have
# much logic to it.
! class Col(object):
def __init__(self,
! name=None,
dbName=None,
default=NoDefault,
--- 16,24 ----
# Col is essentially a column definition, it doesn't have
# much logic to it.
! class SOCol(object):
def __init__(self,
! name,
! soClass,
dbName=None,
default=NoDefault,
***************
*** 26,32 ****
alternateMethodName=None,
constraints=None,
! notNull=False,
unique=NoDefault,
! sqlType=None):
# This isn't strictly true, since we *could* use backquotes
# around column names, but why would anyone *want* to
--- 27,36 ----
alternateMethodName=None,
constraints=None,
! notNull=NoDefault,
! notNone=NoDefault,
unique=NoDefault,
! sqlType=None,
! columnDef=None):
!
# This isn't strictly true, since we *could* use backquotes
# around column names, but why would anyone *want* to
***************
*** 37,55 ****
% repr(name)
assert name != 'id', 'The column name "id" is reserved for SQLObject use (and is implicitly created).'
! self.foreignKey = foreignKey
! self.alternateID = alternateID
! self.alternateMethodName = alternateMethodName
! if unique is NoDefault:
! self.unique = alternateID
! else:
! self.unique = unique
! self.constraints = constraints or []
if type(constraints) not in (type([]), type(())):
constraints = [constraints]
self.constraints = self.autoConstraints() + constraints
! self.notNull = notNull
! self.dbName = dbName
! if notNull:
self.constraints = [Constraints.notNull] + self.constraints
self.name = name
self.soClass = None
--- 41,63 ----
% repr(name)
assert name != 'id', 'The column name "id" is reserved for SQLObject use (and is implicitly created).'
! assert name, "You must provide a name for all columns"
!
! self.columnDef = columnDef
!
if type(constraints) not in (type([]), type(())):
constraints = [constraints]
self.constraints = self.autoConstraints() + constraints
!
! self.notNone = False
! if notNull is not NoDefault:
! self.notNone = notNull
! assert notNone is NoDefault or \
! (not notNone) == (not notNull), \
! "The notNull and notNone arguments are aliases, and must not conflict. You gave notNull=%r, notNone=%r" % (notNull, notNone)
! elif notNone is not NoDefault:
! self.notNone = notNone
! if self.notNone:
self.constraints = [Constraints.notNull] + self.constraints
+
self.name = name
self.soClass = None
***************
*** 57,76 ****
self.customSQLType = sqlType
- def setClass(self, soClass):
- if soClass is self.soClass:
- return
- assert not self.soClass, "This column (%r) has already been associated with another class (%r), and you tried to reassociate it with %r" % (self, self.soClass, soClass)
-
# if they don't give us a specific database name for
# the column, we separate the mixedCase into mixed_case
# and assume that. @@: should be able to define
# different policies for naming.
! if self.dbName is None:
self.dbName = soClass._style.pythonAttrToDBColumn(self.name)
# alternateID means that this is a unique column that
# can be used to identify rows
! if self.alternateID and self.alternateMethodName is None:
self.alternateMethodName = 'by' + self.name[0].capitalize() + self.name[1:]
if self.foreignKey:
assert self.name.upper().endswith('ID'), "All foreign key columns must end with 'ID' (%s)" % repr(self.name)
--- 65,91 ----
self.customSQLType = sqlType
# if they don't give us a specific database name for
# the column, we separate the mixedCase into mixed_case
# and assume that. @@: should be able to define
# different policies for naming.
! if dbName is None:
self.dbName = soClass._style.pythonAttrToDBColumn(self.name)
+ else:
+ self.dbName = dbName
+
# alternateID means that this is a unique column that
# can be used to identify rows
! self.alternateID = alternateID
! if self.alternateID and alternateMethodName is None:
self.alternateMethodName = 'by' + self.name[0].capitalize() + self.name[1:]
+ else:
+ self.alternateMethodName = alternateMethodName
+
+ if unique is NoDefault:
+ self.unique = alternateID
+ else:
+ self.unique = unique
+ self.foreignKey = foreignKey
if self.foreignKey:
assert self.name.upper().endswith('ID'), "All foreign key columns must end with 'ID' (%s)" % repr(self.name)
***************
*** 108,112 ****
if self.alternateID:
r += ' alternate ID'
! if self.notNull:
r += ' not null'
return r + '>'
--- 123,127 ----
if self.alternateID:
r += ' alternate ID'
! if self.notNone:
r += ' not null'
return r + '>'
***************
*** 117,121 ****
def _extraSQL(self):
result = []
! if self.notNull or self.alternateID:
result.append('NOT NULL')
if self.unique or self.alternateID:
--- 132,136 ----
def _extraSQL(self):
result = []
! if self.notNone or self.alternateID:
result.append('NOT NULL')
if self.unique or self.alternateID:
***************
*** 152,160 ****
return ' '.join([self.dbName, self._sqliteType()] + self._extraSQL())
! class StringCol(Col):
# 3-03 @@: What about BLOB?
! def __init__(self, *args, **kw):
self.length = popKey(kw, 'length')
self.varchar = popKey(kw, 'varchar', 'auto')
--- 167,191 ----
return ' '.join([self.dbName, self._sqliteType()] + self._extraSQL())
! class Col(object):
!
! baseClass = SOCol
!
! def __init__(self, name=None, **kw):
! kw['name'] = name
! kw['columnDef'] = self
! self.kw = kw
!
! def setName(self, value):
! assert kw['name'] is None, "You cannot change a name after it has already been set"
! self.kw['name'] = value
!
! def withClass(self, soClass):
! return self.baseClass(soClass=soClass, **self.kw)
!
! class SOStringCol(SOCol):
# 3-03 @@: What about BLOB?
! def __init__(self, **kw):
self.length = popKey(kw, 'length')
self.varchar = popKey(kw, 'varchar', 'auto')
***************
*** 166,170 ****
self.varchar = True
! Col.__init__(self, *args, **kw)
def autoConstraints(self):
--- 197,201 ----
self.varchar = True
! SOCol.__init__(self, **kw)
def autoConstraints(self):
***************
*** 181,186 ****
else:
return 'CHAR(%i)' % self.length
! class IntCol(Col):
# 3-03 @@: support precision, maybe max and min directly
--- 212,220 ----
else:
return 'CHAR(%i)' % self.length
+
+ class StringCol(Col):
+ baseClass = SOStringCol
! class SOIntCol(SOCol):
# 3-03 @@: support precision, maybe max and min directly
***************
*** 192,196 ****
return 'INT'
! class FloatCol(Col):
# 3-03 @@: support precision (e.g., DECIMAL)
--- 226,233 ----
return 'INT'
! class IntCol(Col):
! baseClass = SOIntCol
!
! class SOFloatCol(SOCol):
# 3-03 @@: support precision (e.g., DECIMAL)
***************
*** 202,206 ****
return 'FLOAT'
! class KeyCol(Col):
# 3-03 @@: this should have a simplified constructor
--- 239,246 ----
return 'FLOAT'
! class FloatCol(Col):
! baseClass = SOFloatCol
!
! class SOKeyCol(SOCol):
# 3-03 @@: this should have a simplified constructor
***************
*** 216,226 ****
return 'INT'
! class EnumCol(Col):
! def __init__(self, *args, **kw):
self.enumValues = popKey(kw, 'enumValues', None)
assert self.enumValues is not None, \
'You must provide an enumValues keyword argument'
! Col.__init__(self, *args, **kw)
def autoConstraints(self):
--- 256,269 ----
return 'INT'
! class KeyCol(Col):
! baseClass = SOKeyCol
! class SOEnumCol(SOCol):
!
! def __init__(self, **kw):
self.enumValues = popKey(kw, 'enumValues', None)
assert self.enumValues is not None, \
'You must provide an enumValues keyword argument'
! SOCol.__init__(self, **kw)
def autoConstraints(self):
***************
*** 239,243 ****
return self._postgresType()
! class DateTimeCol(Col):
# 3-03 @@: provide constraints; right now we let the database
--- 282,289 ----
return self._postgresType()
! class EnumCol(Col):
! baseClass = SOEnumCol
!
! class SODateTimeCol(SOCol):
# 3-03 @@: provide constraints; right now we let the database
***************
*** 250,268 ****
return 'TIMESTAMP'
! class DecimalCol(Col):
! def __init__(self, name, size, precision, **kw):
! self.size = size
! self.precision = precision
! Col.__init__(self, name, **kw)
def _sqlType(self):
return 'DECIMAL(%i, %i)' % (self.size, self.precision)
! class CurrencyCol(DecimalCol):
! def __init__(self, name, **kw):
! DecimalCol.__init__(self, name, size=10, precision=2, **kw)
def popKey(kw, name, default=None):
--- 296,325 ----
return 'TIMESTAMP'
! class DateTimeCol(Col):
! baseClass = SODateTimeCol
! class SODecimalCol(SOCol):
!
! def __init__(self, **kw):
! self.size = popKey(kw, 'size', NoDefault)
! assert self.size is not NoDefault, \
! "You must give a size argument"
! self.precision = popKey(kw, 'precision', NoDefault)
! assert self.precision is not NoDefault, \
! "You must give a precision argument"
! SOCol.__init__(self, **kw)
def _sqlType(self):
return 'DECIMAL(%i, %i)' % (self.size, self.precision)
! class DecimalCol(Col):
! baseClass = SODecimalCol
! class SOCurrencyCol(SODecimalCol):
+ def __init__(self, **kw):
+ pushKey(kw, 'size', 10)
+ pushKey(kw, 'precision', 2)
+ SODecimalCol.__init__(self, **kw)
def popKey(kw, name, default=None):
***************
*** 273,283 ****
return value
all = []
for key, value in globals().items():
! try:
! if issubclass(value, Col):
! all.append(key)
! except TypeError:
! pass
__all__ = all
--- 330,341 ----
return value
+ def pushKey(kw, name, value):
+ if not kw.has_key(name):
+ kw[name] = value
+
all = []
for key, value in globals().items():
! if isinstance(value, type) and issubclass(value, Col):
! all.append(key)
__all__ = all
Index: DBConnection.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/DBConnection.py,v
retrieving revision 1.32
retrieving revision 1.33
diff -C2 -d -r1.32 -r1.33
*** DBConnection.py 5 May 2003 17:35:19 -0000 1.32
--- DBConnection.py 6 May 2003 22:43:34 -0000 1.33
***************
*** 164,168 ****
(cls._table, cls._idName,
", ".join(["%s.%s" % (cls._table, col.dbName)
! for col in cls._columns]),
", ".join(select.tables))
--- 164,168 ----
(cls._table, cls._idName,
", ".join(["%s.%s" % (cls._table, col.dbName)
! for col in cls._SO_columns]),
", ".join(select.tables))
***************
*** 221,225 ****
columnDefs = [self.createIDColumn(soClass)] \
+ [self.createColumn(soClass, col)
! for col in soClass._columns]
return ",\n".join([" %s" % c for c in columnDefs])
--- 221,225 ----
columnDefs = [self.createIDColumn(soClass)] \
+ [self.createColumn(soClass, col)
! for col in soClass._SO_columns]
return ",\n".join([" %s" % c for c in columnDefs])
***************
*** 399,403 ****
colClass, kw = self.guessClass(t)
kw['name'] = soClass._style.dbColumnToPythonAttr(field)
! kw['notNull'] = not nullAllowed
kw['default'] = default
# @@ skip key...
--- 399,403 ----
colClass, kw = self.guessClass(t)
kw['name'] = soClass._style.dbColumnToPythonAttr(field)
! kw['notNone'] = not nullAllowed
kw['default'] = default
# @@ skip key...
***************
*** 520,524 ****
colClass, kw = self.guessClass(t)
kw['name'] = soClass._style.dbColumnToPythonAttr(field)
! kw['notNull'] = notnull
if defaultstr is not None:
kw['default'] = getattr(SQLBuilder.const, defaultstr)
--- 520,524 ----
colClass, kw = self.guessClass(t)
kw['name'] = soClass._style.dbColumnToPythonAttr(field)
! kw['notNone'] = notnull
if defaultstr is not None:
kw['default'] = getattr(SQLBuilder.const, defaultstr)
***************
*** 670,678 ****
clauses = []
for name, value in kw.items():
! clauses.append(getattr(SQLBuilder.SmartTable(soClass._table), name) == value)
return SQLBuilder.AND(*clauses)
def _SO_selectJoin(self, soClass, column, value):
results = []
for id in self._allIDs(soClass._table):
d = self._fetchDict(soClass._table, id)
--- 670,680 ----
clauses = []
for name, value in kw.items():
! clauses.append(getattr(soClass.q, name) == value)
return SQLBuilder.AND(*clauses)
def _SO_selectJoin(self, soClass, column, value):
results = []
+ # @@: seems lame I need to do this...
+ value = int(value)
for id in self._allIDs(soClass._table):
d = self._fetchDict(soClass._table, id)
Index: SQLObject.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/SQLObject.py,v
retrieving revision 1.32
retrieving revision 1.33
diff -C2 -d -r1.32 -r1.33
*** SQLObject.py 5 May 2003 20:40:37 -0000 1.32
--- SQLObject.py 6 May 2003 22:43:35 -0000 1.33
***************
*** 87,96 ****
column = Col.Col(column)
columns.append(column)
for attr, value in d.items():
if isinstance(value, Col.Col):
! value.name = attr
! columns.append(value)
del d[attr]
- d['_columns'] = columns
# We *don't* want to inherit _table, so we make sure it
--- 87,99 ----
column = Col.Col(column)
columns.append(column)
+ if columns:
+ d['_columns'] = columns
+
+ implicitColumns = []
for attr, value in d.items():
if isinstance(value, Col.Col):
! value.setName(attr)
! implicitColumns.append(value)
del d[attr]
# We *don't* want to inherit _table, so we make sure it
***************
*** 108,111 ****
--- 111,120 ----
newClass._SO_finishedClassCreation = False
+ # We append to _columns, but we don't want to change the
+ # superclass's _columns list, so we make a copy if necessary
+ if not d.has_key('_columns'):
+ newClass._columns = newClass._columns[:]
+ newClass._columns.extend(implicitColumns)
+
######################################################
# Set some attributes to their defaults, if necessary.
***************
*** 148,151 ****
--- 157,161 ----
# This is a dictionary of columnName: columnObject
newClass._SO_columnDict = {}
+ newClass._SO_columns = []
# If _table isn't given, use style default
***************
*** 288,291 ****
--- 298,303 ----
_connection = None
+ _columns = []
+
_joins = []
***************
*** 329,340 ****
return val
! def addColumn(cls, column, changeSchema=False):
! column.setClass(cls)
name = column.name
assert name != 'id', "The 'id' column is implicit, and should not be defined as a column"
cls._SO_columnDict[name] = column
! if column not in cls._columns:
! cls._columns.append(column)
###################################################
--- 341,353 ----
return val
! def addColumn(cls, columnDef, changeSchema=False):
! column = columnDef.withClass(cls)
name = column.name
assert name != 'id', "The 'id' column is implicit, and should not be defined as a column"
cls._SO_columnDict[name] = column
+ cls._SO_columns.append(column)
! if columnDef not in cls._columns:
! cls._columns.append(columnDef)
###################################################
***************
*** 435,441 ****
def addColumnsFromDatabase(cls):
! for column in cls._connection.columnsFromSchema(cls._table, cls):
! if not cls._SO_columnDict.has_key(column.name):
! cls.addColumn(column)
addColumnsFromDatabase = classmethod(addColumnsFromDatabase)
--- 448,459 ----
def addColumnsFromDatabase(cls):
! for columnDef in cls._connection.columnsFromSchema(cls._table, cls):
! alreadyExists = False
! for c in cls._columns:
! if c.kw['name'] == columnDef.kw['name']:
! alreadyExists = True
! break
! if not alreadyExists:
! cls.addColumn(columnDef)
addColumnsFromDatabase = classmethod(addColumnsFromDatabase)
***************
*** 444,448 ****
if isinstance(column, str):
column = cls._SO_columnDict[column]
! cls._columns.remove(column)
name = column.name
del cls._SO_columnDict[name]
--- 462,472 ----
if isinstance(column, str):
column = cls._SO_columnDict[column]
! if isinstance(column, Col.Col):
! for c in cls._SO_columns:
! if column is c.columnDef:
! column = c
! break
! cls._SO_columns.remove(column)
! cls._columns.remove(column.columnDef)
name = column.name
del cls._SO_columnDict[name]
***************
*** 570,574 ****
self._SO_perConnection = True
! dbNames = [col.dbName for col in self._columns]
if not selectResults:
selectResults = (connection or self._connection)._SO_selectOne(self, dbNames)
--- 594,598 ----
self._SO_perConnection = True
! dbNames = [col.dbName for col in self._SO_columns]
if not selectResults:
selectResults = (connection or self._connection)._SO_selectOne(self, dbNames)
***************
*** 629,633 ****
def _SO_selectInit(self, row):
! for col, colValue in zip(self._columns, row):
setattr(self, instanceName(col.name), colValue)
--- 653,657 ----
def _SO_selectInit(self, row):
! for col, colValue in zip(self._SO_columns, row):
setattr(self, instanceName(col.name), colValue)
***************
*** 659,663 ****
# First we do a little fix-up on the keywords we were
# passed:
! for column in inst._columns:
# If a foreign key is given, we get the ID of the object
--- 683,687 ----
# First we do a little fix-up on the keywords we were
# passed:
! for column in inst._SO_columns:
# If a foreign key is given, we get the ID of the object
***************
*** 695,699 ****
# The rest go through setattr():
for name, value in others.items():
! if not cls.__dict__.has_key(name):
raise TypeError, "%s.new() got an unexpected keyword argument %s" % (cls.__name__, name)
setattr(inst, name, value)
--- 719,725 ----
# The rest go through setattr():
for name, value in others.items():
! try:
! getattr(cls, name)
! except AttributeError:
raise TypeError, "%s.new() got an unexpected keyword argument %s" % (cls.__name__, name)
setattr(inst, name, value)
***************
*** 732,736 ****
cls,
[cls._idName] +
! [col.dbName for col in cls._columns],
dbIDName,
value)
--- 758,762 ----
cls,
[cls._idName] +
! [col.dbName for col in cls._SO_columns],
dbIDName,
value)
***************
*** 833,837 ****
def _reprItems(self):
items = []
! for col in self._columns:
value = getattr(self, col.name)
r = repr(value)
--- 859,863 ----
def _reprItems(self):
items = []
! for col in self._SO_columns:
value = getattr(self, col.name)
r = repr(value)
|
|
From: <ian...@us...> - 2003-05-06 22:43:40
|
Update of /cvsroot/sqlobject/SQLObject/tests
In directory sc8-pr-cvs1:/tmp/cvs-serv9293/tests
Modified Files:
test.py
Log Message:
* Col objects are more like definitions/factories, SO* classes
do the actual work (to the degree there is work there)
* SQLObject classes can inherit from each other
* New ._SO_columns attribute that holds the non-factory columns
Index: test.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/tests/test.py,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -d -r1.11 -r1.12
*** test.py 6 May 2003 21:02:00 -0000 1.11
--- test.py 6 May 2003 22:43:35 -0000 1.12
***************
*** 363,369 ****
def testSuper(self):
- return
- print 'super', Super._columns
- print 'sub', Sub._columns
s1 = Super.new(name='one')
s2 = Super.new(name='two')
--- 363,366 ----
***************
*** 372,376 ****
def testSub(self):
- return
s1 = Sub.new(name='one', name2='1')
s2 = Sub.new(name='two', name2='2')
--- 369,372 ----
|
|
From: <ian...@us...> - 2003-05-06 21:02:05
|
Update of /cvsroot/sqlobject/SQLObject/tests
In directory sc8-pr-cvs1:/tmp/cvs-serv29477/tests
Modified Files:
test.py
Log Message:
Added a test of MultipleJoin
Index: test.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/tests/test.py,v
retrieving revision 1.10
retrieving revision 1.11
diff -C2 -d -r1.10 -r1.11
*** test.py 5 May 2003 17:35:20 -0000 1.10
--- test.py 6 May 2003 21:02:00 -0000 1.11
***************
*** 33,36 ****
--- 33,45 ----
self.assertEqual(bob.passwd, 'god'.encode('rot13'))
+ class TestCaseGetSet(TestCase1):
+
+ def testGet(self):
+ bob = TestSO1.selectBy(name='bob')[0]
+ self.assertEqual(bob.name, 'bob')
+ bob.name = 'joe'
+ self.assertEqual(bob.name, 'joe')
+
+
########################################
## Delete during select
***************
*** 298,301 ****
--- 307,348 ----
def assertNamesEqual(self, people, dest):
self.assertEqual([p.name for p in people], dest)
+
+ class PersonJoiner2(SQLObject):
+
+ _columns = [StringCol('name', length=40, alternateID=True)]
+ _joins = [MultipleJoin('AddressJoiner2')]
+
+ class AddressJoiner2(SQLObject):
+
+ _columns = [StringCol('zip', length=5),
+ KeyCol('personJoiner2ID', foreignKey='PersonJoiner2')]
+
+ class JoinTest2(SQLObjectTest):
+
+ classes = [PersonJoiner2, AddressJoiner2]
+
+ def inserts(self):
+ p1 = PersonJoiner2.new(name='bob')
+ p2 = PersonJoiner2.new(name='sally')
+ for z in ['11111', '22222', '33333']:
+ a = AddressJoiner2.new(zip=z, personJoiner2=p1)
+ #p1.addAddressJoiner2(a)
+ AddressJoiner2.new(zip='00000', personJoiner2=p2)
+
+ def test(self):
+ bob = PersonJoiner2.byName('bob')
+ sally = PersonJoiner2.byName('sally')
+ self.assertEqual(len(bob.addressJoiner2s), 3)
+ self.assertEqual(len(sally.addressJoiner2s), 1)
+ bob.addressJoiner2s[0].destroySelf()
+ self.assertEqual(len(bob.addressJoiner2s), 2)
+ z = bob.addressJoiner2s[0]
+ z.zip = 'xxxxx'
+ id = z.id
+ del z
+ z = AddressJoiner2(id)
+ self.assertEqual(z.zip, 'xxxxx')
+
+
########################################
|
|
From: <ian...@us...> - 2003-05-05 20:42:12
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject
In directory sc8-pr-cvs1:/tmp/cvs-serv14782/SQLObject
Modified Files:
Cache.py
Log Message:
Added clear method to CacheSet too...
Index: Cache.py
===================================================================
RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Cache.py,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** Cache.py 5 May 2003 20:40:37 -0000 1.6
--- Cache.py 5 May 2003 20:42:08 -0000 1.7
***************
*** 174,175 ****
--- 174,183 ----
except KeyError:
pass
+
+ def clear(self, cls=None):
+ if cls is None:
+ for cache in self.caches.values():
+ cache.clear()
+ elif self.caches.has_key(cls.__name__):
+ self.caches[cls.__name__].clear()
+
|