blob: b7ec1ad0d900dc3de77801dd6153260c9a6781d1 [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
28except ImportError:
29 threading = None
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000030
31class ModuleTests(unittest.TestCase):
32 def CheckAPILevel(self):
33 self.assertEqual(sqlite.apilevel, "2.0",
34 "apilevel is %s, should be 2.0" % sqlite.apilevel)
35
36 def CheckThreadSafety(self):
37 self.assertEqual(sqlite.threadsafety, 1,
38 "threadsafety is %d, should be 1" % sqlite.threadsafety)
39
40 def CheckParamStyle(self):
41 self.assertEqual(sqlite.paramstyle, "qmark",
42 "paramstyle is '%s', should be 'qmark'" %
43 sqlite.paramstyle)
44
45 def CheckWarning(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
49 def CheckError(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
53 def CheckInterfaceError(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
57 def CheckDatabaseError(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
61 def CheckDataError(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
65 def CheckOperationalError(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
69 def CheckIntegrityError(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
73 def CheckInternalError(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
77 def CheckProgrammingError(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
81 def CheckNotSupportedError(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
86class ConnectionTests(unittest.TestCase):
R. David Murrayd35251d2010-06-01 01:32:12 +000087
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000088 def setUp(self):
89 self.cx = sqlite.connect(":memory:")
90 cu = self.cx.cursor()
91 cu.execute("create table test(id integer primary key, name text)")
92 cu.execute("insert into test(name) values (?)", ("foo",))
93
94 def tearDown(self):
95 self.cx.close()
96
97 def CheckCommit(self):
98 self.cx.commit()
99
100 def CheckCommitAfterNoChanges(self):
101 """
102 A commit should also work when no changes were made to the database.
103 """
104 self.cx.commit()
105 self.cx.commit()
106
107 def CheckRollback(self):
108 self.cx.rollback()
109
110 def CheckRollbackAfterNoChanges(self):
111 """
112 A rollback should also work when no changes were made to the database.
113 """
114 self.cx.rollback()
115 self.cx.rollback()
116
117 def CheckCursor(self):
118 cu = self.cx.cursor()
119
120 def CheckFailedOpen(self):
121 YOU_CANNOT_OPEN_THIS = "/foo/bar/bla/23534/mydb.db"
122 try:
123 con = sqlite.connect(YOU_CANNOT_OPEN_THIS)
124 except sqlite.OperationalError:
125 return
126 self.fail("should have raised an OperationalError")
127
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
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000166class CursorTests(unittest.TestCase):
167 def setUp(self):
168 self.cx = sqlite.connect(":memory:")
169 self.cu = self.cx.cursor()
170 self.cu.execute("create table test(id integer primary key, name text, income number)")
171 self.cu.execute("insert into test(name) values (?)", ("foo",))
172
173 def tearDown(self):
174 self.cu.close()
175 self.cx.close()
176
177 def CheckExecuteNoArgs(self):
178 self.cu.execute("delete from test")
179
180 def CheckExecuteIllegalSql(self):
181 try:
182 self.cu.execute("select asdf")
183 self.fail("should have raised an OperationalError")
184 except sqlite.OperationalError:
185 return
186 except:
187 self.fail("raised wrong exception")
188
189 def CheckExecuteTooMuchSql(self):
190 try:
191 self.cu.execute("select 5+4; select 4+5")
192 self.fail("should have raised a Warning")
193 except sqlite.Warning:
194 return
195 except:
196 self.fail("raised wrong exception")
197
198 def CheckExecuteTooMuchSql2(self):
199 self.cu.execute("select 5+4; -- foo bar")
200
201 def CheckExecuteTooMuchSql3(self):
202 self.cu.execute("""
203 select 5+4;
204
205 /*
206 foo
207 */
208 """)
209
210 def CheckExecuteWrongSqlArg(self):
211 try:
212 self.cu.execute(42)
213 self.fail("should have raised a ValueError")
214 except ValueError:
215 return
216 except:
217 self.fail("raised wrong exception.")
218
219 def CheckExecuteArgInt(self):
220 self.cu.execute("insert into test(id) values (?)", (42,))
221
222 def CheckExecuteArgFloat(self):
223 self.cu.execute("insert into test(income) values (?)", (2500.32,))
224
225 def CheckExecuteArgString(self):
226 self.cu.execute("insert into test(name) values (?)", ("Hugo",))
227
Petri Lehtinen023fe332012-02-01 22:18:19 +0200228 def CheckExecuteArgStringWithZeroByte(self):
229 self.cu.execute("insert into test(name) values (?)", ("Hu\x00go",))
230
231 self.cu.execute("select name from test where id=?", (self.cu.lastrowid,))
232 row = self.cu.fetchone()
233 self.assertEqual(row[0], "Hu\x00go")
234
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000235 def CheckExecuteWrongNoOfArgs1(self):
236 # too many parameters
237 try:
238 self.cu.execute("insert into test(id) values (?)", (17, "Egon"))
239 self.fail("should have raised ProgrammingError")
240 except sqlite.ProgrammingError:
241 pass
242
243 def CheckExecuteWrongNoOfArgs2(self):
244 # too little parameters
245 try:
246 self.cu.execute("insert into test(id) values (?)")
247 self.fail("should have raised ProgrammingError")
248 except sqlite.ProgrammingError:
249 pass
250
251 def CheckExecuteWrongNoOfArgs3(self):
252 # no parameters, parameters are needed
253 try:
254 self.cu.execute("insert into test(id) values (?)")
255 self.fail("should have raised ProgrammingError")
256 except sqlite.ProgrammingError:
257 pass
258
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000259 def CheckExecuteParamList(self):
260 self.cu.execute("insert into test(name) values ('foo')")
261 self.cu.execute("select name from test where name=?", ["foo"])
262 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000263 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000264
265 def CheckExecuteParamSequence(self):
266 class L(object):
267 def __len__(self):
268 return 1
269 def __getitem__(self, x):
270 assert x == 0
271 return "foo"
272
273 self.cu.execute("insert into test(name) values ('foo')")
274 self.cu.execute("select name from test where name=?", L())
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
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000278 def CheckExecuteDictMapping(self):
279 self.cu.execute("insert into test(name) values ('foo')")
280 self.cu.execute("select name from test where name=:name", {"name": "foo"})
281 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000282 self.assertEqual(row[0], "foo")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000283
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000284 def CheckExecuteDictMapping_Mapping(self):
285 class D(dict):
286 def __missing__(self, key):
287 return "foo"
288
289 self.cu.execute("insert into test(name) values ('foo')")
290 self.cu.execute("select name from test where name=:name", D())
291 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000292 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000293
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000294 def CheckExecuteDictMappingTooLittleArgs(self):
295 self.cu.execute("insert into test(name) values ('foo')")
296 try:
297 self.cu.execute("select name from test where name=:name and id=:id", {"name": "foo"})
298 self.fail("should have raised ProgrammingError")
299 except sqlite.ProgrammingError:
300 pass
301
302 def CheckExecuteDictMappingNoArgs(self):
303 self.cu.execute("insert into test(name) values ('foo')")
304 try:
305 self.cu.execute("select name from test where name=:name")
306 self.fail("should have raised ProgrammingError")
307 except sqlite.ProgrammingError:
308 pass
309
310 def CheckExecuteDictMappingUnnamed(self):
311 self.cu.execute("insert into test(name) values ('foo')")
312 try:
313 self.cu.execute("select name from test where name=?", {"name": "foo"})
314 self.fail("should have raised ProgrammingError")
315 except sqlite.ProgrammingError:
316 pass
317
318 def CheckClose(self):
319 self.cu.close()
320
321 def CheckRowcountExecute(self):
322 self.cu.execute("delete from test")
323 self.cu.execute("insert into test(name) values ('foo')")
324 self.cu.execute("insert into test(name) values ('foo')")
325 self.cu.execute("update test set name='bar'")
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000326 self.assertEqual(self.cu.rowcount, 2)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000327
Georg Brandlf78e02b2008-06-10 17:40:04 +0000328 def CheckRowcountSelect(self):
329 """
330 pysqlite does not know the rowcount of SELECT statements, because we
331 don't fetch all rows after executing the select statement. The rowcount
332 has thus to be -1.
333 """
334 self.cu.execute("select 5 union select 6")
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000335 self.assertEqual(self.cu.rowcount, -1)
Georg Brandlf78e02b2008-06-10 17:40:04 +0000336
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000337 def CheckRowcountExecutemany(self):
338 self.cu.execute("delete from test")
339 self.cu.executemany("insert into test(name) values (?)", [(1,), (2,), (3,)])
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000340 self.assertEqual(self.cu.rowcount, 3)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000341
342 def CheckTotalChanges(self):
343 self.cu.execute("insert into test(name) values ('foo')")
344 self.cu.execute("insert into test(name) values ('foo')")
345 if self.cx.total_changes < 2:
346 self.fail("total changes reported wrong value")
347
348 # Checks for executemany:
349 # Sequences are required by the DB-API, iterators
350 # enhancements in pysqlite.
351
352 def CheckExecuteManySequence(self):
353 self.cu.executemany("insert into test(income) values (?)", [(x,) for x in range(100, 110)])
354
355 def CheckExecuteManyIterator(self):
356 class MyIter:
357 def __init__(self):
358 self.value = 5
359
Georg Brandla18af4e2007-04-21 15:47:16 +0000360 def __next__(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000361 if self.value == 10:
362 raise StopIteration
363 else:
364 self.value += 1
365 return (self.value,)
366
367 self.cu.executemany("insert into test(income) values (?)", MyIter())
368
369 def CheckExecuteManyGenerator(self):
370 def mygen():
371 for i in range(5):
372 yield (i,)
373
374 self.cu.executemany("insert into test(income) values (?)", mygen())
375
376 def CheckExecuteManyWrongSqlArg(self):
377 try:
378 self.cu.executemany(42, [(3,)])
379 self.fail("should have raised a ValueError")
380 except ValueError:
381 return
382 except:
383 self.fail("raised wrong exception.")
384
385 def CheckExecuteManySelect(self):
386 try:
387 self.cu.executemany("select ?", [(3,)])
388 self.fail("should have raised a ProgrammingError")
389 except sqlite.ProgrammingError:
390 return
391 except:
392 self.fail("raised wrong exception.")
393
394 def CheckExecuteManyNotIterable(self):
395 try:
396 self.cu.executemany("insert into test(income) values (?)", 42)
397 self.fail("should have raised a TypeError")
398 except TypeError:
399 return
Guido van Rossumb940e112007-01-10 16:19:56 +0000400 except Exception as e:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000401 print("raised", e.__class__)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000402 self.fail("raised wrong exception.")
403
404 def CheckFetchIter(self):
405 # Optional DB-API extension.
406 self.cu.execute("delete from test")
407 self.cu.execute("insert into test(id) values (?)", (5,))
408 self.cu.execute("insert into test(id) values (?)", (6,))
409 self.cu.execute("select id from test order by id")
410 lst = []
411 for row in self.cu:
412 lst.append(row[0])
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000413 self.assertEqual(lst[0], 5)
414 self.assertEqual(lst[1], 6)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000415
416 def CheckFetchone(self):
417 self.cu.execute("select name from test")
418 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000419 self.assertEqual(row[0], "foo")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000420 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000421 self.assertEqual(row, None)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000422
423 def CheckFetchoneNoStatement(self):
424 cur = self.cx.cursor()
425 row = cur.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000426 self.assertEqual(row, None)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000427
428 def CheckArraySize(self):
429 # must default ot 1
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000430 self.assertEqual(self.cu.arraysize, 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000431
432 # now set to 2
433 self.cu.arraysize = 2
434
435 # now make the query return 3 rows
436 self.cu.execute("delete from test")
437 self.cu.execute("insert into test(name) values ('A')")
438 self.cu.execute("insert into test(name) values ('B')")
439 self.cu.execute("insert into test(name) values ('C')")
440 self.cu.execute("select name from test")
441 res = self.cu.fetchmany()
442
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000443 self.assertEqual(len(res), 2)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000444
445 def CheckFetchmany(self):
446 self.cu.execute("select name from test")
447 res = self.cu.fetchmany(100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000448 self.assertEqual(len(res), 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000449 res = self.cu.fetchmany(100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000450 self.assertEqual(res, [])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000451
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000452 def CheckFetchmanyKwArg(self):
453 """Checks if fetchmany works with keyword arguments"""
454 self.cu.execute("select name from test")
455 res = self.cu.fetchmany(size=100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000456 self.assertEqual(len(res), 1)
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000457
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000458 def CheckFetchall(self):
459 self.cu.execute("select name from test")
460 res = self.cu.fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000461 self.assertEqual(len(res), 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000462 res = self.cu.fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000463 self.assertEqual(res, [])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000464
465 def CheckSetinputsizes(self):
466 self.cu.setinputsizes([3, 4, 5])
467
468 def CheckSetoutputsize(self):
469 self.cu.setoutputsize(5, 0)
470
471 def CheckSetoutputsizeNoColumn(self):
472 self.cu.setoutputsize(42)
473
474 def CheckCursorConnection(self):
475 # Optional DB-API extension.
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000476 self.assertEqual(self.cu.connection, self.cx)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000477
478 def CheckWrongCursorCallable(self):
479 try:
480 def f(): pass
481 cur = self.cx.cursor(f)
482 self.fail("should have raised a TypeError")
483 except TypeError:
484 return
485 self.fail("should have raised a ValueError")
486
487 def CheckCursorWrongClass(self):
488 class Foo: pass
489 foo = Foo()
490 try:
491 cur = sqlite.Cursor(foo)
492 self.fail("should have raised a ValueError")
493 except TypeError:
494 pass
495
Victor Stinner45df8202010-04-28 22:31:17 +0000496@unittest.skipUnless(threading, 'This test requires threading.')
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000497class ThreadTests(unittest.TestCase):
498 def setUp(self):
499 self.con = sqlite.connect(":memory:")
500 self.cur = self.con.cursor()
501 self.cur.execute("create table test(id integer primary key, name text, bin binary, ratio number, ts timestamp)")
502
503 def tearDown(self):
504 self.cur.close()
505 self.con.close()
506
507 def CheckConCursor(self):
508 def run(con, errors):
509 try:
510 cur = con.cursor()
511 errors.append("did not raise ProgrammingError")
512 return
513 except sqlite.ProgrammingError:
514 return
515 except:
516 errors.append("raised wrong exception")
517
518 errors = []
519 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
520 t.start()
521 t.join()
522 if len(errors) > 0:
523 self.fail("\n".join(errors))
524
525 def CheckConCommit(self):
526 def run(con, errors):
527 try:
528 con.commit()
529 errors.append("did not raise ProgrammingError")
530 return
531 except sqlite.ProgrammingError:
532 return
533 except:
534 errors.append("raised wrong exception")
535
536 errors = []
537 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
538 t.start()
539 t.join()
540 if len(errors) > 0:
541 self.fail("\n".join(errors))
542
543 def CheckConRollback(self):
544 def run(con, errors):
545 try:
546 con.rollback()
547 errors.append("did not raise ProgrammingError")
548 return
549 except sqlite.ProgrammingError:
550 return
551 except:
552 errors.append("raised wrong exception")
553
554 errors = []
555 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
556 t.start()
557 t.join()
558 if len(errors) > 0:
559 self.fail("\n".join(errors))
560
561 def CheckConClose(self):
562 def run(con, errors):
563 try:
564 con.close()
565 errors.append("did not raise ProgrammingError")
566 return
567 except sqlite.ProgrammingError:
568 return
569 except:
570 errors.append("raised wrong exception")
571
572 errors = []
573 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
574 t.start()
575 t.join()
576 if len(errors) > 0:
577 self.fail("\n".join(errors))
578
579 def CheckCurImplicitBegin(self):
580 def run(cur, errors):
581 try:
582 cur.execute("insert into test(name) values ('a')")
583 errors.append("did not raise ProgrammingError")
584 return
585 except sqlite.ProgrammingError:
586 return
587 except:
588 errors.append("raised wrong exception")
589
590 errors = []
591 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
592 t.start()
593 t.join()
594 if len(errors) > 0:
595 self.fail("\n".join(errors))
596
597 def CheckCurClose(self):
598 def run(cur, errors):
599 try:
600 cur.close()
601 errors.append("did not raise ProgrammingError")
602 return
603 except sqlite.ProgrammingError:
604 return
605 except:
606 errors.append("raised wrong exception")
607
608 errors = []
609 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
610 t.start()
611 t.join()
612 if len(errors) > 0:
613 self.fail("\n".join(errors))
614
615 def CheckCurExecute(self):
616 def run(cur, errors):
617 try:
618 cur.execute("select name from test")
619 errors.append("did not raise ProgrammingError")
620 return
621 except sqlite.ProgrammingError:
622 return
623 except:
624 errors.append("raised wrong exception")
625
626 errors = []
627 self.cur.execute("insert into test(name) values ('a')")
628 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
629 t.start()
630 t.join()
631 if len(errors) > 0:
632 self.fail("\n".join(errors))
633
634 def CheckCurIterNext(self):
635 def run(cur, errors):
636 try:
637 row = cur.fetchone()
638 errors.append("did not raise ProgrammingError")
639 return
640 except sqlite.ProgrammingError:
641 return
642 except:
643 errors.append("raised wrong exception")
644
645 errors = []
646 self.cur.execute("insert into test(name) values ('a')")
647 self.cur.execute("select name from test")
648 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
649 t.start()
650 t.join()
651 if len(errors) > 0:
652 self.fail("\n".join(errors))
653
654class ConstructorTests(unittest.TestCase):
655 def CheckDate(self):
656 d = sqlite.Date(2004, 10, 28)
657
658 def CheckTime(self):
659 t = sqlite.Time(12, 39, 35)
660
661 def CheckTimestamp(self):
662 ts = sqlite.Timestamp(2004, 10, 28, 12, 39, 35)
663
664 def CheckDateFromTicks(self):
665 d = sqlite.DateFromTicks(42)
666
667 def CheckTimeFromTicks(self):
668 t = sqlite.TimeFromTicks(42)
669
670 def CheckTimestampFromTicks(self):
671 ts = sqlite.TimestampFromTicks(42)
672
673 def CheckBinary(self):
Guido van Rossumbae07c92007-10-08 02:46:15 +0000674 b = sqlite.Binary(b"\0'")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000675
676class ExtensionTests(unittest.TestCase):
677 def CheckScriptStringSql(self):
678 con = sqlite.connect(":memory:")
679 cur = con.cursor()
680 cur.executescript("""
681 -- bla bla
682 /* a stupid comment */
683 create table a(i);
684 insert into a(i) values (5);
685 """)
686 cur.execute("select i from a")
687 res = cur.fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000688 self.assertEqual(res, 5)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000689
Gerhard Häringf9cee222010-03-05 15:20:03 +0000690 def CheckScriptSyntaxError(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000691 con = sqlite.connect(":memory:")
692 cur = con.cursor()
693 raised = False
694 try:
Gerhard Häringf9cee222010-03-05 15:20:03 +0000695 cur.executescript("create table test(x); asdf; create table test2(x)")
696 except sqlite.OperationalError:
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000697 raised = True
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000698 self.assertEqual(raised, True, "should have raised an exception")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000699
700 def CheckScriptErrorNormal(self):
701 con = sqlite.connect(":memory:")
702 cur = con.cursor()
703 raised = False
704 try:
705 cur.executescript("create table test(sadfsadfdsa); select foo from hurz;")
706 except sqlite.OperationalError:
707 raised = True
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000708 self.assertEqual(raised, True, "should have raised an exception")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000709
710 def CheckConnectionExecute(self):
711 con = sqlite.connect(":memory:")
712 result = con.execute("select 5").fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000713 self.assertEqual(result, 5, "Basic test of Connection.execute")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000714
715 def CheckConnectionExecutemany(self):
716 con = sqlite.connect(":memory:")
717 con.execute("create table test(foo)")
718 con.executemany("insert into test(foo) values (?)", [(3,), (4,)])
719 result = con.execute("select foo from test order by foo").fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000720 self.assertEqual(result[0][0], 3, "Basic test of Connection.executemany")
721 self.assertEqual(result[1][0], 4, "Basic test of Connection.executemany")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000722
723 def CheckConnectionExecutescript(self):
724 con = sqlite.connect(":memory:")
725 con.executescript("create table test(foo); insert into test(foo) values (5);")
726 result = con.execute("select foo from test").fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000727 self.assertEqual(result, 5, "Basic test of Connection.executescript")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000728
Gerhard Häringf9cee222010-03-05 15:20:03 +0000729class ClosedConTests(unittest.TestCase):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000730 def setUp(self):
731 pass
732
733 def tearDown(self):
734 pass
735
736 def CheckClosedConCursor(self):
737 con = sqlite.connect(":memory:")
738 con.close()
739 try:
740 cur = con.cursor()
741 self.fail("Should have raised a ProgrammingError")
742 except sqlite.ProgrammingError:
743 pass
744 except:
745 self.fail("Should have raised a ProgrammingError")
746
747 def CheckClosedConCommit(self):
748 con = sqlite.connect(":memory:")
749 con.close()
750 try:
751 con.commit()
752 self.fail("Should have raised a ProgrammingError")
753 except sqlite.ProgrammingError:
754 pass
755 except:
756 self.fail("Should have raised a ProgrammingError")
757
758 def CheckClosedConRollback(self):
759 con = sqlite.connect(":memory:")
760 con.close()
761 try:
762 con.rollback()
763 self.fail("Should have raised a ProgrammingError")
764 except sqlite.ProgrammingError:
765 pass
766 except:
767 self.fail("Should have raised a ProgrammingError")
768
769 def CheckClosedCurExecute(self):
770 con = sqlite.connect(":memory:")
771 cur = con.cursor()
772 con.close()
773 try:
774 cur.execute("select 4")
775 self.fail("Should have raised a ProgrammingError")
776 except sqlite.ProgrammingError:
777 pass
778 except:
779 self.fail("Should have raised a ProgrammingError")
780
Gerhard Häringf9cee222010-03-05 15:20:03 +0000781 def CheckClosedCreateFunction(self):
782 con = sqlite.connect(":memory:")
783 con.close()
784 def f(x): return 17
785 try:
786 con.create_function("foo", 1, f)
787 self.fail("Should have raised a ProgrammingError")
788 except sqlite.ProgrammingError:
789 pass
790 except:
791 self.fail("Should have raised a ProgrammingError")
792
793 def CheckClosedCreateAggregate(self):
794 con = sqlite.connect(":memory:")
795 con.close()
796 class Agg:
797 def __init__(self):
798 pass
799 def step(self, x):
800 pass
801 def finalize(self):
802 return 17
803 try:
804 con.create_aggregate("foo", 1, Agg)
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
811 def CheckClosedSetAuthorizer(self):
812 con = sqlite.connect(":memory:")
813 con.close()
814 def authorizer(*args):
815 return sqlite.DENY
816 try:
817 con.set_authorizer(authorizer)
818 self.fail("Should have raised a ProgrammingError")
819 except sqlite.ProgrammingError:
820 pass
821 except:
822 self.fail("Should have raised a ProgrammingError")
823
824 def CheckClosedSetProgressCallback(self):
825 con = sqlite.connect(":memory:")
826 con.close()
827 def progress(): pass
828 try:
829 con.set_progress_handler(progress, 100)
830 self.fail("Should have raised a ProgrammingError")
831 except sqlite.ProgrammingError:
832 pass
833 except:
834 self.fail("Should have raised a ProgrammingError")
835
836 def CheckClosedCall(self):
837 con = sqlite.connect(":memory:")
838 con.close()
839 try:
840 con()
841 self.fail("Should have raised a ProgrammingError")
842 except sqlite.ProgrammingError:
843 pass
844 except:
845 self.fail("Should have raised a ProgrammingError")
846
847class ClosedCurTests(unittest.TestCase):
848 def setUp(self):
849 pass
850
851 def tearDown(self):
852 pass
853
854 def CheckClosed(self):
855 con = sqlite.connect(":memory:")
856 cur = con.cursor()
857 cur.close()
858
859 for method_name in ("execute", "executemany", "executescript", "fetchall", "fetchmany", "fetchone"):
860 if method_name in ("execute", "executescript"):
861 params = ("select 4 union select 5",)
862 elif method_name == "executemany":
863 params = ("insert into foo(bar) values (?)", [(3,), (4,)])
864 else:
865 params = []
866
867 try:
868 method = getattr(cur, method_name)
869
870 method(*params)
871 self.fail("Should have raised a ProgrammingError: method " + method_name)
872 except sqlite.ProgrammingError:
873 pass
874 except:
875 self.fail("Should have raised a ProgrammingError: " + method_name)
876
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000877def suite():
878 module_suite = unittest.makeSuite(ModuleTests, "Check")
879 connection_suite = unittest.makeSuite(ConnectionTests, "Check")
880 cursor_suite = unittest.makeSuite(CursorTests, "Check")
881 thread_suite = unittest.makeSuite(ThreadTests, "Check")
882 constructor_suite = unittest.makeSuite(ConstructorTests, "Check")
883 ext_suite = unittest.makeSuite(ExtensionTests, "Check")
Gerhard Häringf9cee222010-03-05 15:20:03 +0000884 closed_con_suite = unittest.makeSuite(ClosedConTests, "Check")
885 closed_cur_suite = unittest.makeSuite(ClosedCurTests, "Check")
886 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 +0000887
888def test():
889 runner = unittest.TextTestRunner()
890 runner.run(suite())
891
892if __name__ == "__main__":
893 test()