sqlobject-cvs Mailing List for SQLObject (Page 181)
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
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <sub...@co...> - 2004-02-07 23:28:03
|
Author: ianb Date: Sat Feb 7 14:20:47 2004 New Revision: 5 Modified: trunk/SQLObject/docs/default.css Log: Made notes and warnings display more nicely. Modified: trunk/SQLObject/docs/default.css ============================================================================== --- trunk/SQLObject/docs/default.css (original) +++ trunk/SQLObject/docs/default.css Sat Feb 7 14:20:47 2004 @@ -53,9 +53,10 @@ // margin: 2em ; background-color: #cccccc; align: center; - //width: 60%; - // border: medium outset ; + width: 40%; + border: medium outset ; padding: 3px; + float: right; } div.attention p.admonition-title, div.caution p.admonition-title, @@ -64,13 +65,19 @@ color: red ; font-weight: bold ; font-family: sans-serif; - text-align: center } + text-align: center; + display: block; + background-color: #999999; + margin: 0; } div.hint p.admonition-title, div.important p.admonition-title, div.note p.admonition-title, div.tip p.admonition-title { font-weight: bold ; font-family: sans-serif; - text-align: center } + text-align: center; + display: block; + background-color: #999999; + margin: 0; } div.dedication { margin: 2em 5em ; |
From: <sub...@co...> - 2004-02-07 23:27:51
|
Author: ianb Date: Sat Feb 7 14:20:30 2004 New Revision: 4 Modified: trunk/SQLObject/docs/Plan06.txt Log: Fixed some reST formatting problems Modified: trunk/SQLObject/docs/Plan06.txt ============================================================================== --- trunk/SQLObject/docs/Plan06.txt (original) +++ trunk/SQLObject/docs/Plan06.txt Sat Feb 7 14:20:30 2004 @@ -116,36 +116,45 @@ explicit ways to control things like: 1. Caching of instances: - + Application/process-global definition. - + Database-level definition. - + Transaction/EditingContext-level definition. - + Class-level definition. + + * Application/process-global definition. + * Database-level definition. + * Transaction/EditingContext-level definition. + * Class-level definition. + 2. Caching of columns: - + Class-level. + + * Class-level. + 3. Cache sweep frequency: - + Application/process-global. - + Database-level. - + Class-level. - + Doesn't need to be as complete as 1; maybe on the class level you + + * Application/process-global. + * Database-level. + * Class-level. + * Doesn't need to be as complete as 1; maybe on the class level you could only indicate that a certain class should not be sweeped. - + Sweep during a fetch (e.g., every 100 fetches), by time or fetch + * Sweep during a fetch (e.g., every 100 fetches), by time or fetch frequency, or sweep with an explicit call (e.g., to do sweeps in a separate thread). + 4. Cache sweep policy: - + Maximum age. - + Least-recently-used (actually, least-recently-fetched). - + Random (the current policy). - + Multi-level (randomly move objects to a lower-priority cache, + + * Maximum age. + * Least-recently-used (actually, least-recently-fetched). + * Random (the current policy). + * Multi-level (randomly move objects to a lower-priority cache, raise level when the object is fetched again). - + Target cache size (keep trimming until the cache is small + * Target cache size (keep trimming until the cache is small enough). - + Simple policy (if enough objects qualify, cache can be of any + * Simple policy (if enough objects qualify, cache can be of any size). - + Percentage culling (e.g., kill 33% of objects for each sweep; + * Percentage culling (e.g., kill 33% of objects for each sweep; this is the current policy). + 5. Batching of updates (whether updates should immediately go to the database, or whether it would be batched until a commit or other signal). + 6. Natural expiring of objects. Even if an object must persist because there are still references, we could expire it so that future accesses re-query the database. To avoid stale data. |
From: <sub...@co...> - 2004-02-06 06:17:06
|
Author: ianb Date: Thu Feb 5 21:09:52 2004 New Revision: 3 Modified: trunk/SQLObject/sqlobject/dbconnection.py trunk/SQLObject/sqlobject/joins.py trunk/SQLObject/sqlobject/main.py trunk/SQLObject/tests/ (props changed) trunk/SQLObject/tests/test.py Log: Renamed __new__ to get, renamed new to __init__ (in other words, class instantiation creates a row, while the get() class method fetches an object) Modified: trunk/SQLObject/sqlobject/dbconnection.py ============================================================================== --- trunk/SQLObject/sqlobject/dbconnection.py (original) +++ trunk/SQLObject/sqlobject/dbconnection.py Thu Feb 5 21:09:52 2004 @@ -176,10 +176,10 @@ self.releaseConnection(conn) break if select.ops.get('lazyColumns', 0): - obj = select.sourceClass(result[0], connection=withConnection) + obj = select.sourceClass.get(result[0], connection=withConnection) yield obj else: - obj = select.sourceClass(result[0], selectResults=result[1:], connection=withConnection) + obj = select.sourceClass.get(result[0], selectResults=result[1:], connection=withConnection) yield obj def iterSelect(self, select): @@ -1358,7 +1358,7 @@ if not self._maxNext: raise StopIteration self._maxNext -= 1 - return self.select.sourceClass(int(idList[self.tableDict[self.select.sourceClass._table]])) + return self.select.sourceClass.get(int(idList[self.tableDict[self.select.sourceClass._table]])) raise StopIteration def field(self, table, field): Modified: trunk/SQLObject/sqlobject/joins.py ============================================================================== --- trunk/SQLObject/sqlobject/joins.py (original) +++ trunk/SQLObject/sqlobject/joins.py Thu Feb 5 21:09:52 2004 @@ -115,7 +115,7 @@ conn = inst._connection else: conn = None - return self._applyOrderBy([self.otherClass(id, conn) for (id,) in ids if id is not None], self.otherClass) + return self._applyOrderBy([self.otherClass.get(id, conn) for (id,) in ids if id is not None], self.otherClass) class MultipleJoin(Join): baseClass = SOMultipleJoin @@ -155,7 +155,7 @@ conn = inst._connection else: conn = None - return self._applyOrderBy([self.otherClass(id, conn) for (id,) in ids if id is not None], self.otherClass) + return self._applyOrderBy([self.otherClass.get(id, conn) for (id,) in ids if id is not None], self.otherClass) def remove(self, inst, other): inst._connection._SO_intermediateDelete( Modified: trunk/SQLObject/sqlobject/main.py ============================================================================== --- trunk/SQLObject/sqlobject/main.py (original) +++ trunk/SQLObject/sqlobject/main.py Thu Feb 5 21:09:52 2004 @@ -309,26 +309,10 @@ # when necessary: (bad clever? maybe) _expired = False - def __new__(cls, id, connection=None, selectResults=None): + def get(cls, id, connection=None, selectResults=None): assert id is not None, 'None is not a possible id for %s' % cls.__name - # When id is CreateNewSQLObject, that means we are trying to - # create a new object. This is a contract of sorts with the - # `new()` method. - if id is CreateNewSQLObject: - # Create an actual new object: - inst = object.__new__(cls) - inst._SO_creating = True - inst._SO_validatorState = SQLObjectState(inst) - # This is a dictionary of column-names to - # column-values for the new row: - inst._SO_createValues = {} - if connection is not None: - inst._connection = connection - assert selectResults is None - return inst - # Some databases annoyingly return longs for INT if isinstance(id, long): id = int(id) @@ -343,7 +327,7 @@ val = cache.get(id, cls) if val is None: try: - val = object.__new__(cls) + val = cls(_SO_fetch_no_create=1) val._SO_validatorState = SQLObjectState(val) val._init(id, connection, selectResults) cache.put(id, cls, val) @@ -351,6 +335,8 @@ cache.finishPut(cls) return val + get = classmethod(get) + def addColumn(cls, columnDef, changeSchema=False): column = columnDef.withClass(cls) name = column.name @@ -755,22 +741,25 @@ if id is None: return None elif self._SO_perConnection: - return joinClass(id, connection=self._connection) + return joinClass.get(id, connection=self._connection) else: - return joinClass(id) - - def new(cls, **kw): - # This is what creates a new row, plus the new Python - # object to go with it. + return joinClass.get(id) + def __init__(self, **kw): + # The get() classmethod/constructor uses a magic keyword + # argument when it wants an empty object, fetched from the + # database. So we have nothing more to do in that case: + if kw.has_key('_SO_fetch_no_create'): + return + # Pass the connection object along if we were given one. # Passing None for the ID tells __new__ we want to create # a new object. if kw.has_key('connection'): - inst = cls(CreateNewSQLObject, connection=kw['connection']) + self._connection = kw['connection'] + self._SO_perConnection = True del kw['connection'] - else: - inst = cls(CreateNewSQLObject) + self._SO_writeLock = threading.Lock() if kw.has_key('id'): id = kw['id'] @@ -778,9 +767,13 @@ else: id = None + self._SO_creating = True + self._SO_createValues = {} + self._SO_validatorState = SQLObjectState(self) + # First we do a little fix-up on the keywords we were # passed: - for column in inst._SO_columns: + for column in self._SO_columns: # If a foreign key is given, we get the ID of the object # and put that in instead @@ -805,27 +798,25 @@ forDB = {} others = {} for name, value in kw.items(): - if name in inst._SO_plainSetters: + if name in self._SO_plainSetters: forDB[name] = value else: others[name] = value # We take all the straight-to-DB values and use set() to # set them: - inst.set(**forDB) + self.set(**forDB) # The rest go through setattr(): for name, value in others.items(): try: - getattr(cls, name) + getattr(self.__class__, name) except AttributeError: - raise TypeError, "%s.new() got an unexpected keyword argument %s" % (cls.__name__, name) - setattr(inst, name, value) + raise TypeError, "%s.new() got an unexpected keyword argument %s" % (self.__class__.__name__, name) + setattr(self, name, value) # Then we finalize the process: - inst._SO_finishCreate(id) - return inst - new = classmethod(new) + self._SO_finishCreate(id) def _SO_finishCreate(self, id=None): # Here's where an INSERT is finalized. @@ -863,9 +854,9 @@ if not result: raise SQLObjectNotFound, "The %s by alternateID %s=%s does not exist" % (cls.__name__, dbIDName, repr(value)) if connection: - obj = cls(result[0], connection=connection) + obj = cls.get(result[0], connection=connection) else: - obj = cls(result[0]) + obj = cls.get(result[0]) if not obj._cacheValues: obj._SO_writeLock.acquire() try: Modified: trunk/SQLObject/tests/test.py ============================================================================== --- trunk/SQLObject/tests/test.py (original) +++ trunk/SQLObject/tests/test.py Thu Feb 5 21:09:52 2004 @@ -46,7 +46,7 @@ def inserts(self): for name, passwd in self.info: - self.MyClass.new(name=name, passwd=passwd) + self.MyClass(name=name, passwd=passwd) def testGet(self): bob = self.MyClass.selectBy(name='bob')[0] @@ -96,7 +96,7 @@ classes = [Student] def testBoolCol(self): - student = Student.new(is_smart = False) + student = Student(is_smart=False) self.assertEqual(student.is_smart, False) class TestCase34(SQLObjectTest): @@ -104,30 +104,30 @@ classes = [TestSO3, TestSO4] def testForeignKey(self): - tc3 = TestSO3.new(name='a') + tc3 = TestSO3(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') + tc4a = TestSO4(me='1') tc3.other = tc4a self.assertEqual(tc3.other, tc4a) self.assertEqual(tc3.otherID, tc4a.id) - tc4b = TestSO4.new(me='2') + tc4b = TestSO4(me='2') tc3.other = tc4b.id self.assertEqual(tc3.other, tc4b) self.assertEqual(tc3.otherID, tc4b.id) - tc4c = TestSO4.new(me='3') + tc4c = TestSO4(me='3') tc3.other2 = tc4c self.assertEqual(tc3.other2, tc4c) self.assertEqual(tc3.other2ID, tc4c.id) - tc4d = TestSO4.new(me='4') + tc4d = TestSO4(me='4') tc3.other2 = tc4d.id self.assertEqual(tc3.other2, tc4d) self.assertEqual(tc3.other2ID, tc4d.id) - tcc = TestSO3.new(name='b', other=tc4a) + tcc = TestSO3(name='b', other=tc4a) self.assertEqual(tcc.other, tc4a) - tcc2 = TestSO3.new(name='c', other=tc4a.id) + tcc2 = TestSO3(name='c', other=tc4a.id) self.assertEqual(tcc2.other, tc4a) class TestSO5(SQLObject): @@ -147,10 +147,10 @@ classes = [TestSO7, TestSO6, TestSO5] def testForeignKeyDestroySelfCascade(self): - tc5 = TestSO5.new(name='a') - tc6a = TestSO6.new(name='1') + tc5 = TestSO5(name='a') + tc6a = TestSO6(name='1') tc5.other = tc6a - tc7a = TestSO7.new(name='2') + tc7a = TestSO7(name='2') tc6a.other = tc7a tc5.another = tc7a self.assertEqual(tc5.other, tc6a) @@ -165,9 +165,9 @@ self.assertEqual(TestSO5.select().count(), 1) self.assertEqual(TestSO6.select().count(), 1) self.assertEqual(TestSO7.select().count(), 1) - tc6b = TestSO6.new(name='3') - tc6c = TestSO6.new(name='4') - tc7b = TestSO7.new(name='5') + tc6b = TestSO6(name='3') + tc6c = TestSO6(name='4') + tc7b = TestSO7(name='5') tc6b.other = tc7b tc6c.other = tc7b self.assertEqual(TestSO5.select().count(), 1) @@ -187,15 +187,15 @@ self.assertEqual(TestSO7.select().count(), 0) def testForeignKeyDropTableCascade(self): - tc5a = TestSO5.new(name='a') - tc6a = TestSO6.new(name='1') + tc5a = TestSO5(name='a') + tc6a = TestSO6(name='1') tc5a.other = tc6a - tc7a = TestSO7.new(name='2') + tc7a = TestSO7(name='2') tc6a.other = tc7a tc5a.another = tc7a - tc5b = TestSO5.new(name='b') - tc5c = TestSO5.new(name='c') - tc6b = TestSO6.new(name='3') + tc5b = TestSO5(name='b') + tc5c = TestSO5(name='c') + tc6b = TestSO6(name='3') tc5c.other = tc6b self.assertEqual(TestSO5.select().count(), 3) self.assertEqual(TestSO6.select().count(), 2) @@ -210,7 +210,7 @@ self.assertEqual(TestSO5.select().count(), 1) self.assertEqual(TestSO6.select().count(), 0) self.assertEqual(iter(TestSO5.select()).next(), tc5b) - tc6c = TestSO6.new(name='3') + tc6c = TestSO6(name='3') tc5b.other = tc6c self.assertEqual(TestSO5.select().count(), 1) self.assertEqual(TestSO6.select().count(), 1) @@ -230,11 +230,11 @@ classes = [TestSO9, TestSO8] def testForeignKeyDestroySelfRestrict(self): - tc8a = TestSO8.new(name='a') - tc9a = TestSO9.new(name='1') + tc8a = TestSO8(name='a') + tc9a = TestSO9(name='1') tc8a.other = tc9a - tc8b = TestSO8.new(name='b') - tc9b = TestSO9.new(name='2') + tc8b = TestSO8(name='b') + tc9b = TestSO9(name='2') self.assertEqual(tc8a.other, tc9a) self.assertEqual(tc8a.otherID, tc9a.id) self.assertEqual(TestSO8.select().count(), 2) @@ -270,7 +270,7 @@ for fname, lname in [('aj', 'baker'), ('joe', 'robbins'), ('tim', 'jackson'), ('joe', 'baker'), ('zoe', 'robbins')]: - Names.new(fname=fname, lname=lname) + Names(fname=fname, lname=lname) def testDefaultOrder(self): self.assertEqual([(n.fname, n.lname) for n in Names.select()], @@ -300,7 +300,7 @@ def inserts(self): for name in self.names: - IterTest.new(name=name) + IterTest(name=name) def test_00_normal(self): count = 0 @@ -379,15 +379,15 @@ classes = [TestSOTrans] def inserts(self): - TestSOTrans.new(name='bob') - TestSOTrans.new(name='tim') + TestSOTrans(name='bob') + TestSOTrans(name='tim') def testTransaction(self): if not self.supportTransactions: return trans = TestSOTrans._connection.transaction() try: TestSOTrans._connection.autoCommit = 'exception' - TestSOTrans.new(name='joe', connection=trans) + TestSOTrans(name='joe', connection=trans) trans.rollback() self.assertEqual([n.name for n in TestSOTrans.select(connection=trans)], ['bob', 'tim']) @@ -418,12 +418,12 @@ def inserts(self): for l in ['a', 'bcd', 'a', 'e']: - Enum1.new(l=l) + Enum1(l=l) def testBad(self): if self.supportRestrictedEnum: try: - v = Enum1.new(l='b') + v = Enum1(l='b') except Exception, e: pass else: @@ -447,7 +447,7 @@ def inserts(self): for i in range(100): - Counter.new(number=i) + Counter(number=i) def counterEqual(self, counters, value): self.assertEquals([c.number for c in counters], value) @@ -492,7 +492,7 @@ def inserts(self): for i in range(10): for j in range(10): - Counter2.new(n1=i, n2=j) + Counter2(n1=i, n2=j) def counterEqual(self, counters, value): self.assertEquals([(c.n1, c.n2) for c in counters], value) @@ -517,10 +517,10 @@ def inserts(self): for n in ['jane', 'tim', 'bob', 'jake']: - Person.new(name=n) + Person(name=n) for p in ['555-555-5555', '555-394-2930', '444-382-4854']: - Phone.new(phone=p) + Phone(phone=p) def testDefaultOrder(self): self.assertEqual(list(Person.select('all')), @@ -531,7 +531,7 @@ return nickname = StringCol('nickname', length=10) Person.addColumn(nickname, changeSchema=True) - n = Person.new(name='robert', nickname='bob') + n = Person(name='robert', nickname='bob') self.assertEqual([p.name for p in Person.select('all')], ['bob', 'jake', 'jane', 'robert', 'tim']) Person.delColumn(nickname, changeSchema=True) @@ -613,20 +613,19 @@ def testClassCreate(self): if not self.supportAuto: return - import sys class AutoTest(SQLObject): _fromDatabase = True _connection = connection() - john = AutoTest.new(firstName='john', - lastName='doe', - age=10, - created=DateTime.now(), - wannahavefun=False) - jane = AutoTest.new(firstName='jane', - lastName='doe', - happy='N', - created=DateTime.now(), - wannahavefun=True) + john = AutoTest(firstName='john', + lastName='doe', + age=10, + created=DateTime.now(), + wannahavefun=False) + jane = AutoTest(firstName='jane', + lastName='doe', + happy='N', + created=DateTime.now(), + wannahavefun=True) self.failIf(john.wannahavefun) self.failUnless(jane.wannahavefun) del classregistry.registry(AutoTest._registry).classes['AutoTest'] @@ -651,9 +650,9 @@ def inserts(self): for n in ['bob', 'tim', 'jane', 'joe', 'fred', 'barb']: - PersonJoiner.new(name=n) + PersonJoiner(name=n) for z in ['11111', '22222', '33333', '44444']: - AddressJoiner.new(zip=z) + AddressJoiner(zip=z) def testJoin(self): b = PersonJoiner.byName('bob') @@ -693,12 +692,12 @@ classes = [PersonJoiner2, AddressJoiner2] def inserts(self): - p1 = PersonJoiner2.new(name='bob') - p2 = PersonJoiner2.new(name='sally') + p1 = PersonJoiner2(name='bob') + p2 = PersonJoiner2(name='sally') for z in ['11111', '22222', '33333']: - a = AddressJoiner2.new(zip=z, personJoiner2=p1) + a = AddressJoiner2(zip=z, personJoiner2=p1) #p1.addAddressJoiner2(a) - AddressJoiner2.new(zip='00000', personJoiner2=p2) + AddressJoiner2(zip='00000', personJoiner2=p2) def test(self): bob = PersonJoiner2.byName('bob') @@ -711,7 +710,7 @@ z.zip = 'xxxxx' id = z.id del z - z = AddressJoiner2(id) + z = AddressJoiner2.get(id) self.assertEqual(z.zip, 'xxxxx') def testDefaultOrder(self): @@ -737,15 +736,15 @@ classes = [Super, Sub] def testSuper(self): - s1 = Super.new(name='one') - s2 = Super.new(name='two') - s3 = Super(s1.id) + s1 = Super(name='one') + s2 = Super(name='two') + s3 = Super.get(s1.id) self.assertEqual(s1, s3) def testSub(self): - s1 = Sub.new(name='one', name2='1') - s2 = Sub.new(name='two', name2='2') - s3 = Sub(s1.id) + s1 = Sub(name='one', name2='1') + s2 = Sub(name='two', name2='2') + s3 = Sub.get(s1.id) self.assertEqual(s1, s3) @@ -761,8 +760,8 @@ classes = [SyncTest] def inserts(self): - SyncTest.new(name='bob') - SyncTest.new(name='tim') + SyncTest(name='bob') + SyncTest(name='tim') def testExpire(self): conn = SyncTest._connection @@ -792,19 +791,19 @@ classes = [SOValidation] def testValidate(self): - t = SOValidation.new(name='hey') + t = SOValidation(name='hey') self.assertRaises(validators.InvalidField, setattr, t, 'name', '!!!') t.name = 'you' def testConfirmType(self): - t = SOValidation.new(name2='hey') + t = SOValidation(name2='hey') self.assertRaises(validators.InvalidField, setattr, t, 'name2', 1) t.name2 = 'you' def testWrapType(self): - t = SOValidation.new(name3=1) + t = SOValidation(name3=1) self.assertRaises(validators.InvalidField, setattr, t, 'name3', 'x') t.name3 = 1L @@ -863,11 +862,11 @@ classes = [SOStringID] def testStringID(self): - t = SOStringID.new(id='hey', val='whatever') + t = SOStringID(id='hey', val='whatever') t2 = SOStringID.byVal('whatever') self.assertEqual(t, t2) - t3 = SOStringID.new(id='you', val='nowhere') - t4 = SOStringID('you') + t3 = SOStringID(id='you', val='nowhere') + t4 = SOStringID.get('you') self.assertEqual(t3, t4) @@ -894,8 +893,8 @@ def test(self): - st1 = SOStyleTest1.new(a='something', st2=None) - st2 = SOStyleTest2.new(b='whatever') + st1 = SOStyleTest1(a='something', st2=None) + st2 = SOStyleTest2(b='whatever') st1.st2 = st2 self.assertEqual(st1._SO_columnDict['st2ID'].dbName, 'idst2') self.assertEqual(st1.st2, st2) |
From: <bbo...@us...> - 2004-01-21 22:24:08
|
Update of /cvsroot/sqlobject/SQLObject/docs In directory sc8-pr-cvs1:/tmp/cvs-serv1886/docs Modified Files: Authors.txt Log Message: Added myself to the list of contributors. Index: Authors.txt =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/docs/Authors.txt,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** Authors.txt 1 Nov 2003 20:33:18 -0000 1.4 --- Authors.txt 21 Jan 2004 22:24:05 -0000 1.5 *************** *** 13,14 **** --- 13,15 ---- * James Ralston <jralston at hotmail.com> * Sidnei da Silva <sidnei at awkly.org> + * Brad Bollenbach <brad at bbnet.ca> |
From: <bbo...@us...> - 2004-01-21 22:21:36
|
Update of /cvsroot/sqlobject/SQLObject/tests In directory sc8-pr-cvs1:/tmp/cvs-serv32608/tests Modified Files: test.py Log Message: Fixed so that class BOOL is a new-style class (inherits from object), so that the call to registerConverter actually means something (without inheriting from object, the type is just <type 'instance'>, which is useless when registering a converter for that type.) There hadn't been any tests for this. :/ Index: test.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/tests/test.py,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** test.py 4 Dec 2003 16:46:31 -0000 1.37 --- test.py 21 Jan 2004 22:21:33 -0000 1.38 *************** *** 89,92 **** --- 89,102 ---- me = StringCol(length=10) + class Student(SQLObject): + is_smart = BoolCol() + + class BoolColTest(SQLObjectTest): + classes = [Student] + + def testBoolCol(self): + student = Student.new(is_smart = False) + self.assertEqual(student.is_smart, False) + class TestCase34(SQLObjectTest): |
From: <bbo...@us...> - 2004-01-21 22:21:35
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv32608/SQLObject Modified Files: Converters.py Log Message: Fixed so that class BOOL is a new-style class (inherits from object), so that the call to registerConverter actually means something (without inheriting from object, the type is just <type 'instance'>, which is useless when registering a converter for that type.) There hadn't been any tests for this. :/ Index: Converters.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Converters.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** Converters.py 14 Jan 2004 14:34:28 -0000 1.11 --- Converters.py 21 Jan 2004 22:21:32 -0000 1.12 *************** *** 24,28 **** if type(1==1) == type(1): ! class BOOL: def __init__(self, value): self.value = not not value --- 24,28 ---- if type(1==1) == type(1): ! class BOOL(object): def __init__(self, value): self.value = not not value |
From: <dre...@us...> - 2004-01-14 14:34:31
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv9410 Modified Files: Col.py Converters.py DBConnection.py SQLBuilder.py Log Message: More sybase support. Table creation, toggle IDENTITY_INSERT if id is passed. Added NumericType converter. Limit is not supported. Index: Col.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Col.py,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** Col.py 13 Jan 2004 15:34:37 -0000 1.37 --- Col.py 14 Jan 2004 14:34:28 -0000 1.38 *************** *** 171,175 **** def _sqlType(self): if self.customSQLType is None: ! raise ValueError, "Col cannot be used for automatic schema creation (too abstract)" else: return self.customSQLType --- 171,177 ---- def _sqlType(self): if self.customSQLType is None: ! raise ValueError, ("Col %s (%s) cannot be used for automatic " ! "schema creation (too abstract)" % ! (self.name, self.__class__)) else: return self.customSQLType *************** *** 340,343 **** --- 342,348 ---- return 'INT' + def _sybaseType(self): + return 'INT' + def _firebirdType(self): return 'INT' *************** *** 378,381 **** --- 383,398 ---- return sql + def sybaseCreateSQL(self): + from SQLObject import findClass + sql = SOKeyCol.sybaseCreateSQL(self) + other = findClass(self.foreignKey) + tName = other._table + idName = other._idName + reference = ('REFERENCES %(tName)s(%(idName)s) ' % + {'tName':tName, + 'idName':idName}) + sql = ' '.join([sql, reference]) + return sql + class ForeignKey(KeyCol): Index: Converters.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Converters.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** Converters.py 13 Jan 2004 15:34:37 -0000 1.10 --- Converters.py 14 Jan 2004 14:34:28 -0000 1.11 *************** *** 17,20 **** --- 17,26 ---- datetime = None + try: + import Sybase + NumericType=Sybase.NumericType + except ImportError: + NumericType = None + if type(1==1) == type(1): class BOOL: *************** *** 102,105 **** --- 108,114 ---- registerConverter(type(0L), IntConverter) + if NumericType: + registerConverter(NumericType, IntConverter) + def BoolConverter(value, db): if db in ('postgres',): *************** *** 171,172 **** --- 180,183 ---- else: return reprFunc(db) + + Index: DBConnection.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/DBConnection.py,v retrieving revision 1.61 retrieving revision 1.62 diff -C2 -d -r1.61 -r1.62 *** DBConnection.py 13 Jan 2004 15:37:58 -0000 1.61 --- DBConnection.py 14 Jan 2004 14:34:28 -0000 1.62 *************** *** 807,810 **** --- 807,813 ---- names = [idName] + names values = [id] + values + c.execute('SET IDENTITY_INSERT %s ON' % table) + else: + c.execute('SET IDENTITY_INSERT %s OFF' % table) q = self._insertSQL(table, names, values) if self.debug: *************** *** 812,816 **** c.execute(q) if id is None: ! id = self.insert_id() if self.debugOutput: self.printDebug(conn, id, 'QueryIns', 'result') --- 815,819 ---- c.execute(q) if id is None: ! id = self.insert_id(conn) if self.debugOutput: self.printDebug(conn, id, 'QueryIns', 'result') *************** *** 818,826 **** def _queryAddLimitOffset(self, query, start, end): ! if not start: ! return "%s LIMIT %i" % (query, end) ! if not end: ! return "%s LIMIT %i, -1" % (query, start) ! return "%s LIMIT %i, %i" % (query, start, end-start) def createColumn(self, soClass, col): --- 821,826 ---- def _queryAddLimitOffset(self, query, start, end): ! # XXX Sybase doesn't support LIMIT ! return query def createColumn(self, soClass, col): *************** *** 828,836 **** def createIDColumn(self, soClass): - #return '%s INT PRIMARY KEY AUTO_INCREMENT' % soClass._idName return '%s NUMERIC(18,0) IDENTITY' % soClass._idName def joinSQLType(self, join): ! return 'NUMERIC(18,0) NOT NULL' #INT NOT NULL' SHOW_TABLES="SELECT name FROM sysobjects WHERE type='U'" --- 828,835 ---- def createIDColumn(self, soClass): return '%s NUMERIC(18,0) IDENTITY' % soClass._idName def joinSQLType(self, join): ! return 'NUMERIC(18,0) NOT NULL' SHOW_TABLES="SELECT name FROM sysobjects WHERE type='U'" Index: SQLBuilder.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/SQLBuilder.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** SQLBuilder.py 4 Dec 2003 16:46:31 -0000 1.15 --- SQLBuilder.py 14 Jan 2004 14:34:28 -0000 1.16 *************** *** 591,596 **** for expr in tests.split('\n'): if not expr.strip(): continue - print expr if expr.startswith('>>> '): expr = expr[4:] - print repr(eval(expr)) --- 591,594 ---- |
From: <dre...@us...> - 2004-01-13 15:38:01
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv3563 Modified Files: DBConnection.py Log Message: Remove leftover from debugging Index: DBConnection.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/DBConnection.py,v retrieving revision 1.60 retrieving revision 1.61 diff -C2 -d -r1.60 -r1.61 *** DBConnection.py 13 Jan 2004 15:34:37 -0000 1.60 --- DBConnection.py 13 Jan 2004 15:37:58 -0000 1.61 *************** *** 270,274 **** def createTable(self, soClass): - import pdb; pdb.set_trace() self.query('CREATE TABLE %s (\n%s\n)' % \ (soClass._table, self.createColumns(soClass))) --- 270,273 ---- |
From: <dre...@us...> - 2004-01-13 15:34:45
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv2613 Modified Files: Col.py Converters.py DBConnection.py Log Message: A few more improvements on sybase support Index: Col.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Col.py,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** Col.py 13 Jan 2004 15:24:45 -0000 1.36 --- Col.py 13 Jan 2004 15:34:37 -0000 1.37 *************** *** 429,433 **** def _sybaseType(self): ! return self._postgresType() class DateTimeCol(Col): --- 429,433 ---- def _sybaseType(self): ! return 'DATETIME' class DateTimeCol(Col): Index: Converters.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Converters.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** Converters.py 4 Dec 2003 16:46:31 -0000 1.9 --- Converters.py 13 Jan 2004 15:34:37 -0000 1.10 *************** *** 84,88 **** def StringLikeConverter(value, db): ! if db in ('mysql', 'postgres'): for orig, repl in sqlStringReplace: value = value.replace(orig, repl) --- 84,88 ---- def StringLikeConverter(value, db): ! if db in ('mysql', 'postgres', 'sybase'): for orig, repl in sqlStringReplace: value = value.replace(orig, repl) Index: DBConnection.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/DBConnection.py,v retrieving revision 1.59 retrieving revision 1.60 diff -C2 -d -r1.59 -r1.60 *** DBConnection.py 13 Jan 2004 15:24:45 -0000 1.59 --- DBConnection.py 13 Jan 2004 15:34:37 -0000 1.60 *************** *** 270,273 **** --- 270,274 ---- def createTable(self, soClass): + import pdb; pdb.set_trace() self.query('CREATE TABLE %s (\n%s\n)' % \ (soClass._table, self.createColumns(soClass))) *************** *** 768,771 **** --- 769,775 ---- class SybaseConnection(DBAPI): + supportTransactions = True + dbName = 'sybase' + def __init__(self, db, user, passwd='', host='localhost', autoCommit=0, **kw): |
From: <dre...@us...> - 2004-01-13 15:24:48
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv592 Modified Files: Col.py DBConnection.py Log Message: Fix BoolCol for Sybase and queryInsertID, which was lacking one parameter Index: Col.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Col.py,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** Col.py 4 Dec 2003 16:46:31 -0000 1.35 --- Col.py 13 Jan 2004 15:24:45 -0000 1.36 *************** *** 307,310 **** --- 307,313 ---- return "TINYINT" + def _sybaseType(self): + return "BIT" + class BoolCol(Col): baseClass = SOBoolCol Index: DBConnection.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/DBConnection.py,v retrieving revision 1.58 retrieving revision 1.59 diff -C2 -d -r1.58 -r1.59 *** DBConnection.py 16 Dec 2003 05:41:11 -0000 1.58 --- DBConnection.py 13 Jan 2004 15:24:45 -0000 1.59 *************** *** 799,809 **** database=self.db, auto_commit=self.autoCommit) ! def _queryInsertID(self, conn, table, idName, names, values): c = conn.cursor() q = self._insertSQL(table, names, values) if self.debug: print 'QueryIns: %s' % q c.execute(q) ! return self.insert_id(conn) def _queryAddLimitOffset(self, query, start, end): --- 799,816 ---- database=self.db, auto_commit=self.autoCommit) ! def _queryInsertID(self, conn, table, idName, id, names, values): c = conn.cursor() + if id is not None: + names = [idName] + names + values = [id] + values q = self._insertSQL(table, names, values) if self.debug: print 'QueryIns: %s' % q c.execute(q) ! if id is None: ! id = self.insert_id() ! if self.debugOutput: ! self.printDebug(conn, id, 'QueryIns', 'result') ! return id def _queryAddLimitOffset(self, query, start, end): |
From: <ian...@us...> - 2003-12-16 05:42:22
|
Update of /cvsroot/sqlobject/SQLObject/docs In directory sc8-pr-cvs1:/tmp/cvs-serv18487/docs Modified Files: News.txt Log Message: Added news Index: News.txt =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/docs/News.txt,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** News.txt 12 Nov 2003 17:08:29 -0000 1.12 --- News.txt 16 Dec 2003 05:42:19 -0000 1.13 *************** *** 8,11 **** --- 8,20 ---- .. _start: + SQLObject 0.5.2 + =============== + + Bugs + ---- + + * Fixed bug which did not release connections after database (query) + error. + SQLObject 0.5.1 =============== |
From: <ian...@us...> - 2003-12-16 05:41:15
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv18229/SQLObject Modified Files: DBConnection.py Log Message: Release connection after database error (patch from Ken Kinder <ke...@ke...>) Index: DBConnection.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/DBConnection.py,v retrieving revision 1.57 retrieving revision 1.58 diff -C2 -d -r1.57 -r1.58 *** DBConnection.py 4 Dec 2003 16:44:04 -0000 1.57 --- DBConnection.py 16 Dec 2003 05:41:11 -0000 1.58 *************** *** 71,76 **** def _runWithConnection(self, meth, *args): conn = self.getConnection() ! val = meth(conn, *args) ! self.releaseConnection(conn) return val --- 71,78 ---- def _runWithConnection(self, meth, *args): conn = self.getConnection() ! try: ! val = meth(conn, *args) ! finally: ! self.releaseConnection(conn) return val *************** *** 905,914 **** except kinterbasdb.ProgrammingError: pass - val = meth(conn, *args) try: ! conn.commit() ! except kinterbasdb.ProgrammingError: ! pass ! self.releaseConnection(conn) return val --- 907,918 ---- except kinterbasdb.ProgrammingError: pass try: ! val = meth(conn, *args) ! try: ! conn.commit() ! except kinterbasdb.ProgrammingError: ! pass ! finally: ! self.releaseConnection(conn) return val |
From: <dre...@us...> - 2003-12-04 16:46:34
|
Update of /cvsroot/sqlobject/SQLObject/examples In directory sc8-pr-cvs1:/tmp/cvs-serv17015/examples Modified Files: codebits.py config.py people.py personaddress.py setup.py simpleperson.py userrole.py Log Message: And while we are at it, run reindent.py Index: codebits.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/examples/codebits.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** codebits.py 30 Nov 2003 21:46:11 -0000 1.4 --- codebits.py 4 Dec 2003 16:46:31 -0000 1.5 *************** *** 122,126 **** firstName = StringCol() lastName = StringCol() ! def _get_employee(self): value = Employee.selectBy(person=self) --- 122,126 ---- firstName = StringCol() lastName = StringCol() ! def _get_employee(self): value = Employee.selectBy(person=self) *************** *** 194,198 **** city = StringCol() state = StringCol(length=2) ! latitude = FloatCol() longitude = FloatCol() --- 194,198 ---- city = StringCol() state = StringCol(length=2) ! latitude = FloatCol() longitude = FloatCol() *************** *** 201,205 **** SQLObject._init(self, id) self._coords = SOCoords(self) ! def _get_coords(self): return self._coords --- 201,205 ---- SQLObject._init(self, id) self._coords = SOCoords(self) ! def _get_coords(self): return self._coords *************** *** 256,258 **** print "Showing page %i of %i" % (start/size + 1, total/size + 1) ## end snippet - --- 256,257 ---- Index: config.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/examples/config.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** config.py 28 Jun 2003 22:17:36 -0000 1.1 --- config.py 4 Dec 2003 16:46:31 -0000 1.2 *************** *** 14,16 **** conn = DBMConnection('database/') conn = MySQLConnection(user='test', db='test') - --- 14,15 ---- Index: people.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/examples/people.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** people.py 14 Mar 2003 03:52:15 -0000 1.5 --- people.py 4 Dec 2003 16:46:31 -0000 1.6 *************** *** 37,41 **** notNull=1), StringCol('firstName', length=30, ! notNull=1), StringCol('middleInitial', length=1, default=None), StringCol('lastName', length=50, notNull=1)] --- 37,41 ---- notNull=1), StringCol('firstName', length=30, ! notNull=1), StringCol('middleInitial', length=1, default=None), StringCol('lastName', length=50, notNull=1)] *************** *** 52,56 **** f.close() return v ! def _set_image(self, value): # assume we get a string for the image --- 52,56 ---- f.close() return v ! def _set_image(self, value): # assume we get a string for the image *************** *** 58,62 **** f.write(value) f.close() ! def _del_image(self, value): # I usually wouldn't include a method like this, but for --- 58,62 ---- f.write(value) f.close() ! def _del_image(self, value): # I usually wouldn't include a method like this, but for Index: personaddress.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/examples/personaddress.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** personaddress.py 28 Jun 2003 22:17:36 -0000 1.1 --- personaddress.py 4 Dec 2003 16:46:31 -0000 1.2 *************** *** 22,26 **** zip = StringCol(length=9) person = ForeignKey('Person') ! ## end snippet def reset(): --- 22,26 ---- zip = StringCol(length=9) person = ForeignKey('Person') ! ## end snippet def reset(): *************** *** 29,33 **** Address.dropTable(ifExists=True) Address.createTable() ! reset() --- 29,33 ---- Address.dropTable(ifExists=True) Address.createTable() ! reset() Index: setup.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/examples/setup.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** setup.py 28 Jun 2003 22:17:36 -0000 1.1 --- setup.py 4 Dec 2003 16:46:31 -0000 1.2 *************** *** 17,20 **** value.dropTable(ifExists=True) value.createTable() - - --- 17,18 ---- Index: simpleperson.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/examples/simpleperson.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** simpleperson.py 28 Jun 2003 22:17:36 -0000 1.1 --- simpleperson.py 4 Dec 2003 16:46:31 -0000 1.2 *************** *** 38,42 **** Person.dropTable(ifExists=True) Person.createTable() ! ## Get rid of any tables we have left over... --- 38,42 ---- Person.dropTable(ifExists=True) Person.createTable() ! ## Get rid of any tables we have left over... *************** *** 95,99 **** #-- Again, no database access, since we're just grabbing the same #-- instance we already had. ! print p2 #>> <Person 1 firstName='John' middleInitial='Q' lastName='Doe'> print p is p2 --- 95,99 ---- #-- Again, no database access, since we're just grabbing the same #-- instance we already had. ! print p2 #>> <Person 1 firstName='John' middleInitial='Q' lastName='Doe'> print p is p2 Index: userrole.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/examples/userrole.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** userrole.py 28 Jun 2003 22:17:36 -0000 1.1 --- userrole.py 4 Dec 2003 16:46:31 -0000 1.2 *************** *** 31,35 **** # Role.dropTable(ifExists=True) # Role.createTable() ! setup.reset() --- 31,35 ---- # Role.dropTable(ifExists=True) # Role.createTable() ! setup.reset() |
From: <dre...@us...> - 2003-12-04 16:46:34
|
Update of /cvsroot/sqlobject/SQLObject/tests In directory sc8-pr-cvs1:/tmp/cvs-serv17015/tests Modified Files: SQLObjectTest.py test.py Log Message: And while we are at it, run reindent.py Index: SQLObjectTest.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/tests/SQLObjectTest.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** SQLObjectTest.py 4 Dec 2003 16:44:05 -0000 1.20 --- SQLObjectTest.py 4 Dec 2003 16:46:31 -0000 1.21 *************** *** 159,161 **** __all__ = ['SQLObjectTest', 'setDatabaseType', 'connection', 'supportedDatabases'] - --- 159,160 ---- Index: test.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/tests/test.py,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** test.py 4 Dec 2003 16:44:05 -0000 1.36 --- test.py 4 Dec 2003 16:46:31 -0000 1.37 *************** *** 582,586 **** age INT DEFAULT 0, created VARCHAT(40) NOT NULL, ! happy char(1) DEFAULT 'Y' NOT NULL ) """ --- 582,586 ---- age INT DEFAULT 0, created VARCHAT(40) NOT NULL, ! happy char(1) DEFAULT 'Y' NOT NULL ) """ *************** *** 1008,1010 **** coverage.stop() coverModules() - --- 1008,1009 ---- |
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv17015/SQLObject Modified Files: Cache.py Col.py Constraints.py Converters.py Join.py SQLBuilder.py SQLObject.py Style.py Log Message: And while we are at it, run reindent.py Index: Cache.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Cache.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** Cache.py 26 Sep 2003 20:05:14 -0000 1.10 --- Cache.py 4 Dec 2003 16:46:31 -0000 1.11 *************** *** 10,14 **** CacheFactory caches object creation. Each object should be referenced by a single hashable ID (note tuples of hashable ! values are also hashable). """ --- 10,14 ---- CacheFactory caches object creation. Each object should be referenced by a single hashable ID (note tuples of hashable ! values are also hashable). """ *************** *** 34,38 **** it will be returned. """ ! self.cullFrequency = cullFrequency self.cullCount = cullFrequency --- 34,38 ---- it will be returned. """ ! self.cullFrequency = cullFrequency self.cullCount = cullFrequency Index: Col.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Col.py,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** Col.py 4 Dec 2003 16:44:04 -0000 1.34 --- Col.py 4 Dec 2003 16:46:31 -0000 1.35 *************** *** 90,94 **** # if they don't give us a specific database name for # the column, we separate the mixedCase into mixed_case ! # and assume that. if dbName is None: self.dbName = soClass._style.pythonAttrToDBColumn(self.name) --- 90,94 ---- # if they don't give us a specific database name for # the column, we separate the mixedCase into mixed_case ! # and assume that. if dbName is None: self.dbName = soClass._style.pythonAttrToDBColumn(self.name) *************** *** 210,214 **** # Ian Sparks pointed out that fb is picky about the order # of the NOT NULL clause in a create statement. So, we handle ! # them differently for Enum columns. if not isinstance(self, SOEnumCol): return ' '.join([self.dbName, self._firebirdType()] + self._extraSQL()) --- 210,214 ---- # Ian Sparks pointed out that fb is picky about the order # of the NOT NULL clause in a create statement. So, we handle ! # them differently for Enum columns. if not isinstance(self, SOEnumCol): return ' '.join([self.dbName, self._firebirdType()] + self._extraSQL()) *************** *** 491,493 **** all.append(key) __all__ = all - --- 491,492 ---- Index: Constraints.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Constraints.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Constraints.py 25 Sep 2003 20:40:25 -0000 1.3 --- Constraints.py 4 Dec 2003 16:46:31 -0000 1.4 *************** *** 59,62 **** % self.length, obj, col, value) - - --- 59,60 ---- Index: Converters.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Converters.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** Converters.py 22 Oct 2003 18:11:56 -0000 1.8 --- Converters.py 4 Dec 2003 16:46:31 -0000 1.9 *************** *** 171,173 **** else: return reprFunc(db) - --- 171,172 ---- Index: Join.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Join.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** Join.py 4 Nov 2003 02:28:53 -0000 1.6 --- Join.py 4 Dec 2003 16:46:31 -0000 1.7 *************** *** 132,136 **** if not self.otherColumn: self.otherColumn = self.soClass._style.tableReference(otherClass._table) ! def hasIntermediateTable(self): --- 132,136 ---- if not self.otherColumn: self.otherColumn = self.soClass._style.tableReference(otherClass._table) ! def hasIntermediateTable(self): *************** *** 170,172 **** def capitalize(name): return name[0].capitalize() + name[1:] - --- 170,171 ---- Index: SQLBuilder.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/SQLBuilder.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** SQLBuilder.py 4 Nov 2003 02:25:33 -0000 1.14 --- SQLBuilder.py 4 Dec 2003 16:46:31 -0000 1.15 *************** *** 484,488 **** registerConverter(Update, SQLExprConverter) ! class Delete(SQLExpression): """To be safe, this will signal an error if there is no where clause, --- 484,488 ---- registerConverter(Update, SQLExprConverter) ! class Delete(SQLExpression): """To be safe, this will signal an error if there is no where clause, *************** *** 595,597 **** expr = expr[4:] print repr(eval(expr)) - --- 595,596 ---- Index: SQLObject.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/SQLObject.py,v retrieving revision 1.65 retrieving revision 1.66 diff -C2 -d -r1.65 -r1.66 *** SQLObject.py 4 Dec 2003 16:44:04 -0000 1.65 --- SQLObject.py 4 Dec 2003 16:46:31 -0000 1.66 *************** *** 1182,1186 **** return list(self)[:value.stop] ! if value.start: assert value.start >= 0 --- 1182,1186 ---- return list(self)[:value.stop] ! if value.start: assert value.start >= 0 Index: Style.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Style.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** Style.py 15 Jul 2003 02:16:07 -0000 1.5 --- Style.py 4 Dec 2003 16:46:31 -0000 1.6 *************** *** 151,153 **** return _underToMixedRE.sub(lambda m: m.group(0)[1].upper(), name) - --- 151,152 ---- |
From: <dre...@us...> - 2003-12-04 16:46:34
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject/include In directory sc8-pr-cvs1:/tmp/cvs-serv17015/SQLObject/include Modified Files: Validator.py Log Message: And while we are at it, run reindent.py Index: Validator.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/include/Validator.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Validator.py 26 Sep 2003 07:12:59 -0000 1.3 --- Validator.py 4 Dec 2003 16:46:31 -0000 1.4 *************** *** 1044,1046 **** ('1800', 15)], } - --- 1044,1045 ---- |
From: <dre...@us...> - 2003-12-04 16:44:08
|
Update of /cvsroot/sqlobject/SQLObject/tests In directory sc8-pr-cvs1:/tmp/cvs-serv16262/tests Modified Files: SQLObjectTest.py test.py Log Message: Merge cascadegeddon-branch. This implements foreign key constraints (postgresql-only) and 'DELETE CASCADE'/'DELETE RESTRICT' (should work on all db's as it's done manually). We don't support 'UPDATE CASCADE'/'UPDATE RESTRICT' yet. To get it working, just pass the 'cascade' keyword argument to ForeignKey. True=CASCADE, False=RESTRICT, None(default)=The old behavior. Index: SQLObjectTest.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/tests/SQLObjectTest.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** SQLObjectTest.py 4 Dec 2003 16:36:17 -0000 1.19 --- SQLObjectTest.py 4 Dec 2003 16:44:05 -0000 1.20 *************** *** 118,122 **** __connection__.query(c.drop) elif hasattr(c, 'dropTable'): ! c.dropTable(ifExists=True) if hasattr(c, '%sCreate' % self.databaseName): --- 118,122 ---- __connection__.query(c.drop) elif hasattr(c, 'dropTable'): ! c.dropTable(ifExists=True, cascade=True) if hasattr(c, '%sCreate' % self.databaseName): Index: test.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/tests/test.py,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** test.py 4 Dec 2003 16:36:17 -0000 1.35 --- test.py 4 Dec 2003 16:44:05 -0000 1.36 *************** *** 120,123 **** --- 120,241 ---- self.assertEqual(tcc2.other, tc4a) + class TestSO5(SQLObject): + name = StringCol(length=10, dbName='name_col') + other = ForeignKey('TestSO6', default=None, cascade=True) + another = ForeignKey('TestSO7', default=None, cascade=True) + + class TestSO6(SQLObject): + name = StringCol(length=10, dbName='name_col') + other = ForeignKey('TestSO7', default=None, cascade=True) + + class TestSO7(SQLObject): + name = StringCol(length=10, dbName='name_col') + + class TestCase567(SQLObjectTest): + + classes = [TestSO7, TestSO6, TestSO5] + + def testForeignKeyDestroySelfCascade(self): + tc5 = TestSO5.new(name='a') + tc6a = TestSO6.new(name='1') + tc5.other = tc6a + tc7a = TestSO7.new(name='2') + tc6a.other = tc7a + tc5.another = tc7a + self.assertEqual(tc5.other, tc6a) + self.assertEqual(tc5.otherID, tc6a.id) + self.assertEqual(tc6a.other, tc7a) + self.assertEqual(tc6a.otherID, tc7a.id) + self.assertEqual(tc5.other.other, tc7a) + self.assertEqual(tc5.other.otherID, tc7a.id) + self.assertEqual(tc5.another, tc7a) + self.assertEqual(tc5.anotherID, tc7a.id) + self.assertEqual(tc5.other.other, tc5.another) + self.assertEqual(TestSO5.select().count(), 1) + self.assertEqual(TestSO6.select().count(), 1) + self.assertEqual(TestSO7.select().count(), 1) + tc6b = TestSO6.new(name='3') + tc6c = TestSO6.new(name='4') + tc7b = TestSO7.new(name='5') + tc6b.other = tc7b + tc6c.other = tc7b + self.assertEqual(TestSO5.select().count(), 1) + self.assertEqual(TestSO6.select().count(), 3) + self.assertEqual(TestSO7.select().count(), 2) + tc6b.destroySelf() + self.assertEqual(TestSO5.select().count(), 1) + self.assertEqual(TestSO6.select().count(), 2) + self.assertEqual(TestSO7.select().count(), 2) + tc7b.destroySelf() + self.assertEqual(TestSO5.select().count(), 1) + self.assertEqual(TestSO6.select().count(), 1) + self.assertEqual(TestSO7.select().count(), 1) + tc7a.destroySelf() + self.assertEqual(TestSO5.select().count(), 0) + self.assertEqual(TestSO6.select().count(), 0) + self.assertEqual(TestSO7.select().count(), 0) + + def testForeignKeyDropTableCascade(self): + tc5a = TestSO5.new(name='a') + tc6a = TestSO6.new(name='1') + tc5a.other = tc6a + tc7a = TestSO7.new(name='2') + tc6a.other = tc7a + tc5a.another = tc7a + tc5b = TestSO5.new(name='b') + tc5c = TestSO5.new(name='c') + tc6b = TestSO6.new(name='3') + tc5c.other = tc6b + self.assertEqual(TestSO5.select().count(), 3) + self.assertEqual(TestSO6.select().count(), 2) + self.assertEqual(TestSO7.select().count(), 1) + TestSO7.dropTable(cascade=True) + self.assertEqual(TestSO5.select().count(), 3) + self.assertEqual(TestSO6.select().count(), 2) + tc6a.destroySelf() + self.assertEqual(TestSO5.select().count(), 2) + self.assertEqual(TestSO6.select().count(), 1) + tc6b.destroySelf() + self.assertEqual(TestSO5.select().count(), 1) + self.assertEqual(TestSO6.select().count(), 0) + self.assertEqual(iter(TestSO5.select()).next(), tc5b) + tc6c = TestSO6.new(name='3') + tc5b.other = tc6c + self.assertEqual(TestSO5.select().count(), 1) + self.assertEqual(TestSO6.select().count(), 1) + tc6c.destroySelf() + self.assertEqual(TestSO5.select().count(), 0) + self.assertEqual(TestSO6.select().count(), 0) + + class TestSO8(SQLObject): + name = StringCol(length=10, dbName='name_col') + other = ForeignKey('TestSO9', default=None, cascade=False) + + class TestSO9(SQLObject): + name = StringCol(length=10, dbName='name_col') + + class TestCase89(SQLObjectTest): + + classes = [TestSO9, TestSO8] + + def testForeignKeyDestroySelfRestrict(self): + tc8a = TestSO8.new(name='a') + tc9a = TestSO9.new(name='1') + tc8a.other = tc9a + tc8b = TestSO8.new(name='b') + tc9b = TestSO9.new(name='2') + self.assertEqual(tc8a.other, tc9a) + self.assertEqual(tc8a.otherID, tc9a.id) + self.assertEqual(TestSO8.select().count(), 2) + self.assertEqual(TestSO9.select().count(), 2) + self.assertRaises(Exception, tc9a.destroySelf) + tc9b.destroySelf() + self.assertEqual(TestSO8.select().count(), 2) + self.assertEqual(TestSO9.select().count(), 1) + tc8a.destroySelf() + tc8b.destroySelf() + tc9a.destroySelf() + self.assertEqual(TestSO8.select().count(), 0) + self.assertEqual(TestSO9.select().count(), 0) ######################################## |
From: <dre...@us...> - 2003-12-04 16:44:08
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv16262/SQLObject Modified Files: Col.py DBConnection.py SQLObject.py Log Message: Merge cascadegeddon-branch. This implements foreign key constraints (postgresql-only) and 'DELETE CASCADE'/'DELETE RESTRICT' (should work on all db's as it's done manually). We don't support 'UPDATE CASCADE'/'UPDATE RESTRICT' yet. To get it working, just pass the 'cascade' keyword argument to ForeignKey. True=CASCADE, False=RESTRICT, None(default)=The old behavior. Index: Col.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Col.py,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -d -r1.33 -r1.34 *** Col.py 4 Dec 2003 16:36:16 -0000 1.33 --- Col.py 4 Dec 2003 16:44:04 -0000 1.34 *************** *** 34,38 **** columnDef=None, validator=None, ! immutable=False): # This isn't strictly true, since we *could* use backquotes or --- 34,39 ---- columnDef=None, validator=None, ! immutable=False, ! cascade=None): # This isn't strictly true, since we *could* use backquotes or *************** *** 50,53 **** --- 51,60 ---- self.immutable = immutable + # cascade can be one of: + # None: no constraint is generated + # True: a CASCADE constraint is generated + # False: a RESTRICT constraint is generated + self.cascade = cascade + if type(constraints) not in (type([]), type(())): constraints = [constraints] *************** *** 348,351 **** --- 355,377 ---- kw['name'] = style.instanceAttrToIDAttr(kw['name']) SOKeyCol.__init__(self, **kw) + + def postgresCreateSQL(self): + from SQLObject import findClass + sql = SOKeyCol.postgresCreateSQL(self) + if self.cascade is not None: + other = findClass(self.foreignKey) + tName = other._table + idName = other._idName + action = self.cascade and 'CASCADE' or 'RESTRICT' + constraint = ('CONSTRAINT %(tName)s_exists ' + 'FOREIGN KEY(%(colName)s) ' + 'REFERENCES %(tName)s(%(idName)s) ' + 'ON DELETE %(action)s' % + {'tName':tName, + 'colName':self.dbName, + 'idName':idName, + 'action':action}) + sql = ', '.join([sql, constraint]) + return sql class ForeignKey(KeyCol): Index: DBConnection.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/DBConnection.py,v retrieving revision 1.56 retrieving revision 1.57 diff -C2 -d -r1.56 -r1.57 *** DBConnection.py 4 Dec 2003 16:36:16 -0000 1.56 --- DBConnection.py 4 Dec 2003 16:44:04 -0000 1.57 *************** *** 280,284 **** assert 0, "Implement in subclasses" ! def dropTable(self, tableName): self.query("DROP TABLE %s" % tableName) --- 280,284 ---- assert 0, "Implement in subclasses" ! def dropTable(self, tableName, cascade=False): self.query("DROP TABLE %s" % tableName) *************** *** 614,617 **** --- 614,621 ---- return '%s SERIAL PRIMARY KEY' % soClass._idName + def dropTable(self, tableName, cascade=False): + self.query("DROP TABLE %s %s" % (tableName, + cascade and 'CASCADE' or '')) + def joinSQLType(self, join): return 'INT NOT NULL' *************** *** 982,986 **** column.firebirdCreateSQL())) ! def dropTable(self, tableName): self.query("DROP TABLE %s" % tableName) self.query("DROP GENERATOR GEN_%s" % tableName) --- 986,990 ---- column.firebirdCreateSQL())) ! def dropTable(self, tableName, cascade=False): self.query("DROP TABLE %s" % tableName) self.query("DROP GENERATOR GEN_%s" % tableName) *************** *** 1218,1222 **** self._meta["%s.id" % soClass._table] = "1" ! def dropTable(self, tableName): try: del self._meta["%s.id" % tableName] --- 1222,1226 ---- self._meta["%s.id" % soClass._table] = "1" ! def dropTable(self, tableName, cascade=False): try: del self._meta["%s.id" % tableName] Index: SQLObject.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/SQLObject.py,v retrieving revision 1.64 retrieving revision 1.65 diff -C2 -d -r1.64 -r1.65 *** SQLObject.py 12 Nov 2003 17:06:00 -0000 1.64 --- SQLObject.py 4 Dec 2003 16:44:04 -0000 1.65 *************** *** 37,40 **** --- 37,41 ---- class SQLObjectNotFound(LookupError): pass + class SQLObjectIntegrityError(Exception): pass True, False = 1==1, 0==1 *************** *** 312,315 **** --- 313,329 ---- return classRegistry[registry][name] + def findDependencies(name, registry=None): + depends = [] + for n, klass in classRegistry[registry].items(): + if findDependantColumns(name, klass): + depends.append(klass) + return depends + + def findDependantColumns(name, klass): + depends = [] + for col in klass._SO_columns: + if col.foreignKey == name and col.cascade is not None: + depends.append(col) + return depends class CreateNewSQLObject: *************** *** 933,936 **** --- 947,954 ---- _SO_fetchAlternateID = classmethod(_SO_fetchAlternateID) + def _SO_depends(cls): + return findDependencies(cls.__name__, cls._registry) + _SO_depends = classmethod(_SO_depends) + def select(cls, clause=None, clauseTables=None, orderBy=NoDefault, limit=None, *************** *** 952,959 **** # 3-03 @@: Should these have a connection argument? ! def dropTable(cls, ifExists=False, dropJoinTables=True): if ifExists and not cls._connection.tableExists(cls._table): return ! cls._connection.dropTable(cls._table) if dropJoinTables: cls.dropJoinTables(ifExists=ifExists) --- 970,977 ---- # 3-03 @@: Should these have a connection argument? ! def dropTable(cls, ifExists=False, dropJoinTables=True, cascade=False): if ifExists and not cls._connection.tableExists(cls._table): return ! cls._connection.dropTable(cls._table, cascade) if dropJoinTables: cls.dropJoinTables(ifExists=ifExists) *************** *** 1010,1013 **** --- 1028,1054 ---- def destroySelf(self): # Kills this object. Kills it dead! + depends = [] + klass = self.__class__ + depends = self._SO_depends() + for k in depends: + cols = findDependantColumns(klass.__name__, k) + query = [] + restrict = False + for col in cols: + if col.cascade == False: + # Found a restriction + restrict = True + query.append("%s = %s" % (col.dbName, self.id)) + query = ' OR '.join(query) + results = k.select(query) + 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() self._SO_obsolete = True self._connection._SO_delete(self) |
From: <dre...@us...> - 2003-12-04 16:36:21
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv14756/SQLObject Modified Files: Col.py DBConnection.py Log Message: Basic Sybase Support, was living in a branch for some long time. Should pass most, but not all tests Index: Col.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Col.py,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** Col.py 12 Nov 2003 17:04:55 -0000 1.32 --- Col.py 4 Dec 2003 16:36:16 -0000 1.33 *************** *** 182,188 **** return '' ! def _firebirdType(self): return self._sqlType() def mysqlCreateSQL(self): --- 182,190 ---- return '' ! def _sybaseType(self): return self._sqlType() + def _firebirdType(self): + return self._sqlType() def mysqlCreateSQL(self): *************** *** 195,198 **** --- 197,203 ---- return ' '.join([self.dbName, self._sqliteType()] + self._extraSQL()) + def sybaseCreateSQL(self): + return ' '.join([self.dbName, self._sybaseType()] + self._extraSQL()) + def firebirdCreateSQL(self): # Ian Sparks pointed out that fb is picky about the order *************** *** 374,377 **** --- 379,385 ---- return self._postgresType() + def _sybaseType(self): + return self._postgresType() + def _firebirdType(self): return self._postgresType() *************** *** 391,396 **** --- 399,424 ---- return 'TIMESTAMP' + def _sybaseType(self): + return self._postgresType() + class DateTimeCol(Col): baseClass = SODateTimeCol + + class SODateCol(SOCol): + + # 3-03 @@: provide constraints; right now we let the database + # do any parsing and checking. And DATE and TIME? + + def _mysqlType(self): + return 'DATE' + + def _postgresType(self): + return 'DATE' + + def _sybaseType(self): + return self._postgresType() + + class DateCol(Col): + baseClass = SODateCol class SODecimalCol(SOCol): Index: DBConnection.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/DBConnection.py,v retrieving revision 1.55 retrieving revision 1.56 diff -C2 -d -r1.55 -r1.56 *** DBConnection.py 12 Nov 2003 17:06:34 -0000 1.55 --- DBConnection.py 4 Dec 2003 16:36:16 -0000 1.56 *************** *** 24,32 **** sqlite = None kinterbasdb = None warnings.filterwarnings("ignore", "DB-API extension cursor.lastrowid used") __all__ = ['MySQLConnection', 'PostgresConnection', 'SQLiteConnection', ! 'DBMConnection', 'FirebirdConnection'] _connections = {} --- 24,33 ---- sqlite = None kinterbasdb = None + Sybase = None warnings.filterwarnings("ignore", "DB-API extension cursor.lastrowid used") __all__ = ['MySQLConnection', 'PostgresConnection', 'SQLiteConnection', ! 'DBMConnection', 'FirebirdConnection', 'SybaseConnection'] _connections = {} *************** *** 431,434 **** --- 432,439 ---- self._dbConnection.releaseConnection(self._connection) + ######################################## + ## MySQL connection + ######################################## + class MySQLConnection(DBAPI): *************** *** 528,531 **** --- 533,539 ---- return Col.Col, {} + ######################################## + ## Postgres connection + ######################################## class PostgresConnection(DBAPI): *************** *** 683,686 **** --- 691,698 ---- + ######################################## + ## SQLite connection + ######################################## + class SQLiteConnection(DBAPI): *************** *** 745,748 **** --- 757,870 ---- ######################################## + ## Sybase connection + ######################################## + + class SybaseConnection(DBAPI): + + def __init__(self, db, user, passwd='', host='localhost', + autoCommit=0, **kw): + global Sybase + if Sybase is None: + import Sybase + from Sybase import NumericType + from Converters import registerConverter, IntConverter + registerConverter(NumericType, IntConverter) + if not autoCommit and not kw.has_key('pool'): + # Pooling doesn't work with transactions... + kw['pool'] = 0 + self.autoCommit=autoCommit + self.host = host + self.db = db + self.user = user + self.passwd = passwd + DBAPI.__init__(self, **kw) + + def insert_id(self, conn): + """ + Sybase adapter/cursor does not support the + insert_id method. + """ + c = conn.cursor() + c.execute('SELECT @@IDENTITY') + return c.fetchone()[0] + + def makeConnection(self): + return Sybase.connect(self.host, self.user, self.passwd, + database=self.db, auto_commit=self.autoCommit) + + def _queryInsertID(self, conn, table, idName, names, values): + c = conn.cursor() + q = self._insertSQL(table, names, values) + if self.debug: + print 'QueryIns: %s' % q + c.execute(q) + return self.insert_id(conn) + + def _queryAddLimitOffset(self, query, start, end): + if not start: + return "%s LIMIT %i" % (query, end) + if not end: + return "%s LIMIT %i, -1" % (query, start) + return "%s LIMIT %i, %i" % (query, start, end-start) + + def createColumn(self, soClass, col): + return col.sybaseCreateSQL() + + def createIDColumn(self, soClass): + #return '%s INT PRIMARY KEY AUTO_INCREMENT' % soClass._idName + return '%s NUMERIC(18,0) IDENTITY' % soClass._idName + + def joinSQLType(self, join): + return 'NUMERIC(18,0) NOT NULL' #INT NOT NULL' + + SHOW_TABLES="SELECT name FROM sysobjects WHERE type='U'" + def tableExists(self, tableName): + for (table,) in self.queryAll(self.SHOW_TABLES): + if table.lower() == tableName.lower(): + return True + return False + + def addColumn(self, tableName, column): + self.query('ALTER TABLE %s ADD COLUMN %s' % + (tableName, + column.sybaseCreateSQL())) + + def delColumn(self, tableName, column): + self.query('ALTER TABLE %s DROP COLUMN %s' % + (tableName, + column.dbName)) + + SHOW_COLUMNS=("select 'column' = COL_NAME(id, colid) " + "from syscolumns where id = OBJECT_ID(%s)") + def columnsFromSchema(self, tableName, soClass): + colData = self.queryAll(self.SHOW_COLUMNS + % tableName) + results = [] + for field, t, nullAllowed, key, default, extra in colData: + if field == 'id': + continue + colClass, kw = self.guessClass(t) + kw['name'] = soClass._style.dbColumnToPythonAttr(field) + kw['notNone'] = not nullAllowed + kw['default'] = default + # @@ skip key... + # @@ skip extra... + results.append(colClass(**kw)) + return results + + def guessClass(self, t): + if t.startswith('int'): + return Col.IntCol, {} + elif t.startswith('varchar'): + return Col.StringCol, {'length': int(t[8:-1])} + elif t.startswith('char'): + return Col.StringCol, {'length': int(t[5:-1]), + 'varchar': False} + elif t.startswith('datetime'): + return Col.DateTimeCol, {} + else: + return Col.Col, {} + + ######################################## ## Firebird connection ######################################## *************** *** 1019,1022 **** --- 1141,1148 ---- results.append((id,)) return results + + ######################################## + ## DBM connection + ######################################## class DBMConnection(FileConnection): |
From: <dre...@us...> - 2003-12-04 16:36:21
|
Update of /cvsroot/sqlobject/SQLObject/tests In directory sc8-pr-cvs1:/tmp/cvs-serv14756/tests Modified Files: SQLObjectTest.py test.py Log Message: Basic Sybase Support, was living in a branch for some long time. Should pass most, but not all tests Index: SQLObjectTest.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/tests/SQLObjectTest.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** SQLObjectTest.py 1 Oct 2003 01:53:48 -0000 1.18 --- SQLObjectTest.py 4 Dec 2003 16:36:17 -0000 1.19 *************** *** 46,49 **** --- 46,61 ---- return SQLiteConnection('data/sqlite.data') + + def sybaseConnection(): + SQLObjectTest.supportDynamic = False + SQLObjectTest.supportAuto = False + SQLObjectTest.supportRestrictedEnum = False + SQLObjectTest.supportTransactions = True + return SybaseConnection(host='localhost', + db='test', + user='sa', + passwd='sybasesa', + autoCommit=1) + def firebirdConnection(): SQLObjectTest.supportDynamic = True *************** *** 54,61 **** --- 66,75 ---- user='sysdba', passwd='masterkey') + _supportedDatabases = { 'mysql': 'MySQLdb', 'postgres': 'psycopg', 'sqlite': 'sqlite', + 'sybase': 'Sybase', 'firebird': 'kinterbasdb', } *************** *** 105,109 **** elif hasattr(c, 'dropTable'): c.dropTable(ifExists=True) ! if hasattr(c, '%sCreate' % self.databaseName): if not __connection__.tableExists(c._table): --- 119,123 ---- elif hasattr(c, 'dropTable'): c.dropTable(ifExists=True) ! if hasattr(c, '%sCreate' % self.databaseName): if not __connection__.tableExists(c._table): Index: test.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/tests/test.py,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** test.py 4 Nov 2003 02:28:35 -0000 1.34 --- test.py 4 Dec 2003 16:36:17 -0000 1.35 *************** *** 225,228 **** --- 225,229 ---- ######################################## + class DeleteSelectTest(TestCase1): *************** *** 235,238 **** --- 236,240 ---- self.assertEqual(list(TestSO1.select('all')), []) + ######################################## ## Transaction test *************** *** 455,458 **** --- 457,471 ---- """ + sybaseCreate = """ + CREATE TABLE auto_test ( + id integer, + first_name VARCHAR(100), + last_name VARCHAR(200) NOT NULL, + age INT DEFAULT 0, + created VARCHAT(40) NOT NULL, + happy char(1) DEFAULT 'Y' NOT NULL + ) + """ + mysqlDrop = """ DROP TABLE IF EXISTS auto_test *************** *** 460,463 **** --- 473,480 ---- postgresDrop = """ + DROP TABLE auto_test + """ + + sybaseDrop = """ DROP TABLE auto_test """ |
From: <dre...@us...> - 2003-12-03 21:58:10
|
Update of /cvsroot/sqlobject/SQLObject/tests In directory sc8-pr-cvs1:/tmp/cvs-serv3728/tests Modified Files: Tag: cascadegeddon-branch SQLObjectTest.py test.py Log Message: Implemented cascade deletes and restriction of deletes. For postgres, it does create a column restriction as well. XXX destroySelf always tries to do the manual delete, even though postgres will do the dirty job for us. Tested with Postgres and SQLLite, all tests pass Index: SQLObjectTest.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/tests/SQLObjectTest.py,v retrieving revision 1.18 retrieving revision 1.18.2.1 diff -C2 -d -r1.18 -r1.18.2.1 *** SQLObjectTest.py 1 Oct 2003 01:53:48 -0000 1.18 --- SQLObjectTest.py 3 Dec 2003 21:58:05 -0000 1.18.2.1 *************** *** 104,109 **** __connection__.query(c.drop) elif hasattr(c, 'dropTable'): ! c.dropTable(ifExists=True) ! if hasattr(c, '%sCreate' % self.databaseName): if not __connection__.tableExists(c._table): --- 104,109 ---- __connection__.query(c.drop) elif hasattr(c, 'dropTable'): ! c.dropTable(ifExists=True, cascade=True) ! if hasattr(c, '%sCreate' % self.databaseName): if not __connection__.tableExists(c._table): Index: test.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/tests/test.py,v retrieving revision 1.34 retrieving revision 1.34.2.1 diff -C2 -d -r1.34 -r1.34.2.1 *** test.py 4 Nov 2003 02:28:35 -0000 1.34 --- test.py 3 Dec 2003 21:58:05 -0000 1.34.2.1 *************** *** 120,123 **** --- 120,241 ---- self.assertEqual(tcc2.other, tc4a) + class TestSO5(SQLObject): + name = StringCol(length=10, dbName='name_col') + other = ForeignKey('TestSO6', default=None, cascade=True) + another = ForeignKey('TestSO7', default=None, cascade=True) + + class TestSO6(SQLObject): + name = StringCol(length=10, dbName='name_col') + other = ForeignKey('TestSO7', default=None, cascade=True) + + class TestSO7(SQLObject): + name = StringCol(length=10, dbName='name_col') + + class TestCase567(SQLObjectTest): + + classes = [TestSO7, TestSO6, TestSO5] + + def testForeignKeyDestroySelfCascade(self): + tc5 = TestSO5.new(name='a') + tc6a = TestSO6.new(name='1') + tc5.other = tc6a + tc7a = TestSO7.new(name='2') + tc6a.other = tc7a + tc5.another = tc7a + self.assertEqual(tc5.other, tc6a) + self.assertEqual(tc5.otherID, tc6a.id) + self.assertEqual(tc6a.other, tc7a) + self.assertEqual(tc6a.otherID, tc7a.id) + self.assertEqual(tc5.other.other, tc7a) + self.assertEqual(tc5.other.otherID, tc7a.id) + self.assertEqual(tc5.another, tc7a) + self.assertEqual(tc5.anotherID, tc7a.id) + self.assertEqual(tc5.other.other, tc5.another) + self.assertEqual(TestSO5.select().count(), 1) + self.assertEqual(TestSO6.select().count(), 1) + self.assertEqual(TestSO7.select().count(), 1) + tc6b = TestSO6.new(name='3') + tc6c = TestSO6.new(name='4') + tc7b = TestSO7.new(name='5') + tc6b.other = tc7b + tc6c.other = tc7b + self.assertEqual(TestSO5.select().count(), 1) + self.assertEqual(TestSO6.select().count(), 3) + self.assertEqual(TestSO7.select().count(), 2) + tc6b.destroySelf() + self.assertEqual(TestSO5.select().count(), 1) + self.assertEqual(TestSO6.select().count(), 2) + self.assertEqual(TestSO7.select().count(), 2) + tc7b.destroySelf() + self.assertEqual(TestSO5.select().count(), 1) + self.assertEqual(TestSO6.select().count(), 1) + self.assertEqual(TestSO7.select().count(), 1) + tc7a.destroySelf() + self.assertEqual(TestSO5.select().count(), 0) + self.assertEqual(TestSO6.select().count(), 0) + self.assertEqual(TestSO7.select().count(), 0) + + def testForeignKeyDropTableCascade(self): + tc5a = TestSO5.new(name='a') + tc6a = TestSO6.new(name='1') + tc5a.other = tc6a + tc7a = TestSO7.new(name='2') + tc6a.other = tc7a + tc5a.another = tc7a + tc5b = TestSO5.new(name='b') + tc5c = TestSO5.new(name='c') + tc6b = TestSO6.new(name='3') + tc5c.other = tc6b + self.assertEqual(TestSO5.select().count(), 3) + self.assertEqual(TestSO6.select().count(), 2) + self.assertEqual(TestSO7.select().count(), 1) + TestSO7.dropTable(cascade=True) + self.assertEqual(TestSO5.select().count(), 3) + self.assertEqual(TestSO6.select().count(), 2) + tc6a.destroySelf() + self.assertEqual(TestSO5.select().count(), 2) + self.assertEqual(TestSO6.select().count(), 1) + tc6b.destroySelf() + self.assertEqual(TestSO5.select().count(), 1) + self.assertEqual(TestSO6.select().count(), 0) + self.assertEqual(iter(TestSO5.select()).next(), tc5b) + tc6c = TestSO6.new(name='3') + tc5b.other = tc6c + self.assertEqual(TestSO5.select().count(), 1) + self.assertEqual(TestSO6.select().count(), 1) + tc6c.destroySelf() + self.assertEqual(TestSO5.select().count(), 0) + self.assertEqual(TestSO6.select().count(), 0) + + class TestSO8(SQLObject): + name = StringCol(length=10, dbName='name_col') + other = ForeignKey('TestSO9', default=None, cascade=False) + + class TestSO9(SQLObject): + name = StringCol(length=10, dbName='name_col') + + class TestCase89(SQLObjectTest): + + classes = [TestSO9, TestSO8] + + def testForeignKeyDestroySelfRestrict(self): + tc8a = TestSO8.new(name='a') + tc9a = TestSO9.new(name='1') + tc8a.other = tc9a + tc8b = TestSO8.new(name='b') + tc9b = TestSO9.new(name='2') + self.assertEqual(tc8a.other, tc9a) + self.assertEqual(tc8a.otherID, tc9a.id) + self.assertEqual(TestSO8.select().count(), 2) + self.assertEqual(TestSO9.select().count(), 2) + self.assertRaises(Exception, tc9a.destroySelf) + tc9b.destroySelf() + self.assertEqual(TestSO8.select().count(), 2) + self.assertEqual(TestSO9.select().count(), 1) + tc8a.destroySelf() + tc8b.destroySelf() + tc9a.destroySelf() + self.assertEqual(TestSO8.select().count(), 0) + self.assertEqual(TestSO9.select().count(), 0) ######################################## |
From: <dre...@us...> - 2003-12-03 21:58:10
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv3728/SQLObject Modified Files: Tag: cascadegeddon-branch Col.py DBConnection.py SQLObject.py Log Message: Implemented cascade deletes and restriction of deletes. For postgres, it does create a column restriction as well. XXX destroySelf always tries to do the manual delete, even though postgres will do the dirty job for us. Tested with Postgres and SQLLite, all tests pass Index: Col.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Col.py,v retrieving revision 1.32 retrieving revision 1.32.2.1 diff -C2 -d -r1.32 -r1.32.2.1 *** Col.py 12 Nov 2003 17:04:55 -0000 1.32 --- Col.py 3 Dec 2003 21:58:04 -0000 1.32.2.1 *************** *** 34,38 **** columnDef=None, validator=None, ! immutable=False): # This isn't strictly true, since we *could* use backquotes or --- 34,39 ---- columnDef=None, validator=None, ! immutable=False, ! cascade=None): # This isn't strictly true, since we *could* use backquotes or *************** *** 50,53 **** --- 51,60 ---- self.immutable = immutable + # cascade can be one of: + # None: no constraint is generated + # True: a CASCADE constraint is generated + # False: a RESTRICT constraint is generated + self.cascade = cascade + if type(constraints) not in (type([]), type(())): constraints = [constraints] *************** *** 343,346 **** --- 350,372 ---- kw['name'] = style.instanceAttrToIDAttr(kw['name']) SOKeyCol.__init__(self, **kw) + + def postgresCreateSQL(self): + from SQLObject import findClass + sql = SOKeyCol.postgresCreateSQL(self) + if self.cascade is not None: + other = findClass(self.foreignKey) + tName = other._table + idName = other._idName + action = self.cascade and 'CASCADE' or 'RESTRICT' + constraint = ('CONSTRAINT %(tName)s_exists ' + 'FOREIGN KEY(%(colName)s) ' + 'REFERENCES %(tName)s(%(idName)s) ' + 'ON DELETE %(action)s' % + {'tName':tName, + 'colName':self.dbName, + 'idName':idName, + 'action':action}) + sql = ', '.join([sql, constraint]) + return sql class ForeignKey(KeyCol): Index: DBConnection.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/DBConnection.py,v retrieving revision 1.55 retrieving revision 1.55.2.1 diff -C2 -d -r1.55 -r1.55.2.1 *** DBConnection.py 12 Nov 2003 17:06:34 -0000 1.55 --- DBConnection.py 3 Dec 2003 21:58:05 -0000 1.55.2.1 *************** *** 279,283 **** assert 0, "Implement in subclasses" ! def dropTable(self, tableName): self.query("DROP TABLE %s" % tableName) --- 279,283 ---- assert 0, "Implement in subclasses" ! def dropTable(self, tableName, cascade=False): self.query("DROP TABLE %s" % tableName) *************** *** 606,609 **** --- 606,613 ---- return '%s SERIAL PRIMARY KEY' % soClass._idName + def dropTable(self, tableName, cascade=False): + self.query("DROP TABLE %s %s" % (tableName, + cascade and 'CASCADE' or '')) + def joinSQLType(self, join): return 'INT NOT NULL' *************** *** 860,864 **** column.firebirdCreateSQL())) ! def dropTable(self, tableName): self.query("DROP TABLE %s" % tableName) self.query("DROP GENERATOR GEN_%s" % tableName) --- 864,868 ---- column.firebirdCreateSQL())) ! def dropTable(self, tableName, cascade=False): self.query("DROP TABLE %s" % tableName) self.query("DROP GENERATOR GEN_%s" % tableName) *************** *** 1092,1096 **** self._meta["%s.id" % soClass._table] = "1" ! def dropTable(self, tableName): try: del self._meta["%s.id" % tableName] --- 1096,1100 ---- self._meta["%s.id" % soClass._table] = "1" ! def dropTable(self, tableName, cascade=False): try: del self._meta["%s.id" % tableName] Index: SQLObject.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/SQLObject.py,v retrieving revision 1.64 retrieving revision 1.64.2.1 diff -C2 -d -r1.64 -r1.64.2.1 *** SQLObject.py 12 Nov 2003 17:06:00 -0000 1.64 --- SQLObject.py 3 Dec 2003 21:58:05 -0000 1.64.2.1 *************** *** 37,40 **** --- 37,41 ---- class SQLObjectNotFound(LookupError): pass + class SQLObjectIntegrityError(Exception): pass True, False = 1==1, 0==1 *************** *** 312,315 **** --- 313,329 ---- return classRegistry[registry][name] + def findDependencies(name, registry=None): + depends = [] + for n, klass in classRegistry[registry].items(): + if findDependantColumns(name, klass): + depends.append(klass) + return depends + + def findDependantColumns(name, klass): + depends = [] + for col in klass._SO_columns: + if col.foreignKey == name and col.cascade is not None: + depends.append(col) + return depends class CreateNewSQLObject: *************** *** 933,936 **** --- 947,954 ---- _SO_fetchAlternateID = classmethod(_SO_fetchAlternateID) + def _SO_depends(cls): + return findDependencies(cls.__name__, cls._registry) + _SO_depends = classmethod(_SO_depends) + def select(cls, clause=None, clauseTables=None, orderBy=NoDefault, limit=None, *************** *** 952,959 **** # 3-03 @@: Should these have a connection argument? ! def dropTable(cls, ifExists=False, dropJoinTables=True): if ifExists and not cls._connection.tableExists(cls._table): return ! cls._connection.dropTable(cls._table) if dropJoinTables: cls.dropJoinTables(ifExists=ifExists) --- 970,977 ---- # 3-03 @@: Should these have a connection argument? ! def dropTable(cls, ifExists=False, dropJoinTables=True, cascade=False): if ifExists and not cls._connection.tableExists(cls._table): return ! cls._connection.dropTable(cls._table, cascade) if dropJoinTables: cls.dropJoinTables(ifExists=ifExists) *************** *** 1010,1013 **** --- 1028,1054 ---- def destroySelf(self): # Kills this object. Kills it dead! + depends = [] + klass = self.__class__ + depends = self._SO_depends() + for k in depends: + cols = findDependantColumns(klass.__name__, k) + query = [] + restrict = False + for col in cols: + if col.cascade == False: + # Found a restriction + restrict = True + query.append("%s = %s" % (col.dbName, self.id)) + query = ' OR '.join(query) + results = k.select(query) + 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() self._SO_obsolete = True self._connection._SO_delete(self) |
From: <ian...@us...> - 2003-11-30 21:46:14
|
Update of /cvsroot/sqlobject/SQLObject/examples In directory sc8-pr-cvs1:/tmp/cvs-serv7708/examples Modified Files: codebits.py Log Message: Added a little more documentation about count(), and an example Index: codebits.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/examples/codebits.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** codebits.py 7 Sep 2003 19:14:43 -0000 1.3 --- codebits.py 30 Nov 2003 21:46:11 -0000 1.4 *************** *** 247,248 **** --- 247,258 ---- return self._SO_get_data().decode('base64') ## end snippet + + ## Snippet "slicing-batch" + start = 20 + size = 10 + query = Table.select() + results = query[start:start+size] + total = query.count() + print "Showing page %i of %i" % (start/size + 1, total/size + 1) + ## end snippet + |
From: <ian...@us...> - 2003-11-30 21:46:14
|
Update of /cvsroot/sqlobject/SQLObject/docs In directory sc8-pr-cvs1:/tmp/cvs-serv7708/docs Modified Files: SQLObject.txt Log Message: Added a little more documentation about count(), and an example Index: SQLObject.txt =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/docs/SQLObject.txt,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** SQLObject.txt 12 Nov 2003 17:09:52 -0000 1.18 --- SQLObject.txt 30 Nov 2003 21:46:11 -0000 1.19 *************** *** 390,396 **** negative indexes. ! You can get the length of the result without fetching all the results. ! A ``COUNT(*)`` query is used. Together with slicing, this makes ! batched queries easy to write. For more information on the where clause in the queries, see the --- 390,401 ---- negative indexes. ! You can get the length of the result without fetching all the results ! by calling ``count`` on the result object, like ! ``MyClass.select().count()``. A ``COUNT(*)`` query is used -- the ! actual objects are not fetched from the database. Together with ! slicing, this makes batched queries easy to write: ! ! .. raw:: html ! :file: ../examples/snippets/slicing-batch.html For more information on the where clause in the queries, see the |
From: <ian...@us...> - 2003-11-30 21:45:47
|
Update of /cvsroot/sqlobject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv7651 Modified Files: README.txt Log Message: Updated version Index: README.txt =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/README.txt,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** README.txt 1 Jul 2003 00:13:04 -0000 1.4 --- README.txt 30 Nov 2003 21:45:44 -0000 1.5 *************** *** 1,5 **** ! ============= ! SQLObject 0.4 ! ============= :Author: Ian Bicking --- 1,5 ---- ! =============== ! SQLObject 0.5.1 ! =============== :Author: Ian Bicking *************** *** 13,17 **** It absolutely requires Python 2.2 or higher. It currently supports MySQL through the `MySQLdb` package, PostgreSQL through the ! `psycopg` package, SQLite, and a DBM-based backend. For more information please see the documentation in --- 13,17 ---- It absolutely requires Python 2.2 or higher. It currently supports MySQL through the `MySQLdb` package, PostgreSQL through the ! `psycopg` package, SQLite, Firebird, and a DBM-based backend. For more information please see the documentation in |