sqlobject-cvs Mailing List for SQLObject (Page 168)
SQLObject is a Python ORM.
Brought to you by:
ianbicking,
phd
You can subscribe to this list here.
| 2003 |
Jan
|
Feb
|
Mar
(9) |
Apr
(74) |
May
(29) |
Jun
(16) |
Jul
(28) |
Aug
(10) |
Sep
(57) |
Oct
(9) |
Nov
(29) |
Dec
(12) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2004 |
Jan
(7) |
Feb
(14) |
Mar
(6) |
Apr
(3) |
May
(12) |
Jun
(34) |
Jul
(9) |
Aug
(29) |
Sep
(22) |
Oct
(2) |
Nov
(15) |
Dec
(52) |
| 2005 |
Jan
(47) |
Feb
(78) |
Mar
(14) |
Apr
(35) |
May
(33) |
Jun
(16) |
Jul
(26) |
Aug
(63) |
Sep
(40) |
Oct
(96) |
Nov
(96) |
Dec
(123) |
| 2006 |
Jan
(159) |
Feb
(144) |
Mar
(64) |
Apr
(31) |
May
(88) |
Jun
(48) |
Jul
(16) |
Aug
(64) |
Sep
(87) |
Oct
(92) |
Nov
(56) |
Dec
(76) |
| 2007 |
Jan
(94) |
Feb
(103) |
Mar
(126) |
Apr
(123) |
May
(85) |
Jun
(11) |
Jul
(130) |
Aug
(47) |
Sep
(65) |
Oct
(70) |
Nov
(12) |
Dec
(11) |
| 2008 |
Jan
(30) |
Feb
(55) |
Mar
(88) |
Apr
(20) |
May
(50) |
Jun
|
Jul
(38) |
Aug
(1) |
Sep
(9) |
Oct
(5) |
Nov
(6) |
Dec
(39) |
| 2009 |
Jan
(8) |
Feb
(16) |
Mar
(3) |
Apr
(33) |
May
(44) |
Jun
(1) |
Jul
(10) |
Aug
(33) |
Sep
(74) |
Oct
(22) |
Nov
|
Dec
(15) |
| 2010 |
Jan
(28) |
Feb
(22) |
Mar
(46) |
Apr
(29) |
May
(1) |
Jun
(1) |
Jul
(27) |
Aug
(8) |
Sep
(5) |
Oct
(33) |
Nov
(24) |
Dec
(41) |
| 2011 |
Jan
(4) |
Feb
(12) |
Mar
(35) |
Apr
(29) |
May
(19) |
Jun
(16) |
Jul
(32) |
Aug
(25) |
Sep
(5) |
Oct
(11) |
Nov
(21) |
Dec
(12) |
| 2012 |
Jan
(3) |
Feb
(4) |
Mar
(20) |
Apr
(4) |
May
(25) |
Jun
(13) |
Jul
|
Aug
|
Sep
(2) |
Oct
(25) |
Nov
(9) |
Dec
(1) |
| 2013 |
Jan
(6) |
Feb
(8) |
Mar
|
Apr
(10) |
May
(31) |
Jun
(7) |
Jul
(18) |
Aug
(33) |
Sep
(4) |
Oct
(16) |
Nov
|
Dec
(27) |
| 2014 |
Jan
(2) |
Feb
|
Mar
|
Apr
(11) |
May
(39) |
Jun
(8) |
Jul
(11) |
Aug
(4) |
Sep
|
Oct
(27) |
Nov
|
Dec
(71) |
| 2015 |
Jan
(17) |
Feb
(47) |
Mar
(33) |
Apr
|
May
|
Jun
(9) |
Jul
(7) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(8) |
| 2016 |
Jan
(4) |
Feb
(4) |
Mar
|
Apr
|
May
(12) |
Jun
(7) |
Jul
(9) |
Aug
(31) |
Sep
(8) |
Oct
(3) |
Nov
(15) |
Dec
(1) |
| 2017 |
Jan
(13) |
Feb
(7) |
Mar
(14) |
Apr
(8) |
May
(10) |
Jun
(4) |
Jul
(2) |
Aug
(1) |
Sep
|
Oct
(8) |
Nov
(4) |
Dec
(5) |
| 2018 |
Jan
(2) |
Feb
(8) |
Mar
|
Apr
(4) |
May
|
Jun
(6) |
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
(1) |
Dec
|
| 2019 |
Jan
(1) |
Feb
(16) |
Mar
(1) |
Apr
(3) |
May
(5) |
Jun
(1) |
Jul
|
Aug
|
Sep
(2) |
Oct
|
Nov
(1) |
Dec
(3) |
| 2020 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
(1) |
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
(2) |
Nov
|
Dec
(2) |
| 2021 |
Jan
|
Feb
(2) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
(1) |
Dec
|
| 2022 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(6) |
Oct
(1) |
Nov
(1) |
Dec
(4) |
| 2023 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
(3) |
Sep
(2) |
Oct
(2) |
Nov
(4) |
Dec
|
| 2024 |
Jan
|
Feb
(2) |
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
(9) |
| 2025 |
Jan
|
Feb
(4) |
Mar
(2) |
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
(2) |
Dec
(2) |
|
From: <sub...@co...> - 2005-03-29 16:30:26
|
Author: phd Date: 2005-03-29 16:30:20 +0000 (Tue, 29 Mar 2005) New Revision: 691 Modified: trunk/SQLObject/sqlobject/__init__.py Log: Applied patch 1162265. Modified: trunk/SQLObject/sqlobject/__init__.py =================================================================== --- trunk/SQLObject/sqlobject/__init__.py 2005-03-29 15:52:06 UTC (rev 690) +++ trunk/SQLObject/sqlobject/__init__.py 2005-03-29 16:30:20 UTC (rev 691) @@ -1,6 +1,6 @@ from main import * from col import * -from sqlbuilder import AND, OR, NOT, IN, LIKE, CONTAINSSTRING, const, func +from sqlbuilder import AND, OR, NOT, IN, LIKE, DESC, CONTAINSSTRING, const, func from styles import * from joins import * from index import * |
|
From: <sub...@co...> - 2005-03-29 15:52:14
|
Author: phd
Date: 2005-03-29 15:52:06 +0000 (Tue, 29 Mar 2005)
New Revision: 690
Modified:
trunk/SQLObject/sqlobject/col.py
Log:
Applied patch 1157423.
Modified: trunk/SQLObject/sqlobject/col.py
===================================================================
--- trunk/SQLObject/sqlobject/col.py 2005-03-27 19:37:29 UTC (rev 689)
+++ trunk/SQLObject/sqlobject/col.py 2005-03-29 15:52:06 UTC (rev 690)
@@ -482,13 +482,17 @@
class BoolValidator(validators.Validator):
def fromPython(self, value, state):
- if value:
+ if value is None:
+ return None
+ elif value:
return sqlbuilder.TRUE
else:
return sqlbuilder.FALSE
def toPython(self, value, state):
- if not value:
+ if value is None:
+ return None
+ elif not value:
return sqlbuilder.FALSE
else:
return sqlbuilder.TRUE
|
|
From: <sub...@co...> - 2005-03-27 19:37:40
|
Author: ianb
Date: 2005-03-27 19:37:29 +0000 (Sun, 27 Mar 2005)
New Revision: 689
Added:
trunk/SQLObject/sqlobject/tests/test_conngetter.py
Modified:
trunk/SQLObject/sqlobject/classregistry.py
trunk/SQLObject/sqlobject/dbconnection.py
trunk/SQLObject/sqlobject/tests/dbtest.py
Log:
* Allow keyword arguments to connectionForURI (and pass through from dbtest.getConnection)
* Add callback to registry that is called for all classes
* Wrappers added to dbconnection instances that create a psuedo-class that is bound to a connection
Modified: trunk/SQLObject/sqlobject/classregistry.py
===================================================================
--- trunk/SQLObject/sqlobject/classregistry.py 2005-03-25 17:39:04 UTC (rev 688)
+++ trunk/SQLObject/sqlobject/classregistry.py 2005-03-27 19:37:29 UTC (rev 689)
@@ -46,6 +46,7 @@
self.name = name
self.classes = {}
self.callbacks = {}
+ self.genericCallbacks = []
def addClassCallback(self, className, callback, *args, **kw):
"""
@@ -59,6 +60,15 @@
else:
self.callbacks.setdefault(className, []).append((callback, args, kw))
+ def addCallback(self, callback, *args, **kw):
+ """
+ This callback is called for all classes, not just specific
+ ones (like addClassCallback).
+ """
+ self.genericCallbacks.append((callback, args, kw))
+ for cls in self.classes.values():
+ callback(cls, *args, **kw)
+
def addClass(self, cls):
"""
Everytime a class is created, we add it to the registry, so
@@ -84,6 +94,8 @@
for callback, args, kw in self.callbacks[cls.__name__]:
callback(cls, *args, **kw)
del self.callbacks[cls.__name__]
+ for callback, args, kw in self.genericCallbacks:
+ callback(cls, *args, **kw)
def getClass(self, className):
return self.classes[className]
Modified: trunk/SQLObject/sqlobject/dbconnection.py
===================================================================
--- trunk/SQLObject/sqlobject/dbconnection.py 2005-03-25 17:39:04 UTC (rev 688)
+++ trunk/SQLObject/sqlobject/dbconnection.py 2005-03-27 19:37:29 UTC (rev 689)
@@ -8,14 +8,16 @@
import atexit
import os
import new
+import types
+import urllib
+import weakref
+import inspect
import sqlbuilder
from cache import CacheSet
import col
from joins import sorter
from converters import sqlrepr
-import urllib
-import weakref
-from classregistry import findClass
+import classregistry
warnings.filterwarnings("ignore", "DB-API extension cursor.lastrowid used")
@@ -30,7 +32,7 @@
def __init__(self, name=None, debug=False, debugOutput=False,
cache=True, style=None, autoCommit=True,
- debugThreading=False):
+ debugThreading=False, registry=None):
self.name = name
self.debug = debug
self.debugOutput = debugOutput
@@ -41,6 +43,9 @@
self._connectionNumbers = {}
self._connectionCount = 1
self.autoCommit = autoCommit
+ self.registry = registry or None
+ classregistry.registry(self.registry).addCallback(
+ self.soClassAdded)
registerConnectionInstance(self)
atexit.register(_closeConnection, weakref.ref(self))
@@ -119,6 +124,75 @@
return user, password, host, port, path, args
_parseURI = staticmethod(_parseURI)
+ def soClassAdded(self, soClass):
+ """
+ This is called for each new class; we use this opportunity
+ to create an instance method that is bound to the class
+ and this connection.
+ """
+ name = soClass.__name__
+ assert not hasattr(self, name), (
+ "Connection %r already has an attribute with the name "
+ "%r (and you just created the conflicting class %r)"
+ % (self, name, soClass))
+ setattr(self, name, ConnWrapper(soClass, self))
+
+class ConnWrapper(object):
+
+ """
+ This represents a SQLObject class that is bound to a specific
+ connection (instances have a connection instance variable, but
+ classes are global, so this is binds the connection variable
+ lazily when a class method is accessed)
+ """
+ # @@: methods that take connection arguments should be explicitly
+ # marked up instead of the implicit use of a connection argument
+ # and inspect.getargspec()
+
+ def __init__(self, soClass, connection):
+ self._soClass = soClass
+ self._connection = connection
+
+ def __call__(self, *args, **kw):
+ kw['connection'] = self._connection
+ return self._soClass(*args, **kw)
+
+ def __getattr__(self, attr):
+ meth = getattr(self._soClass, attr)
+ if not isinstance(meth, types.MethodType):
+ # We don't need to wrap non-methods
+ return meth
+ try:
+ takes_conn = meth.takes_connection
+ except AttributeError:
+ args, varargs, varkw, defaults = inspect.getargspec(meth)
+ assert not varkw and not varargs, (
+ "I cannot tell whether I must wrap this method, "
+ "because it takes **kw: %r"
+ % meth)
+ takes_conn = 'connection' in args
+ meth.im_func.takes_connection = takes_conn
+ if not takes_conn:
+ return meth
+ return ConnMethodWrapper(meth, self._connection)
+
+class ConnMethodWrapper(object):
+
+ def __init__(self, method, connection):
+ self._method = method
+ self._connection = connection
+
+ def __getattr__(self, attr):
+ return getattr(self._method, attr)
+
+ def __call__(self, *args, **kw):
+ kw['connection'] = self._connection
+ return self._method(*args, **kw)
+
+ def __repr__(self):
+ return '<Wrapped %r with connection %r>' % (
+ self._method, self._connection)
+
class DBAPI(DBConnection):
"""
@@ -627,7 +701,10 @@
try:
func = attr.im_func
except AttributeError:
- return attr
+ if isinstance(attr, ConnWrapper):
+ return ConnWrapper(attr._soClass, self)
+ else:
+ return attr
else:
meth = new.instancemethod(func, self, self.__class__)
return meth
@@ -674,13 +751,18 @@
assert inst.name.find(':') == -1, "You cannot include ':' in your class names (%r)" % cls.name
self.instanceNames[inst.name] = inst
- def connectionForURI(self, uri):
+ def connectionForURI(self, uri, **args):
+ if args:
+ if '?' not in uri:
+ uri += '?'
+ uri += urllib.urlencode(args)
if self.cachedURIs.has_key(uri):
return self.cachedURIs[uri]
if uri.find(':') != -1:
scheme, rest = uri.split(':', 1)
- assert self.schemeBuilders.has_key(scheme), \
- "No SQLObject driver exists for %s" % scheme
+ assert self.schemeBuilders.has_key(scheme), (
+ "No SQLObject driver exists for %s (only %s)"
+ % (scheme, ', '.join(self.schemeBuilders.keys())))
conn = self.schemeBuilders[scheme]().connectionFromURI(uri)
else:
# We just have a name, not a URI
Modified: trunk/SQLObject/sqlobject/tests/dbtest.py
===================================================================
--- trunk/SQLObject/sqlobject/tests/dbtest.py 2005-03-25 17:39:04 UTC (rev 688)
+++ trunk/SQLObject/sqlobject/tests/dbtest.py 2005-03-27 19:37:29 UTC (rev 689)
@@ -69,12 +69,12 @@
installedDBTracker = sqlobject.connectionForURI(
'sqlite:///' + installedDBFilename)
-def getConnection():
+def getConnection(**kw):
name = os.environ.get('TESTDB')
assert name, 'You must set $TESTDB to do database operations'
if connectionShortcuts.has_key(name):
name = connectionShortcuts[name]
- return sqlobject.connectionForURI(name)
+ return sqlobject.connectionForURI(name, **kw)
connection = getConnection()
Added: trunk/SQLObject/sqlobject/tests/test_conngetter.py
===================================================================
--- trunk/SQLObject/sqlobject/tests/test_conngetter.py 2005-03-25 17:39:04 UTC (rev 688)
+++ trunk/SQLObject/sqlobject/tests/test_conngetter.py 2005-03-27 19:37:29 UTC (rev 689)
@@ -0,0 +1,37 @@
+from sqlobject import *
+from sqlobject.tests.dbtest import *
+
+class TestSimple(SQLObject):
+
+ class sqlmeta:
+ registry = 'conngetter'
+
+ name = StringCol(alternateID=True)
+
+class TestJoined(SQLObject):
+
+ class sqlmeta:
+ registry = 'conngetter'
+
+ this_name = StringCol(alternateID=True)
+ simple = ForeignKey('TestSimple')
+
+def test_autogetter():
+ conn = getConnection(registry='conngetter')
+ TestJoined.dropTable(connection=conn, ifExists=True)
+ TestSimple.dropTable(connection=conn, ifExists=True)
+ TestSimple.createTable(connection=conn, ifNotExists=True)
+ TestJoined.createTable(connection=conn, ifNotExists=True)
+ assert conn.TestSimple.__sqlobject_class__ is TestSimple
+ obj = conn.TestSimple(name='test')
+ assert (TestSimple.get(obj.id, connection=conn) is obj)
+ assert obj._connection is conn
+ obj2 = TestSimple(name='test2', connection=conn)
+ assert (conn.TestSimple.byName('test2') is obj2)
+ joined = conn.TestJoined(this_name='join_test', simple=obj)
+ assert joined.simple is obj
+ assert joined.simple._connection is conn
+ assert joined._connection is conn
+ for item in conn.TestSimple.select():
+ assert item._connection is conn
+
|
|
From: <sub...@co...> - 2005-03-03 12:15:32
|
Author: phd
Date: 2005-03-03 12:15:10 +0000 (Thu, 03 Mar 2005)
New Revision: 663
Modified:
trunk/SQLObject/sqlobject/mysql/mysqlconnection.py
Log:
Added _setAutoCommit().
Modified: trunk/SQLObject/sqlobject/mysql/mysqlconnection.py
===================================================================
--- trunk/SQLObject/sqlobject/mysql/mysqlconnection.py 2005-03-03 12:12:15 UTC (rev 662)
+++ trunk/SQLObject/sqlobject/mysql/mysqlconnection.py 2005-03-03 12:15:10 UTC (rev 663)
@@ -41,6 +41,10 @@
return conn
+ def _setAutoCommit(self, conn, auto):
+ if hasattr(conn, 'autocommit'):
+ conn.autocommit(auto)
+
def _executeRetry(self, conn, cursor, query):
while 1:
try:
|
|
From: <sub...@co...> - 2005-03-03 12:12:25
|
Author: phd Date: 2005-03-03 12:12:15 +0000 (Thu, 03 Mar 2005) New Revision: 662 Modified: trunk/SQLObject/sqlobject/mysql/mysqlconnection.py Log: Fixed the bug https://sourceforge.net/tracker/index.php?func=detail&aid=1150183&group_id=74338&atid=540672 Modified makeConnection and set autocommit if it's supported. Modified: trunk/SQLObject/sqlobject/mysql/mysqlconnection.py =================================================================== --- trunk/SQLObject/sqlobject/mysql/mysqlconnection.py 2005-03-01 23:09:06 UTC (rev 661) +++ trunk/SQLObject/sqlobject/mysql/mysqlconnection.py 2005-03-03 12:12:15 UTC (rev 662) @@ -27,9 +27,20 @@ connectionFromURI = classmethod(connectionFromURI) def makeConnection(self): - return MySQLdb.connect(host=self.host, port=self.port, db=self.db, - user=self.user, passwd=self.password) + try: + conn = self.module.connect(host=self.host, port=self.port, + db=self.db, user=self.user, passwd=self.password) + except self.module.OperationalError, e: + raise self.module.OperationalError( + "%s; used connection string: host=%s, port=%s, db=%s, user=%s, pwd=%s" % ( + e, self.host, self.port, self.db, self.user, self.password) + ) + if hasattr(conn, 'autocommit'): + conn.autocommit(self.autoCommit) + + return conn + def _executeRetry(self, conn, cursor, query): while 1: try: |
|
From: <sub...@co...> - 2005-03-01 18:04:53
|
Author: phd
Date: 2005-03-01 18:04:32 +0000 (Tue, 01 Mar 2005)
New Revision: 660
Modified:
trunk/SQLObject/sqlobject/mysql/mysqlconnection.py
Log:
Fixed a bug in MySQLconnection - default port is indicated by 0, not ''.
Modified: trunk/SQLObject/sqlobject/mysql/mysqlconnection.py
===================================================================
--- trunk/SQLObject/sqlobject/mysql/mysqlconnection.py 2005-03-01 14:52:06 UTC (rev 659)
+++ trunk/SQLObject/sqlobject/mysql/mysqlconnection.py 2005-03-01 18:04:32 UTC (rev 660)
@@ -23,7 +23,7 @@
def connectionFromURI(cls, uri):
user, password, host, port, path, args = cls._parseURI(uri)
return cls(db=path.strip('/'), user=user or '', passwd=password or '',
- host=host or 'localhost', port=port or '', **args)
+ host=host or 'localhost', port=port or 0, **args)
connectionFromURI = classmethod(connectionFromURI)
def makeConnection(self):
|
|
From: <sub...@co...> - 2005-03-01 14:52:09
|
Author: phd Date: 2005-03-01 14:52:06 +0000 (Tue, 01 Mar 2005) New Revision: 659 Modified: trunk/SQLObject/docs/FAQ.txt trunk/SQLObject/docs/SQLObjectCustomization.txt trunk/SQLObject/docs/SQLObjectLegacy.txt trunk/SQLObject/docs/SQLObjectUse.txt Log: Fixed https://sourceforge.net/tracker/index.php?func=detail&aid=1072399&group_id=74338&atid=540672 - all mentions of .new() replaced with constructors. Modified: trunk/SQLObject/docs/FAQ.txt =================================================================== --- trunk/SQLObject/docs/FAQ.txt 2005-03-01 14:22:14 UTC (rev 658) +++ trunk/SQLObject/docs/FAQ.txt 2005-03-01 14:52:06 UTC (rev 659) @@ -159,7 +159,7 @@ ``CREATE TABLE`` generation (i.e., ``createTable``). You also will have to give your own ID values when creating an object, like:: - color = Something.new(id="blue", r=0, b=100, g=0) + color = Something(id="blue", r=0, b=100, g=0) IDs are, and always will in future versions, be considered immutable. Right now that is not enforced; you can assign to the ``id`` Modified: trunk/SQLObject/docs/SQLObjectCustomization.txt =================================================================== --- trunk/SQLObject/docs/SQLObjectCustomization.txt 2005-03-01 14:22:14 UTC (rev 658) +++ trunk/SQLObject/docs/SQLObjectCustomization.txt 2005-03-01 14:52:06 UTC (rev 659) @@ -41,8 +41,8 @@ keep in files as opposed to the database (such as large, opaque data like images). -You can also pass an ``image`` keyword argument to the `new` class -method or the `set` method, like ``Person.new(..., image=imageText)``. +You can also pass an ``image`` keyword argument to the constructor +or the `set` method, like ``Person(..., image=imageText)``. All of the methods (``_get_``, ``_set_``, etc) are optional -- you can use any one of them without using the others (except ``_doc_``, since Modified: trunk/SQLObject/docs/SQLObjectLegacy.txt =================================================================== --- trunk/SQLObject/docs/SQLObjectLegacy.txt 2005-03-01 14:22:14 UTC (rev 658) +++ trunk/SQLObject/docs/SQLObjectLegacy.txt 2005-03-01 14:52:06 UTC (rev 659) @@ -93,4 +93,4 @@ category of "irregularities". If you use non-integer keys, all primary key management is up to you. You must create the table yourself, and when you create instances you must pass a ``id`` keyword -argument into ``new`` (like ``Person.new(id='555-55-5555', ...)``). +argument into constructor (like ``Person(id='555-55-5555', ...)``). Modified: trunk/SQLObject/docs/SQLObjectUse.txt =================================================================== --- trunk/SQLObject/docs/SQLObjectUse.txt 2005-03-01 14:22:14 UTC (rev 658) +++ trunk/SQLObject/docs/SQLObjectUse.txt 2005-03-01 14:52:06 UTC (rev 659) @@ -16,7 +16,7 @@ method fetches a row. To create a new object (and row), use class instantiation. In this -case you might call ``Person.new(firstName="John", lastName="Doe")``. +case you might call ``Person(firstName="John", lastName="Doe")``. If you had left out ``firstName`` or ``lastName`` you would have gotten an error, as no default was given for these columns (``middleInitial`` has a default, so it will be set to ``NULL``, the |
|
From: <sub...@co...> - 2005-03-01 14:22:44
|
Author: phd Date: 2005-03-01 14:22:14 +0000 (Tue, 01 Mar 2005) New Revision: 658 Modified: trunk/SQLObject/sqlobject/dbconnection.py trunk/SQLObject/sqlobject/tests/test_basic.py Log: Fixed bug https://sourceforge.net/tracker/index.php?func=detail&aid=1012150&group_id=74338&atid=540672. Foo.selectBy(column=None) now issues '... column IS NULL'. Modified: trunk/SQLObject/sqlobject/dbconnection.py =================================================================== --- trunk/SQLObject/sqlobject/dbconnection.py 2005-03-01 13:04:43 UTC (rev 657) +++ trunk/SQLObject/sqlobject/dbconnection.py 2005-03-01 14:22:14 UTC (rev 658) @@ -478,10 +478,11 @@ self.sqlrepr(secondValue))) def _SO_columnClause(self, soClass, kw): + ops = {None: "IS"} return ' AND '.join( - ['%s = %s' % + ['%s %s %s' % (soClass.sqlmeta._columnDict[key].dbName, - self.sqlrepr(value)) + ops.get(value, "="), self.sqlrepr(value)) for key, value in kw.items()]) Modified: trunk/SQLObject/sqlobject/tests/test_basic.py =================================================================== --- trunk/SQLObject/sqlobject/tests/test_basic.py 2005-03-01 13:04:43 UTC (rev 657) +++ trunk/SQLObject/sqlobject/tests/test_basic.py 2005-03-01 14:22:14 UTC (rev 658) @@ -34,6 +34,7 @@ def test_count(): setupGetters(TestSO1) + assert TestSO1.selectBy(name=None).count() == 0 assert TestSO1.selectBy(name='bob').count() == 1 assert TestSO1.select(TestSO1.q.name == 'bob').count() == 1 assert TestSO1.select().count() == len(list(TestSO1.select())) |
|
From: <sub...@co...> - 2005-03-01 13:05:08
|
Author: phd
Date: 2005-03-01 13:04:43 +0000 (Tue, 01 Mar 2005)
New Revision: 657
Modified:
trunk/SQLObject/sqlobject/sresults.py
trunk/SQLObject/sqlobject/tests/test_minmax.py
Log:
accumulateMany() usage is now even simpler: select.accumulateMany(*atributes).
Modified: trunk/SQLObject/sqlobject/sresults.py
===================================================================
--- trunk/SQLObject/sqlobject/sresults.py 2005-03-01 09:40:03 UTC (rev 656)
+++ trunk/SQLObject/sqlobject/sresults.py 2005-03-01 13:04:43 UTC (rev 657)
@@ -1,6 +1,8 @@
import sqlbuilder
import dbconnection
+StringType = type('')
+
class SelectResults(object):
IterationClass = dbconnection.Iteration
@@ -147,41 +149,39 @@
count = min(self.ops['end'] - self.ops.get('start', 0), count)
return count
- def _accumulateOne(self, func_name, attribute):
+ def accumulateMany(self, *attributes):
+ """ Making the expressions for count/sum/min/max/avg
+ of a given select result attributes.
+ `attributes` must be a list/tuple of pairs (func_name, attribute);
+ `attribute` can be a column name (like 'a_column')
+ or a dot-q attribute (like Table.q.aColumn)
+ """
+ expressions = []
+ for func_name, attribute in attributes:
+ if type(attribute) == StringType:
+ expression = '%s(%s)' % (func_name, attribute)
+ else:
+ expression = getattr(sqlbuilder.func, func_name)(attribute)
+ expressions.append(expression)
+ return self.accumulate(*expressions)
+
+ def accumulateOne(self, func_name, attribute):
""" Making the sum/min/max/avg of a given select result attribute.
`attribute` can be a column name (like 'a_column')
or a dot-q attribute (like Table.q.aColumn)
"""
- return self.accumulate(*accumulateMany((func_name, attribute)))
+ return self.accumulateMany((func_name, attribute))
def sum(self, attribute):
- return self._accumulateOne("SUM", attribute)
+ return self.accumulateOne("SUM", attribute)
def min(self, attribute):
- return self._accumulateOne("MIN", attribute)
+ return self.accumulateOne("MIN", attribute)
def avg(self, attribute):
- return self._accumulateOne("AVG", attribute)
+ return self.accumulateOne("AVG", attribute)
def max(self, attribute):
- return self._accumulateOne("MAX", attribute)
+ return self.accumulateOne("MAX", attribute)
-StringType = type('')
-
-def accumulateMany(*attributes):
- """ Making the expressions for sum/min/max/avg
- of a given select result attributes.
- `attributes` must be a list/tuple of pairs (func_name, attribute);
- `attribute` can be a column name (like 'a_column')
- or a dot-q attribute (like Table.q.aColumn)
- """
- expressions = []
- for func_name, attribute in attributes:
- if type(attribute) == StringType:
- expression = '%s(%s)' % (func_name, attribute)
- else:
- expression = getattr(sqlbuilder.func, func_name)(attribute)
- expressions.append(expression)
- return expressions
-
-__all__ = ['SelectResults', 'accumulateMany']
+__all__ = ['SelectResults']
Modified: trunk/SQLObject/sqlobject/tests/test_minmax.py
===================================================================
--- trunk/SQLObject/sqlobject/tests/test_minmax.py 2005-03-01 09:40:03 UTC (rev 656)
+++ trunk/SQLObject/sqlobject/tests/test_minmax.py 2005-03-01 13:04:43 UTC (rev 657)
@@ -1,5 +1,4 @@
from sqlobject import *
-from sqlobject.sresults import *
from sqlobject.tests.dbtest import *
# Test MIN, AVG, MAX, SUM
@@ -55,5 +54,6 @@
select = IntAccumulator.select()
attribute = IntAccumulator.q.value
- expression = accumulateMany(("MIN", attribute), ("AVG", attribute), ("MAX", attribute))
- assert select.accumulate(*expression) == (1, 2, 3)
+ assert select.accumulateMany(
+ ("MIN", attribute), ("AVG", attribute), ("MAX", attribute)
+ ) == (1, 2, 3)
|
|
From: <sub...@co...> - 2005-03-01 09:40:24
|
Author: phd
Date: 2005-03-01 09:40:03 +0000 (Tue, 01 Mar 2005)
New Revision: 656
Modified:
trunk/SQLObject/sqlobject/dbconnection.py
trunk/SQLObject/sqlobject/sresults.py
trunk/SQLObject/sqlobject/tests/test_minmax.py
Log:
Changed the way accumalte functions work.
Now you can accumulate a list of functions at once:
select.accumulate(*accumulateMany(("MIN", attribute), ("MAX", attribute))).
Modified: trunk/SQLObject/sqlobject/dbconnection.py
===================================================================
--- trunk/SQLObject/sqlobject/dbconnection.py 2005-03-01 09:35:22 UTC (rev 655)
+++ trunk/SQLObject/sqlobject/dbconnection.py 2005-03-01 09:40:03 UTC (rev 656)
@@ -264,14 +264,16 @@
return select.IterationClass(self, self.getConnection(),
select, keepConnection=False)
- def accumulateSelect(self, select, expression):
- """ Apply an accumulate function (SUM, COUNT, MIN, AVG, MAX, etc...)
+ def accumulateSelect(self, select, *expressions):
+ """ Apply an accumulate function(s) (SUM, COUNT, MIN, AVG, MAX, etc...)
to the select object.
"""
- q = "SELECT %s" % expression
+ q = "SELECT %s" % ", ".join([str(expression) for expression in expressions])
q += " FROM %s WHERE" % ", ".join(select.tables)
q = self._addWhereClause(select, q, limit=0, order=0)
- val = self.queryOne(q)[0]
+ val = self.queryOne(q)
+ if len(expressions) == 1:
+ val = val[0]
return val
def queryForSelect(self, select):
Modified: trunk/SQLObject/sqlobject/sresults.py
===================================================================
--- trunk/SQLObject/sqlobject/sresults.py 2005-03-01 09:35:22 UTC (rev 655)
+++ trunk/SQLObject/sqlobject/sresults.py 2005-03-01 09:40:03 UTC (rev 656)
@@ -127,14 +127,14 @@
conn = self.ops.get('connection', self.sourceClass._connection)
return conn.iterSelect(self)
- def accumulate(self, expression):
- """ Use an accumulate expression to select result
+ def accumulate(self, *expressions):
+ """ Use accumulate expression(s) to select result
using another SQL select through current
connection.
Return the accumulate result
"""
conn = self.ops.get('connection', self.sourceClass._connection)
- return conn.accumulateSelect(self, expression)
+ return conn.accumulateSelect(self, *expressions)
def count(self):
""" Counting elements of current select results """
@@ -147,48 +147,41 @@
count = min(self.ops['end'] - self.ops.get('start', 0), count)
return count
- def sum(self, attribute):
- """ Making the sum of a given select result attribute.
+ def _accumulateOne(self, func_name, attribute):
+ """ Making the sum/min/max/avg of a given select result attribute.
`attribute` can be a column name (like 'a_column')
or a dot-q attribute (like Table.q.aColumn)
"""
- if type(attribute) == type(''):
- expression = 'SUM(%s)' % attribute
- else:
- expression = sqlbuilder.func.SUM(attribute)
- return self.accumulate(expression)
+ return self.accumulate(*accumulateMany((func_name, attribute)))
+ def sum(self, attribute):
+ return self._accumulateOne("SUM", attribute)
+
def min(self, attribute):
- """ Giving the min of a given select result attribute.
- `attribute` can be a column name (like 'a_column')
- or a dot-q attribute (like Table.q.aColumn)
- """
- if type(attribute) == type(''):
- expression = 'MIN(%s)' % attribute
- else:
- expression = sqlbuilder.func.MIN(attribute)
- return self.accumulate(expression)
+ return self._accumulateOne("MIN", attribute)
def avg(self, attribute):
- """ Giving the average of a given select result attribute.
- `attribute` can be a column name (like 'a_column')
- or a dot-q attribute (like Table.q.aColumn)
- """
- if type(attribute) == type(''):
- expression = 'AVG(%s)' % attribute
- else:
- expression = sqlbuilder.func.AVG(attribute)
- return self.accumulate(expression)
+ return self._accumulateOne("AVG", attribute)
def max(self, attribute):
- """ Giving the max of a given select result attribute.
- `attribute` can be a column name (like 'a_column')
- or a dot-q attribute (like Table.q.aColumn)
- """
- if type(attribute) == type(''):
- expression = 'MAX(%s)' % attribute
+ return self._accumulateOne("MAX", attribute)
+
+StringType = type('')
+
+def accumulateMany(*attributes):
+ """ Making the expressions for sum/min/max/avg
+ of a given select result attributes.
+ `attributes` must be a list/tuple of pairs (func_name, attribute);
+ `attribute` can be a column name (like 'a_column')
+ or a dot-q attribute (like Table.q.aColumn)
+ """
+ expressions = []
+ for func_name, attribute in attributes:
+ if type(attribute) == StringType:
+ expression = '%s(%s)' % (func_name, attribute)
else:
- expression = sqlbuilder.func.MAX(attribute)
- return self.accumulate(expression)
+ expression = getattr(sqlbuilder.func, func_name)(attribute)
+ expressions.append(expression)
+ return expressions
-__all__ = ['SelectResults']
+__all__ = ['SelectResults', 'accumulateMany']
Modified: trunk/SQLObject/sqlobject/tests/test_minmax.py
===================================================================
--- trunk/SQLObject/sqlobject/tests/test_minmax.py 2005-03-01 09:35:22 UTC (rev 655)
+++ trunk/SQLObject/sqlobject/tests/test_minmax.py 2005-03-01 09:40:03 UTC (rev 656)
@@ -1,4 +1,5 @@
from sqlobject import *
+from sqlobject.sresults import *
from sqlobject.tests.dbtest import *
# Test MIN, AVG, MAX, SUM
@@ -44,3 +45,15 @@
assert floatcmp(FloatAccumulator.select().avg(FloatAccumulator.q.value), 2.5) == 0
assert floatcmp(FloatAccumulator.select().max(FloatAccumulator.q.value), 3.8) == 0
assert floatcmp(FloatAccumulator.select().sum(FloatAccumulator.q.value), 7.4) == 0
+
+
+def test_many():
+ setupClass(IntAccumulator)
+ IntAccumulator(value=1)
+ IntAccumulator(value=2)
+ IntAccumulator(value=3)
+
+ select = IntAccumulator.select()
+ attribute = IntAccumulator.q.value
+ expression = accumulateMany(("MIN", attribute), ("AVG", attribute), ("MAX", attribute))
+ assert select.accumulate(*expression) == (1, 2, 3)
|
|
From: <sub...@co...> - 2005-02-27 19:32:13
|
Author: phd
Date: 2005-02-27 19:32:06 +0000 (Sun, 27 Feb 2005)
New Revision: 652
Modified:
trunk/SQLObject/sqlobject/dbconnection.py
trunk/SQLObject/sqlobject/tests/test_minmax.py
Log:
Some statistical functions (MIN, AVG, MAX) may return fload result.
Added tests for float functions.
Modified: trunk/SQLObject/sqlobject/dbconnection.py
===================================================================
--- trunk/SQLObject/sqlobject/dbconnection.py 2005-02-26 13:09:20 UTC (rev 651)
+++ trunk/SQLObject/sqlobject/dbconnection.py 2005-02-27 19:32:06 UTC (rev 652)
@@ -265,15 +265,13 @@
select, keepConnection=False)
def accumulateSelect(self, select, expression):
- """ Apply an accumulate function (like SUM, COUNT, ..)
+ """ Apply an accumulate function (SUM, COUNT, MIN, AVG, MAX, etc...)
to the select object.
- Return the value resulting from the SQL accumulate function
- as an integer.
"""
q = "SELECT %s" % expression
q += " FROM %s WHERE" % ", ".join(select.tables)
q = self._addWhereClause(select, q, limit=0, order=0)
- val = int(self.queryOne(q)[0])
+ val = self.queryOne(q)[0]
return val
def queryForSelect(self, select):
Modified: trunk/SQLObject/sqlobject/tests/test_minmax.py
===================================================================
--- trunk/SQLObject/sqlobject/tests/test_minmax.py 2005-02-26 13:09:20 UTC (rev 651)
+++ trunk/SQLObject/sqlobject/tests/test_minmax.py 2005-02-27 19:32:06 UTC (rev 652)
@@ -3,19 +3,44 @@
# Test MIN, AVG, MAX, SUM
-class Accumulator(SQLObject):
+
+class IntAccumulator(SQLObject):
value = IntCol()
-def test_minmax():
- setupClass(Accumulator)
- Accumulator(value=1)
- Accumulator(value=2)
- Accumulator(value=3)
- assert Accumulator.select().min(Accumulator.q.value) == 1
- assert Accumulator.select().avg(Accumulator.q.value) == 2
- assert Accumulator.select().max(Accumulator.q.value) == 3
- assert Accumulator.select().sum(Accumulator.q.value) == 6
+class FloatAccumulator(SQLObject):
+ value = FloatCol()
- assert Accumulator.select(Accumulator.q.value > 1).max(Accumulator.q.value) == 3
- assert Accumulator.select(Accumulator.q.value > 1).sum(Accumulator.q.value) == 5
+
+def test_integer():
+ setupClass(IntAccumulator)
+ IntAccumulator(value=1)
+ IntAccumulator(value=2)
+ IntAccumulator(value=3)
+
+ assert IntAccumulator.select().min(IntAccumulator.q.value) == 1
+ assert IntAccumulator.select().avg(IntAccumulator.q.value) == 2
+ assert IntAccumulator.select().max(IntAccumulator.q.value) == 3
+ assert IntAccumulator.select().sum(IntAccumulator.q.value) == 6
+
+ assert IntAccumulator.select(IntAccumulator.q.value > 1).max(IntAccumulator.q.value) == 3
+ assert IntAccumulator.select(IntAccumulator.q.value > 1).sum(IntAccumulator.q.value) == 5
+
+
+def floatcmp(f1, f2):
+ if abs(f1-f2) < 0.1:
+ return 0
+ if f1 < f2:
+ return 1
+ return -1
+
+def test_float():
+ setupClass(FloatAccumulator)
+ FloatAccumulator(value=1.2)
+ FloatAccumulator(value=2.4)
+ FloatAccumulator(value=3.8)
+
+ assert floatcmp(FloatAccumulator.select().min(FloatAccumulator.q.value), 1.2) == 0
+ assert floatcmp(FloatAccumulator.select().avg(FloatAccumulator.q.value), 2.5) == 0
+ assert floatcmp(FloatAccumulator.select().max(FloatAccumulator.q.value), 3.8) == 0
+ assert floatcmp(FloatAccumulator.select().sum(FloatAccumulator.q.value), 7.4) == 0
|
|
From: <sub...@co...> - 2005-02-26 13:09:27
|
Author: phd
Date: 2005-02-26 13:09:20 +0000 (Sat, 26 Feb 2005)
New Revision: 651
Modified:
trunk/SQLObject/docs/Inheritance.txt
trunk/SQLObject/sqlobject/inheritance/__init__.py
trunk/SQLObject/sqlobject/inheritance/tests/test_inheritance.py
trunk/SQLObject/sqlobject/main.py
Log:
InheritableSQLObject are now inheritable by default -
one does not need to set _inheritable = True.
Tests and documentation were updated.
Modified: trunk/SQLObject/docs/Inheritance.txt
===================================================================
--- trunk/SQLObject/docs/Inheritance.txt 2005-02-25 17:50:40 UTC (rev 650)
+++ trunk/SQLObject/docs/Inheritance.txt 2005-02-26 13:09:20 UTC (rev 651)
@@ -21,13 +21,13 @@
The following code::
- class Person(SQLObject):
- _inheritable = 1 # I want this class to be inherited
+ frim sqlobject.inheritance import InheritableSQLObject
+ class Person(InheritableSQLObject):
firstName = StringCol()
lastName = StringCol()
class Employee(Person):
- _inheritable = 0 # If I don't want this class to be inherited
+ _inheritable = False
position = StringCol()
will generate the following tables::
@@ -128,7 +128,7 @@
* You may not redefine columns in an inherited class (this
will raise an exception).
* If you don't want 'childName' columns in your last class (one that
- will never be inherited), you must set '_inheritable' to 0 in this
+ will never be inherited), you must set '_inheritable' to False in this
class.
* I made it because I needed to be able to have automatic
inheritance with linked table.
@@ -138,4 +138,4 @@
* Thanks to Ian Bicking for SQLObject, this is a wonderful python
module.
* If you have suggestion, bugs, or patch to this patch, you can
- contact me at <sqlobject xsoli.com>
+ contact SQLObject team: <sqlobject-discuss at lists.sourceforge.net>
Modified: trunk/SQLObject/sqlobject/inheritance/__init__.py
===================================================================
--- trunk/SQLObject/sqlobject/inheritance/__init__.py 2005-02-25 17:50:40 UTC (rev 650)
+++ trunk/SQLObject/sqlobject/inheritance/__init__.py 2005-02-26 13:09:20 UTC (rev 651)
@@ -65,6 +65,7 @@
class InheritableSQLObject(SQLObject):
+ _inheritable = True
SelectResultsClass = InheritableSelectResults
def get(cls, id, connection=None, selectResults=None, childResults=None, childUpdate=False):
Modified: trunk/SQLObject/sqlobject/inheritance/tests/test_inheritance.py
===================================================================
--- trunk/SQLObject/sqlobject/inheritance/tests/test_inheritance.py 2005-02-25 17:50:40 UTC (rev 650)
+++ trunk/SQLObject/sqlobject/inheritance/tests/test_inheritance.py 2005-02-26 13:09:20 UTC (rev 651)
@@ -8,12 +8,11 @@
class InherPerson(InheritableSQLObject):
- _inheritable = 1 # I want this class to be inherited
firstName = StringCol()
lastName = StringCol(alternateID=True)
class Employee(InherPerson):
- _inheritable = 0 # If I don't want this class to be inherited
+ _inheritable = False
position = StringCol()
def setup():
Modified: trunk/SQLObject/sqlobject/main.py
===================================================================
--- trunk/SQLObject/sqlobject/main.py 2005-02-25 17:50:40 UTC (rev 650)
+++ trunk/SQLObject/sqlobject/main.py 2005-02-26 13:09:20 UTC (rev 651)
@@ -396,10 +396,11 @@
#DSM: inheritable class. If so, we keep a link to our parent class.
cls._childClasses = {}
for _cls in cls.__bases__:
- if hasattr(_cls, '_inheritable') and _cls._inheritable:
- cls._parentClass = _cls
- cls._parent = None
- _cls._childClasses[cls.__name__] = cls
+ if hasattr(_cls, '_inheritable') and _cls._inheritable and \
+ _cls.__name__ <> "InheritableSQLObject":
+ cls._parentClass = _cls
+ cls._parent = None
+ _cls._childClasses[cls.__name__] = cls
#DSM: If this class is a child of a parent class, we need to do some
#DSM: attribute check and a a foreign key to the parent.
@@ -421,9 +422,11 @@
cls._columns = []
#DSM: If this is inheritable, add some default columns
# to be able to link to children
- if hasattr(cls, '_inheritable') and cls._inheritable:
- cls._columns.append(
- col.StringCol(name='childName',default=None))
+ if hasattr(cls, '_inheritable') and cls._inheritable and \
+ cls.__name__ <> "InheritableSQLObject":
+ cls._columns.append(
+ col.StringCol(name='childName', default=None)
+ )
cls._columns.extend(implicitColumns)
if not new_attrs.has_key('_joins'):
|
|
From: <sub...@co...> - 2005-02-25 17:50:43
|
Author: phd
Date: 2005-02-25 17:50:40 +0000 (Fri, 25 Feb 2005)
New Revision: 650
Added:
trunk/SQLObject/sqlobject/tests/test_minmax.py
Modified:
trunk/SQLObject/sqlobject/sresults.py
Log:
Added min() and max() - patch by michelts <mic...@gm...>.
Added avg() and tests.
Modified: trunk/SQLObject/sqlobject/sresults.py
===================================================================
--- trunk/SQLObject/sqlobject/sresults.py 2005-02-25 15:37:35 UTC (rev 649)
+++ trunk/SQLObject/sqlobject/sresults.py 2005-02-25 17:50:40 UTC (rev 650)
@@ -158,4 +158,37 @@
expression = sqlbuilder.func.SUM(attribute)
return self.accumulate(expression)
+ def min(self, attribute):
+ """ Giving the min of a given select result attribute.
+ `attribute` can be a column name (like 'a_column')
+ or a dot-q attribute (like Table.q.aColumn)
+ """
+ if type(attribute) == type(''):
+ expression = 'MIN(%s)' % attribute
+ else:
+ expression = sqlbuilder.func.MIN(attribute)
+ return self.accumulate(expression)
+
+ def avg(self, attribute):
+ """ Giving the average of a given select result attribute.
+ `attribute` can be a column name (like 'a_column')
+ or a dot-q attribute (like Table.q.aColumn)
+ """
+ if type(attribute) == type(''):
+ expression = 'AVG(%s)' % attribute
+ else:
+ expression = sqlbuilder.func.AVG(attribute)
+ return self.accumulate(expression)
+
+ def max(self, attribute):
+ """ Giving the max of a given select result attribute.
+ `attribute` can be a column name (like 'a_column')
+ or a dot-q attribute (like Table.q.aColumn)
+ """
+ if type(attribute) == type(''):
+ expression = 'MAX(%s)' % attribute
+ else:
+ expression = sqlbuilder.func.MAX(attribute)
+ return self.accumulate(expression)
+
__all__ = ['SelectResults']
Added: trunk/SQLObject/sqlobject/tests/test_minmax.py
===================================================================
--- trunk/SQLObject/sqlobject/tests/test_minmax.py 2005-02-25 15:37:35 UTC (rev 649)
+++ trunk/SQLObject/sqlobject/tests/test_minmax.py 2005-02-25 17:50:40 UTC (rev 650)
@@ -0,0 +1,21 @@
+from sqlobject import *
+from sqlobject.tests.dbtest import *
+
+# Test MIN, AVG, MAX, SUM
+
+class Accumulator(SQLObject):
+ value = IntCol()
+
+def test_minmax():
+ setupClass(Accumulator)
+ Accumulator(value=1)
+ Accumulator(value=2)
+ Accumulator(value=3)
+
+ assert Accumulator.select().min(Accumulator.q.value) == 1
+ assert Accumulator.select().avg(Accumulator.q.value) == 2
+ assert Accumulator.select().max(Accumulator.q.value) == 3
+ assert Accumulator.select().sum(Accumulator.q.value) == 6
+
+ assert Accumulator.select(Accumulator.q.value > 1).max(Accumulator.q.value) == 3
+ assert Accumulator.select(Accumulator.q.value > 1).sum(Accumulator.q.value) == 5
|
|
From: <sub...@co...> - 2005-02-25 15:37:39
|
Author: phd
Date: 2005-02-25 15:37:35 +0000 (Fri, 25 Feb 2005)
New Revision: 649
Modified:
trunk/SQLObject/sqlobject/mysql/mysqlconnection.py
Log:
Fixed bugs with passing port to MySQLdb.
Modified: trunk/SQLObject/sqlobject/mysql/mysqlconnection.py
===================================================================
--- trunk/SQLObject/sqlobject/mysql/mysqlconnection.py 2005-02-25 15:19:35 UTC (rev 648)
+++ trunk/SQLObject/sqlobject/mysql/mysqlconnection.py 2005-02-25 15:37:35 UTC (rev 649)
@@ -8,12 +8,13 @@
dbName = 'mysql'
schemes = [dbName]
- def __init__(self, db, user, passwd='', host='localhost', **kw):
+ def __init__(self, db, user, passwd='', host='localhost', port=None, **kw):
global MySQLdb
if MySQLdb is None:
import MySQLdb
self.module = MySQLdb
self.host = host
+ self.port = port
self.db = db
self.user = user
self.password = passwd
@@ -26,7 +27,7 @@
connectionFromURI = classmethod(connectionFromURI)
def makeConnection(self):
- return MySQLdb.connect(host=self.host, db=self.db,
+ return MySQLdb.connect(host=self.host, port=self.port, db=self.db,
user=self.user, passwd=self.password)
def _executeRetry(self, conn, cursor, query):
|
|
From: <sub...@co...> - 2005-02-25 15:19:44
|
Author: phd
Date: 2005-02-25 15:19:35 +0000 (Fri, 25 Feb 2005)
New Revision: 648
Modified:
trunk/SQLObject/sqlobject/sqlite/sqliteconnection.py
Log:
Fixed a bug with autocommit in sqlite.
Modified: trunk/SQLObject/sqlobject/sqlite/sqliteconnection.py
===================================================================
--- trunk/SQLObject/sqlobject/sqlite/sqliteconnection.py 2005-02-24 22:56:21 UTC (rev 647)
+++ trunk/SQLObject/sqlobject/sqlite/sqliteconnection.py 2005-02-25 15:19:35 UTC (rev 648)
@@ -18,7 +18,7 @@
kw['pool'] = 0
# use only one connection for sqlite - supports multiple
# cursors per connection
- self._conn = sqlite.connect(self.filename)
+ self._conn = sqlite.connect(self.filename, autocommit=autoCommit)
DBAPI.__init__(self, **kw)
def connectionFromURI(cls, uri):
|
|
From: <sub...@co...> - 2005-02-24 22:56:49
|
Author: phd
Date: 2005-02-24 22:56:21 +0000 (Thu, 24 Feb 2005)
New Revision: 647
Modified:
trunk/SQLObject/sqlobject/dbconnection.py
trunk/SQLObject/sqlobject/tests/test_parse.py
Log:
_parseURI() now translate paths from C|/path to C:/path on w32 platforms.
Modified: trunk/SQLObject/sqlobject/dbconnection.py
===================================================================
--- trunk/SQLObject/sqlobject/dbconnection.py 2005-02-24 14:05:57 UTC (rev 646)
+++ trunk/SQLObject/sqlobject/dbconnection.py 2005-02-24 22:56:21 UTC (rev 647)
@@ -105,6 +105,9 @@
else:
port = None
path = '/' + rest
+ if os.name == 'nt':
+ if (len(rest) > 1) and (rest[1] == '|'):
+ path = "%s:%s" % (rest[0], rest[2:])
args = {}
if path.find('?') != -1:
path, arglist = path.split('?', 1)
Modified: trunk/SQLObject/sqlobject/tests/test_parse.py
===================================================================
--- trunk/SQLObject/sqlobject/tests/test_parse.py 2005-02-24 14:05:57 UTC (rev 646)
+++ trunk/SQLObject/sqlobject/tests/test_parse.py 2005-02-24 22:56:21 UTC (rev 647)
@@ -1,3 +1,4 @@
+import os
from sqlobject.dbconnection import DBConnection
########################################
@@ -54,3 +55,12 @@
assert port is None
assert path == "/:memory:"
assert args == {}
+
+ if os.name == 'nt':
+ user, password, host, port, path, args = _parseURI("sqlite:/C|/full/path/to/database")
+ assert user is None
+ assert password is None
+ assert host is None
+ assert port is None
+ assert path == "C:/full/path/to/database"
+ assert args == {}
|
|
From: <sub...@co...> - 2005-02-24 14:06:22
|
Author: phd
Date: 2005-02-24 14:05:57 +0000 (Thu, 24 Feb 2005)
New Revision: 646
Modified:
trunk/SQLObject/sqlobject/dbconnection.py
trunk/SQLObject/sqlobject/firebird/firebirdconnection.py
trunk/SQLObject/sqlobject/maxdb/maxdbconnection.py
trunk/SQLObject/sqlobject/mysql/mysqlconnection.py
trunk/SQLObject/sqlobject/postgres/pgconnection.py
trunk/SQLObject/sqlobject/sqlite/sqliteconnection.py
trunk/SQLObject/sqlobject/sybase/sybaseconnection.py
trunk/SQLObject/sqlobject/tests/test_parse.py
Log:
_parseURI now splits host and port, if the host contains :port.
Modified: trunk/SQLObject/sqlobject/dbconnection.py
===================================================================
--- trunk/SQLObject/sqlobject/dbconnection.py 2005-02-24 04:18:55 UTC (rev 645)
+++ trunk/SQLObject/sqlobject/dbconnection.py 2005-02-24 14:05:57 UTC (rev 646)
@@ -93,6 +93,17 @@
password = None
else:
user = password = None
+ if host and host.find(':') != -1:
+ _host, port = host.split(':')
+ try:
+ port = int(port)
+ except ValueError:
+ raise ValueError, "port must be integer, got '%s' instead" % port
+ if not (1 <= port <= 65535):
+ raise ValueError, "port must be integer in the range 1-65535, got '%d' instead" % port
+ host = _host
+ else:
+ port = None
path = '/' + rest
args = {}
if path.find('?') != -1:
@@ -102,7 +113,7 @@
argname, argvalue = single.split('=', 1)
argvalue = urllib.unquote(argvalue)
args[argname] = argvalue
- return user, password, host, path, args
+ return user, password, host, port, path, args
_parseURI = staticmethod(_parseURI)
class DBAPI(DBConnection):
Modified: trunk/SQLObject/sqlobject/firebird/firebirdconnection.py
===================================================================
--- trunk/SQLObject/sqlobject/firebird/firebirdconnection.py 2005-02-24 04:18:55 UTC (rev 645)
+++ trunk/SQLObject/sqlobject/firebird/firebirdconnection.py 2005-02-24 14:05:57 UTC (rev 646)
@@ -16,7 +16,7 @@
if kinterbasdb is None:
import kinterbasdb
self.module = kinterbasdb
-
+
self.limit_re = re.compile('^\s*(select )(.*)', re.IGNORECASE)
if not autoCommit and not kw.has_key('pool'):
@@ -37,7 +37,7 @@
DBAPI.__init__(self, **kw)
def connectionFromURI(cls, uri):
- auth, password, host, path, args = cls._parseURI(uri)
+ auth, password, host, port, path, args = cls._parseURI(uri)
if not password:
password = 'masterkey'
if not auth:
@@ -45,7 +45,7 @@
path = path.replace('/', os.sep)
return cls(host, db=path, user=auth, passwd=password, **args)
connectionFromURI = classmethod(connectionFromURI)
-
+
def _runWithConnection(self, meth, *args):
conn = self.getConnection()
# @@: Horrible auto-commit implementation. Just horrible!
Modified: trunk/SQLObject/sqlobject/maxdb/maxdbconnection.py
===================================================================
--- trunk/SQLObject/sqlobject/maxdb/maxdbconnection.py 2005-02-24 04:18:55 UTC (rev 645)
+++ trunk/SQLObject/sqlobject/maxdb/maxdbconnection.py 2005-02-24 14:05:57 UTC (rev 646)
@@ -78,7 +78,7 @@
DBAPI.__init__(self, **kw)
def connectionFromURI(cls, uri):
- auth, password, host, path, args = cls._parseURI(uri)
+ auth, password, host, port, path, args = cls._parseURI(uri)
path = path.replace('/', os.path.sep)
return cls(host, db=path, user=auth, passwd=password, **args)
connectionFromURI = classmethod(connectionFromURI)
Modified: trunk/SQLObject/sqlobject/mysql/mysqlconnection.py
===================================================================
--- trunk/SQLObject/sqlobject/mysql/mysqlconnection.py 2005-02-24 04:18:55 UTC (rev 645)
+++ trunk/SQLObject/sqlobject/mysql/mysqlconnection.py 2005-02-24 14:05:57 UTC (rev 646)
@@ -20,9 +20,9 @@
DBAPI.__init__(self, **kw)
def connectionFromURI(cls, uri):
- user, password, host, path, args = cls._parseURI(uri)
+ user, password, host, port, path, args = cls._parseURI(uri)
return cls(db=path.strip('/'), user=user or '', passwd=password or '',
- host=host or 'localhost', **args)
+ host=host or 'localhost', port=port or '', **args)
connectionFromURI = classmethod(connectionFromURI)
def makeConnection(self):
Modified: trunk/SQLObject/sqlobject/postgres/pgconnection.py
===================================================================
--- trunk/SQLObject/sqlobject/postgres/pgconnection.py 2005-02-24 04:18:55 UTC (rev 645)
+++ trunk/SQLObject/sqlobject/postgres/pgconnection.py 2005-02-24 14:05:57 UTC (rev 646)
@@ -12,7 +12,7 @@
dbName = 'postgres'
schemes = [dbName, 'postgresql', 'psycopg']
- def __init__(self, dsn=None, host=None, db=None,
+ def __init__(self, dsn=None, host=None, port=None, db=None,
user=None, passwd=None, usePygresql=False,
**kw):
global psycopg, pgdb
@@ -31,6 +31,7 @@
self.user = user
self.host = host
+ self.port = port
self.db = db
self.password = passwd
if dsn is None:
@@ -44,6 +45,8 @@
if host:
# @@: right format?
dsn.append('host=%s' % host)
+ if port:
+ dsn.append('port=%s' % port)
dsn = ' '.join(dsn)
self.dsn = dsn
DBAPI.__init__(self, **kw)
@@ -52,9 +55,9 @@
self._server_version = None # Not yet initialized
def connectionFromURI(cls, uri):
- user, password, host, path, args = cls._parseURI(uri)
+ user, password, host, port, path, args = cls._parseURI(uri)
path = path.strip('/')
- return cls(host=host, db=path, user=user, passwd=password, **args)
+ return cls(host=host, port=port, db=path, user=user, passwd=password, **args)
connectionFromURI = classmethod(connectionFromURI)
def _setAutoCommit(self, conn, auto):
Modified: trunk/SQLObject/sqlobject/sqlite/sqliteconnection.py
===================================================================
--- trunk/SQLObject/sqlobject/sqlite/sqliteconnection.py 2005-02-24 04:18:55 UTC (rev 645)
+++ trunk/SQLObject/sqlobject/sqlite/sqliteconnection.py 2005-02-24 14:05:57 UTC (rev 646)
@@ -22,7 +22,7 @@
DBAPI.__init__(self, **kw)
def connectionFromURI(cls, uri):
- user, password, host, path, args = cls._parseURI(uri)
+ user, password, host, port, path, args = cls._parseURI(uri)
assert host is None, (
"SQLite can only be used locally (with a URI like "
"sqlite:///file or sqlite:/file, not %r)" % uri)
Modified: trunk/SQLObject/sqlobject/sybase/sybaseconnection.py
===================================================================
--- trunk/SQLObject/sqlobject/sybase/sybaseconnection.py 2005-02-24 04:18:55 UTC (rev 645)
+++ trunk/SQLObject/sqlobject/sybase/sybaseconnection.py 2005-02-24 14:05:57 UTC (rev 646)
@@ -33,7 +33,7 @@
DBAPI.__init__(self, **kw)
def connectionFromURI(cls, uri):
- user, password, host, path, args = cls._parseURI(uri)
+ user, password, host, port, path, args = cls._parseURI(uri)
return cls(user=user, passwd=password, host=host or 'localhost',
db=path, **args)
connectionFromURI = classmethod(connectionFromURI)
Modified: trunk/SQLObject/sqlobject/tests/test_parse.py
===================================================================
--- trunk/SQLObject/sqlobject/tests/test_parse.py 2005-02-24 04:18:55 UTC (rev 645)
+++ trunk/SQLObject/sqlobject/tests/test_parse.py 2005-02-24 14:05:57 UTC (rev 646)
@@ -7,44 +7,50 @@
def test_parse():
_parseURI = DBConnection._parseURI
- user, password, host, path, args = _parseURI("mysql://user:passwd@host/database")
+ user, password, host, port, path, args = _parseURI("mysql://user:passwd@host/database")
assert user == "user"
assert password == "passwd"
assert host == "host"
+ assert port is None
assert path == "/database"
assert args == {}
- user, password, host, path, args = _parseURI("mysql://host/database")
- assert user == None
- assert password == None
+ user, password, host, port, path, args = _parseURI("mysql://host/database")
+ assert user is None
+ assert password is None
assert host == "host"
+ assert port is None
assert path == "/database"
assert args == {}
- user, password, host, path, args = _parseURI("postgres://user@host/database")
+ user, password, host, port, path, args = _parseURI("postgres://user@host/database")
assert user == "user"
- assert password == None
+ assert password is None
assert host == "host"
+ assert port is None
assert path == "/database"
assert args == {}
- user, password, host, path, args = _parseURI("postgres://host:5432/database")
- assert user == None
- assert password == None
- assert host == "host:5432"
+ user, password, host, port, path, args = _parseURI("postgres://host:5432/database")
+ assert user is None
+ assert password is None
+ assert host == "host"
+ assert port == 5432
assert path == "/database"
assert args == {}
- user, password, host, path, args = _parseURI("sqlite:///full/path/to/database")
- assert user == None
- assert password == None
- assert host == None
+ user, password, host, port, path, args = _parseURI("sqlite:///full/path/to/database")
+ assert user is None
+ assert password is None
+ assert host is None
+ assert port is None
assert path == "/full/path/to/database"
assert args == {}
- user, password, host, path, args = _parseURI("sqlite:/:memory:")
- assert user == None
- assert password == None
- assert host == None
+ user, password, host, port, path, args = _parseURI("sqlite:/:memory:")
+ assert user is None
+ assert password is None
+ assert host is None
+ assert port is None
assert path == "/:memory:"
assert args == {}
|
|
From: <sub...@co...> - 2005-02-23 19:28:33
|
Author: phd
Date: 2005-02-23 19:28:17 +0000 (Wed, 23 Feb 2005)
New Revision: 638
Modified:
trunk/SQLObject/sqlobject/cache.py
trunk/SQLObject/sqlobject/inheritance/__init__.py
trunk/SQLObject/sqlobject/main.py
Log:
The patch simplified and made faster inherited _SO_fetchAlternateID
(_findAlternateID, actually), but changed their signatures.
Fixed a minor bug in cache.py expireAll().
Modified: trunk/SQLObject/sqlobject/cache.py
===================================================================
--- trunk/SQLObject/sqlobject/cache.py 2005-02-23 19:19:42 UTC (rev 637)
+++ trunk/SQLObject/sqlobject/cache.py 2005-02-23 19:28:17 UTC (rev 638)
@@ -225,7 +225,7 @@
self.lock.acquire()
try:
for key, value in self.cache.items():
- self.expiredCache[key] = ref(obj)
+ self.expiredCache[key] = ref(value)
self.cache = {}
finally:
self.lock.release()
Modified: trunk/SQLObject/sqlobject/inheritance/__init__.py
===================================================================
--- trunk/SQLObject/sqlobject/inheritance/__init__.py 2005-02-23 19:19:42 UTC (rev 637)
+++ trunk/SQLObject/sqlobject/inheritance/__init__.py 2005-02-23 19:28:17 UTC (rev 638)
@@ -193,21 +193,8 @@
super(InheritableSQLObject, self)._create(id, **kw)
- def _findAlternateID(cls, dbIDName, value, connection=None):
- found = False
- currentClass = cls
- try:
- while currentClass:
- for col in currentClass.sqlmeta._columns:
- if col.dbName == dbIDName:
- found = True
- raise StopIteration
- currentClass = currentClass._parentClass
- except StopIteration:
- pass
- if not found:
- return [], None
- result = list(cls.selectBy(connection, **{col.name: value}))
+ def _findAlternateID(cls, name, dbName, value, connection=None):
+ result = list(cls.selectBy(connection, **{name: value}))
if not result:
return result, None
obj = result[0]
Modified: trunk/SQLObject/sqlobject/main.py
===================================================================
--- trunk/SQLObject/sqlobject/main.py 2005-02-23 19:19:42 UTC (rev 637)
+++ trunk/SQLObject/sqlobject/main.py 2005-02-23 19:28:17 UTC (rev 638)
@@ -649,7 +649,7 @@
cls, '_SO_class_%s' % column.foreignKey)
if column.alternateMethodName:
- func = eval('lambda cls, val, connection=None: cls._SO_fetchAlternateID(%s, val, connection=connection)' % repr(column.dbName))
+ func = eval('lambda cls, val, connection=None: cls._SO_fetchAlternateID(%s, %s, val, connection=connection)' % (repr(column.name), repr(column.dbName)))
setattr(cls, column.alternateMethodName, classmethod(func))
if changeSchema:
@@ -1119,19 +1119,19 @@
def _SO_getID(self, obj):
return getID(obj)
- def _findAlternateID(cls, dbIDName, value, connection=None):
+ def _findAlternateID(cls, name, dbName, value, connection=None):
return (connection or cls._connection)._SO_selectOneAlt(
cls,
[cls.sqlmeta.idName] +
[col.dbName for col in cls.sqlmeta._columns],
- dbIDName,
+ dbName,
value), None
_findAlternateID = classmethod(_findAlternateID)
- def _SO_fetchAlternateID(cls, dbIDName, value, connection=None):
- result, obj = cls._findAlternateID(dbIDName, value, connection)
+ def _SO_fetchAlternateID(cls, name, dbName, value, connection=None):
+ result, obj = cls._findAlternateID(name, dbName, value, connection)
if not result:
- raise SQLObjectNotFound, "The %s by alternateID %s=%s does not exist" % (cls.__name__, dbIDName, repr(value))
+ raise SQLObjectNotFound, "The %s by alternateID %s=%s does not exist" % (cls.__name__, name, repr(value))
if obj:
return obj
if connection:
|
|
From: <sub...@co...> - 2005-02-22 12:32:45
|
Author: phd
Date: 2005-02-22 12:32:34 +0000 (Tue, 22 Feb 2005)
New Revision: 635
Modified:
trunk/SQLObject/sqlobject/inheritance/__init__.py
trunk/SQLObject/sqlobject/inheritance/tests/test_inheritance.py
trunk/SQLObject/sqlobject/main.py
Log:
Fixed bugs in nherited byAlternateID() and selectBy().
Split _SO_fetchAlternateID() into _findAlternateID()
overrided _findAlternateID() in InheritableSQLObject.
Added more inheritance tests.
Modified: trunk/SQLObject/sqlobject/inheritance/__init__.py
===================================================================
--- trunk/SQLObject/sqlobject/inheritance/__init__.py 2005-02-21 16:50:34 UTC (rev 634)
+++ trunk/SQLObject/sqlobject/inheritance/__init__.py 2005-02-22 12:32:34 UTC (rev 635)
@@ -193,6 +193,37 @@
super(InheritableSQLObject, self)._create(id, **kw)
+ def _findAlternateID(cls, dbIDName, value, connection=None):
+ found = False
+ currentClass = cls
+ try:
+ while currentClass:
+ for col in currentClass.sqlmeta._columns:
+ if col.dbName == dbIDName:
+ found = True
+ raise StopIteration
+ currentClass = currentClass._parentClass
+ except StopIteration:
+ pass
+ if not found:
+ return [], None
+ result = list(cls.selectBy(connection, **{col.name: value}))
+ if not result:
+ return result, None
+ obj = result[0]
+ return [obj.id], obj
+ _findAlternateID = classmethod(_findAlternateID)
+
+ def selectBy(cls, connection=None, **kw):
+ clause = []
+ for name, value in kw.items():
+ clause.append(getattr(cls.q, name) == value)
+ clause = reduce(sqlbuilder.AND, clause)
+ conn = connection or cls._connection
+ return cls.SelectResultsClass(cls, clause, connection=conn)
+
+ selectBy = classmethod(selectBy)
+
def destroySelf(self):
#DSM: If this object has parents, recursivly kill them
if hasattr(self, '_parent') and self._parent:
Modified: trunk/SQLObject/sqlobject/inheritance/tests/test_inheritance.py
===================================================================
--- trunk/SQLObject/sqlobject/inheritance/tests/test_inheritance.py 2005-02-21 16:50:34 UTC (rev 634)
+++ trunk/SQLObject/sqlobject/inheritance/tests/test_inheritance.py 2005-02-22 12:32:34 UTC (rev 635)
@@ -10,7 +10,7 @@
class InherPerson(InheritableSQLObject):
_inheritable = 1 # I want this class to be inherited
firstName = StringCol()
- lastName = StringCol()
+ lastName = StringCol(alternateID=True)
class Employee(InherPerson):
_inheritable = 0 # If I don't want this class to be inherited
@@ -20,8 +20,8 @@
setupClass(InherPerson)
setupClass(Employee)
- Employee(firstName='Ian', lastName='Bicking', position='Project leader')
- InherPerson(firstName='Daniel', lastName='Savard')
+ Employee(firstName='Project', lastName='Leader', position='Project leader')
+ InherPerson(firstName='Oneof', lastName='Authors')
def test_inheritance():
@@ -43,8 +43,34 @@
persons = InherPerson.select(InherPerson.q.firstName <> None)
assert persons.count() == 2
+ persons = InherPerson.select(InherPerson.q.firstName == "phd")
+ assert persons.count() == 0
+
employees = Employee.select(Employee.q.firstName <> None)
assert employees.count() == 1
+ employees = Employee.select(Employee.q.firstName == "phd")
+ assert employees.count() == 0
+
employees = Employee.select(Employee.q.position <> None)
assert employees.count() == 1
+
+ persons = InherPerson.selectBy(firstName="Project")
+ assert persons.count() == 1
+ assert isinstance(persons[0], Employee)
+
+ persons = Employee.selectBy(firstName="Project")
+ assert persons.count() == 1
+
+ try:
+ person = InherPerson.byLastName("Oneof")
+ except:
+ pass
+ else:
+ raise RuntimeError, "unknown person %s" % person
+
+ person = InherPerson.byLastName("Leader")
+ assert person.firstName == "Project"
+
+ person = Employee.byLastName("Leader")
+ assert person.firstName == "Project"
Modified: trunk/SQLObject/sqlobject/main.py
===================================================================
--- trunk/SQLObject/sqlobject/main.py 2005-02-21 16:50:34 UTC (rev 634)
+++ trunk/SQLObject/sqlobject/main.py 2005-02-22 12:32:34 UTC (rev 635)
@@ -1119,15 +1119,21 @@
def _SO_getID(self, obj):
return getID(obj)
- def _SO_fetchAlternateID(cls, dbIDName, value, connection=None):
- result = (connection or cls._connection)._SO_selectOneAlt(
+ def _findAlternateID(cls, dbIDName, value, connection=None):
+ return (connection or cls._connection)._SO_selectOneAlt(
cls,
[cls.sqlmeta.idName] +
[col.dbName for col in cls.sqlmeta._columns],
dbIDName,
- value)
+ value), None
+ _findAlternateID = classmethod(_findAlternateID)
+
+ def _SO_fetchAlternateID(cls, dbIDName, value, connection=None):
+ result, obj = cls._findAlternateID(dbIDName, value, connection)
if not result:
raise SQLObjectNotFound, "The %s by alternateID %s=%s does not exist" % (cls.__name__, dbIDName, repr(value))
+ if obj:
+ return obj
if connection:
obj = cls.get(result[0], connection=connection)
else:
|
|
From: <sub...@co...> - 2005-02-21 16:50:39
|
Author: phd
Date: 2005-02-21 16:50:34 +0000 (Mon, 21 Feb 2005)
New Revision: 634
Added:
trunk/SQLObject/sqlobject/tests/test_parse.py
Modified:
trunk/SQLObject/sqlobject/sqlite/sqliteconnection.py
Log:
Fixed a bug in sqlite connection - allow in-memory database with sqlite:/:memory: URI.
Added tests for _parseURI.
Modified: trunk/SQLObject/sqlobject/sqlite/sqliteconnection.py
===================================================================
--- trunk/SQLObject/sqlobject/sqlite/sqliteconnection.py 2005-02-21 13:39:55 UTC (rev 633)
+++ trunk/SQLObject/sqlobject/sqlite/sqliteconnection.py 2005-02-21 16:50:34 UTC (rev 634)
@@ -29,6 +29,7 @@
assert user is None and password is None, (
"You may not provide usernames or passwords for SQLite "
"databases")
+ if path == "/:memory:": path = ":memory:"
return cls(filename=path, **args)
connectionFromURI = classmethod(connectionFromURI)
Added: trunk/SQLObject/sqlobject/tests/test_parse.py
===================================================================
--- trunk/SQLObject/sqlobject/tests/test_parse.py 2005-02-21 13:39:55 UTC (rev 633)
+++ trunk/SQLObject/sqlobject/tests/test_parse.py 2005-02-21 16:50:34 UTC (rev 634)
@@ -0,0 +1,50 @@
+from sqlobject.dbconnection import DBConnection
+
+########################################
+## Test _parseURI
+########################################
+
+def test_parse():
+ _parseURI = DBConnection._parseURI
+
+ user, password, host, path, args = _parseURI("mysql://user:passwd@host/database")
+ assert user == "user"
+ assert password == "passwd"
+ assert host == "host"
+ assert path == "/database"
+ assert args == {}
+
+ user, password, host, path, args = _parseURI("mysql://host/database")
+ assert user == None
+ assert password == None
+ assert host == "host"
+ assert path == "/database"
+ assert args == {}
+
+ user, password, host, path, args = _parseURI("postgres://user@host/database")
+ assert user == "user"
+ assert password == None
+ assert host == "host"
+ assert path == "/database"
+ assert args == {}
+
+ user, password, host, path, args = _parseURI("postgres://host:5432/database")
+ assert user == None
+ assert password == None
+ assert host == "host:5432"
+ assert path == "/database"
+ assert args == {}
+
+ user, password, host, path, args = _parseURI("sqlite:///full/path/to/database")
+ assert user == None
+ assert password == None
+ assert host == None
+ assert path == "/full/path/to/database"
+ assert args == {}
+
+ user, password, host, path, args = _parseURI("sqlite:/:memory:")
+ assert user == None
+ assert password == None
+ assert host == None
+ assert path == "/:memory:"
+ assert args == {}
|
|
From: <sub...@co...> - 2005-02-21 13:39:58
|
Author: phd Date: 2005-02-21 13:39:55 +0000 (Mon, 21 Feb 2005) New Revision: 633 Removed: home/phd/SQLObject/inheritance/ home/phd/SQLObject/postgres-7.2/ Log: Removed old private branches. Inheritance has been merged into the trunk, and Postgres 7.2 is just too old to be merged. |
|
From: <sub...@co...> - 2005-02-21 13:37:13
|
Author: phd Date: 2005-02-21 13:37:09 +0000 (Mon, 21 Feb 2005) New Revision: 632 Modified: trunk/SQLObject/docs/News.txt Log: Started new section about SQLObject 0.7.0. Modified: trunk/SQLObject/docs/News.txt =================================================================== --- trunk/SQLObject/docs/News.txt 2005-02-21 13:33:48 UTC (rev 631) +++ trunk/SQLObject/docs/News.txt 2005-02-21 13:37:09 UTC (rev 632) @@ -7,6 +7,17 @@ .. _start: +SQLObject 0.7.0 +=============== + +Features +-------- + +* Inheritance. See Inheritance.html_ + +.. _Inheritance.html: Inheritance.html + + SQLObject 0.6.1 =============== |
|
From: <sub...@co...> - 2005-02-21 13:33:53
|
Author: phd Date: 2005-02-21 13:33:48 +0000 (Mon, 21 Feb 2005) New Revision: 631 Modified: trunk/SQLObject/docs/Inheritance.txt trunk/SQLObject/docs/build Log: Minor inheritance documentation update. Modified: trunk/SQLObject/docs/Inheritance.txt =================================================================== --- trunk/SQLObject/docs/Inheritance.txt 2005-02-21 12:49:20 UTC (rev 630) +++ trunk/SQLObject/docs/Inheritance.txt 2005-02-21 13:33:48 UTC (rev 631) @@ -3,6 +3,13 @@ Inheritance ----------- +Daniel Savard has implemented inheritance for SQLObject. According to +ObjectMatter_ this is a kind of vertical inheritance. The only difference +is that objects reference their leafs, not parents. Links to parents are +reconstructed at run-time using the hierarchy of Python classes. + +.. _ObjectMatter: http://www.objectmatter.com/vbsf/docs/maptool/ormapping.html + * As suggested by Ian Bicking, each child class now has the same ID than the parent class. No more need for childID column and parent foreignKey (with a small speed boost). Modified: trunk/SQLObject/docs/build =================================================================== --- trunk/SQLObject/docs/build 2005-02-21 12:49:20 UTC (rev 630) +++ trunk/SQLObject/docs/build 2005-02-21 13:33:48 UTC (rev 631) @@ -1,7 +1,6 @@ #!/bin/sh -cd ../examples -./examplestripper.py -cd ../docs -buildhtml.py --report=2 --prune=.svn --prune=europython --silent --no-toc-backlinks - +cd ../examples && \ +./examplestripper.py && \ +cd ../docs && \ +exec buildhtml.py --report=2 --prune=.svn --prune=europython --silent --no-toc-backlinks |
|
From: <sub...@co...> - 2005-02-21 12:49:27
|
Author: phd Date: 2005-02-21 12:49:20 +0000 (Mon, 21 Feb 2005) New Revision: 630 Modified: trunk/SQLObject/sqlobject/mysql/mysqlconnection.py Log: Applied the patch from https://sourceforge.net/tracker/index.php?func=detail&aid=1040262&group_id=74338&atid=540672 Modified: trunk/SQLObject/sqlobject/mysql/mysqlconnection.py =================================================================== --- trunk/SQLObject/sqlobject/mysql/mysqlconnection.py 2005-02-21 12:43:02 UTC (rev 629) +++ trunk/SQLObject/sqlobject/mysql/mysqlconnection.py 2005-02-21 12:49:20 UTC (rev 630) @@ -52,7 +52,10 @@ self.printDebug(conn, q, 'QueryIns') self._executeRetry(conn, c, q) if id is None: - id = c.lastrowid + try: + id = c.lastrowid + except AttributeError: + id = c.insert_id() if self.debugOutput: self.printDebug(conn, id, 'QueryIns', 'result') return id |
|
From: <sub...@co...> - 2005-02-21 12:43:08
|
Author: phd Date: 2005-02-21 12:43:02 +0000 (Mon, 21 Feb 2005) New Revision: 629 Modified: trunk/SQLObject/sqlobject/sybase/sybaseconnection.py Log: Applied the patch from https://sourceforge.net/tracker/index.php?func=detail&aid=1104058&group_id=74338&atid=540674 Modified: trunk/SQLObject/sqlobject/sybase/sybaseconnection.py =================================================================== --- trunk/SQLObject/sqlobject/sybase/sybaseconnection.py 2005-02-21 12:32:50 UTC (rev 628) +++ trunk/SQLObject/sqlobject/sybase/sybaseconnection.py 2005-02-21 12:43:02 UTC (rev 629) @@ -1,4 +1,5 @@ from sqlobject.dbconnection import DBAPI +from sqlobject import col Sybase = None class SybaseConnection(DBAPI): @@ -128,13 +129,13 @@ (tableName, column.dbName)) - SHOW_COLUMNS=("select 'column' = COL_NAME(id, colid) " - "from syscolumns where id = OBJECT_ID(%s)") + SHOW_COLUMNS=('SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_DEFAULT FROM INFORMATION_SCHEMA.COLUMNS ' + 'WHERE TABLE_NAME = \'%s\'') def columnsFromSchema(self, tableName, soClass): colData = self.queryAll(self.SHOW_COLUMNS % tableName) results = [] - for field, t, nullAllowed, key, default, extra in colData: + for field, t, nullAllowed, default in colData: if field == 'id': continue colClass, kw = self.guessClass(t) @@ -143,6 +144,7 @@ kw['default'] = default # @@ skip key... # @@ skip extra... + kw['forceDBName'] = True results.append(colClass(**kw)) return results |