blob: 39c9bf5b61143db5f221d1e0b4fe0509d5d86d75 [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
95
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000096class ConnectionTests(unittest.TestCase):
R. David Murrayd35251d2010-06-01 01:32:12 +000097
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000098 def setUp(self):
99 self.cx = sqlite.connect(":memory:")
100 cu = self.cx.cursor()
101 cu.execute("create table test(id integer primary key, name text)")
102 cu.execute("insert into test(name) values (?)", ("foo",))
103
104 def tearDown(self):
105 self.cx.close()
106
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100107 def test_commit(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000108 self.cx.commit()
109
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100110 def test_commit_after_no_changes(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000111 """
112 A commit should also work when no changes were made to the database.
113 """
114 self.cx.commit()
115 self.cx.commit()
116
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100117 def test_rollback(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000118 self.cx.rollback()
119
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100120 def test_rollback_after_no_changes(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000121 """
122 A rollback should also work when no changes were made to the database.
123 """
124 self.cx.rollback()
125 self.cx.rollback()
126
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100127 def test_cursor(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000128 cu = self.cx.cursor()
129
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100130 def test_failed_open(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000131 YOU_CANNOT_OPEN_THIS = "/foo/bar/bla/23534/mydb.db"
Berker Peksag1003b342016-06-12 22:34:49 +0300132 with self.assertRaises(sqlite.OperationalError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000133 con = sqlite.connect(YOU_CANNOT_OPEN_THIS)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000134
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100135 def test_close(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000136 self.cx.close()
137
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100138 def test_exceptions(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000139 # Optional DB-API extension.
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000140 self.assertEqual(self.cx.Warning, sqlite.Warning)
141 self.assertEqual(self.cx.Error, sqlite.Error)
142 self.assertEqual(self.cx.InterfaceError, sqlite.InterfaceError)
143 self.assertEqual(self.cx.DatabaseError, sqlite.DatabaseError)
144 self.assertEqual(self.cx.DataError, sqlite.DataError)
145 self.assertEqual(self.cx.OperationalError, sqlite.OperationalError)
146 self.assertEqual(self.cx.IntegrityError, sqlite.IntegrityError)
147 self.assertEqual(self.cx.InternalError, sqlite.InternalError)
148 self.assertEqual(self.cx.ProgrammingError, sqlite.ProgrammingError)
149 self.assertEqual(self.cx.NotSupportedError, sqlite.NotSupportedError)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000150
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100151 def test_in_transaction(self):
R. David Murrayd35251d2010-06-01 01:32:12 +0000152 # Can't use db from setUp because we want to test initial state.
153 cx = sqlite.connect(":memory:")
154 cu = cx.cursor()
155 self.assertEqual(cx.in_transaction, False)
156 cu.execute("create table transactiontest(id integer primary key, name text)")
157 self.assertEqual(cx.in_transaction, False)
158 cu.execute("insert into transactiontest(name) values (?)", ("foo",))
159 self.assertEqual(cx.in_transaction, True)
160 cu.execute("select name from transactiontest where name=?", ["foo"])
161 row = cu.fetchone()
162 self.assertEqual(cx.in_transaction, True)
163 cx.commit()
164 self.assertEqual(cx.in_transaction, False)
165 cu.execute("select name from transactiontest where name=?", ["foo"])
166 row = cu.fetchone()
167 self.assertEqual(cx.in_transaction, False)
168
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100169 def test_in_transaction_ro(self):
R. David Murrayd35251d2010-06-01 01:32:12 +0000170 with self.assertRaises(AttributeError):
171 self.cx.in_transaction = True
172
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100173 def test_open_with_path_like_object(self):
Ville Skyttä61f82e02018-04-20 23:08:45 +0300174 """ Checks that we can successfully connect to a database using an object that
Anders Lorentsena22a1272017-11-07 01:47:43 +0100175 is PathLike, i.e. has __fspath__(). """
176 self.addCleanup(unlink, TESTFN)
177 class Path:
178 def __fspath__(self):
179 return TESTFN
180 path = Path()
181 with sqlite.connect(path) as cx:
182 cx.execute('create table test(id integer)')
183
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100184 def test_open_uri(self):
Antoine Pitrou902fc8b2013-02-10 00:02:44 +0100185 self.addCleanup(unlink, TESTFN)
186 with sqlite.connect(TESTFN) as cx:
187 cx.execute('create table test(id integer)')
188 with sqlite.connect('file:' + TESTFN, uri=True) as cx:
189 cx.execute('insert into test(id) values(0)')
190 with sqlite.connect('file:' + TESTFN + '?mode=ro', uri=True) as cx:
191 with self.assertRaises(sqlite.OperationalError):
192 cx.execute('insert into test(id) values(1)')
193
194
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000195class CursorTests(unittest.TestCase):
196 def setUp(self):
197 self.cx = sqlite.connect(":memory:")
198 self.cu = self.cx.cursor()
Berker Peksage0b70cd2016-06-14 15:25:36 +0300199 self.cu.execute(
200 "create table test(id integer primary key, name text, "
201 "income number, unique_test text unique)"
202 )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000203 self.cu.execute("insert into test(name) values (?)", ("foo",))
204
205 def tearDown(self):
206 self.cu.close()
207 self.cx.close()
208
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100209 def test_execute_no_args(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000210 self.cu.execute("delete from test")
211
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100212 def test_execute_illegal_sql(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300213 with self.assertRaises(sqlite.OperationalError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000214 self.cu.execute("select asdf")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000215
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100216 def test_execute_too_much_sql(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300217 with self.assertRaises(sqlite.Warning):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000218 self.cu.execute("select 5+4; select 4+5")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000219
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100220 def test_execute_too_much_sql2(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000221 self.cu.execute("select 5+4; -- foo bar")
222
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100223 def test_execute_too_much_sql3(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000224 self.cu.execute("""
225 select 5+4;
226
227 /*
228 foo
229 */
230 """)
231
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100232 def test_execute_wrong_sql_arg(self):
Victor Stinnerc6a23202019-06-26 03:16:24 +0200233 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000234 self.cu.execute(42)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000235
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100236 def test_execute_arg_int(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000237 self.cu.execute("insert into test(id) values (?)", (42,))
238
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100239 def test_execute_arg_float(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000240 self.cu.execute("insert into test(income) values (?)", (2500.32,))
241
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100242 def test_execute_arg_string(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000243 self.cu.execute("insert into test(name) values (?)", ("Hugo",))
244
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100245 def test_execute_arg_string_with_zero_byte(self):
Petri Lehtinen023fe332012-02-01 22:18:19 +0200246 self.cu.execute("insert into test(name) values (?)", ("Hu\x00go",))
247
248 self.cu.execute("select name from test where id=?", (self.cu.lastrowid,))
249 row = self.cu.fetchone()
250 self.assertEqual(row[0], "Hu\x00go")
251
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100252 def test_execute_non_iterable(self):
Berker Peksagc4154402016-06-12 13:41:47 +0300253 with self.assertRaises(ValueError) as cm:
254 self.cu.execute("insert into test(id) values (?)", 42)
255 self.assertEqual(str(cm.exception), 'parameters are of unsupported type')
256
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100257 def test_execute_wrong_no_of_args1(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000258 # too many parameters
Berker Peksag1003b342016-06-12 22:34:49 +0300259 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000260 self.cu.execute("insert into test(id) values (?)", (17, "Egon"))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000261
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100262 def test_execute_wrong_no_of_args2(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000263 # too little 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 (?)")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000266
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100267 def test_execute_wrong_no_of_args3(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000268 # no parameters, parameters are needed
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_param_list(self):
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000273 self.cu.execute("insert into test(name) values ('foo')")
274 self.cu.execute("select name from test where name=?", ["foo"])
275 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000276 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000277
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100278 def test_execute_param_sequence(self):
Serhiy Storchaka0b419b72020-09-17 10:35:44 +0300279 class L:
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000280 def __len__(self):
281 return 1
282 def __getitem__(self, x):
283 assert x == 0
284 return "foo"
285
286 self.cu.execute("insert into test(name) values ('foo')")
287 self.cu.execute("select name from test where name=?", L())
288 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000289 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000290
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100291 def test_execute_param_sequence_bad_len(self):
Serhiy Storchaka0b419b72020-09-17 10:35:44 +0300292 # Issue41662: Error in __len__() was overridden with ProgrammingError.
293 class L:
294 def __len__(self):
295 1/0
296 def __getitem__(slf, x):
297 raise AssertionError
298
299 self.cu.execute("insert into test(name) values ('foo')")
300 with self.assertRaises(ZeroDivisionError):
301 self.cu.execute("select name from test where name=?", L())
302
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100303 def test_execute_dict_mapping(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000304 self.cu.execute("insert into test(name) values ('foo')")
305 self.cu.execute("select name from test where name=:name", {"name": "foo"})
306 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000307 self.assertEqual(row[0], "foo")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000308
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100309 def test_execute_dict_mapping_mapping(self):
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000310 class D(dict):
311 def __missing__(self, key):
312 return "foo"
313
314 self.cu.execute("insert into test(name) values ('foo')")
315 self.cu.execute("select name from test where name=:name", D())
316 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000317 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000318
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100319 def test_execute_dict_mapping_too_little_args(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000320 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag1003b342016-06-12 22:34:49 +0300321 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000322 self.cu.execute("select name from test where name=:name and id=:id", {"name": "foo"})
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000323
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100324 def test_execute_dict_mapping_no_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")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000328
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100329 def test_execute_dict_mapping_unnamed(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": "foo"})
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000333
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100334 def test_close(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000335 self.cu.close()
336
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100337 def test_rowcount_execute(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000338 self.cu.execute("delete from test")
339 self.cu.execute("insert into test(name) values ('foo')")
340 self.cu.execute("insert into test(name) values ('foo')")
341 self.cu.execute("update test set name='bar'")
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000342 self.assertEqual(self.cu.rowcount, 2)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000343
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100344 def test_rowcount_select(self):
Georg Brandlf78e02b2008-06-10 17:40:04 +0000345 """
346 pysqlite does not know the rowcount of SELECT statements, because we
347 don't fetch all rows after executing the select statement. The rowcount
348 has thus to be -1.
349 """
350 self.cu.execute("select 5 union select 6")
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000351 self.assertEqual(self.cu.rowcount, -1)
Georg Brandlf78e02b2008-06-10 17:40:04 +0000352
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100353 def test_rowcount_executemany(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000354 self.cu.execute("delete from test")
355 self.cu.executemany("insert into test(name) values (?)", [(1,), (2,), (3,)])
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000356 self.assertEqual(self.cu.rowcount, 3)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000357
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100358 def test_total_changes(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000359 self.cu.execute("insert into test(name) values ('foo')")
360 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag48b5c982016-06-14 00:42:50 +0300361 self.assertLess(2, self.cx.total_changes, msg='total changes reported wrong value')
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000362
363 # Checks for executemany:
364 # Sequences are required by the DB-API, iterators
365 # enhancements in pysqlite.
366
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100367 def test_execute_many_sequence(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000368 self.cu.executemany("insert into test(income) values (?)", [(x,) for x in range(100, 110)])
369
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100370 def test_execute_many_iterator(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000371 class MyIter:
372 def __init__(self):
373 self.value = 5
374
Georg Brandla18af4e2007-04-21 15:47:16 +0000375 def __next__(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000376 if self.value == 10:
377 raise StopIteration
378 else:
379 self.value += 1
380 return (self.value,)
381
382 self.cu.executemany("insert into test(income) values (?)", MyIter())
383
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100384 def test_execute_many_generator(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000385 def mygen():
386 for i in range(5):
387 yield (i,)
388
389 self.cu.executemany("insert into test(income) values (?)", mygen())
390
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100391 def test_execute_many_wrong_sql_arg(self):
Victor Stinnerc6a23202019-06-26 03:16:24 +0200392 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000393 self.cu.executemany(42, [(3,)])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000394
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100395 def test_execute_many_select(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300396 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000397 self.cu.executemany("select ?", [(3,)])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000398
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100399 def test_execute_many_not_iterable(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300400 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000401 self.cu.executemany("insert into test(income) values (?)", 42)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000402
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100403 def test_fetch_iter(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000404 # Optional DB-API extension.
405 self.cu.execute("delete from test")
406 self.cu.execute("insert into test(id) values (?)", (5,))
407 self.cu.execute("insert into test(id) values (?)", (6,))
408 self.cu.execute("select id from test order by id")
409 lst = []
410 for row in self.cu:
411 lst.append(row[0])
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000412 self.assertEqual(lst[0], 5)
413 self.assertEqual(lst[1], 6)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000414
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100415 def test_fetchone(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000416 self.cu.execute("select name from test")
417 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000418 self.assertEqual(row[0], "foo")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000419 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000420 self.assertEqual(row, None)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000421
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100422 def test_fetchone_no_statement(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000423 cur = self.cx.cursor()
424 row = cur.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_array_size(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000428 # must default ot 1
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000429 self.assertEqual(self.cu.arraysize, 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000430
431 # now set to 2
432 self.cu.arraysize = 2
433
434 # now make the query return 3 rows
435 self.cu.execute("delete from test")
436 self.cu.execute("insert into test(name) values ('A')")
437 self.cu.execute("insert into test(name) values ('B')")
438 self.cu.execute("insert into test(name) values ('C')")
439 self.cu.execute("select name from test")
440 res = self.cu.fetchmany()
441
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000442 self.assertEqual(len(res), 2)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000443
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100444 def test_fetchmany(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000445 self.cu.execute("select name from test")
446 res = self.cu.fetchmany(100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000447 self.assertEqual(len(res), 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000448 res = self.cu.fetchmany(100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000449 self.assertEqual(res, [])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000450
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100451 def test_fetchmany_kw_arg(self):
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000452 """Checks if fetchmany works with keyword arguments"""
453 self.cu.execute("select name from test")
454 res = self.cu.fetchmany(size=100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000455 self.assertEqual(len(res), 1)
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000456
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100457 def test_fetchall(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000458 self.cu.execute("select name from test")
459 res = self.cu.fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000460 self.assertEqual(len(res), 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000461 res = self.cu.fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000462 self.assertEqual(res, [])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000463
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100464 def test_setinputsizes(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000465 self.cu.setinputsizes([3, 4, 5])
466
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100467 def test_setoutputsize(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000468 self.cu.setoutputsize(5, 0)
469
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100470 def test_setoutputsize_no_column(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000471 self.cu.setoutputsize(42)
472
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100473 def test_cursor_connection(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000474 # Optional DB-API extension.
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000475 self.assertEqual(self.cu.connection, self.cx)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000476
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100477 def test_wrong_cursor_callable(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300478 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000479 def f(): pass
480 cur = self.cx.cursor(f)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000481
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100482 def test_cursor_wrong_class(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000483 class Foo: pass
484 foo = Foo()
Berker Peksag1003b342016-06-12 22:34:49 +0300485 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000486 cur = sqlite.Cursor(foo)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000487
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100488 def test_last_row_id_on_replace(self):
Berker Peksage0b70cd2016-06-14 15:25:36 +0300489 """
490 INSERT OR REPLACE and REPLACE INTO should produce the same behavior.
491 """
492 sql = '{} INTO test(id, unique_test) VALUES (?, ?)'
493 for statement in ('INSERT OR REPLACE', 'REPLACE'):
494 with self.subTest(statement=statement):
495 self.cu.execute(sql.format(statement), (1, 'foo'))
496 self.assertEqual(self.cu.lastrowid, 1)
497
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100498 def test_last_row_id_on_ignore(self):
Berker Peksage0b70cd2016-06-14 15:25:36 +0300499 self.cu.execute(
500 "insert or ignore into test(unique_test) values (?)",
501 ('test',))
502 self.assertEqual(self.cu.lastrowid, 2)
503 self.cu.execute(
504 "insert or ignore into test(unique_test) values (?)",
505 ('test',))
506 self.assertEqual(self.cu.lastrowid, 2)
507
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100508 def test_last_row_id_insert_o_r(self):
Berker Peksage0b70cd2016-06-14 15:25:36 +0300509 results = []
510 for statement in ('FAIL', 'ABORT', 'ROLLBACK'):
511 sql = 'INSERT OR {} INTO test(unique_test) VALUES (?)'
512 with self.subTest(statement='INSERT OR {}'.format(statement)):
513 self.cu.execute(sql.format(statement), (statement,))
514 results.append((statement, self.cu.lastrowid))
515 with self.assertRaises(sqlite.IntegrityError):
516 self.cu.execute(sql.format(statement), (statement,))
517 results.append((statement, self.cu.lastrowid))
518 expected = [
519 ('FAIL', 2), ('FAIL', 2),
520 ('ABORT', 3), ('ABORT', 3),
521 ('ROLLBACK', 4), ('ROLLBACK', 4),
522 ]
523 self.assertEqual(results, expected)
524
525
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000526class ThreadTests(unittest.TestCase):
527 def setUp(self):
528 self.con = sqlite.connect(":memory:")
529 self.cur = self.con.cursor()
530 self.cur.execute("create table test(id integer primary key, name text, bin binary, ratio number, ts timestamp)")
531
532 def tearDown(self):
533 self.cur.close()
534 self.con.close()
535
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100536 def test_con_cursor(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000537 def run(con, errors):
538 try:
539 cur = con.cursor()
540 errors.append("did not raise ProgrammingError")
541 return
542 except sqlite.ProgrammingError:
543 return
544 except:
545 errors.append("raised wrong exception")
546
547 errors = []
548 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
549 t.start()
550 t.join()
551 if len(errors) > 0:
552 self.fail("\n".join(errors))
553
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100554 def test_con_commit(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000555 def run(con, errors):
556 try:
557 con.commit()
558 errors.append("did not raise ProgrammingError")
559 return
560 except sqlite.ProgrammingError:
561 return
562 except:
563 errors.append("raised wrong exception")
564
565 errors = []
566 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
567 t.start()
568 t.join()
569 if len(errors) > 0:
570 self.fail("\n".join(errors))
571
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100572 def test_con_rollback(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000573 def run(con, errors):
574 try:
575 con.rollback()
576 errors.append("did not raise ProgrammingError")
577 return
578 except sqlite.ProgrammingError:
579 return
580 except:
581 errors.append("raised wrong exception")
582
583 errors = []
584 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
585 t.start()
586 t.join()
587 if len(errors) > 0:
588 self.fail("\n".join(errors))
589
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100590 def test_con_close(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000591 def run(con, errors):
592 try:
593 con.close()
594 errors.append("did not raise ProgrammingError")
595 return
596 except sqlite.ProgrammingError:
597 return
598 except:
599 errors.append("raised wrong exception")
600
601 errors = []
602 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
603 t.start()
604 t.join()
605 if len(errors) > 0:
606 self.fail("\n".join(errors))
607
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100608 def test_cur_implicit_begin(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000609 def run(cur, errors):
610 try:
611 cur.execute("insert into test(name) values ('a')")
612 errors.append("did not raise ProgrammingError")
613 return
614 except sqlite.ProgrammingError:
615 return
616 except:
617 errors.append("raised wrong exception")
618
619 errors = []
620 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
621 t.start()
622 t.join()
623 if len(errors) > 0:
624 self.fail("\n".join(errors))
625
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100626 def test_cur_close(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000627 def run(cur, errors):
628 try:
629 cur.close()
630 errors.append("did not raise ProgrammingError")
631 return
632 except sqlite.ProgrammingError:
633 return
634 except:
635 errors.append("raised wrong exception")
636
637 errors = []
638 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
639 t.start()
640 t.join()
641 if len(errors) > 0:
642 self.fail("\n".join(errors))
643
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100644 def test_cur_execute(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000645 def run(cur, errors):
646 try:
647 cur.execute("select name from test")
648 errors.append("did not raise ProgrammingError")
649 return
650 except sqlite.ProgrammingError:
651 return
652 except:
653 errors.append("raised wrong exception")
654
655 errors = []
656 self.cur.execute("insert into test(name) values ('a')")
657 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
658 t.start()
659 t.join()
660 if len(errors) > 0:
661 self.fail("\n".join(errors))
662
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100663 def test_cur_iter_next(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000664 def run(cur, errors):
665 try:
666 row = cur.fetchone()
667 errors.append("did not raise ProgrammingError")
668 return
669 except sqlite.ProgrammingError:
670 return
671 except:
672 errors.append("raised wrong exception")
673
674 errors = []
675 self.cur.execute("insert into test(name) values ('a')")
676 self.cur.execute("select name from test")
677 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
678 t.start()
679 t.join()
680 if len(errors) > 0:
681 self.fail("\n".join(errors))
682
683class ConstructorTests(unittest.TestCase):
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100684 def test_date(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000685 d = sqlite.Date(2004, 10, 28)
686
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100687 def test_time(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000688 t = sqlite.Time(12, 39, 35)
689
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100690 def test_timestamp(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000691 ts = sqlite.Timestamp(2004, 10, 28, 12, 39, 35)
692
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100693 def test_date_from_ticks(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000694 d = sqlite.DateFromTicks(42)
695
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100696 def test_time_from_ticks(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000697 t = sqlite.TimeFromTicks(42)
698
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100699 def test_timestamp_from_ticks(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000700 ts = sqlite.TimestampFromTicks(42)
701
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100702 def test_binary(self):
Guido van Rossumbae07c92007-10-08 02:46:15 +0000703 b = sqlite.Binary(b"\0'")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000704
705class ExtensionTests(unittest.TestCase):
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100706 def test_script_string_sql(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000707 con = sqlite.connect(":memory:")
708 cur = con.cursor()
709 cur.executescript("""
710 -- bla bla
711 /* a stupid comment */
712 create table a(i);
713 insert into a(i) values (5);
714 """)
715 cur.execute("select i from a")
716 res = cur.fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000717 self.assertEqual(res, 5)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000718
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100719 def test_script_syntax_error(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000720 con = sqlite.connect(":memory:")
721 cur = con.cursor()
Berker Peksag1003b342016-06-12 22:34:49 +0300722 with self.assertRaises(sqlite.OperationalError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000723 cur.executescript("create table test(x); asdf; create table test2(x)")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000724
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100725 def test_script_error_normal(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000726 con = sqlite.connect(":memory:")
727 cur = con.cursor()
Berker Peksag1003b342016-06-12 22:34:49 +0300728 with self.assertRaises(sqlite.OperationalError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000729 cur.executescript("create table test(sadfsadfdsa); select foo from hurz;")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000730
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100731 def test_cursor_executescript_as_bytes(self):
Berker Peksagc4154402016-06-12 13:41:47 +0300732 con = sqlite.connect(":memory:")
733 cur = con.cursor()
734 with self.assertRaises(ValueError) as cm:
735 cur.executescript(b"create table test(foo); insert into test(foo) values (5);")
736 self.assertEqual(str(cm.exception), 'script argument must be unicode.')
737
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100738 def test_connection_execute(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000739 con = sqlite.connect(":memory:")
740 result = con.execute("select 5").fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000741 self.assertEqual(result, 5, "Basic test of Connection.execute")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000742
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100743 def test_connection_executemany(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000744 con = sqlite.connect(":memory:")
745 con.execute("create table test(foo)")
746 con.executemany("insert into test(foo) values (?)", [(3,), (4,)])
747 result = con.execute("select foo from test order by foo").fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000748 self.assertEqual(result[0][0], 3, "Basic test of Connection.executemany")
749 self.assertEqual(result[1][0], 4, "Basic test of Connection.executemany")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000750
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100751 def test_connection_executescript(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000752 con = sqlite.connect(":memory:")
753 con.executescript("create table test(foo); insert into test(foo) values (5);")
754 result = con.execute("select foo from test").fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000755 self.assertEqual(result, 5, "Basic test of Connection.executescript")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000756
Gerhard Häringf9cee222010-03-05 15:20:03 +0000757class ClosedConTests(unittest.TestCase):
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100758 def test_closed_con_cursor(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000759 con = sqlite.connect(":memory:")
760 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300761 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000762 cur = con.cursor()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000763
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100764 def test_closed_con_commit(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000765 con = sqlite.connect(":memory:")
766 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300767 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000768 con.commit()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000769
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100770 def test_closed_con_rollback(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000771 con = sqlite.connect(":memory:")
772 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300773 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000774 con.rollback()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000775
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100776 def test_closed_cur_execute(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000777 con = sqlite.connect(":memory:")
778 cur = con.cursor()
779 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300780 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000781 cur.execute("select 4")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000782
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100783 def test_closed_create_function(self):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000784 con = sqlite.connect(":memory:")
785 con.close()
786 def f(x): return 17
Berker Peksag1003b342016-06-12 22:34:49 +0300787 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000788 con.create_function("foo", 1, f)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000789
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100790 def test_closed_create_aggregate(self):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000791 con = sqlite.connect(":memory:")
792 con.close()
793 class Agg:
794 def __init__(self):
795 pass
796 def step(self, x):
797 pass
798 def finalize(self):
799 return 17
Berker Peksag1003b342016-06-12 22:34:49 +0300800 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000801 con.create_aggregate("foo", 1, Agg)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000802
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100803 def test_closed_set_authorizer(self):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000804 con = sqlite.connect(":memory:")
805 con.close()
806 def authorizer(*args):
807 return sqlite.DENY
Berker Peksag1003b342016-06-12 22:34:49 +0300808 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000809 con.set_authorizer(authorizer)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000810
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100811 def test_closed_set_progress_callback(self):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000812 con = sqlite.connect(":memory:")
813 con.close()
814 def progress(): pass
Berker Peksag1003b342016-06-12 22:34:49 +0300815 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000816 con.set_progress_handler(progress, 100)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000817
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100818 def test_closed_call(self):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000819 con = sqlite.connect(":memory:")
820 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300821 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000822 con()
Gerhard Häringf9cee222010-03-05 15:20:03 +0000823
824class ClosedCurTests(unittest.TestCase):
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100825 def test_closed(self):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000826 con = sqlite.connect(":memory:")
827 cur = con.cursor()
828 cur.close()
829
830 for method_name in ("execute", "executemany", "executescript", "fetchall", "fetchmany", "fetchone"):
831 if method_name in ("execute", "executescript"):
832 params = ("select 4 union select 5",)
833 elif method_name == "executemany":
834 params = ("insert into foo(bar) values (?)", [(3,), (4,)])
835 else:
836 params = []
837
Berker Peksag1003b342016-06-12 22:34:49 +0300838 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000839 method = getattr(cur, method_name)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000840 method(*params)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000841
Berker Peksag4bf580d2016-09-07 02:04:34 +0300842
843class SqliteOnConflictTests(unittest.TestCase):
844 """
845 Tests for SQLite's "insert on conflict" feature.
846
847 See https://www.sqlite.org/lang_conflict.html for details.
848 """
849
850 def setUp(self):
851 self.cx = sqlite.connect(":memory:")
852 self.cu = self.cx.cursor()
853 self.cu.execute("""
854 CREATE TABLE test(
855 id INTEGER PRIMARY KEY, name TEXT, unique_name TEXT UNIQUE
856 );
857 """)
858
859 def tearDown(self):
860 self.cu.close()
861 self.cx.close()
862
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100863 def test_on_conflict_rollback_with_explicit_transaction(self):
Berker Peksag4bf580d2016-09-07 02:04:34 +0300864 self.cx.isolation_level = None # autocommit mode
865 self.cu = self.cx.cursor()
866 # Start an explicit transaction.
867 self.cu.execute("BEGIN")
868 self.cu.execute("INSERT INTO test(name) VALUES ('abort_test')")
869 self.cu.execute("INSERT OR ROLLBACK INTO test(unique_name) VALUES ('foo')")
870 with self.assertRaises(sqlite.IntegrityError):
871 self.cu.execute("INSERT OR ROLLBACK INTO test(unique_name) VALUES ('foo')")
872 # Use connection to commit.
873 self.cx.commit()
874 self.cu.execute("SELECT name, unique_name from test")
875 # Transaction should have rolled back and nothing should be in table.
876 self.assertEqual(self.cu.fetchall(), [])
877
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100878 def test_on_conflict_abort_raises_with_explicit_transactions(self):
Berker Peksag4bf580d2016-09-07 02:04:34 +0300879 # Abort cancels the current sql statement but doesn't change anything
880 # about the current transaction.
881 self.cx.isolation_level = None # autocommit mode
882 self.cu = self.cx.cursor()
883 # Start an explicit transaction.
884 self.cu.execute("BEGIN")
885 self.cu.execute("INSERT INTO test(name) VALUES ('abort_test')")
886 self.cu.execute("INSERT OR ABORT INTO test(unique_name) VALUES ('foo')")
887 with self.assertRaises(sqlite.IntegrityError):
888 self.cu.execute("INSERT OR ABORT INTO test(unique_name) VALUES ('foo')")
889 self.cx.commit()
890 self.cu.execute("SELECT name, unique_name FROM test")
891 # Expect the first two inserts to work, third to do nothing.
892 self.assertEqual(self.cu.fetchall(), [('abort_test', None), (None, 'foo',)])
893
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100894 def test_on_conflict_rollback_without_transaction(self):
Berker Peksag4bf580d2016-09-07 02:04:34 +0300895 # Start of implicit transaction
896 self.cu.execute("INSERT INTO test(name) VALUES ('abort_test')")
897 self.cu.execute("INSERT OR ROLLBACK INTO test(unique_name) VALUES ('foo')")
898 with self.assertRaises(sqlite.IntegrityError):
899 self.cu.execute("INSERT OR ROLLBACK INTO test(unique_name) VALUES ('foo')")
900 self.cu.execute("SELECT name, unique_name FROM test")
901 # Implicit transaction is rolled back on error.
902 self.assertEqual(self.cu.fetchall(), [])
903
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100904 def test_on_conflict_abort_raises_without_transactions(self):
Berker Peksag4bf580d2016-09-07 02:04:34 +0300905 # Abort cancels the current sql statement but doesn't change anything
906 # about the current transaction.
907 self.cu.execute("INSERT INTO test(name) VALUES ('abort_test')")
908 self.cu.execute("INSERT OR ABORT INTO test(unique_name) VALUES ('foo')")
909 with self.assertRaises(sqlite.IntegrityError):
910 self.cu.execute("INSERT OR ABORT INTO test(unique_name) VALUES ('foo')")
911 # Make sure all other values were inserted.
912 self.cu.execute("SELECT name, unique_name FROM test")
913 self.assertEqual(self.cu.fetchall(), [('abort_test', None), (None, 'foo',)])
914
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100915 def test_on_conflict_fail(self):
Berker Peksag4bf580d2016-09-07 02:04:34 +0300916 self.cu.execute("INSERT OR FAIL INTO test(unique_name) VALUES ('foo')")
917 with self.assertRaises(sqlite.IntegrityError):
918 self.cu.execute("INSERT OR FAIL INTO test(unique_name) VALUES ('foo')")
919 self.assertEqual(self.cu.fetchall(), [])
920
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100921 def test_on_conflict_ignore(self):
Berker Peksag4bf580d2016-09-07 02:04:34 +0300922 self.cu.execute("INSERT OR IGNORE INTO test(unique_name) VALUES ('foo')")
923 # Nothing should happen.
924 self.cu.execute("INSERT OR IGNORE INTO test(unique_name) VALUES ('foo')")
925 self.cu.execute("SELECT unique_name FROM test")
926 self.assertEqual(self.cu.fetchall(), [('foo',)])
927
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100928 def test_on_conflict_replace(self):
Berker Peksag4bf580d2016-09-07 02:04:34 +0300929 self.cu.execute("INSERT OR REPLACE INTO test(name, unique_name) VALUES ('Data!', 'foo')")
930 # There shouldn't be an IntegrityError exception.
931 self.cu.execute("INSERT OR REPLACE INTO test(name, unique_name) VALUES ('Very different data!', 'foo')")
932 self.cu.execute("SELECT name, unique_name FROM test")
933 self.assertEqual(self.cu.fetchall(), [('Very different data!', 'foo')])
934
935
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000936def suite():
Erlend Egeberg Aasland849e3392021-01-07 01:05:07 +0100937 tests = [
938 ClosedConTests,
939 ClosedCurTests,
940 ConnectionTests,
941 ConstructorTests,
942 CursorTests,
943 ExtensionTests,
944 ModuleTests,
945 SqliteOnConflictTests,
946 ThreadTests,
947 ]
948 return unittest.TestSuite(
949 [unittest.TestLoader().loadTestsFromTestCase(t) for t in tests]
950 )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000951
952def test():
953 runner = unittest.TextTestRunner()
954 runner.run(suite())
955
956if __name__ == "__main__":
957 test()