blob: 7985cd3fcf9142e13a9fab16798f50e2579b167a [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/dbapi.py: tests for DB-API compliance
3#
Gerhard Häringf9cee222010-03-05 15:20:03 +00004# Copyright (C) 2004-2010 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
Antoine Pitroua6a4dc82017-09-07 18:56:24 +020024import threading
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000025import unittest
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000026import sqlite3 as sqlite
27
Hai Shifcce8c62020-08-08 05:55:35 +080028from test.support.os_helper import TESTFN, unlink
Antoine Pitrou902fc8b2013-02-10 00:02:44 +010029
30
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000031class ModuleTests(unittest.TestCase):
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010032 def test_api_level(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000033 self.assertEqual(sqlite.apilevel, "2.0",
34 "apilevel is %s, should be 2.0" % sqlite.apilevel)
35
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010036 def test_thread_safety(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000037 self.assertEqual(sqlite.threadsafety, 1,
38 "threadsafety is %d, should be 1" % sqlite.threadsafety)
39
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010040 def test_param_style(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000041 self.assertEqual(sqlite.paramstyle, "qmark",
42 "paramstyle is '%s', should be 'qmark'" %
43 sqlite.paramstyle)
44
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010045 def test_warning(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +000046 self.assertTrue(issubclass(sqlite.Warning, Exception),
Guido van Rossumcd16bf62007-06-13 18:07:49 +000047 "Warning is not a subclass of Exception")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000048
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010049 def test_error(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000050 self.assertTrue(issubclass(sqlite.Error, Exception),
Guido van Rossumcd16bf62007-06-13 18:07:49 +000051 "Error is not a subclass of Exception")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000052
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010053 def test_interface_error(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000054 self.assertTrue(issubclass(sqlite.InterfaceError, sqlite.Error),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000055 "InterfaceError is not a subclass of Error")
56
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010057 def test_database_error(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000058 self.assertTrue(issubclass(sqlite.DatabaseError, sqlite.Error),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000059 "DatabaseError is not a subclass of Error")
60
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010061 def test_data_error(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000062 self.assertTrue(issubclass(sqlite.DataError, sqlite.DatabaseError),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000063 "DataError is not a subclass of DatabaseError")
64
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010065 def test_operational_error(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000066 self.assertTrue(issubclass(sqlite.OperationalError, sqlite.DatabaseError),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000067 "OperationalError is not a subclass of DatabaseError")
68
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010069 def test_integrity_error(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000070 self.assertTrue(issubclass(sqlite.IntegrityError, sqlite.DatabaseError),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000071 "IntegrityError is not a subclass of DatabaseError")
72
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010073 def test_internal_error(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000074 self.assertTrue(issubclass(sqlite.InternalError, sqlite.DatabaseError),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000075 "InternalError is not a subclass of DatabaseError")
76
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010077 def test_programming_error(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000078 self.assertTrue(issubclass(sqlite.ProgrammingError, sqlite.DatabaseError),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000079 "ProgrammingError is not a subclass of DatabaseError")
80
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010081 def test_not_supported_error(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000082 self.assertTrue(issubclass(sqlite.NotSupportedError,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000083 sqlite.DatabaseError),
84 "NotSupportedError is not a subclass of DatabaseError")
85
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010086 def test_shared_cache_deprecated(self):
Erlend Egeberg Aaslandddb5e112021-01-06 01:36:04 +010087 for enable in (True, False):
88 with self.assertWarns(DeprecationWarning) as cm:
89 sqlite.enable_shared_cache(enable)
90 self.assertIn("dbapi.py", cm.filename)
91
92
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000093class ConnectionTests(unittest.TestCase):
R. David Murrayd35251d2010-06-01 01:32:12 +000094
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000095 def setUp(self):
96 self.cx = sqlite.connect(":memory:")
97 cu = self.cx.cursor()
98 cu.execute("create table test(id integer primary key, name text)")
99 cu.execute("insert into test(name) values (?)", ("foo",))
100
101 def tearDown(self):
102 self.cx.close()
103
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100104 def test_commit(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000105 self.cx.commit()
106
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100107 def test_commit_after_no_changes(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000108 """
109 A commit should also work when no changes were made to the database.
110 """
111 self.cx.commit()
112 self.cx.commit()
113
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100114 def test_rollback(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000115 self.cx.rollback()
116
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100117 def test_rollback_after_no_changes(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000118 """
119 A rollback should also work when no changes were made to the database.
120 """
121 self.cx.rollback()
122 self.cx.rollback()
123
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100124 def test_cursor(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000125 cu = self.cx.cursor()
126
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100127 def test_failed_open(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000128 YOU_CANNOT_OPEN_THIS = "/foo/bar/bla/23534/mydb.db"
Berker Peksag1003b342016-06-12 22:34:49 +0300129 with self.assertRaises(sqlite.OperationalError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000130 con = sqlite.connect(YOU_CANNOT_OPEN_THIS)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000131
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100132 def test_close(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000133 self.cx.close()
134
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100135 def test_exceptions(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000136 # Optional DB-API extension.
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000137 self.assertEqual(self.cx.Warning, sqlite.Warning)
138 self.assertEqual(self.cx.Error, sqlite.Error)
139 self.assertEqual(self.cx.InterfaceError, sqlite.InterfaceError)
140 self.assertEqual(self.cx.DatabaseError, sqlite.DatabaseError)
141 self.assertEqual(self.cx.DataError, sqlite.DataError)
142 self.assertEqual(self.cx.OperationalError, sqlite.OperationalError)
143 self.assertEqual(self.cx.IntegrityError, sqlite.IntegrityError)
144 self.assertEqual(self.cx.InternalError, sqlite.InternalError)
145 self.assertEqual(self.cx.ProgrammingError, sqlite.ProgrammingError)
146 self.assertEqual(self.cx.NotSupportedError, sqlite.NotSupportedError)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000147
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100148 def test_in_transaction(self):
R. David Murrayd35251d2010-06-01 01:32:12 +0000149 # Can't use db from setUp because we want to test initial state.
150 cx = sqlite.connect(":memory:")
151 cu = cx.cursor()
152 self.assertEqual(cx.in_transaction, False)
153 cu.execute("create table transactiontest(id integer primary key, name text)")
154 self.assertEqual(cx.in_transaction, False)
155 cu.execute("insert into transactiontest(name) values (?)", ("foo",))
156 self.assertEqual(cx.in_transaction, True)
157 cu.execute("select name from transactiontest where name=?", ["foo"])
158 row = cu.fetchone()
159 self.assertEqual(cx.in_transaction, True)
160 cx.commit()
161 self.assertEqual(cx.in_transaction, False)
162 cu.execute("select name from transactiontest where name=?", ["foo"])
163 row = cu.fetchone()
164 self.assertEqual(cx.in_transaction, False)
165
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100166 def test_in_transaction_ro(self):
R. David Murrayd35251d2010-06-01 01:32:12 +0000167 with self.assertRaises(AttributeError):
168 self.cx.in_transaction = True
169
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100170 def test_open_with_path_like_object(self):
Ville Skyttä61f82e02018-04-20 23:08:45 +0300171 """ Checks that we can successfully connect to a database using an object that
Anders Lorentsena22a1272017-11-07 01:47:43 +0100172 is PathLike, i.e. has __fspath__(). """
173 self.addCleanup(unlink, TESTFN)
174 class Path:
175 def __fspath__(self):
176 return TESTFN
177 path = Path()
178 with sqlite.connect(path) as cx:
179 cx.execute('create table test(id integer)')
180
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100181 def test_open_uri(self):
Antoine Pitrou902fc8b2013-02-10 00:02:44 +0100182 self.addCleanup(unlink, TESTFN)
183 with sqlite.connect(TESTFN) as cx:
184 cx.execute('create table test(id integer)')
185 with sqlite.connect('file:' + TESTFN, uri=True) as cx:
186 cx.execute('insert into test(id) values(0)')
187 with sqlite.connect('file:' + TESTFN + '?mode=ro', uri=True) as cx:
188 with self.assertRaises(sqlite.OperationalError):
189 cx.execute('insert into test(id) values(1)')
190
191
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000192class CursorTests(unittest.TestCase):
193 def setUp(self):
194 self.cx = sqlite.connect(":memory:")
195 self.cu = self.cx.cursor()
Berker Peksage0b70cd2016-06-14 15:25:36 +0300196 self.cu.execute(
197 "create table test(id integer primary key, name text, "
198 "income number, unique_test text unique)"
199 )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000200 self.cu.execute("insert into test(name) values (?)", ("foo",))
201
202 def tearDown(self):
203 self.cu.close()
204 self.cx.close()
205
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100206 def test_execute_no_args(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000207 self.cu.execute("delete from test")
208
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100209 def test_execute_illegal_sql(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300210 with self.assertRaises(sqlite.OperationalError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000211 self.cu.execute("select asdf")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000212
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100213 def test_execute_too_much_sql(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300214 with self.assertRaises(sqlite.Warning):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000215 self.cu.execute("select 5+4; select 4+5")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000216
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100217 def test_execute_too_much_sql2(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000218 self.cu.execute("select 5+4; -- foo bar")
219
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100220 def test_execute_too_much_sql3(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000221 self.cu.execute("""
222 select 5+4;
223
224 /*
225 foo
226 */
227 """)
228
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100229 def test_execute_wrong_sql_arg(self):
Victor Stinnerc6a23202019-06-26 03:16:24 +0200230 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000231 self.cu.execute(42)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000232
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100233 def test_execute_arg_int(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000234 self.cu.execute("insert into test(id) values (?)", (42,))
235
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100236 def test_execute_arg_float(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000237 self.cu.execute("insert into test(income) values (?)", (2500.32,))
238
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100239 def test_execute_arg_string(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000240 self.cu.execute("insert into test(name) values (?)", ("Hugo",))
241
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100242 def test_execute_arg_string_with_zero_byte(self):
Petri Lehtinen023fe332012-02-01 22:18:19 +0200243 self.cu.execute("insert into test(name) values (?)", ("Hu\x00go",))
244
245 self.cu.execute("select name from test where id=?", (self.cu.lastrowid,))
246 row = self.cu.fetchone()
247 self.assertEqual(row[0], "Hu\x00go")
248
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100249 def test_execute_non_iterable(self):
Berker Peksagc4154402016-06-12 13:41:47 +0300250 with self.assertRaises(ValueError) as cm:
251 self.cu.execute("insert into test(id) values (?)", 42)
252 self.assertEqual(str(cm.exception), 'parameters are of unsupported type')
253
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100254 def test_execute_wrong_no_of_args1(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000255 # too many parameters
Berker Peksag1003b342016-06-12 22:34:49 +0300256 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000257 self.cu.execute("insert into test(id) values (?)", (17, "Egon"))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000258
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100259 def test_execute_wrong_no_of_args2(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000260 # too little parameters
Berker Peksag1003b342016-06-12 22:34:49 +0300261 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000262 self.cu.execute("insert into test(id) values (?)")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000263
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100264 def test_execute_wrong_no_of_args3(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000265 # no parameters, parameters are needed
Berker Peksag1003b342016-06-12 22:34:49 +0300266 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000267 self.cu.execute("insert into test(id) values (?)")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000268
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100269 def test_execute_param_list(self):
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000270 self.cu.execute("insert into test(name) values ('foo')")
271 self.cu.execute("select name from test where name=?", ["foo"])
272 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000273 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000274
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100275 def test_execute_param_sequence(self):
Serhiy Storchaka0b419b72020-09-17 10:35:44 +0300276 class L:
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000277 def __len__(self):
278 return 1
279 def __getitem__(self, x):
280 assert x == 0
281 return "foo"
282
283 self.cu.execute("insert into test(name) values ('foo')")
284 self.cu.execute("select name from test where name=?", L())
285 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000286 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000287
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100288 def test_execute_param_sequence_bad_len(self):
Serhiy Storchaka0b419b72020-09-17 10:35:44 +0300289 # Issue41662: Error in __len__() was overridden with ProgrammingError.
290 class L:
291 def __len__(self):
292 1/0
293 def __getitem__(slf, x):
294 raise AssertionError
295
296 self.cu.execute("insert into test(name) values ('foo')")
297 with self.assertRaises(ZeroDivisionError):
298 self.cu.execute("select name from test where name=?", L())
299
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100300 def test_execute_dict_mapping(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000301 self.cu.execute("insert into test(name) values ('foo')")
302 self.cu.execute("select name from test where name=:name", {"name": "foo"})
303 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000304 self.assertEqual(row[0], "foo")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000305
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100306 def test_execute_dict_mapping_mapping(self):
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000307 class D(dict):
308 def __missing__(self, key):
309 return "foo"
310
311 self.cu.execute("insert into test(name) values ('foo')")
312 self.cu.execute("select name from test where name=:name", D())
313 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000314 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000315
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100316 def test_execute_dict_mapping_too_little_args(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000317 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag1003b342016-06-12 22:34:49 +0300318 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000319 self.cu.execute("select name from test where name=:name and id=:id", {"name": "foo"})
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000320
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100321 def test_execute_dict_mapping_no_args(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000322 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag1003b342016-06-12 22:34:49 +0300323 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000324 self.cu.execute("select name from test where name=:name")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000325
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100326 def test_execute_dict_mapping_unnamed(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000327 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag1003b342016-06-12 22:34:49 +0300328 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000329 self.cu.execute("select name from test where name=?", {"name": "foo"})
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000330
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100331 def test_close(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000332 self.cu.close()
333
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100334 def test_rowcount_execute(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000335 self.cu.execute("delete from test")
336 self.cu.execute("insert into test(name) values ('foo')")
337 self.cu.execute("insert into test(name) values ('foo')")
338 self.cu.execute("update test set name='bar'")
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000339 self.assertEqual(self.cu.rowcount, 2)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000340
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100341 def test_rowcount_select(self):
Georg Brandlf78e02b2008-06-10 17:40:04 +0000342 """
343 pysqlite does not know the rowcount of SELECT statements, because we
344 don't fetch all rows after executing the select statement. The rowcount
345 has thus to be -1.
346 """
347 self.cu.execute("select 5 union select 6")
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000348 self.assertEqual(self.cu.rowcount, -1)
Georg Brandlf78e02b2008-06-10 17:40:04 +0000349
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100350 def test_rowcount_executemany(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000351 self.cu.execute("delete from test")
352 self.cu.executemany("insert into test(name) values (?)", [(1,), (2,), (3,)])
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000353 self.assertEqual(self.cu.rowcount, 3)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000354
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100355 def test_total_changes(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000356 self.cu.execute("insert into test(name) values ('foo')")
357 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag48b5c982016-06-14 00:42:50 +0300358 self.assertLess(2, self.cx.total_changes, msg='total changes reported wrong value')
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000359
360 # Checks for executemany:
361 # Sequences are required by the DB-API, iterators
362 # enhancements in pysqlite.
363
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100364 def test_execute_many_sequence(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000365 self.cu.executemany("insert into test(income) values (?)", [(x,) for x in range(100, 110)])
366
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100367 def test_execute_many_iterator(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000368 class MyIter:
369 def __init__(self):
370 self.value = 5
371
Georg Brandla18af4e2007-04-21 15:47:16 +0000372 def __next__(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000373 if self.value == 10:
374 raise StopIteration
375 else:
376 self.value += 1
377 return (self.value,)
378
379 self.cu.executemany("insert into test(income) values (?)", MyIter())
380
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100381 def test_execute_many_generator(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000382 def mygen():
383 for i in range(5):
384 yield (i,)
385
386 self.cu.executemany("insert into test(income) values (?)", mygen())
387
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100388 def test_execute_many_wrong_sql_arg(self):
Victor Stinnerc6a23202019-06-26 03:16:24 +0200389 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000390 self.cu.executemany(42, [(3,)])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000391
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100392 def test_execute_many_select(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300393 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000394 self.cu.executemany("select ?", [(3,)])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000395
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100396 def test_execute_many_not_iterable(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300397 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000398 self.cu.executemany("insert into test(income) values (?)", 42)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000399
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100400 def test_fetch_iter(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000401 # Optional DB-API extension.
402 self.cu.execute("delete from test")
403 self.cu.execute("insert into test(id) values (?)", (5,))
404 self.cu.execute("insert into test(id) values (?)", (6,))
405 self.cu.execute("select id from test order by id")
406 lst = []
407 for row in self.cu:
408 lst.append(row[0])
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000409 self.assertEqual(lst[0], 5)
410 self.assertEqual(lst[1], 6)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000411
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100412 def test_fetchone(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000413 self.cu.execute("select name from test")
414 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000415 self.assertEqual(row[0], "foo")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000416 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000417 self.assertEqual(row, None)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000418
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100419 def test_fetchone_no_statement(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000420 cur = self.cx.cursor()
421 row = cur.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000422 self.assertEqual(row, None)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000423
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100424 def test_array_size(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000425 # must default ot 1
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000426 self.assertEqual(self.cu.arraysize, 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000427
428 # now set to 2
429 self.cu.arraysize = 2
430
431 # now make the query return 3 rows
432 self.cu.execute("delete from test")
433 self.cu.execute("insert into test(name) values ('A')")
434 self.cu.execute("insert into test(name) values ('B')")
435 self.cu.execute("insert into test(name) values ('C')")
436 self.cu.execute("select name from test")
437 res = self.cu.fetchmany()
438
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000439 self.assertEqual(len(res), 2)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000440
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100441 def test_fetchmany(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000442 self.cu.execute("select name from test")
443 res = self.cu.fetchmany(100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000444 self.assertEqual(len(res), 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000445 res = self.cu.fetchmany(100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000446 self.assertEqual(res, [])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000447
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100448 def test_fetchmany_kw_arg(self):
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000449 """Checks if fetchmany works with keyword arguments"""
450 self.cu.execute("select name from test")
451 res = self.cu.fetchmany(size=100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000452 self.assertEqual(len(res), 1)
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000453
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100454 def test_fetchall(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000455 self.cu.execute("select name from test")
456 res = self.cu.fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000457 self.assertEqual(len(res), 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000458 res = self.cu.fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000459 self.assertEqual(res, [])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000460
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100461 def test_setinputsizes(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000462 self.cu.setinputsizes([3, 4, 5])
463
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100464 def test_setoutputsize(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000465 self.cu.setoutputsize(5, 0)
466
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100467 def test_setoutputsize_no_column(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000468 self.cu.setoutputsize(42)
469
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100470 def test_cursor_connection(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000471 # Optional DB-API extension.
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000472 self.assertEqual(self.cu.connection, self.cx)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000473
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100474 def test_wrong_cursor_callable(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300475 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000476 def f(): pass
477 cur = self.cx.cursor(f)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000478
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100479 def test_cursor_wrong_class(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000480 class Foo: pass
481 foo = Foo()
Berker Peksag1003b342016-06-12 22:34:49 +0300482 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000483 cur = sqlite.Cursor(foo)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000484
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100485 def test_last_row_id_on_replace(self):
Berker Peksage0b70cd2016-06-14 15:25:36 +0300486 """
487 INSERT OR REPLACE and REPLACE INTO should produce the same behavior.
488 """
489 sql = '{} INTO test(id, unique_test) VALUES (?, ?)'
490 for statement in ('INSERT OR REPLACE', 'REPLACE'):
491 with self.subTest(statement=statement):
492 self.cu.execute(sql.format(statement), (1, 'foo'))
493 self.assertEqual(self.cu.lastrowid, 1)
494
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100495 def test_last_row_id_on_ignore(self):
Berker Peksage0b70cd2016-06-14 15:25:36 +0300496 self.cu.execute(
497 "insert or ignore into test(unique_test) values (?)",
498 ('test',))
499 self.assertEqual(self.cu.lastrowid, 2)
500 self.cu.execute(
501 "insert or ignore into test(unique_test) values (?)",
502 ('test',))
503 self.assertEqual(self.cu.lastrowid, 2)
504
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100505 def test_last_row_id_insert_o_r(self):
Berker Peksage0b70cd2016-06-14 15:25:36 +0300506 results = []
507 for statement in ('FAIL', 'ABORT', 'ROLLBACK'):
508 sql = 'INSERT OR {} INTO test(unique_test) VALUES (?)'
509 with self.subTest(statement='INSERT OR {}'.format(statement)):
510 self.cu.execute(sql.format(statement), (statement,))
511 results.append((statement, self.cu.lastrowid))
512 with self.assertRaises(sqlite.IntegrityError):
513 self.cu.execute(sql.format(statement), (statement,))
514 results.append((statement, self.cu.lastrowid))
515 expected = [
516 ('FAIL', 2), ('FAIL', 2),
517 ('ABORT', 3), ('ABORT', 3),
518 ('ROLLBACK', 4), ('ROLLBACK', 4),
519 ]
520 self.assertEqual(results, expected)
521
522
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000523class ThreadTests(unittest.TestCase):
524 def setUp(self):
525 self.con = sqlite.connect(":memory:")
526 self.cur = self.con.cursor()
527 self.cur.execute("create table test(id integer primary key, name text, bin binary, ratio number, ts timestamp)")
528
529 def tearDown(self):
530 self.cur.close()
531 self.con.close()
532
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100533 def test_con_cursor(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000534 def run(con, errors):
535 try:
536 cur = con.cursor()
537 errors.append("did not raise ProgrammingError")
538 return
539 except sqlite.ProgrammingError:
540 return
541 except:
542 errors.append("raised wrong exception")
543
544 errors = []
545 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
546 t.start()
547 t.join()
548 if len(errors) > 0:
549 self.fail("\n".join(errors))
550
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100551 def test_con_commit(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000552 def run(con, errors):
553 try:
554 con.commit()
555 errors.append("did not raise ProgrammingError")
556 return
557 except sqlite.ProgrammingError:
558 return
559 except:
560 errors.append("raised wrong exception")
561
562 errors = []
563 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
564 t.start()
565 t.join()
566 if len(errors) > 0:
567 self.fail("\n".join(errors))
568
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100569 def test_con_rollback(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000570 def run(con, errors):
571 try:
572 con.rollback()
573 errors.append("did not raise ProgrammingError")
574 return
575 except sqlite.ProgrammingError:
576 return
577 except:
578 errors.append("raised wrong exception")
579
580 errors = []
581 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
582 t.start()
583 t.join()
584 if len(errors) > 0:
585 self.fail("\n".join(errors))
586
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100587 def test_con_close(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000588 def run(con, errors):
589 try:
590 con.close()
591 errors.append("did not raise ProgrammingError")
592 return
593 except sqlite.ProgrammingError:
594 return
595 except:
596 errors.append("raised wrong exception")
597
598 errors = []
599 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
600 t.start()
601 t.join()
602 if len(errors) > 0:
603 self.fail("\n".join(errors))
604
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100605 def test_cur_implicit_begin(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000606 def run(cur, errors):
607 try:
608 cur.execute("insert into test(name) values ('a')")
609 errors.append("did not raise ProgrammingError")
610 return
611 except sqlite.ProgrammingError:
612 return
613 except:
614 errors.append("raised wrong exception")
615
616 errors = []
617 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
618 t.start()
619 t.join()
620 if len(errors) > 0:
621 self.fail("\n".join(errors))
622
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100623 def test_cur_close(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000624 def run(cur, errors):
625 try:
626 cur.close()
627 errors.append("did not raise ProgrammingError")
628 return
629 except sqlite.ProgrammingError:
630 return
631 except:
632 errors.append("raised wrong exception")
633
634 errors = []
635 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
636 t.start()
637 t.join()
638 if len(errors) > 0:
639 self.fail("\n".join(errors))
640
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100641 def test_cur_execute(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000642 def run(cur, errors):
643 try:
644 cur.execute("select name from test")
645 errors.append("did not raise ProgrammingError")
646 return
647 except sqlite.ProgrammingError:
648 return
649 except:
650 errors.append("raised wrong exception")
651
652 errors = []
653 self.cur.execute("insert into test(name) values ('a')")
654 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
655 t.start()
656 t.join()
657 if len(errors) > 0:
658 self.fail("\n".join(errors))
659
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100660 def test_cur_iter_next(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000661 def run(cur, errors):
662 try:
663 row = cur.fetchone()
664 errors.append("did not raise ProgrammingError")
665 return
666 except sqlite.ProgrammingError:
667 return
668 except:
669 errors.append("raised wrong exception")
670
671 errors = []
672 self.cur.execute("insert into test(name) values ('a')")
673 self.cur.execute("select name from test")
674 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
675 t.start()
676 t.join()
677 if len(errors) > 0:
678 self.fail("\n".join(errors))
679
680class ConstructorTests(unittest.TestCase):
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100681 def test_date(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000682 d = sqlite.Date(2004, 10, 28)
683
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100684 def test_time(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000685 t = sqlite.Time(12, 39, 35)
686
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100687 def test_timestamp(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000688 ts = sqlite.Timestamp(2004, 10, 28, 12, 39, 35)
689
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100690 def test_date_from_ticks(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000691 d = sqlite.DateFromTicks(42)
692
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100693 def test_time_from_ticks(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000694 t = sqlite.TimeFromTicks(42)
695
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100696 def test_timestamp_from_ticks(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000697 ts = sqlite.TimestampFromTicks(42)
698
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100699 def test_binary(self):
Guido van Rossumbae07c92007-10-08 02:46:15 +0000700 b = sqlite.Binary(b"\0'")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000701
702class ExtensionTests(unittest.TestCase):
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100703 def test_script_string_sql(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000704 con = sqlite.connect(":memory:")
705 cur = con.cursor()
706 cur.executescript("""
707 -- bla bla
708 /* a stupid comment */
709 create table a(i);
710 insert into a(i) values (5);
711 """)
712 cur.execute("select i from a")
713 res = cur.fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000714 self.assertEqual(res, 5)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000715
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100716 def test_script_syntax_error(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000717 con = sqlite.connect(":memory:")
718 cur = con.cursor()
Berker Peksag1003b342016-06-12 22:34:49 +0300719 with self.assertRaises(sqlite.OperationalError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000720 cur.executescript("create table test(x); asdf; create table test2(x)")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000721
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100722 def test_script_error_normal(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000723 con = sqlite.connect(":memory:")
724 cur = con.cursor()
Berker Peksag1003b342016-06-12 22:34:49 +0300725 with self.assertRaises(sqlite.OperationalError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000726 cur.executescript("create table test(sadfsadfdsa); select foo from hurz;")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000727
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100728 def test_cursor_executescript_as_bytes(self):
Berker Peksagc4154402016-06-12 13:41:47 +0300729 con = sqlite.connect(":memory:")
730 cur = con.cursor()
731 with self.assertRaises(ValueError) as cm:
732 cur.executescript(b"create table test(foo); insert into test(foo) values (5);")
733 self.assertEqual(str(cm.exception), 'script argument must be unicode.')
734
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100735 def test_connection_execute(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000736 con = sqlite.connect(":memory:")
737 result = con.execute("select 5").fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000738 self.assertEqual(result, 5, "Basic test of Connection.execute")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000739
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100740 def test_connection_executemany(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000741 con = sqlite.connect(":memory:")
742 con.execute("create table test(foo)")
743 con.executemany("insert into test(foo) values (?)", [(3,), (4,)])
744 result = con.execute("select foo from test order by foo").fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000745 self.assertEqual(result[0][0], 3, "Basic test of Connection.executemany")
746 self.assertEqual(result[1][0], 4, "Basic test of Connection.executemany")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000747
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100748 def test_connection_executescript(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000749 con = sqlite.connect(":memory:")
750 con.executescript("create table test(foo); insert into test(foo) values (5);")
751 result = con.execute("select foo from test").fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000752 self.assertEqual(result, 5, "Basic test of Connection.executescript")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000753
Gerhard Häringf9cee222010-03-05 15:20:03 +0000754class ClosedConTests(unittest.TestCase):
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100755 def test_closed_con_cursor(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000756 con = sqlite.connect(":memory:")
757 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300758 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000759 cur = con.cursor()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000760
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100761 def test_closed_con_commit(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000762 con = sqlite.connect(":memory:")
763 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300764 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000765 con.commit()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000766
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100767 def test_closed_con_rollback(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000768 con = sqlite.connect(":memory:")
769 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300770 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000771 con.rollback()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000772
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100773 def test_closed_cur_execute(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000774 con = sqlite.connect(":memory:")
775 cur = con.cursor()
776 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300777 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000778 cur.execute("select 4")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000779
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100780 def test_closed_create_function(self):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000781 con = sqlite.connect(":memory:")
782 con.close()
783 def f(x): return 17
Berker Peksag1003b342016-06-12 22:34:49 +0300784 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000785 con.create_function("foo", 1, f)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000786
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100787 def test_closed_create_aggregate(self):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000788 con = sqlite.connect(":memory:")
789 con.close()
790 class Agg:
791 def __init__(self):
792 pass
793 def step(self, x):
794 pass
795 def finalize(self):
796 return 17
Berker Peksag1003b342016-06-12 22:34:49 +0300797 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000798 con.create_aggregate("foo", 1, Agg)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000799
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100800 def test_closed_set_authorizer(self):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000801 con = sqlite.connect(":memory:")
802 con.close()
803 def authorizer(*args):
804 return sqlite.DENY
Berker Peksag1003b342016-06-12 22:34:49 +0300805 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000806 con.set_authorizer(authorizer)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000807
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100808 def test_closed_set_progress_callback(self):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000809 con = sqlite.connect(":memory:")
810 con.close()
811 def progress(): pass
Berker Peksag1003b342016-06-12 22:34:49 +0300812 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000813 con.set_progress_handler(progress, 100)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000814
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100815 def test_closed_call(self):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000816 con = sqlite.connect(":memory:")
817 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300818 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000819 con()
Gerhard Häringf9cee222010-03-05 15:20:03 +0000820
821class ClosedCurTests(unittest.TestCase):
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100822 def test_closed(self):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000823 con = sqlite.connect(":memory:")
824 cur = con.cursor()
825 cur.close()
826
827 for method_name in ("execute", "executemany", "executescript", "fetchall", "fetchmany", "fetchone"):
828 if method_name in ("execute", "executescript"):
829 params = ("select 4 union select 5",)
830 elif method_name == "executemany":
831 params = ("insert into foo(bar) values (?)", [(3,), (4,)])
832 else:
833 params = []
834
Berker Peksag1003b342016-06-12 22:34:49 +0300835 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000836 method = getattr(cur, method_name)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000837 method(*params)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000838
Berker Peksag4bf580d2016-09-07 02:04:34 +0300839
840class SqliteOnConflictTests(unittest.TestCase):
841 """
842 Tests for SQLite's "insert on conflict" feature.
843
844 See https://www.sqlite.org/lang_conflict.html for details.
845 """
846
847 def setUp(self):
848 self.cx = sqlite.connect(":memory:")
849 self.cu = self.cx.cursor()
850 self.cu.execute("""
851 CREATE TABLE test(
852 id INTEGER PRIMARY KEY, name TEXT, unique_name TEXT UNIQUE
853 );
854 """)
855
856 def tearDown(self):
857 self.cu.close()
858 self.cx.close()
859
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100860 def test_on_conflict_rollback_with_explicit_transaction(self):
Berker Peksag4bf580d2016-09-07 02:04:34 +0300861 self.cx.isolation_level = None # autocommit mode
862 self.cu = self.cx.cursor()
863 # Start an explicit transaction.
864 self.cu.execute("BEGIN")
865 self.cu.execute("INSERT INTO test(name) VALUES ('abort_test')")
866 self.cu.execute("INSERT OR ROLLBACK INTO test(unique_name) VALUES ('foo')")
867 with self.assertRaises(sqlite.IntegrityError):
868 self.cu.execute("INSERT OR ROLLBACK INTO test(unique_name) VALUES ('foo')")
869 # Use connection to commit.
870 self.cx.commit()
871 self.cu.execute("SELECT name, unique_name from test")
872 # Transaction should have rolled back and nothing should be in table.
873 self.assertEqual(self.cu.fetchall(), [])
874
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100875 def test_on_conflict_abort_raises_with_explicit_transactions(self):
Berker Peksag4bf580d2016-09-07 02:04:34 +0300876 # Abort cancels the current sql statement but doesn't change anything
877 # about the current transaction.
878 self.cx.isolation_level = None # autocommit mode
879 self.cu = self.cx.cursor()
880 # Start an explicit transaction.
881 self.cu.execute("BEGIN")
882 self.cu.execute("INSERT INTO test(name) VALUES ('abort_test')")
883 self.cu.execute("INSERT OR ABORT INTO test(unique_name) VALUES ('foo')")
884 with self.assertRaises(sqlite.IntegrityError):
885 self.cu.execute("INSERT OR ABORT INTO test(unique_name) VALUES ('foo')")
886 self.cx.commit()
887 self.cu.execute("SELECT name, unique_name FROM test")
888 # Expect the first two inserts to work, third to do nothing.
889 self.assertEqual(self.cu.fetchall(), [('abort_test', None), (None, 'foo',)])
890
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100891 def test_on_conflict_rollback_without_transaction(self):
Berker Peksag4bf580d2016-09-07 02:04:34 +0300892 # Start of implicit transaction
893 self.cu.execute("INSERT INTO test(name) VALUES ('abort_test')")
894 self.cu.execute("INSERT OR ROLLBACK INTO test(unique_name) VALUES ('foo')")
895 with self.assertRaises(sqlite.IntegrityError):
896 self.cu.execute("INSERT OR ROLLBACK INTO test(unique_name) VALUES ('foo')")
897 self.cu.execute("SELECT name, unique_name FROM test")
898 # Implicit transaction is rolled back on error.
899 self.assertEqual(self.cu.fetchall(), [])
900
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100901 def test_on_conflict_abort_raises_without_transactions(self):
Berker Peksag4bf580d2016-09-07 02:04:34 +0300902 # Abort cancels the current sql statement but doesn't change anything
903 # about the current transaction.
904 self.cu.execute("INSERT INTO test(name) VALUES ('abort_test')")
905 self.cu.execute("INSERT OR ABORT INTO test(unique_name) VALUES ('foo')")
906 with self.assertRaises(sqlite.IntegrityError):
907 self.cu.execute("INSERT OR ABORT INTO test(unique_name) VALUES ('foo')")
908 # Make sure all other values were inserted.
909 self.cu.execute("SELECT name, unique_name FROM test")
910 self.assertEqual(self.cu.fetchall(), [('abort_test', None), (None, 'foo',)])
911
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100912 def test_on_conflict_fail(self):
Berker Peksag4bf580d2016-09-07 02:04:34 +0300913 self.cu.execute("INSERT OR FAIL INTO test(unique_name) VALUES ('foo')")
914 with self.assertRaises(sqlite.IntegrityError):
915 self.cu.execute("INSERT OR FAIL INTO test(unique_name) VALUES ('foo')")
916 self.assertEqual(self.cu.fetchall(), [])
917
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100918 def test_on_conflict_ignore(self):
Berker Peksag4bf580d2016-09-07 02:04:34 +0300919 self.cu.execute("INSERT OR IGNORE INTO test(unique_name) VALUES ('foo')")
920 # Nothing should happen.
921 self.cu.execute("INSERT OR IGNORE INTO test(unique_name) VALUES ('foo')")
922 self.cu.execute("SELECT unique_name FROM test")
923 self.assertEqual(self.cu.fetchall(), [('foo',)])
924
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100925 def test_on_conflict_replace(self):
Berker Peksag4bf580d2016-09-07 02:04:34 +0300926 self.cu.execute("INSERT OR REPLACE INTO test(name, unique_name) VALUES ('Data!', 'foo')")
927 # There shouldn't be an IntegrityError exception.
928 self.cu.execute("INSERT OR REPLACE INTO test(name, unique_name) VALUES ('Very different data!', 'foo')")
929 self.cu.execute("SELECT name, unique_name FROM test")
930 self.assertEqual(self.cu.fetchall(), [('Very different data!', 'foo')])
931
932
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000933def suite():
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100934 tests = [
935 ClosedConTests,
936 ClosedCurTests,
937 ConnectionTests,
938 ConstructorTests,
939 CursorTests,
940 ExtensionTests,
941 ModuleTests,
942 SqliteOnConflictTests,
943 ThreadTests,
944 ]
945 return unittest.TestSuite(
946 [unittest.TestLoader().loadTestsFromTestCase(t) for t in tests]
947 )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000948
949def test():
950 runner = unittest.TextTestRunner()
951 runner.run(suite())
952
953if __name__ == "__main__":
954 test()