blob: 0716e656a7f26f60cea1a32e3ae10f4e0f03cfcc [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
Erlend Egeberg Aaslandd16f6172021-01-09 12:25:55 +010026import sys
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000027
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 Aaslandd16f6172021-01-09 12:25:55 +010086 # sqlite3_enable_shared_cache() is deprecated on macOS and calling it may raise
87 # OperationalError on some buildbots.
88 @unittest.skipIf(sys.platform == "darwin", "shared cache is deprecated on macOS")
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +010089 def test_shared_cache_deprecated(self):
Erlend Egeberg Aaslandddb5e112021-01-06 01:36:04 +010090 for enable in (True, False):
91 with self.assertWarns(DeprecationWarning) as cm:
92 sqlite.enable_shared_cache(enable)
93 self.assertIn("dbapi.py", cm.filename)
94
Erlend Egeberg Aaslandccc95c72021-06-20 23:07:31 +020095 def test_disallow_instantiation(self):
96 cx = sqlite.connect(":memory:")
97 tp = type(cx("select 1"))
98 self.assertRaises(TypeError, tp)
99
Erlend Egeberg Aaslandddb5e112021-01-06 01:36:04 +0100100
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000101class ConnectionTests(unittest.TestCase):
R. David Murrayd35251d2010-06-01 01:32:12 +0000102
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000103 def setUp(self):
104 self.cx = sqlite.connect(":memory:")
105 cu = self.cx.cursor()
106 cu.execute("create table test(id integer primary key, name text)")
107 cu.execute("insert into test(name) values (?)", ("foo",))
108
109 def tearDown(self):
110 self.cx.close()
111
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100112 def test_commit(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000113 self.cx.commit()
114
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100115 def test_commit_after_no_changes(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000116 """
117 A commit should also work when no changes were made to the database.
118 """
119 self.cx.commit()
120 self.cx.commit()
121
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100122 def test_rollback(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000123 self.cx.rollback()
124
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100125 def test_rollback_after_no_changes(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000126 """
127 A rollback should also work when no changes were made to the database.
128 """
129 self.cx.rollback()
130 self.cx.rollback()
131
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100132 def test_cursor(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000133 cu = self.cx.cursor()
134
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100135 def test_failed_open(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000136 YOU_CANNOT_OPEN_THIS = "/foo/bar/bla/23534/mydb.db"
Berker Peksag1003b342016-06-12 22:34:49 +0300137 with self.assertRaises(sqlite.OperationalError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000138 con = sqlite.connect(YOU_CANNOT_OPEN_THIS)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000139
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100140 def test_close(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000141 self.cx.close()
142
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100143 def test_exceptions(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000144 # Optional DB-API extension.
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000145 self.assertEqual(self.cx.Warning, sqlite.Warning)
146 self.assertEqual(self.cx.Error, sqlite.Error)
147 self.assertEqual(self.cx.InterfaceError, sqlite.InterfaceError)
148 self.assertEqual(self.cx.DatabaseError, sqlite.DatabaseError)
149 self.assertEqual(self.cx.DataError, sqlite.DataError)
150 self.assertEqual(self.cx.OperationalError, sqlite.OperationalError)
151 self.assertEqual(self.cx.IntegrityError, sqlite.IntegrityError)
152 self.assertEqual(self.cx.InternalError, sqlite.InternalError)
153 self.assertEqual(self.cx.ProgrammingError, sqlite.ProgrammingError)
154 self.assertEqual(self.cx.NotSupportedError, sqlite.NotSupportedError)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000155
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100156 def test_in_transaction(self):
R. David Murrayd35251d2010-06-01 01:32:12 +0000157 # Can't use db from setUp because we want to test initial state.
158 cx = sqlite.connect(":memory:")
159 cu = cx.cursor()
160 self.assertEqual(cx.in_transaction, False)
161 cu.execute("create table transactiontest(id integer primary key, name text)")
162 self.assertEqual(cx.in_transaction, False)
163 cu.execute("insert into transactiontest(name) values (?)", ("foo",))
164 self.assertEqual(cx.in_transaction, True)
165 cu.execute("select name from transactiontest where name=?", ["foo"])
166 row = cu.fetchone()
167 self.assertEqual(cx.in_transaction, True)
168 cx.commit()
169 self.assertEqual(cx.in_transaction, False)
170 cu.execute("select name from transactiontest where name=?", ["foo"])
171 row = cu.fetchone()
172 self.assertEqual(cx.in_transaction, False)
173
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100174 def test_in_transaction_ro(self):
R. David Murrayd35251d2010-06-01 01:32:12 +0000175 with self.assertRaises(AttributeError):
176 self.cx.in_transaction = True
177
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100178 def test_open_with_path_like_object(self):
Ville Skyttä61f82e02018-04-20 23:08:45 +0300179 """ Checks that we can successfully connect to a database using an object that
Anders Lorentsena22a1272017-11-07 01:47:43 +0100180 is PathLike, i.e. has __fspath__(). """
181 self.addCleanup(unlink, TESTFN)
182 class Path:
183 def __fspath__(self):
184 return TESTFN
185 path = Path()
186 with sqlite.connect(path) as cx:
187 cx.execute('create table test(id integer)')
188
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100189 def test_open_uri(self):
Antoine Pitrou902fc8b2013-02-10 00:02:44 +0100190 self.addCleanup(unlink, TESTFN)
191 with sqlite.connect(TESTFN) as cx:
192 cx.execute('create table test(id integer)')
193 with sqlite.connect('file:' + TESTFN, uri=True) as cx:
194 cx.execute('insert into test(id) values(0)')
195 with sqlite.connect('file:' + TESTFN + '?mode=ro', uri=True) as cx:
196 with self.assertRaises(sqlite.OperationalError):
197 cx.execute('insert into test(id) values(1)')
198
199
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000200class CursorTests(unittest.TestCase):
201 def setUp(self):
202 self.cx = sqlite.connect(":memory:")
203 self.cu = self.cx.cursor()
Berker Peksage0b70cd2016-06-14 15:25:36 +0300204 self.cu.execute(
205 "create table test(id integer primary key, name text, "
206 "income number, unique_test text unique)"
207 )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000208 self.cu.execute("insert into test(name) values (?)", ("foo",))
209
210 def tearDown(self):
211 self.cu.close()
212 self.cx.close()
213
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100214 def test_execute_no_args(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000215 self.cu.execute("delete from test")
216
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100217 def test_execute_illegal_sql(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300218 with self.assertRaises(sqlite.OperationalError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000219 self.cu.execute("select asdf")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000220
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100221 def test_execute_too_much_sql(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300222 with self.assertRaises(sqlite.Warning):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000223 self.cu.execute("select 5+4; select 4+5")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000224
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100225 def test_execute_too_much_sql2(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000226 self.cu.execute("select 5+4; -- foo bar")
227
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100228 def test_execute_too_much_sql3(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000229 self.cu.execute("""
230 select 5+4;
231
232 /*
233 foo
234 */
235 """)
236
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100237 def test_execute_wrong_sql_arg(self):
Victor Stinnerc6a23202019-06-26 03:16:24 +0200238 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000239 self.cu.execute(42)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000240
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100241 def test_execute_arg_int(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000242 self.cu.execute("insert into test(id) values (?)", (42,))
243
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100244 def test_execute_arg_float(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000245 self.cu.execute("insert into test(income) values (?)", (2500.32,))
246
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100247 def test_execute_arg_string(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000248 self.cu.execute("insert into test(name) values (?)", ("Hugo",))
249
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100250 def test_execute_arg_string_with_zero_byte(self):
Petri Lehtinen023fe332012-02-01 22:18:19 +0200251 self.cu.execute("insert into test(name) values (?)", ("Hu\x00go",))
252
253 self.cu.execute("select name from test where id=?", (self.cu.lastrowid,))
254 row = self.cu.fetchone()
255 self.assertEqual(row[0], "Hu\x00go")
256
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100257 def test_execute_non_iterable(self):
Berker Peksagc4154402016-06-12 13:41:47 +0300258 with self.assertRaises(ValueError) as cm:
259 self.cu.execute("insert into test(id) values (?)", 42)
260 self.assertEqual(str(cm.exception), 'parameters are of unsupported type')
261
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100262 def test_execute_wrong_no_of_args1(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000263 # too many parameters
Berker Peksag1003b342016-06-12 22:34:49 +0300264 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000265 self.cu.execute("insert into test(id) values (?)", (17, "Egon"))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000266
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100267 def test_execute_wrong_no_of_args2(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000268 # too little parameters
Berker Peksag1003b342016-06-12 22:34:49 +0300269 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000270 self.cu.execute("insert into test(id) values (?)")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000271
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100272 def test_execute_wrong_no_of_args3(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000273 # no parameters, parameters are needed
Berker Peksag1003b342016-06-12 22:34:49 +0300274 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000275 self.cu.execute("insert into test(id) values (?)")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000276
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100277 def test_execute_param_list(self):
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000278 self.cu.execute("insert into test(name) values ('foo')")
279 self.cu.execute("select name from test where name=?", ["foo"])
280 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000281 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000282
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100283 def test_execute_param_sequence(self):
Serhiy Storchaka0b419b72020-09-17 10:35:44 +0300284 class L:
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000285 def __len__(self):
286 return 1
287 def __getitem__(self, x):
288 assert x == 0
289 return "foo"
290
291 self.cu.execute("insert into test(name) values ('foo')")
292 self.cu.execute("select name from test where name=?", L())
293 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000294 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000295
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100296 def test_execute_param_sequence_bad_len(self):
Serhiy Storchaka0b419b72020-09-17 10:35:44 +0300297 # Issue41662: Error in __len__() was overridden with ProgrammingError.
298 class L:
299 def __len__(self):
300 1/0
301 def __getitem__(slf, x):
302 raise AssertionError
303
304 self.cu.execute("insert into test(name) values ('foo')")
305 with self.assertRaises(ZeroDivisionError):
306 self.cu.execute("select name from test where name=?", L())
307
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100308 def test_execute_dict_mapping(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000309 self.cu.execute("insert into test(name) values ('foo')")
310 self.cu.execute("select name from test where name=:name", {"name": "foo"})
311 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000312 self.assertEqual(row[0], "foo")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000313
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100314 def test_execute_dict_mapping_mapping(self):
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000315 class D(dict):
316 def __missing__(self, key):
317 return "foo"
318
319 self.cu.execute("insert into test(name) values ('foo')")
320 self.cu.execute("select name from test where name=:name", D())
321 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000322 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000323
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100324 def test_execute_dict_mapping_too_little_args(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000325 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag1003b342016-06-12 22:34:49 +0300326 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000327 self.cu.execute("select name from test where name=:name and id=:id", {"name": "foo"})
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000328
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100329 def test_execute_dict_mapping_no_args(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000330 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag1003b342016-06-12 22:34:49 +0300331 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000332 self.cu.execute("select name from test where name=:name")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000333
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100334 def test_execute_dict_mapping_unnamed(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000335 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag1003b342016-06-12 22:34:49 +0300336 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000337 self.cu.execute("select name from test where name=?", {"name": "foo"})
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000338
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100339 def test_close(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000340 self.cu.close()
341
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100342 def test_rowcount_execute(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000343 self.cu.execute("delete from test")
344 self.cu.execute("insert into test(name) values ('foo')")
345 self.cu.execute("insert into test(name) values ('foo')")
346 self.cu.execute("update test set name='bar'")
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000347 self.assertEqual(self.cu.rowcount, 2)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000348
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100349 def test_rowcount_select(self):
Georg Brandlf78e02b2008-06-10 17:40:04 +0000350 """
351 pysqlite does not know the rowcount of SELECT statements, because we
352 don't fetch all rows after executing the select statement. The rowcount
353 has thus to be -1.
354 """
355 self.cu.execute("select 5 union select 6")
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000356 self.assertEqual(self.cu.rowcount, -1)
Georg Brandlf78e02b2008-06-10 17:40:04 +0000357
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100358 def test_rowcount_executemany(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000359 self.cu.execute("delete from test")
360 self.cu.executemany("insert into test(name) values (?)", [(1,), (2,), (3,)])
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000361 self.assertEqual(self.cu.rowcount, 3)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000362
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100363 def test_total_changes(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000364 self.cu.execute("insert into test(name) values ('foo')")
365 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag48b5c982016-06-14 00:42:50 +0300366 self.assertLess(2, self.cx.total_changes, msg='total changes reported wrong value')
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000367
368 # Checks for executemany:
369 # Sequences are required by the DB-API, iterators
370 # enhancements in pysqlite.
371
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100372 def test_execute_many_sequence(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000373 self.cu.executemany("insert into test(income) values (?)", [(x,) for x in range(100, 110)])
374
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100375 def test_execute_many_iterator(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000376 class MyIter:
377 def __init__(self):
378 self.value = 5
379
Georg Brandla18af4e2007-04-21 15:47:16 +0000380 def __next__(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000381 if self.value == 10:
382 raise StopIteration
383 else:
384 self.value += 1
385 return (self.value,)
386
387 self.cu.executemany("insert into test(income) values (?)", MyIter())
388
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100389 def test_execute_many_generator(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000390 def mygen():
391 for i in range(5):
392 yield (i,)
393
394 self.cu.executemany("insert into test(income) values (?)", mygen())
395
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100396 def test_execute_many_wrong_sql_arg(self):
Victor Stinnerc6a23202019-06-26 03:16:24 +0200397 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000398 self.cu.executemany(42, [(3,)])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000399
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100400 def test_execute_many_select(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300401 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000402 self.cu.executemany("select ?", [(3,)])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000403
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100404 def test_execute_many_not_iterable(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300405 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000406 self.cu.executemany("insert into test(income) values (?)", 42)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000407
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100408 def test_fetch_iter(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000409 # Optional DB-API extension.
410 self.cu.execute("delete from test")
411 self.cu.execute("insert into test(id) values (?)", (5,))
412 self.cu.execute("insert into test(id) values (?)", (6,))
413 self.cu.execute("select id from test order by id")
414 lst = []
415 for row in self.cu:
416 lst.append(row[0])
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000417 self.assertEqual(lst[0], 5)
418 self.assertEqual(lst[1], 6)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000419
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100420 def test_fetchone(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000421 self.cu.execute("select name from test")
422 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000423 self.assertEqual(row[0], "foo")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000424 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000425 self.assertEqual(row, None)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000426
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100427 def test_fetchone_no_statement(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000428 cur = self.cx.cursor()
429 row = cur.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000430 self.assertEqual(row, None)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000431
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100432 def test_array_size(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000433 # must default ot 1
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000434 self.assertEqual(self.cu.arraysize, 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000435
436 # now set to 2
437 self.cu.arraysize = 2
438
439 # now make the query return 3 rows
440 self.cu.execute("delete from test")
441 self.cu.execute("insert into test(name) values ('A')")
442 self.cu.execute("insert into test(name) values ('B')")
443 self.cu.execute("insert into test(name) values ('C')")
444 self.cu.execute("select name from test")
445 res = self.cu.fetchmany()
446
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000447 self.assertEqual(len(res), 2)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000448
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100449 def test_fetchmany(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000450 self.cu.execute("select name from test")
451 res = self.cu.fetchmany(100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000452 self.assertEqual(len(res), 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000453 res = self.cu.fetchmany(100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000454 self.assertEqual(res, [])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000455
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100456 def test_fetchmany_kw_arg(self):
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000457 """Checks if fetchmany works with keyword arguments"""
458 self.cu.execute("select name from test")
459 res = self.cu.fetchmany(size=100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000460 self.assertEqual(len(res), 1)
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000461
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100462 def test_fetchall(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000463 self.cu.execute("select name from test")
464 res = self.cu.fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000465 self.assertEqual(len(res), 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000466 res = self.cu.fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000467 self.assertEqual(res, [])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000468
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100469 def test_setinputsizes(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000470 self.cu.setinputsizes([3, 4, 5])
471
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100472 def test_setoutputsize(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000473 self.cu.setoutputsize(5, 0)
474
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100475 def test_setoutputsize_no_column(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000476 self.cu.setoutputsize(42)
477
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100478 def test_cursor_connection(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000479 # Optional DB-API extension.
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000480 self.assertEqual(self.cu.connection, self.cx)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000481
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100482 def test_wrong_cursor_callable(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300483 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000484 def f(): pass
485 cur = self.cx.cursor(f)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000486
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100487 def test_cursor_wrong_class(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000488 class Foo: pass
489 foo = Foo()
Berker Peksag1003b342016-06-12 22:34:49 +0300490 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000491 cur = sqlite.Cursor(foo)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000492
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100493 def test_last_row_id_on_replace(self):
Berker Peksage0b70cd2016-06-14 15:25:36 +0300494 """
495 INSERT OR REPLACE and REPLACE INTO should produce the same behavior.
496 """
497 sql = '{} INTO test(id, unique_test) VALUES (?, ?)'
498 for statement in ('INSERT OR REPLACE', 'REPLACE'):
499 with self.subTest(statement=statement):
500 self.cu.execute(sql.format(statement), (1, 'foo'))
501 self.assertEqual(self.cu.lastrowid, 1)
502
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100503 def test_last_row_id_on_ignore(self):
Berker Peksage0b70cd2016-06-14 15:25:36 +0300504 self.cu.execute(
505 "insert or ignore into test(unique_test) values (?)",
506 ('test',))
507 self.assertEqual(self.cu.lastrowid, 2)
508 self.cu.execute(
509 "insert or ignore into test(unique_test) values (?)",
510 ('test',))
511 self.assertEqual(self.cu.lastrowid, 2)
512
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100513 def test_last_row_id_insert_o_r(self):
Berker Peksage0b70cd2016-06-14 15:25:36 +0300514 results = []
515 for statement in ('FAIL', 'ABORT', 'ROLLBACK'):
516 sql = 'INSERT OR {} INTO test(unique_test) VALUES (?)'
517 with self.subTest(statement='INSERT OR {}'.format(statement)):
518 self.cu.execute(sql.format(statement), (statement,))
519 results.append((statement, self.cu.lastrowid))
520 with self.assertRaises(sqlite.IntegrityError):
521 self.cu.execute(sql.format(statement), (statement,))
522 results.append((statement, self.cu.lastrowid))
523 expected = [
524 ('FAIL', 2), ('FAIL', 2),
525 ('ABORT', 3), ('ABORT', 3),
526 ('ROLLBACK', 4), ('ROLLBACK', 4),
527 ]
528 self.assertEqual(results, expected)
529
530
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000531class ThreadTests(unittest.TestCase):
532 def setUp(self):
533 self.con = sqlite.connect(":memory:")
534 self.cur = self.con.cursor()
535 self.cur.execute("create table test(id integer primary key, name text, bin binary, ratio number, ts timestamp)")
536
537 def tearDown(self):
538 self.cur.close()
539 self.con.close()
540
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100541 def test_con_cursor(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000542 def run(con, errors):
543 try:
544 cur = con.cursor()
545 errors.append("did not raise ProgrammingError")
546 return
547 except sqlite.ProgrammingError:
548 return
549 except:
550 errors.append("raised wrong exception")
551
552 errors = []
553 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
554 t.start()
555 t.join()
556 if len(errors) > 0:
557 self.fail("\n".join(errors))
558
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100559 def test_con_commit(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000560 def run(con, errors):
561 try:
562 con.commit()
563 errors.append("did not raise ProgrammingError")
564 return
565 except sqlite.ProgrammingError:
566 return
567 except:
568 errors.append("raised wrong exception")
569
570 errors = []
571 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
572 t.start()
573 t.join()
574 if len(errors) > 0:
575 self.fail("\n".join(errors))
576
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100577 def test_con_rollback(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000578 def run(con, errors):
579 try:
580 con.rollback()
581 errors.append("did not raise ProgrammingError")
582 return
583 except sqlite.ProgrammingError:
584 return
585 except:
586 errors.append("raised wrong exception")
587
588 errors = []
589 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
590 t.start()
591 t.join()
592 if len(errors) > 0:
593 self.fail("\n".join(errors))
594
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100595 def test_con_close(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000596 def run(con, errors):
597 try:
598 con.close()
599 errors.append("did not raise ProgrammingError")
600 return
601 except sqlite.ProgrammingError:
602 return
603 except:
604 errors.append("raised wrong exception")
605
606 errors = []
607 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
608 t.start()
609 t.join()
610 if len(errors) > 0:
611 self.fail("\n".join(errors))
612
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100613 def test_cur_implicit_begin(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000614 def run(cur, errors):
615 try:
616 cur.execute("insert into test(name) values ('a')")
617 errors.append("did not raise ProgrammingError")
618 return
619 except sqlite.ProgrammingError:
620 return
621 except:
622 errors.append("raised wrong exception")
623
624 errors = []
625 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
626 t.start()
627 t.join()
628 if len(errors) > 0:
629 self.fail("\n".join(errors))
630
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100631 def test_cur_close(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000632 def run(cur, errors):
633 try:
634 cur.close()
635 errors.append("did not raise ProgrammingError")
636 return
637 except sqlite.ProgrammingError:
638 return
639 except:
640 errors.append("raised wrong exception")
641
642 errors = []
643 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
644 t.start()
645 t.join()
646 if len(errors) > 0:
647 self.fail("\n".join(errors))
648
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100649 def test_cur_execute(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000650 def run(cur, errors):
651 try:
652 cur.execute("select name from test")
653 errors.append("did not raise ProgrammingError")
654 return
655 except sqlite.ProgrammingError:
656 return
657 except:
658 errors.append("raised wrong exception")
659
660 errors = []
661 self.cur.execute("insert into test(name) values ('a')")
662 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
663 t.start()
664 t.join()
665 if len(errors) > 0:
666 self.fail("\n".join(errors))
667
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100668 def test_cur_iter_next(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000669 def run(cur, errors):
670 try:
671 row = cur.fetchone()
672 errors.append("did not raise ProgrammingError")
673 return
674 except sqlite.ProgrammingError:
675 return
676 except:
677 errors.append("raised wrong exception")
678
679 errors = []
680 self.cur.execute("insert into test(name) values ('a')")
681 self.cur.execute("select name from test")
682 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
683 t.start()
684 t.join()
685 if len(errors) > 0:
686 self.fail("\n".join(errors))
687
688class ConstructorTests(unittest.TestCase):
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100689 def test_date(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000690 d = sqlite.Date(2004, 10, 28)
691
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100692 def test_time(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000693 t = sqlite.Time(12, 39, 35)
694
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100695 def test_timestamp(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000696 ts = sqlite.Timestamp(2004, 10, 28, 12, 39, 35)
697
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100698 def test_date_from_ticks(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000699 d = sqlite.DateFromTicks(42)
700
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100701 def test_time_from_ticks(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000702 t = sqlite.TimeFromTicks(42)
703
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100704 def test_timestamp_from_ticks(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000705 ts = sqlite.TimestampFromTicks(42)
706
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100707 def test_binary(self):
Guido van Rossumbae07c92007-10-08 02:46:15 +0000708 b = sqlite.Binary(b"\0'")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000709
710class ExtensionTests(unittest.TestCase):
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100711 def test_script_string_sql(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000712 con = sqlite.connect(":memory:")
713 cur = con.cursor()
714 cur.executescript("""
715 -- bla bla
716 /* a stupid comment */
717 create table a(i);
718 insert into a(i) values (5);
719 """)
720 cur.execute("select i from a")
721 res = cur.fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000722 self.assertEqual(res, 5)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000723
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100724 def test_script_syntax_error(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000725 con = sqlite.connect(":memory:")
726 cur = con.cursor()
Berker Peksag1003b342016-06-12 22:34:49 +0300727 with self.assertRaises(sqlite.OperationalError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000728 cur.executescript("create table test(x); asdf; create table test2(x)")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000729
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100730 def test_script_error_normal(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000731 con = sqlite.connect(":memory:")
732 cur = con.cursor()
Berker Peksag1003b342016-06-12 22:34:49 +0300733 with self.assertRaises(sqlite.OperationalError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000734 cur.executescript("create table test(sadfsadfdsa); select foo from hurz;")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000735
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100736 def test_cursor_executescript_as_bytes(self):
Berker Peksagc4154402016-06-12 13:41:47 +0300737 con = sqlite.connect(":memory:")
738 cur = con.cursor()
739 with self.assertRaises(ValueError) as cm:
740 cur.executescript(b"create table test(foo); insert into test(foo) values (5);")
741 self.assertEqual(str(cm.exception), 'script argument must be unicode.')
742
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100743 def test_connection_execute(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000744 con = sqlite.connect(":memory:")
745 result = con.execute("select 5").fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000746 self.assertEqual(result, 5, "Basic test of Connection.execute")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000747
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100748 def test_connection_executemany(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000749 con = sqlite.connect(":memory:")
750 con.execute("create table test(foo)")
751 con.executemany("insert into test(foo) values (?)", [(3,), (4,)])
752 result = con.execute("select foo from test order by foo").fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000753 self.assertEqual(result[0][0], 3, "Basic test of Connection.executemany")
754 self.assertEqual(result[1][0], 4, "Basic test of Connection.executemany")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000755
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100756 def test_connection_executescript(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000757 con = sqlite.connect(":memory:")
758 con.executescript("create table test(foo); insert into test(foo) values (5);")
759 result = con.execute("select foo from test").fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000760 self.assertEqual(result, 5, "Basic test of Connection.executescript")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000761
Gerhard Häringf9cee222010-03-05 15:20:03 +0000762class ClosedConTests(unittest.TestCase):
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100763 def test_closed_con_cursor(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000764 con = sqlite.connect(":memory:")
765 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300766 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000767 cur = con.cursor()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000768
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100769 def test_closed_con_commit(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000770 con = sqlite.connect(":memory:")
771 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300772 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000773 con.commit()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000774
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100775 def test_closed_con_rollback(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000776 con = sqlite.connect(":memory:")
777 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300778 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000779 con.rollback()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000780
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100781 def test_closed_cur_execute(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000782 con = sqlite.connect(":memory:")
783 cur = con.cursor()
784 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300785 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000786 cur.execute("select 4")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000787
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100788 def test_closed_create_function(self):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000789 con = sqlite.connect(":memory:")
790 con.close()
791 def f(x): return 17
Berker Peksag1003b342016-06-12 22:34:49 +0300792 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000793 con.create_function("foo", 1, f)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000794
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100795 def test_closed_create_aggregate(self):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000796 con = sqlite.connect(":memory:")
797 con.close()
798 class Agg:
799 def __init__(self):
800 pass
801 def step(self, x):
802 pass
803 def finalize(self):
804 return 17
Berker Peksag1003b342016-06-12 22:34:49 +0300805 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000806 con.create_aggregate("foo", 1, Agg)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000807
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100808 def test_closed_set_authorizer(self):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000809 con = sqlite.connect(":memory:")
810 con.close()
811 def authorizer(*args):
812 return sqlite.DENY
Berker Peksag1003b342016-06-12 22:34:49 +0300813 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000814 con.set_authorizer(authorizer)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000815
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100816 def test_closed_set_progress_callback(self):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000817 con = sqlite.connect(":memory:")
818 con.close()
819 def progress(): pass
Berker Peksag1003b342016-06-12 22:34:49 +0300820 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000821 con.set_progress_handler(progress, 100)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000822
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100823 def test_closed_call(self):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000824 con = sqlite.connect(":memory:")
825 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300826 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000827 con()
Gerhard Häringf9cee222010-03-05 15:20:03 +0000828
829class ClosedCurTests(unittest.TestCase):
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100830 def test_closed(self):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000831 con = sqlite.connect(":memory:")
832 cur = con.cursor()
833 cur.close()
834
835 for method_name in ("execute", "executemany", "executescript", "fetchall", "fetchmany", "fetchone"):
836 if method_name in ("execute", "executescript"):
837 params = ("select 4 union select 5",)
838 elif method_name == "executemany":
839 params = ("insert into foo(bar) values (?)", [(3,), (4,)])
840 else:
841 params = []
842
Berker Peksag1003b342016-06-12 22:34:49 +0300843 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000844 method = getattr(cur, method_name)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000845 method(*params)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000846
Berker Peksag4bf580d2016-09-07 02:04:34 +0300847
848class SqliteOnConflictTests(unittest.TestCase):
849 """
850 Tests for SQLite's "insert on conflict" feature.
851
852 See https://www.sqlite.org/lang_conflict.html for details.
853 """
854
855 def setUp(self):
856 self.cx = sqlite.connect(":memory:")
857 self.cu = self.cx.cursor()
858 self.cu.execute("""
859 CREATE TABLE test(
860 id INTEGER PRIMARY KEY, name TEXT, unique_name TEXT UNIQUE
861 );
862 """)
863
864 def tearDown(self):
865 self.cu.close()
866 self.cx.close()
867
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100868 def test_on_conflict_rollback_with_explicit_transaction(self):
Berker Peksag4bf580d2016-09-07 02:04:34 +0300869 self.cx.isolation_level = None # autocommit mode
870 self.cu = self.cx.cursor()
871 # Start an explicit transaction.
872 self.cu.execute("BEGIN")
873 self.cu.execute("INSERT INTO test(name) VALUES ('abort_test')")
874 self.cu.execute("INSERT OR ROLLBACK INTO test(unique_name) VALUES ('foo')")
875 with self.assertRaises(sqlite.IntegrityError):
876 self.cu.execute("INSERT OR ROLLBACK INTO test(unique_name) VALUES ('foo')")
877 # Use connection to commit.
878 self.cx.commit()
879 self.cu.execute("SELECT name, unique_name from test")
880 # Transaction should have rolled back and nothing should be in table.
881 self.assertEqual(self.cu.fetchall(), [])
882
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100883 def test_on_conflict_abort_raises_with_explicit_transactions(self):
Berker Peksag4bf580d2016-09-07 02:04:34 +0300884 # Abort cancels the current sql statement but doesn't change anything
885 # about the current transaction.
886 self.cx.isolation_level = None # autocommit mode
887 self.cu = self.cx.cursor()
888 # Start an explicit transaction.
889 self.cu.execute("BEGIN")
890 self.cu.execute("INSERT INTO test(name) VALUES ('abort_test')")
891 self.cu.execute("INSERT OR ABORT INTO test(unique_name) VALUES ('foo')")
892 with self.assertRaises(sqlite.IntegrityError):
893 self.cu.execute("INSERT OR ABORT INTO test(unique_name) VALUES ('foo')")
894 self.cx.commit()
895 self.cu.execute("SELECT name, unique_name FROM test")
896 # Expect the first two inserts to work, third to do nothing.
897 self.assertEqual(self.cu.fetchall(), [('abort_test', None), (None, 'foo',)])
898
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100899 def test_on_conflict_rollback_without_transaction(self):
Berker Peksag4bf580d2016-09-07 02:04:34 +0300900 # Start of implicit transaction
901 self.cu.execute("INSERT INTO test(name) VALUES ('abort_test')")
902 self.cu.execute("INSERT OR ROLLBACK INTO test(unique_name) VALUES ('foo')")
903 with self.assertRaises(sqlite.IntegrityError):
904 self.cu.execute("INSERT OR ROLLBACK INTO test(unique_name) VALUES ('foo')")
905 self.cu.execute("SELECT name, unique_name FROM test")
906 # Implicit transaction is rolled back on error.
907 self.assertEqual(self.cu.fetchall(), [])
908
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100909 def test_on_conflict_abort_raises_without_transactions(self):
Berker Peksag4bf580d2016-09-07 02:04:34 +0300910 # Abort cancels the current sql statement but doesn't change anything
911 # about the current transaction.
912 self.cu.execute("INSERT INTO test(name) VALUES ('abort_test')")
913 self.cu.execute("INSERT OR ABORT INTO test(unique_name) VALUES ('foo')")
914 with self.assertRaises(sqlite.IntegrityError):
915 self.cu.execute("INSERT OR ABORT INTO test(unique_name) VALUES ('foo')")
916 # Make sure all other values were inserted.
917 self.cu.execute("SELECT name, unique_name FROM test")
918 self.assertEqual(self.cu.fetchall(), [('abort_test', None), (None, 'foo',)])
919
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100920 def test_on_conflict_fail(self):
Berker Peksag4bf580d2016-09-07 02:04:34 +0300921 self.cu.execute("INSERT OR FAIL INTO test(unique_name) VALUES ('foo')")
922 with self.assertRaises(sqlite.IntegrityError):
923 self.cu.execute("INSERT OR FAIL INTO test(unique_name) VALUES ('foo')")
924 self.assertEqual(self.cu.fetchall(), [])
925
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100926 def test_on_conflict_ignore(self):
Berker Peksag4bf580d2016-09-07 02:04:34 +0300927 self.cu.execute("INSERT OR IGNORE INTO test(unique_name) VALUES ('foo')")
928 # Nothing should happen.
929 self.cu.execute("INSERT OR IGNORE INTO test(unique_name) VALUES ('foo')")
930 self.cu.execute("SELECT unique_name FROM test")
931 self.assertEqual(self.cu.fetchall(), [('foo',)])
932
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100933 def test_on_conflict_replace(self):
Berker Peksag4bf580d2016-09-07 02:04:34 +0300934 self.cu.execute("INSERT OR REPLACE INTO test(name, unique_name) VALUES ('Data!', 'foo')")
935 # There shouldn't be an IntegrityError exception.
936 self.cu.execute("INSERT OR REPLACE INTO test(name, unique_name) VALUES ('Very different data!', 'foo')")
937 self.cu.execute("SELECT name, unique_name FROM test")
938 self.assertEqual(self.cu.fetchall(), [('Very different data!', 'foo')])
939
940
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000941def suite():
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100942 tests = [
943 ClosedConTests,
944 ClosedCurTests,
945 ConnectionTests,
946 ConstructorTests,
947 CursorTests,
948 ExtensionTests,
949 ModuleTests,
950 SqliteOnConflictTests,
951 ThreadTests,
952 ]
953 return unittest.TestSuite(
954 [unittest.TestLoader().loadTestsFromTestCase(t) for t in tests]
955 )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000956
957def test():
958 runner = unittest.TextTestRunner()
959 runner.run(suite())
960
961if __name__ == "__main__":
962 test()