PageRenderTime 103ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/Lib/sqlite3/test/types.py

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