sqlobject-cvs Mailing List for SQLObject (Page 154)
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-11-04 05:25:43
|
Author: ianb
Date: 2005-11-04 05:25:25 +0000 (Fri, 04 Nov 2005)
New Revision: 1221
Modified:
SQLObject/trunk/sqlobject/tests/test_index_get.py
Log:
Make sure class name doesn't conflict with other tests
Modified: SQLObject/trunk/sqlobject/tests/test_index_get.py
===================================================================
--- SQLObject/trunk/sqlobject/tests/test_index_get.py 2005-11-04 05:19:49 UTC (rev 1220)
+++ SQLObject/trunk/sqlobject/tests/test_index_get.py 2005-11-04 05:25:25 UTC (rev 1221)
@@ -1,46 +1,46 @@
from sqlobject import *
from sqlobject.tests.dbtest import *
-class Person(SQLObject):
+class PersonIndexGet(SQLObject):
firstName = StringCol()
lastName = StringCol()
age = IntCol(alternateID=True)
nameIndex = DatabaseIndex(firstName, lastName, unique=True)
def test_1():
- setupClass(Person)
+ setupClass(PersonIndexGet)
- Person(firstName='Eric', lastName='Idle', age=62)
- Person(firstName='Terry', lastName='Gilliam', age=65)
- Person(firstName='John', lastName='Cleese', age=66)
+ PersonIndexGet(firstName='Eric', lastName='Idle', age=62)
+ PersonIndexGet(firstName='Terry', lastName='Gilliam', age=65)
+ PersonIndexGet(firstName='John', lastName='Cleese', age=66)
- Person.get(1)
- Person.nameIndex.get('Terry', 'Gilliam')
- Person.nameIndex.get(firstName='John', lastName='Cleese')
+ PersonIndexGet.get(1)
+ PersonIndexGet.nameIndex.get('Terry', 'Gilliam')
+ PersonIndexGet.nameIndex.get(firstName='John', lastName='Cleese')
try:
- print Person.nameIndex.get(firstName='Graham', lastName='Chapman')
+ print PersonIndexGet.nameIndex.get(firstName='Graham', lastName='Chapman')
except Exception, e:
pass
else:
raise AssertError
try:
- print Person.nameIndex.get('Terry', lastName='Gilliam')
+ print PersonIndexGet.nameIndex.get('Terry', lastName='Gilliam')
except Exception, e:
pass
else:
raise AssertError
try:
- print Person.nameIndex.get('Terry', 'Gilliam', 65)
+ print PersonIndexGet.nameIndex.get('Terry', 'Gilliam', 65)
except Exception, e:
pass
else:
raise AssertError
try:
- print Person.nameIndex.get('Terry')
+ print PersonIndexGet.nameIndex.get('Terry')
except Exception, e:
pass
else:
|
|
From: <sub...@co...> - 2005-11-04 05:20:02
|
Author: ianb
Date: 2005-11-04 05:19:49 +0000 (Fri, 04 Nov 2005)
New Revision: 1220
Modified:
SQLObject/trunk/sqlobject/conftest.py
SQLObject/trunk/sqlobject/declarative.py
SQLObject/trunk/sqlobject/events.py
SQLObject/trunk/sqlobject/tests/test_events.py
Log:
Added tests for column adding events; fixed a bug with inheriting events (they weren't inherited immediately); added some debugging routines for events; added an option to py.test for debugging events
Modified: SQLObject/trunk/sqlobject/conftest.py
===================================================================
--- SQLObject/trunk/sqlobject/conftest.py 2005-11-03 22:18:32 UTC (rev 1219)
+++ SQLObject/trunk/sqlobject/conftest.py 2005-11-04 05:19:49 UTC (rev 1220)
@@ -45,7 +45,12 @@
Option('-O', '--SQL-output',
action="store_true", dest="show_sql_output", default=False,
help="Show output from SQL statements (when capturing "
- "stdout the output is only displayed when a test fails)"))
+ "stdout the output is only displayed when a test fails)"),
+ Option('-E', '--events',
+ action="store_true", dest="debug_events", default=False,
+ help="Debug events (print information about events as they are "
+ "sent)"),
+ )
class SQLObjectClass(py.test.collect.Class):
def run(self):
@@ -55,3 +60,8 @@
return super(SQLObjectClass, self).run()
Class = SQLObjectClass
+
+def setup_tests():
+ if option.debug_events:
+ from sqlobject import events
+ events.debug_events()
Modified: SQLObject/trunk/sqlobject/declarative.py
===================================================================
--- SQLObject/trunk/sqlobject/declarative.py 2005-11-03 22:18:32 UTC (rev 1219)
+++ SQLObject/trunk/sqlobject/declarative.py 2005-11-04 05:19:49 UTC (rev 1220)
@@ -90,10 +90,13 @@
def __new__(meta, class_name, bases, new_attrs):
post_funcs = []
+ early_funcs = []
events.send(events.ClassCreateSignal,
bases[0], class_name, bases, new_attrs,
- post_funcs)
+ post_funcs, early_funcs)
cls = type.__new__(meta, class_name, bases, new_attrs)
+ for func in early_funcs:
+ func(cls)
if new_attrs.has_key('__classinit__'):
cls.__classinit__ = staticmethod(cls.__classinit__.im_func)
cls.__classinit__(cls, new_attrs)
Modified: SQLObject/trunk/sqlobject/events.py
===================================================================
--- SQLObject/trunk/sqlobject/events.py 2005-11-03 22:18:32 UTC (rev 1219)
+++ SQLObject/trunk/sqlobject/events.py 2005-11-04 05:19:49 UTC (rev 1220)
@@ -1,3 +1,5 @@
+import sys
+import types
from sqlobject.include.pydispatch import dispatcher
from weakref import ref
@@ -30,21 +32,25 @@
class ClassCreateSignal(Signal):
"""
- Signal raised before class creation. The sender is the superclass
+ Signal raised after class creation. The sender is the superclass
(in case of multiple superclasses, the first superclass). The
- arguments are ``(new_class_name, bases, new_attrs, post_funcs)``.
- ``new_attrs`` is a dictionary and may be modified (but
- ``new_class_name`` and ``bases`` are immutable). ``post_funcs``
- is an initially-empty list that can have callbacks appended to it.
+ arguments are ``(new_class_name, bases, new_attrs, post_funcs,
+ early_funcs)``. ``new_attrs`` is a dictionary and may be modified
+ (but ``new_class_name`` and ``bases`` are immutable).
+ ``post_funcs`` is an initially-empty list that can have callbacks
+ appended to it.
Note: at the time this event is called, the new class has not yet
been created. The functions in ``post_funcs`` will be called
after the class is created, with the single arguments of
- ``(new_class)``.
+ ``(new_class)``. Also, ``early_funcs`` will be called at the
+ soonest possible time after class creation (``post_funcs`` is
+ called after the class's ``__classinit__``).
"""
-def _makeSubclassConnections(new_class_name, bases, new_attrs, post_funcs):
- post_funcs.append(_makeSubclassConnectionsPost)
+def _makeSubclassConnections(new_class_name, bases, new_attrs,
+ post_funcs, early_funcs):
+ early_funcs.insert(0, _makeSubclassConnectionsPost)
def _makeSubclassConnectionsPost(new_class):
for cls in new_class.__bases__:
@@ -150,6 +156,123 @@
after the table has been dropped.
"""
+############################################################
+## Event Debugging
+############################################################
+
+def summarize_events_by_sender(sender=None, output=None, indent=0):
+ """
+ Prints out a summary of the senders and listeners in the system,
+ for debugging purposes.
+ """
+ if output is None:
+ output = sys.stdout
+ if sender is None:
+ send_list = [
+ (deref(dispatcher.senders.get(sid)), listeners)
+ for sid, listeners in dispatcher.connections.items()
+ if deref(dispatcher.senders.get(sid))]
+ for sender, listeners in sorted_items(send_list):
+ real_sender = deref(sender)
+ if not real_sender:
+ continue
+ header = 'Sender: %r' % real_sender
+ print >> output, (' '*indent) + header
+ print >> output, (' '*indent) + '='*len(header)
+ summarize_events_by_sender(real_sender, output=output, indent=indent+2)
+ else:
+ for signal, receivers in sorted_items(dispatcher.connections.get(id(sender), [])):
+ receivers = [deref(r) for r in receivers if deref(r)]
+ header = 'Signal: %s (%i receivers)' % (sort_name(signal),
+ len(receivers))
+ print >> output, (' '*indent) + header
+ print >> output, (' '*indent) + '-'*len(header)
+ for receiver in sorted(receivers, key=sort_name):
+ print >> output, (' '*indent) + ' ' + nice_repr(receiver)
+
+def deref(value):
+ if isinstance(value, dispatcher.WEAKREF_TYPES):
+ return value()
+ else:
+ return value
+
+def sorted_items(a_dict):
+ if isinstance(a_dict, dict):
+ a_dict = a_dict.items()
+ return sorted(a_dict, key=lambda t: sort_name(t[0]))
+
+def sort_name(value):
+ if isinstance(value, type):
+ return value.__name__
+ elif isinstance(value, types.FunctionType):
+ return value.func_name
+ else:
+ return str(value)
+
+_real_dispatcher_send = dispatcher.send
+_real_dispatcher_sendExact = dispatcher.sendExact
+_real_dispatcher_disconnect = dispatcher.disconnect
+_real_dispatcher_connect = dispatcher.connect
+_debug_enabled = False
+def debug_events():
+ global _debug_enabled, send
+ if _debug_enabled:
+ return
+ _debug_enabled = True
+ dispatcher.send = send = _debug_send
+ dispatcher.sendExact = _debug_sendExact
+ dispatcher.disconnect = _debug_disconnect
+ dispatcher.connect = _debug_connect
+
+def _debug_send(signal=dispatcher.Any, sender=dispatcher.Anonymous,
+ *arguments, **named):
+ print "send %s from %s: %s" % (
+ nice_repr(signal), nice_repr(sender), fmt_args(*arguments, **named))
+ return _real_dispatcher_send(signal, sender, *arguments, **named)
+
+def _debug_sendExact(signal=dispatcher.Any, sender=dispatcher.Anonymous,
+ *arguments, **named):
+ print "sendExact %s from %s: %s" % (
+ nice_repr(signal), nice_repr(sender), fmt_args(*arguments, **name))
+ return _real_dispatcher_sendExact(signal, sender, *arguments, **named)
+
+def _debug_connect(receiver, signal=dispatcher.Any, sender=dispatcher.Any,
+ weak=True):
+ print "connect %s to %s signal %s" % (
+ nice_repr(receiver), nice_repr(signal), nice_repr(sender))
+ return _real_dispatcher_connect(receiver, signal, sender, weak)
+
+def _debug_disconnect(receiver, signal=dispatcher.Any, sender=dispatcher.Any,
+ weak=True):
+ print "disconnecting %s from %s signal %s" % (
+ nice_repr(receiver), nice_repr(signal), nice_repr(sender))
+ return disconnect(receiver, signal, sender, weak)
+
+def fmt_args(*arguments, **name):
+ args = [repr(a) for a in arguments]
+ args.extend([
+ '%s=%r' % (n, v) for n, v in sorted(name.items())])
+ return ', '.join(args)
+
+def nice_repr(v):
+ """
+ Like repr(), but nicer for debugging here.
+ """
+ if isinstance(v, (types.ClassType, type)):
+ return v.__module__ + '.' + v.__name__
+ elif isinstance(v, types.FunctionType):
+ if '__name__' in v.func_globals:
+ if getattr(sys.modules[v.func_globals['__name__']],
+ v.func_name, None) is v:
+ return '%s.%s' % (v.func_globals['__name__'], v.func_name)
+ return repr(v)
+ elif isinstance(v, types.MethodType):
+ return '%s.%s of %s' % (
+ nice_repr(v.im_class), v.im_func.func_name,
+ nice_repr(v.im_self))
+ else:
+ return repr(v)
+
__all__ = ['listen', 'send']
for name, value in globals().items():
if isinstance(value, type) and issubclass(value, Signal):
Modified: SQLObject/trunk/sqlobject/tests/test_events.py
===================================================================
--- SQLObject/trunk/sqlobject/tests/test_events.py 2005-11-03 22:18:32 UTC (rev 1219)
+++ SQLObject/trunk/sqlobject/tests/test_events.py 2005-11-04 05:19:49 UTC (rev 1220)
@@ -27,7 +27,7 @@
class EventTesterSub2(EventTesterSub1):
pass
assert len(watcher.log) == 2
- assert len(watcher.log[0]) == 4
+ assert len(watcher.log[0]) == 5
assert watcher.log[0][0] == 'EventTesterSub1'
assert watcher.log[0][1] == (EventTester,)
assert isinstance(watcher.log[0][2], dict)
@@ -60,13 +60,15 @@
(f, {'name': 'bar2'}),
(f, {'name': 'bar3'})]
-def disbaled_test_add_column():
+def test_add_column():
setupClass(EventTester)
- watcher = make_listen(events.RowUpdateSignal)
+ watcher = make_listen(events.AddColumnSignal)
+ events.summarize_events_by_sender()
class NewEventTester(EventTester):
name2 = StringCol()
- assert watcher.log == [
- (NewEventTester, NewEventTester._connection,
- 'name2', NewEventTester.sqlmeta.columns['name2'],
- True, [])]
-
+ expect = (
+ NewEventTester, None,
+ 'name2', NewEventTester.sqlmeta.columnDefinitions['name2'],
+ False, [])
+ print zip(watcher.log[1], expect)
+ assert watcher.log[1] == expect
|
|
From: <sub...@co...> - 2005-11-03 22:18:45
|
Author: test
Date: 2005-11-03 22:18:32 +0000 (Thu, 03 Nov 2005)
New Revision: 1219
Modified:
SQLObject/trunk/sqlobject/main.py
Log:
Removed spurious print statement
Modified: SQLObject/trunk/sqlobject/main.py
===================================================================
--- SQLObject/trunk/sqlobject/main.py 2005-11-03 21:51:23 UTC (rev 1218)
+++ SQLObject/trunk/sqlobject/main.py 2005-11-03 22:18:32 UTC (rev 1219)
@@ -297,7 +297,6 @@
def addColumn(cls, columnDef, changeSchema=False, connection=None):
post_funcs = []
- print "Send on", cls.soClass, columnDef.name
cls.send(events.AddColumnSignal, cls.soClass, connection,
columnDef.name, columnDef, changeSchema, post_funcs)
sqlmeta = cls
|
|
From: <sub...@co...> - 2005-11-03 17:16:53
|
Author: phd
Date: 2005-11-03 17:16:47 +0000 (Thu, 03 Nov 2005)
New Revision: 1208
Modified:
home/phd/SQLObject/paramstyles/sqlobject/dbconnection.py
home/phd/SQLObject/paramstyles/sqlobject/sqlbuilder.py
Log:
Renamed SQLQuery to SQLList; implemented __sqlrepr__().
Modified: home/phd/SQLObject/paramstyles/sqlobject/dbconnection.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/dbconnection.py 2005-11-03 16:33:27 UTC (rev 1207)
+++ home/phd/SQLObject/paramstyles/sqlobject/dbconnection.py 2005-11-03 17:16:47 UTC (rev 1208)
@@ -300,7 +300,7 @@
if self.debug:
self.printDebug(conn, query, 'QueryR')
return cursor.execute(query)
- elif isinstance(query, sqlbuilder.SQLQuery):
+ elif isinstance(query, sqlbuilder.SQLList):
query_string, params = self._convertQuery(query)
if self.debug:
self.printDebug(conn, query_string, 'QueryString')
@@ -362,7 +362,7 @@
def _insertSQL(self, table, names, values):
name_value_dict = dict(zip(names, values))
- return sqlbuilder.SQLQuery(DBSingleStyle.insert(table, name_value_dict))
+ return sqlbuilder.SQLList(DBSingleStyle.insert(table, name_value_dict))
def transaction(self):
return Transaction(self)
Modified: home/phd/SQLObject/paramstyles/sqlobject/sqlbuilder.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/sqlbuilder.py 2005-11-03 16:33:27 UTC (rev 1207)
+++ home/phd/SQLObject/paramstyles/sqlobject/sqlbuilder.py 2005-11-03 17:16:47 UTC (rev 1208)
@@ -431,13 +431,17 @@
########################################
-## SQL Queries
+## SQL Query lists
########################################
-class SQLQuery(object):
+class SQLList(object):
def __init__(self, query_list):
self.query_list = query_list
+ def __sqlrepr__(self, db):
+ query_list = [sqlrepr(part, db) for part in self.query_list]
+ return ''.join(query_list)
+
########################################
## SQL Statements
########################################
|
|
From: <sub...@co...> - 2005-11-03 16:33:31
|
Author: phd
Date: 2005-11-03 16:33:27 +0000 (Thu, 03 Nov 2005)
New Revision: 1207
Modified:
home/phd/SQLObject/paramstyles/sqlobject/tests/test_decimal.py
Log:
Merged patches from the revisions 1206:1206 from the trunk: a small patch for psycopg2 by Humberto Diogenes <adm...@di...>.
Modified: home/phd/SQLObject/paramstyles/sqlobject/tests/test_decimal.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/tests/test_decimal.py 2005-11-03 16:27:43 UTC (rev 1206)
+++ home/phd/SQLObject/paramstyles/sqlobject/tests/test_decimal.py 2005-11-03 16:33:27 UTC (rev 1207)
@@ -13,18 +13,23 @@
class DecimalTable(SQLObject):
col1 = DecimalCol(size=6, precision=4)
-def test_1decimal():
- if not supports('decimalColumn'):
- return
- setupClass(DecimalTable)
- d = DecimalTable(col1=21.12)
- assert d.col1 == 21.12
-
-if Decimal and supports('decimalColumn'):
- def test_2Decimal():
+if supports('decimalColumn'):
+ def test_1decimal():
+ """Tests new instance with a float in col1."""
setupClass(DecimalTable)
- d = DecimalTable(col1=Decimal("21.12"))
- if isinstance(d.col1, Decimal):
+ d = DecimalTable(col1=21.12)
+ # psycopg2 returns float as Decimal
+ if Decimal and isinstance(d.col1, Decimal):
assert d.col1 == Decimal("21.12")
else:
assert d.col1 == 21.12
+
+ if Decimal:
+ def test_2Decimal():
+ """Tests new instance with a Decimal in col1."""
+ setupClass(DecimalTable)
+ d = DecimalTable(col1=Decimal("21.12"))
+ if isinstance(d.col1, Decimal):
+ assert d.col1 == Decimal("21.12")
+ else:
+ assert d.col1 == 21.12
|
|
From: <sub...@co...> - 2005-11-03 16:27:59
|
Author: phd
Date: 2005-11-03 16:27:43 +0000 (Thu, 03 Nov 2005)
New Revision: 1206
Modified:
SQLObject/trunk/sqlobject/tests/test_decimal.py
Log:
A little patch for psycopg2 by Humberto Diogenes <adm...@di...>.
Modified: SQLObject/trunk/sqlobject/tests/test_decimal.py
===================================================================
--- SQLObject/trunk/sqlobject/tests/test_decimal.py 2005-11-03 12:30:45 UTC (rev 1205)
+++ SQLObject/trunk/sqlobject/tests/test_decimal.py 2005-11-03 16:27:43 UTC (rev 1206)
@@ -13,18 +13,23 @@
class DecimalTable(SQLObject):
col1 = DecimalCol(size=6, precision=4)
-def test_1decimal():
- if not supports('decimalColumn'):
- return
- setupClass(DecimalTable)
- d = DecimalTable(col1=21.12)
- assert d.col1 == 21.12
-
-if Decimal and supports('decimalColumn'):
- def test_2Decimal():
+if supports('decimalColumn'):
+ def test_1decimal():
+ """Tests new instance with a float in col1."""
setupClass(DecimalTable)
- d = DecimalTable(col1=Decimal("21.12"))
- if isinstance(d.col1, Decimal):
+ d = DecimalTable(col1=21.12)
+ # psycopg2 returns float as Decimal
+ if Decimal and isinstance(d.col1, Decimal):
assert d.col1 == Decimal("21.12")
else:
assert d.col1 == 21.12
+
+ if Decimal:
+ def test_2Decimal():
+ """Tests new instance with a Decimal in col1."""
+ setupClass(DecimalTable)
+ d = DecimalTable(col1=Decimal("21.12"))
+ if isinstance(d.col1, Decimal):
+ assert d.col1 == Decimal("21.12")
+ else:
+ assert d.col1 == 21.12
|
|
From: <sub...@co...> - 2005-11-03 12:31:51
|
Author: phd Date: 2005-11-03 12:30:45 +0000 (Thu, 03 Nov 2005) New Revision: 1205 Modified: home/phd/SQLObject/paramstyles/docs/SQLObject.txt Log: Merged patches from the revisions 1202:1204 from the trunk: added a pointer to psycopg2. Modified: home/phd/SQLObject/paramstyles/docs/SQLObject.txt =================================================================== --- home/phd/SQLObject/paramstyles/docs/SQLObject.txt 2005-11-03 12:26:44 UTC (rev 1204) +++ home/phd/SQLObject/paramstyles/docs/SQLObject.txt 2005-11-03 12:30:45 UTC (rev 1205) @@ -44,14 +44,16 @@ ============ Currently SQLObject supports MySQL_ via MySQLdb_ aka MySQL-python, -PostgreSQL_ via psycopg_, SQLite_ via PySQLite_, Firebird_ via kinterbasdb_, -Sybase via Sybase_, and `MAX DB`_ (also known as SAP DB) via sapdb_, -`MSSQL Server`_ via pymssql_ (+ FreeTDS_) or ADODBAPI_ (Win32). +PostgreSQL_ via psycopg1_ or psycopg2_, SQLite_ via PySQLite_, +Firebird_ via kinterbasdb_, `MAX DB`_ (also known as SAP DB) via sapdb_, +Sybase via Sybase_, and `MSSQL Server`_ via pymssql_ (+ FreeTDS_) or +ADODBAPI_ (Win32). .. _MySQL: http://mysql.com .. _MySQLdb: http://sourceforge.net/projects/mysql-python/ .. _PostgreSQL: http://postgresql.org -.. _psycopg: http://initd.org/projects/psycopg1 +.. _psycopg1: http://initd.org/projects/psycopg1 +.. _psycopg2: http://initd.org/projects/psycopg2 .. _SQLite: http://sqlite.org .. _PySQLite: http://initd.org/projects/pysqlite .. _Firebird: http://firebird.sourceforge.net |
|
From: <sub...@co...> - 2005-11-03 12:27:50
|
Author: phd Date: 2005-11-03 12:26:44 +0000 (Thu, 03 Nov 2005) New Revision: 1204 Modified: SQLObject/trunk/docs/SQLObject.txt Log: Added a pointer to psycopg2. Modified: SQLObject/trunk/docs/SQLObject.txt =================================================================== --- SQLObject/trunk/docs/SQLObject.txt 2005-11-03 12:22:15 UTC (rev 1203) +++ SQLObject/trunk/docs/SQLObject.txt 2005-11-03 12:26:44 UTC (rev 1204) @@ -44,14 +44,16 @@ ============ Currently SQLObject supports MySQL_ via MySQLdb_ aka MySQL-python, -PostgreSQL_ via psycopg_, SQLite_ via PySQLite_, Firebird_ via kinterbasdb_, -Sybase via Sybase_, and `MAX DB`_ (also known as SAP DB) via sapdb_, -`MSSQL Server`_ via pymssql_ (+ FreeTDS_) or ADODBAPI_ (Win32). +PostgreSQL_ via psycopg1_ or psycopg2_, SQLite_ via PySQLite_, +Firebird_ via kinterbasdb_, `MAX DB`_ (also known as SAP DB) via sapdb_, +Sybase via Sybase_, and `MSSQL Server`_ via pymssql_ (+ FreeTDS_) or +ADODBAPI_ (Win32). .. _MySQL: http://mysql.com .. _MySQLdb: http://sourceforge.net/projects/mysql-python/ .. _PostgreSQL: http://postgresql.org -.. _psycopg: http://initd.org/projects/psycopg1 +.. _psycopg1: http://initd.org/projects/psycopg1 +.. _psycopg2: http://initd.org/projects/psycopg2 .. _SQLite: http://sqlite.org .. _PySQLite: http://initd.org/projects/pysqlite .. _Firebird: http://firebird.sourceforge.net |
|
From: <sub...@co...> - 2005-11-03 12:24:15
|
Author: phd Date: 2005-11-03 12:22:15 +0000 (Thu, 03 Nov 2005) New Revision: 1203 Modified: SQLObject/branches/0.7-bugfix/docs/SQLObject.txt Log: Added a pointer to psycopg2. Modified: SQLObject/branches/0.7-bugfix/docs/SQLObject.txt =================================================================== --- SQLObject/branches/0.7-bugfix/docs/SQLObject.txt 2005-11-03 12:15:48 UTC (rev 1202) +++ SQLObject/branches/0.7-bugfix/docs/SQLObject.txt 2005-11-03 12:22:15 UTC (rev 1203) @@ -44,13 +44,15 @@ ============ Currently SQLObject supports MySQL_ via MySQLdb_ aka MySQL-python, -PostgreSQL_ via psycopg_, SQLite_ via PySQLite_, Firebird_ via kinterbasdb_, -Sybase via Sybase_, and `MAX DB`_ (also known as SAP DB) via sapdb_. +PostgreSQL_ via psycopg1_ or psycopg2_, SQLite_ via PySQLite_, +Firebird_ via kinterbasdb_, Sybase via Sybase_, and +`MAX DB`_ (also known as SAP DB) via sapdb_. .. _MySQL: http://mysql.com .. _MySQLdb: http://sourceforge.net/projects/mysql-python/ .. _PostgreSQL: http://postgresql.org -.. _psycopg: http://initd.org/projects/psycopg1 +.. _psycopg1: http://initd.org/projects/psycopg1 +.. _psycopg2: http://initd.org/projects/psycopg2 .. _SQLite: http://sqlite.org .. _PySQLite: http://initd.org/projects/pysqlite .. _Firebird: http://firebird.sourceforge.net |
|
From: <sub...@co...> - 2005-11-03 12:17:23
|
Author: phd
Date: 2005-11-03 12:15:48 +0000 (Thu, 03 Nov 2005)
New Revision: 1202
Added:
home/phd/SQLObject/paramstyles/sqlobject/tests/test_events.py
Modified:
home/phd/SQLObject/paramstyles/docs/News.txt
home/phd/SQLObject/paramstyles/sqlobject/events.py
home/phd/SQLObject/paramstyles/sqlobject/main.py
home/phd/SQLObject/paramstyles/sqlobject/sresults.py
home/phd/SQLObject/paramstyles/sqlobject/tests/test_select.py
Log:
Merged patches from the revisions 1196:1201 from the trunk
Modified: home/phd/SQLObject/paramstyles/docs/News.txt
===================================================================
--- home/phd/SQLObject/paramstyles/docs/News.txt 2005-11-03 08:17:07 UTC (rev 1201)
+++ home/phd/SQLObject/paramstyles/docs/News.txt 2005-11-03 12:15:48 UTC (rev 1202)
@@ -43,6 +43,13 @@
This will run ``process_request(os.environ)``. The return
value will be preserved.
+* Added method ``.getOne([default])`` to ``SelectResults`` (these are
+ the objects returned by ``.select()`` and ``.selectBy()``). This
+ returns a single object, when the query is expected to return only
+ one object. The single argument is the value to return when zero
+ results are found (more than one result is always an error). If no
+ default is given, it is an error if no such object exists.
+
SQLObject 0.7.1
===============
Modified: home/phd/SQLObject/paramstyles/sqlobject/events.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/events.py 2005-11-03 08:17:07 UTC (rev 1201)
+++ home/phd/SQLObject/paramstyles/sqlobject/events.py 2005-11-03 12:15:48 UTC (rev 1202)
@@ -14,9 +14,8 @@
an event is fired on any subclass.
"""
dispatcher.connect(receiver, signal=signal, sender=soClass)
- weakSOClass = ref(soClass)
weakReceiver = ref(receiver)
- subclassClones.setdefault(weakSOClass, []).append((weakReceiver, signal))
+ subclassClones.setdefault(soClass, []).append((weakReceiver, signal))
# We export this function:
send = dispatcher.send
@@ -53,7 +52,7 @@
receiver = weakReceiver()
if not receiver:
continue
- dispatcher.connect(receiver, signal=signal, sender=new_class)
+ listen(receiver, new_class, signal)
dispatcher.connect(_makeSubclassConnections, signal=ClassCreateSignal)
Modified: home/phd/SQLObject/paramstyles/sqlobject/main.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/main.py 2005-11-03 08:17:07 UTC (rev 1201)
+++ home/phd/SQLObject/paramstyles/sqlobject/main.py 2005-11-03 12:15:48 UTC (rev 1202)
@@ -297,6 +297,7 @@
def addColumn(cls, columnDef, changeSchema=False, connection=None):
post_funcs = []
+ print "Send on", cls.soClass, columnDef.name
cls.send(events.AddColumnSignal, cls.soClass, connection,
columnDef.name, columnDef, changeSchema, post_funcs)
sqlmeta = cls
@@ -1060,7 +1061,8 @@
# the parts are set. So we just keep them in a
# dictionary until later:
d = {name: value}
- self.sqlmeta.send(events.RowUpdateSignal, self, d)
+ if not self.sqlmeta._creating:
+ self.sqlmeta.send(events.RowUpdateSignal, self, d)
if len(d) != 1 or name not in d:
return self.set(**d)
value = d[name]
@@ -1084,7 +1086,8 @@
setattr(self, instanceName(name), value)
def set(self, **kw):
- self.sqlmeta.send(events.RowUpdateSignal, self, kw)
+ if not self.sqlmeta._creating:
+ self.sqlmeta.send(events.RowUpdateSignal, self, kw)
# set() is used to update multiple values at once,
# potentially with one SQL statement if possible.
Modified: home/phd/SQLObject/paramstyles/sqlobject/sresults.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/sresults.py 2005-11-03 08:17:07 UTC (rev 1201)
+++ home/phd/SQLObject/paramstyles/sqlobject/sresults.py 2005-11-03 12:15:48 UTC (rev 1202)
@@ -1,5 +1,6 @@
import sqlbuilder
import dbconnection
+import main
StringType = type('')
@@ -227,4 +228,29 @@
def max(self, attribute):
return self.accumulateOne("MAX", attribute)
+ def getOne(self, default=sqlbuilder.NoDefault):
+ """
+ If a query is expected to only return a single value,
+ using ``.getOne()`` will return just that value.
+
+ If not results are found, ``SQLObjectNotFound`` will be
+ raised, unless you pass in a default value (like
+ ``.getOne(None)``).
+
+ If more than one result is returned,
+ ``SQLObjectIntegrityError`` will be raised.
+ """
+ results = list(self)
+ if not results:
+ if default is sqlbuilder.NoDefault:
+ raise main.SQLObjectNotFound(
+ "No results matched the query for %s"
+ % self.sourceClass.__name__)
+ return default
+ if len(results) > 1:
+ raise main.SQLObjectIntegrityError(
+ "More than one result returned from query: %s"
+ % results)
+ return results[0]
+
__all__ = ['SelectResults']
Copied: home/phd/SQLObject/paramstyles/sqlobject/tests/test_events.py (from rev 1201, SQLObject/trunk/sqlobject/tests/test_events.py)
Modified: home/phd/SQLObject/paramstyles/sqlobject/tests/test_select.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/tests/test_select.py 2005-11-03 08:17:07 UTC (rev 1201)
+++ home/phd/SQLObject/paramstyles/sqlobject/tests/test_select.py 2005-11-03 12:15:48 UTC (rev 1202)
@@ -1,6 +1,8 @@
from __future__ import generators # for enumerate
from sqlobject import *
+from sqlobject.main import SQLObjectIntegrityError
from sqlobject.tests.dbtest import *
+from py.test import raises
try:
enumerate
@@ -71,6 +73,18 @@
pass
assert count == len(names)
+def test_select_getOne():
+ setupClass(IterTest)
+ a = IterTest(name='a')
+ b = IterTest(name='b')
+ assert IterTest.selectBy(name='a').getOne() == a
+ assert IterTest.select(IterTest.q.name=='b').getOne() == b
+ assert IterTest.selectBy(name='c').getOne(None) is None
+ raises(SQLObjectNotFound, 'IterTest.selectBy(name="c").getOne()')
+ b2 = IterTest(name='b')
+ raises(SQLObjectIntegrityError, 'IterTest.selectBy(name="b").getOne()')
+ raises(SQLObjectIntegrityError, 'IterTest.selectBy(name="b").getOne(None)')
+
|
|
From: <sub...@co...> - 2005-11-03 08:17:18
|
Author: ianb
Date: 2005-11-03 08:17:07 +0000 (Thu, 03 Nov 2005)
New Revision: 1201
Modified:
SQLObject/trunk/sqlobject/main.py
SQLObject/trunk/sqlobject/tests/test_events.py
Log:
Some more tests and a fix (last test is broken, but disabled)
Modified: SQLObject/trunk/sqlobject/main.py
===================================================================
--- SQLObject/trunk/sqlobject/main.py 2005-11-03 08:06:05 UTC (rev 1200)
+++ SQLObject/trunk/sqlobject/main.py 2005-11-03 08:17:07 UTC (rev 1201)
@@ -297,6 +297,7 @@
def addColumn(cls, columnDef, changeSchema=False, connection=None):
post_funcs = []
+ print "Send on", cls.soClass, columnDef.name
cls.send(events.AddColumnSignal, cls.soClass, connection,
columnDef.name, columnDef, changeSchema, post_funcs)
sqlmeta = cls
@@ -1060,7 +1061,8 @@
# the parts are set. So we just keep them in a
# dictionary until later:
d = {name: value}
- self.sqlmeta.send(events.RowUpdateSignal, self, d)
+ if not self.sqlmeta._creating:
+ self.sqlmeta.send(events.RowUpdateSignal, self, d)
if len(d) != 1 or name not in d:
return self.set(**d)
value = d[name]
@@ -1084,7 +1086,8 @@
setattr(self, instanceName(name), value)
def set(self, **kw):
- self.sqlmeta.send(events.RowUpdateSignal, self, kw)
+ if not self.sqlmeta._creating:
+ self.sqlmeta.send(events.RowUpdateSignal, self, kw)
# set() is used to update multiple values at once,
# potentially with one SQL statement if possible.
Modified: SQLObject/trunk/sqlobject/tests/test_events.py
===================================================================
--- SQLObject/trunk/sqlobject/tests/test_events.py 2005-11-03 08:06:05 UTC (rev 1200)
+++ SQLObject/trunk/sqlobject/tests/test_events.py 2005-11-03 08:17:07 UTC (rev 1201)
@@ -13,9 +13,15 @@
watch.log = log
return watch
+def make_listen(signal, cls=None):
+ if cls is None:
+ cls = EventTester
+ watcher = make_watcher()
+ events.listen(watcher, cls, signal)
+ return watcher
+
def test_create():
- watcher = make_watcher()
- events.listen(watcher, EventTester, events.ClassCreateSignal)
+ watcher = make_listen(events.ClassCreateSignal)
class EventTesterSub1(EventTester):
pass
class EventTesterSub2(EventTesterSub1):
@@ -27,3 +33,40 @@
assert isinstance(watcher.log[0][2], dict)
assert isinstance(watcher.log[0][3], list)
+def test_row_create():
+ setupClass(EventTester)
+ watcher = make_listen(events.RowCreateSignal)
+ EventTester(name='foo')
+ EventTester(name='bar')
+ assert len(watcher.log) == 2
+ assert watcher.log[0] == ({'name': 'foo'}, [])
+
+def test_row_destrow():
+ setupClass(EventTester)
+ watcher = make_listen(events.RowDestroySignal)
+ f = EventTester(name='foo')
+ assert not watcher.log
+ f.destroySelf()
+ assert watcher.log == [(f,)]
+
+def test_row_update():
+ setupClass(EventTester)
+ watcher = make_listen(events.RowUpdateSignal)
+ f = EventTester(name='bar')
+ assert not watcher.log
+ f.name = 'bar2'
+ f.set(name='bar3')
+ assert watcher.log == [
+ (f, {'name': 'bar2'}),
+ (f, {'name': 'bar3'})]
+
+def disbaled_test_add_column():
+ setupClass(EventTester)
+ watcher = make_listen(events.RowUpdateSignal)
+ class NewEventTester(EventTester):
+ name2 = StringCol()
+ assert watcher.log == [
+ (NewEventTester, NewEventTester._connection,
+ 'name2', NewEventTester.sqlmeta.columns['name2'],
+ True, [])]
+
|
|
From: <sub...@co...> - 2005-11-03 08:06:15
|
Author: ianb
Date: 2005-11-03 08:06:05 +0000 (Thu, 03 Nov 2005)
New Revision: 1200
Added:
SQLObject/trunk/sqlobject/tests/test_events.py
Modified:
SQLObject/trunk/sqlobject/events.py
Log:
Started event testing; fixed bug with inheriting listeners
Modified: SQLObject/trunk/sqlobject/events.py
===================================================================
--- SQLObject/trunk/sqlobject/events.py 2005-11-03 02:14:20 UTC (rev 1199)
+++ SQLObject/trunk/sqlobject/events.py 2005-11-03 08:06:05 UTC (rev 1200)
@@ -14,9 +14,8 @@
an event is fired on any subclass.
"""
dispatcher.connect(receiver, signal=signal, sender=soClass)
- weakSOClass = ref(soClass)
weakReceiver = ref(receiver)
- subclassClones.setdefault(weakSOClass, []).append((weakReceiver, signal))
+ subclassClones.setdefault(soClass, []).append((weakReceiver, signal))
# We export this function:
send = dispatcher.send
@@ -53,7 +52,7 @@
receiver = weakReceiver()
if not receiver:
continue
- dispatcher.connect(receiver, signal=signal, sender=new_class)
+ listen(receiver, new_class, signal)
dispatcher.connect(_makeSubclassConnections, signal=ClassCreateSignal)
Added: SQLObject/trunk/sqlobject/tests/test_events.py
===================================================================
--- SQLObject/trunk/sqlobject/tests/test_events.py 2005-11-03 02:14:20 UTC (rev 1199)
+++ SQLObject/trunk/sqlobject/tests/test_events.py 2005-11-03 08:06:05 UTC (rev 1200)
@@ -0,0 +1,29 @@
+from sqlobject import *
+from sqlobject.tests.dbtest import *
+from sqlobject import events
+import sys
+
+class EventTester(SQLObject):
+ name = StringCol()
+
+def make_watcher():
+ log = []
+ def watch(*args):
+ log.append(args)
+ watch.log = log
+ return watch
+
+def test_create():
+ watcher = make_watcher()
+ events.listen(watcher, EventTester, events.ClassCreateSignal)
+ class EventTesterSub1(EventTester):
+ pass
+ class EventTesterSub2(EventTesterSub1):
+ pass
+ assert len(watcher.log) == 2
+ assert len(watcher.log[0]) == 4
+ assert watcher.log[0][0] == 'EventTesterSub1'
+ assert watcher.log[0][1] == (EventTester,)
+ assert isinstance(watcher.log[0][2], dict)
+ assert isinstance(watcher.log[0][3], list)
+
|
|
From: <sub...@co...> - 2005-11-02 21:37:53
|
Author: test
Date: 2005-11-02 21:37:43 +0000 (Wed, 02 Nov 2005)
New Revision: 1197
Modified:
SQLObject/trunk/docs/News.txt
SQLObject/trunk/sqlobject/sresults.py
SQLObject/trunk/sqlobject/tests/test_select.py
Log:
Added .getOne() method to SelectResults
Modified: SQLObject/trunk/docs/News.txt
===================================================================
--- SQLObject/trunk/docs/News.txt 2005-11-02 20:51:34 UTC (rev 1196)
+++ SQLObject/trunk/docs/News.txt 2005-11-02 21:37:43 UTC (rev 1197)
@@ -43,6 +43,13 @@
This will run ``process_request(os.environ)``. The return
value will be preserved.
+* Added method ``.getOne([default])`` to ``SelectResults`` (these are
+ the objects returned by ``.select()`` and ``.selectBy()``). This
+ returns a single object, when the query is expected to return only
+ one object. The single argument is the value to return when zero
+ results are found (more than one result is always an error). If no
+ default is given, it is an error if no such object exists.
+
SQLObject 0.7.1
===============
Modified: SQLObject/trunk/sqlobject/sresults.py
===================================================================
--- SQLObject/trunk/sqlobject/sresults.py 2005-11-02 20:51:34 UTC (rev 1196)
+++ SQLObject/trunk/sqlobject/sresults.py 2005-11-02 21:37:43 UTC (rev 1197)
@@ -1,5 +1,6 @@
import sqlbuilder
import dbconnection
+import main
StringType = type('')
@@ -227,4 +228,29 @@
def max(self, attribute):
return self.accumulateOne("MAX", attribute)
+ def getOne(self, default=sqlbuilder.NoDefault):
+ """
+ If a query is expected to only return a single value,
+ using ``.getOne()`` will return just that value.
+
+ If not results are found, ``SQLObjectNotFound`` will be
+ raised, unless you pass in a default value (like
+ ``.getOne(None)``).
+
+ If more than one result is returned,
+ ``SQLObjectIntegrityError`` will be raised.
+ """
+ results = list(self)
+ if not results:
+ if default is sqlbuilder.NoDefault:
+ raise main.SQLObjectNotFound(
+ "No results matched the query for %s"
+ % self.sourceClass.__name__)
+ return default
+ if len(results) > 1:
+ raise main.SQLObjectIntegrityError(
+ "More than one result returned from query: %s"
+ % results)
+ return results[0]
+
__all__ = ['SelectResults']
Modified: SQLObject/trunk/sqlobject/tests/test_select.py
===================================================================
--- SQLObject/trunk/sqlobject/tests/test_select.py 2005-11-02 20:51:34 UTC (rev 1196)
+++ SQLObject/trunk/sqlobject/tests/test_select.py 2005-11-02 21:37:43 UTC (rev 1197)
@@ -1,6 +1,8 @@
from __future__ import generators # for enumerate
from sqlobject import *
+from sqlobject.main import SQLObjectIntegrityError
from sqlobject.tests.dbtest import *
+from py.test import raises
try:
enumerate
@@ -71,6 +73,18 @@
pass
assert count == len(names)
+def test_select_getOne():
+ setupClass(IterTest)
+ a = IterTest(name='a')
+ b = IterTest(name='b')
+ assert IterTest.selectBy(name='a').getOne() == a
+ assert IterTest.select(IterTest.q.name=='b').getOne() == b
+ assert IterTest.selectBy(name='c').getOne(None) is None
+ raises(SQLObjectNotFound, 'IterTest.selectBy(name="c").getOne()')
+ b2 = IterTest(name='b')
+ raises(SQLObjectIntegrityError, 'IterTest.selectBy(name="b").getOne()')
+ raises(SQLObjectIntegrityError, 'IterTest.selectBy(name="b").getOne(None)')
+
|
|
From: SourceForge.net <no...@so...> - 2005-11-02 21:05:16
|
Bugs item #1344338, was opened at 2005-10-31 17:28 Message generated for change (Comment added) made by adustman You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1344338&group_id=74338 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: MySQL Group: SQLObject release (specify) Status: Open Resolution: None Priority: 5 Submitted By: Andy Dustman (adustman) Assigned to: Nobody/Anonymous (nobody) Summary: 0.7.0: autoCommit from URI wrong type Initial Comment: In dbconnection.py, when the URI is parsed, there is no special treatment or type conversion of the autoCommit parameter, so it is always stored as a string. In the MySQL case (mysql.mysqlconnection), this causes the call to conn.autocommit() to always, since that API function requires an integer (booleans work too). A workaround for this is to change conn.autocommit(self.autoCommit) to conn.autocommit(int(self.autoCommit)), though only works if an integer is used as a parameter; it fails if True or False is used. Note that sybase support has this sequence in SybaseConnection.__init__(): autoCommit = kw.get('autoCommit') if autoCommit: autoCommmit = int(autoCommit) else: autoCommit = None kw['autoCommit'] = autoCommit DBAPI.__init__(self, **kw) A similar block of code would also work for MySQLdb. ---------------------------------------------------------------------- >Comment By: Andy Dustman (adustman) Date: 2005-11-02 16:05 Message: Logged In: YES user_id=71372 That doesn't work; I tried it previously. It results in SQLObject trying to do conn.autocommit(''), which still results in a TypeError. Even though '' == False, it is not an integer, and thismethod requires an integer (or boolean). ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2005-11-02 15:42 Message: Logged In: YES user_id=4799 Pass autoCommit as an empty string: mysql://server:port/db?autoCommit=&debug= ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1344338&group_id=74338 |
|
From: <sub...@co...> - 2005-11-02 20:51:39
|
Author: phd
Date: 2005-11-02 20:51:34 +0000 (Wed, 02 Nov 2005)
New Revision: 1196
Modified:
home/phd/SQLObject/paramstyles/docs/SQLObject.txt
Log:
Merged patches from the revisions 1193:1195 from the trunk
Modified: home/phd/SQLObject/paramstyles/docs/SQLObject.txt
===================================================================
--- home/phd/SQLObject/paramstyles/docs/SQLObject.txt 2005-11-02 20:48:45 UTC (rev 1195)
+++ home/phd/SQLObject/paramstyles/docs/SQLObject.txt 2005-11-02 20:51:34 UTC (rev 1196)
@@ -974,7 +974,7 @@
If you give a callable object or function, the function will be
called, and the return value will be used. So you can give
``DateTime.now`` to make the default value be the current time.
- Or you can use ``SQLBuilder.func.NOW()`` to have the database use
+ Or you can use ``sqlbuilder.func.NOW()`` to have the database use
the ``NOW()`` function internally. If you don't give a default
there will be an exception if this column isn't specified in the
call to `new`.
|
|
From: SourceForge.net <no...@so...> - 2005-11-02 20:50:35
|
Bugs item #1346103, was opened at 2005-11-02 19:03 Message generated for change (Comment added) made by phd You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1346103&group_id=74338 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: Postgres Group: None >Status: Closed >Resolution: Duplicate Priority: 5 Submitted By: Felipe Hoffa (fhoffa) Assigned to: Nobody/Anonymous (nobody) Summary: working with schemas Initial Comment: We use heavily schemas within a database (using PostgreSQL), and SQLObject has trouble identifying the primary with a table that lives in a schema, or a table in the default schema that has the same name than a table in other schema. In pgconnection.py I patched the following code and everything worked afterwards, but now I have to specify the schema name even for the tables in the default one: primaryKeyQuery = """ SELECT pg_index.indisprimary, pg_catalog.pg_get_indexdef(pg_index.indexrelid) FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index AS pg_index WHERE c.relname = %s AND c.oid = pg_index.indrelid AND pg_index.indexrelid = c2.oid AND pg_index.indisprimary AND pg_namespace.oid=c.relnamespace AND %s=pg_namespace.nspname """ keyData = self.queryAll(keyQuery % self.sqlrepr(tableName)) keyRE = re.compile(r"\((.+)\) REFERENCES (.+)\(") keymap = {} for (condef,) in keyData: match = keyRE.search(condef) if match: field, reftable = match.groups() keymap[field] = reftable.capitalize() sqlrepr = self.sqlrepr(tableName) table = "'"+sqlrepr[sqlrepr.find('.')+1:] schema = sqlrepr[0:sqlrepr.find('.')]+"'" primaryData = self.queryAll(primaryKeyQuery % (table, schema)) The code above parses the schema and the table name from a sqlrepr as "public.user" and uses the schema for a new where clause in the select query ("%s=pg_namespace.nspname") joining with the internal table that maps oids with schema names ("pg_namespace.oid=c.relnamespace"). I don't have a lot of experience with Python yet, otherwise I would have sumbitted a patch. ---------------------------------------------------------------------- >Comment By: Oleg Broytmann (phd) Date: 2005-11-02 23:50 Message: Logged In: YES user_id=4799 Dup of the bug 1346066. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1346103&group_id=74338 |
|
From: SourceForge.net <no...@so...> - 2005-11-02 20:49:09
|
Bugs item #1345587, was opened at 2005-11-02 08:00 Message generated for change (Comment added) made by phd You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1345587&group_id=74338 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: General Group: SQLObject from repository >Status: Closed >Resolution: Fixed Priority: 5 Submitted By: elpargo (elpargo) Assigned to: Nobody/Anonymous (nobody) Summary: Documentation says SQLBuilder went it should be sqlbuilder Initial Comment: pretty much Summary, where to find it ? http://sqlobject.org/SQLObject.html#col-class-specifying-columns under default: it says SQLBuilder.func.NOW() it should be sqlbuilder.func.NOW() ---------------------------------------------------------------------- >Comment By: Oleg Broytmann (phd) Date: 2005-11-02 23:49 Message: Logged In: YES user_id=4799 Fixed at the revision 1194. Thank you! ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1345587&group_id=74338 |
|
From: <sub...@co...> - 2005-11-02 20:48:53
|
Author: phd
Date: 2005-11-02 20:48:45 +0000 (Wed, 02 Nov 2005)
New Revision: 1195
Modified:
SQLObject/branches/0.7-bugfix/docs/SQLObject.txt
Log:
Merged patch from revision 1193:1194.
Modified: SQLObject/branches/0.7-bugfix/docs/SQLObject.txt
===================================================================
--- SQLObject/branches/0.7-bugfix/docs/SQLObject.txt 2005-11-02 20:46:15 UTC (rev 1194)
+++ SQLObject/branches/0.7-bugfix/docs/SQLObject.txt 2005-11-02 20:48:45 UTC (rev 1195)
@@ -969,7 +969,7 @@
If you give a callable object or function, the function will be
called, and the return value will be used. So you can give
``DateTime.now`` to make the default value be the current time.
- Or you can use ``SQLBuilder.func.NOW()`` to have the database use
+ Or you can use ``sqlbuilder.func.NOW()`` to have the database use
the ``NOW()`` function internally. If you don't give a default
there will be an exception if this column isn't specified in the
call to `new`.
|
|
From: <sub...@co...> - 2005-11-02 20:46:19
|
Author: phd
Date: 2005-11-02 20:46:15 +0000 (Wed, 02 Nov 2005)
New Revision: 1194
Modified:
SQLObject/trunk/docs/SQLObject.txt
Log:
Fixed bug 1345587 - the module is sqlbuilder, not SQLBuilder.
Modified: SQLObject/trunk/docs/SQLObject.txt
===================================================================
--- SQLObject/trunk/docs/SQLObject.txt 2005-11-02 20:37:21 UTC (rev 1193)
+++ SQLObject/trunk/docs/SQLObject.txt 2005-11-02 20:46:15 UTC (rev 1194)
@@ -974,7 +974,7 @@
If you give a callable object or function, the function will be
called, and the return value will be used. So you can give
``DateTime.now`` to make the default value be the current time.
- Or you can use ``SQLBuilder.func.NOW()`` to have the database use
+ Or you can use ``sqlbuilder.func.NOW()`` to have the database use
the ``NOW()`` function internally. If you don't give a default
there will be an exception if this column isn't specified in the
call to `new`.
|
|
From: SourceForge.net <no...@so...> - 2005-11-02 20:42:29
|
Bugs item #1344338, was opened at 2005-11-01 01:28 Message generated for change (Comment added) made by phd You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1344338&group_id=74338 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: MySQL Group: SQLObject release (specify) Status: Open Resolution: None Priority: 5 Submitted By: Andy Dustman (adustman) Assigned to: Nobody/Anonymous (nobody) Summary: 0.7.0: autoCommit from URI wrong type Initial Comment: In dbconnection.py, when the URI is parsed, there is no special treatment or type conversion of the autoCommit parameter, so it is always stored as a string. In the MySQL case (mysql.mysqlconnection), this causes the call to conn.autocommit() to always, since that API function requires an integer (booleans work too). A workaround for this is to change conn.autocommit(self.autoCommit) to conn.autocommit(int(self.autoCommit)), though only works if an integer is used as a parameter; it fails if True or False is used. Note that sybase support has this sequence in SybaseConnection.__init__(): autoCommit = kw.get('autoCommit') if autoCommit: autoCommmit = int(autoCommit) else: autoCommit = None kw['autoCommit'] = autoCommit DBAPI.__init__(self, **kw) A similar block of code would also work for MySQLdb. ---------------------------------------------------------------------- >Comment By: Oleg Broytmann (phd) Date: 2005-11-02 23:42 Message: Logged In: YES user_id=4799 Pass autoCommit as an empty string: mysql://server:port/db?autoCommit=&debug= ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1344338&group_id=74338 |
|
From: <sub...@co...> - 2005-11-02 20:37:37
|
Author: phd
Date: 2005-11-02 20:37:21 +0000 (Wed, 02 Nov 2005)
New Revision: 1193
Added:
home/phd/SQLObject/paramstyles/sqlobject/tests/test_index_get.py
Modified:
home/phd/SQLObject/paramstyles/docs/SQLBuilder.txt
home/phd/SQLObject/paramstyles/docs/index.txt
home/phd/SQLObject/paramstyles/sqlobject/conftest.py
home/phd/SQLObject/paramstyles/sqlobject/dbconnection.py
home/phd/SQLObject/paramstyles/sqlobject/index.py
home/phd/SQLObject/paramstyles/sqlobject/main.py
Log:
Merged patches from the revisions 1186:1192 from the trunk
Modified: home/phd/SQLObject/paramstyles/docs/SQLBuilder.txt
===================================================================
--- home/phd/SQLObject/paramstyles/docs/SQLBuilder.txt 2005-11-02 20:33:36 UTC (rev 1192)
+++ home/phd/SQLObject/paramstyles/docs/SQLBuilder.txt 2005-11-02 20:37:21 UTC (rev 1193)
@@ -34,7 +34,7 @@
>>> person.first_name != name
person.first_name <> 'John'
>>> AND(person.first_name == 'John', person.last_name == 'Doe')
- (person.first_name = 'John AND person.last_name = 'Doe')
+ (person.first_name = 'John' AND person.last_name = 'Doe')
Most of the operators work properly: <, >, <=, >=, !=, ==, +, -, /,
\*, \*\*, %. However, ``and``, ``or``, and ``not`` **do not work**.
Modified: home/phd/SQLObject/paramstyles/docs/index.txt
===================================================================
--- home/phd/SQLObject/paramstyles/docs/index.txt 2005-11-02 20:33:36 UTC (rev 1192)
+++ home/phd/SQLObject/paramstyles/docs/index.txt 2005-11-02 20:37:21 UTC (rev 1193)
@@ -19,7 +19,7 @@
* `News and updates <News.html>`_
* `Main SQLObject documentation <SQLObject.html>`_
-* `sqlbuiler documentation <SQLBuilder.html>`_
+* `sqlbuilder documentation <SQLBuilder.html>`_
* `sqlobject-admin documentation <sqlobject-admin.html>`_
* `Frequently Asked Questions <FAQ.html>`_
* `Inheritance <Inheritance.html>`_
Modified: home/phd/SQLObject/paramstyles/sqlobject/conftest.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/conftest.py 2005-11-02 20:33:36 UTC (rev 1192)
+++ home/phd/SQLObject/paramstyles/sqlobject/conftest.py 2005-11-02 20:37:21 UTC (rev 1193)
@@ -10,9 +10,14 @@
import py
import os
import sqlobject
-import pkg_resources
-pkg_resources.require('SQLObject')
+try:
+ import pkg_resources
+except ImportError: # Python 2.2
+ pass
+else:
+ pkg_resources.require('SQLObject')
+
connectionShortcuts = {
'mysql': 'mysql://test@localhost/test',
'dbm': 'dbm:///data',
Modified: home/phd/SQLObject/paramstyles/sqlobject/dbconnection.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/dbconnection.py 2005-11-02 20:33:36 UTC (rev 1192)
+++ home/phd/SQLObject/paramstyles/sqlobject/dbconnection.py 2005-11-02 20:37:21 UTC (rev 1193)
@@ -631,11 +631,19 @@
self.sqlrepr(so.id)))
def _SO_selectOneAlt(self, cls, columnNames, column, value):
- return self.queryOne("SELECT %s FROM %s WHERE %s = %s" %
+ if isinstance(column, str):
+ column = (column,)
+ value = (value,)
+ if len(column) != len(value):
+ raise ValueError, "'column' and 'value' tuples must be of the same size"
+ columns = []
+ for i in xrange(len(column)):
+ columns.append("%s = %s" % (column[i], self.sqlrepr(value[i])))
+ condition = ' AND '.join(columns)
+ return self.queryOne("SELECT %s FROM %s WHERE %s" %
(", ".join(columnNames),
cls.sqlmeta.table,
- column,
- self.sqlrepr(value)))
+ condition))
def _SO_delete(self, so):
self.query("DELETE FROM %s WHERE %s = %s" %
Modified: home/phd/SQLObject/paramstyles/sqlobject/index.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/index.py 2005-11-02 20:33:36 UTC (rev 1192)
+++ home/phd/SQLObject/paramstyles/sqlobject/index.py 2005-11-02 20:37:21 UTC (rev 1193)
@@ -14,6 +14,29 @@
self.descriptions = self.convertColumns(columns)
self.unique = unique
+ def get(self, *args, **kw):
+ if not self.unique:
+ raise AttributeError, (
+ "'%s' object has no attribute 'get' (index is not unique)" % self.name)
+ connection = col.popKey(kw, 'connection', None)
+ if args and kw:
+ raise TypeError, "You cannot mix named and unnamed arguments"
+ columns = [d['column'] for d in self.descriptions
+ if d.has_key('column')]
+ if kw:
+ args = []
+ for i in xrange(len(columns)):
+ args.append(kw[columns[i].name])
+ del kw[columns[i].name]
+ if kw or len(args) != len(columns):
+ raise TypeError, ("get() takes exactly %d argument and an optional "
+ "named argument 'connection' (%d given)" % (
+ len(columns), len(args)+len(kw)))
+ cols = [c.name for c in columns]
+ dbcols = [c.dbName for c in columns]
+ return self.soClass._SO_fetchAlternateID(cols, dbcols, args,
+ connection=connection, idxName=self.name)
+
def convertColumns(self, columns):
"""
Converts all the columns to dictionary descriptors;
Modified: home/phd/SQLObject/paramstyles/sqlobject/main.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/main.py 2005-11-02 20:33:36 UTC (rev 1192)
+++ home/phd/SQLObject/paramstyles/sqlobject/main.py 2005-11-02 20:37:21 UTC (rev 1193)
@@ -436,7 +436,8 @@
addColumnsFromDatabase = classmethod(addColumnsFromDatabase)
- def delColumn(sqlmeta, column, changeSchema=False, connection=None):
+ def delColumn(cls, column, changeSchema=False, connection=None):
+ sqlmeta = cls
soClass = sqlmeta.soClass
if isinstance(column, str):
column = sqlmeta.columns[column]
@@ -578,6 +579,7 @@
cls.indexDefinitions.append(indexDef)
index = indexDef.withClass(cls.soClass)
cls.indexes.append(index)
+ setattr(cls.soClass, index.name, index)
addIndex = classmethod(addIndex)
########################################
@@ -1290,10 +1292,17 @@
value), None
_findAlternateID = classmethod(_findAlternateID)
- def _SO_fetchAlternateID(cls, name, dbName, value, connection=None):
+ def _SO_fetchAlternateID(cls, name, dbName, value, connection=None, idxName=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__, name, repr(value))
+ if idxName is None:
+ raise SQLObjectNotFound, "The %s by alternateID %s = %s does not exist" % (cls.__name__, name, repr(value))
+ else:
+ names = []
+ for i in xrange(len(name)):
+ names.append("%s = %s" % (name[i], repr(value[i])))
+ names = ', '.join(names)
+ raise SQLObjectNotFound, "The %s by unique index %s(%s) does not exist" % (cls.__name__, idxName, names)
if obj:
return obj
if connection:
Copied: home/phd/SQLObject/paramstyles/sqlobject/tests/test_index_get.py (from rev 1192, SQLObject/trunk/sqlobject/tests/test_index_get.py)
|
|
From: SourceForge.net <no...@so...> - 2005-11-02 20:36:08
|
Patches item #1341999, was opened at 2005-10-30 02:16 Message generated for change (Comment added) made by phd You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1341999&group_id=74338 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: None Group: None >Status: Closed >Resolution: Accepted Priority: 5 Submitted By: Leandro Lucarella (llucax) Assigned to: Oleg Broytmann (phd) Summary: Adds by[IndexName] method for every unique index. Initial Comment: This is the summary of changes (copied from the patch). User-visible Changes: Now, fo each DatabaseIndex with unique=True you have an extra method by[IndexName] like by[AlternateID], that takes as parameters the columns used in the index. You can specify an extra option when creating DatabaseIndex, alternateMethodName, just like with Columns with alternateID=True. Internal Changes: Now dbconnection.DBAPI._SO_selectOneAlt() can accept a sequence for 'column' and 'value' parameters. Both must have the same len() and it's mapped in the query as column[0] = value[0] AND ... column[N] = value[N] index.SODatabaseIndex() constructor takes an extra optional parameter 'alternateMethodName' wich is set by default to by[IndexName]. main.sqlmeta.addIndex() now adds the proper by[IndexName] method to soClass, using main.sqlmeta._SO_fetchAlternateID() to retrieve the data. main.sqlmeta._SO_fetchAlternateID() now takes an extra optional parameter 'idxName' with the index name (when it's called for an index) for error reporting purpose. 'column' and 'value' parameters can accept a sequence just like dbconnection.DBAPI._SO_selectOneAlt(). ---------------------------------------------------------------------- >Comment By: Oleg Broytmann (phd) Date: 2005-11-02 23:36 Message: Logged In: YES user_id=4799 Applied at the revision 1192 to the trunk. Thank you! ---------------------------------------------------------------------- Comment By: Ian Bicking (ianbicking) Date: 2005-10-31 20:06 Message: Logged In: YES user_id=210337 (copied from email comments) I don't want anymore automatic addition of methods to SQLObject classes -- I'm not very happy with the ones that already exist. Instead, I'd like index objects to become smarter, since they are already being explicitly named and put on the class as attributes. Potentially these objects could be callable, or have a .get() method. So it would be like: class Contact(SQLObject): areaCode = StringCol() number = StringCol() phoneIndex = DatabaseIndex('areaCode', 'number', unique=True) Contact.phoneIndex.get('555', '555-5555') # Also allowable: Contact.phoneIndex.get(number='555-5555', areaCode='555') ---------------------------------------------------------------------- Comment By: Leandro Lucarella (llucax) Date: 2005-10-30 02:20 Message: Logged In: YES user_id=240225 Here's a simple example of use. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1341999&group_id=74338 |
|
From: <sub...@co...> - 2005-11-02 20:33:41
|
Author: phd
Date: 2005-11-02 20:33:36 +0000 (Wed, 02 Nov 2005)
New Revision: 1192
Added:
SQLObject/trunk/sqlobject/tests/test_index_get.py
Modified:
SQLObject/trunk/sqlobject/dbconnection.py
SQLObject/trunk/sqlobject/index.py
SQLObject/trunk/sqlobject/main.py
Log:
Patch 1341999 index.get() for every unique index by Leandro Lucarella <lu...@ll...>.
Modified: SQLObject/trunk/sqlobject/dbconnection.py
===================================================================
--- SQLObject/trunk/sqlobject/dbconnection.py 2005-11-02 20:14:37 UTC (rev 1191)
+++ SQLObject/trunk/sqlobject/dbconnection.py 2005-11-02 20:33:36 UTC (rev 1192)
@@ -617,11 +617,19 @@
self.sqlrepr(so.id)))
def _SO_selectOneAlt(self, cls, columnNames, column, value):
- return self.queryOne("SELECT %s FROM %s WHERE %s = %s" %
+ if isinstance(column, str):
+ column = (column,)
+ value = (value,)
+ if len(column) != len(value):
+ raise ValueError, "'column' and 'value' tuples must be of the same size"
+ columns = []
+ for i in xrange(len(column)):
+ columns.append("%s = %s" % (column[i], self.sqlrepr(value[i])))
+ condition = ' AND '.join(columns)
+ return self.queryOne("SELECT %s FROM %s WHERE %s" %
(", ".join(columnNames),
cls.sqlmeta.table,
- column,
- self.sqlrepr(value)))
+ condition))
def _SO_delete(self, so):
self.query("DELETE FROM %s WHERE %s = %s" %
Modified: SQLObject/trunk/sqlobject/index.py
===================================================================
--- SQLObject/trunk/sqlobject/index.py 2005-11-02 20:14:37 UTC (rev 1191)
+++ SQLObject/trunk/sqlobject/index.py 2005-11-02 20:33:36 UTC (rev 1192)
@@ -14,6 +14,29 @@
self.descriptions = self.convertColumns(columns)
self.unique = unique
+ def get(self, *args, **kw):
+ if not self.unique:
+ raise AttributeError, (
+ "'%s' object has no attribute 'get' (index is not unique)" % self.name)
+ connection = col.popKey(kw, 'connection', None)
+ if args and kw:
+ raise TypeError, "You cannot mix named and unnamed arguments"
+ columns = [d['column'] for d in self.descriptions
+ if d.has_key('column')]
+ if kw:
+ args = []
+ for i in xrange(len(columns)):
+ args.append(kw[columns[i].name])
+ del kw[columns[i].name]
+ if kw or len(args) != len(columns):
+ raise TypeError, ("get() takes exactly %d argument and an optional "
+ "named argument 'connection' (%d given)" % (
+ len(columns), len(args)+len(kw)))
+ cols = [c.name for c in columns]
+ dbcols = [c.dbName for c in columns]
+ return self.soClass._SO_fetchAlternateID(cols, dbcols, args,
+ connection=connection, idxName=self.name)
+
def convertColumns(self, columns):
"""
Converts all the columns to dictionary descriptors;
Modified: SQLObject/trunk/sqlobject/main.py
===================================================================
--- SQLObject/trunk/sqlobject/main.py 2005-11-02 20:14:37 UTC (rev 1191)
+++ SQLObject/trunk/sqlobject/main.py 2005-11-02 20:33:36 UTC (rev 1192)
@@ -579,6 +579,7 @@
cls.indexDefinitions.append(indexDef)
index = indexDef.withClass(cls.soClass)
cls.indexes.append(index)
+ setattr(cls.soClass, index.name, index)
addIndex = classmethod(addIndex)
########################################
@@ -1291,10 +1292,17 @@
value), None
_findAlternateID = classmethod(_findAlternateID)
- def _SO_fetchAlternateID(cls, name, dbName, value, connection=None):
+ def _SO_fetchAlternateID(cls, name, dbName, value, connection=None, idxName=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__, name, repr(value))
+ if idxName is None:
+ raise SQLObjectNotFound, "The %s by alternateID %s = %s does not exist" % (cls.__name__, name, repr(value))
+ else:
+ names = []
+ for i in xrange(len(name)):
+ names.append("%s = %s" % (name[i], repr(value[i])))
+ names = ', '.join(names)
+ raise SQLObjectNotFound, "The %s by unique index %s(%s) does not exist" % (cls.__name__, idxName, names)
if obj:
return obj
if connection:
Added: SQLObject/trunk/sqlobject/tests/test_index_get.py
===================================================================
--- SQLObject/trunk/sqlobject/tests/test_index_get.py 2005-11-02 20:14:37 UTC (rev 1191)
+++ SQLObject/trunk/sqlobject/tests/test_index_get.py 2005-11-02 20:33:36 UTC (rev 1192)
@@ -0,0 +1,47 @@
+from sqlobject import *
+from sqlobject.tests.dbtest import *
+
+class Person(SQLObject):
+ firstName = StringCol()
+ lastName = StringCol()
+ age = IntCol(alternateID=True)
+ nameIndex = DatabaseIndex(firstName, lastName, unique=True)
+
+def test_1():
+ setupClass(Person)
+
+ Person(firstName='Eric', lastName='Idle', age=62)
+ Person(firstName='Terry', lastName='Gilliam', age=65)
+ Person(firstName='John', lastName='Cleese', age=66)
+
+ Person.get(1)
+ Person.nameIndex.get('Terry', 'Gilliam')
+ Person.nameIndex.get(firstName='John', lastName='Cleese')
+
+ try:
+ print Person.nameIndex.get(firstName='Graham', lastName='Chapman')
+ except Exception, e:
+ pass
+ else:
+ raise AssertError
+
+ try:
+ print Person.nameIndex.get('Terry', lastName='Gilliam')
+ except Exception, e:
+ pass
+ else:
+ raise AssertError
+
+ try:
+ print Person.nameIndex.get('Terry', 'Gilliam', 65)
+ except Exception, e:
+ pass
+ else:
+ raise AssertError
+
+ try:
+ print Person.nameIndex.get('Terry')
+ except Exception, e:
+ pass
+ else:
+ raise AssertError
|
|
From: <sub...@co...> - 2005-11-02 20:14:45
|
Author: phd
Date: 2005-11-02 20:14:37 +0000 (Wed, 02 Nov 2005)
New Revision: 1191
Modified:
SQLObject/trunk/sqlobject/main.py
Log:
Fixed a bug with cls/sqlmeta duality.
Modified: SQLObject/trunk/sqlobject/main.py
===================================================================
--- SQLObject/trunk/sqlobject/main.py 2005-11-02 20:07:16 UTC (rev 1190)
+++ SQLObject/trunk/sqlobject/main.py 2005-11-02 20:14:37 UTC (rev 1191)
@@ -436,7 +436,8 @@
addColumnsFromDatabase = classmethod(addColumnsFromDatabase)
- def delColumn(sqlmeta, column, changeSchema=False, connection=None):
+ def delColumn(cls, column, changeSchema=False, connection=None):
+ sqlmeta = cls
soClass = sqlmeta.soClass
if isinstance(column, str):
column = sqlmeta.columns[column]
|
|
From: <sub...@co...> - 2005-11-02 20:07:27
|
Author: phd
Date: 2005-11-02 20:07:16 +0000 (Wed, 02 Nov 2005)
New Revision: 1190
Modified:
SQLObject/trunk/sqlobject/conftest.py
Log:
Do not import pkg_resources under Python 2.2.
Modified: SQLObject/trunk/sqlobject/conftest.py
===================================================================
--- SQLObject/trunk/sqlobject/conftest.py 2005-11-02 18:24:51 UTC (rev 1189)
+++ SQLObject/trunk/sqlobject/conftest.py 2005-11-02 20:07:16 UTC (rev 1190)
@@ -10,9 +10,14 @@
import py
import os
import sqlobject
-import pkg_resources
-pkg_resources.require('SQLObject')
+try:
+ import pkg_resources
+except ImportError: # Python 2.2
+ pass
+else:
+ pkg_resources.require('SQLObject')
+
connectionShortcuts = {
'mysql': 'mysql://test@localhost/test',
'dbm': 'dbm:///data',
|