sqlobject-cvs Mailing List for SQLObject (Page 189)
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: <ian...@us...> - 2003-04-29 09:47:51
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv22936/SQLObject Modified Files: SQLObject.py Log Message: Changed _cacheValues default back to True Index: SQLObject.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/SQLObject.py,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** SQLObject.py 29 Apr 2003 08:15:11 -0000 1.29 --- SQLObject.py 29 Apr 2003 09:47:48 -0000 1.30 *************** *** 281,285 **** # values fetched from the database. We make sure # it's set (default 1). ! _cacheValues = False # The _defaultOrder is used by SelectResults --- 281,285 ---- # values fetched from the database. We make sure # it's set (default 1). ! _cacheValues = True # The _defaultOrder is used by SelectResults |
From: <ian...@us...> - 2003-04-29 09:37:11
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv14229/SQLObject Modified Files: Col.py Log Message: Made alternateID imply NOT NULL Index: Col.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Col.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** Col.py 29 Apr 2003 09:26:52 -0000 1.16 --- Col.py 29 Apr 2003 09:37:06 -0000 1.17 *************** *** 110,114 **** def _extraSQL(self): result = [] ! if self.notNull: result.append('NOT NULL') if self.unique or self.alternateID: --- 110,114 ---- def _extraSQL(self): result = [] ! if self.notNull or self.alternateID: result.append('NOT NULL') if self.unique or self.alternateID: |
From: <ian...@us...> - 2003-04-29 09:36:29
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv13462/SQLObject Modified Files: DBConnection.py Log Message: Took out SQLite's concurrency protection, because it doesn't seem necessary anymore. Not entirely sure about this, though. Index: DBConnection.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/DBConnection.py,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** DBConnection.py 29 Apr 2003 09:30:03 -0000 1.30 --- DBConnection.py 29 Apr 2003 09:36:25 -0000 1.31 *************** *** 588,598 **** return not not result - def iterSelect(self, select): - """ - SQLite doesn't support concurrent access, so we do the entire - SELECT right away and iterate over a list of objects. - """ - return iter(list(DBAPI.iterSelect(self, select))) - ######################################## ## File-based connections --- 588,591 ---- |
From: <ian...@us...> - 2003-04-29 09:30:07
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv7646/SQLObject Modified Files: DBConnection.py Log Message: typo Index: DBConnection.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/DBConnection.py,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** DBConnection.py 29 Apr 2003 09:27:55 -0000 1.29 --- DBConnection.py 29 Apr 2003 09:30:03 -0000 1.30 *************** *** 544,548 **** class SQLiteConnection(DBAPI): ! def __init__(self, filename, **kw): assert sqlite, 'sqlite module cannot be found' self.filename = filename # full path to sqlite-db-file --- 544,548 ---- class SQLiteConnection(DBAPI): ! def __init__(self, filename, autoCommit=1, **kw): assert sqlite, 'sqlite module cannot be found' self.filename = filename # full path to sqlite-db-file |
From: <ian...@us...> - 2003-04-29 09:27:58
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv6070/SQLObject Modified Files: DBConnection.py Log Message: Fixed up SQLite __init__ a bit (from Peter Wilkinson) Index: DBConnection.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/DBConnection.py,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** DBConnection.py 29 Apr 2003 08:15:10 -0000 1.28 --- DBConnection.py 29 Apr 2003 09:27:55 -0000 1.29 *************** *** 544,554 **** class SQLiteConnection(DBAPI): ! def __init__(self, dsn, **kw): assert sqlite, 'sqlite module cannot be found' ! self.dsn = dsn # full path to sqlite-db-file DBAPI.__init__(self, **kw) def makeConnection(self): ! return sqlite.connect(self.dsn) def _queryInsertID(self, conn, table, idName, names, values): --- 544,560 ---- class SQLiteConnection(DBAPI): ! def __init__(self, filename, **kw): assert sqlite, 'sqlite module cannot be found' ! self.filename = filename # full path to sqlite-db-file ! if not autoCommit and not kw.has_key('pool'): ! # Pooling doesn't work with transactions... ! kw['pool'] = 0 ! # use only one connection for sqlite - supports multiple ! # cursors per connection ! self._conn = sqlite.connect(self.filename) DBAPI.__init__(self, **kw) def makeConnection(self): ! return self._conn def _queryInsertID(self, conn, table, idName, names, values): |
From: <ian...@us...> - 2003-04-29 09:26:56
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv5369/SQLObject Modified Files: Col.py Log Message: Removed obsolete code Index: Col.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Col.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** Col.py 22 Apr 2003 03:10:00 -0000 1.15 --- Col.py 29 Apr 2003 09:26:52 -0000 1.16 *************** *** 61,66 **** if self.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 --- 61,64 ---- |
From: <ian...@us...> - 2003-04-29 08:23:21
|
Update of /cvsroot/sqlobject/SQLObject/docs In directory sc8-pr-cvs1:/tmp/cvs-serv21139/docs Modified Files: SQLObject.txt Log Message: Noted __connection__'s textual position. Index: SQLObject.txt =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/docs/SQLObject.txt,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** SQLObject.txt 17 Apr 2003 07:17:12 -0000 1.11 --- SQLObject.txt 29 Apr 2003 08:23:17 -0000 1.12 *************** *** 150,156 **** The special variable `__connection__` gives the database connection ! for any classes in the module. You can also use the class variable ! `_connection` in the same way. The MySQL connection is shown, for ! Postgres use ``DBConnection.PostgresConnection(dsnString)``. That's pretty much all you have to do to set the object up -- give it --- 150,157 ---- The special variable `__connection__` gives the database connection ! for any classes in the module (it must appear above the class ! definition). You can also use the class variable `_connection` in the ! same way. The MySQL connection is shown, for Postgres use ! ``DBConnection.PostgresConnection(dsnString)``. That's pretty much all you have to do to set the object up -- give it |
From: <ian...@us...> - 2003-04-29 08:15:16
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv14373/SQLObject Modified Files: DBConnection.py SQLObject.py Log Message: Postgres: Use lastoid instead of selecting directly from the sequence. Means you *must* use SERIAL for your ID column, or something that acts like it (i.e., does an auto increment) Index: DBConnection.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/DBConnection.py,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** DBConnection.py 22 Apr 2003 02:27:10 -0000 1.27 --- DBConnection.py 29 Apr 2003 08:15:10 -0000 1.28 *************** *** 446,458 **** def _queryInsertID(self, conn, table, idName, names, values): c = conn.cursor() - c.execute('SELECT nextval(\'%s_%s_seq\')' % (table, idName)) - (id,) = c.fetchone() - names.append(idName) - values.append(id) q = self._insertSQL(table, names, values) if self.debug: print 'QueryIns: %s' % q c.execute(q) ! return id def _queryAddLimitOffset(self, query, start, end): --- 446,456 ---- 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) ! c.execute('SELECT %s FROM %s WHERE oid = %s' ! % (idName, table, c.lastoid())) ! return c.fetchone()[0] def _queryAddLimitOffset(self, query, start, end): Index: SQLObject.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/SQLObject.py,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** SQLObject.py 22 Apr 2003 03:10:01 -0000 1.28 --- SQLObject.py 29 Apr 2003 08:15:11 -0000 1.29 *************** *** 592,596 **** # There's a write lock. Not sure if I need this... ! self._SO_writeLock.acquire() self._connection._SO_update(self, [(self._SO_columnDict[name].dbName, --- 592,596 ---- # There's a write lock. Not sure if I need this... ! #self._SO_writeLock.acquire() self._connection._SO_update(self, [(self._SO_columnDict[name].dbName, *************** *** 601,605 **** if self._SO_autoInitDone: setattr(self, instanceName(name), value) ! self._SO_writeLock.release() def set(self, **kw): --- 601,605 ---- if self._SO_autoInitDone: setattr(self, instanceName(name), value) ! #self._SO_writeLock.release() def set(self, **kw): *************** *** 643,649 **** % (self.__class__.__name__, self.id) # @@: do we really need this lock? ! self._SO_writeLock.acquire() results = self._connection._SO_selectOne(self, [self._SO_columnDict[name].dbName]) ! self._SO_writeLock.release() assert results != None, "%s with id %s is not in the database" \ % (self.__class__.__name__, self.id) --- 643,649 ---- % (self.__class__.__name__, self.id) # @@: do we really need this lock? ! #self._SO_writeLock.acquire() results = self._connection._SO_selectOne(self, [self._SO_columnDict[name].dbName]) ! #self._SO_writeLock.release() assert results != None, "%s with id %s is not in the database" \ % (self.__class__.__name__, self.id) |
From: <ian...@us...> - 2003-04-22 03:10:07
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv893/SQLObject Modified Files: Col.py SQLObject.py Log Message: Removed references to util module (which has been removed) Index: Col.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Col.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** Col.py 21 Apr 2003 22:37:16 -0000 1.14 --- Col.py 22 Apr 2003 03:10:00 -0000 1.15 *************** *** 4,8 **** import SQLBuilder - from util import splitWords import re import Constraints --- 4,7 ---- *************** *** 77,88 **** def autoConstraints(self): return [] - - def generateDBName(self, name): - if name.endswith('ID'): - # We'd get row_i_d if we didn't do this (or - # you'd be required to use names like rowId) - return splitWords(name[:-2]) + "_id" - else: - return splitWords(name) def _get_default(self): --- 76,79 ---- Index: SQLObject.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/SQLObject.py,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** SQLObject.py 22 Apr 2003 02:27:10 -0000 1.27 --- SQLObject.py 22 Apr 2003 03:10:01 -0000 1.28 *************** *** 26,30 **** import Col import Style - from util import splitWords import sys --- 26,29 ---- |
From: <ian...@us...> - 2003-04-22 02:27:13
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv15147/SQLObject Modified Files: DBConnection.py SQLObject.py Log Message: Took out all the lazy retrieval of stuff from the database Index: DBConnection.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/DBConnection.py,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** DBConnection.py 21 Apr 2003 22:43:48 -0000 1.26 --- DBConnection.py 22 Apr 2003 02:27:10 -0000 1.27 *************** *** 141,148 **** yield select.sourceClass(result[0]) else: ! obj = select.sourceClass(result[0]) ! obj._SO_writeLock.acquire() ! obj._SO_selectInit(result[1:]) ! obj._SO_writeLock.release() yield obj --- 141,145 ---- yield select.sourceClass(result[0]) else: ! obj = select.sourceClass(result[0], selectResults=result[1:]) yield obj Index: SQLObject.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/SQLObject.py,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** SQLObject.py 21 Apr 2003 22:37:16 -0000 1.26 --- SQLObject.py 22 Apr 2003 02:27:10 -0000 1.27 *************** *** 295,303 **** _style = None ! def __new__(cls, id, connection=None): # When id is None, that means we are trying # to create a new object. This is done by the ! # `new` method. if id is None: # Create an actual new object: --- 295,303 ---- _style = None ! def __new__(cls, id, connection=None, selectResults=None): # When id is None, that means we are trying # to create a new object. This is done by the ! # `new()` method. if id is None: # Create an actual new object: *************** *** 318,326 **** cache = connection.cache val = cache.get(id, cls) if val is None: try: ! val = object.__new__(cls, id, connection) ! val._init(id, connection) cache.put(id, cls, val) finally: --- 318,328 ---- cache = connection.cache + # This whole sequence comes from Cache.CacheFactory's + # behavior, where a None returned means a cache miss. val = cache.get(id, cls) if val is None: try: ! val = object.__new__(cls) ! val._init(id, connection, selectResults) cache.put(id, cls, val) finally: *************** *** 347,365 **** # We create a method here, which is just a function ! # that takes "self" as the first argument. The ! # basic logic of the lambda is: ! # When we have cached values, self._SO_autoInitDone ! # is true, so we skip out of the parenthesis. ! # If we don't, we run self._SO_autoInit() which ! # gets the cached values (for all columns). ! # The cached values are stored in something ! # like _SO_val_columnName, so we return that ! # last. ! setattr(cls, rawGetterName(name), eval('lambda self: (self._SO_autoInitDone or self._SO_autoInit()) and self.%s' % (instanceName(name)))) else: # If we aren't caching values, we just call the # function _SO_getValue, which fetches from the # database. ! setattr(cls, rawGetterName(name), eval('lambda self: self._SO_getValue(%s)' % repr(name))) # Here if the _get_columnName method isn't in the --- 349,360 ---- # We create a method here, which is just a function ! # that takes "self" as the first argument. ! getter = eval('lambda self: self.%s' % instanceName(name)) else: # If we aren't caching values, we just call the # function _SO_getValue, which fetches from the # database. ! getter = eval('lambda self: self._SO_getValue(%s)' % repr(name)) ! setattr(cls, rawGetterName(name), getter) # Here if the _get_columnName method isn't in the *************** *** 367,371 **** # _SO_get_columnName definition. if not hasattr(cls, getterName(name)): ! setattr(cls, getterName(name), getattr(cls, rawGetterName(name))) cls._SO_plainGetters[name] = 1 --- 362,366 ---- # _SO_get_columnName definition. if not hasattr(cls, getterName(name)): ! setattr(cls, getterName(name), getter) cls._SO_plainGetters[name] = 1 *************** *** 378,385 **** # We start by just using the _SO_setValue method ! setattr(cls, rawSetterName(name), eval('lambda self, val: self._SO_setValue(%s, val)' % repr(name))) # Then do the aliasing if not hasattr(cls, setterName(name)): ! setattr(cls, setterName(name), getattr(cls, rawSetterName(name))) # We keep track of setters that haven't been # overridden, because we can combine these --- 373,381 ---- # We start by just using the _SO_setValue method ! setter = eval('lambda self, val: self._SO_setValue(%s, val)' % repr(name)) ! setattr(cls, rawSetterName(name), setter) # Then do the aliasing if not hasattr(cls, setterName(name)): ! setattr(cls, setterName(name), setter) # We keep track of setters that haven't been # overridden, because we can combine these *************** *** 402,421 **** # self._SO_class_className is a reference # to the class in question. ! setattr(cls, rawGetterName(name)[:-2], eval('lambda self: (self._SO_autoInitDone or self._SO_autoInit()) and self._SO_class_%s(self.%s)' % (column.foreignKey, instanceName(name)))) else: # Same non-caching version as above. ! setattr(cls, rawGetterName(name)[:-2], eval('lambda self: self._SO_class_%s(self._SO_getValue(%s))' % (column.foreignKey, repr(name)))) # And we set the _get_columnName version # (sans ID ending) if not hasattr(cls, getterName(name)[:-2]): ! setattr(cls, getterName(name)[:-2], getattr(cls, rawGetterName(name)[:-2])) cls._SO_plainForeignGetters[name[:-2]] = 1 # The setter just gets the ID of the object, # and then sets the real column. ! setattr(cls, rawSetterName(name)[:-2], eval('lambda self, val: setattr(self, %s, self._SO_getID(val))' % (repr(name)))) if not hasattr(cls, setterName(name)[:-2]): ! setattr(cls, setterName(name)[:-2], getattr(cls, rawSetterName(name)[:-2])) cls._SO_plainForeignSetters[name[:-2]] = 1 # We'll need to put in a real reference at # some point. See needSet at the top of the --- 398,421 ---- # 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. ! getter = eval('lambda self: self._SO_class_%s(self._SO_getValue(%s))' % (column.foreignKey, repr(name))) ! setattr(cls, rawGetterName(name)[:-2], getter) ! # And we set the _get_columnName version # (sans ID ending) if not hasattr(cls, getterName(name)[:-2]): ! setattr(cls, getterName(name)[:-2], getter) cls._SO_plainForeignGetters[name[:-2]] = 1 # The setter just gets the ID of the object, # and then sets the real column. ! setter = eval('lambda self, val: setattr(self, %s, self._SO_getID(val))' % (repr(name))) ! setattr(cls, rawSetterName(name)[:-2], setter) if not hasattr(cls, setterName(name)[:-2]): ! setattr(cls, setterName(name)[:-2], setter) cls._SO_plainForeignSetters[name[:-2]] = 1 + # We'll need to put in a real reference at # some point. See needSet at the top of the *************** *** 443,449 **** def delColumn(cls, column, changeSchema=False): - cls._columns.remove(column) if isinstance(column, str): column = cls._SO_columnDict[column] name = column.name del cls._SO_columnDict[name] --- 443,449 ---- def delColumn(cls, column, changeSchema=False): if isinstance(column, str): column = cls._SO_columnDict[column] + cls._columns.remove(column) name = column.name del cls._SO_columnDict[name] *************** *** 554,558 **** delJoin = classmethod(delJoin) ! def _init(self, id, connection=None): assert id is not None # This function gets called only when the object is --- 554,558 ---- delJoin = classmethod(delJoin) ! def _init(self, id, connection=None, selectResults=None): assert id is not None # This function gets called only when the object is *************** *** 571,574 **** --- 571,582 ---- # This flag tells us that: self._SO_perConnection = True + + dbNames = [col.dbName for col in self._columns] + if not selectResults: + selectResults = (connection or self._connection)._SO_selectOne(self, dbNames) + if not selectResults: + raise SQLObjectNotFound, "The object %s by the ID %s does not exist" % (self.__class__.__name__, self.id) + self._SO_selectInit(selectResults) + def _SO_setValue(self, name, value): *************** *** 627,658 **** self._SO_writeLock.release() - def _SO_autoInit(self): - # This loads all the columns from the database, and - # caches them in instance variables. - - # First check we aren't dead: - assert not self._SO_obsolete, "%s with id %s has become obsolete" \ - % (self.__class__.__name__, self.id) - - # Make sure nobody changes things underneith us: - self._SO_writeLock.acquire() - - # Database (_-using) names: - dbNames = [col.dbName for col in self._columns] - - results = self._connection._SO_selectOne(self, dbNames) - assert results, "The object %s by the ID %s does not exist" % (self.__class__.__name__, self.id) - - self._SO_selectInit(results) - self._SO_writeLock.release() - - # We have to return True so that the fancy - # (... or ...) and ... logic in the lambda works out. - return True - def _SO_selectInit(self, row): for col, colValue in zip(self._columns, row): setattr(self, instanceName(col.name), colValue) - self._SO_autoInitDone = 1 def _SO_getValue(self, name): --- 635,641 ---- |
From: <ian...@us...> - 2003-04-21 23:34:51
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv23138/SQLObject Removed Files: util.py Log Message: Removed now-unused util module (what little functionality there was is moved to Style) --- util.py DELETED --- |
From: <ian...@us...> - 2003-04-21 22:50:41
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv5788/SQLObject Added Files: Style.py Log Message: New Style module --- NEW FILE: Style.py --- import re __all__ = ["Style", "MixedCaseUnderscoreStyle", "DefaultStyle"] class Style(object): """ The base Style class, and also the simplest implementation. No translation occurs -- column names and attribute names match, as do class names and table names (when using auto class or schema generation). """ def __init__(self, pythonAttrToDBColumn=None, dbColumnToPythonAttr=None, pythonClassToDBTable=None, dbTableToPythonClass=None, idForTable=None): if pythonAttrToDBColumn: self.pythonAttrToDBColumn = lambda a, s=self: pythonAttrToDBColumn(s, a) if dbColumnToPythonAttr: self.dbColumnToPythonAttr = lambda a, s=self: dbColumnToPythonAttr(s, a) if pythonClassToDBTable: self.pythonClassToDBTable = lambda a, s=self: pythonClassToDBTable(s, a) if dbTableToPythonClass: self.dbTableToPythonClass = lambda a, s=self: dbTableToPythonClass(s, a) if idForTable: self.idForTable = lambda a, s=self: idForTable(s, a) def pythonAttrToDBColumn(self, attr): return attr def dbColumnToPythonAttr(self, col): return col def pythonClassToDBTable(self, className): return className def dbTableToPythonClass(self, table): return table def idForTable(self, table): return 'id' class MixedCaseUnderscoreStyle(Style): """ This is the default style. Python attributes use mixedCase, while database columns use underscore_separated. """ def pythonAttrToDBColumn(self, attr): return mixedToUnder(attr) def dbColumnToPythonAttr(self, col): return underToMixed(col) def pythonClassToDBTable(self, className): return className[0].lower() \ + mixedToUnder(className[1:]) def dbTableToPythonClass(self, table): return table[0].upper() \ + underToMixed(table[1:]) def pythonClassToDBTableReference(self, className): return self.tableReference(self.pythonClassToDBTable(className)) def tableReference(self, table): return table + "_id" DefaultStyle = MixedCaseUnderscoreStyle def longID(self, table): """ Use SomeStyle(idForTable=longID) to use this. This will make table IDs use the full table, like person_id. """ return defaultStyle = DefaultStyle() def getStyle(soClass, dbConnection=None): if dbConnection is None: if hasattr(soClass, '_connection'): dbConnection = soClass._connection if hasattr(soClass, '_style') and soClass._style: return soClass._style elif dbConnection and dbConnection.style: return dbConnection.style else: return defaultStyle ############################################################ ## Text utilities ############################################################ _mixedToUnderRE = re.compile(r'[A-Z]+') def mixedToUnder(s): if s.endswith('ID'): return mixedToUnder(s[:-2] + "_id") trans = _mixedToUnderRE.sub(lambda x: '_%s' % x.group(0).lower(), s) if trans.startswith('_'): trans = trans[1:] return trans _underToMixedRE = re.compile('_.') def underToMixed(name): if name.endswith('_id'): return underToMixed(name[:-3] + "ID") return _underToMixedRE.sub(lambda m: m.group(0)[1].upper(), name) |
From: <ian...@us...> - 2003-04-21 22:50:13
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv5193/SQLObject Modified Files: __init__.py Log Message: Added Style import Index: __init__.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/__init__.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** __init__.py 14 Mar 2003 03:52:01 -0000 1.2 --- __init__.py 21 Apr 2003 22:50:09 -0000 1.3 *************** *** 3,4 **** --- 3,5 ---- from SQLBuilder import AND, OR, NOT, IN, LIKE, CONTAINSSTRING, const, func from DBConnection import * + from Style import * |
From: <ian...@us...> - 2003-04-21 22:43:51
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv2679/SQLObject Modified Files: DBConnection.py Log Message: Removed unneeded fcntl import Index: DBConnection.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/DBConnection.py,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** DBConnection.py 21 Apr 2003 22:43:25 -0000 1.25 --- DBConnection.py 21 Apr 2003 22:43:48 -0000 1.26 *************** *** 8,15 **** import Col try: - import fcntl - except ImportError: - fcntl = None - try: import cPickle as pickle except ImportError: --- 8,11 ---- |
From: <ian...@us...> - 2003-04-21 22:43:28
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv2559/SQLObject Modified Files: DBConnection.py Log Message: Removed PickleConnection Index: DBConnection.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/DBConnection.py,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** DBConnection.py 21 Apr 2003 22:40:56 -0000 1.24 --- DBConnection.py 21 Apr 2003 22:43:25 -0000 1.25 *************** *** 38,42 **** __all__ = ['MySQLConnection', 'PostgresConnection', 'SQLiteConnection', ! 'PickleConnection', 'DBMConnection'] _connections = {} --- 38,42 ---- __all__ = ['MySQLConnection', 'PostgresConnection', 'SQLiteConnection', ! 'DBMConnection'] _connections = {} *************** *** 688,769 **** results.append((id,)) return results - - class PickleConnection(FileConnection): - - def __init__(self, path, **kw): - self.path = path - FileConnection.__init__(self, **kw) - - def _filename(self, table, id): - return '%s-%i.pickle' % (table, id) - - def _newID(self, table): - idFilename = os.path.join(self.path, "%s-ids.txt" % table) - try: - f = open(idFilename, "r+") - except IOError: - f = open(idFilename, "w") - f.write("0") - f.close() - f = open(idFilename, "r+") - fcntl.lockf(f, fcntl.LOCK_EX) - id = int(f.read()) + 1 - # @@: Can I just close this and open it in write mode, while - # retaining this lock? - f.seek(0) - f.write(str(id)) - fcntl.lockf(f, fcntl.LOCK_UN) - f.close() - return id - - def _fetchDict(self, table, id): - f = open(self._filename(table, id), 'rb') - d = pickle.load(f) - f.close() - return d - - def _saveDict(self, table, id, d): - f = open(self._filename(table, id), 'wb') - pickle.dump(d, f) - f.close() - - def _fetchTables(self): - filename = os.path.join(self.path, "table-list.txt") - try: - f = open(filename, "r") - except IOError: - return [] - lines = [l.strip() for l in f.readlines()] - f.close() - return lines - - def _saveTables(self, tables): - filename = os.path.join(self.path, "table-list.txt") - f = open(filename, "w") - f.write('\n'.join(tables)) - f.close() - - def tableExists(self, table): - return table in self._fetchTables() - - def createTable(self, soClass): - tables = self._fetchTables() - tables.append(soClass._table) - self._saveTables(tables) - - def dropTable(self, tableName): - tables = self._fetchTables() - tables.remove(tableName) - self._saveTables(tables) - self.clearTable(tableName) - - def clearTable(self, tableName): - for filename in os.listdir(self.path): - if filename.startswith(tableName + "-"): - os.unlink(os.path.join(self.path, filename)) - - def _SO_delete(self, so): - os.unlink(self._filename(so._table, so.id)) - class DBMConnection(FileConnection): --- 688,691 ---- |
From: <ian...@us...> - 2003-04-21 22:40:59
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv1243/SQLObject Modified Files: DBConnection.py Log Message: Fixed some bugs for Postgres columnsFromSchema Forgot to mention in last commit that SQLObject can take columns like: class SomeObject(SQLObject): someColumn = Col() Index: DBConnection.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/DBConnection.py,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** DBConnection.py 21 Apr 2003 22:37:16 -0000 1.23 --- DBConnection.py 21 Apr 2003 22:40:56 -0000 1.24 *************** *** 513,517 **** keyData = self.queryAll(keyQuery % tableName) ! keyRE = re.compile("\((.)\) REFERENCES (.)\(") keymap = {} for (condef,) in keyData: --- 513,517 ---- keyData = self.queryAll(keyQuery % tableName) ! keyRE = re.compile("\((.+)\) REFERENCES (.+)\(") keymap = {} for (condef,) in keyData: *************** *** 520,524 **** field, reftable = match.groups() keymap[field] = reftable.capitalize() - #print "keymap:", keymap colData = self.queryAll(colQuery % tableName) results = [] --- 520,523 ---- *************** *** 530,534 **** kw['notNull'] = notnull if defaultstr is not None: ! kw['default'] = eval(defaultstr) if keymap.has_key(field): kw['foreignKey'] = keymap[field] --- 529,533 ---- kw['notNull'] = notnull if defaultstr is not None: ! kw['default'] = getattr(SQLBuilder.const, defaultstr) if keymap.has_key(field): kw['foreignKey'] = keymap[field] |
From: <ian...@us...> - 2003-04-21 22:37:20
|
Update of /cvsroot/sqlobject/SQLObject/tests In directory sc8-pr-cvs1:/tmp/cvs-serv32496/tests Modified Files: SQLObjectTest.py Log Message: * Reorganized SQLObjectMeta.__new__ (simplified) * New Style module, that allows different ways to map Python attributes to database names (instead of columnName -> column_name) Index: SQLObjectTest.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/tests/SQLObjectTest.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** SQLObjectTest.py 19 Apr 2003 00:54:25 -0000 1.8 --- SQLObjectTest.py 21 Apr 2003 22:37:17 -0000 1.9 *************** *** 70,74 **** elif hasattr(c, 'createTable'): c.createTable(ifNotExists=True) ! #__connection__.debug = 0 self.inserts() __connection__.debug = self.debugSQL --- 70,74 ---- elif hasattr(c, 'createTable'): c.createTable(ifNotExists=True) ! #__connection__.debug = self.debugSQL self.inserts() __connection__.debug = self.debugSQL |
From: <ian...@us...> - 2003-04-21 22:37:20
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv32496/SQLObject Modified Files: Col.py DBConnection.py SQLObject.py Log Message: * Reorganized SQLObjectMeta.__new__ (simplified) * New Style module, that allows different ways to map Python attributes to database names (instead of columnName -> column_name) Index: Col.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Col.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** Col.py 21 Apr 2003 07:40:26 -0000 1.13 --- Col.py 21 Apr 2003 22:37:16 -0000 1.14 *************** *** 19,23 **** class Col(object): ! def __init__(self, name, dbName=None, default=NoDefault, foreignKey=None, alternateID=False, alternateMethodName=None, --- 19,23 ---- class Col(object): ! def __init__(self, name=None, dbName=None, default=NoDefault, foreignKey=None, alternateID=False, alternateMethodName=None, *************** *** 27,70 **** # around column names, but why would anyone *want* to # use a name like that? assert SQLBuilder.sqlIdentifier(name), 'Name must be SQL-safe (letters, numbers, underscores): %s' \ % repr(name) assert name != 'id', 'The column name "id" is reserved for SQLObject use (and is implicitly created).' ! # .name is public self.name = name # 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 = self.generateDBName(self.name) else: self.dbName = dbName - self._default = default # alternateID means that this is a unique column that # can be used to identify rows ! self.alternateID = alternateID ! if alternateID and alternateMethodName is None: ! self.alternateMethodName = 'by' + name[0].capitalize() + name[1:] ! else: ! self.alternateMethodName = alternateMethodName ! self.foreignKey = foreignKey ! if foreignKey: ! assert name.upper().endswith('ID'), "All foreign key columns must end with 'ID' (%s)" % repr(name) ! self.foreignName = name[:-2] else: self.foreignName = None - constraints = constraints or [] - if type(constraints) not in (type([]), type(())): - constraints = [constraints] - constraints = self.autoConstraints() + constraints - self.notNull = notNull - if notNull: - constraints = [Constraints.notNull] + constraints - self.contraints = constraints - if unique is NoDefault: - self.unique = alternateID - else: - self.unique = unique def autoConstraints(self): --- 27,77 ---- # around column names, but why would anyone *want* to # use a name like that? + # @@: I suppose we could actually add backquotes to the + # dbName if we needed to... assert SQLBuilder.sqlIdentifier(name), 'Name must be SQL-safe (letters, numbers, underscores): %s' \ % 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 + self._default = default + + 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) else: self.dbName = dbName # 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) ! self.foreignName = self.name[:-2] else: self.foreignName = None def autoConstraints(self): *************** *** 266,277 **** del kw[name] return value - - _generatePythonNameRE = re.compile('_.') - def generatePythonName(name): - if name.endswith('_id'): - return generatePythonName(name[:-3] + "ID") - def subber(match): - return match.group(0)[1].upper() - return _generatePythonNameRE.sub(subber, name) all = [] --- 273,276 ---- Index: DBConnection.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/DBConnection.py,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** DBConnection.py 21 Apr 2003 07:40:51 -0000 1.22 --- DBConnection.py 21 Apr 2003 22:37:16 -0000 1.23 *************** *** 44,48 **** class DBConnection: ! def __init__(self, name=None, debug=False, cache=True): if name: assert not _connections.has_key(name), 'A database by the name %s has already been created: %s' % (name, _connections[name]) --- 44,49 ---- class DBConnection: ! def __init__(self, name=None, debug=False, cache=True, ! style=None): if name: assert not _connections.has_key(name), 'A database by the name %s has already been created: %s' % (name, _connections[name]) *************** *** 51,54 **** --- 52,56 ---- self.debug = debug self.cache = CacheSet(cache=cache) + self.style = style *************** *** 393,397 **** column.dbName)) ! def columnsFromSchema(self, tableName): colData = self.queryAll("SHOW COLUMNS FROM %s" % tableName) --- 395,399 ---- column.dbName)) ! def columnsFromSchema(self, tableName, soClass): colData = self.queryAll("SHOW COLUMNS FROM %s" % tableName) *************** *** 401,405 **** continue colClass, kw = self.guessClass(t) ! kw['name'] = Col.generatePythonName(field) kw['notNull'] = not nullAllowed kw['default'] = default --- 403,407 ---- continue colClass, kw = self.guessClass(t) ! kw['name'] = soClass._style.dbColumnToPythonAttr(field) kw['notNull'] = not nullAllowed kw['default'] = default *************** *** 493,497 **** column.dbName)) ! def columnsFromSchema(self, tableName): keyQuery = """ --- 495,499 ---- column.dbName)) ! def columnsFromSchema(self, tableName, soClass): keyQuery = """ *************** *** 525,529 **** continue colClass, kw = self.guessClass(t) ! kw['name'] = Col.generatePythonName(field) kw['notNull'] = notnull if defaultstr is not None: --- 527,531 ---- continue colClass, kw = self.guessClass(t) ! kw['name'] = soClass._style.dbColumnToPythonAttr(field) kw['notNull'] = notnull if defaultstr is not None: *************** *** 589,592 **** --- 591,601 ---- # turn it into a boolean: return not not result + + def iterSelect(self, select): + """ + SQLite doesn't support concurrent access, so we do the entire + SELECT right away and iterate over a list of objects. + """ + return iter(list(DBAPI.iterSelect(self, select))) ######################################## Index: SQLObject.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/SQLObject.py,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** SQLObject.py 19 Apr 2003 03:31:11 -0000 1.25 --- SQLObject.py 21 Apr 2003 22:37:16 -0000 1.26 *************** *** 25,28 **** --- 25,29 ---- import DBConnection import Col + import Style from util import splitWords *************** *** 74,186 **** class MetaSQLObject(type): ! def __new__(cls, className, bases, dict): global classRegistry, needSet ! # plainSetters are columns that haven't been ! # overridden by the user, so we can contact the ! # database directly to set them. ! dict['_SO_plainSetters'] = {} ! dict['_SO_plainGetters'] = {} ! dict['_SO_plainForeignSetters'] = {} ! dict['_SO_plainForeignGetters'] = {} ! dict['_SO_plainJoinGetters'] = {} ! dict['_SO_plainJoinAdders'] = {} ! dict['_SO_plainJoinRemovers'] = {} ! ! # This is a dictionary of columnName: columnObject ! dict['_SO_columnDict'] = {} ! ! # The _cacheValues attribute controls if you cache ! # values fetched from the database. We make sure ! # it's set (default 1). ! cacheValues = dict.get('_cacheValues', 1) ! dict['_cacheValues'] = cacheValues ! ! # The _defaultOrder is used by SelectResults ! if not dict.has_key('_defaultOrder'): ! dict['_defaultOrder'] = None ! ! # We fix up the columns here -- replacing any ! # strings with simply-contructed Col objects, ! # and making sure each column knows where it ! # comes from (the className). columns = [] ! for column in dict.get('_columns', []): if isinstance(column, str): column = Col.Col(column) columns.append(column) ! column.className = className ! dict['_columns'] = columns ###################################################### # Set some attributes to their defaults, if necessary. # First we get the connection: ! if not dict.has_key('_connection'): ! # The SQLObject class is special for these defaults, ! # since it's abstract we'll ignore it. ! if className != 'SQLObject': ! mod = sys.modules[dict['__module__']] ! # See if there's a __connection__ global in ! # the module, use it if there is. ! if hasattr(mod, '__connection__'): ! dict['_connection'] = mod.__connection__ ! # If _table isn't given, just use the class name ! # (with mixedCase turned to mixed_case). ! if not dict.has_key('_table'): ! dict['_table'] = generateTableName(className) ! # If _idName isn't given, just use "id" ! if not dict.has_key('_idName'): ! dict['_idName'] = 'id' ! ######################################## ! # Now we do the joins: ! # We keep track of the different joins by index, ! # putting them in this list. ! dict['_SO_joinList'] = [] ! # Joins are generally many-to-many, or many-to-one where ! # this class is the "one", so there's no associated ! # column. ! if not dict.has_key('_joins'): ! dict['_joins'] = [] # We use the magic "q" attribute for accessing lazy # SQL where-clause generation. See the sql module for # more. ! dict['q'] = SQLBuilder.SmartTable(dict['_table']) ! ! # If the connection is named, we turn the name into ! # a real connection. ! if dict.has_key('_connection') and \ ! isinstance(dict['_connection'], str): ! dict['_connection'] = DBConnection.connectionForName(dict['_connection']) ! ! # 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, dict) ! newClass._SO_finishedClassCreation = False for column in newClass._columns[:]: newClass.addColumn(column) ! if dict.get('_fromDatabase'): newClass.addColumnsFromDatabase() ! for join in newClass._joins[:]: ! newClass.addJoin(join) ! # Register it, for use with needSet ! classRegistry[className] = newClass ! # Call needSet ! setNeedSet() # We don't setup the properties until we're finished with the --- 75,180 ---- class MetaSQLObject(type): ! def __new__(cls, className, bases, d): global classRegistry, needSet ! # We fix up the columns here -- replacing any strings with ! # simply-contructed Col objects, and searching the class ! # variables for instances of Col objects (which get put into ! # the _columns instance variable and deleted). columns = [] ! for column in d.get('_columns', []): if isinstance(column, str): 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 ! # is defined in this class (not a superclass) ! if not d.has_key('_table'): ! 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 ###################################################### # Set some attributes to their defaults, if necessary. # First we get the connection: ! if not newClass._connection: ! mod = sys.modules[newClass.__module__] ! # See if there's a __connection__ global in ! # the module, use it if there is. ! if hasattr(mod, '__connection__'): ! newClass._connection = mod.__connection__ ! # If the connection is named, we turn the name into ! # a real connection. ! if isinstance(newClass._connection, str): ! newClass._connection = DBConnection.connectionForName( ! newClass._connection) ! # The style object tells how to map between Python ! # identifiers and Database identifiers: ! if not newClass._style: ! if newClass._connection and newClass._connection.style: ! newClass._style = newClass._connection.style ! else: ! newClass._style = Style.defaultStyle ! # plainSetters are columns that haven't been overridden by the ! # user, so we can contact the database directly to set them. ! # Note that these can't set these in the SQLObject class ! # itself, because they specific to this subclass of SQLObject, ! # and cannot be shared among classes. ! newClass._SO_plainSetters = {} ! newClass._SO_plainGetters = {} ! newClass._SO_plainForeignSetters = {} ! newClass._SO_plainForeignGetters = {} ! newClass._SO_plainJoinGetters = {} ! newClass._SO_plainJoinAdders = {} ! newClass._SO_plainJoinRemovers = {} ! # This is a dictionary of columnName: columnObject ! newClass._SO_columnDict = {} ! # If _table isn't given, use style default ! if not newClass._table: ! newClass._table = newClass._style.pythonClassToDBTable(className) ! ! # If _idName isn't given, use style default ! if not hasattr(newClass, '_idName'): ! newClass._idName = newClass._style.idForTable(newClass._table) # We use the magic "q" attribute for accessing lazy # SQL where-clause generation. See the sql module for # more. ! newClass.q = SQLBuilder.SmartTable(newClass._table) for column in newClass._columns[:]: newClass.addColumn(column) ! if newClass._fromDatabase: newClass.addColumnsFromDatabase() ! ######################################## ! # Now we do the joins: ! # We keep track of the different joins by index, ! # putting them in this list. ! newClass._SO_joinList = [] ! for join in newClass._joins: ! newClass.addJoin(join) # We don't setup the properties until we're finished with the *************** *** 189,192 **** --- 183,191 ---- makeProperties(newClass) + # Register it, for use with needSet + classRegistry[className] = newClass + # Call needSet + setNeedSet() + # And return the class return newClass *************** *** 250,262 **** break - def generateTableName(s): - """ - Given a mixed case class name, like SomeClass, turn it into - a underscore-separated name like some_class. - """ - return s[0].lower() + splitWords(s[1:]) - def findClass(name): ! assert classRegistry.has_key(name), "No class by the name %s found" % repr(name) return classRegistry[name] --- 249,254 ---- 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] *************** *** 280,288 **** # left. _SO_creating = False # Sometimes an intance is attached to a connection, not # globally available. In that case, self._SO_perConnection # will be true. It's false by default: ! _SO_perConnection=False def __new__(cls, id, connection=None): --- 272,297 ---- # left. _SO_creating = False + _SO_obsolete = False # Sometimes an intance is attached to a connection, not # globally available. In that case, self._SO_perConnection # will be true. It's false by default: ! _SO_perConnection = False ! ! # The _cacheValues attribute controls if you cache ! # values fetched from the database. We make sure ! # it's set (default 1). ! _cacheValues = False ! ! # The _defaultOrder is used by SelectResults ! _defaultOrder = None ! ! _connection = None ! ! _joins = [] ! ! _fromDatabase = False ! ! _style = None def __new__(cls, id, connection=None): *************** *** 320,323 **** --- 329,333 ---- 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" *************** *** 426,430 **** def addColumnsFromDatabase(cls): ! for column in cls._connection.columnsFromSchema(cls._table): if not cls._SO_columnDict.has_key(column.name): cls.addColumn(column) --- 436,440 ---- def addColumnsFromDatabase(cls): ! for column in cls._connection.columnsFromSchema(cls._table, cls): if not cls._SO_columnDict.has_key(column.name): cls.addColumn(column) *************** *** 476,480 **** # The join sometimes needs to know who we are, # mostly to generate some internal names: ! join.initCallingClass(cls.__name__, cls._table) # Now that the join is set up, we add it to our --- 486,490 ---- # 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 *************** *** 552,557 **** self._SO_autoInitDone = False self._SO_writeLock = threading.Lock() - # _SO_obsolete means we were deleted: - self._SO_obsolete = False # If no connection was given, we'll inherit the class # instance variable which should have a _connection --- 562,565 ---- *************** *** 711,715 **** # The rest go through setattr(): for name, value in others.items(): ! if not hasattr(inst, name): raise TypeError, "%s.new() got an unexpected keyword argument %s" % (cls.__name__, name) setattr(inst, name, value) --- 719,723 ---- # 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) *************** *** 888,892 **** self.joinMethodName = joinMethodName ! def initCallingClass(self, callingClass, dbName): # Since some of the automatic generation of the names # depends on the class/table to which this join belongs, --- 896,900 ---- self.joinMethodName = joinMethodName ! def initCallingClass(self, callingClass): # Since some of the automatic generation of the names # depends on the class/table to which this join belongs, *************** *** 895,904 **** # been created. self.callingClass = callingClass ! self.callingClassDBName = dbName 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 = dbName + "_id" def hasIntermediateTable(self): --- 903,912 ---- # 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): *************** *** 946,962 **** MultipleJoin.__init__(self, otherClass, **kw) self.intermediateTable = intermediateTable ! if otherColumn: ! self.otherColumn = otherColumn ! else: ! self.otherColumn = generateTableName(otherClass) + "_id" def hasIntermediateTable(self): return True ! def initCallingClass(self, callingClass, dbName): ! MultipleJoin.initCallingClass(self, callingClass, dbName) if not self.intermediateTable: ! names = [dbName, ! generateTableName(self.otherClass)] names.sort() self.intermediateTable = "%s_%s" % (names[0], names[1]) --- 954,970 ---- 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]) *************** *** 964,968 **** def performJoin(self, inst): cls = findClass(self.otherClass) ! me = findClass(self.callingClass) ids = me._connection._SO_intermediateJoin( self.intermediateTable, --- 972,976 ---- def performJoin(self, inst): cls = findClass(self.otherClass) ! me = self.callingClass ids = me._connection._SO_intermediateJoin( self.intermediateTable, *************** *** 973,977 **** def remove(self, inst, other): ! me = findClass(self.callingClass) me._connection._SO_intermediateDelete( self.intermediateTable, --- 981,985 ---- def remove(self, inst, other): ! me = self.callingClass me._connection._SO_intermediateDelete( self.intermediateTable, *************** *** 982,986 **** def add(self, inst, other): ! me = findClass(self.callingClass) me._connection._SO_intermediateInsert( self.intermediateTable, --- 990,994 ---- def add(self, inst, other): ! me = self.callingClass me._connection._SO_intermediateInsert( self.intermediateTable, |
From: <ian...@us...> - 2003-04-21 07:40:55
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv21443/SQLObject Modified Files: DBConnection.py Log Message: Make password and host default (to '' and 'localhost' respectively) Index: DBConnection.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/DBConnection.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** DBConnection.py 19 Apr 2003 00:04:08 -0000 1.21 --- DBConnection.py 21 Apr 2003 07:40:51 -0000 1.22 *************** *** 341,345 **** class MySQLConnection(DBAPI): ! def __init__(self, host, db, user, passwd, **kw): assert MySQLdb, 'MySQLdb module cannot be found' self.host = host --- 341,345 ---- class MySQLConnection(DBAPI): ! def __init__(self, db, user, passwd='', host='localhost', **kw): assert MySQLdb, 'MySQLdb module cannot be found' self.host = host |
From: <ian...@us...> - 2003-04-21 07:40:30
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv21201a/SQLObject Modified Files: Col.py Log Message: * Added Decimal and Currency Col * Fixed bug with using SQLBuilder const's as defaults to Col objects Index: Col.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Col.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** Col.py 19 Apr 2003 00:54:25 -0000 1.12 --- Col.py 21 Apr 2003 07:40:26 -0000 1.13 *************** *** 84,87 **** --- 84,89 ---- if self._default is NoDefault: return NoDefault + elif hasattr(self._default, 'sqlRepr'): + return self._default elif callable(self._default): return self._default() *************** *** 242,245 **** --- 244,261 ---- 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) |
From: <ian...@us...> - 2003-04-19 03:31:14
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv26941/SQLObject Modified Files: SQLObject.py Log Message: Raise TypeError if you give an unexpected keyword argument to new() Index: SQLObject.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/SQLObject.py,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** SQLObject.py 19 Apr 2003 01:04:18 -0000 1.24 --- SQLObject.py 19 Apr 2003 03:31:11 -0000 1.25 *************** *** 711,714 **** --- 711,716 ---- # The rest go through setattr(): for name, value in others.items(): + if not hasattr(inst, name): + raise TypeError, "%s.new() got an unexpected keyword argument %s" % (cls.__name__, name) setattr(inst, name, value) |
From: <ian...@us...> - 2003-04-19 01:04:22
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv21226/SQLObject Modified Files: SQLObject.py Log Message: Failed alternateID calls will raise SQLObjectNotFound Index: SQLObject.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/SQLObject.py,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** SQLObject.py 17 Apr 2003 07:22:51 -0000 1.23 --- SQLObject.py 19 Apr 2003 01:04:18 -0000 1.24 *************** *** 33,36 **** --- 33,38 ---- NoDefault = SQLBuilder.NoDefault + class SQLObjectNotFound(LookupError): pass + True, False = 1==1, 0==1 *************** *** 747,750 **** --- 749,754 ---- dbIDName, value) + if not result: + raise SQLObjectNotFound, "The %s by alternateID %s=%s does not exist" % (cls.__name__, dbIDName, repr(value)) obj = cls(result[0]) if not obj._SO_autoInitDone: *************** *** 1105,1107 **** __all__ = ['NoDefault', 'SQLObject', ! 'MultipleJoin', 'RelatedJoin', 'getID', 'getObject'] --- 1109,1112 ---- __all__ = ['NoDefault', 'SQLObject', ! 'MultipleJoin', 'RelatedJoin', 'getID', 'getObject', ! 'SQLObjectNotFound'] |
From: <ian...@us...> - 2003-04-19 00:58:48
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv19773/SQLObject Modified Files: Constraints.py Log Message: Added isFloat constraint, which FloatCol already was expecting to exist. Index: Constraints.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Constraints.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Constraints.py 14 Mar 2003 03:52:01 -0000 1.1 --- Constraints.py 19 Apr 2003 00:58:45 -0000 1.2 *************** *** 29,32 **** --- 29,36 ---- raise BadValue("only allows integers", obj, col, value) + def isFloat(obj, col, value): + if type(value) not in (type(1), type(1L), type(1.1)): + raise BadValue("only allows floating point numbers", obj, col, value) + class InList: |
From: <ian...@us...> - 2003-04-19 00:54:30
|
Update of /cvsroot/sqlobject/SQLObject/tests In directory sc8-pr-cvs1:/tmp/cvs-serv18414/tests Modified Files: SQLObjectTest.py test.py Log Message: * Made the EnumCol use Postgres' constraints * Small Enum test * Made alternateID imply unique Index: SQLObjectTest.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/tests/SQLObjectTest.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** SQLObjectTest.py 19 Apr 2003 00:04:08 -0000 1.7 --- SQLObjectTest.py 19 Apr 2003 00:54:25 -0000 1.8 *************** *** 7,10 **** --- 7,13 ---- SQLObjectTest.supportDynamic = True SQLObjectTest.supportAuto = True + # @@: MySQL *should* support this, but it appears not to + # care when you assign incorrect to an ENUM... + SQLObjectTest.supportRestrictedEnum = False return MySQLConnection(host='localhost', db='test', *************** *** 16,19 **** --- 19,23 ---- SQLObjectTest.supportDynamic = True SQLObjectTest.supportAuto = False + SQLObjectTest.supportRestrictedEnum = False return DBMConnection('data') *************** *** 21,24 **** --- 25,29 ---- SQLObjectTest.supportDynamic = True SQLObjectTest.supportAuto = True + SQLObjectTest.supportRestrictedEnum = True return PostgresConnection(db='test') *************** *** 26,33 **** SQLObjectTest.supportDynamic = False SQLObjectTest.supportAuto = False return SQLiteConnection('data/sqlite.data') - databaseName = None - supportedDatabases = ['mysql', 'postgres', 'sqlite', 'dbm'] --- 31,37 ---- SQLObjectTest.supportDynamic = False SQLObjectTest.supportAuto = False + SQLObjectTest.supportRestrictedEnum = False return SQLiteConnection('data/sqlite.data') supportedDatabases = ['mysql', 'postgres', 'sqlite', 'dbm'] *************** *** 38,41 **** --- 42,47 ---- debugSQL = 0 + databaseName = None + def setUp(self): if self.debugSQL: *************** *** 47,54 **** c._connection = __connection__ for c in self.classes + [self]: ! if hasattr(c, '%sDrop' % databaseName): if __connection__.tableExists(c._table): __connection__.query( ! getattr(c, '%sDrop' % databaseName)) elif hasattr(c, 'drop'): __connection__.query(c.drop) --- 53,60 ---- c._connection = __connection__ for c in self.classes + [self]: ! if hasattr(c, '%sDrop' % self.databaseName): if __connection__.tableExists(c._table): __connection__.query( ! getattr(c, '%sDrop' % self.databaseName)) elif hasattr(c, 'drop'): __connection__.query(c.drop) *************** *** 56,63 **** c.dropTable(ifExists=True) ! if hasattr(c, '%sCreate' % databaseName): if not __connection__.tableExists(c._table): __connection__.query( ! getattr(c, '%sCreate' % databaseName)) elif hasattr(c, 'create'): __connection__.query(c.create) --- 62,69 ---- c.dropTable(ifExists=True) ! if hasattr(c, '%sCreate' % self.databaseName): if not __connection__.tableExists(c._table): __connection__.query( ! getattr(c, '%sCreate' % self.databaseName)) elif hasattr(c, 'create'): __connection__.query(c.create) *************** *** 80,86 **** def setDatabaseType(t): global __connection__ - global databaseName conn = globals()[t + "Connection"]() ! databaseName = t __connection__ = conn --- 86,91 ---- def setDatabaseType(t): global __connection__ conn = globals()[t + "Connection"]() ! SQLObject.databaseName = t __connection__ = conn Index: test.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/tests/test.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** test.py 19 Apr 2003 00:04:08 -0000 1.8 --- test.py 19 Apr 2003 00:54:25 -0000 1.9 *************** *** 32,35 **** --- 32,64 ---- ######################################## + ## Enum test + ######################################## + + class Enum1(SQLObject): + + _columns = [ + EnumCol('l', enumValues=['a', 'bcd', 'e']), + ] + + class TestEnum1(SQLObjectTest): + + classes = [Enum1] + + def inserts(self): + for l in ['a', 'bcd', 'a', 'e']: + Enum1.new(l=l) + + def testBad(self): + if self.supportRestrictedEnum: + try: + v = Enum1.new(l='b') + except Exception, e: + pass + else: + print v + assert 0, "This should cause an error" + + + ######################################## ## Slicing tests ######################################## |
From: <ian...@us...> - 2003-04-19 00:54:30
|
Update of /cvsroot/sqlobject/SQLObject/SQLObject In directory sc8-pr-cvs1:/tmp/cvs-serv18414/SQLObject Modified Files: Col.py Log Message: * Made the EnumCol use Postgres' constraints * Small Enum test * Made alternateID imply unique Index: Col.py =================================================================== RCS file: /cvsroot/sqlobject/SQLObject/SQLObject/Col.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** Col.py 19 Apr 2003 00:06:04 -0000 1.11 --- Col.py 19 Apr 2003 00:54:25 -0000 1.12 *************** *** 114,118 **** if self.notNull: result.append('NOT NULL') ! if self.unique: result.append('UNIQUE') return result --- 114,118 ---- if self.notNull: result.append('NOT NULL') ! if self.unique or self.alternateID: result.append('UNIQUE') return result *************** *** 206,210 **** def _postgresType(self): - # @@: there's a better type for this... return 'INT' --- 206,209 ---- *************** *** 225,230 **** def _postgresType(self): length = max(map(len, self.enumValues)) ! # 3-03 @@: should this be CHAR? ! return "VARCHAR(%i)" % length def _sqliteType(self): --- 224,230 ---- def _postgresType(self): length = max(map(len, self.enumValues)) ! enumValues = ', '.join(map(SQLBuilder.sqlRepr, self.enumValues)) ! checkConstraint = "CHECK (%s in (%s))" % (self.dbName, enumValues) ! return "VARCHAR(%i) %s" % (length, checkConstraint) def _sqliteType(self): |