PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/Lib/sqlite3/test/types.py

https://bitbucket.org/mirror/python-trunk/
Python | 391 lines | 314 code | 39 blank | 38 comment | 11 complexity | 4c488e13d726117061c439c7ccc592fa MD5 | raw file
Possible License(s): BSD-3-Clause, 0BSD
  1. #-*- coding: ISO-8859-1 -*-
  2. # pysqlite2/test/types.py: tests for type conversion and detection
  3. #
  4. # Copyright (C) 2005-2007 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. import datetime
  24. import unittest
  25. import sqlite3 as sqlite
  26. try:
  27. import zlib
  28. except ImportError:
  29. zlib = None
  30. class SqliteTypeTests(unittest.TestCase):
  31. def setUp(self):
  32. self.con = sqlite.connect(":memory:")
  33. self.cur = self.con.cursor()
  34. self.cur.execute("create table test(i integer, s varchar, f number, b blob)")
  35. def tearDown(self):
  36. self.cur.close()
  37. self.con.close()
  38. def CheckString(self):
  39. self.cur.execute("insert into test(s) values (?)", (u"Österreich",))
  40. self.cur.execute("select s from test")
  41. row = self.cur.fetchone()
  42. self.assertEqual(row[0], u"Österreich")
  43. def CheckSmallInt(self):
  44. self.cur.execute("insert into test(i) values (?)", (42,))
  45. self.cur.execute("select i from test")
  46. row = self.cur.fetchone()
  47. self.assertEqual(row[0], 42)
  48. def CheckLargeInt(self):
  49. num = 2**40
  50. self.cur.execute("insert into test(i) values (?)", (num,))
  51. self.cur.execute("select i from test")
  52. row = self.cur.fetchone()
  53. self.assertEqual(row[0], num)
  54. def CheckFloat(self):
  55. val = 3.14
  56. self.cur.execute("insert into test(f) values (?)", (val,))
  57. self.cur.execute("select f from test")
  58. row = self.cur.fetchone()
  59. self.assertEqual(row[0], val)
  60. def CheckBlob(self):
  61. val = buffer("Guglhupf")
  62. self.cur.execute("insert into test(b) values (?)", (val,))
  63. self.cur.execute("select b from test")
  64. row = self.cur.fetchone()
  65. self.assertEqual(row[0], val)
  66. def CheckUnicodeExecute(self):
  67. self.cur.execute(u"select 'Österreich'")
  68. row = self.cur.fetchone()
  69. self.assertEqual(row[0], u"Österreich")
  70. class DeclTypesTests(unittest.TestCase):
  71. class Foo:
  72. def __init__(self, _val):
  73. self.val = _val
  74. def __cmp__(self, other):
  75. if not isinstance(other, DeclTypesTests.Foo):
  76. raise ValueError
  77. if self.val == other.val:
  78. return 0
  79. else:
  80. return 1
  81. def __conform__(self, protocol):
  82. if protocol is sqlite.PrepareProtocol:
  83. return self.val
  84. else:
  85. return None
  86. def __str__(self):
  87. return "<%s>" % self.val
  88. def setUp(self):
  89. self.con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_DECLTYPES)
  90. self.cur = self.con.cursor()
  91. 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))")
  92. # override float, make them always return the same number
  93. sqlite.converters["FLOAT"] = lambda x: 47.2
  94. # and implement two custom ones
  95. sqlite.converters["BOOL"] = lambda x: bool(int(x))
  96. sqlite.converters["FOO"] = DeclTypesTests.Foo
  97. sqlite.converters["WRONG"] = lambda x: "WRONG"
  98. sqlite.converters["NUMBER"] = float
  99. def tearDown(self):
  100. del sqlite.converters["FLOAT"]
  101. del sqlite.converters["BOOL"]
  102. del sqlite.converters["FOO"]
  103. del sqlite.converters["NUMBER"]
  104. self.cur.close()
  105. self.con.close()
  106. def CheckString(self):
  107. # default
  108. self.cur.execute("insert into test(s) values (?)", ("foo",))
  109. self.cur.execute('select s as "s [WRONG]" from test')
  110. row = self.cur.fetchone()
  111. self.assertEqual(row[0], "foo")
  112. def CheckSmallInt(self):
  113. # default
  114. self.cur.execute("insert into test(i) values (?)", (42,))
  115. self.cur.execute("select i from test")
  116. row = self.cur.fetchone()
  117. self.assertEqual(row[0], 42)
  118. def CheckLargeInt(self):
  119. # default
  120. num = 2**40
  121. self.cur.execute("insert into test(i) values (?)", (num,))
  122. self.cur.execute("select i from test")
  123. row = self.cur.fetchone()
  124. self.assertEqual(row[0], num)
  125. def CheckFloat(self):
  126. # custom
  127. val = 3.14
  128. self.cur.execute("insert into test(f) values (?)", (val,))
  129. self.cur.execute("select f from test")
  130. row = self.cur.fetchone()
  131. self.assertEqual(row[0], 47.2)
  132. def CheckBool(self):
  133. # custom
  134. self.cur.execute("insert into test(b) values (?)", (False,))
  135. self.cur.execute("select b from test")
  136. row = self.cur.fetchone()
  137. self.assertEqual(row[0], False)
  138. self.cur.execute("delete from test")
  139. self.cur.execute("insert into test(b) values (?)", (True,))
  140. self.cur.execute("select b from test")
  141. row = self.cur.fetchone()
  142. self.assertEqual(row[0], True)
  143. def CheckUnicode(self):
  144. # default
  145. val = u"\xd6sterreich"
  146. self.cur.execute("insert into test(u) values (?)", (val,))
  147. self.cur.execute("select u from test")
  148. row = self.cur.fetchone()
  149. self.assertEqual(row[0], val)
  150. def CheckFoo(self):
  151. val = DeclTypesTests.Foo("bla")
  152. self.cur.execute("insert into test(foo) values (?)", (val,))
  153. self.cur.execute("select foo from test")
  154. row = self.cur.fetchone()
  155. self.assertEqual(row[0], val)
  156. def CheckUnsupportedSeq(self):
  157. class Bar: pass
  158. val = Bar()
  159. try:
  160. self.cur.execute("insert into test(f) values (?)", (val,))
  161. self.fail("should have raised an InterfaceError")
  162. except sqlite.InterfaceError:
  163. pass
  164. except:
  165. self.fail("should have raised an InterfaceError")
  166. def CheckUnsupportedDict(self):
  167. class Bar: pass
  168. val = Bar()
  169. try:
  170. self.cur.execute("insert into test(f) values (:val)", {"val": val})
  171. self.fail("should have raised an InterfaceError")
  172. except sqlite.InterfaceError:
  173. pass
  174. except:
  175. self.fail("should have raised an InterfaceError")
  176. def CheckBlob(self):
  177. # default
  178. val = buffer("Guglhupf")
  179. self.cur.execute("insert into test(bin) values (?)", (val,))
  180. self.cur.execute("select bin from test")
  181. row = self.cur.fetchone()
  182. self.assertEqual(row[0], val)
  183. def CheckNumber1(self):
  184. self.cur.execute("insert into test(n1) values (5)")
  185. value = self.cur.execute("select n1 from test").fetchone()[0]
  186. # if the converter is not used, it's an int instead of a float
  187. self.assertEqual(type(value), float)
  188. def CheckNumber2(self):
  189. """Checks wether converter names are cut off at '(' characters"""
  190. self.cur.execute("insert into test(n2) values (5)")
  191. value = self.cur.execute("select n2 from test").fetchone()[0]
  192. # if the converter is not used, it's an int instead of a float
  193. self.assertEqual(type(value), float)
  194. class ColNamesTests(unittest.TestCase):
  195. def setUp(self):
  196. self.con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_COLNAMES)
  197. self.cur = self.con.cursor()
  198. self.cur.execute("create table test(x foo)")
  199. sqlite.converters["FOO"] = lambda x: "[%s]" % x
  200. sqlite.converters["BAR"] = lambda x: "<%s>" % x
  201. sqlite.converters["EXC"] = lambda x: 5/0
  202. sqlite.converters["B1B1"] = lambda x: "MARKER"
  203. def tearDown(self):
  204. del sqlite.converters["FOO"]
  205. del sqlite.converters["BAR"]
  206. del sqlite.converters["EXC"]
  207. del sqlite.converters["B1B1"]
  208. self.cur.close()
  209. self.con.close()
  210. def CheckDeclTypeNotUsed(self):
  211. """
  212. Assures that the declared type is not used when PARSE_DECLTYPES
  213. is not set.
  214. """
  215. self.cur.execute("insert into test(x) values (?)", ("xxx",))
  216. self.cur.execute("select x from test")
  217. val = self.cur.fetchone()[0]
  218. self.assertEqual(val, "xxx")
  219. def CheckNone(self):
  220. self.cur.execute("insert into test(x) values (?)", (None,))
  221. self.cur.execute("select x from test")
  222. val = self.cur.fetchone()[0]
  223. self.assertEqual(val, None)
  224. def CheckColName(self):
  225. self.cur.execute("insert into test(x) values (?)", ("xxx",))
  226. self.cur.execute('select x as "x [bar]" from test')
  227. val = self.cur.fetchone()[0]
  228. self.assertEqual(val, "<xxx>")
  229. # Check if the stripping of colnames works. Everything after the first
  230. # whitespace should be stripped.
  231. self.assertEqual(self.cur.description[0][0], "x")
  232. def CheckCaseInConverterName(self):
  233. self.cur.execute("""select 'other' as "x [b1b1]\"""")
  234. val = self.cur.fetchone()[0]
  235. self.assertEqual(val, "MARKER")
  236. def CheckCursorDescriptionNoRow(self):
  237. """
  238. cursor.description should at least provide the column name(s), even if
  239. no row returned.
  240. """
  241. self.cur.execute("select * from test where 0 = 1")
  242. self.assert_(self.cur.description[0][0] == "x")
  243. class ObjectAdaptationTests(unittest.TestCase):
  244. def cast(obj):
  245. return float(obj)
  246. cast = staticmethod(cast)
  247. def setUp(self):
  248. self.con = sqlite.connect(":memory:")
  249. try:
  250. del sqlite.adapters[int]
  251. except:
  252. pass
  253. sqlite.register_adapter(int, ObjectAdaptationTests.cast)
  254. self.cur = self.con.cursor()
  255. def tearDown(self):
  256. del sqlite.adapters[(int, sqlite.PrepareProtocol)]
  257. self.cur.close()
  258. self.con.close()
  259. def CheckCasterIsUsed(self):
  260. self.cur.execute("select ?", (4,))
  261. val = self.cur.fetchone()[0]
  262. self.assertEqual(type(val), float)
  263. @unittest.skipUnless(zlib, "requires zlib")
  264. class BinaryConverterTests(unittest.TestCase):
  265. def convert(s):
  266. return zlib.decompress(s)
  267. convert = staticmethod(convert)
  268. def setUp(self):
  269. self.con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_COLNAMES)
  270. sqlite.register_converter("bin", BinaryConverterTests.convert)
  271. def tearDown(self):
  272. self.con.close()
  273. def CheckBinaryInputForConverter(self):
  274. testdata = "abcdefg" * 10
  275. result = self.con.execute('select ? as "x [bin]"', (buffer(zlib.compress(testdata)),)).fetchone()[0]
  276. self.assertEqual(testdata, result)
  277. class DateTimeTests(unittest.TestCase):
  278. def setUp(self):
  279. self.con = sqlite.connect(":memory:", detect_types=sqlite.PARSE_DECLTYPES)
  280. self.cur = self.con.cursor()
  281. self.cur.execute("create table test(d date, ts timestamp)")
  282. def tearDown(self):
  283. self.cur.close()
  284. self.con.close()
  285. def CheckSqliteDate(self):
  286. d = sqlite.Date(2004, 2, 14)
  287. self.cur.execute("insert into test(d) values (?)", (d,))
  288. self.cur.execute("select d from test")
  289. d2 = self.cur.fetchone()[0]
  290. self.assertEqual(d, d2)
  291. def CheckSqliteTimestamp(self):
  292. ts = sqlite.Timestamp(2004, 2, 14, 7, 15, 0)
  293. self.cur.execute("insert into test(ts) values (?)", (ts,))
  294. self.cur.execute("select ts from test")
  295. ts2 = self.cur.fetchone()[0]
  296. self.assertEqual(ts, ts2)
  297. def CheckSqlTimestamp(self):
  298. # The date functions are only available in SQLite version 3.1 or later
  299. if sqlite.sqlite_version_info < (3, 1):
  300. return
  301. # SQLite's current_timestamp uses UTC time, while datetime.datetime.now() uses local time.
  302. now = datetime.datetime.now()
  303. self.cur.execute("insert into test(ts) values (current_timestamp)")
  304. self.cur.execute("select ts from test")
  305. ts = self.cur.fetchone()[0]
  306. self.assertEqual(type(ts), datetime.datetime)
  307. self.assertEqual(ts.year, now.year)
  308. def CheckDateTimeSubSeconds(self):
  309. ts = sqlite.Timestamp(2004, 2, 14, 7, 15, 0, 500000)
  310. self.cur.execute("insert into test(ts) values (?)", (ts,))
  311. self.cur.execute("select ts from test")
  312. ts2 = self.cur.fetchone()[0]
  313. self.assertEqual(ts, ts2)
  314. def CheckDateTimeSubSecondsFloatingPoint(self):
  315. ts = sqlite.Timestamp(2004, 2, 14, 7, 15, 0, 510241)
  316. self.cur.execute("insert into test(ts) values (?)", (ts,))
  317. self.cur.execute("select ts from test")
  318. ts2 = self.cur.fetchone()[0]
  319. self.assertEqual(ts, ts2)
  320. def suite():
  321. sqlite_type_suite = unittest.makeSuite(SqliteTypeTests, "Check")
  322. decltypes_type_suite = unittest.makeSuite(DeclTypesTests, "Check")
  323. colnames_type_suite = unittest.makeSuite(ColNamesTests, "Check")
  324. adaptation_suite = unittest.makeSuite(ObjectAdaptationTests, "Check")
  325. bin_suite = unittest.makeSuite(BinaryConverterTests, "Check")
  326. date_suite = unittest.makeSuite(DateTimeTests, "Check")
  327. return unittest.TestSuite((sqlite_type_suite, decltypes_type_suite, colnames_type_suite, adaptation_suite, bin_suite, date_suite))
  328. def test():
  329. runner = unittest.TextTestRunner()
  330. runner.run(suite())
  331. if __name__ == "__main__":
  332. test()