blob: 04d04794c79d0435ebcb6c191f9b333565bbd9ee [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"
125 try:
126 con = sqlite.connect(YOU_CANNOT_OPEN_THIS)
127 except sqlite.OperationalError:
128 return
129 self.fail("should have raised an OperationalError")
130
131 def CheckClose(self):
132 self.cx.close()
133
134 def CheckExceptions(self):
135 # Optional DB-API extension.
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000136 self.assertEqual(self.cx.Warning, sqlite.Warning)
137 self.assertEqual(self.cx.Error, sqlite.Error)
138 self.assertEqual(self.cx.InterfaceError, sqlite.InterfaceError)
139 self.assertEqual(self.cx.DatabaseError, sqlite.DatabaseError)
140 self.assertEqual(self.cx.DataError, sqlite.DataError)
141 self.assertEqual(self.cx.OperationalError, sqlite.OperationalError)
142 self.assertEqual(self.cx.IntegrityError, sqlite.IntegrityError)
143 self.assertEqual(self.cx.InternalError, sqlite.InternalError)
144 self.assertEqual(self.cx.ProgrammingError, sqlite.ProgrammingError)
145 self.assertEqual(self.cx.NotSupportedError, sqlite.NotSupportedError)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000146
R. David Murrayd35251d2010-06-01 01:32:12 +0000147 def CheckInTransaction(self):
148 # Can't use db from setUp because we want to test initial state.
149 cx = sqlite.connect(":memory:")
150 cu = cx.cursor()
151 self.assertEqual(cx.in_transaction, False)
152 cu.execute("create table transactiontest(id integer primary key, name text)")
153 self.assertEqual(cx.in_transaction, False)
154 cu.execute("insert into transactiontest(name) values (?)", ("foo",))
155 self.assertEqual(cx.in_transaction, True)
156 cu.execute("select name from transactiontest where name=?", ["foo"])
157 row = cu.fetchone()
158 self.assertEqual(cx.in_transaction, True)
159 cx.commit()
160 self.assertEqual(cx.in_transaction, False)
161 cu.execute("select name from transactiontest where name=?", ["foo"])
162 row = cu.fetchone()
163 self.assertEqual(cx.in_transaction, False)
164
165 def CheckInTransactionRO(self):
166 with self.assertRaises(AttributeError):
167 self.cx.in_transaction = True
168
Antoine Pitrou902fc8b2013-02-10 00:02:44 +0100169 def CheckOpenUri(self):
170 if sqlite.sqlite_version_info < (3, 7, 7):
171 with self.assertRaises(sqlite.NotSupportedError):
172 sqlite.connect(':memory:', uri=True)
173 return
174 self.addCleanup(unlink, TESTFN)
175 with sqlite.connect(TESTFN) as cx:
176 cx.execute('create table test(id integer)')
177 with sqlite.connect('file:' + TESTFN, uri=True) as cx:
178 cx.execute('insert into test(id) values(0)')
179 with sqlite.connect('file:' + TESTFN + '?mode=ro', uri=True) as cx:
180 with self.assertRaises(sqlite.OperationalError):
181 cx.execute('insert into test(id) values(1)')
182
183
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000184class CursorTests(unittest.TestCase):
185 def setUp(self):
186 self.cx = sqlite.connect(":memory:")
187 self.cu = self.cx.cursor()
188 self.cu.execute("create table test(id integer primary key, name text, income number)")
189 self.cu.execute("insert into test(name) values (?)", ("foo",))
190
191 def tearDown(self):
192 self.cu.close()
193 self.cx.close()
194
195 def CheckExecuteNoArgs(self):
196 self.cu.execute("delete from test")
197
198 def CheckExecuteIllegalSql(self):
199 try:
200 self.cu.execute("select asdf")
201 self.fail("should have raised an OperationalError")
202 except sqlite.OperationalError:
203 return
204 except:
205 self.fail("raised wrong exception")
206
207 def CheckExecuteTooMuchSql(self):
208 try:
209 self.cu.execute("select 5+4; select 4+5")
210 self.fail("should have raised a Warning")
211 except sqlite.Warning:
212 return
213 except:
214 self.fail("raised wrong exception")
215
216 def CheckExecuteTooMuchSql2(self):
217 self.cu.execute("select 5+4; -- foo bar")
218
219 def CheckExecuteTooMuchSql3(self):
220 self.cu.execute("""
221 select 5+4;
222
223 /*
224 foo
225 */
226 """)
227
228 def CheckExecuteWrongSqlArg(self):
229 try:
230 self.cu.execute(42)
231 self.fail("should have raised a ValueError")
232 except ValueError:
233 return
234 except:
235 self.fail("raised wrong exception.")
236
237 def CheckExecuteArgInt(self):
238 self.cu.execute("insert into test(id) values (?)", (42,))
239
240 def CheckExecuteArgFloat(self):
241 self.cu.execute("insert into test(income) values (?)", (2500.32,))
242
243 def CheckExecuteArgString(self):
244 self.cu.execute("insert into test(name) values (?)", ("Hugo",))
245
Petri Lehtinen023fe332012-02-01 22:18:19 +0200246 def CheckExecuteArgStringWithZeroByte(self):
247 self.cu.execute("insert into test(name) values (?)", ("Hu\x00go",))
248
249 self.cu.execute("select name from test where id=?", (self.cu.lastrowid,))
250 row = self.cu.fetchone()
251 self.assertEqual(row[0], "Hu\x00go")
252
Berker Peksagc4154402016-06-12 13:41:47 +0300253 def CheckExecuteNonIterable(self):
254 with self.assertRaises(ValueError) as cm:
255 self.cu.execute("insert into test(id) values (?)", 42)
256 self.assertEqual(str(cm.exception), 'parameters are of unsupported type')
257
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000258 def CheckExecuteWrongNoOfArgs1(self):
259 # too many parameters
260 try:
261 self.cu.execute("insert into test(id) values (?)", (17, "Egon"))
262 self.fail("should have raised ProgrammingError")
263 except sqlite.ProgrammingError:
264 pass
265
266 def CheckExecuteWrongNoOfArgs2(self):
267 # too little parameters
268 try:
269 self.cu.execute("insert into test(id) values (?)")
270 self.fail("should have raised ProgrammingError")
271 except sqlite.ProgrammingError:
272 pass
273
274 def CheckExecuteWrongNoOfArgs3(self):
275 # no parameters, parameters are needed
276 try:
277 self.cu.execute("insert into test(id) values (?)")
278 self.fail("should have raised ProgrammingError")
279 except sqlite.ProgrammingError:
280 pass
281
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000282 def CheckExecuteParamList(self):
283 self.cu.execute("insert into test(name) values ('foo')")
284 self.cu.execute("select name from test where name=?", ["foo"])
285 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000286 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000287
288 def CheckExecuteParamSequence(self):
289 class L(object):
290 def __len__(self):
291 return 1
292 def __getitem__(self, x):
293 assert x == 0
294 return "foo"
295
296 self.cu.execute("insert into test(name) values ('foo')")
297 self.cu.execute("select name from test where name=?", L())
298 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000299 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000300
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000301 def CheckExecuteDictMapping(self):
302 self.cu.execute("insert into test(name) values ('foo')")
303 self.cu.execute("select name from test where name=:name", {"name": "foo"})
304 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000305 self.assertEqual(row[0], "foo")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000306
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000307 def CheckExecuteDictMapping_Mapping(self):
308 class D(dict):
309 def __missing__(self, key):
310 return "foo"
311
312 self.cu.execute("insert into test(name) values ('foo')")
313 self.cu.execute("select name from test where name=:name", D())
314 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000315 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000316
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000317 def CheckExecuteDictMappingTooLittleArgs(self):
318 self.cu.execute("insert into test(name) values ('foo')")
319 try:
320 self.cu.execute("select name from test where name=:name and id=:id", {"name": "foo"})
321 self.fail("should have raised ProgrammingError")
322 except sqlite.ProgrammingError:
323 pass
324
325 def CheckExecuteDictMappingNoArgs(self):
326 self.cu.execute("insert into test(name) values ('foo')")
327 try:
328 self.cu.execute("select name from test where name=:name")
329 self.fail("should have raised ProgrammingError")
330 except sqlite.ProgrammingError:
331 pass
332
333 def CheckExecuteDictMappingUnnamed(self):
334 self.cu.execute("insert into test(name) values ('foo')")
335 try:
336 self.cu.execute("select name from test where name=?", {"name": "foo"})
337 self.fail("should have raised ProgrammingError")
338 except sqlite.ProgrammingError:
339 pass
340
341 def CheckClose(self):
342 self.cu.close()
343
344 def CheckRowcountExecute(self):
345 self.cu.execute("delete from test")
346 self.cu.execute("insert into test(name) values ('foo')")
347 self.cu.execute("insert into test(name) values ('foo')")
348 self.cu.execute("update test set name='bar'")
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000349 self.assertEqual(self.cu.rowcount, 2)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000350
Georg Brandlf78e02b2008-06-10 17:40:04 +0000351 def CheckRowcountSelect(self):
352 """
353 pysqlite does not know the rowcount of SELECT statements, because we
354 don't fetch all rows after executing the select statement. The rowcount
355 has thus to be -1.
356 """
357 self.cu.execute("select 5 union select 6")
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000358 self.assertEqual(self.cu.rowcount, -1)
Georg Brandlf78e02b2008-06-10 17:40:04 +0000359
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000360 def CheckRowcountExecutemany(self):
361 self.cu.execute("delete from test")
362 self.cu.executemany("insert into test(name) values (?)", [(1,), (2,), (3,)])
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000363 self.assertEqual(self.cu.rowcount, 3)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000364
365 def CheckTotalChanges(self):
366 self.cu.execute("insert into test(name) values ('foo')")
367 self.cu.execute("insert into test(name) values ('foo')")
368 if self.cx.total_changes < 2:
369 self.fail("total changes reported wrong value")
370
371 # Checks for executemany:
372 # Sequences are required by the DB-API, iterators
373 # enhancements in pysqlite.
374
375 def CheckExecuteManySequence(self):
376 self.cu.executemany("insert into test(income) values (?)", [(x,) for x in range(100, 110)])
377
378 def CheckExecuteManyIterator(self):
379 class MyIter:
380 def __init__(self):
381 self.value = 5
382
Georg Brandla18af4e2007-04-21 15:47:16 +0000383 def __next__(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000384 if self.value == 10:
385 raise StopIteration
386 else:
387 self.value += 1
388 return (self.value,)
389
390 self.cu.executemany("insert into test(income) values (?)", MyIter())
391
392 def CheckExecuteManyGenerator(self):
393 def mygen():
394 for i in range(5):
395 yield (i,)
396
397 self.cu.executemany("insert into test(income) values (?)", mygen())
398
399 def CheckExecuteManyWrongSqlArg(self):
400 try:
401 self.cu.executemany(42, [(3,)])
402 self.fail("should have raised a ValueError")
403 except ValueError:
404 return
405 except:
406 self.fail("raised wrong exception.")
407
408 def CheckExecuteManySelect(self):
409 try:
410 self.cu.executemany("select ?", [(3,)])
411 self.fail("should have raised a ProgrammingError")
412 except sqlite.ProgrammingError:
413 return
414 except:
415 self.fail("raised wrong exception.")
416
417 def CheckExecuteManyNotIterable(self):
418 try:
419 self.cu.executemany("insert into test(income) values (?)", 42)
420 self.fail("should have raised a TypeError")
421 except TypeError:
422 return
Guido van Rossumb940e112007-01-10 16:19:56 +0000423 except Exception as e:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000424 print("raised", e.__class__)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000425 self.fail("raised wrong exception.")
426
427 def CheckFetchIter(self):
428 # Optional DB-API extension.
429 self.cu.execute("delete from test")
430 self.cu.execute("insert into test(id) values (?)", (5,))
431 self.cu.execute("insert into test(id) values (?)", (6,))
432 self.cu.execute("select id from test order by id")
433 lst = []
434 for row in self.cu:
435 lst.append(row[0])
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000436 self.assertEqual(lst[0], 5)
437 self.assertEqual(lst[1], 6)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000438
439 def CheckFetchone(self):
440 self.cu.execute("select name from test")
441 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000442 self.assertEqual(row[0], "foo")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000443 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000444 self.assertEqual(row, None)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000445
446 def CheckFetchoneNoStatement(self):
447 cur = self.cx.cursor()
448 row = cur.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000449 self.assertEqual(row, None)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000450
451 def CheckArraySize(self):
452 # must default ot 1
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000453 self.assertEqual(self.cu.arraysize, 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000454
455 # now set to 2
456 self.cu.arraysize = 2
457
458 # now make the query return 3 rows
459 self.cu.execute("delete from test")
460 self.cu.execute("insert into test(name) values ('A')")
461 self.cu.execute("insert into test(name) values ('B')")
462 self.cu.execute("insert into test(name) values ('C')")
463 self.cu.execute("select name from test")
464 res = self.cu.fetchmany()
465
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000466 self.assertEqual(len(res), 2)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000467
468 def CheckFetchmany(self):
469 self.cu.execute("select name from test")
470 res = self.cu.fetchmany(100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000471 self.assertEqual(len(res), 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000472 res = self.cu.fetchmany(100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000473 self.assertEqual(res, [])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000474
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000475 def CheckFetchmanyKwArg(self):
476 """Checks if fetchmany works with keyword arguments"""
477 self.cu.execute("select name from test")
478 res = self.cu.fetchmany(size=100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000479 self.assertEqual(len(res), 1)
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000480
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000481 def CheckFetchall(self):
482 self.cu.execute("select name from test")
483 res = self.cu.fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000484 self.assertEqual(len(res), 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000485 res = self.cu.fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000486 self.assertEqual(res, [])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000487
488 def CheckSetinputsizes(self):
489 self.cu.setinputsizes([3, 4, 5])
490
491 def CheckSetoutputsize(self):
492 self.cu.setoutputsize(5, 0)
493
494 def CheckSetoutputsizeNoColumn(self):
495 self.cu.setoutputsize(42)
496
497 def CheckCursorConnection(self):
498 # Optional DB-API extension.
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000499 self.assertEqual(self.cu.connection, self.cx)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000500
501 def CheckWrongCursorCallable(self):
502 try:
503 def f(): pass
504 cur = self.cx.cursor(f)
505 self.fail("should have raised a TypeError")
506 except TypeError:
507 return
508 self.fail("should have raised a ValueError")
509
510 def CheckCursorWrongClass(self):
511 class Foo: pass
512 foo = Foo()
513 try:
514 cur = sqlite.Cursor(foo)
515 self.fail("should have raised a ValueError")
516 except TypeError:
517 pass
518
Victor Stinner45df8202010-04-28 22:31:17 +0000519@unittest.skipUnless(threading, 'This test requires threading.')
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000520class ThreadTests(unittest.TestCase):
521 def setUp(self):
522 self.con = sqlite.connect(":memory:")
523 self.cur = self.con.cursor()
524 self.cur.execute("create table test(id integer primary key, name text, bin binary, ratio number, ts timestamp)")
525
526 def tearDown(self):
527 self.cur.close()
528 self.con.close()
529
530 def CheckConCursor(self):
531 def run(con, errors):
532 try:
533 cur = con.cursor()
534 errors.append("did not raise ProgrammingError")
535 return
536 except sqlite.ProgrammingError:
537 return
538 except:
539 errors.append("raised wrong exception")
540
541 errors = []
542 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
543 t.start()
544 t.join()
545 if len(errors) > 0:
546 self.fail("\n".join(errors))
547
548 def CheckConCommit(self):
549 def run(con, errors):
550 try:
551 con.commit()
552 errors.append("did not raise ProgrammingError")
553 return
554 except sqlite.ProgrammingError:
555 return
556 except:
557 errors.append("raised wrong exception")
558
559 errors = []
560 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
561 t.start()
562 t.join()
563 if len(errors) > 0:
564 self.fail("\n".join(errors))
565
566 def CheckConRollback(self):
567 def run(con, errors):
568 try:
569 con.rollback()
570 errors.append("did not raise ProgrammingError")
571 return
572 except sqlite.ProgrammingError:
573 return
574 except:
575 errors.append("raised wrong exception")
576
577 errors = []
578 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
579 t.start()
580 t.join()
581 if len(errors) > 0:
582 self.fail("\n".join(errors))
583
584 def CheckConClose(self):
585 def run(con, errors):
586 try:
587 con.close()
588 errors.append("did not raise ProgrammingError")
589 return
590 except sqlite.ProgrammingError:
591 return
592 except:
593 errors.append("raised wrong exception")
594
595 errors = []
596 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
597 t.start()
598 t.join()
599 if len(errors) > 0:
600 self.fail("\n".join(errors))
601
602 def CheckCurImplicitBegin(self):
603 def run(cur, errors):
604 try:
605 cur.execute("insert into test(name) values ('a')")
606 errors.append("did not raise ProgrammingError")
607 return
608 except sqlite.ProgrammingError:
609 return
610 except:
611 errors.append("raised wrong exception")
612
613 errors = []
614 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
615 t.start()
616 t.join()
617 if len(errors) > 0:
618 self.fail("\n".join(errors))
619
620 def CheckCurClose(self):
621 def run(cur, errors):
622 try:
623 cur.close()
624 errors.append("did not raise ProgrammingError")
625 return
626 except sqlite.ProgrammingError:
627 return
628 except:
629 errors.append("raised wrong exception")
630
631 errors = []
632 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
633 t.start()
634 t.join()
635 if len(errors) > 0:
636 self.fail("\n".join(errors))
637
638 def CheckCurExecute(self):
639 def run(cur, errors):
640 try:
641 cur.execute("select name from test")
642 errors.append("did not raise ProgrammingError")
643 return
644 except sqlite.ProgrammingError:
645 return
646 except:
647 errors.append("raised wrong exception")
648
649 errors = []
650 self.cur.execute("insert into test(name) values ('a')")
651 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
652 t.start()
653 t.join()
654 if len(errors) > 0:
655 self.fail("\n".join(errors))
656
657 def CheckCurIterNext(self):
658 def run(cur, errors):
659 try:
660 row = cur.fetchone()
661 errors.append("did not raise ProgrammingError")
662 return
663 except sqlite.ProgrammingError:
664 return
665 except:
666 errors.append("raised wrong exception")
667
668 errors = []
669 self.cur.execute("insert into test(name) values ('a')")
670 self.cur.execute("select name from test")
671 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
672 t.start()
673 t.join()
674 if len(errors) > 0:
675 self.fail("\n".join(errors))
676
677class ConstructorTests(unittest.TestCase):
678 def CheckDate(self):
679 d = sqlite.Date(2004, 10, 28)
680
681 def CheckTime(self):
682 t = sqlite.Time(12, 39, 35)
683
684 def CheckTimestamp(self):
685 ts = sqlite.Timestamp(2004, 10, 28, 12, 39, 35)
686
687 def CheckDateFromTicks(self):
688 d = sqlite.DateFromTicks(42)
689
690 def CheckTimeFromTicks(self):
691 t = sqlite.TimeFromTicks(42)
692
693 def CheckTimestampFromTicks(self):
694 ts = sqlite.TimestampFromTicks(42)
695
696 def CheckBinary(self):
Guido van Rossumbae07c92007-10-08 02:46:15 +0000697 b = sqlite.Binary(b"\0'")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000698
699class ExtensionTests(unittest.TestCase):
700 def CheckScriptStringSql(self):
701 con = sqlite.connect(":memory:")
702 cur = con.cursor()
703 cur.executescript("""
704 -- bla bla
705 /* a stupid comment */
706 create table a(i);
707 insert into a(i) values (5);
708 """)
709 cur.execute("select i from a")
710 res = cur.fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000711 self.assertEqual(res, 5)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000712
Gerhard Häringf9cee222010-03-05 15:20:03 +0000713 def CheckScriptSyntaxError(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000714 con = sqlite.connect(":memory:")
715 cur = con.cursor()
716 raised = False
717 try:
Gerhard Häringf9cee222010-03-05 15:20:03 +0000718 cur.executescript("create table test(x); asdf; create table test2(x)")
719 except sqlite.OperationalError:
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000720 raised = True
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000721 self.assertEqual(raised, True, "should have raised an exception")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000722
723 def CheckScriptErrorNormal(self):
724 con = sqlite.connect(":memory:")
725 cur = con.cursor()
726 raised = False
727 try:
728 cur.executescript("create table test(sadfsadfdsa); select foo from hurz;")
729 except sqlite.OperationalError:
730 raised = True
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000731 self.assertEqual(raised, True, "should have raised an exception")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000732
Berker Peksagc4154402016-06-12 13:41:47 +0300733 def CheckCursorExecutescriptAsBytes(self):
734 con = sqlite.connect(":memory:")
735 cur = con.cursor()
736 with self.assertRaises(ValueError) as cm:
737 cur.executescript(b"create table test(foo); insert into test(foo) values (5);")
738 self.assertEqual(str(cm.exception), 'script argument must be unicode.')
739
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000740 def CheckConnectionExecute(self):
741 con = sqlite.connect(":memory:")
742 result = con.execute("select 5").fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000743 self.assertEqual(result, 5, "Basic test of Connection.execute")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000744
745 def CheckConnectionExecutemany(self):
746 con = sqlite.connect(":memory:")
747 con.execute("create table test(foo)")
748 con.executemany("insert into test(foo) values (?)", [(3,), (4,)])
749 result = con.execute("select foo from test order by foo").fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000750 self.assertEqual(result[0][0], 3, "Basic test of Connection.executemany")
751 self.assertEqual(result[1][0], 4, "Basic test of Connection.executemany")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000752
753 def CheckConnectionExecutescript(self):
754 con = sqlite.connect(":memory:")
755 con.executescript("create table test(foo); insert into test(foo) values (5);")
756 result = con.execute("select foo from test").fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000757 self.assertEqual(result, 5, "Basic test of Connection.executescript")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000758
Gerhard Häringf9cee222010-03-05 15:20:03 +0000759class ClosedConTests(unittest.TestCase):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000760 def setUp(self):
761 pass
762
763 def tearDown(self):
764 pass
765
766 def CheckClosedConCursor(self):
767 con = sqlite.connect(":memory:")
768 con.close()
769 try:
770 cur = con.cursor()
771 self.fail("Should have raised a ProgrammingError")
772 except sqlite.ProgrammingError:
773 pass
774 except:
775 self.fail("Should have raised a ProgrammingError")
776
777 def CheckClosedConCommit(self):
778 con = sqlite.connect(":memory:")
779 con.close()
780 try:
781 con.commit()
782 self.fail("Should have raised a ProgrammingError")
783 except sqlite.ProgrammingError:
784 pass
785 except:
786 self.fail("Should have raised a ProgrammingError")
787
788 def CheckClosedConRollback(self):
789 con = sqlite.connect(":memory:")
790 con.close()
791 try:
792 con.rollback()
793 self.fail("Should have raised a ProgrammingError")
794 except sqlite.ProgrammingError:
795 pass
796 except:
797 self.fail("Should have raised a ProgrammingError")
798
799 def CheckClosedCurExecute(self):
800 con = sqlite.connect(":memory:")
801 cur = con.cursor()
802 con.close()
803 try:
804 cur.execute("select 4")
805 self.fail("Should have raised a ProgrammingError")
806 except sqlite.ProgrammingError:
807 pass
808 except:
809 self.fail("Should have raised a ProgrammingError")
810
Gerhard Häringf9cee222010-03-05 15:20:03 +0000811 def CheckClosedCreateFunction(self):
812 con = sqlite.connect(":memory:")
813 con.close()
814 def f(x): return 17
815 try:
816 con.create_function("foo", 1, f)
817 self.fail("Should have raised a ProgrammingError")
818 except sqlite.ProgrammingError:
819 pass
820 except:
821 self.fail("Should have raised a ProgrammingError")
822
823 def CheckClosedCreateAggregate(self):
824 con = sqlite.connect(":memory:")
825 con.close()
826 class Agg:
827 def __init__(self):
828 pass
829 def step(self, x):
830 pass
831 def finalize(self):
832 return 17
833 try:
834 con.create_aggregate("foo", 1, Agg)
835 self.fail("Should have raised a ProgrammingError")
836 except sqlite.ProgrammingError:
837 pass
838 except:
839 self.fail("Should have raised a ProgrammingError")
840
841 def CheckClosedSetAuthorizer(self):
842 con = sqlite.connect(":memory:")
843 con.close()
844 def authorizer(*args):
845 return sqlite.DENY
846 try:
847 con.set_authorizer(authorizer)
848 self.fail("Should have raised a ProgrammingError")
849 except sqlite.ProgrammingError:
850 pass
851 except:
852 self.fail("Should have raised a ProgrammingError")
853
854 def CheckClosedSetProgressCallback(self):
855 con = sqlite.connect(":memory:")
856 con.close()
857 def progress(): pass
858 try:
859 con.set_progress_handler(progress, 100)
860 self.fail("Should have raised a ProgrammingError")
861 except sqlite.ProgrammingError:
862 pass
863 except:
864 self.fail("Should have raised a ProgrammingError")
865
866 def CheckClosedCall(self):
867 con = sqlite.connect(":memory:")
868 con.close()
869 try:
870 con()
871 self.fail("Should have raised a ProgrammingError")
872 except sqlite.ProgrammingError:
873 pass
874 except:
875 self.fail("Should have raised a ProgrammingError")
876
877class ClosedCurTests(unittest.TestCase):
878 def setUp(self):
879 pass
880
881 def tearDown(self):
882 pass
883
884 def CheckClosed(self):
885 con = sqlite.connect(":memory:")
886 cur = con.cursor()
887 cur.close()
888
889 for method_name in ("execute", "executemany", "executescript", "fetchall", "fetchmany", "fetchone"):
890 if method_name in ("execute", "executescript"):
891 params = ("select 4 union select 5",)
892 elif method_name == "executemany":
893 params = ("insert into foo(bar) values (?)", [(3,), (4,)])
894 else:
895 params = []
896
897 try:
898 method = getattr(cur, method_name)
899
900 method(*params)
901 self.fail("Should have raised a ProgrammingError: method " + method_name)
902 except sqlite.ProgrammingError:
903 pass
904 except:
905 self.fail("Should have raised a ProgrammingError: " + method_name)
906
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000907def suite():
908 module_suite = unittest.makeSuite(ModuleTests, "Check")
909 connection_suite = unittest.makeSuite(ConnectionTests, "Check")
910 cursor_suite = unittest.makeSuite(CursorTests, "Check")
911 thread_suite = unittest.makeSuite(ThreadTests, "Check")
912 constructor_suite = unittest.makeSuite(ConstructorTests, "Check")
913 ext_suite = unittest.makeSuite(ExtensionTests, "Check")
Gerhard Häringf9cee222010-03-05 15:20:03 +0000914 closed_con_suite = unittest.makeSuite(ClosedConTests, "Check")
915 closed_cur_suite = unittest.makeSuite(ClosedCurTests, "Check")
916 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 +0000917
918def test():
919 runner = unittest.TextTestRunner()
920 runner.run(suite())
921
922if __name__ == "__main__":
923 test()