blob: 51c4d539bde5173403c00b97e19e7387720a814f [file] [log] [blame]
Petri Lehtinenf8547992012-02-02 17:17:36 +02001#-*- coding: iso-8859-1 -*-
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002# pysqlite2/test/dbapi.py: tests for DB-API compliance
3#
Gerhard Häringf9cee222010-03-05 15:20:03 +00004# Copyright (C) 2004-2010 Gerhard Häring <gh@ghaering.de>
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005#
6# This file is part of pysqlite.
7#
8# This software is provided 'as-is', without any express or implied
9# warranty. In no event will the authors be held liable for any damages
10# arising from the use of this software.
11#
12# Permission is granted to anyone to use this software for any purpose,
13# including commercial applications, and to alter it and redistribute it
14# freely, subject to the following restrictions:
15#
16# 1. The origin of this software must not be misrepresented; you must not
17# claim that you wrote the original software. If you use this software
18# in a product, an acknowledgment in the product documentation would be
19# appreciated but is not required.
20# 2. Altered source versions must be plainly marked as such, and must not be
21# misrepresented as being the original software.
22# 3. This notice may not be removed or altered from any source distribution.
23
24import unittest
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000025import sqlite3 as sqlite
Victor Stinner45df8202010-04-28 22:31:17 +000026try:
27 import threading
Brett Cannoncd171c82013-07-04 17:43:24 -040028except ImportError:
Victor Stinner45df8202010-04-28 22:31:17 +000029 threading = None
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000030
Antoine Pitrou902fc8b2013-02-10 00:02:44 +010031from test.support import TESTFN, unlink
32
33
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000034class ModuleTests(unittest.TestCase):
35 def CheckAPILevel(self):
36 self.assertEqual(sqlite.apilevel, "2.0",
37 "apilevel is %s, should be 2.0" % sqlite.apilevel)
38
39 def CheckThreadSafety(self):
40 self.assertEqual(sqlite.threadsafety, 1,
41 "threadsafety is %d, should be 1" % sqlite.threadsafety)
42
43 def CheckParamStyle(self):
44 self.assertEqual(sqlite.paramstyle, "qmark",
45 "paramstyle is '%s', should be 'qmark'" %
46 sqlite.paramstyle)
47
48 def CheckWarning(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +000049 self.assertTrue(issubclass(sqlite.Warning, Exception),
Guido van Rossumcd16bf62007-06-13 18:07:49 +000050 "Warning is not a subclass of Exception")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000051
52 def CheckError(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000053 self.assertTrue(issubclass(sqlite.Error, Exception),
Guido van Rossumcd16bf62007-06-13 18:07:49 +000054 "Error is not a subclass of Exception")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000055
56 def CheckInterfaceError(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000057 self.assertTrue(issubclass(sqlite.InterfaceError, sqlite.Error),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000058 "InterfaceError is not a subclass of Error")
59
60 def CheckDatabaseError(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000061 self.assertTrue(issubclass(sqlite.DatabaseError, sqlite.Error),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000062 "DatabaseError is not a subclass of Error")
63
64 def CheckDataError(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000065 self.assertTrue(issubclass(sqlite.DataError, sqlite.DatabaseError),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000066 "DataError is not a subclass of DatabaseError")
67
68 def CheckOperationalError(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000069 self.assertTrue(issubclass(sqlite.OperationalError, sqlite.DatabaseError),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000070 "OperationalError is not a subclass of DatabaseError")
71
72 def CheckIntegrityError(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000073 self.assertTrue(issubclass(sqlite.IntegrityError, sqlite.DatabaseError),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000074 "IntegrityError is not a subclass of DatabaseError")
75
76 def CheckInternalError(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000077 self.assertTrue(issubclass(sqlite.InternalError, sqlite.DatabaseError),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000078 "InternalError is not a subclass of DatabaseError")
79
80 def CheckProgrammingError(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000081 self.assertTrue(issubclass(sqlite.ProgrammingError, sqlite.DatabaseError),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000082 "ProgrammingError is not a subclass of DatabaseError")
83
84 def CheckNotSupportedError(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000085 self.assertTrue(issubclass(sqlite.NotSupportedError,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000086 sqlite.DatabaseError),
87 "NotSupportedError is not a subclass of DatabaseError")
88
89class ConnectionTests(unittest.TestCase):
R. David Murrayd35251d2010-06-01 01:32:12 +000090
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000091 def setUp(self):
92 self.cx = sqlite.connect(":memory:")
93 cu = self.cx.cursor()
94 cu.execute("create table test(id integer primary key, name text)")
95 cu.execute("insert into test(name) values (?)", ("foo",))
96
97 def tearDown(self):
98 self.cx.close()
99
100 def CheckCommit(self):
101 self.cx.commit()
102
103 def CheckCommitAfterNoChanges(self):
104 """
105 A commit should also work when no changes were made to the database.
106 """
107 self.cx.commit()
108 self.cx.commit()
109
110 def CheckRollback(self):
111 self.cx.rollback()
112
113 def CheckRollbackAfterNoChanges(self):
114 """
115 A rollback should also work when no changes were made to the database.
116 """
117 self.cx.rollback()
118 self.cx.rollback()
119
120 def CheckCursor(self):
121 cu = self.cx.cursor()
122
123 def CheckFailedOpen(self):
124 YOU_CANNOT_OPEN_THIS = "/foo/bar/bla/23534/mydb.db"
Berker Peksag1003b342016-06-12 22:34:49 +0300125 with self.assertRaises(sqlite.OperationalError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000126 con = sqlite.connect(YOU_CANNOT_OPEN_THIS)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000127
128 def CheckClose(self):
129 self.cx.close()
130
131 def CheckExceptions(self):
132 # Optional DB-API extension.
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000133 self.assertEqual(self.cx.Warning, sqlite.Warning)
134 self.assertEqual(self.cx.Error, sqlite.Error)
135 self.assertEqual(self.cx.InterfaceError, sqlite.InterfaceError)
136 self.assertEqual(self.cx.DatabaseError, sqlite.DatabaseError)
137 self.assertEqual(self.cx.DataError, sqlite.DataError)
138 self.assertEqual(self.cx.OperationalError, sqlite.OperationalError)
139 self.assertEqual(self.cx.IntegrityError, sqlite.IntegrityError)
140 self.assertEqual(self.cx.InternalError, sqlite.InternalError)
141 self.assertEqual(self.cx.ProgrammingError, sqlite.ProgrammingError)
142 self.assertEqual(self.cx.NotSupportedError, sqlite.NotSupportedError)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000143
R. David Murrayd35251d2010-06-01 01:32:12 +0000144 def CheckInTransaction(self):
145 # Can't use db from setUp because we want to test initial state.
146 cx = sqlite.connect(":memory:")
147 cu = cx.cursor()
148 self.assertEqual(cx.in_transaction, False)
149 cu.execute("create table transactiontest(id integer primary key, name text)")
150 self.assertEqual(cx.in_transaction, False)
151 cu.execute("insert into transactiontest(name) values (?)", ("foo",))
152 self.assertEqual(cx.in_transaction, True)
153 cu.execute("select name from transactiontest where name=?", ["foo"])
154 row = cu.fetchone()
155 self.assertEqual(cx.in_transaction, True)
156 cx.commit()
157 self.assertEqual(cx.in_transaction, False)
158 cu.execute("select name from transactiontest where name=?", ["foo"])
159 row = cu.fetchone()
160 self.assertEqual(cx.in_transaction, False)
161
162 def CheckInTransactionRO(self):
163 with self.assertRaises(AttributeError):
164 self.cx.in_transaction = True
165
Antoine Pitrou902fc8b2013-02-10 00:02:44 +0100166 def CheckOpenUri(self):
167 if sqlite.sqlite_version_info < (3, 7, 7):
168 with self.assertRaises(sqlite.NotSupportedError):
169 sqlite.connect(':memory:', uri=True)
170 return
171 self.addCleanup(unlink, TESTFN)
172 with sqlite.connect(TESTFN) as cx:
173 cx.execute('create table test(id integer)')
174 with sqlite.connect('file:' + TESTFN, uri=True) as cx:
175 cx.execute('insert into test(id) values(0)')
176 with sqlite.connect('file:' + TESTFN + '?mode=ro', uri=True) as cx:
177 with self.assertRaises(sqlite.OperationalError):
178 cx.execute('insert into test(id) values(1)')
179
Berker Peksagf85bce72016-06-14 14:19:02 +0300180 @unittest.skipIf(sqlite.sqlite_version_info >= (3, 3, 1),
181 'needs sqlite versions older than 3.3.1')
Berker Peksag7bea2342016-06-12 14:09:51 +0300182 def CheckSameThreadErrorOnOldVersion(self):
Berker Peksag7bea2342016-06-12 14:09:51 +0300183 with self.assertRaises(sqlite.NotSupportedError) as cm:
184 sqlite.connect(':memory:', check_same_thread=False)
185 self.assertEqual(str(cm.exception), 'shared connections not available')
Antoine Pitrou902fc8b2013-02-10 00:02:44 +0100186
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000187class CursorTests(unittest.TestCase):
188 def setUp(self):
189 self.cx = sqlite.connect(":memory:")
190 self.cu = self.cx.cursor()
Berker Peksage0b70cd2016-06-14 15:25:36 +0300191 self.cu.execute(
192 "create table test(id integer primary key, name text, "
193 "income number, unique_test text unique)"
194 )
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000195 self.cu.execute("insert into test(name) values (?)", ("foo",))
196
197 def tearDown(self):
198 self.cu.close()
199 self.cx.close()
200
201 def CheckExecuteNoArgs(self):
202 self.cu.execute("delete from test")
203
204 def CheckExecuteIllegalSql(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300205 with self.assertRaises(sqlite.OperationalError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000206 self.cu.execute("select asdf")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000207
208 def CheckExecuteTooMuchSql(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300209 with self.assertRaises(sqlite.Warning):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000210 self.cu.execute("select 5+4; select 4+5")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000211
212 def CheckExecuteTooMuchSql2(self):
213 self.cu.execute("select 5+4; -- foo bar")
214
215 def CheckExecuteTooMuchSql3(self):
216 self.cu.execute("""
217 select 5+4;
218
219 /*
220 foo
221 */
222 """)
223
224 def CheckExecuteWrongSqlArg(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300225 with self.assertRaises(ValueError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000226 self.cu.execute(42)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000227
228 def CheckExecuteArgInt(self):
229 self.cu.execute("insert into test(id) values (?)", (42,))
230
231 def CheckExecuteArgFloat(self):
232 self.cu.execute("insert into test(income) values (?)", (2500.32,))
233
234 def CheckExecuteArgString(self):
235 self.cu.execute("insert into test(name) values (?)", ("Hugo",))
236
Petri Lehtinen023fe332012-02-01 22:18:19 +0200237 def CheckExecuteArgStringWithZeroByte(self):
238 self.cu.execute("insert into test(name) values (?)", ("Hu\x00go",))
239
240 self.cu.execute("select name from test where id=?", (self.cu.lastrowid,))
241 row = self.cu.fetchone()
242 self.assertEqual(row[0], "Hu\x00go")
243
Berker Peksagc4154402016-06-12 13:41:47 +0300244 def CheckExecuteNonIterable(self):
245 with self.assertRaises(ValueError) as cm:
246 self.cu.execute("insert into test(id) values (?)", 42)
247 self.assertEqual(str(cm.exception), 'parameters are of unsupported type')
248
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000249 def CheckExecuteWrongNoOfArgs1(self):
250 # too many parameters
Berker Peksag1003b342016-06-12 22:34:49 +0300251 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000252 self.cu.execute("insert into test(id) values (?)", (17, "Egon"))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000253
254 def CheckExecuteWrongNoOfArgs2(self):
255 # too little parameters
Berker Peksag1003b342016-06-12 22:34:49 +0300256 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000257 self.cu.execute("insert into test(id) values (?)")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000258
259 def CheckExecuteWrongNoOfArgs3(self):
260 # no parameters, parameters are needed
Berker Peksag1003b342016-06-12 22:34:49 +0300261 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000262 self.cu.execute("insert into test(id) values (?)")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000263
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000264 def CheckExecuteParamList(self):
265 self.cu.execute("insert into test(name) values ('foo')")
266 self.cu.execute("select name from test where name=?", ["foo"])
267 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000268 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000269
270 def CheckExecuteParamSequence(self):
271 class L(object):
272 def __len__(self):
273 return 1
274 def __getitem__(self, x):
275 assert x == 0
276 return "foo"
277
278 self.cu.execute("insert into test(name) values ('foo')")
279 self.cu.execute("select name from test where name=?", L())
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
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000283 def CheckExecuteDictMapping(self):
284 self.cu.execute("insert into test(name) values ('foo')")
285 self.cu.execute("select name from test where name=:name", {"name": "foo"})
286 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000287 self.assertEqual(row[0], "foo")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000288
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000289 def CheckExecuteDictMapping_Mapping(self):
290 class D(dict):
291 def __missing__(self, key):
292 return "foo"
293
294 self.cu.execute("insert into test(name) values ('foo')")
295 self.cu.execute("select name from test where name=:name", D())
296 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000297 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000298
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000299 def CheckExecuteDictMappingTooLittleArgs(self):
300 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag1003b342016-06-12 22:34:49 +0300301 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000302 self.cu.execute("select name from test where name=:name and id=:id", {"name": "foo"})
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000303
304 def CheckExecuteDictMappingNoArgs(self):
305 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag1003b342016-06-12 22:34:49 +0300306 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000307 self.cu.execute("select name from test where name=:name")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000308
309 def CheckExecuteDictMappingUnnamed(self):
310 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag1003b342016-06-12 22:34:49 +0300311 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000312 self.cu.execute("select name from test where name=?", {"name": "foo"})
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000313
314 def CheckClose(self):
315 self.cu.close()
316
317 def CheckRowcountExecute(self):
318 self.cu.execute("delete from test")
319 self.cu.execute("insert into test(name) values ('foo')")
320 self.cu.execute("insert into test(name) values ('foo')")
321 self.cu.execute("update test set name='bar'")
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000322 self.assertEqual(self.cu.rowcount, 2)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000323
Georg Brandlf78e02b2008-06-10 17:40:04 +0000324 def CheckRowcountSelect(self):
325 """
326 pysqlite does not know the rowcount of SELECT statements, because we
327 don't fetch all rows after executing the select statement. The rowcount
328 has thus to be -1.
329 """
330 self.cu.execute("select 5 union select 6")
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000331 self.assertEqual(self.cu.rowcount, -1)
Georg Brandlf78e02b2008-06-10 17:40:04 +0000332
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000333 def CheckRowcountExecutemany(self):
334 self.cu.execute("delete from test")
335 self.cu.executemany("insert into test(name) values (?)", [(1,), (2,), (3,)])
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000336 self.assertEqual(self.cu.rowcount, 3)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000337
338 def CheckTotalChanges(self):
339 self.cu.execute("insert into test(name) values ('foo')")
340 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag48b5c982016-06-14 00:42:50 +0300341 self.assertLess(2, self.cx.total_changes, msg='total changes reported wrong value')
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000342
343 # Checks for executemany:
344 # Sequences are required by the DB-API, iterators
345 # enhancements in pysqlite.
346
347 def CheckExecuteManySequence(self):
348 self.cu.executemany("insert into test(income) values (?)", [(x,) for x in range(100, 110)])
349
350 def CheckExecuteManyIterator(self):
351 class MyIter:
352 def __init__(self):
353 self.value = 5
354
Georg Brandla18af4e2007-04-21 15:47:16 +0000355 def __next__(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000356 if self.value == 10:
357 raise StopIteration
358 else:
359 self.value += 1
360 return (self.value,)
361
362 self.cu.executemany("insert into test(income) values (?)", MyIter())
363
364 def CheckExecuteManyGenerator(self):
365 def mygen():
366 for i in range(5):
367 yield (i,)
368
369 self.cu.executemany("insert into test(income) values (?)", mygen())
370
371 def CheckExecuteManyWrongSqlArg(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300372 with self.assertRaises(ValueError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000373 self.cu.executemany(42, [(3,)])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000374
375 def CheckExecuteManySelect(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300376 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000377 self.cu.executemany("select ?", [(3,)])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000378
379 def CheckExecuteManyNotIterable(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300380 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000381 self.cu.executemany("insert into test(income) values (?)", 42)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000382
383 def CheckFetchIter(self):
384 # Optional DB-API extension.
385 self.cu.execute("delete from test")
386 self.cu.execute("insert into test(id) values (?)", (5,))
387 self.cu.execute("insert into test(id) values (?)", (6,))
388 self.cu.execute("select id from test order by id")
389 lst = []
390 for row in self.cu:
391 lst.append(row[0])
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000392 self.assertEqual(lst[0], 5)
393 self.assertEqual(lst[1], 6)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000394
395 def CheckFetchone(self):
396 self.cu.execute("select name from test")
397 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000398 self.assertEqual(row[0], "foo")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000399 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000400 self.assertEqual(row, None)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000401
402 def CheckFetchoneNoStatement(self):
403 cur = self.cx.cursor()
404 row = cur.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000405 self.assertEqual(row, None)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000406
407 def CheckArraySize(self):
408 # must default ot 1
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000409 self.assertEqual(self.cu.arraysize, 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000410
411 # now set to 2
412 self.cu.arraysize = 2
413
414 # now make the query return 3 rows
415 self.cu.execute("delete from test")
416 self.cu.execute("insert into test(name) values ('A')")
417 self.cu.execute("insert into test(name) values ('B')")
418 self.cu.execute("insert into test(name) values ('C')")
419 self.cu.execute("select name from test")
420 res = self.cu.fetchmany()
421
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000422 self.assertEqual(len(res), 2)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000423
424 def CheckFetchmany(self):
425 self.cu.execute("select name from test")
426 res = self.cu.fetchmany(100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000427 self.assertEqual(len(res), 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000428 res = self.cu.fetchmany(100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000429 self.assertEqual(res, [])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000430
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000431 def CheckFetchmanyKwArg(self):
432 """Checks if fetchmany works with keyword arguments"""
433 self.cu.execute("select name from test")
434 res = self.cu.fetchmany(size=100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000435 self.assertEqual(len(res), 1)
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000436
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000437 def CheckFetchall(self):
438 self.cu.execute("select name from test")
439 res = self.cu.fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000440 self.assertEqual(len(res), 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000441 res = self.cu.fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000442 self.assertEqual(res, [])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000443
444 def CheckSetinputsizes(self):
445 self.cu.setinputsizes([3, 4, 5])
446
447 def CheckSetoutputsize(self):
448 self.cu.setoutputsize(5, 0)
449
450 def CheckSetoutputsizeNoColumn(self):
451 self.cu.setoutputsize(42)
452
453 def CheckCursorConnection(self):
454 # Optional DB-API extension.
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000455 self.assertEqual(self.cu.connection, self.cx)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000456
457 def CheckWrongCursorCallable(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300458 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000459 def f(): pass
460 cur = self.cx.cursor(f)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000461
462 def CheckCursorWrongClass(self):
463 class Foo: pass
464 foo = Foo()
Berker Peksag1003b342016-06-12 22:34:49 +0300465 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000466 cur = sqlite.Cursor(foo)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000467
Berker Peksage0b70cd2016-06-14 15:25:36 +0300468 def CheckLastRowIDOnReplace(self):
469 """
470 INSERT OR REPLACE and REPLACE INTO should produce the same behavior.
471 """
472 sql = '{} INTO test(id, unique_test) VALUES (?, ?)'
473 for statement in ('INSERT OR REPLACE', 'REPLACE'):
474 with self.subTest(statement=statement):
475 self.cu.execute(sql.format(statement), (1, 'foo'))
476 self.assertEqual(self.cu.lastrowid, 1)
477
478 def CheckLastRowIDOnIgnore(self):
479 self.cu.execute(
480 "insert or ignore into test(unique_test) values (?)",
481 ('test',))
482 self.assertEqual(self.cu.lastrowid, 2)
483 self.cu.execute(
484 "insert or ignore into test(unique_test) values (?)",
485 ('test',))
486 self.assertEqual(self.cu.lastrowid, 2)
487
488 def CheckLastRowIDInsertOR(self):
489 results = []
490 for statement in ('FAIL', 'ABORT', 'ROLLBACK'):
491 sql = 'INSERT OR {} INTO test(unique_test) VALUES (?)'
492 with self.subTest(statement='INSERT OR {}'.format(statement)):
493 self.cu.execute(sql.format(statement), (statement,))
494 results.append((statement, self.cu.lastrowid))
495 with self.assertRaises(sqlite.IntegrityError):
496 self.cu.execute(sql.format(statement), (statement,))
497 results.append((statement, self.cu.lastrowid))
498 expected = [
499 ('FAIL', 2), ('FAIL', 2),
500 ('ABORT', 3), ('ABORT', 3),
501 ('ROLLBACK', 4), ('ROLLBACK', 4),
502 ]
503 self.assertEqual(results, expected)
504
505
Victor Stinner45df8202010-04-28 22:31:17 +0000506@unittest.skipUnless(threading, 'This test requires threading.')
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000507class ThreadTests(unittest.TestCase):
508 def setUp(self):
509 self.con = sqlite.connect(":memory:")
510 self.cur = self.con.cursor()
511 self.cur.execute("create table test(id integer primary key, name text, bin binary, ratio number, ts timestamp)")
512
513 def tearDown(self):
514 self.cur.close()
515 self.con.close()
516
517 def CheckConCursor(self):
518 def run(con, errors):
519 try:
520 cur = con.cursor()
521 errors.append("did not raise ProgrammingError")
522 return
523 except sqlite.ProgrammingError:
524 return
525 except:
526 errors.append("raised wrong exception")
527
528 errors = []
529 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
530 t.start()
531 t.join()
532 if len(errors) > 0:
533 self.fail("\n".join(errors))
534
535 def CheckConCommit(self):
536 def run(con, errors):
537 try:
538 con.commit()
539 errors.append("did not raise ProgrammingError")
540 return
541 except sqlite.ProgrammingError:
542 return
543 except:
544 errors.append("raised wrong exception")
545
546 errors = []
547 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
548 t.start()
549 t.join()
550 if len(errors) > 0:
551 self.fail("\n".join(errors))
552
553 def CheckConRollback(self):
554 def run(con, errors):
555 try:
556 con.rollback()
557 errors.append("did not raise ProgrammingError")
558 return
559 except sqlite.ProgrammingError:
560 return
561 except:
562 errors.append("raised wrong exception")
563
564 errors = []
565 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
566 t.start()
567 t.join()
568 if len(errors) > 0:
569 self.fail("\n".join(errors))
570
571 def CheckConClose(self):
572 def run(con, errors):
573 try:
574 con.close()
575 errors.append("did not raise ProgrammingError")
576 return
577 except sqlite.ProgrammingError:
578 return
579 except:
580 errors.append("raised wrong exception")
581
582 errors = []
583 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
584 t.start()
585 t.join()
586 if len(errors) > 0:
587 self.fail("\n".join(errors))
588
589 def CheckCurImplicitBegin(self):
590 def run(cur, errors):
591 try:
592 cur.execute("insert into test(name) values ('a')")
593 errors.append("did not raise ProgrammingError")
594 return
595 except sqlite.ProgrammingError:
596 return
597 except:
598 errors.append("raised wrong exception")
599
600 errors = []
601 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
602 t.start()
603 t.join()
604 if len(errors) > 0:
605 self.fail("\n".join(errors))
606
607 def CheckCurClose(self):
608 def run(cur, errors):
609 try:
610 cur.close()
611 errors.append("did not raise ProgrammingError")
612 return
613 except sqlite.ProgrammingError:
614 return
615 except:
616 errors.append("raised wrong exception")
617
618 errors = []
619 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
620 t.start()
621 t.join()
622 if len(errors) > 0:
623 self.fail("\n".join(errors))
624
625 def CheckCurExecute(self):
626 def run(cur, errors):
627 try:
628 cur.execute("select name from test")
629 errors.append("did not raise ProgrammingError")
630 return
631 except sqlite.ProgrammingError:
632 return
633 except:
634 errors.append("raised wrong exception")
635
636 errors = []
637 self.cur.execute("insert into test(name) values ('a')")
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
644 def CheckCurIterNext(self):
645 def run(cur, errors):
646 try:
647 row = cur.fetchone()
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 self.cur.execute("select name from test")
658 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
659 t.start()
660 t.join()
661 if len(errors) > 0:
662 self.fail("\n".join(errors))
663
664class ConstructorTests(unittest.TestCase):
665 def CheckDate(self):
666 d = sqlite.Date(2004, 10, 28)
667
668 def CheckTime(self):
669 t = sqlite.Time(12, 39, 35)
670
671 def CheckTimestamp(self):
672 ts = sqlite.Timestamp(2004, 10, 28, 12, 39, 35)
673
674 def CheckDateFromTicks(self):
675 d = sqlite.DateFromTicks(42)
676
677 def CheckTimeFromTicks(self):
678 t = sqlite.TimeFromTicks(42)
679
680 def CheckTimestampFromTicks(self):
681 ts = sqlite.TimestampFromTicks(42)
682
683 def CheckBinary(self):
Guido van Rossumbae07c92007-10-08 02:46:15 +0000684 b = sqlite.Binary(b"\0'")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000685
686class ExtensionTests(unittest.TestCase):
687 def CheckScriptStringSql(self):
688 con = sqlite.connect(":memory:")
689 cur = con.cursor()
690 cur.executescript("""
691 -- bla bla
692 /* a stupid comment */
693 create table a(i);
694 insert into a(i) values (5);
695 """)
696 cur.execute("select i from a")
697 res = cur.fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000698 self.assertEqual(res, 5)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000699
Gerhard Häringf9cee222010-03-05 15:20:03 +0000700 def CheckScriptSyntaxError(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000701 con = sqlite.connect(":memory:")
702 cur = con.cursor()
Berker Peksag1003b342016-06-12 22:34:49 +0300703 with self.assertRaises(sqlite.OperationalError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000704 cur.executescript("create table test(x); asdf; create table test2(x)")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000705
706 def CheckScriptErrorNormal(self):
707 con = sqlite.connect(":memory:")
708 cur = con.cursor()
Berker Peksag1003b342016-06-12 22:34:49 +0300709 with self.assertRaises(sqlite.OperationalError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000710 cur.executescript("create table test(sadfsadfdsa); select foo from hurz;")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000711
Berker Peksagc4154402016-06-12 13:41:47 +0300712 def CheckCursorExecutescriptAsBytes(self):
713 con = sqlite.connect(":memory:")
714 cur = con.cursor()
715 with self.assertRaises(ValueError) as cm:
716 cur.executescript(b"create table test(foo); insert into test(foo) values (5);")
717 self.assertEqual(str(cm.exception), 'script argument must be unicode.')
718
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000719 def CheckConnectionExecute(self):
720 con = sqlite.connect(":memory:")
721 result = con.execute("select 5").fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000722 self.assertEqual(result, 5, "Basic test of Connection.execute")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000723
724 def CheckConnectionExecutemany(self):
725 con = sqlite.connect(":memory:")
726 con.execute("create table test(foo)")
727 con.executemany("insert into test(foo) values (?)", [(3,), (4,)])
728 result = con.execute("select foo from test order by foo").fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000729 self.assertEqual(result[0][0], 3, "Basic test of Connection.executemany")
730 self.assertEqual(result[1][0], 4, "Basic test of Connection.executemany")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000731
732 def CheckConnectionExecutescript(self):
733 con = sqlite.connect(":memory:")
734 con.executescript("create table test(foo); insert into test(foo) values (5);")
735 result = con.execute("select foo from test").fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000736 self.assertEqual(result, 5, "Basic test of Connection.executescript")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000737
Gerhard Häringf9cee222010-03-05 15:20:03 +0000738class ClosedConTests(unittest.TestCase):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000739 def CheckClosedConCursor(self):
740 con = sqlite.connect(":memory:")
741 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300742 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000743 cur = con.cursor()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000744
745 def CheckClosedConCommit(self):
746 con = sqlite.connect(":memory:")
747 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300748 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000749 con.commit()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000750
751 def CheckClosedConRollback(self):
752 con = sqlite.connect(":memory:")
753 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300754 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000755 con.rollback()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000756
757 def CheckClosedCurExecute(self):
758 con = sqlite.connect(":memory:")
759 cur = con.cursor()
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.execute("select 4")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000763
Gerhard Häringf9cee222010-03-05 15:20:03 +0000764 def CheckClosedCreateFunction(self):
765 con = sqlite.connect(":memory:")
766 con.close()
767 def f(x): return 17
Berker Peksag1003b342016-06-12 22:34:49 +0300768 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000769 con.create_function("foo", 1, f)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000770
771 def CheckClosedCreateAggregate(self):
772 con = sqlite.connect(":memory:")
773 con.close()
774 class Agg:
775 def __init__(self):
776 pass
777 def step(self, x):
778 pass
779 def finalize(self):
780 return 17
Berker Peksag1003b342016-06-12 22:34:49 +0300781 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000782 con.create_aggregate("foo", 1, Agg)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000783
784 def CheckClosedSetAuthorizer(self):
785 con = sqlite.connect(":memory:")
786 con.close()
787 def authorizer(*args):
788 return sqlite.DENY
Berker Peksag1003b342016-06-12 22:34:49 +0300789 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000790 con.set_authorizer(authorizer)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000791
792 def CheckClosedSetProgressCallback(self):
793 con = sqlite.connect(":memory:")
794 con.close()
795 def progress(): pass
Berker Peksag1003b342016-06-12 22:34:49 +0300796 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000797 con.set_progress_handler(progress, 100)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000798
799 def CheckClosedCall(self):
800 con = sqlite.connect(":memory:")
801 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300802 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000803 con()
Gerhard Häringf9cee222010-03-05 15:20:03 +0000804
805class ClosedCurTests(unittest.TestCase):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000806 def CheckClosed(self):
807 con = sqlite.connect(":memory:")
808 cur = con.cursor()
809 cur.close()
810
811 for method_name in ("execute", "executemany", "executescript", "fetchall", "fetchmany", "fetchone"):
812 if method_name in ("execute", "executescript"):
813 params = ("select 4 union select 5",)
814 elif method_name == "executemany":
815 params = ("insert into foo(bar) values (?)", [(3,), (4,)])
816 else:
817 params = []
818
Berker Peksag1003b342016-06-12 22:34:49 +0300819 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000820 method = getattr(cur, method_name)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000821 method(*params)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000822
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000823def suite():
824 module_suite = unittest.makeSuite(ModuleTests, "Check")
825 connection_suite = unittest.makeSuite(ConnectionTests, "Check")
826 cursor_suite = unittest.makeSuite(CursorTests, "Check")
827 thread_suite = unittest.makeSuite(ThreadTests, "Check")
828 constructor_suite = unittest.makeSuite(ConstructorTests, "Check")
829 ext_suite = unittest.makeSuite(ExtensionTests, "Check")
Gerhard Häringf9cee222010-03-05 15:20:03 +0000830 closed_con_suite = unittest.makeSuite(ClosedConTests, "Check")
831 closed_cur_suite = unittest.makeSuite(ClosedCurTests, "Check")
832 return unittest.TestSuite((module_suite, connection_suite, cursor_suite, thread_suite, constructor_suite, ext_suite, closed_con_suite, closed_cur_suite))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000833
834def test():
835 runner = unittest.TextTestRunner()
836 runner.run(suite())
837
838if __name__ == "__main__":
839 test()