PageRenderTime 56ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/Lib/sqlite3/test/types.py

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