blob: a25360a7d82a5109b50e36fe2287311547a51c4d [file] [log] [blame]
Petri Lehtinenf8547992012-02-02 17:17:36 +02001#-*- coding: iso-8859-1 -*-
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002# pysqlite2/test/transactions.py: tests transactions
3#
Gerhard Häringe7ea7452008-03-29 00:45:29 +00004# Copyright (C) 2005-2007 Gerhard Häring <gh@ghaering.de>
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005#
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
24import os, unittest
25import sqlite3 as sqlite
26
27def get_db_path():
28 return "sqlite_testdb"
29
30class TransactionTests(unittest.TestCase):
31 def setUp(self):
32 try:
33 os.remove(get_db_path())
Christian Heimesdd15f6c2008-03-16 00:07:10 +000034 except OSError:
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000035 pass
36
37 self.con1 = sqlite.connect(get_db_path(), timeout=0.1)
38 self.cur1 = self.con1.cursor()
39
40 self.con2 = sqlite.connect(get_db_path(), timeout=0.1)
41 self.cur2 = self.con2.cursor()
42
43 def tearDown(self):
44 self.cur1.close()
45 self.con1.close()
46
47 self.cur2.close()
48 self.con2.close()
49
Christian Heimesdd15f6c2008-03-16 00:07:10 +000050 try:
51 os.unlink(get_db_path())
52 except OSError:
53 pass
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000054
55 def CheckDMLdoesAutoCommitBefore(self):
56 self.cur1.execute("create table test(i)")
57 self.cur1.execute("insert into test(i) values (5)")
58 self.cur1.execute("create table test2(j)")
59 self.cur2.execute("select i from test")
60 res = self.cur2.fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000061 self.assertEqual(len(res), 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000062
63 def CheckInsertStartsTransaction(self):
64 self.cur1.execute("create table test(i)")
65 self.cur1.execute("insert into test(i) values (5)")
66 self.cur2.execute("select i from test")
67 res = self.cur2.fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000068 self.assertEqual(len(res), 0)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000069
70 def CheckUpdateStartsTransaction(self):
71 self.cur1.execute("create table test(i)")
72 self.cur1.execute("insert into test(i) values (5)")
73 self.con1.commit()
74 self.cur1.execute("update test set i=6")
75 self.cur2.execute("select i from test")
76 res = self.cur2.fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000077 self.assertEqual(res, 5)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000078
79 def CheckDeleteStartsTransaction(self):
80 self.cur1.execute("create table test(i)")
81 self.cur1.execute("insert into test(i) values (5)")
82 self.con1.commit()
83 self.cur1.execute("delete from test")
84 self.cur2.execute("select i from test")
85 res = self.cur2.fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000086 self.assertEqual(len(res), 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000087
88 def CheckReplaceStartsTransaction(self):
89 self.cur1.execute("create table test(i)")
90 self.cur1.execute("insert into test(i) values (5)")
91 self.con1.commit()
92 self.cur1.execute("replace into test(i) values (6)")
93 self.cur2.execute("select i from test")
94 res = self.cur2.fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000095 self.assertEqual(len(res), 1)
96 self.assertEqual(res[0][0], 5)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000097
98 def CheckToggleAutoCommit(self):
99 self.cur1.execute("create table test(i)")
100 self.cur1.execute("insert into test(i) values (5)")
101 self.con1.isolation_level = None
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000102 self.assertEqual(self.con1.isolation_level, None)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000103 self.cur2.execute("select i from test")
104 res = self.cur2.fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000105 self.assertEqual(len(res), 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000106
107 self.con1.isolation_level = "DEFERRED"
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000108 self.assertEqual(self.con1.isolation_level , "DEFERRED")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000109 self.cur1.execute("insert into test(i) values (5)")
110 self.cur2.execute("select i from test")
111 res = self.cur2.fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000112 self.assertEqual(len(res), 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000113
Berker Peksagf85bce72016-06-14 14:19:02 +0300114 @unittest.skipIf(sqlite.sqlite_version_info < (3, 2, 2),
115 'test hangs on sqlite versions older than 3.2.2')
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000116 def CheckRaiseTimeout(self):
117 self.cur1.execute("create table test(i)")
118 self.cur1.execute("insert into test(i) values (5)")
Berker Peksag1003b342016-06-12 22:34:49 +0300119 with self.assertRaises(sqlite.OperationalError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000120 self.cur2.execute("insert into test(i) values (5)")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000121
Berker Peksagf85bce72016-06-14 14:19:02 +0300122 @unittest.skipIf(sqlite.sqlite_version_info < (3, 2, 2),
123 'test hangs on sqlite versions older than 3.2.2')
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000124 def CheckLocking(self):
125 """
126 This tests the improved concurrency with pysqlite 2.3.4. You needed
127 to roll back con2 before you could commit con1.
128 """
129 self.cur1.execute("create table test(i)")
130 self.cur1.execute("insert into test(i) values (5)")
Berker Peksag1003b342016-06-12 22:34:49 +0300131 with self.assertRaises(sqlite.OperationalError):
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000132 self.cur2.execute("insert into test(i) values (5)")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000133 # NO self.con2.rollback() HERE!!!
134 self.con1.commit()
135
Gerhard Häringf9cee222010-03-05 15:20:03 +0000136 def CheckRollbackCursorConsistency(self):
137 """
138 Checks if cursors on the connection are set into a "reset" state
139 when a rollback is done on the connection.
140 """
141 con = sqlite.connect(":memory:")
142 cur = con.cursor()
143 cur.execute("create table test(x)")
144 cur.execute("insert into test(x) values (5)")
145 cur.execute("select 1 union select 2 union select 3")
146
147 con.rollback()
Berker Peksag1003b342016-06-12 22:34:49 +0300148 with self.assertRaises(sqlite.InterfaceError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000149 cur.fetchall()
Gerhard Häringf9cee222010-03-05 15:20:03 +0000150
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000151class SpecialCommandTests(unittest.TestCase):
152 def setUp(self):
153 self.con = sqlite.connect(":memory:")
154 self.cur = self.con.cursor()
155
156 def CheckVacuum(self):
157 self.cur.execute("create table test(i)")
158 self.cur.execute("insert into test(i) values (5)")
159 self.cur.execute("vacuum")
160
161 def CheckDropTable(self):
162 self.cur.execute("create table test(i)")
163 self.cur.execute("insert into test(i) values (5)")
164 self.cur.execute("drop table test")
165
166 def CheckPragma(self):
167 self.cur.execute("create table test(i)")
168 self.cur.execute("insert into test(i) values (5)")
169 self.cur.execute("pragma count_changes=1")
170
171 def tearDown(self):
172 self.cur.close()
173 self.con.close()
174
175def suite():
176 default_suite = unittest.makeSuite(TransactionTests, "Check")
177 special_command_suite = unittest.makeSuite(SpecialCommandTests, "Check")
178 return unittest.TestSuite((default_suite, special_command_suite))
179
180def test():
181 runner = unittest.TextTestRunner()
182 runner.run(suite())
183
184if __name__ == "__main__":
185 test()