Author: phd
Date: 2006-02-16 09:50:16 -0700 (Thu, 16 Feb 2006)
New Revision: 1601
Modified:
SQLObject/trunk/sqlobject/__init__.py
SQLObject/trunk/sqlobject/sqlbuilder.py
SQLObject/trunk/sqlobject/tests/test_select.py
Log:
Applied the patch 1410834: add RLIKE operator; added tests for LIKE and RLIKE.
Modified: SQLObject/trunk/sqlobject/__init__.py
===================================================================
--- SQLObject/trunk/sqlobject/__init__.py 2006-02-15 18:58:39 UTC (rev 1600)
+++ SQLObject/trunk/sqlobject/__init__.py 2006-02-16 16:50:16 UTC (rev 1601)
@@ -1,6 +1,6 @@
from main import *
from col import *
-from sqlbuilder import AND, OR, NOT, IN, LIKE, DESC, CONTAINSSTRING, const, func
+from sqlbuilder import AND, OR, NOT, IN, LIKE, RLIKE, DESC, CONTAINSSTRING, const, func
from styles import *
from joins import *
from index import *
Modified: SQLObject/trunk/sqlobject/sqlbuilder.py
===================================================================
--- SQLObject/trunk/sqlobject/sqlbuilder.py 2006-02-15 18:58:39 UTC (rev 1600)
+++ SQLObject/trunk/sqlobject/sqlbuilder.py 2006-02-16 16:50:16 UTC (rev 1601)
@@ -240,17 +240,6 @@
elif self.op == "OR":
return execute(self.expr1, executor) \
or execute(self.expr2, executor)
- elif self.op == "LIKE":
- if not hasattr(self, '_regex'):
- # @@: Crude, not entirely accurate
- dest = self.expr2
- dest = dest.replace("%%", "\001")
- dest = dest.replace("*", "\002")
- dest = dest.replace("%", "*")
- dest = dest.replace("\001", "%")
- dest = dest.replace("\002", "[*]")
- self._regex = re.compile(fnmatch.translate(dest), re.I)
- return self._regex.search(execute(self.expr1, executor))
else:
return operatorMap[self.op.upper()](execute(self.expr1, executor),
execute(self.expr2, executor))
@@ -625,9 +614,6 @@
else:
return NOT(_IN(item, list))
-def LIKE(expr, string):
- return SQLOp("LIKE", expr, string)
-
def STARTSWITH(expr, string):
return SQLOp("LIKE", expr, _LikeQuoted(string) + '%')
@@ -893,6 +879,49 @@
self.q = OuterTable(table)
+class LIKE(SQLExpression):
+ op = "LIKE"
+
+ def __init__(self, expr, string):
+ self.expr = expr
+ self.string = string
+ def __sqlrepr__(self, 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):
+ if not hasattr(self, '_regex'):
+ # @@: Crude, not entirely accurate
+ dest = self.string
+ dest = dest.replace("%%", "\001")
+ dest = dest.replace("*", "\002")
+ dest = dest.replace("%", "*")
+ dest = dest.replace("\001", "%")
+ dest = dest.replace("\002", "[*]")
+ self._regex = re.compile(fnmatch.translate(dest), re.I)
+ return self._regex.search(execute(self.expr, executor))
+
+class RLIKE(LIKE):
+ op = "RLIKE"
+
+ def _get_op(self, db):
+ if db in ('mysql', 'maxdb', 'firebird'):
+ return "RLIKE"
+ elif db == 'sqlite':
+ return "REGEXP"
+ elif db == 'postgres':
+ return "~"
+ else:
+ return "LIKE"
+ def __sqlrepr__(self, db):
+ 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)
+
+
class INSubquery(SQLExpression):
op = "IN"
Modified: SQLObject/trunk/sqlobject/tests/test_select.py
===================================================================
--- SQLObject/trunk/sqlobject/tests/test_select.py 2006-02-15 18:58:39 UTC (rev 1600)
+++ SQLObject/trunk/sqlobject/tests/test_select.py 2006-02-16 16:50:16 UTC (rev 1601)
@@ -132,3 +132,39 @@
def test_2(self):
self.accumulateEqual(len,Counter2.select('all'), 100)
+
+def test_sqlbuilder_LIKE():
+ setupClass(IterTest)
+ IterTest(name='sqlobject')
+ IterTest(name='sqlbuilder')
+ assert IterTest.select(LIKE(IterTest.q.name, "sql%")).count() == 2
+ assert IterTest.select(LIKE(IterTest.q.name, "sqlb%")).count() == 1
+ assert IterTest.select(LIKE(IterTest.q.name, "sqlb%")).count() == 1
+ assert IterTest.select(LIKE(IterTest.q.name, "sqlx%")).count() == 0
+
+def test_sqlbuilder_RLIKE():
+ setupClass(IterTest)
+
+ if IterTest._connection.dbName == "sqlite":
+ from sqlobject.sqlite.sqliteconnection import using_sqlite2
+ if not using_sqlite2:
+ return
+
+ # Implement regexp() function for SQLite; only works with PySQLite2
+ import re
+ def regexp(regexp, test):
+ return bool(re.search(regexp, test))
+
+ _get_connection = IterTest._connection.getConnection
+ def new_get_connection(*args, **kw):
+ _connection = _get_connection(*args, **kw)
+ _connection.create_function("regexp", 2, regexp)
+ return _connection
+ IterTest._connection.getConnection = new_get_connection
+
+ IterTest(name='sqlobject')
+ IterTest(name='sqlbuilder')
+ assert IterTest.select(RLIKE(IterTest.q.name, "^sql.*$")).count() == 2
+ assert IterTest.select(RLIKE(IterTest.q.name, "^sqlb.*$")).count() == 1
+ assert IterTest.select(RLIKE(IterTest.q.name, "^sqlb.*$")).count() == 1
+ assert IterTest.select(RLIKE(IterTest.q.name, "^sqlx.*$")).count() == 0
|