[tryton-debian-vcs] python-sql branch debian updated. debian/0.3-1-4-ge080757
Mathias Behrle
tryton-debian-vcs at alioth.debian.org
Tue Aug 26 16:41:08 UTC 2014
The following commit has been merged in the debian branch:
https://alioth.debian.org/plugins/scmgit/cgi-bin/gitweb.cgi/?p=tryton/python-sql.git;a=commitdiff;h=debian/0.3-1-4-ge080757
commit e0807572c86030efe724bcb259fbfc1ca51531d8
Author: Mathias Behrle <mathiasb at m9s.biz>
Date: Tue Aug 26 15:56:56 2014 +0200
Releasing debian version 0.4-1.
diff --git a/debian/changelog b/debian/changelog
index c0ee9e4..1f24376 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,12 @@
+python-sql (0.4-1) unstable; urgency=medium
+
+ * Updating signing key while using now plain .asc files instead of .pgp
+ binaries.
+ * Updating gbp.conf for the usage of the tarball compression.
+ * Merging upstream version 0.4.
+
+ -- Mathias Behrle <mathiasb at m9s.biz> Tue, 26 Aug 2014 15:56:06 +0200
+
python-sql (0.3-1) unstable; urgency=medium
* Updating year in debian copyright.
commit edc45d0b744f8ea445b3deaaaa9e2c8818928bfa
Author: Mathias Behrle <mathiasb at m9s.biz>
Date: Tue Aug 26 14:57:42 2014 +0200
Merging upstream version 0.4.
diff --git a/CHANGELOG b/CHANGELOG
index 06d65f3..b3144e4 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,12 @@
+Version 0.4 - 2014-08-03
+* Fix Mapping in Trim function
+* Add __truediv__ alias of __div__ for Python3
+* Fix For tables setter when tables is not a list
+* Allow to add Table to existing From list
+* Fix Select with for_ clause
+* Add Null alias for None
+* Add missing format of operand in Unary operator
+
Version 0.3 - 2014-01-31
* Add returning to Update
* Add missing params for returning
diff --git a/PKG-INFO b/PKG-INFO
index 1dd3522..85cba71 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: python-sql
-Version: 0.3
+Version: 0.4
Summary: Library to write SQL queries
Home-page: http://code.google.com/p/python-sql/
Author: B2CK
diff --git a/python_sql.egg-info/PKG-INFO b/python_sql.egg-info/PKG-INFO
index 1dd3522..85cba71 100644
--- a/python_sql.egg-info/PKG-INFO
+++ b/python_sql.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: python-sql
-Version: 0.3
+Version: 0.4
Summary: Library to write SQL queries
Home-page: http://code.google.com/p/python-sql/
Author: B2CK
diff --git a/sql/__init__.py b/sql/__init__.py
index 1238546..fb09560 100644
--- a/sql/__init__.py
+++ b/sql/__init__.py
@@ -29,7 +29,7 @@
from __future__ import division
-__version__ = '0.3'
+__version__ = '0.4'
__all__ = ['Flavor', 'Table', 'Literal', 'Column', 'Join', 'Asc', 'Desc']
import string
@@ -321,7 +321,7 @@ class Select(Query, FromItem, _SelectQueryMixin):
if value is not None:
if isinstance(value, For):
value = [value]
- assert isinstance(all(isinstance(f, For) for f in value))
+ assert all(isinstance(f, For) for f in value)
self.__for_ = value
@staticmethod
@@ -349,7 +349,7 @@ class Select(Query, FromItem, _SelectQueryMixin):
having = ' HAVING ' + str(self.having)
for_ = ''
if self.for_ is not None:
- for_ = ' '.join(self.for_)
+ for_ = ' ' + ' '.join(map(str, self.for_))
return ('SELECT %s FROM %s' % (columns, from_) + where + group_by
+ having + self._order_by_str + self._limit_str +
self._offset_str + for_)
@@ -811,7 +811,8 @@ class From(list):
return tuple(p)
def __add__(self, other):
- assert isinstance(other, (Join, Select))
+ assert isinstance(other, FromItem)
+ assert not isinstance(other, CombiningQuery)
return From(super(From, self).__add__([other]))
@@ -853,6 +854,8 @@ class Expression(object):
from sql.operators import Div
return Div(self, other)
+ __truediv__ = __div__
+
def __floordiv__(self, other):
from sql.functions import Div
return Div(self, other)
@@ -957,6 +960,8 @@ class Literal(Expression):
def params(self):
return (self.__value,)
+Null = None
+
class Column(Expression):
__slots__ = ('__from', '__name')
@@ -1074,7 +1079,7 @@ class For(object):
@tables.setter
def tables(self, value):
if not isinstance(value, list):
- value = list(value)
+ value = [value]
all(isinstance(table, Table) for table in value)
self.__tables = value
diff --git a/sql/functions.py b/sql/functions.py
index 6e86138..c987df2 100644
--- a/sql/functions.py
+++ b/sql/functions.py
@@ -332,7 +332,7 @@ class Trim(Function):
def params(self):
Mapping = Flavor.get().function_mapping.get(self.__class__)
if Mapping:
- return Mapping(*self.args).params
+ return Mapping(self.string, self.position, self.characters).params
p = []
for arg in (self.characters, self.string):
if isinstance(arg, basestring):
diff --git a/sql/operators.py b/sql/operators.py
index 87587b3..25d9157 100644
--- a/sql/operators.py
+++ b/sql/operators.py
@@ -28,7 +28,7 @@
import warnings
from array import array
-from sql import Expression, Select, CombiningQuery, Flavor
+from sql import Expression, Select, CombiningQuery, Flavor, Null
__all__ = ['And', 'Or', 'Not', 'Less', 'Greater', 'LessEqual', 'GreaterEqual',
'Equal', 'NotEqual', 'Add', 'Sub', 'Mul', 'Div', 'FloorDiv', 'Mod', 'Pow',
@@ -112,7 +112,7 @@ class UnaryOperator(Operator):
return (self.operand,)
def __str__(self):
- return '(%s %s)' % (self._operator, self.operand)
+ return '(%s %s)' % (self._operator, self._format(self.operand))
class BinaryOperator(Operator):
@@ -198,16 +198,16 @@ class Equal(BinaryOperator):
@property
def _operands(self):
- if self.left is None:
+ if self.left is Null:
return (self.right,)
- elif self.right is None:
+ elif self.right is Null:
return (self.left,)
return super(Equal, self)._operands
def __str__(self):
- if self.left is None:
+ if self.left is Null:
return '(%s IS NULL)' % self.right
- elif self.right is None:
+ elif self.right is Null:
return '(%s IS NULL)' % self.left
return super(Equal, self).__str__()
@@ -217,9 +217,9 @@ class NotEqual(Equal):
_operator = '!='
def __str__(self):
- if self.left is None:
+ if self.left is Null:
return '(%s IS NOT NULL)' % self.right
- elif self.right is None:
+ elif self.right is Null:
return '(%s IS NOT NULL)' % self.left
return super(Equal, self).__str__()
diff --git a/sql/tests/test_cast.py b/sql/tests/test_cast.py
index a76b648..ee7bf3f 100644
--- a/sql/tests/test_cast.py
+++ b/sql/tests/test_cast.py
@@ -35,8 +35,9 @@ class TestCast(unittest.TestCase):
column = Column(Table('t'), 'c')
def test_cast(self):
- self.assertEqual(str(Cast(self.column, 'int')),
- 'CAST("c" AS int)')
+ for cast in [Cast(self.column, 'int'), self.column.cast('int')]:
+ self.assertEqual(str(cast), 'CAST("c" AS int)')
+ self.assertEqual(cast.params, ())
def test_cast_no_expression(self):
cast = Cast(1.1, 'int')
diff --git a/sql/tests/test_column.py b/sql/tests/test_column.py
index 6be3168..080b59d 100644
--- a/sql/tests/test_column.py
+++ b/sql/tests/test_column.py
@@ -35,6 +35,7 @@ class TestColumn(unittest.TestCase):
def test_column(self):
column = Column(Table('t'), 'c')
self.assertEqual(str(column), '"c"')
+ self.assertEqual(column.name, 'c')
with AliasManager():
self.assertEqual(str(column), '"a"."c"')
diff --git a/sql/tests/test_for.py b/sql/tests/test_for.py
index cf0b940..764baaf 100644
--- a/sql/tests/test_for.py
+++ b/sql/tests/test_for.py
@@ -35,3 +35,8 @@ class TestFor(unittest.TestCase):
def test_for(self):
for_ = For('UPDATE', Table('t1'), Table('t2'), nowait=True)
self.assertEqual(str(for_), 'FOR UPDATE OF "t1", "t2" NOWAIT')
+
+ def test_for_single_table(self):
+ for_ = For('UPDATE')
+ for_.tables = Table('t1')
+ self.assertEqual(str(for_), 'FOR UPDATE OF "t1"')
diff --git a/sql/tests/test_functions.py b/sql/tests/test_functions.py
index 091e9b6..248142b 100644
--- a/sql/tests/test_functions.py
+++ b/sql/tests/test_functions.py
@@ -29,7 +29,8 @@
import unittest
from sql import Table, Flavor
-from sql.functions import Function, Abs, Overlay, Trim, AtTimeZone
+from sql.functions import (Function, FunctionKeyword, FunctionNotCallable, Abs,
+ Overlay, Trim, AtTimeZone, Div, CurrentTime)
class TestFunctions(unittest.TestCase):
@@ -49,14 +50,40 @@ class TestFunctions(unittest.TestCase):
_function = 'MY_ABS'
params = ('test',)
+ class MyOverlay(FunctionKeyword):
+ _function = 'MY_OVERLAY'
+ _keywords = ('', 'PLACING', 'FROM', 'FOR')
+
+ class MyCurrentTime(FunctionNotCallable):
+ _function = 'MY_CURRENT_TIME'
+
+ class MyTrim(Trim):
+ _function = 'MY_TRIM'
+
abs_ = Abs(self.table.c1)
+ overlay = Overlay(self.table.c1, 'test', 2)
+ current_time = CurrentTime()
+ trim = Trim(' test ')
flavor = Flavor(function_mapping={
Abs: MyAbs,
+ Overlay: MyOverlay,
+ CurrentTime: MyCurrentTime,
+ Trim: MyTrim,
})
Flavor.set(flavor)
try:
self.assertEqual(str(abs_), 'MY_ABS("c1")')
self.assertEqual(abs_.params, ('test',))
+
+ self.assertEqual(str(overlay),
+ 'MY_OVERLAY("c1" PLACING %s FROM %s)')
+ self.assertEqual(overlay.params, ('test', 2))
+
+ self.assertEqual(str(current_time), 'MY_CURRENT_TIME')
+ self.assertEqual(current_time.params, ())
+
+ self.assertEqual(str(trim), 'MY_TRIM(BOTH %s FROM %s)')
+ self.assertEqual(trim.params, (' ', ' test ',))
finally:
Flavor.set(Flavor())
@@ -74,6 +101,10 @@ class TestFunctions(unittest.TestCase):
self.assertEqual(str(trim), 'TRIM(BOTH %s FROM %s)')
self.assertEqual(trim.params, (' ', ' test ',))
+ trim = Trim(self.table.c1)
+ self.assertEqual(str(trim), 'TRIM(BOTH %s FROM "c1")')
+ self.assertEqual(trim.params, (' ',))
+
def test_at_time_zone(self):
time_zone = AtTimeZone(self.table.c1, 'UTC')
self.assertEqual(str(time_zone), '"c1" AT TIME ZONE %s')
@@ -93,3 +124,14 @@ class TestFunctions(unittest.TestCase):
self.assertEqual(time_zone.params, ('UTC',))
finally:
Flavor.set(Flavor())
+
+ def test_div(self):
+ for div in [Div(self.table.c1, self.table.c2),
+ self.table.c1 // self.table.c2]:
+ self.assertEqual(str(div), 'DIV("c1", "c2")')
+ self.assertEqual(div.params, ())
+
+ def test_current_time(self):
+ current_time = CurrentTime()
+ self.assertEqual(str(current_time), 'CURRENT_TIME')
+ self.assertEqual(current_time.params, ())
diff --git a/sql/tests/test_literal.py b/sql/tests/test_literal.py
index 7c8f3b4..c8dd5bf 100644
--- a/sql/tests/test_literal.py
+++ b/sql/tests/test_literal.py
@@ -36,3 +36,4 @@ class TestLiteral(unittest.TestCase):
literal = Literal(1)
self.assertEqual(str(literal), '%s')
self.assertEqual(literal.params, (1,))
+ self.assertEqual(literal.value, 1)
diff --git a/sql/tests/test_operators.py b/sql/tests/test_operators.py
index d726655..23619e3 100644
--- a/sql/tests/test_operators.py
+++ b/sql/tests/test_operators.py
@@ -30,82 +30,250 @@ import unittest
import warnings
from array import array
-from sql import Table, Literal
-from sql.operators import And, Not, Less, Equal, NotEqual, In, FloorDiv
+from sql import Table, Literal, Null, Flavor
+from sql.operators import (And, Or, Not, Neg, Pos, Less, Greater, LessEqual,
+ GreaterEqual, Equal, NotEqual, Sub, Mul, Div, Mod, Pow, Abs, LShift,
+ RShift, Like, NotLike, ILike, NotILike, In, NotIn, FloorDiv, Exists)
class TestOperators(unittest.TestCase):
table = Table('t')
def test_and(self):
- and_ = And((self.table.c1, self.table.c2))
- self.assertEqual(str(and_), '("c1" AND "c2")')
- self.assertEqual(and_.params, ())
+ for and_ in [And((self.table.c1, self.table.c2)),
+ self.table.c1 & self.table.c2]:
+ self.assertEqual(str(and_), '("c1" AND "c2")')
+ self.assertEqual(and_.params, ())
and_ = And((Literal(True), self.table.c2))
self.assertEqual(str(and_), '(%s AND "c2")')
self.assertEqual(and_.params, (True,))
+ def test_operator_operators(self):
+ and_ = And((Literal(True), self.table.c1))
+ and2 = and_ & And((Literal(True), self.table.c2))
+ self.assertEqual(str(and2), '((%s AND "c1") AND %s AND "c2")')
+ self.assertEqual(and2.params, (True, True))
+
+ and3 = and_ & Literal(True)
+ self.assertEqual(str(and3), '((%s AND "c1") AND %s)')
+ self.assertEqual(and3.params, (True, True))
+
+ or_ = Or((Literal(True), self.table.c1))
+ or2 = or_ | Or((Literal(True), self.table.c2))
+ self.assertEqual(str(or2), '((%s OR "c1") OR %s OR "c2")')
+ self.assertEqual(or2.params, (True, True))
+
+ or3 = or_ | Literal(True)
+ self.assertEqual(str(or3), '((%s OR "c1") OR %s)')
+ self.assertEqual(or3.params, (True, True))
+
+ def test_operator_compat_column(self):
+ and_ = And((self.table.c1, self.table.c2))
+ self.assertEqual(and_.table, '')
+ self.assertEqual(and_.name, '')
+
+ def test_or(self):
+ for or_ in [Or((self.table.c1, self.table.c2)),
+ self.table.c1 | self.table.c2]:
+ self.assertEqual(str(or_), '("c1" OR "c2")')
+ self.assertEqual(or_.params, ())
+
def test_not(self):
- not_ = Not(self.table.c)
- self.assertEqual(str(not_), '(NOT "c")')
- self.assertEqual(not_.params, ())
+ for not_ in [Not(self.table.c), ~self.table.c]:
+ self.assertEqual(str(not_), '(NOT "c")')
+ self.assertEqual(not_.params, ())
not_ = Not(Literal(False))
self.assertEqual(str(not_), '(NOT %s)')
self.assertEqual(not_.params, (False,))
+ def test_neg(self):
+ for neg in [Neg(self.table.c1), -self.table.c1]:
+ self.assertEqual(str(neg), '(- "c1")')
+ self.assertEqual(neg.params, ())
+
+ def test_pos(self):
+ for pos in [Pos(self.table.c1), +self.table.c1]:
+ self.assertEqual(str(pos), '(+ "c1")')
+ self.assertEqual(pos.params, ())
+
def test_less(self):
- less = Less(self.table.c1, self.table.c2)
- self.assertEqual(str(less), '("c1" < "c2")')
- self.assertEqual(less.params, ())
+ for less in [Less(self.table.c1, self.table.c2),
+ self.table.c1 < self.table.c2,
+ ~GreaterEqual(self.table.c1, self.table.c2)]:
+ self.assertEqual(str(less), '("c1" < "c2")')
+ self.assertEqual(less.params, ())
less = Less(Literal(0), self.table.c2)
self.assertEqual(str(less), '(%s < "c2")')
self.assertEqual(less.params, (0,))
+ def test_greater(self):
+ for greater in [Greater(self.table.c1, self.table.c2),
+ self.table.c1 > self.table.c2,
+ ~LessEqual(self.table.c1, self.table.c2)]:
+ self.assertEqual(str(greater), '("c1" > "c2")')
+ self.assertEqual(greater.params, ())
+
+ def test_less_equal(self):
+ for less in [LessEqual(self.table.c1, self.table.c2),
+ self.table.c1 <= self.table.c2,
+ ~Greater(self.table.c1, self.table.c2)]:
+ self.assertEqual(str(less), '("c1" <= "c2")')
+ self.assertEqual(less.params, ())
+
+ def test_greater_equal(self):
+ for greater in [GreaterEqual(self.table.c1, self.table.c2),
+ self.table.c1 >= self.table.c2,
+ ~Less(self.table.c1, self.table.c2)]:
+ self.assertEqual(str(greater), '("c1" >= "c2")')
+ self.assertEqual(greater.params, ())
+
def test_equal(self):
- equal = Equal(self.table.c1, self.table.c2)
- self.assertEqual(str(equal), '("c1" = "c2")')
- self.assertEqual(equal.params, ())
+ for equal in [Equal(self.table.c1, self.table.c2),
+ self.table.c1 == self.table.c2,
+ ~NotEqual(self.table.c1, self.table.c2)]:
+ self.assertEqual(str(equal), '("c1" = "c2")')
+ self.assertEqual(equal.params, ())
equal = Equal(Literal('foo'), Literal('bar'))
self.assertEqual(str(equal), '(%s = %s)')
self.assertEqual(equal.params, ('foo', 'bar'))
- equal = Equal(self.table.c1, None)
+ equal = Equal(self.table.c1, Null)
self.assertEqual(str(equal), '("c1" IS NULL)')
self.assertEqual(equal.params, ())
- equal = Equal(Literal('test'), None)
+ equal = Equal(Literal('test'), Null)
self.assertEqual(str(equal), '(%s IS NULL)')
self.assertEqual(equal.params, ('test',))
- equal = Equal(None, self.table.c1)
+ equal = Equal(Null, self.table.c1)
self.assertEqual(str(equal), '("c1" IS NULL)')
self.assertEqual(equal.params, ())
- equal = Equal(None, Literal('test'))
+ equal = Equal(Null, Literal('test'))
self.assertEqual(str(equal), '(%s IS NULL)')
self.assertEqual(equal.params, ('test',))
def test_not_equal(self):
- equal = NotEqual(self.table.c1, self.table.c2)
- self.assertEqual(str(equal), '("c1" != "c2")')
- self.assertEqual(equal.params, ())
+ for equal in [NotEqual(self.table.c1, self.table.c2),
+ self.table.c1 != self.table.c2,
+ ~Equal(self.table.c1, self.table.c2)]:
+ self.assertEqual(str(equal), '("c1" != "c2")')
+ self.assertEqual(equal.params, ())
- equal = NotEqual(self.table.c1, None)
+ equal = NotEqual(self.table.c1, Null)
self.assertEqual(str(equal), '("c1" IS NOT NULL)')
self.assertEqual(equal.params, ())
- equal = NotEqual(None, self.table.c1)
+ equal = NotEqual(Null, self.table.c1)
self.assertEqual(str(equal), '("c1" IS NOT NULL)')
self.assertEqual(equal.params, ())
+ def test_sub(self):
+ for sub in [Sub(self.table.c1, self.table.c2),
+ self.table.c1 - self.table.c2]:
+ self.assertEqual(str(sub), '("c1" - "c2")')
+ self.assertEqual(sub.params, ())
+
+ def test_mul(self):
+ for mul in [Mul(self.table.c1, self.table.c2),
+ self.table.c1 * self.table.c2]:
+ self.assertEqual(str(mul), '("c1" * "c2")')
+ self.assertEqual(mul.params, ())
+
+ def test_div(self):
+ for div in [Div(self.table.c1, self.table.c2),
+ self.table.c1 / self.table.c2]:
+ self.assertEqual(str(div), '("c1" / "c2")')
+ self.assertEqual(div.params, ())
+
+ def test_mod(self):
+ for mod in [Mod(self.table.c1, self.table.c2),
+ self.table.c1 % self.table.c2]:
+ self.assertEqual(str(mod), '("c1" % "c2")')
+ self.assertEqual(mod.params, ())
+
+ def test_pow(self):
+ for pow_ in [Pow(self.table.c1, self.table.c2),
+ self.table.c1 ** self.table.c2]:
+ self.assertEqual(str(pow_), '("c1" ^ "c2")')
+ self.assertEqual(pow_.params, ())
+
+ def test_abs(self):
+ for abs_ in [Abs(self.table.c1), abs(self.table.c1)]:
+ self.assertEqual(str(abs_), '(@ "c1")')
+ self.assertEqual(abs_.params, ())
+
+ def test_lshift(self):
+ for lshift in [LShift(self.table.c1, 2),
+ self.table.c1 << 2]:
+ self.assertEqual(str(lshift), '("c1" << %s)')
+ self.assertEqual(lshift.params, (2,))
+
+ def test_rshift(self):
+ for rshift in [RShift(self.table.c1, 2),
+ self.table.c1 >> 2]:
+ self.assertEqual(str(rshift), '("c1" >> %s)')
+ self.assertEqual(rshift.params, (2,))
+
+ def test_like(self):
+ for like in [Like(self.table.c1, 'foo'),
+ self.table.c1.like('foo'),
+ ~NotLike(self.table.c1, 'foo'),
+ ~~Like(self.table.c1, 'foo')]:
+ self.assertEqual(str(like), '("c1" LIKE %s)')
+ self.assertEqual(like.params, ('foo',))
+
+ def test_ilike(self):
+ flavor = Flavor(ilike=True)
+ Flavor.set(flavor)
+ try:
+ for like in [ILike(self.table.c1, 'foo'),
+ self.table.c1.ilike('foo'),
+ ~NotILike(self.table.c1, 'foo')]:
+ self.assertEqual(str(like), '("c1" ILIKE %s)')
+ self.assertEqual(like.params, ('foo',))
+ finally:
+ Flavor.set(Flavor())
+
+ flavor = Flavor(ilike=False)
+ Flavor.set(flavor)
+ try:
+ like = ILike(self.table.c1, 'foo')
+ self.assertEqual(str(like), '("c1" LIKE %s)')
+ self.assertEqual(like.params, ('foo',))
+ finally:
+ Flavor.set(Flavor())
+
+ def test_not_ilike(self):
+ flavor = Flavor(ilike=True)
+ Flavor.set(flavor)
+ try:
+ for like in [NotILike(self.table.c1, 'foo'),
+ ~self.table.c1.ilike('foo')]:
+ self.assertEqual(str(like), '("c1" NOT ILIKE %s)')
+ self.assertEqual(like.params, ('foo',))
+ finally:
+ Flavor.set(Flavor())
+
+ flavor = Flavor(ilike=False)
+ Flavor.set(flavor)
+ try:
+ like = NotILike(self.table.c1, 'foo')
+ self.assertEqual(str(like), '("c1" NOT LIKE %s)')
+ self.assertEqual(like.params, ('foo',))
+ finally:
+ Flavor.set(Flavor())
+
def test_in(self):
- in_ = In(self.table.c1, [self.table.c2, 1, None])
- self.assertEqual(str(in_), '("c1" IN ("c2", %s, %s))')
- self.assertEqual(in_.params, (1, None))
+ for in_ in [In(self.table.c1, [self.table.c2, 1, Null]),
+ ~NotIn(self.table.c1, [self.table.c2, 1, Null]),
+ ~~In(self.table.c1, [self.table.c2, 1, Null])]:
+ self.assertEqual(str(in_), '("c1" IN ("c2", %s, %s))')
+ self.assertEqual(in_.params, (1, None))
t2 = Table('t2')
in_ = In(self.table.c1, t2.select(t2.c2))
@@ -124,6 +292,14 @@ class TestOperators(unittest.TestCase):
'("c1" IN (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s))')
self.assertEqual(in_.params, tuple(range(10)))
+ def test_exists(self):
+ exists = Exists(self.table.select(self.table.c1,
+ where=self.table.c1 == 1))
+ self.assertEqual(str(exists),
+ '(EXISTS (SELECT "a"."c1" FROM "t" AS "a" '
+ 'WHERE ("a"."c1" = %s)))')
+ self.assertEqual(exists.params, (1,))
+
def test_floordiv(self):
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
diff --git a/sql/tests/test_select.py b/sql/tests/test_select.py
index 0adadd7..bf8cd26 100644
--- a/sql/tests/test_select.py
+++ b/sql/tests/test_select.py
@@ -29,7 +29,7 @@
import unittest
-from sql import Table, Join, Union, Literal, Flavor
+from sql import Table, Join, Union, Literal, Flavor, For
from sql.functions import Now, Function
from sql.aggregate import Min
@@ -57,6 +57,14 @@ class TestSelect(unittest.TestCase):
'SELECT * FROM "t" AS "a" WHERE ("a"."c" = %s)')
self.assertEqual(query.params, ('foo',))
+ def test_select_from_list(self):
+ t2 = Table('t2')
+ t3 = Table('t3')
+ query = (self.table + t2 + t3).select(self.table.c, getattr(t2, '*'))
+ self.assertEqual(str(query),
+ 'SELECT "a"."c", "b".* FROM "t" AS "a", "t2" AS "b", "t3" AS "c"')
+ self.assertEqual(query.params, ())
+
def test_select_union(self):
query1 = self.table.select()
query2 = Table('t2').select()
@@ -92,6 +100,20 @@ class TestSelect(unittest.TestCase):
'ORDER BY %s')
self.assertEqual(union.params, (1,))
+ def test_select_intersect(self):
+ query1 = self.table.select()
+ query2 = Table('t2').select()
+ intersect = query1 & query2
+ self.assertEqual(str(intersect),
+ 'SELECT * FROM "t" AS "a" INTERSECT SELECT * FROM "t2" AS "b"')
+
+ def test_select_except(self):
+ query1 = self.table.select()
+ query2 = Table('t2').select()
+ except_ = query1 - query2
+ self.assertEqual(str(except_),
+ 'SELECT * FROM "t" AS "a" EXCEPT SELECT * FROM "t2" AS "b"')
+
def test_select_join(self):
t1 = Table('t1')
t2 = Table('t2')
@@ -195,3 +217,10 @@ class TestSelect(unittest.TestCase):
self.assertEqual(query.params, ())
finally:
Flavor.set(Flavor())
+
+ def test_select_for(self):
+ c = self.table.c
+ query = self.table.select(c, for_=For('UPDATE'))
+ self.assertEqual(str(query),
+ 'SELECT "a"."c" FROM "t" AS "a" FOR UPDATE')
+ self.assertEqual(query.params, ())
diff --git a/sql/tests/test_update.py b/sql/tests/test_update.py
index 3cf1964..63ef2a8 100644
--- a/sql/tests/test_update.py
+++ b/sql/tests/test_update.py
@@ -28,7 +28,7 @@
import unittest
-from sql import Table
+from sql import Table, Literal
class TestUpdate(unittest.TestCase):
@@ -39,7 +39,7 @@ class TestUpdate(unittest.TestCase):
self.assertEqual(str(query), 'UPDATE "t" SET "c" = %s')
self.assertEqual(query.params, ('foo',))
- query.where = (self.table.b == True)
+ query.where = (self.table.b == Literal(True))
self.assertEqual(str(query),
'UPDATE "t" SET "c" = %s WHERE ("t"."b" = %s)')
self.assertEqual(query.params, ('foo', True))
@@ -56,11 +56,13 @@ class TestUpdate(unittest.TestCase):
def test_update_subselect(self):
t1 = Table('t1')
t2 = Table('t2')
- query = t1.update([t1.c], [t2.select(t2.c, where=t2.i == t1.i)])
- self.assertEqual(str(query),
- 'UPDATE "t1" SET "c" = ('
- 'SELECT "b"."c" FROM "t2" AS "b" WHERE ("b"."i" = "t1"."i"))')
- self.assertEqual(query.params, ())
+ query_list = t1.update([t1.c], [t2.select(t2.c, where=t2.i == t1.i)])
+ query_nolist = t1.update([t1.c], t2.select(t2.c, where=t2.i == t1.i))
+ for query in [query_list, query_nolist]:
+ self.assertEqual(str(query),
+ 'UPDATE "t1" SET "c" = ('
+ 'SELECT "b"."c" FROM "t2" AS "b" WHERE ("b"."i" = "t1"."i"))')
+ self.assertEqual(query.params, ())
def test_update_returning(self):
query = self.table.update([self.table.c], ['foo'],
--
python-sql
More information about the tryton-debian-vcs
mailing list