blob: 68a3062239532528a14721b8575a585a4e1ffc16 [file] [log] [blame]
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001# pysqlite2/test/dbapi.py: tests for DB-API compliance
2#
Erlend Egeberg Aaslanddeab1e52021-01-07 01:36:35 +01003# Copyright (C) 2004-2010 Gerhard Häring <gh@ghaering.de>
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004#
5# This file is part of pysqlite.
6#
7# This software is provided 'as-is', without any express or implied
8# warranty. In no event will the authors be held liable for any damages
9# arising from the use of this software.
10#
11# Permission is granted to anyone to use this software for any purpose,
12# including commercial applications, and to alter it and redistribute it
13# freely, subject to the following restrictions:
14#
15# 1. The origin of this software must not be misrepresented; you must not
16# claim that you wrote the original software. If you use this software
17# in a product, an acknowledgment in the product documentation would be
18# appreciated but is not required.
19# 2. Altered source versions must be plainly marked as such, and must not be
20# misrepresented as being the original software.
21# 3. This notice may not be removed or altered from any source distribution.
22
Antoine Pitroua6a4dc82017-09-07 18:56:24 +020023import threading
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000024import unittest
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000025import sqlite3 as sqlite
26
Hai Shifcce8c62020-08-08 05:55:35 +080027from test.support.os_helper import TESTFN, unlink
Antoine Pitrou902fc8b2013-02-10 00:02:44 +010028
29
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000030class ModuleTests(unittest.TestCase):
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010031 def test_api_level(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000032 self.assertEqual(sqlite.apilevel, "2.0",
33 "apilevel is %s, should be 2.0" % sqlite.apilevel)
34
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010035 def test_thread_safety(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000036 self.assertEqual(sqlite.threadsafety, 1,
37 "threadsafety is %d, should be 1" % sqlite.threadsafety)
38
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010039 def test_param_style(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000040 self.assertEqual(sqlite.paramstyle, "qmark",
41 "paramstyle is '%s', should be 'qmark'" %
42 sqlite.paramstyle)
43
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010044 def test_warning(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +000045 self.assertTrue(issubclass(sqlite.Warning, Exception),
Guido van Rossumcd16bf62007-06-13 18:07:49 +000046 "Warning is not a subclass of Exception")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000047
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010048 def test_error(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000049 self.assertTrue(issubclass(sqlite.Error, Exception),
Guido van Rossumcd16bf62007-06-13 18:07:49 +000050 "Error is not a subclass of Exception")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000051
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010052 def test_interface_error(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000053 self.assertTrue(issubclass(sqlite.InterfaceError, sqlite.Error),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000054 "InterfaceError is not a subclass of Error")
55
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010056 def test_database_error(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000057 self.assertTrue(issubclass(sqlite.DatabaseError, sqlite.Error),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000058 "DatabaseError is not a subclass of Error")
59
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010060 def test_data_error(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000061 self.assertTrue(issubclass(sqlite.DataError, sqlite.DatabaseError),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000062 "DataError is not a subclass of DatabaseError")
63
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010064 def test_operational_error(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000065 self.assertTrue(issubclass(sqlite.OperationalError, sqlite.DatabaseError),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000066 "OperationalError is not a subclass of DatabaseError")
67
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010068 def test_integrity_error(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000069 self.assertTrue(issubclass(sqlite.IntegrityError, sqlite.DatabaseError),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000070 "IntegrityError is not a subclass of DatabaseError")
71
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010072 def test_internal_error(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000073 self.assertTrue(issubclass(sqlite.InternalError, sqlite.DatabaseError),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000074 "InternalError is not a subclass of DatabaseError")
75
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010076 def test_programming_error(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000077 self.assertTrue(issubclass(sqlite.ProgrammingError, sqlite.DatabaseError),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000078 "ProgrammingError is not a subclass of DatabaseError")
79
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010080 def test_not_supported_error(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000081 self.assertTrue(issubclass(sqlite.NotSupportedError,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000082 sqlite.DatabaseError),
83 "NotSupportedError is not a subclass of DatabaseError")
84
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010085 def test_shared_cache_deprecated(self):
Erlend Egeberg Aaslandddb5e112021-01-06 01:36:04 +010086 for enable in (True, False):
87 with self.assertWarns(DeprecationWarning) as cm:
88 sqlite.enable_shared_cache(enable)
89 self.assertIn("dbapi.py", cm.filename)
90
91
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000092class ConnectionTests(unittest.TestCase):
R. David Murrayd35251d2010-06-01 01:32:12 +000093
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000094 def setUp(self):
95 self.cx = sqlite.connect(":memory:")
96 cu = self.cx.cursor()
97 cu.execute("create table test(id integer primary key, name text)")
98 cu.execute("insert into test(name) values (?)", ("foo",))
99
100 def tearDown(self):
101 self.cx.close()
102
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100103 def test_commit(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000104 self.cx.commit()
105
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100106 def test_commit_after_no_changes(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000107 """
108 A commit should also work when no changes were made to the database.
109 """
110 self.cx.commit()
111 self.cx.commit()
112
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100113 def test_rollback(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000114 self.cx.rollback()
115
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100116 def test_rollback_after_no_changes(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000117 """
118 A rollback should also work when no changes were made to the database.
119 """
120 self.cx.rollback()
121 self.cx.rollback()
122
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100123 def test_cursor(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000124 cu = self.cx.cursor()
125
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100126 def test_failed_open(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000127 YOU_CANNOT_OPEN_THIS = "/foo/bar/bla/23534/mydb.db"
Berker Peksag1003b342016-06-12 22:34:49 +0300128 with self.assertRaises(sqlite.OperationalError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000129 con = sqlite.connect(YOU_CANNOT_OPEN_THIS)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000130
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100131 def test_close(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000132 self.cx.close()
133
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100134 def test_exceptions(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000135 # Optional DB-API extension.
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000136 self.assertEqual(self.cx.Warning, sqlite.Warning)
137 self.assertEqual(self.cx.Error, sqlite.Error)
138 self.assertEqual(self.cx.InterfaceError, sqlite.InterfaceError)
139 self.assertEqual(self.cx.DatabaseError, sqlite.DatabaseError)
140 self.assertEqual(self.cx.DataError, sqlite.DataError)
141 self.assertEqual(self.cx.OperationalError, sqlite.OperationalError)
142 self.assertEqual(self.cx.IntegrityError, sqlite.IntegrityError)
143 self.assertEqual(self.cx.InternalError, sqlite.InternalError)
144 self.assertEqual(self.cx.ProgrammingError, sqlite.ProgrammingError)
145 self.assertEqual(self.cx.NotSupportedError, sqlite.NotSupportedError)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000146
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100147 def test_in_transaction(self):
R. David Murrayd35251d2010-06-01 01:32:12 +0000148 # Can't use db from setUp because we want to test initial state.
149 cx = sqlite.connect(":memory:")
150 cu = cx.cursor()
151 self.assertEqual(cx.in_transaction, False)
152 cu.execute("create table transactiontest(id integer primary key, name text)")
153 self.assertEqual(cx.in_transaction, False)
154 cu.execute("insert into transactiontest(name) values (?)", ("foo",))
155 self.assertEqual(cx.in_transaction, True)
156 cu.execute("select name from transactiontest where name=?", ["foo"])
157 row = cu.fetchone()
158 self.assertEqual(cx.in_transaction, True)
159 cx.commit()
160 self.assertEqual(cx.in_transaction, False)
161 cu.execute("select name from transactiontest where name=?", ["foo"])
162 row = cu.fetchone()
163 self.assertEqual(cx.in_transaction, False)
164
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100165 def test_in_transaction_ro(self):
R. David Murrayd35251d2010-06-01 01:32:12 +0000166 with self.assertRaises(AttributeError):
167 self.cx.in_transaction = True
168
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100169 def test_open_with_path_like_object(self):
Ville Skyttä61f82e02018-04-20 23:08:45 +0300170 """ Checks that we can successfully connect to a database using an object that
Anders Lorentsena22a1272017-11-07 01:47:43 +0100171 is PathLike, i.e. has __fspath__(). """
172 self.addCleanup(unlink, TESTFN)
173 class Path:
174 def __fspath__(self):
175 return TESTFN
176 path = Path()
177 with sqlite.connect(path) as cx:
178 cx.execute('create table test(id integer)')
179
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100180 def test_open_uri(self):
Antoine Pitrou902fc8b2013-02-10 00:02:44 +0100181 self.addCleanup(unlink, TESTFN)
182 with sqlite.connect(TESTFN) as cx:
183 cx.execute('create table test(id integer)')
184 with sqlite.connect('file:' + TESTFN, uri=True) as cx:
185 cx.execute('insert into test(id) values(0)')
186 with sqlite.connect('file:' + TESTFN + '?mode=ro', uri=True) as cx:
187 with self.assertRaises(sqlite.OperationalError):
188 cx.execute('insert into test(id) values(1)')
189
190
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000191class CursorTests(unittest.TestCase):
192 def setUp(self):
193 self.cx = sqlite.connect(":memory:")
194 self.cu = self.cx.cursor()
Berker Peksage0b70cd2016-06-14 15:25:36 +0300195 self.cu.execute(
196 "create table test(id integer primary key, name text, "
197 "income number, unique_test text unique)"
198 )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000199 self.cu.execute("insert into test(name) values (?)", ("foo",))
200
201 def tearDown(self):
202 self.cu.close()
203 self.cx.close()
204
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100205 def test_execute_no_args(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000206 self.cu.execute("delete from test")
207
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100208 def test_execute_illegal_sql(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300209 with self.assertRaises(sqlite.OperationalError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000210 self.cu.execute("select asdf")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000211
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100212 def test_execute_too_much_sql(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300213 with self.assertRaises(sqlite.Warning):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000214 self.cu.execute("select 5+4; select 4+5")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000215
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100216 def test_execute_too_much_sql2(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000217 self.cu.execute("select 5+4; -- foo bar")
218
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100219 def test_execute_too_much_sql3(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000220 self.cu.execute("""
221 select 5+4;
222
223 /*
224 foo
225 */
226 """)
227
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100228 def test_execute_wrong_sql_arg(self):
Victor Stinnerc6a23202019-06-26 03:16:24 +0200229 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000230 self.cu.execute(42)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000231
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100232 def test_execute_arg_int(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000233 self.cu.execute("insert into test(id) values (?)", (42,))
234
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100235 def test_execute_arg_float(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000236 self.cu.execute("insert into test(income) values (?)", (2500.32,))
237
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100238 def test_execute_arg_string(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000239 self.cu.execute("insert into test(name) values (?)", ("Hugo",))
240
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100241 def test_execute_arg_string_with_zero_byte(self):
Petri Lehtinen023fe332012-02-01 22:18:19 +0200242 self.cu.execute("insert into test(name) values (?)", ("Hu\x00go",))
243
244 self.cu.execute("select name from test where id=?", (self.cu.lastrowid,))
245 row = self.cu.fetchone()
246 self.assertEqual(row[0], "Hu\x00go")
247
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100248 def test_execute_non_iterable(self):
Berker Peksagc4154402016-06-12 13:41:47 +0300249 with self.assertRaises(ValueError) as cm:
250 self.cu.execute("insert into test(id) values (?)", 42)
251 self.assertEqual(str(cm.exception), 'parameters are of unsupported type')
252
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100253 def test_execute_wrong_no_of_args1(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000254 # too many parameters
Berker Peksag1003b342016-06-12 22:34:49 +0300255 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000256 self.cu.execute("insert into test(id) values (?)", (17, "Egon"))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000257
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100258 def test_execute_wrong_no_of_args2(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000259 # too little parameters
Berker Peksag1003b342016-06-12 22:34:49 +0300260 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000261 self.cu.execute("insert into test(id) values (?)")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000262
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100263 def test_execute_wrong_no_of_args3(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000264 # no parameters, parameters are needed
Berker Peksag1003b342016-06-12 22:34:49 +0300265 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000266 self.cu.execute("insert into test(id) values (?)")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000267
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100268 def test_execute_param_list(self):
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000269 self.cu.execute("insert into test(name) values ('foo')")
270 self.cu.execute("select name from test where name=?", ["foo"])
271 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000272 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000273
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100274 def test_execute_param_sequence(self):
Serhiy Storchaka0b419b72020-09-17 10:35:44 +0300275 class L:
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000276 def __len__(self):
277 return 1
278 def __getitem__(self, x):
279 assert x == 0
280 return "foo"
281
282 self.cu.execute("insert into test(name) values ('foo')")
283 self.cu.execute("select name from test where name=?", L())
284 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000285 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000286
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100287 def test_execute_param_sequence_bad_len(self):
Serhiy Storchaka0b419b72020-09-17 10:35:44 +0300288 # Issue41662: Error in __len__() was overridden with ProgrammingError.
289 class L:
290 def __len__(self):
291 1/0
292 def __getitem__(slf, x):
293 raise AssertionError
294
295 self.cu.execute("insert into test(name) values ('foo')")
296 with self.assertRaises(ZeroDivisionError):
297 self.cu.execute("select name from test where name=?", L())
298
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100299 def test_execute_dict_mapping(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000300 self.cu.execute("insert into test(name) values ('foo')")
301 self.cu.execute("select name from test where name=:name", {"name": "foo"})
302 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000303 self.assertEqual(row[0], "foo")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000304
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100305 def test_execute_dict_mapping_mapping(self):
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000306 class D(dict):
307 def __missing__(self, key):
308 return "foo"
309
310 self.cu.execute("insert into test(name) values ('foo')")
311 self.cu.execute("select name from test where name=:name", D())
312 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000313 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000314
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100315 def test_execute_dict_mapping_too_little_args(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000316 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag1003b342016-06-12 22:34:49 +0300317 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000318 self.cu.execute("select name from test where name=:name and id=:id", {"name": "foo"})
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000319
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100320 def test_execute_dict_mapping_no_args(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000321 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag1003b342016-06-12 22:34:49 +0300322 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000323 self.cu.execute("select name from test where name=:name")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000324
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100325 def test_execute_dict_mapping_unnamed(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000326 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag1003b342016-06-12 22:34:49 +0300327 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000328 self.cu.execute("select name from test where name=?", {"name": "foo"})
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000329
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100330 def test_close(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000331 self.cu.close()
332
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100333 def test_rowcount_execute(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000334 self.cu.execute("delete from test")
335 self.cu.execute("insert into test(name) values ('foo')")
336 self.cu.execute("insert into test(name) values ('foo')")
337 self.cu.execute("update test set name='bar'")
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000338 self.assertEqual(self.cu.rowcount, 2)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000339
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100340 def test_rowcount_select(self):
Georg Brandlf78e02b2008-06-10 17:40:04 +0000341 """
342 pysqlite does not know the rowcount of SELECT statements, because we
343 don't fetch all rows after executing the select statement. The rowcount
344 has thus to be -1.
345 """
346 self.cu.execute("select 5 union select 6")
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000347 self.assertEqual(self.cu.rowcount, -1)
Georg Brandlf78e02b2008-06-10 17:40:04 +0000348
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100349 def test_rowcount_executemany(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000350 self.cu.execute("delete from test")
351 self.cu.executemany("insert into test(name) values (?)", [(1,), (2,), (3,)])
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000352 self.assertEqual(self.cu.rowcount, 3)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000353
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100354 def test_total_changes(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000355 self.cu.execute("insert into test(name) values ('foo')")
356 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag48b5c982016-06-14 00:42:50 +0300357 self.assertLess(2, self.cx.total_changes, msg='total changes reported wrong value')
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000358
359 # Checks for executemany:
360 # Sequences are required by the DB-API, iterators
361 # enhancements in pysqlite.
362
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100363 def test_execute_many_sequence(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000364 self.cu.executemany("insert into test(income) values (?)", [(x,) for x in range(100, 110)])
365
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100366 def test_execute_many_iterator(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000367 class MyIter:
368 def __init__(self):
369 self.value = 5
370
Georg Brandla18af4e2007-04-21 15:47:16 +0000371 def __next__(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000372 if self.value == 10:
373 raise StopIteration
374 else:
375 self.value += 1
376 return (self.value,)
377
378 self.cu.executemany("insert into test(income) values (?)", MyIter())
379
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100380 def test_execute_many_generator(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000381 def mygen():
382 for i in range(5):
383 yield (i,)
384
385 self.cu.executemany("insert into test(income) values (?)", mygen())
386
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100387 def test_execute_many_wrong_sql_arg(self):
Victor Stinnerc6a23202019-06-26 03:16:24 +0200388 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000389 self.cu.executemany(42, [(3,)])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000390
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100391 def test_execute_many_select(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300392 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000393 self.cu.executemany("select ?", [(3,)])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000394
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100395 def test_execute_many_not_iterable(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300396 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000397 self.cu.executemany("insert into test(income) values (?)", 42)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000398
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100399 def test_fetch_iter(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000400 # Optional DB-API extension.
401 self.cu.execute("delete from test")
402 self.cu.execute("insert into test(id) values (?)", (5,))
403 self.cu.execute("insert into test(id) values (?)", (6,))
404 self.cu.execute("select id from test order by id")
405 lst = []
406 for row in self.cu:
407 lst.append(row[0])
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000408 self.assertEqual(lst[0], 5)
409 self.assertEqual(lst[1], 6)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000410
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100411 def test_fetchone(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000412 self.cu.execute("select name from test")
413 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000414 self.assertEqual(row[0], "foo")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000415 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000416 self.assertEqual(row, None)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000417
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100418 def test_fetchone_no_statement(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000419 cur = self.cx.cursor()
420 row = cur.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000421 self.assertEqual(row, None)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000422
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100423 def test_array_size(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000424 # must default ot 1
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000425 self.assertEqual(self.cu.arraysize, 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000426
427 # now set to 2
428 self.cu.arraysize = 2
429
430 # now make the query return 3 rows
431 self.cu.execute("delete from test")
432 self.cu.execute("insert into test(name) values ('A')")
433 self.cu.execute("insert into test(name) values ('B')")
434 self.cu.execute("insert into test(name) values ('C')")
435 self.cu.execute("select name from test")
436 res = self.cu.fetchmany()
437
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000438 self.assertEqual(len(res), 2)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000439
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100440 def test_fetchmany(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000441 self.cu.execute("select name from test")
442 res = self.cu.fetchmany(100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000443 self.assertEqual(len(res), 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000444 res = self.cu.fetchmany(100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000445 self.assertEqual(res, [])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000446
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100447 def test_fetchmany_kw_arg(self):
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000448 """Checks if fetchmany works with keyword arguments"""
449 self.cu.execute("select name from test")
450 res = self.cu.fetchmany(size=100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000451 self.assertEqual(len(res), 1)
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000452
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100453 def test_fetchall(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000454 self.cu.execute("select name from test")
455 res = self.cu.fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000456 self.assertEqual(len(res), 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000457 res = self.cu.fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000458 self.assertEqual(res, [])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000459
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100460 def test_setinputsizes(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000461 self.cu.setinputsizes([3, 4, 5])
462
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100463 def test_setoutputsize(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000464 self.cu.setoutputsize(5, 0)
465
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100466 def test_setoutputsize_no_column(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000467 self.cu.setoutputsize(42)
468
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100469 def test_cursor_connection(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000470 # Optional DB-API extension.
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000471 self.assertEqual(self.cu.connection, self.cx)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000472
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100473 def test_wrong_cursor_callable(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300474 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000475 def f(): pass
476 cur = self.cx.cursor(f)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000477
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100478 def test_cursor_wrong_class(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000479 class Foo: pass
480 foo = Foo()
Berker Peksag1003b342016-06-12 22:34:49 +0300481 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000482 cur = sqlite.Cursor(foo)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000483
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100484 def test_last_row_id_on_replace(self):
Berker Peksage0b70cd2016-06-14 15:25:36 +0300485 """
486 INSERT OR REPLACE and REPLACE INTO should produce the same behavior.
487 """
488 sql = '{} INTO test(id, unique_test) VALUES (?, ?)'
489 for statement in ('INSERT OR REPLACE', 'REPLACE'):
490 with self.subTest(statement=statement):
491 self.cu.execute(sql.format(statement), (1, 'foo'))
492 self.assertEqual(self.cu.lastrowid, 1)
493
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100494 def test_last_row_id_on_ignore(self):
Berker Peksage0b70cd2016-06-14 15:25:36 +0300495 self.cu.execute(
496 "insert or ignore into test(unique_test) values (?)",
497 ('test',))
498 self.assertEqual(self.cu.lastrowid, 2)
499 self.cu.execute(
500 "insert or ignore into test(unique_test) values (?)",
501 ('test',))
502 self.assertEqual(self.cu.lastrowid, 2)
503
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100504 def test_last_row_id_insert_o_r(self):
Berker Peksage0b70cd2016-06-14 15:25:36 +0300505 results = []
506 for statement in ('FAIL', 'ABORT', 'ROLLBACK'):
507 sql = 'INSERT OR {} INTO test(unique_test) VALUES (?)'
508 with self.subTest(statement='INSERT OR {}'.format(statement)):
509 self.cu.execute(sql.format(statement), (statement,))
510 results.append((statement, self.cu.lastrowid))
511 with self.assertRaises(sqlite.IntegrityError):
512 self.cu.execute(sql.format(statement), (statement,))
513 results.append((statement, self.cu.lastrowid))
514 expected = [
515 ('FAIL', 2), ('FAIL', 2),
516 ('ABORT', 3), ('ABORT', 3),
517 ('ROLLBACK', 4), ('ROLLBACK', 4),
518 ]
519 self.assertEqual(results, expected)
520
521
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000522class ThreadTests(unittest.TestCase):
523 def setUp(self):
524 self.con = sqlite.connect(":memory:")
525 self.cur = self.con.cursor()
526 self.cur.execute("create table test(id integer primary key, name text, bin binary, ratio number, ts timestamp)")
527
528 def tearDown(self):
529 self.cur.close()
530 self.con.close()
531
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100532 def test_con_cursor(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000533 def run(con, errors):
534 try:
535 cur = con.cursor()
536 errors.append("did not raise ProgrammingError")
537 return
538 except sqlite.ProgrammingError:
539 return
540 except:
541 errors.append("raised wrong exception")
542
543 errors = []
544 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
545 t.start()
546 t.join()
547 if len(errors) > 0:
548 self.fail("\n".join(errors))
549
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100550 def test_con_commit(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000551 def run(con, errors):
552 try:
553 con.commit()
554 errors.append("did not raise ProgrammingError")
555 return
556 except sqlite.ProgrammingError:
557 return
558 except:
559 errors.append("raised wrong exception")
560
561 errors = []
562 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
563 t.start()
564 t.join()
565 if len(errors) > 0:
566 self.fail("\n".join(errors))
567
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100568 def test_con_rollback(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000569 def run(con, errors):
570 try:
571 con.rollback()
572 errors.append("did not raise ProgrammingError")
573 return
574 except sqlite.ProgrammingError:
575 return
576 except:
577 errors.append("raised wrong exception")
578
579 errors = []
580 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
581 t.start()
582 t.join()
583 if len(errors) > 0:
584 self.fail("\n".join(errors))
585
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100586 def test_con_close(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000587 def run(con, errors):
588 try:
589 con.close()
590 errors.append("did not raise ProgrammingError")
591 return
592 except sqlite.ProgrammingError:
593 return
594 except:
595 errors.append("raised wrong exception")
596
597 errors = []
598 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
599 t.start()
600 t.join()
601 if len(errors) > 0:
602 self.fail("\n".join(errors))
603
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100604 def test_cur_implicit_begin(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000605 def run(cur, errors):
606 try:
607 cur.execute("insert into test(name) values ('a')")
608 errors.append("did not raise ProgrammingError")
609 return
610 except sqlite.ProgrammingError:
611 return
612 except:
613 errors.append("raised wrong exception")
614
615 errors = []
616 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
617 t.start()
618 t.join()
619 if len(errors) > 0:
620 self.fail("\n".join(errors))
621
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100622 def test_cur_close(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000623 def run(cur, errors):
624 try:
625 cur.close()
626 errors.append("did not raise ProgrammingError")
627 return
628 except sqlite.ProgrammingError:
629 return
630 except:
631 errors.append("raised wrong exception")
632
633 errors = []
634 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
635 t.start()
636 t.join()
637 if len(errors) > 0:
638 self.fail("\n".join(errors))
639
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100640 def test_cur_execute(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000641 def run(cur, errors):
642 try:
643 cur.execute("select name from test")
644 errors.append("did not raise ProgrammingError")
645 return
646 except sqlite.ProgrammingError:
647 return
648 except:
649 errors.append("raised wrong exception")
650
651 errors = []
652 self.cur.execute("insert into test(name) values ('a')")
653 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
654 t.start()
655 t.join()
656 if len(errors) > 0:
657 self.fail("\n".join(errors))
658
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100659 def test_cur_iter_next(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000660 def run(cur, errors):
661 try:
662 row = cur.fetchone()
663 errors.append("did not raise ProgrammingError")
664 return
665 except sqlite.ProgrammingError:
666 return
667 except:
668 errors.append("raised wrong exception")
669
670 errors = []
671 self.cur.execute("insert into test(name) values ('a')")
672 self.cur.execute("select name from test")
673 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
674 t.start()
675 t.join()
676 if len(errors) > 0:
677 self.fail("\n".join(errors))
678
679class ConstructorTests(unittest.TestCase):
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100680 def test_date(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000681 d = sqlite.Date(2004, 10, 28)
682
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100683 def test_time(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000684 t = sqlite.Time(12, 39, 35)
685
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100686 def test_timestamp(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000687 ts = sqlite.Timestamp(2004, 10, 28, 12, 39, 35)
688
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100689 def test_date_from_ticks(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000690 d = sqlite.DateFromTicks(42)
691
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100692 def test_time_from_ticks(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000693 t = sqlite.TimeFromTicks(42)
694
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100695 def test_timestamp_from_ticks(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000696 ts = sqlite.TimestampFromTicks(42)
697
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100698 def test_binary(self):
Guido van Rossumbae07c92007-10-08 02:46:15 +0000699 b = sqlite.Binary(b"\0'")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000700
701class ExtensionTests(unittest.TestCase):
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100702 def test_script_string_sql(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000703 con = sqlite.connect(":memory:")
704 cur = con.cursor()
705 cur.executescript("""
706 -- bla bla
707 /* a stupid comment */
708 create table a(i);
709 insert into a(i) values (5);
710 """)
711 cur.execute("select i from a")
712 res = cur.fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000713 self.assertEqual(res, 5)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000714
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100715 def test_script_syntax_error(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000716 con = sqlite.connect(":memory:")
717 cur = con.cursor()
Berker Peksag1003b342016-06-12 22:34:49 +0300718 with self.assertRaises(sqlite.OperationalError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000719 cur.executescript("create table test(x); asdf; create table test2(x)")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000720
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100721 def test_script_error_normal(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000722 con = sqlite.connect(":memory:")
723 cur = con.cursor()
Berker Peksag1003b342016-06-12 22:34:49 +0300724 with self.assertRaises(sqlite.OperationalError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000725 cur.executescript("create table test(sadfsadfdsa); select foo from hurz;")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000726
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100727 def test_cursor_executescript_as_bytes(self):
Berker Peksagc4154402016-06-12 13:41:47 +0300728 con = sqlite.connect(":memory:")
729 cur = con.cursor()
730 with self.assertRaises(ValueError) as cm:
731 cur.executescript(b"create table test(foo); insert into test(foo) values (5);")
732 self.assertEqual(str(cm.exception), 'script argument must be unicode.')
733
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100734 def test_connection_execute(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000735 con = sqlite.connect(":memory:")
736 result = con.execute("select 5").fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000737 self.assertEqual(result, 5, "Basic test of Connection.execute")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000738
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100739 def test_connection_executemany(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000740 con = sqlite.connect(":memory:")
741 con.execute("create table test(foo)")
742 con.executemany("insert into test(foo) values (?)", [(3,), (4,)])
743 result = con.execute("select foo from test order by foo").fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000744 self.assertEqual(result[0][0], 3, "Basic test of Connection.executemany")
745 self.assertEqual(result[1][0], 4, "Basic test of Connection.executemany")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000746
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100747 def test_connection_executescript(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000748 con = sqlite.connect(":memory:")
749 con.executescript("create table test(foo); insert into test(foo) values (5);")
750 result = con.execute("select foo from test").fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000751 self.assertEqual(result, 5, "Basic test of Connection.executescript")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000752
Gerhard Häringf9cee222010-03-05 15:20:03 +0000753class ClosedConTests(unittest.TestCase):
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100754 def test_closed_con_cursor(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000755 con = sqlite.connect(":memory:")
756 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300757 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000758 cur = con.cursor()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000759
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100760 def test_closed_con_commit(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000761 con = sqlite.connect(":memory:")
762 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300763 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000764 con.commit()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000765
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100766 def test_closed_con_rollback(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000767 con = sqlite.connect(":memory:")
768 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300769 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000770 con.rollback()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000771
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100772 def test_closed_cur_execute(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000773 con = sqlite.connect(":memory:")
774 cur = con.cursor()
775 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300776 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000777 cur.execute("select 4")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000778
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100779 def test_closed_create_function(self):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000780 con = sqlite.connect(":memory:")
781 con.close()
782 def f(x): return 17
Berker Peksag1003b342016-06-12 22:34:49 +0300783 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000784 con.create_function("foo", 1, f)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000785
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100786 def test_closed_create_aggregate(self):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000787 con = sqlite.connect(":memory:")
788 con.close()
789 class Agg:
790 def __init__(self):
791 pass
792 def step(self, x):
793 pass
794 def finalize(self):
795 return 17
Berker Peksag1003b342016-06-12 22:34:49 +0300796 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000797 con.create_aggregate("foo", 1, Agg)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000798
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100799 def test_closed_set_authorizer(self):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000800 con = sqlite.connect(":memory:")
801 con.close()
802 def authorizer(*args):
803 return sqlite.DENY
Berker Peksag1003b342016-06-12 22:34:49 +0300804 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000805 con.set_authorizer(authorizer)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000806
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100807 def test_closed_set_progress_callback(self):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000808 con = sqlite.connect(":memory:")
809 con.close()
810 def progress(): pass
Berker Peksag1003b342016-06-12 22:34:49 +0300811 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000812 con.set_progress_handler(progress, 100)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000813
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100814 def test_closed_call(self):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000815 con = sqlite.connect(":memory:")
816 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300817 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000818 con()
Gerhard Häringf9cee222010-03-05 15:20:03 +0000819
820class ClosedCurTests(unittest.TestCase):
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100821 def test_closed(self):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000822 con = sqlite.connect(":memory:")
823 cur = con.cursor()
824 cur.close()
825
826 for method_name in ("execute", "executemany", "executescript", "fetchall", "fetchmany", "fetchone"):
827 if method_name in ("execute", "executescript"):
828 params = ("select 4 union select 5",)
829 elif method_name == "executemany":
830 params = ("insert into foo(bar) values (?)", [(3,), (4,)])
831 else:
832 params = []
833
Berker Peksag1003b342016-06-12 22:34:49 +0300834 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000835 method = getattr(cur, method_name)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000836 method(*params)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000837
Berker Peksag4bf580d2016-09-07 02:04:34 +0300838
839class SqliteOnConflictTests(unittest.TestCase):
840 """
841 Tests for SQLite's "insert on conflict" feature.
842
843 See https://www.sqlite.org/lang_conflict.html for details.
844 """
845
846 def setUp(self):
847 self.cx = sqlite.connect(":memory:")
848 self.cu = self.cx.cursor()
849 self.cu.execute("""
850 CREATE TABLE test(
851 id INTEGER PRIMARY KEY, name TEXT, unique_name TEXT UNIQUE
852 );
853 """)
854
855 def tearDown(self):
856 self.cu.close()
857 self.cx.close()
858
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100859 def test_on_conflict_rollback_with_explicit_transaction(self):
Berker Peksag4bf580d2016-09-07 02:04:34 +0300860 self.cx.isolation_level = None # autocommit mode
861 self.cu = self.cx.cursor()
862 # Start an explicit transaction.
863 self.cu.execute("BEGIN")
864 self.cu.execute("INSERT INTO test(name) VALUES ('abort_test')")
865 self.cu.execute("INSERT OR ROLLBACK INTO test(unique_name) VALUES ('foo')")
866 with self.assertRaises(sqlite.IntegrityError):
867 self.cu.execute("INSERT OR ROLLBACK INTO test(unique_name) VALUES ('foo')")
868 # Use connection to commit.
869 self.cx.commit()
870 self.cu.execute("SELECT name, unique_name from test")
871 # Transaction should have rolled back and nothing should be in table.
872 self.assertEqual(self.cu.fetchall(), [])
873
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100874 def test_on_conflict_abort_raises_with_explicit_transactions(self):
Berker Peksag4bf580d2016-09-07 02:04:34 +0300875 # Abort cancels the current sql statement but doesn't change anything
876 # about the current transaction.
877 self.cx.isolation_level = None # autocommit mode
878 self.cu = self.cx.cursor()
879 # Start an explicit transaction.
880 self.cu.execute("BEGIN")
881 self.cu.execute("INSERT INTO test(name) VALUES ('abort_test')")
882 self.cu.execute("INSERT OR ABORT INTO test(unique_name) VALUES ('foo')")
883 with self.assertRaises(sqlite.IntegrityError):
884 self.cu.execute("INSERT OR ABORT INTO test(unique_name) VALUES ('foo')")
885 self.cx.commit()
886 self.cu.execute("SELECT name, unique_name FROM test")
887 # Expect the first two inserts to work, third to do nothing.
888 self.assertEqual(self.cu.fetchall(), [('abort_test', None), (None, 'foo',)])
889
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100890 def test_on_conflict_rollback_without_transaction(self):
Berker Peksag4bf580d2016-09-07 02:04:34 +0300891 # Start of implicit transaction
892 self.cu.execute("INSERT INTO test(name) VALUES ('abort_test')")
893 self.cu.execute("INSERT OR ROLLBACK INTO test(unique_name) VALUES ('foo')")
894 with self.assertRaises(sqlite.IntegrityError):
895 self.cu.execute("INSERT OR ROLLBACK INTO test(unique_name) VALUES ('foo')")
896 self.cu.execute("SELECT name, unique_name FROM test")
897 # Implicit transaction is rolled back on error.
898 self.assertEqual(self.cu.fetchall(), [])
899
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100900 def test_on_conflict_abort_raises_without_transactions(self):
Berker Peksag4bf580d2016-09-07 02:04:34 +0300901 # Abort cancels the current sql statement but doesn't change anything
902 # about the current transaction.
903 self.cu.execute("INSERT INTO test(name) VALUES ('abort_test')")
904 self.cu.execute("INSERT OR ABORT INTO test(unique_name) VALUES ('foo')")
905 with self.assertRaises(sqlite.IntegrityError):
906 self.cu.execute("INSERT OR ABORT INTO test(unique_name) VALUES ('foo')")
907 # Make sure all other values were inserted.
908 self.cu.execute("SELECT name, unique_name FROM test")
909 self.assertEqual(self.cu.fetchall(), [('abort_test', None), (None, 'foo',)])
910
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100911 def test_on_conflict_fail(self):
Berker Peksag4bf580d2016-09-07 02:04:34 +0300912 self.cu.execute("INSERT OR FAIL INTO test(unique_name) VALUES ('foo')")
913 with self.assertRaises(sqlite.IntegrityError):
914 self.cu.execute("INSERT OR FAIL INTO test(unique_name) VALUES ('foo')")
915 self.assertEqual(self.cu.fetchall(), [])
916
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100917 def test_on_conflict_ignore(self):
Berker Peksag4bf580d2016-09-07 02:04:34 +0300918 self.cu.execute("INSERT OR IGNORE INTO test(unique_name) VALUES ('foo')")
919 # Nothing should happen.
920 self.cu.execute("INSERT OR IGNORE INTO test(unique_name) VALUES ('foo')")
921 self.cu.execute("SELECT unique_name FROM test")
922 self.assertEqual(self.cu.fetchall(), [('foo',)])
923
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100924 def test_on_conflict_replace(self):
Berker Peksag4bf580d2016-09-07 02:04:34 +0300925 self.cu.execute("INSERT OR REPLACE INTO test(name, unique_name) VALUES ('Data!', 'foo')")
926 # There shouldn't be an IntegrityError exception.
927 self.cu.execute("INSERT OR REPLACE INTO test(name, unique_name) VALUES ('Very different data!', 'foo')")
928 self.cu.execute("SELECT name, unique_name FROM test")
929 self.assertEqual(self.cu.fetchall(), [('Very different data!', 'foo')])
930
931
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000932def suite():
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100933 tests = [
934 ClosedConTests,
935 ClosedCurTests,
936 ConnectionTests,
937 ConstructorTests,
938 CursorTests,
939 ExtensionTests,
940 ModuleTests,
941 SqliteOnConflictTests,
942 ThreadTests,
943 ]
944 return unittest.TestSuite(
945 [unittest.TestLoader().loadTestsFromTestCase(t) for t in tests]
946 )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000947
948def test():
949 runner = unittest.TextTestRunner()
950 runner.run(suite())
951
952if __name__ == "__main__":
953 test()