sqlobject-cvs Mailing List for SQLObject (Page 131)
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...> - 2006-04-16 12:00:06
|
Author: phd
Date: 2006-04-16 05:59:55 -0600 (Sun, 16 Apr 2006)
New Revision: 1708
Modified:
home/phd/SQLObject/paramstyles/sqlobject/dbconnection.py
home/phd/SQLObject/paramstyles/sqlobject/main.py
home/phd/SQLObject/paramstyles/sqlobject/sqlbuilder.py
home/phd/SQLObject/paramstyles/sqlobject/tests/test_aliases.py
home/phd/SQLObject/paramstyles/sqlobject/tests/test_converters.py
home/phd/SQLObject/paramstyles/sqlobject/tests/test_joins_conditional.py
home/phd/SQLObject/paramstyles/sqlobject/tests/test_subqueries.py
Log:
Merged patches from the revisions 1705:1707 from the trunk: a patch by Charles Duffy <cd...@sp...> - more parethesis around pa
rameters to protect subselects.
Modified: home/phd/SQLObject/paramstyles/sqlobject/dbconnection.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/dbconnection.py 2006-04-16 11:56:29 UTC (rev 1707)
+++ home/phd/SQLObject/paramstyles/sqlobject/dbconnection.py 2006-04-16 11:59:55 UTC (rev 1708)
@@ -628,14 +628,14 @@
columns = ", ".join(columnNames)
if columns:
return self.queryOne(
- "SELECT %s FROM %s WHERE %s = %s" %
+ "SELECT %s FROM %s WHERE %s = (%s)" %
(columns,
so.sqlmeta.table,
so.sqlmeta.idName,
self.sqlrepr(so.id)))
else:
return self.queryOne(
- "SELECT NULL FROM %s WHERE %s = %s" %
+ "SELECT NULL FROM %s WHERE %s = (%s)" %
(so.sqlmeta.table,
so.sqlmeta.idName,
self.sqlrepr(so.id)))
@@ -648,7 +648,7 @@
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])))
+ 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),
@@ -656,20 +656,20 @@
condition))
def _SO_delete(self, so):
- self.query("DELETE FROM %s WHERE %s = %s" %
+ self.query("DELETE FROM %s WHERE %s = (%s)" %
(so.sqlmeta.table,
so.sqlmeta.idName,
self.sqlrepr(so.id)))
def _SO_selectJoin(self, soClass, column, value):
- return self.queryAll("SELECT %s FROM %s WHERE %s = %s" %
+ return self.queryAll("SELECT %s FROM %s WHERE %s = (%s)" %
(soClass.sqlmeta.idName,
soClass.sqlmeta.table,
column,
self.sqlrepr(value)))
def _SO_intermediateJoin(self, table, getColumn, joinColumn, value):
- return self.queryAll("SELECT %s FROM %s WHERE %s = %s" %
+ return self.queryAll("SELECT %s FROM %s WHERE %s = (%s)" %
(getColumn,
table,
joinColumn,
@@ -677,7 +677,7 @@
def _SO_intermediateDelete(self, table, firstColumn, firstValue,
secondColumn, secondValue):
- self.query("DELETE FROM %s WHERE %s = %s AND %s = %s" %
+ self.query("DELETE FROM %s WHERE %s = (%s) AND %s = (%s)" %
(table,
firstColumn,
self.sqlrepr(firstValue),
Modified: home/phd/SQLObject/paramstyles/sqlobject/main.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/main.py 2006-04-16 11:56:29 UTC (rev 1707)
+++ home/phd/SQLObject/paramstyles/sqlobject/main.py 2006-04-16 11:59:55 UTC (rev 1708)
@@ -1483,7 +1483,7 @@
if col.cascade == False:
# Found a restriction
restrict = True
- query.append("%s = %s" % (col.dbName, self.id))
+ query.append("%s = (%s)" % (col.dbName, self.id))
if col.cascade == 'null':
setnull = col.name
elif col.cascade:
Modified: home/phd/SQLObject/paramstyles/sqlobject/sqlbuilder.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/sqlbuilder.py 2006-04-16 11:56:29 UTC (rev 1707)
+++ home/phd/SQLObject/paramstyles/sqlobject/sqlbuilder.py 2006-04-16 11:59:55 UTC (rev 1708)
@@ -259,7 +259,13 @@
self.expr1 = expr1
self.expr2 = expr2
def __sqlrepr__(self, db):
- return "(%s %s %s)" % (sqlrepr(self.expr1, db), self.op, sqlrepr(self.expr2, db))
+ s1 = sqlrepr(self.expr1, db)
+ s2 = sqlrepr(self.expr2, db)
+ if s1[0] != '(' and s1 != 'NULL':
+ s1 = '(' + s1 + ')'
+ if s2[0] != '(' and s2 != 'NULL':
+ s2 = '(' + s2 + ')'
+ return "(%s %s %s)" % (s1, self.op, s2)
def __sqllist__(self):
return ["("] + sqllist(self.expr1) + [self.op] + sqllist(self.expr2) + [")"]
def components(self):
@@ -1004,7 +1010,7 @@
self.expr = expr
self.string = string
def __sqlrepr__(self, db):
- return "(%s %s %s)" % (sqlrepr(self.expr, db), self.op, sqlrepr(self.string, db))
+ return "(%s %s (%s))" % (sqlrepr(self.expr, db), self.op, sqlrepr(self.string, db))
def components(self):
return [self.expr, self.string]
def execute(self, executor):
@@ -1032,7 +1038,7 @@
else:
return "LIKE"
def __sqlrepr__(self, db):
- return "(%s %s %s)" % (
+ return "(%s %s (%s))" % (
sqlrepr(self.expr, db), self._get_op(db), sqlrepr(self.string, db)
)
def execute(self, executor):
Modified: home/phd/SQLObject/paramstyles/sqlobject/tests/test_aliases.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/tests/test_aliases.py 2006-04-16 11:56:29 UTC (rev 1707)
+++ home/phd/SQLObject/paramstyles/sqlobject/tests/test_aliases.py 2006-04-16 11:59:55 UTC (rev 1708)
@@ -15,7 +15,7 @@
alias = Alias(JoinAlias)
select = JoinAlias.select(JoinAlias.q.parent == alias.q.name)
assert str(select) == \
- "SELECT join_alias.id, join_alias.name, join_alias.parent FROM join_alias AS join_alias_alias1, join_alias WHERE (join_alias.parent = join_alias_alias1.name)"
+ "SELECT join_alias.id, join_alias.name, join_alias.parent FROM join_alias AS join_alias_alias1, join_alias WHERE ((join_alias.parent) = (join_alias_alias1.name))"
def test_2perform_join():
setupClass(JoinAlias)
Modified: home/phd/SQLObject/paramstyles/sqlobject/tests/test_converters.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/tests/test_converters.py 2006-04-16 11:56:29 UTC (rev 1707)
+++ home/phd/SQLObject/paramstyles/sqlobject/tests/test_converters.py 2006-04-16 11:59:55 UTC (rev 1708)
@@ -163,7 +163,7 @@
def test_op():
instance = SQLOp('and', 'this', 'that')
- assert sqlrepr(instance, 'mysql') == "('this' AND 'that')"
+ assert sqlrepr(instance, 'mysql') == "(('this') AND ('that'))"
def test_call():
instance = SQLCall('test', ('test',))
Modified: home/phd/SQLObject/paramstyles/sqlobject/tests/test_joins_conditional.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/tests/test_joins_conditional.py 2006-04-16 11:56:29 UTC (rev 1707)
+++ home/phd/SQLObject/paramstyles/sqlobject/tests/test_joins_conditional.py 2006-04-16 11:59:55 UTC (rev 1708)
@@ -35,7 +35,7 @@
on_condition=(TestJoin1.q.col1 == TestJoin2.q.col2))
)
assert str(select) == \
- "SELECT test_join1.id, test_join1.col1 FROM test_join1 LEFT JOIN test_join2 ON (test_join1.col1 = test_join2.col2) WHERE 1 = 1"
+ "SELECT test_join1.id, test_join1.col1 FROM test_join1 LEFT JOIN test_join2 ON ((test_join1.col1) = (test_join2.col2)) WHERE 1 = 1"
def test_3perform_join():
setup()
Modified: home/phd/SQLObject/paramstyles/sqlobject/tests/test_subqueries.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/tests/test_subqueries.py 2006-04-16 11:56:29 UTC (rev 1707)
+++ home/phd/SQLObject/paramstyles/sqlobject/tests/test_subqueries.py 2006-04-16 11:59:55 UTC (rev 1708)
@@ -40,9 +40,25 @@
setup()
select = TestIn1.select(NOTEXISTS(Select(TestIn2.q.col2, where=(Outer(TestIn1).q.col1 == TestIn2.q.col2))))
assert str(select) == \
- "SELECT test_in1.id, test_in1.col1 FROM test_in1 WHERE NOT EXISTS (SELECT test_in2.col2 FROM test_in2 WHERE (test_in1.col1 = test_in2.col2))"
+ "SELECT test_in1.id, test_in1.col1 FROM test_in1 WHERE NOT EXISTS (SELECT test_in2.col2 FROM test_in2 WHERE ((test_in1.col1) = (test_in2.col2)))"
def test_4perform_exists():
insert()
select = TestIn1.select(EXISTS(Select(TestIn2.q.col2, where=(Outer(TestIn1).q.col1 == TestIn2.q.col2))))
assert len(list(select)) == 2
+
+def test_4syntax_direct():
+ setup()
+ select = TestIn1.select(TestIn1.q.col1 == Select(TestIn2.q.col2, where=(TestIn2.q.col2 == "test")))
+ assert str(select) == \
+ "SELECT test_in1.id, test_in1.col1 FROM test_in1 WHERE ((test_in1.col1) = (SELECT test_in2.col2 FROM test_in2 WHERE ((test_in2.col2) = ('test'))))"
+
+def test_4perform_direct():
+ insert()
+ select = TestIn1.select(TestIn1.q.col1 == Select(TestIn2.q.col2, where=(TestIn2.q.col2 == "test")))
+ assert select.count() == 1
+
+def test_5perform_direct():
+ insert()
+ select = TestIn1.select(TestIn1.q.col1 == Select(TestIn2.q.col2, where=(TestIn2.q.col2 == "test")))
+ assert select.count() == 1
|
|
From: <sub...@co...> - 2006-04-16 11:56:38
|
Author: phd
Date: 2006-04-16 05:56:29 -0600 (Sun, 16 Apr 2006)
New Revision: 1707
Modified:
SQLObject/branches/0.7-bugfix/sqlobject/dbconnection.py
SQLObject/branches/0.7-bugfix/sqlobject/main.py
SQLObject/branches/0.7-bugfix/sqlobject/sqlbuilder.py
SQLObject/branches/0.7-bugfix/sqlobject/tests/test_aliases.py
SQLObject/branches/0.7-bugfix/sqlobject/tests/test_converters.py
SQLObject/branches/0.7-bugfix/sqlobject/tests/test_joins_conditional.py
SQLObject/branches/0.7-bugfix/sqlobject/tests/test_subqueries.py
Log:
Merged a patch by Charles Duffy <cd...@sp...> - more parethesis around parameters to protect subselects.
Modified: SQLObject/branches/0.7-bugfix/sqlobject/dbconnection.py
===================================================================
--- SQLObject/branches/0.7-bugfix/sqlobject/dbconnection.py 2006-04-16 11:54:57 UTC (rev 1706)
+++ SQLObject/branches/0.7-bugfix/sqlobject/dbconnection.py 2006-04-16 11:56:29 UTC (rev 1707)
@@ -560,9 +560,9 @@
# in the SQLObject class.
def _SO_update(self, so, values):
- self.query("UPDATE %s SET %s WHERE %s = %s" %
+ self.query("UPDATE %s SET %s WHERE %s = (%s)" %
(so.sqlmeta.table,
- ", ".join(["%s = %s" % (dbName, self.sqlrepr(value))
+ ", ".join(["%s = (%s)" % (dbName, self.sqlrepr(value))
for dbName, value in values]),
so.sqlmeta.idName,
self.sqlrepr(so.id)))
@@ -571,14 +571,14 @@
columns = ", ".join(columnNames)
if columns:
return self.queryOne(
- "SELECT %s FROM %s WHERE %s = %s" %
+ "SELECT %s FROM %s WHERE %s = (%s)" %
(columns,
so.sqlmeta.table,
so.sqlmeta.idName,
self.sqlrepr(so.id)))
else:
return self.queryOne(
- "SELECT NULL FROM %s WHERE %s = %s" %
+ "SELECT NULL FROM %s WHERE %s = (%s)" %
(so.sqlmeta.table,
so.sqlmeta.idName,
self.sqlrepr(so.id)))
@@ -591,20 +591,20 @@
self.sqlrepr(value)))
def _SO_delete(self, so):
- self.query("DELETE FROM %s WHERE %s = %s" %
+ self.query("DELETE FROM %s WHERE %s = (%s)" %
(so.sqlmeta.table,
so.sqlmeta.idName,
self.sqlrepr(so.id)))
def _SO_selectJoin(self, soClass, column, value):
- return self.queryAll("SELECT %s FROM %s WHERE %s = %s" %
+ return self.queryAll("SELECT %s FROM %s WHERE %s = (%s)" %
(soClass.sqlmeta.idName,
soClass.sqlmeta.table,
column,
self.sqlrepr(value)))
def _SO_intermediateJoin(self, table, getColumn, joinColumn, value):
- return self.queryAll("SELECT %s FROM %s WHERE %s = %s" %
+ return self.queryAll("SELECT %s FROM %s WHERE %s = (%s)" %
(getColumn,
table,
joinColumn,
@@ -612,7 +612,7 @@
def _SO_intermediateDelete(self, table, firstColumn, firstValue,
secondColumn, secondValue):
- self.query("DELETE FROM %s WHERE %s = %s AND %s = %s" %
+ self.query("DELETE FROM %s WHERE %s = (%s) AND %s = (%s)" %
(table,
firstColumn,
self.sqlrepr(firstValue),
Modified: SQLObject/branches/0.7-bugfix/sqlobject/main.py
===================================================================
--- SQLObject/branches/0.7-bugfix/sqlobject/main.py 2006-04-16 11:54:57 UTC (rev 1706)
+++ SQLObject/branches/0.7-bugfix/sqlobject/main.py 2006-04-16 11:56:29 UTC (rev 1707)
@@ -1432,7 +1432,7 @@
if col.cascade == False:
# Found a restriction
restrict = True
- query.append("%s = %s" % (col.dbName, self.id))
+ query.append("%s = (%s)" % (col.dbName, self.id))
if col.cascade == 'null':
setnull = col.name
elif col.cascade:
Modified: SQLObject/branches/0.7-bugfix/sqlobject/sqlbuilder.py
===================================================================
--- SQLObject/branches/0.7-bugfix/sqlobject/sqlbuilder.py 2006-04-16 11:54:57 UTC (rev 1706)
+++ SQLObject/branches/0.7-bugfix/sqlobject/sqlbuilder.py 2006-04-16 11:56:29 UTC (rev 1707)
@@ -227,7 +227,13 @@
self.expr1 = expr1
self.expr2 = expr2
def __sqlrepr__(self, db):
- return "(%s %s %s)" % (sqlrepr(self.expr1, db), self.op, sqlrepr(self.expr2, db))
+ s1 = sqlrepr(self.expr1, db)
+ s2 = sqlrepr(self.expr2, db)
+ if s1[0] != '(' and s1 != 'NULL':
+ s1 = '(' + s1 + ')'
+ if s2[0] != '(' and s2 != 'NULL':
+ s2 = '(' + s2 + ')'
+ return "(%s %s %s)" % (s1, self.op, s2)
def components(self):
return [self.expr1, self.expr2]
def execute(self, executor):
@@ -881,7 +887,7 @@
self.expr = expr
self.string = string
def __sqlrepr__(self, db):
- return "(%s %s %s)" % (sqlrepr(self.expr, db), self.op, sqlrepr(self.string, db))
+ return "(%s %s (%s))" % (sqlrepr(self.expr, db), self.op, sqlrepr(self.string, db))
def components(self):
return [self.expr, self.string]
def execute(self, executor):
@@ -909,7 +915,7 @@
else:
return "LIKE"
def __sqlrepr__(self, db):
- return "(%s %s %s)" % (
+ return "(%s %s (%s))" % (
sqlrepr(self.expr, db), self._get_op(db), sqlrepr(self.string, db)
)
def execute(self, executor):
Modified: SQLObject/branches/0.7-bugfix/sqlobject/tests/test_aliases.py
===================================================================
--- SQLObject/branches/0.7-bugfix/sqlobject/tests/test_aliases.py 2006-04-16 11:54:57 UTC (rev 1706)
+++ SQLObject/branches/0.7-bugfix/sqlobject/tests/test_aliases.py 2006-04-16 11:56:29 UTC (rev 1707)
@@ -15,7 +15,7 @@
alias = Alias(JoinAlias)
select = JoinAlias.select(JoinAlias.q.parent == alias.q.name)
assert str(select) == \
- "SELECT join_alias.id, join_alias.name, join_alias.parent FROM join_alias AS join_alias_alias1, join_alias WHERE (join_alias.parent = join_alias_alias1.name)"
+ "SELECT join_alias.id, join_alias.name, join_alias.parent FROM join_alias AS join_alias_alias1, join_alias WHERE ((join_alias.parent) = (join_alias_alias1.name))"
def test_2perform_join():
setupClass(JoinAlias)
Modified: SQLObject/branches/0.7-bugfix/sqlobject/tests/test_converters.py
===================================================================
--- SQLObject/branches/0.7-bugfix/sqlobject/tests/test_converters.py 2006-04-16 11:54:57 UTC (rev 1706)
+++ SQLObject/branches/0.7-bugfix/sqlobject/tests/test_converters.py 2006-04-16 11:56:29 UTC (rev 1707)
@@ -163,7 +163,7 @@
def test_op():
instance = SQLOp('and', 'this', 'that')
- assert sqlrepr(instance, 'mysql') == "('this' AND 'that')"
+ assert sqlrepr(instance, 'mysql') == "(('this') AND ('that'))"
def test_call():
instance = SQLCall('test', ('test',))
Modified: SQLObject/branches/0.7-bugfix/sqlobject/tests/test_joins_conditional.py
===================================================================
--- SQLObject/branches/0.7-bugfix/sqlobject/tests/test_joins_conditional.py 2006-04-16 11:54:57 UTC (rev 1706)
+++ SQLObject/branches/0.7-bugfix/sqlobject/tests/test_joins_conditional.py 2006-04-16 11:56:29 UTC (rev 1707)
@@ -35,7 +35,7 @@
on_condition=(TestJoin1.q.col1 == TestJoin2.q.col2))
)
assert str(select) == \
- "SELECT test_join1.id, test_join1.col1 FROM test_join1 LEFT JOIN test_join2 ON (test_join1.col1 = test_join2.col2) WHERE 1 = 1"
+ "SELECT test_join1.id, test_join1.col1 FROM test_join1 LEFT JOIN test_join2 ON ((test_join1.col1) = (test_join2.col2)) WHERE 1 = 1"
def test_3perform_join():
setup()
Modified: SQLObject/branches/0.7-bugfix/sqlobject/tests/test_subqueries.py
===================================================================
--- SQLObject/branches/0.7-bugfix/sqlobject/tests/test_subqueries.py 2006-04-16 11:54:57 UTC (rev 1706)
+++ SQLObject/branches/0.7-bugfix/sqlobject/tests/test_subqueries.py 2006-04-16 11:56:29 UTC (rev 1707)
@@ -40,9 +40,25 @@
setup()
select = TestIn1.select(NOTEXISTS(Select(TestIn2.q.col2, where=(Outer(TestIn1).q.col1 == TestIn2.q.col2))))
assert str(select) == \
- "SELECT test_in1.id, test_in1.col1 FROM test_in1 WHERE NOT EXISTS (SELECT test_in2.col2 FROM test_in2 WHERE (test_in1.col1 = test_in2.col2))"
+ "SELECT test_in1.id, test_in1.col1 FROM test_in1 WHERE NOT EXISTS (SELECT test_in2.col2 FROM test_in2 WHERE ((test_in1.col1) = (test_in2.col2)))"
def test_4perform_exists():
insert()
select = TestIn1.select(EXISTS(Select(TestIn2.q.col2, where=(Outer(TestIn1).q.col1 == TestIn2.q.col2))))
assert len(list(select)) == 2
+
+def test_4syntax_direct():
+ setup()
+ select = TestIn1.select(TestIn1.q.col1 == Select(TestIn2.q.col2, where=(TestIn2.q.col2 == "test")))
+ assert str(select) == \
+ "SELECT test_in1.id, test_in1.col1 FROM test_in1 WHERE ((test_in1.col1) = (SELECT test_in2.col2 FROM test_in2 WHERE ((test_in2.col2) = ('test'))))"
+
+def test_4perform_direct():
+ insert()
+ select = TestIn1.select(TestIn1.q.col1 == Select(TestIn2.q.col2, where=(TestIn2.q.col2 == "test")))
+ assert select.count() == 1
+
+def test_5perform_direct():
+ insert()
+ select = TestIn1.select(TestIn1.q.col1 == Select(TestIn2.q.col2, where=(TestIn2.q.col2 == "test")))
+ assert select.count() == 1
|
|
From: <sub...@co...> - 2006-04-16 11:55:13
|
Author: phd
Date: 2006-04-16 05:54:57 -0600 (Sun, 16 Apr 2006)
New Revision: 1706
Modified:
SQLObject/trunk/sqlobject/dbconnection.py
SQLObject/trunk/sqlobject/main.py
SQLObject/trunk/sqlobject/sqlbuilder.py
SQLObject/trunk/sqlobject/tests/test_aliases.py
SQLObject/trunk/sqlobject/tests/test_converters.py
SQLObject/trunk/sqlobject/tests/test_joins_conditional.py
SQLObject/trunk/sqlobject/tests/test_subqueries.py
Log:
A patch by Charles Duffy <cd...@sp...> - more parethesis around parameters to protect subselects.
Modified: SQLObject/trunk/sqlobject/dbconnection.py
===================================================================
--- SQLObject/trunk/sqlobject/dbconnection.py 2006-04-15 10:36:47 UTC (rev 1705)
+++ SQLObject/trunk/sqlobject/dbconnection.py 2006-04-16 11:54:57 UTC (rev 1706)
@@ -604,9 +604,9 @@
# in the SQLObject class.
def _SO_update(self, so, values):
- self.query("UPDATE %s SET %s WHERE %s = %s" %
+ self.query("UPDATE %s SET %s WHERE %s = (%s)" %
(so.sqlmeta.table,
- ", ".join(["%s = %s" % (dbName, self.sqlrepr(value))
+ ", ".join(["%s = (%s)" % (dbName, self.sqlrepr(value))
for dbName, value in values]),
so.sqlmeta.idName,
self.sqlrepr(so.id)))
@@ -615,14 +615,14 @@
columns = ", ".join(columnNames)
if columns:
return self.queryOne(
- "SELECT %s FROM %s WHERE %s = %s" %
+ "SELECT %s FROM %s WHERE %s = (%s)" %
(columns,
so.sqlmeta.table,
so.sqlmeta.idName,
self.sqlrepr(so.id)))
else:
return self.queryOne(
- "SELECT NULL FROM %s WHERE %s = %s" %
+ "SELECT NULL FROM %s WHERE %s = (%s)" %
(so.sqlmeta.table,
so.sqlmeta.idName,
self.sqlrepr(so.id)))
@@ -635,7 +635,7 @@
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])))
+ 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),
@@ -643,20 +643,20 @@
condition))
def _SO_delete(self, so):
- self.query("DELETE FROM %s WHERE %s = %s" %
+ self.query("DELETE FROM %s WHERE %s = (%s)" %
(so.sqlmeta.table,
so.sqlmeta.idName,
self.sqlrepr(so.id)))
def _SO_selectJoin(self, soClass, column, value):
- return self.queryAll("SELECT %s FROM %s WHERE %s = %s" %
+ return self.queryAll("SELECT %s FROM %s WHERE %s = (%s)" %
(soClass.sqlmeta.idName,
soClass.sqlmeta.table,
column,
self.sqlrepr(value)))
def _SO_intermediateJoin(self, table, getColumn, joinColumn, value):
- return self.queryAll("SELECT %s FROM %s WHERE %s = %s" %
+ return self.queryAll("SELECT %s FROM %s WHERE %s = (%s)" %
(getColumn,
table,
joinColumn,
@@ -664,7 +664,7 @@
def _SO_intermediateDelete(self, table, firstColumn, firstValue,
secondColumn, secondValue):
- self.query("DELETE FROM %s WHERE %s = %s AND %s = %s" %
+ self.query("DELETE FROM %s WHERE %s = (%s) AND %s = (%s)" %
(table,
firstColumn,
self.sqlrepr(firstValue),
Modified: SQLObject/trunk/sqlobject/main.py
===================================================================
--- SQLObject/trunk/sqlobject/main.py 2006-04-15 10:36:47 UTC (rev 1705)
+++ SQLObject/trunk/sqlobject/main.py 2006-04-16 11:54:57 UTC (rev 1706)
@@ -1483,7 +1483,7 @@
if col.cascade == False:
# Found a restriction
restrict = True
- query.append("%s = %s" % (col.dbName, self.id))
+ query.append("%s = (%s)" % (col.dbName, self.id))
if col.cascade == 'null':
setnull = col.name
elif col.cascade:
Modified: SQLObject/trunk/sqlobject/sqlbuilder.py
===================================================================
--- SQLObject/trunk/sqlobject/sqlbuilder.py 2006-04-15 10:36:47 UTC (rev 1705)
+++ SQLObject/trunk/sqlobject/sqlbuilder.py 2006-04-16 11:54:57 UTC (rev 1706)
@@ -230,7 +230,13 @@
self.expr1 = expr1
self.expr2 = expr2
def __sqlrepr__(self, db):
- return "(%s %s %s)" % (sqlrepr(self.expr1, db), self.op, sqlrepr(self.expr2, db))
+ s1 = sqlrepr(self.expr1, db)
+ s2 = sqlrepr(self.expr2, db)
+ if s1[0] != '(' and s1 != 'NULL':
+ s1 = '(' + s1 + ')'
+ if s2[0] != '(' and s2 != 'NULL':
+ s2 = '(' + s2 + ')'
+ return "(%s %s %s)" % (s1, self.op, s2)
def components(self):
return [self.expr1, self.expr2]
def execute(self, executor):
@@ -884,7 +890,7 @@
self.expr = expr
self.string = string
def __sqlrepr__(self, db):
- return "(%s %s %s)" % (sqlrepr(self.expr, db), self.op, sqlrepr(self.string, db))
+ return "(%s %s (%s))" % (sqlrepr(self.expr, db), self.op, sqlrepr(self.string, db))
def components(self):
return [self.expr, self.string]
def execute(self, executor):
@@ -912,7 +918,7 @@
else:
return "LIKE"
def __sqlrepr__(self, db):
- return "(%s %s %s)" % (
+ return "(%s %s (%s))" % (
sqlrepr(self.expr, db), self._get_op(db), sqlrepr(self.string, db)
)
def execute(self, executor):
Modified: SQLObject/trunk/sqlobject/tests/test_aliases.py
===================================================================
--- SQLObject/trunk/sqlobject/tests/test_aliases.py 2006-04-15 10:36:47 UTC (rev 1705)
+++ SQLObject/trunk/sqlobject/tests/test_aliases.py 2006-04-16 11:54:57 UTC (rev 1706)
@@ -15,7 +15,7 @@
alias = Alias(JoinAlias)
select = JoinAlias.select(JoinAlias.q.parent == alias.q.name)
assert str(select) == \
- "SELECT join_alias.id, join_alias.name, join_alias.parent FROM join_alias AS join_alias_alias1, join_alias WHERE (join_alias.parent = join_alias_alias1.name)"
+ "SELECT join_alias.id, join_alias.name, join_alias.parent FROM join_alias AS join_alias_alias1, join_alias WHERE ((join_alias.parent) = (join_alias_alias1.name))"
def test_2perform_join():
setupClass(JoinAlias)
Modified: SQLObject/trunk/sqlobject/tests/test_converters.py
===================================================================
--- SQLObject/trunk/sqlobject/tests/test_converters.py 2006-04-15 10:36:47 UTC (rev 1705)
+++ SQLObject/trunk/sqlobject/tests/test_converters.py 2006-04-16 11:54:57 UTC (rev 1706)
@@ -163,7 +163,7 @@
def test_op():
instance = SQLOp('and', 'this', 'that')
- assert sqlrepr(instance, 'mysql') == "('this' AND 'that')"
+ assert sqlrepr(instance, 'mysql') == "(('this') AND ('that'))"
def test_call():
instance = SQLCall('test', ('test',))
Modified: SQLObject/trunk/sqlobject/tests/test_joins_conditional.py
===================================================================
--- SQLObject/trunk/sqlobject/tests/test_joins_conditional.py 2006-04-15 10:36:47 UTC (rev 1705)
+++ SQLObject/trunk/sqlobject/tests/test_joins_conditional.py 2006-04-16 11:54:57 UTC (rev 1706)
@@ -35,7 +35,7 @@
on_condition=(TestJoin1.q.col1 == TestJoin2.q.col2))
)
assert str(select) == \
- "SELECT test_join1.id, test_join1.col1 FROM test_join1 LEFT JOIN test_join2 ON (test_join1.col1 = test_join2.col2) WHERE 1 = 1"
+ "SELECT test_join1.id, test_join1.col1 FROM test_join1 LEFT JOIN test_join2 ON ((test_join1.col1) = (test_join2.col2)) WHERE 1 = 1"
def test_3perform_join():
setup()
Modified: SQLObject/trunk/sqlobject/tests/test_subqueries.py
===================================================================
--- SQLObject/trunk/sqlobject/tests/test_subqueries.py 2006-04-15 10:36:47 UTC (rev 1705)
+++ SQLObject/trunk/sqlobject/tests/test_subqueries.py 2006-04-16 11:54:57 UTC (rev 1706)
@@ -40,9 +40,25 @@
setup()
select = TestIn1.select(NOTEXISTS(Select(TestIn2.q.col2, where=(Outer(TestIn1).q.col1 == TestIn2.q.col2))))
assert str(select) == \
- "SELECT test_in1.id, test_in1.col1 FROM test_in1 WHERE NOT EXISTS (SELECT test_in2.col2 FROM test_in2 WHERE (test_in1.col1 = test_in2.col2))"
+ "SELECT test_in1.id, test_in1.col1 FROM test_in1 WHERE NOT EXISTS (SELECT test_in2.col2 FROM test_in2 WHERE ((test_in1.col1) = (test_in2.col2)))"
def test_4perform_exists():
insert()
select = TestIn1.select(EXISTS(Select(TestIn2.q.col2, where=(Outer(TestIn1).q.col1 == TestIn2.q.col2))))
assert len(list(select)) == 2
+
+def test_4syntax_direct():
+ setup()
+ select = TestIn1.select(TestIn1.q.col1 == Select(TestIn2.q.col2, where=(TestIn2.q.col2 == "test")))
+ assert str(select) == \
+ "SELECT test_in1.id, test_in1.col1 FROM test_in1 WHERE ((test_in1.col1) = (SELECT test_in2.col2 FROM test_in2 WHERE ((test_in2.col2) = ('test'))))"
+
+def test_4perform_direct():
+ insert()
+ select = TestIn1.select(TestIn1.q.col1 == Select(TestIn2.q.col2, where=(TestIn2.q.col2 == "test")))
+ assert select.count() == 1
+
+def test_5perform_direct():
+ insert()
+ select = TestIn1.select(TestIn1.q.col1 == Select(TestIn2.q.col2, where=(TestIn2.q.col2 == "test")))
+ assert select.count() == 1
|
|
From: <sub...@co...> - 2006-04-15 04:42:26
|
Author: ianb Date: 2006-04-14 22:42:21 -0600 (Fri, 14 Apr 2006) New Revision: 1697 Modified: SQLObject/docs/index.comments.txt Log: in page: http://pythonpaste.org/ Modified: SQLObject/docs/index.comments.txt =================================================================== --- SQLObject/docs/index.comments.txt 2006-04-15 04:41:42 UTC (rev 1696) +++ SQLObject/docs/index.comments.txt 2006-04-15 04:42:21 UTC (rev 1697) @@ -5,7 +5,7 @@ ip: 84.190.227.75 username: MB -Hier kann man Kommentare eingeben +Hier kann man Kommentare eingeben ==== $(example) c ---------------------------------------- date: 2006-01-31T06:42:16 |
|
From: <sub...@co...> - 2006-04-15 04:41:52
|
Author: ianb Date: 2006-04-14 22:41:42 -0600 (Fri, 14 Apr 2006) New Revision: 1696 Modified: SQLObject/docs/index.comments.txt Log: in page: http://pythonpaste.org/ Add comment Modified: SQLObject/docs/index.comments.txt =================================================================== --- SQLObject/docs/index.comments.txt 2006-04-13 16:02:48 UTC (rev 1695) +++ SQLObject/docs/index.comments.txt 2006-04-15 04:41:42 UTC (rev 1696) @@ -30,3 +30,10 @@ username: Adrian H. Just spamming this page with another test! :) +==== $(example) c +++ +---------------------------------------- +date: 2006-04-14T22:41:40 +id: 5 +ip: 68.98.143.137 + +testing |
|
From: <sub...@co...> - 2006-04-11 15:19:17
|
Author: ericdm
Date: 2006-04-11 09:19:11 -0600 (Tue, 11 Apr 2006)
New Revision: 1691
Added:
SQLObject/branches/trunk-oracle/sqlobject/oracle/
SQLObject/branches/trunk-oracle/sqlobject/oracle/__init__.py
SQLObject/branches/trunk-oracle/sqlobject/oracle/oracleconnection.py
Log:
Adding the directory for the Oracle connection.
Added: SQLObject/branches/trunk-oracle/sqlobject/oracle/__init__.py
===================================================================
--- SQLObject/branches/trunk-oracle/sqlobject/oracle/__init__.py 2006-04-11 15:15:50 UTC (rev 1690)
+++ SQLObject/branches/trunk-oracle/sqlobject/oracle/__init__.py 2006-04-11 15:19:11 UTC (rev 1691)
@@ -0,0 +1,14 @@
+from sqlobject.dbconnection import registerConnection
+
+def builder():
+ import oracleconnection
+ return oracleconnection.OracleConnection
+
+def isSupported():
+ try:
+ import cx_Oracle
+ except ImportError:
+ return False
+ return True
+
+registerConnection(['oracle'], builder, isSupported)
Added: SQLObject/branches/trunk-oracle/sqlobject/oracle/oracleconnection.py
===================================================================
--- SQLObject/branches/trunk-oracle/sqlobject/oracle/oracleconnection.py 2006-04-11 15:15:50 UTC (rev 1690)
+++ SQLObject/branches/trunk-oracle/sqlobject/oracle/oracleconnection.py 2006-04-11 15:19:11 UTC (rev 1691)
@@ -0,0 +1,183 @@
+from sqlobject.dbconnection import DBAPI
+from sqlobject import col
+cx_Oracle = None
+
+import array
+
+class OracleConnection(DBAPI):
+
+ supportTransactions = True
+ dbName = 'oracle'
+ schemes = [dbName]
+
+ def __init__(self, db, user, passwd='', host='localhost', port=1521, **kw):
+ global cx_Oracle
+ if cx_Oracle is None:
+ import cx_Oracle
+ self.module = cx_Oracle
+ self.db = db
+ self.user = user
+ self.password = passwd
+ self.host = host
+ self.port = port
+ DBAPI.__init__(self, **kw)
+
+ def connectionFromURI(cls, uri):
+ user, password, host, port, path, args = cls._parseURI(uri)
+ return cls(db=path.strip('/'), user=user or '', passwd=password or '', host=host or 'localhost', port=port or 1521, **args)
+ connectionFromURI = classmethod(connectionFromURI)
+
+ def _setAutoCommit(self, conn, auto):
+ pass
+
+ def makeConnection(self):
+ return cx_Oracle.connect('%s/%s@%s:%s/%s' % (self.user, self.password, self.host, self.port, self.db))
+
+ def _queryInsertID(self, conn, soInstance, id, names, values):
+ """Oracle can use 'sequences' to create new ids for a table.
+ The sequence is created when the table is created. """
+ table = soInstance.sqlmeta.table
+ idName = soInstance.sqlmeta.idName
+ # Nothing ever sets _idSequence (why?) so this getattr call always returns the default name.
+ sequenceName = getattr(soInstance, '_idSequence', '%s_ID_SEQ' % table)
+
+ cs = conn.cursor()
+ if id is None:
+ # The select syntax requires a table name. The Oracle convention is to select
+ # from the dual table since it always exists. It could be any table.
+ cs.execute('SELECT %s.NEXTVAL from dual' % sequenceName)
+ id = cs.fetchone()[0]
+ names = [idName] + names
+ values = [id] + values
+ q = self._insertSQL(table, names, values)
+ if self.debug:
+ self.printDebug(conn, q, 'QueryIns')
+ cs.execute(q)
+ if self.debugOutput:
+ self.printDebug(conn, id, 'QueryIns', 'result')
+ return id
+
+ def _queryAddLimitOffset(self, query, start, end):
+ # XXX Oracle doesn't support LIMIT
+ return query
+
+ def createTable(self, soClass):
+ self.query('CREATE TABLE %s (\n%s\n)' % (soClass.sqlmeta.table, self.createColumns(soClass)))
+ self.query("CREATE SEQUENCE %s_ID_SEQ" % soClass.sqlmeta.table)
+
+ def createColumn(self, soClass, col):
+ return col.oracleCreateSQL()
+
+ def createReferenceConstraint(self, soClass, col):
+ return col.oracleCreateReferenceConstraint()
+
+ def createIndexSQL(self, soClass, index):
+ return index.oracleCreateIndexSQL(soClass)
+
+ def createIDColumn(self, soClass):
+ key_type = {int: "INT", str: "VARCHAR(1000)"}[soClass.sqlmeta.idType]
+ return '%s %s PRIMARY KEY' % (soClass.sqlmeta.idName, key_type)
+
+ def createBinary(self, value):
+ """Translate value to Oracle hex format, that is 01, 02, ... FF.
+ This should work up to 4000 characters, the Oracle limit for strings
+ in sql statements."""
+ if value is None:
+ return value
+ else:
+ # e.g. 'abc' --> '616263'
+ # s = '%s%s%s' % (chr(253), chr(254), chr(255)) --> 'FDFEFF'
+
+ x = ''.join(['%02X' % ord(c) for c in value])
+ return x
+
+ def returnBinary(self, value):
+ """Translate value from Oracle hex format to a string of byte values."""
+ try:
+ len(value)
+ except TypeError:
+ return value
+ a = array.array('B')
+ l = []
+ for i in range(len(value)-1):
+ if i % 2:
+ continue
+ l.append(eval('0x%s%s' % (value[i], value[i+1])))
+ a.fromlist(l)
+ return a.tostring()
+
+ def joinSQLType(self, join):
+ return 'INT NOT NULL'
+
+ def tableExists(self, tableName):
+ for (table,) in self.queryAll("SELECT TABLE_NAME FROM USER_TABLES"):
+ if table.lower() == tableName.lower():
+ return True
+ return False
+
+ def addColumn(self, tableName, column):
+ self.query('ALTER TABLE %s ADD %s' % (tableName, column.oracleCreateSQL()))
+
+ def dropTable(self, tableName, cascade=False):
+ self.query("DROP TABLE %s %s" % (tableName, cascade and 'CASCADE CONSTRAINTS' or ''))
+ try:
+ self.query("DROP SEQUENCE %s_ID_SEQ" % tableName)
+ except:
+ pass
+
+ def delColumn(self, tableName, column):
+ self.query('ALTER TABLE %s DROP COLUMN %s' % (tableName, column.dbName))
+
+ def columnsFromSchema(self, tableName, soClass):
+ colData = self.queryAll("SELECT LOWER(COLUMN_NAME), DATA_TYPE, NULLABLE, DATA_DEFAULT, DATA_TYPE FROM USER_TAB_COLUMNS WHERE TABLE_NAME = UPPER('%s')" % tableName)
+ primaryKey = self.queryOne("select lower(a.column_name) from sys.user_cons_columns a, sys.user_constraints b where b.table_name = '%s' and b.constraint_type = 'P' and b.constraint_name = a.constraint_name" % str.upper(tableName))
+
+ results = []
+ for field, t, nullAllowed, default, defaultType in colData:
+ if primaryKey and field == primaryKey[0]:
+ continue
+ colClass, kw = self.guessClass(t)
+ kw['name'] = soClass.sqlmeta.style.dbColumnToPythonAttr(field)
+ kw['notNone'] = not nullAllowed
+ if default:
+ kw['default'] = self.decodeLong(default, defaultType)
+ else:
+ kw['default'] = None
+ results.append(colClass(**kw))
+ return results
+
+ def decodeLong(self, value, type):
+ if type == 'CHAR':
+ return value.replace("'", "").strip()
+ return value
+
+ def guessClass(self, t):
+ if t.startswith('int'):
+ return col.IntCol, {}
+ elif t.startswith('varchar'):
+ return col.StringCol, {'length': int(t[8:-1])}
+ elif t.startswith('char'):
+ return col.StringCol, {'length': int(t[5:-1]), 'varchar': False}
+ elif t.startswith('datetime'):
+ return col.DateTimeCol, {}
+ elif t.startswith('bool'):
+ return col.BoolCol, {}
+ elif t.startswith('tinyblob'):
+ return col.BLOBCol, {"length": 2**8-1}
+ elif t.startswith('tinytext'):
+ return col.BLOBCol, {"length": 2**8-1, "varchar": True}
+ elif t.startswith('blob'):
+ return col.BLOBCol, {"length": 2**16-1}
+ elif t.startswith('text'):
+ return col.BLOBCol, {"length": 2**16-1, "varchar": True}
+ elif t.startswith('mediumblob'):
+ return col.BLOBCol, {"length": 2**24-1}
+ elif t.startswith('mediumtext'):
+ return col.BLOBCol, {"length": 2**24-1, "varchar": True}
+ elif t.startswith('longblob'):
+ return col.BLOBCol, {"length": 2**32}
+ elif t.startswith('longtext'):
+ return col.BLOBCol, {"length": 2**32, "varchar": True}
+ else:
+ return col.Col, {}
+
|
|
From: <sub...@co...> - 2006-04-11 15:16:09
|
Author: ericdm
Date: 2006-04-11 09:15:50 -0600 (Tue, 11 Apr 2006)
New Revision: 1690
Modified:
SQLObject/branches/trunk-oracle/setup.py
SQLObject/branches/trunk-oracle/sqlobject/__init__.py
SQLObject/branches/trunk-oracle/sqlobject/col.py
SQLObject/branches/trunk-oracle/sqlobject/conftest.py
SQLObject/branches/trunk-oracle/sqlobject/converters.py
SQLObject/branches/trunk-oracle/sqlobject/dbconnection.py
SQLObject/branches/trunk-oracle/sqlobject/index.py
SQLObject/branches/trunk-oracle/sqlobject/joins.py
SQLObject/branches/trunk-oracle/sqlobject/main.py
SQLObject/branches/trunk-oracle/sqlobject/sqlbuilder.py
SQLObject/branches/trunk-oracle/sqlobject/tests/dbtest.py
SQLObject/branches/trunk-oracle/sqlobject/tests/test_aliases.py
SQLObject/branches/trunk-oracle/sqlobject/tests/test_auto.py
SQLObject/branches/trunk-oracle/sqlobject/tests/test_auto_old.py
SQLObject/branches/trunk-oracle/sqlobject/tests/test_combining_joins.py
SQLObject/branches/trunk-oracle/sqlobject/tests/test_create_drop.py
SQLObject/branches/trunk-oracle/sqlobject/tests/test_cyclic_reference.py
SQLObject/branches/trunk-oracle/sqlobject/tests/test_datetime.py
SQLObject/branches/trunk-oracle/sqlobject/tests/test_indexes.py
SQLObject/branches/trunk-oracle/sqlobject/tests/test_joins.py
SQLObject/branches/trunk-oracle/sqlobject/tests/test_setters.py
SQLObject/branches/trunk-oracle/sqlobject/tests/test_slice.py
SQLObject/branches/trunk-oracle/sqlobject/tests/test_stringid.py
SQLObject/branches/trunk-oracle/sqlobject/tests/test_stringid_old.py
SQLObject/branches/trunk-oracle/sqlobject/tests/test_subqueries.py
Log:
Committing the initial changes for Oracle support.
Modified: SQLObject/branches/trunk-oracle/setup.py
===================================================================
--- SQLObject/branches/trunk-oracle/setup.py 2006-04-11 08:15:40 UTC (rev 1689)
+++ SQLObject/branches/trunk-oracle/setup.py 2006-04-11 15:15:50 UTC (rev 1690)
@@ -11,7 +11,7 @@
subpackages = ['firebird', 'include', 'include.pydispatch', 'inheritance',
'manager', 'maxdb', 'mysql', 'mssql', 'postgres', 'sqlite',
- 'sybase', 'util']
+ 'sybase', 'util', 'oracle']
import sys
# patch distutils if it can't cope with the "classifiers" keyword
@@ -65,6 +65,7 @@
'postgresql': ['psycopg'],
'mysql': ['MySQLdb'],
'sqlite': ['pysqlite'],
+ 'oracle': ['cx_Oracle'],
# Others?
},
**kw
Modified: SQLObject/branches/trunk-oracle/sqlobject/__init__.py
===================================================================
--- SQLObject/branches/trunk-oracle/sqlobject/__init__.py 2006-04-11 08:15:40 UTC (rev 1689)
+++ SQLObject/branches/trunk-oracle/sqlobject/__init__.py 2006-04-11 15:15:50 UTC (rev 1690)
@@ -18,6 +18,11 @@
_warn('FirebirdConnection is deprecated; use connectionForURI("firebird://...") or "from sqlobject.firebird import builder; FirebirdConnection = builder()"')
return _firebird.builder()(*args, **kw)
+import oracle as _oracle
+def OracleConnection(*args, **kw):
+ _warn('OracleConnection is deprecated; use connectionForURI("oracle://...") or "from sqlobject.oracle import builder; OracleConnection = builder()"')
+ return _oracle.builder()(*args, **kw)
+
import mysql as _mysql
def MySQLConnection(*args, **kw):
_warn('MySQLConnection is deprecated; use connectionForURI("mysql://...") or "from sqlobject.mysql import builder; MySQLConnection = builder()"')
Modified: SQLObject/branches/trunk-oracle/sqlobject/col.py
===================================================================
--- SQLObject/branches/trunk-oracle/sqlobject/col.py 2006-04-11 08:15:40 UTC (rev 1689)
+++ SQLObject/branches/trunk-oracle/sqlobject/col.py 2006-04-11 15:15:50 UTC (rev 1690)
@@ -325,6 +325,9 @@
def _maxdbType(self):
return self._sqlType()
+ def _oracleType(self):
+ return self._sqlType()
+
def mysqlCreateSQL(self):
return ' '.join([self.dbName, self._mysqlType()] + self._extraSQL())
@@ -352,6 +355,9 @@
def maxdbCreateSQL(self):
return ' '.join([self.dbName, self._maxdbType()] + self._extraSQL())
+ def oracleCreateSQL(self):
+ return ' '.join([self.dbName, self._oracleType()] + self._extraSQL())
+
def __get__(self, obj, type=None):
if obj is None:
# class attribute, return the descriptor itself
@@ -503,7 +509,15 @@
else:
return self._sqlType()
+ def _oracleType(self):
+ if not self.length:
+ return 'VARCHAR(1000)'
+ elif not self.varchar:
+ return 'CHAR(%i)' % self.length
+ else:
+ return 'VARCHAR(%i)' % self.length
+
class StringValidator(validators.Validator):
def to_python(self, value, state):
@@ -643,6 +657,9 @@
def _firebirdType(self):
return 'INT'
+ def _oracleType(self):
+ return 'NUMBER(1,0)'
+
def _maxdbType(self):
return "BOOLEAN"
@@ -690,6 +707,9 @@
def _mysqlType(self):
return "DOUBLE PRECISION"
+ def _oracleType(self):
+ return 'NUMBER'
+
class FloatCol(Col):
baseClass = SOFloatCol
@@ -711,6 +731,10 @@
key_type = {int: "INT NULL", str: "TEXT"}
return key_type[self.soClass.sqlmeta.idType]
+ def _oracleType(self):
+ key_type = {int: "INT", str: "VARCHAR(1000)"}
+ return key_type[self.soClass.sqlmeta.idType]
+
class KeyCol(Col):
baseClass = SOKeyCol
@@ -824,6 +848,41 @@
# @@: Code from above should be moved here
return None
+ def oracleCreateSQL(self):
+ sql = SOKeyCol.oracleCreateSQL(self)
+ return sql
+
+ def oracleCreateReferenceConstraint(self):
+ sTName = self.soClass.sqlmeta.table
+ other = findClass(self.foreignKey)
+ tName = other.sqlmeta.table
+ idName = other.sqlmeta.idName
+ #prevent constraint name > 30 characters
+ constName = str(sTName + '_' + self.dbName)
+ if len(constName) > 30:
+ from md5 import md5
+ constName = 'c' + md5(constName).hexdigest()[:29]
+ if self.cascade is not None:
+ if self.cascade == 'null':
+ action = 'ON DELETE SET NULL'
+ elif self.cascade:
+ action = 'ON DELETE CASCADE'
+ else:
+ action = ''
+ else:
+ action = ''
+ constraint = ('ALTER TABLE %(sTName)s ADD CONSTRAINT %(constName)s '
+ 'FOREIGN KEY (%(colName)s) '
+ 'REFERENCES %(tName)s (%(idName)s) '
+ '%(action)s' %
+ {'tName': tName,
+ 'constName': constName,
+ 'colName': self.dbName,
+ 'idName': idName,
+ 'action': action,
+ 'sTName': sTName})
+ return constraint
+
def mssqlCreateSQL(self):
sql = SOKeyCol.mssqlCreateSQL(self)
other = findClass(self.foreignKey)
@@ -901,6 +960,12 @@
#NB. Return a tuple, not a string here
return "VARCHAR(%i)" % (length), checkConstraint
+ def _oracleType(self):
+ length = max(map(self._getlength, self.enumValues))
+ enumValues = ', '.join([sqlbuilder.sqlrepr(v, 'oracle') for v in self.enumValues])
+ checkConstraint = "CHECK (%s in (%s))" % (self.dbName, enumValues)
+ return "VARCHAR(%i) %s" % (length, checkConstraint)
+
def _maxdbType(self):
raise "Enum type is not supported"
@@ -1036,6 +1101,10 @@
def _firebirdType(self):
return 'TIMESTAMP'
+ def _oracleType(self):
+ #return 'DATE'
+ return 'TIMESTAMP'
+
def _maxdbType(self):
return 'TIMESTAMP'
@@ -1102,6 +1171,9 @@
def _firebirdType(self):
return 'DATE'
+ def _oracleType(self):
+ return 'DATE'
+
def _maxdbType(self):
return 'DATE'
@@ -1156,6 +1228,9 @@
def _firebirdType(self):
return 'TIME'
+ def _oracleType(self):
+ return 'TIMESTAMP'
+
def _maxdbType(self):
return 'TIME'
@@ -1293,6 +1368,9 @@
def _mssqlType(self):
return "IMAGE"
+ def _oracleType(self):
+ return 'BLOB'
+
class BLOBCol(StringCol):
baseClass = SOBLOBCol
@@ -1333,6 +1411,9 @@
name=self.name, pickleProtocol=self.pickleProtocol)] + \
super(SOPickleCol, self).createValidators()
+ def _oracleType(self):
+ return 'BLOB'
+
class PickleCol(BLOBCol):
baseClass = SOPickleCol
Modified: SQLObject/branches/trunk-oracle/sqlobject/conftest.py
===================================================================
--- SQLObject/branches/trunk-oracle/sqlobject/conftest.py 2006-04-11 08:15:40 UTC (rev 1689)
+++ SQLObject/branches/trunk-oracle/sqlobject/conftest.py 2006-04-11 15:15:50 UTC (rev 1690)
@@ -27,6 +27,7 @@
'sqlite': 'sqlite:/:memory:',
'sybase': 'sybase://test:test123@sybase/test?autoCommit=0',
'firebird': 'firebird://sysdba:masterkey@localhost/var/lib/firebird/data/test.gdb',
+ 'oracle': 'oracle://phoenix:phoenix@10.10.16.164/orcl',
'mssql': 'mssql://sa:@127.0.0.1/test'
}
Modified: SQLObject/branches/trunk-oracle/sqlobject/converters.py
===================================================================
--- SQLObject/branches/trunk-oracle/sqlobject/converters.py 2006-04-11 08:15:40 UTC (rev 1689)
+++ SQLObject/branches/trunk-oracle/sqlobject/converters.py 2006-04-11 15:15:50 UTC (rev 1690)
@@ -112,7 +112,7 @@
if db in ('mysql', 'postgres'):
for orig, repl in sqlStringReplace:
value = value.replace(orig, repl)
- elif db in ('sqlite', 'firebird', 'sybase', 'maxdb', 'mssql'):
+ elif db in ('sqlite', 'firebird', 'sybase', 'maxdb', 'mssql', 'oracle'):
value = value.replace("'", "''")
else:
assert 0, "Database %s unknown" % db
@@ -161,15 +161,30 @@
if DateTimeType:
def DateTimeConverter(value, db):
- return "'%s'" % isoStr(value)
+ if db in ('oracle',):
+ #return "TO_DATE('%s', 'YYYY-MM-DD HH24:MI:SS')" % "%s" % isoStr(value)
+ return "TO_TIMESTAMP('%s', 'YYYY-MM-DD HH24:MI:SS')" % "%s" % isoStr(value).rstrip('.')
+ else:
+ return "'%s'" % isoStr(value)
registerConverter(DateTimeType, DateTimeConverter)
def TimeConverter(value, db):
- return "'%s'" % value.strftime("%T")
+ if db in ('oracle',):
+ return "TO_TIMESTAMP('%s', 'HH24:MI:SS')" % value.strftime('%H:%M:%S')
+ else:
+ return "'%s'" % value.strftime("%T")
registerConverter(DateTimeDeltaType, TimeConverter)
+ #def DateConverter(value, db):
+ # if db in ('oracle',):
+ # return "TO_DATE('%s', 'YYYY-MM-DD')" % value.strftime('%Y-%m-%d')
+ # else:
+ # return "'%4d-%02d-%02d'" % (value.year, value.month, value.day)
+#
+ #registerConverter(DateTimeType, DateConverter)
+
def NoneConverter(value, db):
return "NULL"
@@ -183,25 +198,39 @@
if hasattr(time, 'struct_time'):
def StructTimeConverter(value, db):
- return time.strftime("'%Y-%m-%d %H:%M:%S'", value)
+ if db in ('oracle',):
+ #return "TO_DATE('%s', 'YYYY-MM-DD HH24:MI:SS')" % time.strftime('%Y-%m-%d %H:%M:%S', value)
+ return "TO_TIMESTAMP('%s', 'HH24:MI:SS')" % time.strftime('%H:%M:%S', value)
+ else:
+ return time.strftime("'%Y-%m-%d %H:%M:%S'", value)
registerConverter(time.struct_time, StructTimeConverter)
if datetime:
def DateTimeConverter(value, db):
- return "'%4d-%02d-%02d %02d:%02d:%02d'" % (
- value.year, value.month, value.day,
- value.hour, value.minute, value.second)
+ if db in ('oracle',):
+ #return "TO_DATE('%s', 'YYYY-MM-DD HH24:MI:SS')" % value.strftime('%Y-%m-%d %H:%M:%S')
+ return "TO_TIMESTAMP('%s', 'YYYY-MM-DD HH24:MI:SS')" % value.strftime('%Y-%m-%d %H:%M:%S')
+ else:
+ return "'%4d-%02d-%02d %02d:%02d:%02d'" % (
+ value.year, value.month, value.day,
+ value.hour, value.minute, value.second)
registerConverter(datetime.datetime, DateTimeConverter)
def DateConverter(value, db):
- return "'%4d-%02d-%02d'" % (value.year, value.month, value.day)
+ if db in ('oracle',):
+ return "TO_DATE('%s', 'YYYY-MM-DD')" % value.strftime('%Y-%m-%d')
+ else:
+ return "'%4d-%02d-%02d'" % (value.year, value.month, value.day)
registerConverter(datetime.date, DateConverter)
def TimeConverter(value, db):
- return "'%02d:%02d:%02d'" % (value.hour, value.minute, value.second)
+ if db in ('oracle',):
+ return "TO_TIMESTAMP('%s', 'HH24:MI:SS')" % value.strftime('%H:%M:%S')
+ else:
+ return "'%02d:%02d:%02d'" % (value.hour, value.minute, value.second)
registerConverter(datetime.time, TimeConverter)
Modified: SQLObject/branches/trunk-oracle/sqlobject/dbconnection.py
===================================================================
--- SQLObject/branches/trunk-oracle/sqlobject/dbconnection.py 2006-04-11 08:15:40 UTC (rev 1689)
+++ SQLObject/branches/trunk-oracle/sqlobject/dbconnection.py 2006-04-11 15:15:50 UTC (rev 1690)
@@ -220,7 +220,11 @@
self._pool = []
self._poolLock = threading.Lock()
DBConnection.__init__(self, **kw)
- self._binaryType = type(self.module.Binary(''))
+ try:
+ self._binaryType = type(self.module.Binary(''))
+ except:
+ #dirty hack because cx_Oracle doesn't implement Binary()
+ self._binaryType = type(self.module.BINARY)
def _runWithConnection(self, meth, *args):
conn = self.getConnection()
Modified: SQLObject/branches/trunk-oracle/sqlobject/index.py
===================================================================
--- SQLObject/branches/trunk-oracle/sqlobject/index.py 2006-04-11 08:15:40 UTC (rev 1689)
+++ SQLObject/branches/trunk-oracle/sqlobject/index.py 2006-04-11 15:15:50 UTC (rev 1690)
@@ -100,7 +100,8 @@
', '.join(spec))
return ret
- postgresCreateIndexSQL = maxdbCreateIndexSQL = mssqlCreateIndexSQL = sybaseCreateIndexSQL = firebirdCreateIndexSQL = sqliteCreateIndexSQL
+ postgresCreateIndexSQL = maxdbCreateIndexSQL = mssqlCreateIndexSQL = sybaseCreateIndexSQL = firebirdCreateIndexSQL = oracleCreateIndexSQL = sqliteCreateIndexSQL
+
def mysqlCreateIndexSQL(self, soClass):
if self.unique:
uniqueOrIndex = 'UNIQUE'
Modified: SQLObject/branches/trunk-oracle/sqlobject/joins.py
===================================================================
--- SQLObject/branches/trunk-oracle/sqlobject/joins.py 2006-04-11 08:15:40 UTC (rev 1689)
+++ SQLObject/branches/trunk-oracle/sqlobject/joins.py 2006-04-11 15:15:50 UTC (rev 1690)
@@ -4,6 +4,7 @@
import classregistry
from col import popKey
import events
+from md5 import md5
__all__ = ['MultipleJoin', 'SQLMultipleJoin', 'RelatedJoin', 'SQLRelatedJoin',
'SingleJoin', 'ManyToMany', 'OneToMany']
@@ -184,10 +185,13 @@
def _setOtherRelatedClass(self, otherClass):
if not self.intermediateTable:
- names = [self.soClass.sqlmeta.table,
- otherClass.sqlmeta.table]
+ #make a name that is unique and short enough that all databases
+ #can handle the length of the table name (*cough* *Oracle* *cough*)
+ #and ensure that the name starts with a letter
+ names = [self.soClass.sqlmeta.table, otherClass.sqlmeta.table]
names.sort()
- self.intermediateTable = '%s_%s' % (names[0], names[1])
+ textName = '%s_%s' % (names[0], names[1])
+ self.intermediateTable = 'j' + str(md5(textName).hexdigest())[:20]
if not self.otherColumn:
self.otherColumn = self.soClass.sqlmeta.style.tableReference(
otherClass.sqlmeta.table)
@@ -328,10 +332,13 @@
def _finishSet(self):
if self.intermediateTable is None:
- names = [self.soClass.sqlmeta.table,
- self.otherClass.sqlmeta.table]
+ #make a name that is unique and short enough that all databases
+ #can handle the length of the table name (*cough* *Oracle* *cough*)
+ #and ensure that the name starts with a letter
+ names = [self.soClass.sqlmeta.table, self.otherClass.sqlmeta.table]
names.sort()
- self.intermediateTable = '%s_%s' % (names[0], names[1])
+ textName = '%s_%s' % (names[0], names[1])
+ self.intermediateTable = 'j' + str(md5(textName).hexdigest())[:20]
if not self.otherColumn:
self.otherColumn = self.soClass.sqlmeta.style.tableReference(
self.otherClass.sqlmeta.table)
Modified: SQLObject/branches/trunk-oracle/sqlobject/main.py
===================================================================
--- SQLObject/branches/trunk-oracle/sqlobject/main.py 2006-04-11 08:15:40 UTC (rev 1689)
+++ SQLObject/branches/trunk-oracle/sqlobject/main.py 2006-04-11 15:15:50 UTC (rev 1690)
@@ -698,7 +698,7 @@
_parent = None # A reference to the parent instance
childName = None # Children name (to be able to get a subclass)
# moved to sqlmeta in 0.8:
- _parentClass = _sqlmeta_attr('parentClass', 2)
+ parentClass = _sqlmeta_attr('parentClass', 2)
_childClasses = _sqlmeta_attr('childClasses', 2)
# The law of Demeter: the class should not call another classes by name
@@ -1228,6 +1228,7 @@
# Then we check if the column wasn't passed in, and
# if not we try to get the default.
if not kw.has_key(column.name) and not kw.has_key(column.foreignName):
+# if not foundColName and not foundFkName:
default = column.default
# If we don't get it, it's an error:
@@ -1362,11 +1363,15 @@
cls.sqlmeta.send(events.CreateTableSignal, cls, connection,
extra_sql, post_funcs)
constraints = conn.createTable(cls)
- if applyConstraints:
- for constraint in constraints:
- conn.query(constraint)
- else:
- extra_sql.extend(constraints)
+
+ #edm 3/29/06
+ if constraints:
+ if applyConstraints:
+ for constraint in constraints:
+ conn.query(constraint)
+ else:
+ extra_sql.extend(constraints)
+
if createJoinTables:
cls.createJoinTables(ifNotExists=ifNotExists,
connection=conn)
Modified: SQLObject/branches/trunk-oracle/sqlobject/sqlbuilder.py
===================================================================
--- SQLObject/branches/trunk-oracle/sqlobject/sqlbuilder.py 2006-04-11 08:15:40 UTC (rev 1689)
+++ SQLObject/branches/trunk-oracle/sqlobject/sqlbuilder.py 2006-04-11 15:15:50 UTC (rev 1690)
@@ -384,7 +384,7 @@
return self.alias + "." + self.fieldName
def tablesUsedImmediate(self):
- return ["%s AS %s" % (self.tableName, self.alias)]
+ return ["%s %s" % (self.tableName, self.alias)]
class AliasTable(Table):
FieldClass = AliasField
@@ -660,12 +660,12 @@
def __init__(self, table1, table2, op=','):
if table1 and type(table1) <> str:
if isinstance(table1, Alias):
- table1 = "%s AS %s" % (table1.q.tableName, table1.q.alias)
+ table1 = "%s %s" % (table1.q.tableName, table1.q.alias)
else:
table1 = table1.sqlmeta.table
if type(table2) <> str:
if isinstance(table2, Alias):
- table2 = "%s AS %s" % (table2.q.tableName, table2.q.alias)
+ table2 = "%s %s" % (table2.q.tableName, table2.q.alias)
else:
table2 = table2.sqlmeta.table
self.table1 = table1
@@ -909,12 +909,19 @@
return "REGEXP"
elif db == 'postgres':
return "~"
+ elif db == 'oracle':
+ return 'REGEXP_LIKE'
else:
return "LIKE"
def __sqlrepr__(self, db):
- return "(%s %s %s)" % (
- sqlrepr(self.expr, db), self._get_op(db), sqlrepr(self.string, db)
- )
+ if db == 'oracle':
+ return "%s(%s, %s)" % (
+ self._get_op(db), sqlrepr(self.expr, db), sqlrepr(self.string, db)
+ )
+ else:
+ return "(%s %s %s)" % (
+ sqlrepr(self.expr, db), self._get_op(db), sqlrepr(self.string, db)
+ )
def execute(self, executor):
self.op = self._get_op(self.db)
return LIKE.execute(self, executor)
Modified: SQLObject/branches/trunk-oracle/sqlobject/tests/dbtest.py
===================================================================
--- SQLObject/branches/trunk-oracle/sqlobject/tests/dbtest.py 2006-04-11 08:15:40 UTC (rev 1689)
+++ SQLObject/branches/trunk-oracle/sqlobject/tests/dbtest.py 2006-04-11 15:15:50 UTC (rev 1690)
@@ -40,7 +40,7 @@
'-blobData': 'mssql',
'-decimalColumn': 'mssql',
'-emptyTable': 'mssql',
- '-limitSelect' : 'mssql'
+ '-limitSelect' : 'mssql, oracle'
}
Modified: SQLObject/branches/trunk-oracle/sqlobject/tests/test_aliases.py
===================================================================
--- SQLObject/branches/trunk-oracle/sqlobject/tests/test_aliases.py 2006-04-11 08:15:40 UTC (rev 1689)
+++ SQLObject/branches/trunk-oracle/sqlobject/tests/test_aliases.py 2006-04-11 15:15:50 UTC (rev 1690)
@@ -15,7 +15,7 @@
alias = Alias(JoinAlias)
select = JoinAlias.select(JoinAlias.q.parent == alias.q.name)
assert str(select) == \
- "SELECT join_alias.id, join_alias.name, join_alias.parent FROM join_alias AS join_alias_alias1, join_alias WHERE (join_alias.parent = join_alias_alias1.name)"
+ "SELECT join_alias.id, join_alias.name, join_alias.parent FROM join_alias join_alias_alias1, join_alias WHERE (join_alias.parent = join_alias_alias1.name)"
def test_2perform_join():
setupClass(JoinAlias)
Modified: SQLObject/branches/trunk-oracle/sqlobject/tests/test_auto.py
===================================================================
--- SQLObject/branches/trunk-oracle/sqlobject/tests/test_auto.py 2006-04-11 08:15:40 UTC (rev 1689)
+++ SQLObject/branches/trunk-oracle/sqlobject/tests/test_auto.py 2006-04-11 15:15:50 UTC (rev 1690)
@@ -120,6 +120,23 @@
)
"""
+ oracleCreate = """
+ CREATE TABLE auto_test (
+ auto_id INT PRIMARY KEY,
+ first_name VARCHAR(100),
+ last_name VARCHAR(200) NOT NULL,
+ age INT DEFAULT 0,
+ created VARCHAR(40) NOT NULL,
+ happy char(1) DEFAULT 'Y' NOT NULL,
+ long_field VARCHAR(2000),
+ wannahavefun SMALLINT DEFAULT 0 NOT NULL
+ )
+ """
+
+ oracleCreateSequence = """
+ CREATE SEQUENCE auto_test_id_seq
+ """
+
mysqlDrop = """
DROP TABLE IF EXISTS auto_test
"""
@@ -134,12 +151,23 @@
mssqlDrop = sybaseDrop
+ oracleDrop = """
+ DROP TABLE auto_test
+ """
+
+ oracleDropSequence = """
+ DROP SEQUENCE auto_test_id_seq
+ """
+
def setup_method(self, meth):
conn = getConnection()
dbName = conn.dbName
creator = getattr(self, dbName + 'Create', None)
if creator:
conn.query(creator)
+ sequence = getattr(self, dbName + 'CreateSequence', None)
+ if sequence:
+ conn.query(sequence)
def teardown_method(self, meth):
conn = getConnection()
@@ -147,6 +175,9 @@
dropper = getattr(self, dbName + 'Drop', None)
if dropper:
conn.query(dropper)
+ sequenceDropper = getattr(self, dbName + 'DropSequence', None)
+ if sequenceDropper:
+ conn.query(sequenceDropper)
def test_classCreate(self):
if not supports('fromDatabase'):
Modified: SQLObject/branches/trunk-oracle/sqlobject/tests/test_auto_old.py
===================================================================
--- SQLObject/branches/trunk-oracle/sqlobject/tests/test_auto_old.py 2006-04-11 08:15:40 UTC (rev 1689)
+++ SQLObject/branches/trunk-oracle/sqlobject/tests/test_auto_old.py 2006-04-11 15:15:50 UTC (rev 1690)
@@ -121,6 +121,23 @@
)
"""
+ oracleCreate = """
+ CREATE TABLE old_auto_test (
+ auto_id INT PRIMARY KEY,
+ first_name VARCHAR(100),
+ last_name VARCHAR(200) NOT NULL,
+ age INT DEFAULT 0,
+ created VARCHAR(40) NOT NULL,
+ happy char(1) DEFAULT 'Y' NOT NULL,
+ long_field VARCHAR(1000),
+ wannahavefun INT DEFAULT 0 NOT NULL
+ )
+ """
+
+ oracleCreateSequence = """
+ CREATE SEQUENCE old_auto_test_id_seq
+ """
+
mysqlDrop = """
DROP TABLE IF EXISTS old_auto_test
"""
@@ -136,12 +153,24 @@
mssqlDrop = """
DROP TABLE old_auto_test
"""
+
+ oracleDrop = """
+ DROP TABLE old_auto_test
+ """
+
+ oracleDropSequence = """
+ DROP SEQUENCE old_auto_test_id_seq
+ """
+
def setup_method(self, meth):
conn = getConnection()
dbName = conn.dbName
creator = getattr(self, dbName + 'Create', None)
if creator:
conn.query(creator)
+ sequence = getattr(self, dbName + 'CreateSequence', None)
+ if sequence:
+ conn.query(sequence)
def teardown_method(self, meth):
conn = getConnection()
@@ -149,6 +178,9 @@
dropper = getattr(self, dbName + 'Drop', None)
if dropper:
conn.query(dropper)
+ sequenceDropper = getattr(self, dbName + 'DropSequence', None)
+ if sequenceDropper:
+ conn.query(sequenceDropper)
def test_classCreate(self):
if not supports('fromDatabase'):
Modified: SQLObject/branches/trunk-oracle/sqlobject/tests/test_combining_joins.py
===================================================================
--- SQLObject/branches/trunk-oracle/sqlobject/tests/test_combining_joins.py 2006-04-11 08:15:40 UTC (rev 1689)
+++ SQLObject/branches/trunk-oracle/sqlobject/tests/test_combining_joins.py 2006-04-11 15:15:50 UTC (rev 1690)
@@ -35,8 +35,8 @@
assert list(Complex.selectBy(name='c1')) == [c1]
assert list(cg1.unit_models) == [u1]
- assert list(cg2.unit_models) == [u1, u2, u2]
- assert list(cg2.unit_models.distinct()) == [u1, u2]
+ assert list(cg2.unit_models).sort() == [u1, u2, u2].sort()
+ assert list(cg2.unit_models.distinct()).sort() == [u1, u2].sort()
assert list(
cg2.unit_models.filter(UnitModel.q.name=='u1')) == [u1]
Modified: SQLObject/branches/trunk-oracle/sqlobject/tests/test_create_drop.py
===================================================================
--- SQLObject/branches/trunk-oracle/sqlobject/tests/test_create_drop.py 2006-04-11 08:15:40 UTC (rev 1689)
+++ SQLObject/branches/trunk-oracle/sqlobject/tests/test_create_drop.py 2006-04-11 15:15:50 UTC (rev 1690)
@@ -6,7 +6,7 @@
idName = 'test_id_here'
table = 'test_create_drop_table'
name = StringCol()
- number = IntCol()
+ anumber = IntCol()
time = DateTimeCol()
short = StringCol(length=10)
blobcol = BLOBCol()
Modified: SQLObject/branches/trunk-oracle/sqlobject/tests/test_cyclic_reference.py
===================================================================
--- SQLObject/branches/trunk-oracle/sqlobject/tests/test_cyclic_reference.py 2006-04-11 08:15:40 UTC (rev 1689)
+++ SQLObject/branches/trunk-oracle/sqlobject/tests/test_cyclic_reference.py 2006-04-11 15:15:50 UTC (rev 1690)
@@ -4,9 +4,9 @@
class TestCyclicReferenceA(SQLObject):
class sqlmeta(sqlmeta):
idName = 'test_id_here'
- table = 'test_cyclic_reference_a_table'
+ table = 'test_cyclic_reference_a'
name = StringCol()
- number = IntCol()
+ anumber = IntCol()
time = DateTimeCol()
short = StringCol(length=10)
blobcol = BLOBCol()
@@ -15,9 +15,9 @@
class TestCyclicReferenceB(SQLObject):
class sqlmeta(sqlmeta):
idName = 'test_id_here'
- table = 'test_cyclic_reference_b_table'
+ table = 'test_cyclic_reference_b'
name = StringCol()
- number = IntCol()
+ anumber = IntCol()
time = DateTimeCol()
short = StringCol(length=10)
blobcol = BLOBCol()
Modified: SQLObject/branches/trunk-oracle/sqlobject/tests/test_datetime.py
===================================================================
--- SQLObject/branches/trunk-oracle/sqlobject/tests/test_datetime.py 2006-04-11 08:15:40 UTC (rev 1689)
+++ SQLObject/branches/trunk-oracle/sqlobject/tests/test_datetime.py 2006-04-11 15:15:50 UTC (rev 1690)
@@ -52,12 +52,14 @@
class DateTime2(SQLObject):
col1 = DateTimeCol()
col2 = DateCol(dateFormat=dateFormat)
+ #col2 = DateCol()
col3 = TimeCol()
def test_mxDateTime():
setupClass(DateTime2)
_now = now()
dt2 = DateTime2(col1=_now, col2=_now, col3=Time(_now.hour, _now.minute, int(_now.second)))
+ #dt2 = DateTime2(col1=_now, col2=Date(_now.year, _now.month, _now.day), col3=Time(_now.hour, _now.minute, int(_now.second)))
assert isinstance(dt2.col1, col.DateTimeType)
assert dt2.col1.year == _now.year
Modified: SQLObject/branches/trunk-oracle/sqlobject/tests/test_indexes.py
===================================================================
--- SQLObject/branches/trunk-oracle/sqlobject/tests/test_indexes.py 2006-04-11 08:15:40 UTC (rev 1689)
+++ SQLObject/branches/trunk-oracle/sqlobject/tests/test_indexes.py 2006-04-11 15:15:50 UTC (rev 1690)
@@ -7,12 +7,14 @@
class SOIndex1(SQLObject):
name = StringCol(length=100)
- number = IntCol()
+ anumber = IntCol()
- nameIndex = DatabaseIndex('name', unique=True)
- nameIndex2 = DatabaseIndex(name, number)
+ #nameIndex = DatabaseIndex('name', unique=True)
+ nameIndex2 = DatabaseIndex(name, anumber)
+ #nameIndex3 = DatabaseIndex({'column': name,
+ # 'length': 3})
nameIndex3 = DatabaseIndex({'column': name,
- 'length': 3})
+ 'length': 3}, unique=True)
class SOIndex2(SQLObject):
@@ -25,10 +27,10 @@
n = 0
for name in 'blah blech boring yep yort snort'.split():
n += 1
- SOIndex1(name=name, number=n)
+ SOIndex1(name=name, anumber=n)
mod = SOIndex1._connection.module
try:
- SOIndex1(name='blah', number=0)
+ SOIndex1(name='blah', anumber=0)
except (mod.ProgrammingError, mod.IntegrityError, mod.OperationalError, mod.DatabaseError):
# expected
pass
Modified: SQLObject/branches/trunk-oracle/sqlobject/tests/test_joins.py
===================================================================
--- SQLObject/branches/trunk-oracle/sqlobject/tests/test_joins.py 2006-04-11 08:15:40 UTC (rev 1689)
+++ SQLObject/branches/trunk-oracle/sqlobject/tests/test_joins.py 2006-04-11 15:15:50 UTC (rev 1690)
@@ -47,10 +47,10 @@
self.assertNamesEqual(z.personJoiners, [])
def assertZipsEqual(self, zips, dest):
- assert [a.zip for a in zips] == dest
+ assert [a.zip for a in zips].sort() == dest.sort()
def assertNamesEqual(self, people, dest):
- assert [p.name for p in people] == dest
+ assert [p.name for p in people].sort() == dest.sort()
def test_joinAttributeWithUnderscores(self):
# Make sure that the implicit setting of joinMethodName works
Modified: SQLObject/branches/trunk-oracle/sqlobject/tests/test_setters.py
===================================================================
--- SQLObject/branches/trunk-oracle/sqlobject/tests/test_setters.py 2006-04-11 08:15:40 UTC (rev 1689)
+++ SQLObject/branches/trunk-oracle/sqlobject/tests/test_setters.py 2006-04-11 15:15:50 UTC (rev 1690)
@@ -1,7 +1,7 @@
from sqlobject import *
from sqlobject.tests.dbtest import *
-class TestPlainAndNonPlainSetter(SQLObject):
+class TestSetters(SQLObject):
firstName = StringCol(length=50, dbName='fname_col', default=None)
lastName = StringCol(length=50, dbName='lname_col', default=None)
@@ -14,8 +14,8 @@
return "%s %s" % (self.firstName, self.lastName)
def test_create():
- setupClass(TestPlainAndNonPlainSetter)
- t = TestPlainAndNonPlainSetter(name='John Doe')
+ setupClass(TestSetters)
+ t = TestSetters(name='John Doe')
assert t.firstName == 'John'
assert t.lastName == 'Doe'
- assert t.name == 'John Doe'
\ No newline at end of file
+ assert t.name == 'John Doe'
Modified: SQLObject/branches/trunk-oracle/sqlobject/tests/test_slice.py
===================================================================
--- SQLObject/branches/trunk-oracle/sqlobject/tests/test_slice.py 2006-04-11 08:15:40 UTC (rev 1689)
+++ SQLObject/branches/trunk-oracle/sqlobject/tests/test_slice.py 2006-04-11 15:15:50 UTC (rev 1690)
@@ -7,45 +7,45 @@
class Counter(SQLObject):
- number = IntCol(notNull=True)
+ anumber = IntCol(notNull=True)
class TestSlice:
def setup_method(self, meth):
setupClass(Counter)
for i in range(100):
- Counter(number=i)
+ Counter(anumber=i)
def counterEqual(self, counters, value):
if not supports('limitSelect'):
return
- assert [c.number for c in counters] == value
+ assert [c.anumber for c in counters] == value
def test_1(self):
self.counterEqual(
- Counter.select(None, orderBy='number'), range(100))
+ Counter.select(None, orderBy='anumber'), range(100))
def test_2(self):
self.counterEqual(
- Counter.select(None, orderBy='number')[10:20],
+ Counter.select(None, orderBy='anumber')[10:20],
range(10, 20))
def test_3(self):
self.counterEqual(
- Counter.select(None, orderBy='number')[20:30][:5],
+ Counter.select(None, orderBy='anumber')[20:30][:5],
range(20, 25))
def test_4(self):
self.counterEqual(
- Counter.select(None, orderBy='number')[:-10],
+ Counter.select(None, orderBy='anumber')[:-10],
range(0, 90))
def test_5(self):
self.counterEqual(
- Counter.select(None, orderBy='number', reversed=True),
+ Counter.select(None, orderBy='anumber', reversed=True),
range(99, -1, -1))
def test_6(self):
self.counterEqual(
- Counter.select(None, orderBy='-number'),
+ Counter.select(None, orderBy='-anumber'),
range(99, -1, -1))
Modified: SQLObject/branches/trunk-oracle/sqlobject/tests/test_stringid.py
===================================================================
--- SQLObject/branches/trunk-oracle/sqlobject/tests/test_stringid.py 2006-04-11 08:15:40 UTC (rev 1689)
+++ SQLObject/branches/trunk-oracle/sqlobject/tests/test_stringid.py 2006-04-11 15:15:50 UTC (rev 1690)
@@ -40,6 +40,13 @@
)
"""
+ oracleCreate = """
+ CREATE TABLE so_string_id (
+ id VARCHAR2(50) NOT NULL PRIMARY KEY,
+ val VARCHAR2(50) NULL
+ )
+ """
+
mssqlCreate = """
CREATE TABLE so_string_id (
id VARCHAR(50) PRIMARY KEY,
Modified: SQLObject/branches/trunk-oracle/sqlobject/tests/test_stringid_old.py
===================================================================
--- SQLObject/branches/trunk-oracle/sqlobject/tests/test_stringid_old.py 2006-04-11 08:15:40 UTC (rev 1689)
+++ SQLObject/branches/trunk-oracle/sqlobject/tests/test_stringid_old.py 2006-04-11 15:15:50 UTC (rev 1690)
@@ -50,6 +50,17 @@
sqliteCreate = postgresCreate
+ oracleCreate = """
+ CREATE TABLE so_string_id (
+ id VARCHAR(50) PRIMARY KEY,
+ val VARCHAR(50) NULL
+ )
+ """
+
+ oracleCreateSequence = """
+ CREATE SEQUENCE so_string_id_ID_SEQ
+ """
+
mysqlDrop = """
DROP TABLE IF EXISTS so_string_id
"""
@@ -62,7 +73,15 @@
firebirdDrop = postgresDrop
mssqlDrop = postgresDrop
+ oracleDrop = """
+ DROP TABLE so_string_id
+ """
+ oracleDropSequence = """
+ DROP SEQUENCE so_string_id_ID_SEQ
+ """
+
+
def test_stringID():
setupClass(OldSOStringID)
t = OldSOStringID(id='hey', val='whatever')
Modified: SQLObject/branches/trunk-oracle/sqlobject/tests/test_subqueries.py
===================================================================
--- SQLObject/branches/trunk-oracle/sqlobject/tests/test_subqueries.py 2006-04-11 08:15:40 UTC (rev 1689)
+++ SQLObject/branches/trunk-oracle/sqlobject/tests/test_subqueries.py 2006-04-11 15:15:50 UTC (rev 1690)
@@ -19,10 +19,10 @@
def insert():
setup()
TestIn1(col1=None)
- TestIn1(col1='')
+ TestIn1(col1="A")
TestIn1(col1="test")
TestIn2(col2=None)
- TestIn2(col2='')
+ TestIn2(col2="A")
TestIn2(col2="test")
def test_1syntax_in():
|
|
From: <sub...@co...> - 2006-04-10 21:20:15
|
Author: ericdm Date: 2006-04-10 15:20:12 -0600 (Mon, 10 Apr 2006) New Revision: 1688 Added: SQLObject/branches/trunk-oracle/ Log: Creating a branch for Oracle support. Copied: SQLObject/branches/trunk-oracle (from rev 1687, SQLObject/trunk) |
|
From: <sub...@co...> - 2006-04-10 21:19:03
|
Author: ericdm Date: 2006-04-10 15:18:59 -0600 (Mon, 10 Apr 2006) New Revision: 1687 Removed: SQLObject/branches/trunk-oracle/ Log: Deleting this stuff and checking it in the right way. |
|
From: <sub...@co...> - 2006-04-06 14:52:41
|
Author: phd
Date: 2006-04-06 08:52:32 -0600 (Thu, 06 Apr 2006)
New Revision: 1685
Modified:
home/phd/SQLObject/paramstyles/sqlobject/col.py
home/phd/SQLObject/paramstyles/sqlobject/dbconnection.py
home/phd/SQLObject/paramstyles/sqlobject/joins.py
home/phd/SQLObject/paramstyles/sqlobject/tests/test_transactions.py
Log:
Merged patches from the revisions 1678:1684 from the trunk
Modified: home/phd/SQLObject/paramstyles/sqlobject/col.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/col.py 2006-04-06 14:51:16 UTC (rev 1684)
+++ home/phd/SQLObject/paramstyles/sqlobject/col.py 2006-04-06 14:52:32 UTC (rev 1685)
@@ -727,6 +727,31 @@
kw['name'] = style.instanceAttrToIDAttr(kw['name'])
super(SOForeignKey, self).__init__(**kw)
+ def sqliteCreateSQL(self):
+ sql = SOKeyCol.sqliteCreateSQL(self)
+ other = findClass(self.foreignKey)
+ tName = other.sqlmeta.table
+ idName = other.sqlmeta.idName
+ if self.cascade is not None:
+ if self.cascade == 'null':
+ action = 'ON DELETE SET NULL'
+ elif self.cascade:
+ action = 'ON DELETE CASCADE'
+ else:
+ action = 'ON DELETE RESTRICT'
+ else:
+ action = ''
+ constraint = ('CONSTRAINT %(colName)s_exists '
+ #'FOREIGN KEY(%(colName)s) '
+ 'REFERENCES %(tName)s(%(idName)s) '
+ '%(action)s' %
+ {'tName': tName,
+ 'colName': self.dbName,
+ 'idName': idName,
+ 'action': action})
+ sql = ' '.join([sql, constraint])
+ return sql
+
def postgresCreateSQL(self):
sql = SOKeyCol.postgresCreateSQL(self)
return sql
Modified: home/phd/SQLObject/paramstyles/sqlobject/dbconnection.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/dbconnection.py 2006-04-06 14:51:16 UTC (rev 1684)
+++ home/phd/SQLObject/paramstyles/sqlobject/dbconnection.py 2006-04-06 14:52:32 UTC (rev 1685)
@@ -839,7 +839,8 @@
if not self._deletedCache.has_key(cls):
self._deletedCache[cls] = []
self._deletedCache[cls].append(inst.id)
- return self._dbConnection._SO_delete(inst)
+ meth = new.instancemethod(self._dbConnection._SO_delete.im_func, self, self.__class__)
+ return meth(inst)
def commit(self, close=False):
if self._obsolete:
Modified: home/phd/SQLObject/paramstyles/sqlobject/joins.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/joins.py 2006-04-06 14:51:16 UTC (rev 1684)
+++ home/phd/SQLObject/paramstyles/sqlobject/joins.py 2006-04-06 14:52:32 UTC (rev 1685)
@@ -154,7 +154,11 @@
class SOSQLMultipleJoin(SOMultipleJoin):
def performJoin(self, inst):
- results = self.otherClass.select(getattr(self.otherClass.q, self.soClass.sqlmeta.style.dbColumnToPythonAttr(self.joinColumn)) == inst.id)
+ if inst.sqlmeta._perConnection:
+ conn = inst._connection
+ else:
+ conn = None
+ results = self.otherClass.select(getattr(self.otherClass.q, self.soClass.sqlmeta.style.dbColumnToPythonAttr(self.joinColumn)) == inst.id, connection=conn)
if self.orderBy is NoDefault:
self.orderBy = self.otherClass.sqlmeta.defaultOrder
return results.orderBy(self.orderBy)
@@ -239,12 +243,17 @@
%(otherTable)s.%(otherID)s = %(interTable)s.%(otherCol)s and
%(interTable)s.%(joinCol)s = %(table)s.%(ID)s and
%(table)s.%(ID)s = %(idValue)s''' % options
+ if inst.sqlmeta._perConnection:
+ conn = inst._connection
+ else:
+ conn = None
results = self.otherClass.select(sqlbuilder.SQLConstant(clause),
clauseTables=(
options['table'],
options['otherTable'],
options['interTable'],
- )
+ ),
+ connection=conn
)
# TODO (michelts): apply orderBy on the selection
return results
Modified: home/phd/SQLObject/paramstyles/sqlobject/tests/test_transactions.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/tests/test_transactions.py 2006-04-06 14:51:16 UTC (rev 1684)
+++ home/phd/SQLObject/paramstyles/sqlobject/tests/test_transactions.py 2006-04-06 14:52:32 UTC (rev 1685)
@@ -51,3 +51,17 @@
assert bOut.name == 'robert'
finally:
TestSOTrans._connection.autoCommit = True
+
+def test_transaction_delete():
+ if not supports('transactions'):
+ return
+ setupClass(TestSOTrans)
+ trans = TestSOTrans._connection.transaction()
+ try:
+ TestSOTrans(name='bob')
+ bIn = TestSOTrans.byName('bob', connection=trans)
+ bIn.destroySelf()
+ bOut = TestSOTrans.select(TestSOTrans.q.name=='bob')
+ assert bOut.count() == 1
+ finally:
+ TestSOTrans._connection.autoCommit = True
|
|
From: SourceForge.net <no...@so...> - 2006-04-06 14:52:17
|
Patches item #1464379, was opened at 2006-04-04 21:30 Message generated for change (Comment added) made by phd You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1464379&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: Luke Opperman (luke_opperman) >Assigned to: Oleg Broytmann (phd) Summary: Alternate fix for Bug 1458595 (with test) Initial Comment: I independently encountered the problem with Transaction._SO_delete using a new connection. I believe I introduced this with the commit-sync stuff, the correct solution is to bind the dbConnection._SO_delete to the transaction instance as we do in Transaction.__getattr__ ---------------------------------------------------------------------- >Comment By: Oleg Broytmann (phd) Date: 2006-04-06 18:52 Message: Logged In: YES user_id=4799 Applied in the revision 1683 in the trunk, r1684 in the 0.7-branch. Thank you! ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1464379&group_id=74338 |
|
From: <sub...@co...> - 2006-04-06 14:51:28
|
Author: phd
Date: 2006-04-06 08:51:16 -0600 (Thu, 06 Apr 2006)
New Revision: 1684
Modified:
SQLObject/branches/0.7-bugfix/sqlobject/dbconnection.py
SQLObject/branches/0.7-bugfix/sqlobject/tests/test_transactions.py
Log:
Applied the patch N 1464379 for .destroySelf() inside a transaction.
Modified: SQLObject/branches/0.7-bugfix/sqlobject/dbconnection.py
===================================================================
--- SQLObject/branches/0.7-bugfix/sqlobject/dbconnection.py 2006-04-06 14:50:57 UTC (rev 1683)
+++ SQLObject/branches/0.7-bugfix/sqlobject/dbconnection.py 2006-04-06 14:51:16 UTC (rev 1684)
@@ -774,7 +774,8 @@
if not self._deletedCache.has_key(cls):
self._deletedCache[cls] = []
self._deletedCache[cls].append(inst.id)
- return self._dbConnection._SO_delete(inst)
+ meth = new.instancemethod(self._dbConnection._SO_delete.im_func, self, self.__class__)
+ return meth(inst)
def commit(self):
if self._obsolete:
Modified: SQLObject/branches/0.7-bugfix/sqlobject/tests/test_transactions.py
===================================================================
--- SQLObject/branches/0.7-bugfix/sqlobject/tests/test_transactions.py 2006-04-06 14:50:57 UTC (rev 1683)
+++ SQLObject/branches/0.7-bugfix/sqlobject/tests/test_transactions.py 2006-04-06 14:51:16 UTC (rev 1684)
@@ -51,3 +51,17 @@
assert bOut.name == 'robert'
finally:
TestSOTrans._connection.autoCommit = True
+
+def test_transaction_delete():
+ if not supports('transactions'):
+ return
+ setupClass(TestSOTrans)
+ trans = TestSOTrans._connection.transaction()
+ try:
+ TestSOTrans(name='bob')
+ bIn = TestSOTrans.byName('bob', connection=trans)
+ bIn.destroySelf()
+ bOut = TestSOTrans.select(TestSOTrans.q.name=='bob')
+ assert bOut.count() == 1
+ finally:
+ TestSOTrans._connection.autoCommit = True
|
|
From: <sub...@co...> - 2006-04-06 14:51:13
|
Author: phd
Date: 2006-04-06 08:50:57 -0600 (Thu, 06 Apr 2006)
New Revision: 1683
Modified:
SQLObject/trunk/sqlobject/dbconnection.py
SQLObject/trunk/sqlobject/tests/test_transactions.py
Log:
Applied the patch N 1464379 for .destroySelf() inside a transaction.
Modified: SQLObject/trunk/sqlobject/dbconnection.py
===================================================================
--- SQLObject/trunk/sqlobject/dbconnection.py 2006-04-05 14:32:39 UTC (rev 1682)
+++ SQLObject/trunk/sqlobject/dbconnection.py 2006-04-06 14:50:57 UTC (rev 1683)
@@ -826,7 +826,8 @@
if not self._deletedCache.has_key(cls):
self._deletedCache[cls] = []
self._deletedCache[cls].append(inst.id)
- return self._dbConnection._SO_delete(inst)
+ meth = new.instancemethod(self._dbConnection._SO_delete.im_func, self, self.__class__)
+ return meth(inst)
def commit(self, close=False):
if self._obsolete:
Modified: SQLObject/trunk/sqlobject/tests/test_transactions.py
===================================================================
--- SQLObject/trunk/sqlobject/tests/test_transactions.py 2006-04-05 14:32:39 UTC (rev 1682)
+++ SQLObject/trunk/sqlobject/tests/test_transactions.py 2006-04-06 14:50:57 UTC (rev 1683)
@@ -51,3 +51,17 @@
assert bOut.name == 'robert'
finally:
TestSOTrans._connection.autoCommit = True
+
+def test_transaction_delete():
+ if not supports('transactions'):
+ return
+ setupClass(TestSOTrans)
+ trans = TestSOTrans._connection.transaction()
+ try:
+ TestSOTrans(name='bob')
+ bIn = TestSOTrans.byName('bob', connection=trans)
+ bIn.destroySelf()
+ bOut = TestSOTrans.select(TestSOTrans.q.name=='bob')
+ assert bOut.count() == 1
+ finally:
+ TestSOTrans._connection.autoCommit = True
|
|
From: SourceForge.net <no...@so...> - 2006-04-06 14:41:33
|
Bugs item #1458595, was opened at 2006-03-26 05:52 Message generated for change (Comment added) made by phd You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1458595&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: SQLObject from repository >Status: Closed >Resolution: Fixed Priority: 5 Submitted By: Cody Pisto (cpisto) >Assigned to: Oleg Broytmann (phd) Summary: destroySelf in transaction causes lockup Initial Comment: Calling destroySelf() on an sqlobject acquired in the same explicit transaction (using conn.transaction()...) causes the entire python interpreter to lockup if the sqlobject schema in question has any SQLRelatedJoin's and the accompaying remove[JoinCol]() function is called in the transaction before destroySelf(). PDB stepping seems to be of no use, the interpreter locks up on line 306 of dbconnection.py "return cursor.execute(query)" The same sequence of calls works without problems outside a transaction. Version details: Python 2.4.2 PostgreSQL 8.1.2 (via psycopg2 2.0b8 or psycopg 1.1.21) SQLObject 0.8dev r1668 and r1615 ---------------------------------------------------------------------- >Comment By: Oleg Broytmann (phd) Date: 2006-04-06 18:41 Message: Logged In: YES user_id=4799 Fixed by the patch N 1464379. ---------------------------------------------------------------------- Comment By: Cody Pisto (cpisto) Date: 2006-03-27 01:32 Message: Logged In: YES user_id=118227 OK, found the problem. The _SO_delete method on the Transaction class had no way of specifying which connection to use for the query, thus a new one was being created. the attached patch fixes that. ---------------------------------------------------------------------- Comment By: Cody Pisto (cpisto) Date: 2006-03-27 01:14 Message: Logged In: YES user_id=118227 OK, after further investigation, It seems that for some reason a second database connection is being created during the lifetime of the transaction (by one of the SQLObjects instantiated inside doInTransaction), so a deadlock is occuring while this second connection waits for a commit on the first connection, I am still investating why this second connection is being created... ---------------------------------------------------------------------- Comment By: Cody Pisto (cpisto) Date: 2006-03-26 08:27 Message: Logged In: YES user_id=118227 The following link seems to reference the exact same problem, only on a slightly older version of sqlobject, and using mysql. http://www.mail-archive.com/sql...@li.../msg00226.html After contacting the poster, reverting to a much older version of sqlobject (r1547) seems to work around the issue ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1458595&group_id=74338 |
|
From: SourceForge.net <no...@so...> - 2006-04-06 14:39:47
|
Patches item #1458925, was opened at 2006-03-27 01:35 Message generated for change (Comment added) made by phd You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1458925&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: Invalid Priority: 5 Submitted By: Cody Pisto (cpisto) Assigned to: Oleg Broytmann (phd) Summary: Fix for bug 1458595 (destroySelf in Transaction = deadlock) Initial Comment: This patch fixes bug 1458595, in which actions that resulted in Transaction._SO_delete being called resulted in an additional database connection being opened, causing a deadlock while multiple connections await on eachothers commit. This patch is against svn trunk, r1668. (dbconnection.py) ---------------------------------------------------------------------- >Comment By: Oleg Broytmann (phd) Date: 2006-04-06 18:39 Message: Logged In: YES user_id=4799 Ok, I'll apply and test it... ---------------------------------------------------------------------- Comment By: Cody Pisto (cpisto) Date: 2006-04-05 22:41 Message: Logged In: YES user_id=118227 Luke's fix looks good, solves the problem my patch addresses, and resolves the duplication of code the patch incurred. ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-04-05 18:34 Message: Logged In: YES user_id=4799 Cody, any opinion on the alternate fix? ---------------------------------------------------------------------- Comment By: Luke Opperman (luke_opperman) Date: 2006-04-04 21:31 Message: Logged In: YES user_id=1393478 See patch #1464379 ---------------------------------------------------------------------- Comment By: Cody Pisto (cpisto) Date: 2006-03-28 18:32 Message: Logged In: YES user_id=118227 sorry, lost track of time, patch will follow today ;) ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-03-28 16:21 Message: Logged In: YES user_id=4799 Problems? :) ---------------------------------------------------------------------- Comment By: Cody Pisto (cpisto) Date: 2006-03-27 19:45 Message: Logged In: YES user_id=118227 Sure, ill refactor- Revised patch will follow this evening. ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-03-27 18:46 Message: Logged In: YES user_id=4799 Your patch duplicates the query from DBAPI._SO_delete() to Transaction._SO_delete(). Would you mind to refactor your patch - split DBAPI._SO_delete() into two methods - one to generate a query string, and another to execute the query; then use the first method to generate a query in the Transaction._SO_delete()? ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1458925&group_id=74338 |
|
From: SourceForge.net <no...@so...> - 2006-04-05 18:41:26
|
Patches item #1458925, was opened at 2006-03-26 14:35 Message generated for change (Comment added) made by cpisto You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1458925&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: Invalid Priority: 5 Submitted By: Cody Pisto (cpisto) Assigned to: Oleg Broytmann (phd) Summary: Fix for bug 1458595 (destroySelf in Transaction = deadlock) Initial Comment: This patch fixes bug 1458595, in which actions that resulted in Transaction._SO_delete being called resulted in an additional database connection being opened, causing a deadlock while multiple connections await on eachothers commit. This patch is against svn trunk, r1668. (dbconnection.py) ---------------------------------------------------------------------- >Comment By: Cody Pisto (cpisto) Date: 2006-04-05 12:41 Message: Logged In: YES user_id=118227 Luke's fix looks good, solves the problem my patch addresses, and resolves the duplication of code the patch incurred. ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-04-05 08:34 Message: Logged In: YES user_id=4799 Cody, any opinion on the alternate fix? ---------------------------------------------------------------------- Comment By: Luke Opperman (luke_opperman) Date: 2006-04-04 11:31 Message: Logged In: YES user_id=1393478 See patch #1464379 ---------------------------------------------------------------------- Comment By: Cody Pisto (cpisto) Date: 2006-03-28 07:32 Message: Logged In: YES user_id=118227 sorry, lost track of time, patch will follow today ;) ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-03-28 05:21 Message: Logged In: YES user_id=4799 Problems? :) ---------------------------------------------------------------------- Comment By: Cody Pisto (cpisto) Date: 2006-03-27 08:45 Message: Logged In: YES user_id=118227 Sure, ill refactor- Revised patch will follow this evening. ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-03-27 07:46 Message: Logged In: YES user_id=4799 Your patch duplicates the query from DBAPI._SO_delete() to Transaction._SO_delete(). Would you mind to refactor your patch - split DBAPI._SO_delete() into two methods - one to generate a query string, and another to execute the query; then use the first method to generate a query in the Transaction._SO_delete()? ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1458925&group_id=74338 |
|
From: SourceForge.net <no...@so...> - 2006-04-05 14:43:04
|
Bugs item #1461361, was opened at 2006-03-30 16:42 Message generated for change (Comment added) made by phd You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1461361&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: Deleted >Resolution: Duplicate Priority: 5 Submitted By: Nobody/Anonymous (nobody) Assigned to: Nobody/Anonymous (nobody) Summary: orderBy: datetime.datetime cannot be compared with None Initial Comment: When datetime.datetime is used for DateTimeCols: Using defaultOrder with a DateTimeCol fails when there is an empty DateTimeCol (None). This does not happen with the mx modules. "can't compare datetime.time to NoneType" ---------------------------------------------------------------------- >Comment By: Oleg Broytmann (phd) Date: 2006-04-05 18:42 Message: Logged In: YES user_id=4799 This is a dup fo bug 1460100. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1461361&group_id=74338 |
|
From: SourceForge.net <no...@so...> - 2006-04-05 14:41:53
|
Bugs item #1459482, was opened at 2006-03-27 21:51 Message generated for change (Comment added) made by phd You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1459482&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: Closed >Resolution: Wont Fix Priority: 5 Submitted By: Nobody/Anonymous (nobody) Assigned to: Nobody/Anonymous (nobody) Summary: Can't access column called 'class' in SQLObject Initial Comment: A syntax error is generated when a column named "class" is accessed using the SQLObject class interface in SQLObject 0.7. Example: The class AltJEDic contains a column named "CLASS" that should be mapped to the python object AltJEDic.class class AltJEDic(SQLObject): class sqlmeta: fromDatabase = True #idName = "sqlid" table = "ALTJEDIC0111" style = HinokiStyle() However, when I try to use AltJEDic.class in a function call, it fails with the following error: # python verify-wordnet.py File "verify-wordnet.py", line 190 if isSynonymRelGT(left_altjdic.class, right_altjdic.class): ^ SyntaxError: invalid syntax It seems that this is interfering with Python keywords. Do we need to add a restriction on column (or SQLObject class member names) or can this be worked around? ---------------------------------------------------------------------- >Comment By: Oleg Broytmann (phd) Date: 2006-04-05 18:41 Message: Logged In: YES user_id=4799 This a Python restriction but there is a simple workaround: gettatr(left_altjdic, "class") ---------------------------------------------------------------------- Comment By: Nobody/Anonymous (nobody) Date: 2006-03-27 21:57 Message: Logged In: NO I forgot to add some context. I get left_altjdic and right_altjdic by taking the first results from selectBy() queries. Ex: left_altjdics = AltJDic.selectBy(entry=left) left_altjdic = left_altjdics[0] try: right_altjdics = AltJDic.selectBy(entry=right) right_altjdic = right_altjdics[0] if isSynonymRelGT(left_altjdic.class, right_altjdic.class): ---------------------------------------------------------------------- Comment By: Nobody/Anonymous (nobody) Date: 2006-03-27 21:55 Message: Logged In: NO I forgot to add some context. I get left_altjdic and right_altjdic by taking the first items from the results of selectBy() queries as follows: left_altjdics = AltJDic.selectBy(entry=left) left_altjdic = left_altjdics[0] try: right_altjdics = AltJDic.selectBy(entry=right) right_altjdic = right_altjdics[0] if isSynonymRelGT(left_altjdic.class, right_altjdic.class): ---------------------------------------------------------------------- Comment By: Nobody/Anonymous (nobody) Date: 2006-03-27 21:54 Message: Logged In: NO I forgot to add some context. I get left_altjdic and right_altjdic by taking the first items from the results of selectBy() queries as follows: left_altjdics = AltJDic.selectBy(entry=left) left_altjdic = left_altjdics[0] try: right_altjdics = AltJDic.selectBy(entry=right) right_altjdic = right_altjdics[0] if isSynonymRelGT(left_altjdic.class, right_altjdic.class): ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1459482&group_id=74338 |
|
From: SourceForge.net <no...@so...> - 2006-04-05 14:34:38
|
Patches item #1458925, was opened at 2006-03-27 01:35 Message generated for change (Comment added) made by phd You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1458925&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: Invalid Priority: 5 Submitted By: Cody Pisto (cpisto) Assigned to: Oleg Broytmann (phd) Summary: Fix for bug 1458595 (destroySelf in Transaction = deadlock) Initial Comment: This patch fixes bug 1458595, in which actions that resulted in Transaction._SO_delete being called resulted in an additional database connection being opened, causing a deadlock while multiple connections await on eachothers commit. This patch is against svn trunk, r1668. (dbconnection.py) ---------------------------------------------------------------------- >Comment By: Oleg Broytmann (phd) Date: 2006-04-05 18:34 Message: Logged In: YES user_id=4799 Cody, any opinion on the alternate fix? ---------------------------------------------------------------------- Comment By: Luke Opperman (luke_opperman) Date: 2006-04-04 21:31 Message: Logged In: YES user_id=1393478 See patch #1464379 ---------------------------------------------------------------------- Comment By: Cody Pisto (cpisto) Date: 2006-03-28 18:32 Message: Logged In: YES user_id=118227 sorry, lost track of time, patch will follow today ;) ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-03-28 16:21 Message: Logged In: YES user_id=4799 Problems? :) ---------------------------------------------------------------------- Comment By: Cody Pisto (cpisto) Date: 2006-03-27 19:45 Message: Logged In: YES user_id=118227 Sure, ill refactor- Revised patch will follow this evening. ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-03-27 18:46 Message: Logged In: YES user_id=4799 Your patch duplicates the query from DBAPI._SO_delete() to Transaction._SO_delete(). Would you mind to refactor your patch - split DBAPI._SO_delete() into two methods - one to generate a query string, and another to execute the query; then use the first method to generate a query in the Transaction._SO_delete()? ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1458925&group_id=74338 |
|
From: <sub...@co...> - 2006-04-05 14:32:51
|
Author: phd
Date: 2006-04-05 08:32:39 -0600 (Wed, 05 Apr 2006)
New Revision: 1682
Modified:
SQLObject/branches/0.7-bugfix/sqlobject/joins.py
Log:
A patch by Luke Opperman: SQLJoins do not respect sqlmeta._perConnection.
Modified: SQLObject/branches/0.7-bugfix/sqlobject/joins.py
===================================================================
--- SQLObject/branches/0.7-bugfix/sqlobject/joins.py 2006-04-05 14:32:26 UTC (rev 1681)
+++ SQLObject/branches/0.7-bugfix/sqlobject/joins.py 2006-04-05 14:32:39 UTC (rev 1682)
@@ -152,7 +152,11 @@
class SOSQLMultipleJoin(SOMultipleJoin):
def performJoin(self, inst):
- results = self.otherClass.select(getattr(self.otherClass.q, self.soClass.sqlmeta.style.dbColumnToPythonAttr(self.joinColumn)) == inst.id)
+ if inst.sqlmeta._perConnection:
+ conn = inst._connection
+ else:
+ conn = None
+ results = self.otherClass.select(getattr(self.otherClass.q, self.soClass.sqlmeta.style.dbColumnToPythonAttr(self.joinColumn)) == inst.id, connection=conn)
if self.orderBy is NoDefault:
self.orderBy = self.otherClass.sqlmeta.defaultOrder
return results.orderBy(self.orderBy)
@@ -237,12 +241,17 @@
%(otherTable)s.%(otherID)s = %(interTable)s.%(otherCol)s and
%(interTable)s.%(joinCol)s = %(table)s.%(ID)s and
%(table)s.%(ID)s = %(idValue)s''' % options
+ if inst.sqlmeta._perConnection:
+ conn = inst._connection
+ else:
+ conn = None
results = self.otherClass.select(sqlbuilder.SQLConstant(clause),
clauseTables=(
options['table'],
options['otherTable'],
options['interTable'],
- )
+ ),
+ connection=conn
)
# TODO (michelts): apply orderBy on the selection
return results
|
|
From: <sub...@co...> - 2006-04-05 14:32:31
|
Author: phd
Date: 2006-04-05 08:32:26 -0600 (Wed, 05 Apr 2006)
New Revision: 1681
Modified:
SQLObject/trunk/sqlobject/joins.py
Log:
A patch by Luke Opperman: SQLJoins do not respect sqlmeta._perConnection.
Modified: SQLObject/trunk/sqlobject/joins.py
===================================================================
--- SQLObject/trunk/sqlobject/joins.py 2006-04-05 14:28:56 UTC (rev 1680)
+++ SQLObject/trunk/sqlobject/joins.py 2006-04-05 14:32:26 UTC (rev 1681)
@@ -154,7 +154,11 @@
class SOSQLMultipleJoin(SOMultipleJoin):
def performJoin(self, inst):
- results = self.otherClass.select(getattr(self.otherClass.q, self.soClass.sqlmeta.style.dbColumnToPythonAttr(self.joinColumn)) == inst.id)
+ if inst.sqlmeta._perConnection:
+ conn = inst._connection
+ else:
+ conn = None
+ results = self.otherClass.select(getattr(self.otherClass.q, self.soClass.sqlmeta.style.dbColumnToPythonAttr(self.joinColumn)) == inst.id, connection=conn)
if self.orderBy is NoDefault:
self.orderBy = self.otherClass.sqlmeta.defaultOrder
return results.orderBy(self.orderBy)
@@ -239,12 +243,17 @@
%(otherTable)s.%(otherID)s = %(interTable)s.%(otherCol)s and
%(interTable)s.%(joinCol)s = %(table)s.%(ID)s and
%(table)s.%(ID)s = %(idValue)s''' % options
+ if inst.sqlmeta._perConnection:
+ conn = inst._connection
+ else:
+ conn = None
results = self.otherClass.select(sqlbuilder.SQLConstant(clause),
clauseTables=(
options['table'],
options['otherTable'],
options['interTable'],
- )
+ ),
+ connection=conn
)
# TODO (michelts): apply orderBy on the selection
return results
|
|
From: <sub...@co...> - 2006-04-05 14:29:03
|
Author: phd
Date: 2006-04-05 08:28:56 -0600 (Wed, 05 Apr 2006)
New Revision: 1680
Modified:
SQLObject/branches/0.7-bugfix/sqlobject/col.py
Log:
A patch by jt...@ud...: sqlite foreign key.
Modified: SQLObject/branches/0.7-bugfix/sqlobject/col.py
===================================================================
--- SQLObject/branches/0.7-bugfix/sqlobject/col.py 2006-04-05 14:28:37 UTC (rev 1679)
+++ SQLObject/branches/0.7-bugfix/sqlobject/col.py 2006-04-05 14:28:56 UTC (rev 1680)
@@ -734,6 +734,31 @@
kw['name'] = style.instanceAttrToIDAttr(kw['name'])
super(SOForeignKey, self).__init__(**kw)
+ def sqliteCreateSQL(self):
+ sql = SOKeyCol.sqliteCreateSQL(self)
+ other = findClass(self.foreignKey)
+ tName = other.sqlmeta.table
+ idName = other.sqlmeta.idName
+ if self.cascade is not None:
+ if self.cascade == 'null':
+ action = 'ON DELETE SET NULL'
+ elif self.cascade:
+ action = 'ON DELETE CASCADE'
+ else:
+ action = 'ON DELETE RESTRICT'
+ else:
+ action = ''
+ constraint = ('CONSTRAINT %(colName)s_exists '
+ #'FOREIGN KEY(%(colName)s) '
+ 'REFERENCES %(tName)s(%(idName)s) '
+ '%(action)s' %
+ {'tName': tName,
+ 'colName': self.dbName,
+ 'idName': idName,
+ 'action': action})
+ sql = ' '.join([sql, constraint])
+ return sql
+
def postgresCreateSQL(self):
sql = SOKeyCol.postgresCreateSQL(self)
other = findClass(self.foreignKey, self.soClass.sqlmeta.registry)
|
|
From: <sub...@co...> - 2006-04-05 14:28:48
|
Author: phd
Date: 2006-04-05 08:28:37 -0600 (Wed, 05 Apr 2006)
New Revision: 1679
Modified:
SQLObject/trunk/sqlobject/col.py
Log:
A patch by jt...@ud...: sqlite foreign key.
Modified: SQLObject/trunk/sqlobject/col.py
===================================================================
--- SQLObject/trunk/sqlobject/col.py 2006-04-05 04:08:03 UTC (rev 1678)
+++ SQLObject/trunk/sqlobject/col.py 2006-04-05 14:28:37 UTC (rev 1679)
@@ -727,6 +727,31 @@
kw['name'] = style.instanceAttrToIDAttr(kw['name'])
super(SOForeignKey, self).__init__(**kw)
+ def sqliteCreateSQL(self):
+ sql = SOKeyCol.sqliteCreateSQL(self)
+ other = findClass(self.foreignKey)
+ tName = other.sqlmeta.table
+ idName = other.sqlmeta.idName
+ if self.cascade is not None:
+ if self.cascade == 'null':
+ action = 'ON DELETE SET NULL'
+ elif self.cascade:
+ action = 'ON DELETE CASCADE'
+ else:
+ action = 'ON DELETE RESTRICT'
+ else:
+ action = ''
+ constraint = ('CONSTRAINT %(colName)s_exists '
+ #'FOREIGN KEY(%(colName)s) '
+ 'REFERENCES %(tName)s(%(idName)s) '
+ '%(action)s' %
+ {'tName': tName,
+ 'colName': self.dbName,
+ 'idName': idName,
+ 'action': action})
+ sql = ' '.join([sql, constraint])
+ return sql
+
def postgresCreateSQL(self):
sql = SOKeyCol.postgresCreateSQL(self)
return sql
|
|
From: SourceForge.net <no...@so...> - 2006-04-04 17:31:07
|
Patches item #1458925, was opened at 2006-03-26 15:35 Message generated for change (Comment added) made by luke_opperman You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1458925&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: Invalid Priority: 5 Submitted By: Cody Pisto (cpisto) Assigned to: Oleg Broytmann (phd) Summary: Fix for bug 1458595 (destroySelf in Transaction = deadlock) Initial Comment: This patch fixes bug 1458595, in which actions that resulted in Transaction._SO_delete being called resulted in an additional database connection being opened, causing a deadlock while multiple connections await on eachothers commit. This patch is against svn trunk, r1668. (dbconnection.py) ---------------------------------------------------------------------- Comment By: Luke Opperman (luke_opperman) Date: 2006-04-04 12:31 Message: Logged In: YES user_id=1393478 See patch #1464379 ---------------------------------------------------------------------- Comment By: Cody Pisto (cpisto) Date: 2006-03-28 08:32 Message: Logged In: YES user_id=118227 sorry, lost track of time, patch will follow today ;) ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-03-28 06:21 Message: Logged In: YES user_id=4799 Problems? :) ---------------------------------------------------------------------- Comment By: Cody Pisto (cpisto) Date: 2006-03-27 09:45 Message: Logged In: YES user_id=118227 Sure, ill refactor- Revised patch will follow this evening. ---------------------------------------------------------------------- Comment By: Oleg Broytmann (phd) Date: 2006-03-27 08:46 Message: Logged In: YES user_id=4799 Your patch duplicates the query from DBAPI._SO_delete() to Transaction._SO_delete(). Would you mind to refactor your patch - split DBAPI._SO_delete() into two methods - one to generate a query string, and another to execute the query; then use the first method to generate a query in the Transaction._SO_delete()? ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1458925&group_id=74338 |
|
From: SourceForge.net <no...@so...> - 2006-04-04 17:30:43
|
Patches item #1464379, was opened at 2006-04-04 12:30 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=1464379&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: Luke Opperman (luke_opperman) Assigned to: Nobody/Anonymous (nobody) Summary: Alternate fix for Bug 1458595 (with test) Initial Comment: I independently encountered the problem with Transaction._SO_delete using a new connection. I believe I introduced this with the commit-sync stuff, the correct solution is to bind the dbConnection._SO_delete to the transaction instance as we do in Transaction.__getattr__ ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540674&aid=1464379&group_id=74338 |