sqlobject-cvs Mailing List for SQLObject (Page 153)
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: SourceForge.net <no...@so...> - 2005-11-14 22:25:50
|
Bugs item #1356912, was opened at 2005-11-14 14:21 Message generated for change (Tracker Item Submitted) made by Item Submitter You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1356912&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: Open Resolution: None Priority: 5 Submitted By: Nobody/Anonymous (nobody) Assigned to: Nobody/Anonymous (nobody) Summary: another application using sqlobject Initial Comment: A not-so-new application using sqlobject: MyNewspaper http://inigo.katxi.org/devel/mynewspaper/ MyNewspaper is a personal RSS aggregator and reader with a Web UI. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1356912&group_id=74338 |
|
From: <sub...@co...> - 2005-11-14 20:15:46
|
Author: phd
Date: 2005-11-14 20:15:41 +0000 (Mon, 14 Nov 2005)
New Revision: 1263
Modified:
home/phd/SQLObject/paramstyles/sqlobject/sqlbuilder.py
home/phd/SQLObject/paramstyles/sqlobject/tests/test_sqllist.py
Log:
Added __sqllist__() to Select, Insert, Update and Delete; added tests.
Modified: home/phd/SQLObject/paramstyles/sqlobject/sqlbuilder.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/sqlbuilder.py 2005-11-14 18:54:57 UTC (rev 1262)
+++ home/phd/SQLObject/paramstyles/sqlobject/sqlbuilder.py 2005-11-14 20:15:41 UTC (rev 1263)
@@ -75,7 +75,9 @@
import types
from converters import sqlrepr, registerConverter, TRUE, FALSE
+from sqlobject.include.DBSingleStyle import Raw, Param
+
safeSQLRE = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_\.]*$')
def sqlIdentifier(obj):
# some db drivers return unicode column names
@@ -105,13 +107,15 @@
class SQLListMixin(object):
def __sqllist__(self):
- return self.__sqlrepr__(None)
+ return [self.__sqlrepr__(None)]
def sqllist(obj):
if isinstance(obj, types.StringTypes):
return [obj]
+ elif hasattr(obj, "__sqllist__"):
+ return obj.__sqllist__()
else:
- return obj.__sqllist__()
+ return [Raw(obj)]
########################################
## Expression generation
@@ -505,6 +509,34 @@
select += " LIMIT %s" % sqlrepr(self.limit, db)
return select
+ def __sqllist__(self):
+ select = ["SELECT "]
+ for v in self.items:
+ select += sqllist(v)
+
+ tables = {}
+ things = self.items[:]
+ if self.whereClause is not NoDefault:
+ things.append(self.whereClause)
+ for thing in things:
+ if isinstance(thing, SQLExpression):
+ tables.update(tablesUsedDict(thing))
+ tables = tables.keys()
+ if tables:
+ select += [" FROM "] + tables
+
+ if self.whereClause is not NoDefault:
+ select += [" WHERE "] + sqllist(self.whereClause)
+ if self.groupBy is not NoDefault:
+ select += [" GROUP BY "] + sqllist(self.groupBy)
+ if self.having is not NoDefault:
+ select += [" HAVING "] + sqllist(self.having)
+ if self.orderBy is not NoDefault:
+ select += [" ORDER BY "] + sqllist(self.orderBy)
+ if self.limit is not NoDefault:
+ select += [" LIMIT "] + sqllist(self.limit)
+ return select
+
registerConverter(Select, SQLExprConverter)
class Insert(SQLExpression):
@@ -517,6 +549,7 @@
self.valueList = valueList
else:
self.valueList = [values]
+
def __sqlrepr__(self, db):
if not self.valueList:
return ''
@@ -544,6 +577,33 @@
insert += "(%s)" % ", ".join([sqlrepr(v, db) for v in value])
return insert
+ def __sqllist__(self):
+ if not self.valueList:
+ return ''
+ insert = ["INSERT INTO %s" % self.table]
+ allowNonDict = True
+ template = self.template
+ if template is NoDefault and type(self.valueList[0]) is type({}):
+ template = self.valueList[0].keys()
+ allowNonDict = False
+ if template is not NoDefault:
+ insert += [" (%s)" % ", ".join(template)]
+ first = True
+ insert += [" VALUES "]
+ for value in self.valueList:
+ if first:
+ first = False
+ else:
+ insert += [", "]
+ if type(value) is type({}):
+ if template is NoDefault:
+ raise TypeError, "You can't mix non-dictionaries with dictionaries in an INSERT if you don't provide a template (%s)" % repr(value)
+ value = dictToList(template, value)
+ elif not allowNonDict:
+ raise TypeError, "You can't mix non-dictionaries with dictionaries in an INSERT if you don't provide a template (%s)" % repr(value)
+ insert += ["("] + [Param(v) for v in value] + [")"]
+ return insert
+
registerConverter(Insert, SQLExprConverter)
def dictToList(template, dict):
@@ -560,6 +620,7 @@
self.values = values
self.template = template
self.whereClause = where
+
def __sqlrepr__(self, db):
update = "%s %s" % (self.sqlName(), self.table)
update += " SET"
@@ -581,9 +642,31 @@
if self.whereClause is not NoDefault:
update += " WHERE %s" % sqlrepr(self.whereClause, db)
return update
+
def sqlName(self):
return "UPDATE"
+ def __sqllist__(self):
+ update = ["%s %s SET" % (self.sqlName(), self.table)]
+ first = True
+ if self.template is not NoDefault:
+ for i in range(len(self.template)):
+ if first:
+ first = False
+ else:
+ update += ","
+ update += [' ', self.template[i], "=", Param(self.values[i])]
+ else:
+ for key, value in self.values.items():
+ if first:
+ first = False
+ else:
+ update += [","]
+ update += [' ', key, "=", Param(value)]
+ if self.whereClause is not NoDefault:
+ update += [" WHERE "] + sqllist(self.whereClause)
+ return update
+
registerConverter(Update, SQLExprConverter)
class Delete(SQLExpression):
@@ -599,6 +682,10 @@
return "DELETE FROM %s" % self.table
return "DELETE FROM %s WHERE %s" \
% (self.table, sqlrepr(self.whereClause, db))
+ def __sqllist__(self):
+ if self.whereClause is None:
+ return ["DELETE FROM %s" % self.table]
+ return ["DELETE FROM %s WHERE " % (self.table,)] + sqllist(self.whereClause)
registerConverter(Delete, SQLExprConverter)
Modified: home/phd/SQLObject/paramstyles/sqlobject/tests/test_sqllist.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/tests/test_sqllist.py 2005-11-14 18:54:57 UTC (rev 1262)
+++ home/phd/SQLObject/paramstyles/sqlobject/tests/test_sqllist.py 2005-11-14 20:15:41 UTC (rev 1263)
@@ -1,3 +1,4 @@
+from sqlobject import *
from sqlobject.sqlbuilder import *
def test_simple_string():
@@ -5,3 +6,37 @@
def test_sql_op():
assert sqllist(SQLOp('+', '1', '2')) == ['(', '1', '+', '2', ')']
+
+
+class TestSQLList(SQLObject):
+ col1 = StringCol()
+
+def test_select():
+ assert sqllist(Select(TestSQLList.q.col1)) == \
+ ["SELECT ", "test_sql_list.col1", " FROM ", "test_sql_list"]
+
+def test_insert():
+ insert = sqllist(Insert("test_sql_list", values={"col1": '1'}))
+ param = insert[-2]
+ assert isinstance(param, Param)
+ assert param.value == '1'
+ del insert[-2] # Param does not support comparison
+ assert insert == ["INSERT INTO test_sql_list", " (col1)", " VALUES ", "(", ")"]
+
+def test_update():
+ update = sqllist(Update("test_sql_list", values={"col1": '1'}))
+ param = update[-1]
+ assert isinstance(param, Param)
+ assert param.value == '1'
+ del update[-1] # Param does not support comparison
+ assert update == ["UPDATE test_sql_list SET", ' ', "col1", "="]
+
+def test_delete():
+ assert sqllist(Delete(TestSQLList.sqlmeta.table, None)) == \
+ ["DELETE FROM test_sql_list"]
+ delete = sqllist(Delete(TestSQLList.sqlmeta.table, TestSQLList.q.col1==1))
+ raw = delete[-2]
+ assert isinstance(raw, Raw)
+ assert raw.value == 1
+ del delete[-2]
+ assert delete == ["DELETE FROM test_sql_list WHERE ", "(", "test_sql_list.col1", "=", ")"]
|
|
From: <sub...@co...> - 2005-11-14 18:24:45
|
Author: phd
Date: 2005-11-14 18:24:35 +0000 (Mon, 14 Nov 2005)
New Revision: 1261
Added:
home/phd/SQLObject/paramstyles/sqlobject/tests/test_sqllist.py
Modified:
home/phd/SQLObject/paramstyles/sqlobject/sqlbuilder.py
Log:
Started to add __sqllist__() method; added two simple tests.
Modified: home/phd/SQLObject/paramstyles/sqlobject/sqlbuilder.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/sqlbuilder.py 2005-11-14 16:31:08 UTC (rev 1260)
+++ home/phd/SQLObject/paramstyles/sqlobject/sqlbuilder.py 2005-11-14 18:24:35 UTC (rev 1261)
@@ -89,6 +89,31 @@
return expr
########################################
+## SQL Query lists
+########################################
+
+class SQLList(object):
+ def __init__(self, query_list):
+ self.query_list = query_list
+
+ def __sqlrepr__(self, db):
+ repr_list = [sqlrepr(part, db) for part in self.query_list]
+ return ''.join(repr_list)
+
+ def __sqllist__(self):
+ return self.query_list
+
+class SQLListMixin(object):
+ def __sqllist__(self):
+ return self.__sqlrepr__(None)
+
+def sqllist(obj):
+ if isinstance(obj, types.StringTypes):
+ return [obj]
+ else:
+ return obj.__sqllist__()
+
+########################################
## Expression generation
########################################
@@ -231,6 +256,8 @@
self.expr2 = expr2
def __sqlrepr__(self, db):
return "(%s %s %s)" % (sqlrepr(self.expr1, db), self.op, sqlrepr(self.expr2, db))
+ def __sqllist__(self):
+ return ["("] + sqllist(self.expr1) + [self.op] + sqllist(self.expr2) + [")"]
def components(self):
return [self.expr1, self.expr2]
def execute(self, executor):
@@ -263,6 +290,8 @@
self.args = args
def __sqlrepr__(self, db):
return "%s%s" % (sqlrepr(self.expr, db), sqlrepr(self.args, db))
+ def __sqllist__(self):
+ return sqllist(self.expr) + sqllist(self.args)
def components(self):
return [self.expr] + list(self.args)
def execute(self, executor):
@@ -276,6 +305,8 @@
self.expr = expr
def __sqlrepr__(self, db):
return "%s %s" % (self.prefix, sqlrepr(self.expr, db))
+ def __sqllist__(self):
+ return sqllist(self.prefix) + [' '] + sqllist(self.expr, db)
def components(self):
return [self.expr]
def execute(self, executor):
@@ -294,12 +325,14 @@
self.const = const
def __sqlrepr__(self, db):
return self.const
+ def __sqllist__(self):
+ return sqllist(self.const)
def execute(self, executor):
raise ValueError, "I don't yet know how to execute SQL constants"
registerConverter(SQLConstant, SQLExprConverter)
-class SQLTrueClauseClass(SQLExpression):
+class SQLTrueClauseClass(SQLExpression, SQLListMixin):
def __sqlrepr__(self, db):
return "1 = 1"
def execute(self, executor):
@@ -313,7 +346,7 @@
## Namespaces
########################################
-class Field(SQLExpression):
+class Field(SQLExpression, SQLListMixin):
def __init__(self, tableName, fieldName):
self.tableName = tableName
self.fieldName = fieldName
@@ -331,7 +364,7 @@
registerConverter(SQLObjectField, SQLExprConverter)
-class Table(SQLExpression):
+class Table(SQLExpression, SQLListMixin):
FieldClass = Field
def __init__(self, tableName):
@@ -384,7 +417,7 @@
## Table aliases
########################################
-class AliasField(Field):
+class AliasField(Field, SQLListMixin):
def __init__(self, tableName, fieldName, alias):
Field.__init__(self, tableName, fieldName)
self.alias = alias
@@ -431,18 +464,6 @@
########################################
-## SQL Query lists
-########################################
-
-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
########################################
Added: home/phd/SQLObject/paramstyles/sqlobject/tests/test_sqllist.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/tests/test_sqllist.py 2005-11-14 16:31:08 UTC (rev 1260)
+++ home/phd/SQLObject/paramstyles/sqlobject/tests/test_sqllist.py 2005-11-14 18:24:35 UTC (rev 1261)
@@ -0,0 +1,7 @@
+from sqlobject.sqlbuilder import *
+
+def test_simple_string():
+ assert sqllist('') == ['']
+
+def test_sql_op():
+ assert sqllist(SQLOp('+', '1', '2')) == ['(', '1', '+', '2', ')']
|
|
From: SourceForge.net <no...@so...> - 2005-11-14 16:02:06
|
Patches item #1356651, was opened at 2005-11-14 11:02 Message generated for change (Tracker Item Submitted) made by Item Submitter You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1356651&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: Open Resolution: None Priority: 5 Submitted By: darkmyst (darkmyst) Assigned to: Nobody/Anonymous (nobody) Summary: Fix for bug #1356639 Initial Comment: fixed the problem as described in the bug report by adding a check for None before the error gets a chance to be triggered. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1356651&group_id=74338 |
|
From: SourceForge.net <no...@so...> - 2005-11-14 15:52:57
|
Bugs item #1356639, was opened at 2005-11-14 10:52 Message generated for change (Tracker Item Submitted) made by Item Submitter You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1356639&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: Open Resolution: None Priority: 5 Submitted By: darkmyst (darkmyst) Assigned to: Nobody/Anonymous (nobody) Summary: delJoin errors when adding and deleting multiple joins Initial Comment: I'm using SQLObject 0.7.0 but I looked at what's in the repository and the situation is the same there. I've encountered a situation, in testing my code, where I add a few joins to a table using sqlmeta.addJoin and then immediately remove them using sqlmeta.delJoin. In running the code I got the following error: File "/usr/lib/python2.4/site-packages/SQLObject-0.7.0-py2.4.egg/sqlobject/main.py", line 525, in delJoin if joinDef is join.joinDef: AttributeError: 'NoneType' object has no attribute 'joinDef' Both my addJoins went off without a hitch and the first delJoin as well. The second dellJoin is what tripped the error. Looking into it, I found that sqlmeta.addJoin uses a list to maintain joins (main.py, line 481) and then uses the index on the list as the reference point for a specific join (main.py, line 489). Therefore, as noted in delJoin (main.py, line 537), one can't just del the join from the list or it'll screw up the indexing. The problem seems to be in the for loop that checks to see if the join we want removed is present (main.py, line 525): 524: for join in sqlmeta.joins: 525: if joinDef is join.joinDef: 526: break If a join has previously been removed, it's set to None. However, in the if statement we see it's assumed that join will have an attribute joinDef. NoneType doesn't have an attribute joinDef, hence the error. Perhaps it should look more like: 524: for join in sqlmeta.joins: 525: if join is None: 526: continue 527: if joinDef is join.joinDef: 528: break ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1356639&group_id=74338 |
|
From: <sub...@co...> - 2005-11-14 09:49:28
|
Author: phd Date: 2005-11-14 09:49:15 +0000 (Mon, 14 Nov 2005) New Revision: 1259 Removed: home/phd/SQLObject/paramstyles/docs/ Modified: home/phd/SQLObject/paramstyles/ Log: Merged patches from the revisions 1243:1258 from the trunk Property changes on: home/phd/SQLObject/paramstyles ___________________________________________________________________ Name: svn:externals - ez_setup svn://svn.eby-sarna.com/svnroot/ez_setup + ez_setup svn://svn.eby-sarna.com/svnroot/ez_setup docs http://svn.colorstudy.com/SQLObject/docs |
|
From: <sub...@co...> - 2005-11-14 02:11:48
|
Author: ianb
Date: 2005-11-14 02:11:39 +0000 (Mon, 14 Nov 2005)
New Revision: 1258
Modified:
SQLObject/docs/sqlobject-admin.txt
Log:
Noted version requirement
Modified: SQLObject/docs/sqlobject-admin.txt
===================================================================
--- SQLObject/docs/sqlobject-admin.txt 2005-11-14 02:04:26 UTC (rev 1257)
+++ SQLObject/docs/sqlobject-admin.txt 2005-11-14 02:11:39 UTC (rev 1258)
@@ -94,11 +94,11 @@
This finds the tables and creates them. Any tables that exist are
simply skipped.
-It also collects data from sqlmeta.createSQL and runs the queries
-after table creation. createSQL can be a string with a single SQL
-command, a list of SQL commands, or a dictionary with keys that are
-dbNames and values that are either single SQL command string or a list
-of SQL commands. An example follows::
+It also collects data from sqlmeta.createSQL (added in svn trunk) and
+runs the queries after table creation. createSQL can be a string with
+a single SQL command, a list of SQL commands, or a dictionary with
+keys that are dbNames and values that are either single SQL command
+string or a list of SQL commands. An example follows::
class MyTable(SQLObject):
class sqlmeta:
|
|
From: <sub...@co...> - 2005-11-14 02:04:33
|
Author: ianb Date: 2005-11-14 02:04:26 +0000 (Mon, 14 Nov 2005) New Revision: 1257 Modified: SQLObject/trunk/ Log: Bring in docs as svn:externals Property changes on: SQLObject/trunk ___________________________________________________________________ Name: svn:externals - ez_setup svn://svn.eby-sarna.com/svnroot/ez_setup + ez_setup svn://svn.eby-sarna.com/svnroot/ez_setup docs http://svn.colorstudy.com/SQLObject/docs |
|
From: <sub...@co...> - 2005-11-14 02:02:07
|
Author: ianb Date: 2005-11-14 02:01:59 +0000 (Mon, 14 Nov 2005) New Revision: 1256 Added: SQLObject/docs/ Removed: SQLObject/trunk/docs/ Log: Moving documentation to new non-branching location Copied: SQLObject/docs (from rev 1255, SQLObject/trunk/docs) |
|
From: SourceForge.net <no...@so...> - 2005-11-13 22:13:44
|
Bugs item #1356102, was opened at 2005-11-13 22:13 Message generated for change (Tracker Item Submitted) made by Item Submitter You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1356102&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 release (specify) Status: Open Resolution: None Priority: 5 Submitted By: stan pinte (stanpinte) Assigned to: Nobody/Anonymous (nobody) Summary: INSERT fails without error Initial Comment: I have an INSERT that fails with no apparent reason from the database... (in that case postgres 8.0) 1/QueryIns: INSERT INTO log (id, message, state, operation, mtime) VALUES (5, 'Station: None', 'Error', 'ImportData', '2005-11-13 23:51:43') 1/COMMIT : auto 2/QueryOne: SELECT mtime, operation, state, message FROM log WHERE id = 5 2/QueryR : SELECT mtime, operation, state, message FROM log WHERE id = 5 2/COMMIT : auto Traceback (most recent call last): ... raise SQLObjectNotFound, "The object %s by the ID %s does not exist" % (self.__class__.__name__, self.id) sqlobject.main.SQLObjectNotFound: The object log by the ID 5 does not exist any idea? thanks a lot, Stan. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1356102&group_id=74338 |
|
From: <sub...@co...> - 2005-11-12 20:52:12
|
Author: phd
Date: 2005-11-12 20:52:04 +0000 (Sat, 12 Nov 2005)
New Revision: 1243
Modified:
home/phd/SQLObject/paramstyles/sqlobject/cache.py
home/phd/SQLObject/paramstyles/sqlobject/dbconnection.py
home/phd/SQLObject/paramstyles/sqlobject/main.py
home/phd/SQLObject/paramstyles/sqlobject/tests/test_cache.py
Log:
Merged patches from the revisions 1239:1242 from the trunk
Modified: home/phd/SQLObject/paramstyles/sqlobject/cache.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/cache.py 2005-11-12 20:35:54 UTC (rev 1242)
+++ home/phd/SQLObject/paramstyles/sqlobject/cache.py 2005-11-12 20:52:04 UTC (rev 1243)
@@ -243,6 +243,19 @@
all.append(id)
return all
+ def getAll(self):
+ """
+ Return all the objects in the cache.
+ """
+ if self.doCache:
+ all = self.cache.values()
+ else:
+ all = []
+ for value in self.expiredCache.values():
+ if value():
+ all.append(value())
+ return all
+
class CacheSet(object):
"""
@@ -305,3 +318,31 @@
def allSubCaches(self):
return self.caches.values()
+
+ def weakrefAll(self, cls=None):
+ """
+ Move all objects in the cls (or if not given, then in all
+ classes) to the weakref dictionary, where they can be
+ collected.
+ """
+ if cls is None:
+ for cache in self.caches.values():
+ cache.expireAll()
+ elif self.caches.has_key(cls.__name__):
+ self.caches[cls.__name__].expireAll()
+
+ def getAll(self, cls=None):
+ """
+ Returns all instances in the cache for the given class or all
+ classes.
+ """
+ if cls is None:
+ results = []
+ for cache in self.caches.values():
+ results.extend(cache.getAll())
+ return results
+ elif cls.__name__ in self.caches:
+ return self.caches[cls.__name__].getAll()
+ else:
+ return []
+
Modified: home/phd/SQLObject/paramstyles/sqlobject/dbconnection.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/dbconnection.py 2005-11-12 20:35:54 UTC (rev 1242)
+++ home/phd/SQLObject/paramstyles/sqlobject/dbconnection.py 2005-11-12 20:52:04 UTC (rev 1243)
@@ -139,6 +139,15 @@
% (self, name, soClass))
setattr(self, name, ConnWrapper(soClass, self))
+ def expireAll(self):
+ """
+ Expire all instances of objects for this connection.
+ """
+ cache_set = self.cache
+ cache_set.weakrefAll()
+ for item in cache_set.getAll():
+ item.expire()
+
class ConnWrapper(object):
"""
Modified: home/phd/SQLObject/paramstyles/sqlobject/main.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/main.py 2005-11-12 20:35:54 UTC (rev 1242)
+++ home/phd/SQLObject/paramstyles/sqlobject/main.py 2005-11-12 20:52:04 UTC (rev 1243)
@@ -587,11 +587,28 @@
########################################
def asDict(self):
+ """
+ Return the object as a dictionary of columns to values.
+ """
result = {}
for key in self.columns:
result[key] = getattr(self.instance, key)
+ result['id'] = self.instance.id
return result
+ def expireAll(sqlmeta, connection=None):
+ """
+ Expire all instances of this class.
+ """
+ soClass = sqlmeta.soClass
+ connection = connection or soClass._connection
+ cache_set = connection.cache
+ cache_set.weakrefAll(soClass)
+ for item in cache_set.getAll(soClass):
+ item.expire()
+
+ expireAll = classmethod(expireAll)
+
sqlhub = dbconnection.ConnectionHub()
class _sqlmeta_attr(object):
Modified: home/phd/SQLObject/paramstyles/sqlobject/tests/test_cache.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/tests/test_cache.py 2005-11-12 20:35:54 UTC (rev 1242)
+++ home/phd/SQLObject/paramstyles/sqlobject/tests/test_cache.py 2005-11-12 20:52:04 UTC (rev 1243)
@@ -1,3 +1,5 @@
+from sqlobject import *
+from dbtest import *
from sqlobject.cache import CacheSet
class Something(object):
@@ -19,3 +21,28 @@
j = x.get(1, y.__class__)
assert j == None
x.finishPut(y.__class__)
+
+
+class CacheTest(SQLObject):
+ name = StringCol(alternateID=True)
+
+def test_cache():
+ setupClass(CacheTest)
+ s = CacheTest(name='foo')
+ obj_id = id(s)
+ s_id = s.id
+ assert CacheTest.get(s_id) is s
+ assert not s.sqlmeta.expired
+ CacheTest.sqlmeta.expireAll()
+ assert s.sqlmeta.expired
+ del s
+ CacheTest.sqlmeta.expireAll()
+ s = CacheTest.get(s_id)
+ # We should have a new object:
+ assert id(s) != obj_id
+ obj_id2 = id(s)
+ del s
+ CacheTest._connection.expireAll()
+ s = CacheTest.get(s_id)
+ assert id(s) != obj_id and id(s) != obj_id2
+
|
|
From: <sub...@co...> - 2005-11-12 20:36:05
|
Author: ianb
Date: 2005-11-12 20:35:54 +0000 (Sat, 12 Nov 2005)
New Revision: 1242
Modified:
SQLObject/trunk/sqlobject/cache.py
SQLObject/trunk/sqlobject/dbconnection.py
SQLObject/trunk/sqlobject/main.py
SQLObject/trunk/sqlobject/tests/test_cache.py
Log:
Added .expireAll() methods to sqlmeta and connection objects, to expire all instances in those cases. Also added id key to asDict results
Modified: SQLObject/trunk/sqlobject/cache.py
===================================================================
--- SQLObject/trunk/sqlobject/cache.py 2005-11-11 23:06:02 UTC (rev 1241)
+++ SQLObject/trunk/sqlobject/cache.py 2005-11-12 20:35:54 UTC (rev 1242)
@@ -243,6 +243,19 @@
all.append(id)
return all
+ def getAll(self):
+ """
+ Return all the objects in the cache.
+ """
+ if self.doCache:
+ all = self.cache.values()
+ else:
+ all = []
+ for value in self.expiredCache.values():
+ if value():
+ all.append(value())
+ return all
+
class CacheSet(object):
"""
@@ -305,3 +318,31 @@
def allSubCaches(self):
return self.caches.values()
+
+ def weakrefAll(self, cls=None):
+ """
+ Move all objects in the cls (or if not given, then in all
+ classes) to the weakref dictionary, where they can be
+ collected.
+ """
+ if cls is None:
+ for cache in self.caches.values():
+ cache.expireAll()
+ elif self.caches.has_key(cls.__name__):
+ self.caches[cls.__name__].expireAll()
+
+ def getAll(self, cls=None):
+ """
+ Returns all instances in the cache for the given class or all
+ classes.
+ """
+ if cls is None:
+ results = []
+ for cache in self.caches.values():
+ results.extend(cache.getAll())
+ return results
+ elif cls.__name__ in self.caches:
+ return self.caches[cls.__name__].getAll()
+ else:
+ return []
+
Modified: SQLObject/trunk/sqlobject/dbconnection.py
===================================================================
--- SQLObject/trunk/sqlobject/dbconnection.py 2005-11-11 23:06:02 UTC (rev 1241)
+++ SQLObject/trunk/sqlobject/dbconnection.py 2005-11-12 20:35:54 UTC (rev 1242)
@@ -138,6 +138,15 @@
% (self, name, soClass))
setattr(self, name, ConnWrapper(soClass, self))
+ def expireAll(self):
+ """
+ Expire all instances of objects for this connection.
+ """
+ cache_set = self.cache
+ cache_set.weakrefAll()
+ for item in cache_set.getAll():
+ item.expire()
+
class ConnWrapper(object):
"""
Modified: SQLObject/trunk/sqlobject/main.py
===================================================================
--- SQLObject/trunk/sqlobject/main.py 2005-11-11 23:06:02 UTC (rev 1241)
+++ SQLObject/trunk/sqlobject/main.py 2005-11-12 20:35:54 UTC (rev 1242)
@@ -587,11 +587,28 @@
########################################
def asDict(self):
+ """
+ Return the object as a dictionary of columns to values.
+ """
result = {}
for key in self.columns:
result[key] = getattr(self.instance, key)
+ result['id'] = self.instance.id
return result
+ def expireAll(sqlmeta, connection=None):
+ """
+ Expire all instances of this class.
+ """
+ soClass = sqlmeta.soClass
+ connection = connection or soClass._connection
+ cache_set = connection.cache
+ cache_set.weakrefAll(soClass)
+ for item in cache_set.getAll(soClass):
+ item.expire()
+
+ expireAll = classmethod(expireAll)
+
sqlhub = dbconnection.ConnectionHub()
class _sqlmeta_attr(object):
Modified: SQLObject/trunk/sqlobject/tests/test_cache.py
===================================================================
--- SQLObject/trunk/sqlobject/tests/test_cache.py 2005-11-11 23:06:02 UTC (rev 1241)
+++ SQLObject/trunk/sqlobject/tests/test_cache.py 2005-11-12 20:35:54 UTC (rev 1242)
@@ -1,3 +1,5 @@
+from sqlobject import *
+from dbtest import *
from sqlobject.cache import CacheSet
class Something(object):
@@ -19,3 +21,28 @@
j = x.get(1, y.__class__)
assert j == None
x.finishPut(y.__class__)
+
+
+class CacheTest(SQLObject):
+ name = StringCol(alternateID=True)
+
+def test_cache():
+ setupClass(CacheTest)
+ s = CacheTest(name='foo')
+ obj_id = id(s)
+ s_id = s.id
+ assert CacheTest.get(s_id) is s
+ assert not s.sqlmeta.expired
+ CacheTest.sqlmeta.expireAll()
+ assert s.sqlmeta.expired
+ del s
+ CacheTest.sqlmeta.expireAll()
+ s = CacheTest.get(s_id)
+ # We should have a new object:
+ assert id(s) != obj_id
+ obj_id2 = id(s)
+ del s
+ CacheTest._connection.expireAll()
+ s = CacheTest.get(s_id)
+ assert id(s) != obj_id and id(s) != obj_id2
+
|
|
From: SourceForge.net <no...@so...> - 2005-11-11 16:15:24
|
Patches item #1354113, was opened at 2005-11-11 14:15 Message generated for change (Tracker Item Submitted) made by Item Submitter You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1354113&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: Open Resolution: None Priority: 5 Submitted By: Sidnei da Silva (dreamcatcher) Assigned to: Nobody/Anonymous (nobody) Summary: Patch to backport mssql support to 0.7-bugfix branch Initial Comment: This patch applies cleanly to 0.7-bugfix branch. Contains all the changes, including tests, to add mssql support. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1354113&group_id=74338 |
|
From: SourceForge.net <no...@so...> - 2005-11-11 07:20:08
|
Patches item #1353728, was opened at 2005-11-11 08:20 Message generated for change (Tracker Item Submitted) made by Item Submitter You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1353728&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: Open Resolution: None Priority: 5 Submitted By: Pau Aliagas (linux4u) Assigned to: Nobody/Anonymous (nobody) Summary: define foreign keys in Style Initial Comment: I don't like to use attrID all along the code to access related tables, I want to be able use the nomeclature I like taking advantage of the nice Style idea. This is especially true when you create RelatedJoins when you use a nomeclature like I do (table.id_table), but it's the same for all the nomeclatures you can imagine. In styles.py it warns: def instanceAttrToIDAttr(self, attr): # @@: Right now, because of how names are created for foreign # keys, you can't really change this style. return attr + "ID" With this patch you can define how you want the foreign keys generated, they won't be mandatorily generated as attrID. Example: class LongStyle(Style): """ This style is derived from Style, that does not do any translation, but constructs the table ids like id_table. """ def instanceAttrToIDAttr(self, attr): return "id_" + attr def tableReference(self, table): # str.rsplit is python 2.4+ only if version_info >= (2, 4): return "id_" + table.rsplit(".", 1)[-1] else: return "id_" + rsplit(table, ".", 1)[-1] class mm_server(SQLObject): class sqlmeta: table = "smsarena.mm_server" style = LongStyle(longID = True) _connection = conn_smsarena server = StringCol(alternateID = True, varchar = True, length = 255, alternateMethodName = "by_server") tz = StringCol(length = 20, default = 'CET', notNone = True) conutry_code = StringCol(length = 2, varchar = False, default = '', notNone = True) # until now I had to do this # mm_server_aliases = SQLMultipleJoin("mm_server_alias", joinColumn = "mm_serverID", orderBy = "server") # now it's perfect! mm_server_aliases = SQLMultipleJoin("mm_server_alias", orderBy = "server") class mm_server_alias(SQLObject): class sqlmeta: table = "smsarena.mm_server_alias" style = LongStyle(longID = True) _connection = conn_smsarena # until now I had to do this # mm_server = ForeignKey("mm_server", dbName = "id_mm_server") mm_server = ForeignKey("mm_server") server = StringCol(alternateID = True, varchar = True, length = 255, alternateMethodName = "by_server") I hope it's clear :) Pau ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1353728&group_id=74338 |
|
From: <sub...@co...> - 2005-11-10 09:54:00
|
Author: phd
Date: 2005-11-10 09:53:52 +0000 (Thu, 10 Nov 2005)
New Revision: 1237
Added:
home/phd/SQLObject/paramstyles/sqlobject/util/csvimport.py
Modified:
home/phd/SQLObject/paramstyles/sqlobject/events.py
home/phd/SQLObject/paramstyles/sqlobject/manager/command.py
Log:
Merged patches from the revisions 1232:1236 from the trunk
Modified: home/phd/SQLObject/paramstyles/sqlobject/events.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/events.py 2005-11-10 05:37:21 UTC (rev 1236)
+++ home/phd/SQLObject/paramstyles/sqlobject/events.py 2005-11-10 09:53:52 UTC (rev 1237)
@@ -103,10 +103,6 @@
The arguments are ``(instance, kwargs)``. ``kwargs`` can be
modified. This is run *before* the instance is updated; if you
want to look at the current values, simply look at ``instance``.
-
- @@: Should this also catch single-column updates? Should this
- only be run before updates go to the server? Should this be
- called RowUpdateSignal?
"""
class AddColumnSignal(Signal):
Modified: home/phd/SQLObject/paramstyles/sqlobject/manager/command.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/manager/command.py 2005-11-10 05:37:21 UTC (rev 1236)
+++ home/phd/SQLObject/paramstyles/sqlobject/manager/command.py 2005-11-10 09:53:52 UTC (rev 1237)
@@ -6,13 +6,11 @@
import sys
import textwrap
import warnings
+import time
try:
- from paste import pyconfig
- from paste import CONFIG
-except ImportError, e:
- pyconfig = None
- CONFIG = {}
-import time
+ from paste.deploy import appconfig
+except ImportError:
+ appconfig = None
import sqlobject
from sqlobject import col
@@ -320,13 +318,15 @@
def config(self):
if not getattr(self.options, 'config_file', None):
return None
- if pyconfig and self.options.config_fn.endswith('.conf'):
- config = pyconfig.Config(with_default=True)
- config.load(self.options.config_file)
- CONFIG.push_process_config(config)
- return config
+ config_file = self.options.config_file
+ if appconfig:
+ if (not config_file.startswith('egg:')
+ and not config_file.startswith('config:')):
+ config_file = 'config:' + config_file
+ return appconfig(config_file,
+ relative_to=os.getcwd())
else:
- return self.ini_config(self.options.config_file)
+ return self.ini_config(config_file)
def ini_config(self, conf_fn):
conf_section = 'main'
Copied: home/phd/SQLObject/paramstyles/sqlobject/util/csvimport.py (from rev 1236, SQLObject/trunk/sqlobject/util/csvimport.py)
|
|
From: <sub...@co...> - 2005-11-10 02:46:37
|
Author: ianb
Date: 2005-11-10 02:46:30 +0000 (Thu, 10 Nov 2005)
New Revision: 1235
Modified:
SQLObject/trunk/sqlobject/events.py
Log:
Removed inaccurate to-do (it got done)
Modified: SQLObject/trunk/sqlobject/events.py
===================================================================
--- SQLObject/trunk/sqlobject/events.py 2005-11-09 22:20:39 UTC (rev 1234)
+++ SQLObject/trunk/sqlobject/events.py 2005-11-10 02:46:30 UTC (rev 1235)
@@ -103,10 +103,6 @@
The arguments are ``(instance, kwargs)``. ``kwargs`` can be
modified. This is run *before* the instance is updated; if you
want to look at the current values, simply look at ``instance``.
-
- @@: Should this also catch single-column updates? Should this
- only be run before updates go to the server? Should this be
- called RowUpdateSignal?
"""
class AddColumnSignal(Signal):
|
|
From: <sub...@co...> - 2005-11-09 22:20:44
|
Author: test
Date: 2005-11-09 22:20:39 +0000 (Wed, 09 Nov 2005)
New Revision: 1234
Added:
SQLObject/trunk/sqlobject/util/csvimport.py
Log:
Added a utility to import data from a CSV file, primarily intended for test fixtures
Added: SQLObject/trunk/sqlobject/util/csvimport.py
===================================================================
--- SQLObject/trunk/sqlobject/util/csvimport.py 2005-11-09 22:20:06 UTC (rev 1233)
+++ SQLObject/trunk/sqlobject/util/csvimport.py 2005-11-09 22:20:39 UTC (rev 1234)
@@ -0,0 +1,349 @@
+"""
+Import from a CSV file or directory of files.
+
+CSV files should have a header line that lists columns. Headers can
+also be appended with ``:type`` to indicate the type of the field.
+``escaped`` is the default, though it can be overridden by the importer.
+Supported types:
+
+``:python``:
+ A python expression, run through ``eval()``. This can be a
+ security risk, pass in ``allow_python=False`` if you don't want to
+ allow it.
+
+``:int``:
+ Integer
+
+``:float``:
+ Float
+
+``:str``:
+ String
+
+``:escaped``:
+ A string with backslash escapes (note that you don't put quotation
+ marks around the value)
+
+``:base64``:
+ A base64-encoded string
+
+``:date``:
+ ISO date, like YYYY-MM-DD; this can also be ``NOW+days`` or
+ ``NOW-days``
+
+``:datetime``:
+ ISO date/time like YYYY-MM-DDTHH:MM:SS (either T or a space can be
+ used to separate the time, and seconds are optional). This can
+ also be ``NOW+seconds`` or ``NOW-seconds``
+
+``:bool``:
+ Converts true/false/yes/no/on/off/1/0 to boolean value
+
+``:ref``:
+ This will be resolved to the ID of the object named in this column
+ (None if the column is empty). @@: Since there's no ordering,
+ there's no way to promise the object already exists.
+
+You can also get back references to the objects if you have a special
+``[name]`` column.
+
+Any column named ``[comment]`` or with no name will be ignored.
+
+In any column you can put ``[default]`` to exclude the value and use
+whatever default the class wants. ``[null]`` will use NULL.
+
+Lines that begin with ``[comment]`` are ignored.
+"""
+
+from datetime import datetime, date, timedelta
+import os
+import csv
+import types
+
+__all__ = ['load_csv_from_directory',
+ 'load_csv',
+ 'create_data']
+
+DEFAULT_TYPE = 'escaped'
+
+def create_data(data, class_getter, keyorder=None):
+ """
+ Create the ``data``, which is the return value from
+ ``load_csv()``. Classes will be resolved with the callable
+ ``class_getter``; or if ``class_getter`` is a module then the
+ class names will be attributes of that.
+
+ Returns a dictionary of ``{object_name: object(s)}``, using the
+ names from the ``[name]`` columns (if there are any). If a name
+ is used multiple times, you get a list of objects, not a single
+ object.
+
+ If ``keyorder`` is given, then the keys will be retrieved in that
+ order. It can be a list/tuple of names, or a sorting function.
+ If not given and ``class_getter`` is a module and has a
+ ``soClasses`` function, then that will be used for the order.
+ """
+ objects = {}
+ classnames = data.keys()
+ if (not keyorder and isinstance(class_getter, types.ModuleType)
+ and hasattr(class_getter, 'soClasses')):
+ keyorder = [c.__name__ for c in class_getter.soClasses]
+ if not keyorder:
+ classnames.sort()
+ elif isinstance(keyorder, (list, tuple)):
+ all = classnames
+ classnames = [name for name in keyorder if name in classnames]
+ for name in all:
+ if name not in classnames:
+ classnames.append(name)
+ else:
+ classnames.sort(keyorder)
+ for classname in classnames:
+ items = data[classname]
+ if not items:
+ continue
+ if isinstance(class_getter, types.ModuleType):
+ soClass = getattr(class_getter, classname)
+ else:
+ soClass = class_getter(classname)
+ for item in items:
+ for key, value in item.items():
+ if isinstance(value, Reference):
+ resolved = objects.get(value.name)
+ if not resolved:
+ raise ValueError(
+ "Object reference to %r does not have target"
+ % value.name)
+ elif (isinstance(resolved, list)
+ and len(resolved) > 1):
+ raise ValueError(
+ "Object reference to %r is ambiguous (got %r)"
+ % (value.name, resolved))
+ item[key] = resolved.id
+ if '[name]' in item:
+ name = item.pop('[name]').strip()
+ else:
+ name = None
+ inst = soClass(**item)
+ if name:
+ if name in objects:
+ if isinstance(objects[name], list):
+ objects[name].append(inst)
+ else:
+ objects[name] = [objects[name], inst]
+ else:
+ objects[name] = inst
+ return objects
+
+
+def load_csv_from_directory(directory,
+ allow_python=True, default_type=DEFAULT_TYPE,
+ allow_multiple_classes=True):
+ """
+ Load the data from all the files in a directory. Filenames
+ indicate the class, with ``general.csv`` for data not associated
+ with a class. Return data just like ``load_csv`` does.
+
+ This might cause problems on case-insensitive filesystems.
+ """
+ results = {}
+ for filename in os.listdir(directory):
+ base, ext = os.path.splitext(filename)
+ if ext.lower() != '.csv':
+ continue
+ f = open(os.path.join(directory, filename), 'rb')
+ csvreader = csv.reader(f)
+ data = load_csv(csvreader, allow_python=allow_python,
+ default_type=default_type,
+ default_class=base,
+ allow_multiple_classes=allow_multiple_classes)
+ f.close()
+ for classname, items in data.items():
+ results.setdefault(classname, []).extend(items)
+ return results
+
+def load_csv(csvreader, allow_python=True, default_type=DEFAULT_TYPE,
+ default_class=None, allow_multiple_classes=True):
+ """
+ Loads the CSV file, returning a list of dictionaries with types
+ coerced.
+ """
+ current_class = default_class
+ current_headers = None
+ results = {}
+
+ for row in csvreader:
+ if not [cell for cell in row if cell.strip()]:
+ # empty row
+ continue
+
+ if row and row[0].strip() == 'CLASS:':
+ if not allow_multiple_classes:
+ raise ValueError(
+ "CLASS: line in CSV file, but multiple classes are not allowed in this file (line: %r)"
+ % row)
+ if not row[1:]:
+ raise ValueError(
+ "CLASS: in line in CSV file, with no class name in next column (line: %r)"
+ % row)
+ current_class = row[1]
+ current_headers = None
+ continue
+
+ if not current_class:
+ raise ValueError(
+ "No CLASS: line given, and there is no default class for this file (line: %r"
+ % row)
+
+ if current_headers is None:
+ current_headers = _parse_headers(row, default_type)
+ continue
+
+ if row[0] == '[comment]':
+ continue
+
+ # Pad row with empty strings:
+ row += ['']*(len(current_headers) - len(row))
+ row_converted = {}
+ for value, (name, coercer, args) in zip(row, current_headers):
+ if name is None:
+ # Comment
+ continue
+ if value == '[default]':
+ continue
+ if value == '[null]':
+ row_converted[name] = None
+ continue
+ args = (value,) + args
+ row_converted[name] = coercer(*args)
+
+ results.setdefault(current_class, []).append(row_converted)
+
+ return results
+
+def _parse_headers(header_row, default_type):
+ headers = []
+ for name in header_row:
+ original_name = name
+ if ':' in name:
+ name, type = name.split(':', 1)
+ else:
+ type = default_type
+ if type == 'python' and not allow_python:
+ raise ValueError(
+ ":python header given when python headers are not allowed (with header %r"
+ % original_name)
+ name = name.strip()
+ if name == '[comment]' or not name:
+ headers.append((None, None, None))
+ continue
+ type = type.strip().lower()
+ if '(' in type:
+ type, arg = type.split('(', 1)
+ if not arg.endswith(')'):
+ raise ValueError(
+ "Arguments (in ()'s) do not end with ): %r"
+ % original_name)
+ args = (arg[:-1],)
+ else:
+ args = ()
+ if name == '[name]':
+ type = 'str'
+ coercer, args = get_coercer(type)
+ headers.append((name, coercer, args))
+ return headers
+
+_coercers = {}
+def get_coercer(type):
+ if type not in _coercers:
+ raise ValueError(
+ "Coercion type %r not known (I know: %s)"
+ % (type, ', '.join(_coercers.keys())))
+ return _coercers[type]
+
+def register_coercer(type, coercer, *args):
+ _coercers[type] = (coercer, args)
+
+def identity(v):
+ return v
+
+register_coercer('str', identity)
+register_coercer('string', identity)
+
+def decode_string(v, encoding):
+ return v.decode(encoding)
+
+register_coercer('escaped', decode_string, 'string_escape')
+register_coercer('strescaped', decode_string, 'string_escape')
+register_coercer('base64', decode_string, 'base64')
+
+register_coercer('int', int)
+register_coercer('float', float)
+
+def parse_python(v):
+ return eval(v, {}, {})
+
+register_coercer('python', parse_python)
+
+def parse_date(v):
+ v = v.strip()
+ if not v:
+ return None
+ if v.startswith('NOW-') or v.startswith('NOW+'):
+ days = int(v[3:])
+ now = date.today()
+ return now+timedelta(days)
+ else:
+ parsed = time.strptime(v, '%Y-%m-%d')
+ return date.fromtimestamp(time.mktime(parsed))
+
+register_coercer('date', parse_date)
+
+def parse_datetime(v):
+ v = v.strip()
+ if not v:
+ return None
+ if v.startswith('NOW-') or v.startswith('NOW+'):
+ seconds = int(v[3:])
+ now = datetime.now()
+ return now+timedelta(0, seconds)
+ else:
+ fmts = ['%Y-%m-%dT%H:%M:%S',
+ '%Y-%m-%d %H:%M:%S',
+ '%Y-%m-%dT%H:%M',
+ '%Y-%m-%d %H:%M']
+ for fmt in fmts[:-1]:
+ try:
+ parsed = time.strptime(v, fmt)
+ break
+ except ValueError:
+ pass
+ else:
+ parsed = time.strptime(v, fmts[-1])
+ return datetime.fromtimestamp(time.mktime(parsed))
+
+register_coercer('datetime', parse_datetime)
+
+class Reference(object):
+ def __init__(self, name):
+ self.name = name
+
+def parse_ref(v):
+ if not v.strip():
+ return None
+ else:
+ return Reference(v)
+
+register_coercer('ref', parse_ref)
+
+def parse_bool(v):
+ v = v.strip().lower()
+ if v in ('y', 'yes', 't', 'true', 'on', '1'):
+ return True
+ elif v in ('n', 'no', 'f', 'false', 'off', '0'):
+ return False
+ raise ValueError(
+ "Value is not boolean-like: %r" % value)
+
+register_coercer('bool', parse_bool)
+register_coercer('boolean', parse_bool)
|
|
From: <sub...@co...> - 2005-11-09 22:20:15
|
Author: test
Date: 2005-11-09 22:20:06 +0000 (Wed, 09 Nov 2005)
New Revision: 1233
Modified:
SQLObject/trunk/sqlobject/manager/command.py
Log:
Clean up configuration and make it use paste deploy's new configuration loader when available
Modified: SQLObject/trunk/sqlobject/manager/command.py
===================================================================
--- SQLObject/trunk/sqlobject/manager/command.py 2005-11-09 00:09:58 UTC (rev 1232)
+++ SQLObject/trunk/sqlobject/manager/command.py 2005-11-09 22:20:06 UTC (rev 1233)
@@ -6,13 +6,11 @@
import sys
import textwrap
import warnings
+import time
try:
- from paste import pyconfig
- from paste import CONFIG
-except ImportError, e:
- pyconfig = None
- CONFIG = {}
-import time
+ from paste.deploy import appconfig
+except ImportError:
+ appconfig = None
import sqlobject
from sqlobject import col
@@ -320,13 +318,15 @@
def config(self):
if not getattr(self.options, 'config_file', None):
return None
- if pyconfig and self.options.config_fn.endswith('.conf'):
- config = pyconfig.Config(with_default=True)
- config.load(self.options.config_file)
- CONFIG.push_process_config(config)
- return config
+ config_file = self.options.config_file
+ if appconfig:
+ if (not config_file.startswith('egg:')
+ and not config_file.startswith('config:')):
+ config_file = 'config:' + config_file
+ return appconfig(config_file,
+ relative_to=os.getcwd())
else:
- return self.ini_config(self.options.config_file)
+ return self.ini_config(config_file)
def ini_config(self, conf_fn):
conf_section = 'main'
|
|
From: <sub...@co...> - 2005-11-08 08:20:29
|
Author: phd Date: 2005-11-08 08:20:16 +0000 (Tue, 08 Nov 2005) New Revision: 1231 Modified: home/phd/SQLObject/paramstyles/docs/links.txt home/phd/SQLObject/paramstyles/sqlobject/joins.py Log: Merged patches from the revisions 1225:1230 from the trunk Modified: home/phd/SQLObject/paramstyles/docs/links.txt =================================================================== --- home/phd/SQLObject/paramstyles/docs/links.txt 2005-11-08 04:52:02 UTC (rev 1230) +++ home/phd/SQLObject/paramstyles/docs/links.txt 2005-11-08 08:20:16 UTC (rev 1231) @@ -20,6 +20,10 @@ * `Pylons <http://pylons.groovie.org/>`_ Web Framework: `Myghty <http://www.myghty.org/>`_ based, with SQLObject integration. +* `Catwalk <http://checkandshare.com/catwalk/>`_ is a web-based + SQLObject browser and object editor (included in TurboGears) + (`related blog items <http://www.checkandshare.com/blog/?cat=8>`_). + * `Nabu <http://furius.ca/nabu/>`_, a publishing system. * `Ultra Gleeper <http://www.crummy.com/software/UltraGleeper/>`_, a @@ -31,9 +35,11 @@ <http://svn.rdflib.net/trunk/rdflib/backends/_sqlobject.py>`_. * Enfold Systems' `EnTransit - <http://www.enfoldsystems.com/About/Talks/entransit-tutorial.pdf>`_ - utilizes SQLObject and rdflib for storing transactional content - from Zope. + <http://www.enfoldsystems.com/About/Talks/entransit-tutorial.pdf>`_ + utilizes SQLObject and rdflib for storing transactional content from + Zope. Also by Enfold is `Sample Inventory Program + <http://www.enfoldsystems.com/Products/Open/SIP>`_, an Open Source + Laboratory Inventory Management Systems. * `Bauble <http://bauble.belizebotanic.org/>`_, a Biodiversity Collection Manager. @@ -74,4 +80,10 @@ <http://formencode.org>`_. * `Translation of SQLObject documentation to Japanese - <http://www.python.jp/~ymasuda/sqlobject/SQLObject.html>`_ + <http://www.python.jp/~ymasuda/sqlobject/SQLObject.html>`_. + +* `How to Use Database Agnostic SQL in SQLObject + <http://groovie.org/articles/2005/11/01/how-to-use-database-agnostic-sql-in-sqlobject>`_. + +* `Using SQLObject with memcached + <http://www.zachary.com/s/blog/2005/09/18/sqlobject_and_memcached,_part_1>`_. Modified: home/phd/SQLObject/paramstyles/sqlobject/joins.py =================================================================== --- home/phd/SQLObject/paramstyles/sqlobject/joins.py 2005-11-08 04:52:02 UTC (rev 1230) +++ home/phd/SQLObject/paramstyles/sqlobject/joins.py 2005-11-08 08:20:16 UTC (rev 1231) @@ -370,7 +370,7 @@ def __getattr__(self, attr): # @@: This passes through private variable access too... should it? # Also magic methods, like __str__ - return getattr(self, select, attr) + return getattr(self.select, attr) def __repr__(self): return '<%s for: %s>' % (self.__class__.__name__, repr(self.select)) |
|
From: <sub...@co...> - 2005-11-08 04:52:11
|
Author: ianb
Date: 2005-11-08 04:52:02 +0000 (Tue, 08 Nov 2005)
New Revision: 1230
Modified:
SQLObject/trunk/sqlobject/joins.py
Log:
Fixed typo
Modified: SQLObject/trunk/sqlobject/joins.py
===================================================================
--- SQLObject/trunk/sqlobject/joins.py 2005-11-08 01:17:13 UTC (rev 1229)
+++ SQLObject/trunk/sqlobject/joins.py 2005-11-08 04:52:02 UTC (rev 1230)
@@ -370,7 +370,7 @@
def __getattr__(self, attr):
# @@: This passes through private variable access too... should it?
# Also magic methods, like __str__
- return getattr(self, select, attr)
+ return getattr(self.select, attr)
def __repr__(self):
return '<%s for: %s>' % (self.__class__.__name__, repr(self.select))
|
|
From: <sub...@co...> - 2005-11-07 17:19:10
|
Author: test Date: 2005-11-07 17:18:57 +0000 (Mon, 07 Nov 2005) New Revision: 1226 Modified: SQLObject/trunk/docs/links.txt Log: Added new links; two blog posts, catwalk, SIP Modified: SQLObject/trunk/docs/links.txt =================================================================== --- SQLObject/trunk/docs/links.txt 2005-11-04 08:21:51 UTC (rev 1225) +++ SQLObject/trunk/docs/links.txt 2005-11-07 17:18:57 UTC (rev 1226) @@ -20,6 +20,10 @@ * `Pylons <http://pylons.groovie.org/>`_ Web Framework: `Myghty <http://www.myghty.org/>`_ based, with SQLObject integration. +* `Catwalk <http://checkandshare.com/catwalk/>`_ is a web-based + SQLObject browser and object editor (included in TurboGears) + (`related blog items <http://www.checkandshare.com/blog/?cat=8>`_). + * `Nabu <http://furius.ca/nabu/>`_, a publishing system. * `Ultra Gleeper <http://www.crummy.com/software/UltraGleeper/>`_, a @@ -31,9 +35,11 @@ <http://svn.rdflib.net/trunk/rdflib/backends/_sqlobject.py>`_. * Enfold Systems' `EnTransit - <http://www.enfoldsystems.com/About/Talks/entransit-tutorial.pdf>`_ - utilizes SQLObject and rdflib for storing transactional content - from Zope. + <http://www.enfoldsystems.com/About/Talks/entransit-tutorial.pdf>`_ + utilizes SQLObject and rdflib for storing transactional content from + Zope. Also by Enfold is `Sample Inventory Program + <http://www.enfoldsystems.com/Products/Open/SIP>`_, an Open Source + Laboratory Inventory Management Systems. * `Bauble <http://bauble.belizebotanic.org/>`_, a Biodiversity Collection Manager. @@ -74,4 +80,10 @@ <http://formencode.org>`_. * `Translation of SQLObject documentation to Japanese - <http://www.python.jp/~ymasuda/sqlobject/SQLObject.html>`_ + <http://www.python.jp/~ymasuda/sqlobject/SQLObject.html>`_. + +* `How to Use Database Agnostic SQL in SQLObject + <http://groovie.org/articles/2005/11/01/how-to-use-database-agnostic-sql-in-sqlobject>`_. + +* `Using SQLObject with memcached + <http://www.zachary.com/s/blog/2005/09/18/sqlobject_and_memcached,_part_1>`_. |
|
From: <sub...@co...> - 2005-11-04 08:21:56
|
Author: phd
Date: 2005-11-04 08:21:51 +0000 (Fri, 04 Nov 2005)
New Revision: 1225
Modified:
home/phd/SQLObject/paramstyles/setup.py
home/phd/SQLObject/paramstyles/sqlobject/conftest.py
home/phd/SQLObject/paramstyles/sqlobject/dbconnection.py
home/phd/SQLObject/paramstyles/sqlobject/declarative.py
home/phd/SQLObject/paramstyles/sqlobject/events.py
home/phd/SQLObject/paramstyles/sqlobject/main.py
home/phd/SQLObject/paramstyles/sqlobject/tests/test_events.py
home/phd/SQLObject/paramstyles/sqlobject/tests/test_index_get.py
Log:
Merged patches from the revisions 1208:1224 from the trunk
Modified: home/phd/SQLObject/paramstyles/setup.py
===================================================================
--- home/phd/SQLObject/paramstyles/setup.py 2005-11-04 08:19:22 UTC (rev 1224)
+++ home/phd/SQLObject/paramstyles/setup.py 2005-11-04 08:21:51 UTC (rev 1225)
@@ -7,8 +7,9 @@
except ImportError:
from distutils.core import setup
-subpackages = ['firebird', 'include', 'inheritance', 'mysql', 'postgres',
- 'sqlite', 'sybase', 'maxdb', 'util', 'manager', 'mssql']
+subpackages = ['firebird', 'include', 'include.pydispatch', 'inheritance',
+ 'manager', 'maxdb', 'mssql', 'mysql', 'postgres', 'sqlite',
+ 'sybase', 'util']
import sys
# patch distutils if it can't cope with the "classifiers" keyword
Modified: home/phd/SQLObject/paramstyles/sqlobject/conftest.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/conftest.py 2005-11-04 08:19:22 UTC (rev 1224)
+++ home/phd/SQLObject/paramstyles/sqlobject/conftest.py 2005-11-04 08:21:51 UTC (rev 1225)
@@ -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: home/phd/SQLObject/paramstyles/sqlobject/dbconnection.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/dbconnection.py 2005-11-04 08:19:22 UTC (rev 1224)
+++ home/phd/SQLObject/paramstyles/sqlobject/dbconnection.py 2005-11-04 08:21:51 UTC (rev 1225)
@@ -928,8 +928,10 @@
"""
This routine can be used to run a function in a transaction,
rolling the transaction back if any exception is raised from
- that function, and committing otherwise. Use like::
+ that function, and committing otherwise.
+ Use like::
+
sqlhub.doInTransaction(process_request, os.environ)
This will run ``process_request(os.environ)``. The return
Modified: home/phd/SQLObject/paramstyles/sqlobject/declarative.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/declarative.py 2005-11-04 08:19:22 UTC (rev 1224)
+++ home/phd/SQLObject/paramstyles/sqlobject/declarative.py 2005-11-04 08:21:51 UTC (rev 1225)
@@ -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: home/phd/SQLObject/paramstyles/sqlobject/events.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/events.py 2005-11-04 08:19:22 UTC (rev 1224)
+++ home/phd/SQLObject/paramstyles/sqlobject/events.py 2005-11-04 08:21:51 UTC (rev 1225)
@@ -1,3 +1,5 @@
+import sys
+import types
from sqlobject.include.pydispatch import dispatcher
from weakref import ref
@@ -4,7 +6,7 @@
subclassClones = {}
-def listen(receiver, soClass, signal, alsoSubclasses=True):
+def listen(receiver, soClass, signal, alsoSubclasses=True, weak=True):
"""
Listen for the given ``signal`` on the SQLObject subclass
``soClass``, calling ``receiver()`` when ``send(soClass, signal,
@@ -13,7 +15,7 @@
If ``alsoSubclasses`` is true, receiver will also be called when
an event is fired on any subclass.
"""
- dispatcher.connect(receiver, signal=signal, sender=soClass)
+ dispatcher.connect(receiver, signal=signal, sender=soClass, weak=weak)
weakReceiver = ref(receiver)
subclassClones.setdefault(soClass, []).append((weakReceiver, signal))
@@ -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,7 +156,124 @@
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):
- __all__.append('value')
+ __all__.append(name)
Modified: home/phd/SQLObject/paramstyles/sqlobject/main.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/main.py 2005-11-04 08:19:22 UTC (rev 1224)
+++ home/phd/SQLObject/paramstyles/sqlobject/main.py 2005-11-04 08:21:51 UTC (rev 1225)
@@ -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
Modified: home/phd/SQLObject/paramstyles/sqlobject/tests/test_events.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/tests/test_events.py 2005-11-04 08:19:22 UTC (rev 1224)
+++ home/phd/SQLObject/paramstyles/sqlobject/tests/test_events.py 2005-11-04 08:21:51 UTC (rev 1225)
@@ -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
Modified: home/phd/SQLObject/paramstyles/sqlobject/tests/test_index_get.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/tests/test_index_get.py 2005-11-04 08:19:22 UTC (rev 1224)
+++ home/phd/SQLObject/paramstyles/sqlobject/tests/test_index_get.py 2005-11-04 08:21:51 UTC (rev 1225)
@@ -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 08:19:27
|
Author: phd
Date: 2005-11-04 08:19:22 +0000 (Fri, 04 Nov 2005)
New Revision: 1224
Modified:
SQLObject/trunk/setup.py
Log:
Added include subpackages.
Modified: SQLObject/trunk/setup.py
===================================================================
--- SQLObject/trunk/setup.py 2005-11-04 08:05:40 UTC (rev 1223)
+++ SQLObject/trunk/setup.py 2005-11-04 08:19:22 UTC (rev 1224)
@@ -7,9 +7,9 @@
except ImportError:
from distutils.core import setup
-subpackages = ['firebird', 'inheritance', 'mysql', 'postgres',
- 'sqlite', 'sybase', 'maxdb', 'util', 'manager',
- 'mssql']
+subpackages = ['firebird', 'include', 'include.pydispatch', 'inheritance',
+ 'manager', 'maxdb', 'mysql', 'mssql', 'postgres', 'sqlite',
+ 'sybase', 'util']
import sys
# patch distutils if it can't cope with the "classifiers" keyword
|
|
From: <sub...@co...> - 2005-11-04 08:05:49
|
Author: ianb
Date: 2005-11-04 08:05:40 +0000 (Fri, 04 Nov 2005)
New Revision: 1223
Modified:
SQLObject/trunk/sqlobject/dbconnection.py
Log:
Fix doc string for pudge
Modified: SQLObject/trunk/sqlobject/dbconnection.py
===================================================================
--- SQLObject/trunk/sqlobject/dbconnection.py 2005-11-04 08:05:17 UTC (rev 1222)
+++ SQLObject/trunk/sqlobject/dbconnection.py 2005-11-04 08:05:40 UTC (rev 1223)
@@ -914,8 +914,10 @@
"""
This routine can be used to run a function in a transaction,
rolling the transaction back if any exception is raised from
- that function, and committing otherwise. Use like::
+ that function, and committing otherwise.
+ Use like::
+
sqlhub.doInTransaction(process_request, os.environ)
This will run ``process_request(os.environ)``. The return
|
|
From: <sub...@co...> - 2005-11-04 08:05:28
|
Author: ianb
Date: 2005-11-04 08:05:17 +0000 (Fri, 04 Nov 2005)
New Revision: 1222
Modified:
SQLObject/trunk/sqlobject/events.py
Log:
Small changes to __all__, and weak arg to listen
Modified: SQLObject/trunk/sqlobject/events.py
===================================================================
--- SQLObject/trunk/sqlobject/events.py 2005-11-04 05:25:25 UTC (rev 1221)
+++ SQLObject/trunk/sqlobject/events.py 2005-11-04 08:05:17 UTC (rev 1222)
@@ -6,7 +6,7 @@
subclassClones = {}
-def listen(receiver, soClass, signal, alsoSubclasses=True):
+def listen(receiver, soClass, signal, alsoSubclasses=True, weak=True):
"""
Listen for the given ``signal`` on the SQLObject subclass
``soClass``, calling ``receiver()`` when ``send(soClass, signal,
@@ -15,7 +15,7 @@
If ``alsoSubclasses`` is true, receiver will also be called when
an event is fired on any subclass.
"""
- dispatcher.connect(receiver, signal=signal, sender=soClass)
+ dispatcher.connect(receiver, signal=signal, sender=soClass, weak=weak)
weakReceiver = ref(receiver)
subclassClones.setdefault(soClass, []).append((weakReceiver, signal))
@@ -276,4 +276,4 @@
__all__ = ['listen', 'send']
for name, value in globals().items():
if isinstance(value, type) and issubclass(value, Signal):
- __all__.append('value')
+ __all__.append(name)
|