hooks.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. #-*- coding: ISO-8859-1 -*-
  2. # pysqlite2/test/hooks.py: tests for various SQLite-specific hooks
  3. #
  4. # Copyright (C) 2006-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 os, unittest
  24. import pysqlcipher.dbapi2 as sqlite
  25. class CollationTests(unittest.TestCase):
  26. def setUp(self):
  27. pass
  28. def tearDown(self):
  29. pass
  30. def CheckCreateCollationNotCallable(self):
  31. con = sqlite.connect(":memory:")
  32. try:
  33. con.create_collation("X", 42)
  34. self.fail("should have raised a TypeError")
  35. except TypeError, e:
  36. self.assertEqual(e.args[0], "parameter must be callable")
  37. def CheckCreateCollationNotAscii(self):
  38. con = sqlite.connect(":memory:")
  39. try:
  40. con.create_collation("collä", cmp)
  41. self.fail("should have raised a ProgrammingError")
  42. except sqlite.ProgrammingError, e:
  43. pass
  44. def CheckCollationIsUsed(self):
  45. if sqlite.version_info < (3, 2, 1): # old SQLite versions crash on this test
  46. return
  47. def mycoll(x, y):
  48. # reverse order
  49. return -cmp(x, y)
  50. con = sqlite.connect(":memory:")
  51. con.create_collation("mycoll", mycoll)
  52. sql = """
  53. select x from (
  54. select 'a' as x
  55. union
  56. select 'b' as x
  57. union
  58. select 'c' as x
  59. ) order by x collate mycoll
  60. """
  61. result = con.execute(sql).fetchall()
  62. if result[0][0] != "c" or result[1][0] != "b" or result[2][0] != "a":
  63. self.fail("the expected order was not returned")
  64. con.create_collation("mycoll", None)
  65. try:
  66. result = con.execute(sql).fetchall()
  67. self.fail("should have raised an OperationalError")
  68. except sqlite.OperationalError, e:
  69. self.assertEqual(e.args[0].lower(), "no such collation sequence: mycoll")
  70. def CheckCollationRegisterTwice(self):
  71. """
  72. Register two different collation functions under the same name.
  73. Verify that the last one is actually used.
  74. """
  75. con = sqlite.connect(":memory:")
  76. con.create_collation("mycoll", cmp)
  77. con.create_collation("mycoll", lambda x, y: -cmp(x, y))
  78. result = con.execute("""
  79. select x from (select 'a' as x union select 'b' as x) order by x collate mycoll
  80. """).fetchall()
  81. if result[0][0] != 'b' or result[1][0] != 'a':
  82. self.fail("wrong collation function is used")
  83. def CheckDeregisterCollation(self):
  84. """
  85. Register a collation, then deregister it. Make sure an error is raised if we try
  86. to use it.
  87. """
  88. con = sqlite.connect(":memory:")
  89. con.create_collation("mycoll", cmp)
  90. con.create_collation("mycoll", None)
  91. try:
  92. con.execute("select 'a' as x union select 'b' as x order by x collate mycoll")
  93. self.fail("should have raised an OperationalError")
  94. except sqlite.OperationalError, e:
  95. if not e.args[0].startswith("no such collation sequence"):
  96. self.fail("wrong OperationalError raised")
  97. class ProgressTests(unittest.TestCase):
  98. def CheckProgressHandlerUsed(self):
  99. """
  100. Test that the progress handler is invoked once it is set.
  101. """
  102. con = sqlite.connect(":memory:")
  103. progress_calls = []
  104. def progress():
  105. progress_calls.append(None)
  106. return 0
  107. con.set_progress_handler(progress, 1)
  108. con.execute("""
  109. create table foo(a, b)
  110. """)
  111. self.assertTrue(progress_calls)
  112. def CheckOpcodeCount(self):
  113. """
  114. Test that the opcode argument is respected.
  115. """
  116. con = sqlite.connect(":memory:")
  117. progress_calls = []
  118. def progress():
  119. progress_calls.append(None)
  120. return 0
  121. con.set_progress_handler(progress, 1)
  122. curs = con.cursor()
  123. curs.execute("""
  124. create table foo (a, b)
  125. """)
  126. first_count = len(progress_calls)
  127. progress_calls = []
  128. con.set_progress_handler(progress, 2)
  129. curs.execute("""
  130. create table bar (a, b)
  131. """)
  132. second_count = len(progress_calls)
  133. self.assertTrue(first_count > second_count)
  134. def CheckCancelOperation(self):
  135. """
  136. Test that returning a non-zero value stops the operation in progress.
  137. """
  138. con = sqlite.connect(":memory:")
  139. progress_calls = []
  140. def progress():
  141. progress_calls.append(None)
  142. return 1
  143. con.set_progress_handler(progress, 1)
  144. curs = con.cursor()
  145. self.assertRaises(
  146. sqlite.OperationalError,
  147. curs.execute,
  148. "create table bar (a, b)")
  149. def CheckClearHandler(self):
  150. """
  151. Test that setting the progress handler to None clears the previously set handler.
  152. """
  153. con = sqlite.connect(":memory:")
  154. action = 0
  155. def progress():
  156. action = 1
  157. return 0
  158. con.set_progress_handler(progress, 1)
  159. con.set_progress_handler(None, 1)
  160. con.execute("select 1 union select 2 union select 3").fetchall()
  161. self.assertEqual(action, 0, "progress handler was not cleared")
  162. def suite():
  163. collation_suite = unittest.makeSuite(CollationTests, "Check")
  164. progress_suite = unittest.makeSuite(ProgressTests, "Check")
  165. return unittest.TestSuite((collation_suite, progress_suite))
  166. def test():
  167. runner = unittest.TextTestRunner()
  168. runner.run(suite())
  169. if __name__ == "__main__":
  170. test()