Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 1 | #-*- coding: ISO-8859-1 -*- |
| 2 | # pysqlite2/test/types.py: tests for type conversion and detection |
| 3 | # |
| 4 | # Copyright (C) 2005 Gerhard Häring <gh@ghaering.de> |
| 5 | # |
| 6 | # This file is part of pysqlite. |
| 7 | # |
| 8 | # This software is provided 'as-is', without any express or implied |
| 9 | # warranty. In no event will the authors be held liable for any damages |
| 10 | # arising from the use of this software. |
| 11 | # |
| 12 | # Permission is granted to anyone to use this software for any purpose, |
| 13 | # including commercial applications, and to alter it and redistribute it |
| 14 | # freely, subject to the following restrictions: |
| 15 | # |
| 16 | # 1. The origin of this software must not be misrepresented; you must not |
| 17 | # claim that you wrote the original software. If you use this software |
| 18 | # in a product, an acknowledgment in the product documentation would be |
| 19 | # appreciated but is not required. |
| 20 | # 2. Altered source versions must be plainly marked as such, and must not be |
| 21 | # misrepresented as being the original software. |
| 22 | # 3. This notice may not be removed or altered from any source distribution. |
| 23 | |
Ezio Melotti | 78ea202 | 2009-09-12 18:41:20 +0000 | [diff] [blame] | 24 | import datetime |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 25 | import unittest |
| 26 | import sqlite3 as sqlite |
Ezio Melotti | 78ea202 | 2009-09-12 18:41:20 +0000 | [diff] [blame] | 27 | try: |
| 28 | import zlib |
| 29 | except ImportError: |
| 30 | zlib = None |
| 31 | |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 32 | |
| 33 | class SqliteTypeTests(unittest.TestCase): |
| 34 | def setUp(self): |
| 35 | self.con = sqlite.connect(":memory:") |
| 36 | self.cur = self.con.cursor() |
| 37 | self.cur.execute("create table test(i integer, s varchar, f number, b blob)") |
| 38 | |
| 39 | def tearDown(self): |
| 40 | self.cur.close() |
| 41 | self.con.close() |
| 42 | |
| 43 | def CheckString(self): |
Guido van Rossum | ef87d6e | 2007-05-02 19:09:54 +0000 | [diff] [blame] | 44 | self.cur.execute("insert into test(s) values (?)", ("Österreich",)) |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 45 | self.cur.execute("select s from test") |
| 46 | row = self.cur.fetchone() |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 47 | self.assertEqual(row[0], "Österreich") |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 48 | |
| 49 | def CheckSmallInt(self): |
| 50 | self.cur.execute("insert into test(i) values (?)", (42,)) |
| 51 | self.cur.execute("select i from test") |
| 52 | row = self.cur.fetchone() |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 53 | self.assertEqual(row[0], 42) |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 54 | |
| 55 | def CheckLargeInt(self): |
| 56 | num = 2**40 |
| 57 | self.cur.execute("insert into test(i) values (?)", (num,)) |
| 58 | self.cur.execute("select i from test") |
| 59 | row = self.cur.fetchone() |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 60 | self.assertEqual(row[0], num) |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 61 | |
| 62 | def CheckFloat(self): |
| 63 | val = 3.14 |
| 64 | self.cur.execute("insert into test(f) values (?)", (val,)) |
| 65 | self.cur.execute("select f from test") |
| 66 | row = self.cur.fetchone() |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 67 | self.assertEqual(row[0], val) |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 68 | |
| 69 | def CheckBlob(self): |
Guido van Rossum | 98297ee | 2007-11-06 21:34:58 +0000 | [diff] [blame] | 70 | sample = b"Guglhupf" |
| 71 | val = memoryview(sample) |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 72 | self.cur.execute("insert into test(b) values (?)", (val,)) |
| 73 | self.cur.execute("select b from test") |
| 74 | row = self.cur.fetchone() |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 75 | self.assertEqual(row[0], sample) |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 76 | |
| 77 | def CheckUnicodeExecute(self): |
Guido van Rossum | ef87d6e | 2007-05-02 19:09:54 +0000 | [diff] [blame] | 78 | self.cur.execute("select 'Österreich'") |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 79 | row = self.cur.fetchone() |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 80 | self.assertEqual(row[0], "Österreich") |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 81 | |
| 82 | class DeclTypesTests(unittest.TestCase): |
| 83 | class Foo: |
| 84 | def __init__(self, _val): |
Guido van Rossum | 98297ee | 2007-11-06 21:34:58 +0000 | [diff] [blame] | 85 | if isinstance(_val, bytes): |
| 86 | # sqlite3 always calls __init__ with a bytes created from a |
Brett Cannon | 4043001 | 2007-10-22 20:24:51 +0000 | [diff] [blame] | 87 | # UTF-8 string when __conform__ was used to store the object. |
| 88 | _val = _val.decode('utf8') |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 89 | self.val = _val |
| 90 | |
| 91 | def __cmp__(self, other): |
| 92 | if not isinstance(other, DeclTypesTests.Foo): |
| 93 | raise ValueError |
| 94 | if self.val == other.val: |
| 95 | return 0 |
| 96 | else: |
| 97 | return 1 |
| 98 | |
Guido van Rossum | 47b9ff6 | 2006-08-24 00:41:19 +0000 | [diff] [blame] | 99 | def __eq__(self, other): |
| 100 | c = self.__cmp__(other) |
| 101 | if c is NotImplemented: |
| 102 | return c |
| 103 | return c == 0 |
| 104 | |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 105 | def __conform__(self, protocol): |
| 106 | if protocol is sqlite.PrepareProtocol: |
| 107 | return self.val |
| 108 | else: |
| 109 | return None |
| 110 | |
| 111 | def __str__(self): |
| 112 | return "<%s>" % self.val |
| 113 | |
| 114 | def setUp(self): |
| 115 | self.con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_DECLTYPES) |
| 116 | self.cur = self.con.cursor() |
Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 117 | self.cur.execute("create table test(i int, s str, f float, b bool, u unicode, foo foo, bin blob, n1 number, n2 number(5))") |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 118 | |
| 119 | # override float, make them always return the same number |
Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 120 | sqlite.converters["FLOAT"] = lambda x: 47.2 |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 121 | |
| 122 | # and implement two custom ones |
Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 123 | sqlite.converters["BOOL"] = lambda x: bool(int(x)) |
| 124 | sqlite.converters["FOO"] = DeclTypesTests.Foo |
Thomas Wouters | fc7bb8c | 2007-01-15 15:49:28 +0000 | [diff] [blame] | 125 | sqlite.converters["WRONG"] = lambda x: "WRONG" |
Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 126 | sqlite.converters["NUMBER"] = float |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 127 | |
| 128 | def tearDown(self): |
Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 129 | del sqlite.converters["FLOAT"] |
| 130 | del sqlite.converters["BOOL"] |
| 131 | del sqlite.converters["FOO"] |
Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 132 | del sqlite.converters["NUMBER"] |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 133 | self.cur.close() |
| 134 | self.con.close() |
| 135 | |
| 136 | def CheckString(self): |
| 137 | # default |
| 138 | self.cur.execute("insert into test(s) values (?)", ("foo",)) |
Thomas Wouters | fc7bb8c | 2007-01-15 15:49:28 +0000 | [diff] [blame] | 139 | self.cur.execute('select s as "s [WRONG]" from test') |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 140 | row = self.cur.fetchone() |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 141 | self.assertEqual(row[0], "foo") |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 142 | |
| 143 | def CheckSmallInt(self): |
| 144 | # default |
| 145 | self.cur.execute("insert into test(i) values (?)", (42,)) |
| 146 | self.cur.execute("select i from test") |
| 147 | row = self.cur.fetchone() |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 148 | self.assertEqual(row[0], 42) |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 149 | |
| 150 | def CheckLargeInt(self): |
| 151 | # default |
| 152 | num = 2**40 |
| 153 | self.cur.execute("insert into test(i) values (?)", (num,)) |
| 154 | self.cur.execute("select i from test") |
| 155 | row = self.cur.fetchone() |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 156 | self.assertEqual(row[0], num) |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 157 | |
| 158 | def CheckFloat(self): |
| 159 | # custom |
| 160 | val = 3.14 |
| 161 | self.cur.execute("insert into test(f) values (?)", (val,)) |
| 162 | self.cur.execute("select f from test") |
| 163 | row = self.cur.fetchone() |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 164 | self.assertEqual(row[0], 47.2) |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 165 | |
| 166 | def CheckBool(self): |
| 167 | # custom |
| 168 | self.cur.execute("insert into test(b) values (?)", (False,)) |
| 169 | self.cur.execute("select b from test") |
| 170 | row = self.cur.fetchone() |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 171 | self.assertEqual(row[0], False) |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 172 | |
| 173 | self.cur.execute("delete from test") |
| 174 | self.cur.execute("insert into test(b) values (?)", (True,)) |
| 175 | self.cur.execute("select b from test") |
| 176 | row = self.cur.fetchone() |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 177 | self.assertEqual(row[0], True) |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 178 | |
| 179 | def CheckUnicode(self): |
| 180 | # default |
Guido van Rossum | ef87d6e | 2007-05-02 19:09:54 +0000 | [diff] [blame] | 181 | val = "\xd6sterreich" |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 182 | self.cur.execute("insert into test(u) values (?)", (val,)) |
| 183 | self.cur.execute("select u from test") |
| 184 | row = self.cur.fetchone() |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 185 | self.assertEqual(row[0], val) |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 186 | |
| 187 | def CheckFoo(self): |
| 188 | val = DeclTypesTests.Foo("bla") |
| 189 | self.cur.execute("insert into test(foo) values (?)", (val,)) |
| 190 | self.cur.execute("select foo from test") |
| 191 | row = self.cur.fetchone() |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 192 | self.assertEqual(row[0], val) |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 193 | |
| 194 | def CheckUnsupportedSeq(self): |
| 195 | class Bar: pass |
| 196 | val = Bar() |
| 197 | try: |
| 198 | self.cur.execute("insert into test(f) values (?)", (val,)) |
| 199 | self.fail("should have raised an InterfaceError") |
| 200 | except sqlite.InterfaceError: |
| 201 | pass |
| 202 | except: |
| 203 | self.fail("should have raised an InterfaceError") |
| 204 | |
| 205 | def CheckUnsupportedDict(self): |
| 206 | class Bar: pass |
| 207 | val = Bar() |
| 208 | try: |
| 209 | self.cur.execute("insert into test(f) values (:val)", {"val": val}) |
| 210 | self.fail("should have raised an InterfaceError") |
| 211 | except sqlite.InterfaceError: |
| 212 | pass |
| 213 | except: |
| 214 | self.fail("should have raised an InterfaceError") |
| 215 | |
| 216 | def CheckBlob(self): |
| 217 | # default |
Guido van Rossum | 98297ee | 2007-11-06 21:34:58 +0000 | [diff] [blame] | 218 | sample = b"Guglhupf" |
| 219 | val = memoryview(sample) |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 220 | self.cur.execute("insert into test(bin) values (?)", (val,)) |
| 221 | self.cur.execute("select bin from test") |
| 222 | row = self.cur.fetchone() |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 223 | self.assertEqual(row[0], sample) |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 224 | |
Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 225 | def CheckNumber1(self): |
| 226 | self.cur.execute("insert into test(n1) values (5)") |
| 227 | value = self.cur.execute("select n1 from test").fetchone()[0] |
| 228 | # if the converter is not used, it's an int instead of a float |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 229 | self.assertEqual(type(value), float) |
Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 230 | |
| 231 | def CheckNumber2(self): |
| 232 | """Checks wether converter names are cut off at '(' characters""" |
| 233 | self.cur.execute("insert into test(n2) values (5)") |
| 234 | value = self.cur.execute("select n2 from test").fetchone()[0] |
| 235 | # if the converter is not used, it's an int instead of a float |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 236 | self.assertEqual(type(value), float) |
Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 237 | |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 238 | class ColNamesTests(unittest.TestCase): |
| 239 | def setUp(self): |
Thomas Wouters | fc7bb8c | 2007-01-15 15:49:28 +0000 | [diff] [blame] | 240 | self.con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_COLNAMES) |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 241 | self.cur = self.con.cursor() |
| 242 | self.cur.execute("create table test(x foo)") |
| 243 | |
Gerhard Häring | e7ea745 | 2008-03-29 00:45:29 +0000 | [diff] [blame] | 244 | sqlite.converters["FOO"] = lambda x: "[%s]" % x.decode("ascii") |
| 245 | sqlite.converters["BAR"] = lambda x: "<%s>" % x.decode("ascii") |
Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 246 | sqlite.converters["EXC"] = lambda x: 5/0 |
Thomas Wouters | fc7bb8c | 2007-01-15 15:49:28 +0000 | [diff] [blame] | 247 | sqlite.converters["B1B1"] = lambda x: "MARKER" |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 248 | |
| 249 | def tearDown(self): |
Gerhard Häring | e7ea745 | 2008-03-29 00:45:29 +0000 | [diff] [blame] | 250 | del sqlite.converters["FOO"] |
Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 251 | del sqlite.converters["BAR"] |
| 252 | del sqlite.converters["EXC"] |
Thomas Wouters | fc7bb8c | 2007-01-15 15:49:28 +0000 | [diff] [blame] | 253 | del sqlite.converters["B1B1"] |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 254 | self.cur.close() |
| 255 | self.con.close() |
| 256 | |
Thomas Wouters | fc7bb8c | 2007-01-15 15:49:28 +0000 | [diff] [blame] | 257 | def CheckDeclTypeNotUsed(self): |
| 258 | """ |
| 259 | Assures that the declared type is not used when PARSE_DECLTYPES |
| 260 | is not set. |
| 261 | """ |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 262 | self.cur.execute("insert into test(x) values (?)", ("xxx",)) |
| 263 | self.cur.execute("select x from test") |
| 264 | val = self.cur.fetchone()[0] |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 265 | self.assertEqual(val, "xxx") |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 266 | |
| 267 | def CheckNone(self): |
| 268 | self.cur.execute("insert into test(x) values (?)", (None,)) |
| 269 | self.cur.execute("select x from test") |
| 270 | val = self.cur.fetchone()[0] |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 271 | self.assertEqual(val, None) |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 272 | |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 273 | def CheckColName(self): |
| 274 | self.cur.execute("insert into test(x) values (?)", ("xxx",)) |
| 275 | self.cur.execute('select x as "x [bar]" from test') |
| 276 | val = self.cur.fetchone()[0] |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 277 | self.assertEqual(val, "<xxx>") |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 278 | |
| 279 | # Check if the stripping of colnames works. Everything after the first |
| 280 | # whitespace should be stripped. |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 281 | self.assertEqual(self.cur.description[0][0], "x") |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 282 | |
Thomas Wouters | fc7bb8c | 2007-01-15 15:49:28 +0000 | [diff] [blame] | 283 | def CheckCaseInConverterName(self): |
Guido van Rossum | 98297ee | 2007-11-06 21:34:58 +0000 | [diff] [blame] | 284 | self.cur.execute("select 'other' as \"x [b1b1]\"") |
Thomas Wouters | fc7bb8c | 2007-01-15 15:49:28 +0000 | [diff] [blame] | 285 | val = self.cur.fetchone()[0] |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 286 | self.assertEqual(val, "MARKER") |
Thomas Wouters | fc7bb8c | 2007-01-15 15:49:28 +0000 | [diff] [blame] | 287 | |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 288 | def CheckCursorDescriptionNoRow(self): |
| 289 | """ |
| 290 | cursor.description should at least provide the column name(s), even if |
| 291 | no row returned. |
| 292 | """ |
| 293 | self.cur.execute("select * from test where 0 = 1") |
Ezio Melotti | b3aedd4 | 2010-11-20 19:04:17 +0000 | [diff] [blame^] | 294 | self.assertEqual(self.cur.description[0][0], "x") |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 295 | |
| 296 | class ObjectAdaptationTests(unittest.TestCase): |
| 297 | def cast(obj): |
| 298 | return float(obj) |
| 299 | cast = staticmethod(cast) |
| 300 | |
| 301 | def setUp(self): |
| 302 | self.con = sqlite.connect(":memory:") |
| 303 | try: |
| 304 | del sqlite.adapters[int] |
| 305 | except: |
| 306 | pass |
| 307 | sqlite.register_adapter(int, ObjectAdaptationTests.cast) |
| 308 | self.cur = self.con.cursor() |
| 309 | |
| 310 | def tearDown(self): |
| 311 | del sqlite.adapters[(int, sqlite.PrepareProtocol)] |
| 312 | self.cur.close() |
| 313 | self.con.close() |
| 314 | |
| 315 | def CheckCasterIsUsed(self): |
| 316 | self.cur.execute("select ?", (4,)) |
| 317 | val = self.cur.fetchone()[0] |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 318 | self.assertEqual(type(val), float) |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 319 | |
Ezio Melotti | 78ea202 | 2009-09-12 18:41:20 +0000 | [diff] [blame] | 320 | @unittest.skipUnless(zlib, "requires zlib") |
Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 321 | class BinaryConverterTests(unittest.TestCase): |
| 322 | def convert(s): |
Gerhard Häring | e7ea745 | 2008-03-29 00:45:29 +0000 | [diff] [blame] | 323 | return zlib.decompress(s) |
Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 324 | convert = staticmethod(convert) |
| 325 | |
| 326 | def setUp(self): |
| 327 | self.con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_COLNAMES) |
| 328 | sqlite.register_converter("bin", BinaryConverterTests.convert) |
| 329 | |
| 330 | def tearDown(self): |
| 331 | self.con.close() |
| 332 | |
| 333 | def CheckBinaryInputForConverter(self): |
Gerhard Häring | 6d21456 | 2007-08-10 18:15:11 +0000 | [diff] [blame] | 334 | testdata = b"abcdefg" * 10 |
Gerhard Häring | e7ea745 | 2008-03-29 00:45:29 +0000 | [diff] [blame] | 335 | result = self.con.execute('select ? as "x [bin]"', (memoryview(zlib.compress(testdata)),)).fetchone()[0] |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 336 | self.assertEqual(testdata, result) |
Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 337 | |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 338 | class DateTimeTests(unittest.TestCase): |
| 339 | def setUp(self): |
| 340 | self.con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_DECLTYPES) |
| 341 | self.cur = self.con.cursor() |
| 342 | self.cur.execute("create table test(d date, ts timestamp)") |
| 343 | |
| 344 | def tearDown(self): |
| 345 | self.cur.close() |
| 346 | self.con.close() |
| 347 | |
| 348 | def CheckSqliteDate(self): |
| 349 | d = sqlite.Date(2004, 2, 14) |
| 350 | self.cur.execute("insert into test(d) values (?)", (d,)) |
| 351 | self.cur.execute("select d from test") |
| 352 | d2 = self.cur.fetchone()[0] |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 353 | self.assertEqual(d, d2) |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 354 | |
| 355 | def CheckSqliteTimestamp(self): |
| 356 | ts = sqlite.Timestamp(2004, 2, 14, 7, 15, 0) |
| 357 | self.cur.execute("insert into test(ts) values (?)", (ts,)) |
| 358 | self.cur.execute("select ts from test") |
| 359 | ts2 = self.cur.fetchone()[0] |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 360 | self.assertEqual(ts, ts2) |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 361 | |
| 362 | def CheckSqlTimestamp(self): |
| 363 | # The date functions are only available in SQLite version 3.1 or later |
| 364 | if sqlite.sqlite_version_info < (3, 1): |
| 365 | return |
| 366 | |
Gerhard Häring | e7ea745 | 2008-03-29 00:45:29 +0000 | [diff] [blame] | 367 | # SQLite's current_timestamp uses UTC time, while datetime.datetime.now() uses local time. |
| 368 | now = datetime.datetime.now() |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 369 | self.cur.execute("insert into test(ts) values (current_timestamp)") |
| 370 | self.cur.execute("select ts from test") |
| 371 | ts = self.cur.fetchone()[0] |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 372 | self.assertEqual(type(ts), datetime.datetime) |
| 373 | self.assertEqual(ts.year, now.year) |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 374 | |
| 375 | def CheckDateTimeSubSeconds(self): |
| 376 | ts = sqlite.Timestamp(2004, 2, 14, 7, 15, 0, 500000) |
| 377 | self.cur.execute("insert into test(ts) values (?)", (ts,)) |
| 378 | self.cur.execute("select ts from test") |
| 379 | ts2 = self.cur.fetchone()[0] |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 380 | self.assertEqual(ts, ts2) |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 381 | |
Thomas Wouters | fc7bb8c | 2007-01-15 15:49:28 +0000 | [diff] [blame] | 382 | def CheckDateTimeSubSecondsFloatingPoint(self): |
| 383 | ts = sqlite.Timestamp(2004, 2, 14, 7, 15, 0, 510241) |
| 384 | self.cur.execute("insert into test(ts) values (?)", (ts,)) |
| 385 | self.cur.execute("select ts from test") |
| 386 | ts2 = self.cur.fetchone()[0] |
Gregory P. Smith | 04cecaf | 2009-07-04 08:32:15 +0000 | [diff] [blame] | 387 | self.assertEqual(ts, ts2) |
Thomas Wouters | fc7bb8c | 2007-01-15 15:49:28 +0000 | [diff] [blame] | 388 | |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 389 | def suite(): |
| 390 | sqlite_type_suite = unittest.makeSuite(SqliteTypeTests, "Check") |
| 391 | decltypes_type_suite = unittest.makeSuite(DeclTypesTests, "Check") |
| 392 | colnames_type_suite = unittest.makeSuite(ColNamesTests, "Check") |
| 393 | adaptation_suite = unittest.makeSuite(ObjectAdaptationTests, "Check") |
Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 394 | bin_suite = unittest.makeSuite(BinaryConverterTests, "Check") |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 395 | date_suite = unittest.makeSuite(DateTimeTests, "Check") |
Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 396 | return unittest.TestSuite((sqlite_type_suite, decltypes_type_suite, colnames_type_suite, adaptation_suite, bin_suite, date_suite)) |
Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 397 | |
| 398 | def test(): |
| 399 | runner = unittest.TextTestRunner() |
| 400 | runner.run(suite()) |
| 401 | |
| 402 | if __name__ == "__main__": |
| 403 | test() |