blob: ced6679140e93bb26342808a65ff09f4782b352f [file] [log] [blame]
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001#-*- coding: ISO-8859-1 -*-
2# 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):
Guido van Rossumcd16bf62007-06-13 18:07:49 +000046 self.assert_(issubclass(sqlite.Warning, Exception),
47 "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):
87 def setUp(self):
88 self.cx = sqlite.connect(":memory:")
89 cu = self.cx.cursor()
90 cu.execute("create table test(id integer primary key, name text)")
91 cu.execute("insert into test(name) values (?)", ("foo",))
92
93 def tearDown(self):
94 self.cx.close()
95
96 def CheckCommit(self):
97 self.cx.commit()
98
99 def CheckCommitAfterNoChanges(self):
100 """
101 A commit should also work when no changes were made to the database.
102 """
103 self.cx.commit()
104 self.cx.commit()
105
106 def CheckRollback(self):
107 self.cx.rollback()
108
109 def CheckRollbackAfterNoChanges(self):
110 """
111 A rollback should also work when no changes were made to the database.
112 """
113 self.cx.rollback()
114 self.cx.rollback()
115
116 def CheckCursor(self):
117 cu = self.cx.cursor()
118
119 def CheckFailedOpen(self):
120 YOU_CANNOT_OPEN_THIS = "/foo/bar/bla/23534/mydb.db"
121 try:
122 con = sqlite.connect(YOU_CANNOT_OPEN_THIS)
123 except sqlite.OperationalError:
124 return
125 self.fail("should have raised an OperationalError")
126
127 def CheckClose(self):
128 self.cx.close()
129
130 def CheckExceptions(self):
131 # Optional DB-API extension.
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000132 self.assertEqual(self.cx.Warning, sqlite.Warning)
133 self.assertEqual(self.cx.Error, sqlite.Error)
134 self.assertEqual(self.cx.InterfaceError, sqlite.InterfaceError)
135 self.assertEqual(self.cx.DatabaseError, sqlite.DatabaseError)
136 self.assertEqual(self.cx.DataError, sqlite.DataError)
137 self.assertEqual(self.cx.OperationalError, sqlite.OperationalError)
138 self.assertEqual(self.cx.IntegrityError, sqlite.IntegrityError)
139 self.assertEqual(self.cx.InternalError, sqlite.InternalError)
140 self.assertEqual(self.cx.ProgrammingError, sqlite.ProgrammingError)
141 self.assertEqual(self.cx.NotSupportedError, sqlite.NotSupportedError)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000142
143class CursorTests(unittest.TestCase):
144 def setUp(self):
145 self.cx = sqlite.connect(":memory:")
146 self.cu = self.cx.cursor()
147 self.cu.execute("create table test(id integer primary key, name text, income number)")
148 self.cu.execute("insert into test(name) values (?)", ("foo",))
149
150 def tearDown(self):
151 self.cu.close()
152 self.cx.close()
153
154 def CheckExecuteNoArgs(self):
155 self.cu.execute("delete from test")
156
157 def CheckExecuteIllegalSql(self):
158 try:
159 self.cu.execute("select asdf")
160 self.fail("should have raised an OperationalError")
161 except sqlite.OperationalError:
162 return
163 except:
164 self.fail("raised wrong exception")
165
166 def CheckExecuteTooMuchSql(self):
167 try:
168 self.cu.execute("select 5+4; select 4+5")
169 self.fail("should have raised a Warning")
170 except sqlite.Warning:
171 return
172 except:
173 self.fail("raised wrong exception")
174
175 def CheckExecuteTooMuchSql2(self):
176 self.cu.execute("select 5+4; -- foo bar")
177
178 def CheckExecuteTooMuchSql3(self):
179 self.cu.execute("""
180 select 5+4;
181
182 /*
183 foo
184 */
185 """)
186
187 def CheckExecuteWrongSqlArg(self):
188 try:
189 self.cu.execute(42)
190 self.fail("should have raised a ValueError")
191 except ValueError:
192 return
193 except:
194 self.fail("raised wrong exception.")
195
196 def CheckExecuteArgInt(self):
197 self.cu.execute("insert into test(id) values (?)", (42,))
198
199 def CheckExecuteArgFloat(self):
200 self.cu.execute("insert into test(income) values (?)", (2500.32,))
201
202 def CheckExecuteArgString(self):
203 self.cu.execute("insert into test(name) values (?)", ("Hugo",))
204
205 def CheckExecuteWrongNoOfArgs1(self):
206 # too many parameters
207 try:
208 self.cu.execute("insert into test(id) values (?)", (17, "Egon"))
209 self.fail("should have raised ProgrammingError")
210 except sqlite.ProgrammingError:
211 pass
212
213 def CheckExecuteWrongNoOfArgs2(self):
214 # too little parameters
215 try:
216 self.cu.execute("insert into test(id) values (?)")
217 self.fail("should have raised ProgrammingError")
218 except sqlite.ProgrammingError:
219 pass
220
221 def CheckExecuteWrongNoOfArgs3(self):
222 # no parameters, parameters are needed
223 try:
224 self.cu.execute("insert into test(id) values (?)")
225 self.fail("should have raised ProgrammingError")
226 except sqlite.ProgrammingError:
227 pass
228
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000229 def CheckExecuteParamList(self):
230 self.cu.execute("insert into test(name) values ('foo')")
231 self.cu.execute("select name from test where name=?", ["foo"])
232 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000233 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000234
235 def CheckExecuteParamSequence(self):
236 class L(object):
237 def __len__(self):
238 return 1
239 def __getitem__(self, x):
240 assert x == 0
241 return "foo"
242
243 self.cu.execute("insert into test(name) values ('foo')")
244 self.cu.execute("select name from test where name=?", L())
245 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000246 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000247
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000248 def CheckExecuteDictMapping(self):
249 self.cu.execute("insert into test(name) values ('foo')")
250 self.cu.execute("select name from test where name=:name", {"name": "foo"})
251 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000252 self.assertEqual(row[0], "foo")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000253
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000254 def CheckExecuteDictMapping_Mapping(self):
255 class D(dict):
256 def __missing__(self, key):
257 return "foo"
258
259 self.cu.execute("insert into test(name) values ('foo')")
260 self.cu.execute("select name from test where name=:name", D())
261 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000262 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000263
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000264 def CheckExecuteDictMappingTooLittleArgs(self):
265 self.cu.execute("insert into test(name) values ('foo')")
266 try:
267 self.cu.execute("select name from test where name=:name and id=:id", {"name": "foo"})
268 self.fail("should have raised ProgrammingError")
269 except sqlite.ProgrammingError:
270 pass
271
272 def CheckExecuteDictMappingNoArgs(self):
273 self.cu.execute("insert into test(name) values ('foo')")
274 try:
275 self.cu.execute("select name from test where name=:name")
276 self.fail("should have raised ProgrammingError")
277 except sqlite.ProgrammingError:
278 pass
279
280 def CheckExecuteDictMappingUnnamed(self):
281 self.cu.execute("insert into test(name) values ('foo')")
282 try:
283 self.cu.execute("select name from test where name=?", {"name": "foo"})
284 self.fail("should have raised ProgrammingError")
285 except sqlite.ProgrammingError:
286 pass
287
288 def CheckClose(self):
289 self.cu.close()
290
291 def CheckRowcountExecute(self):
292 self.cu.execute("delete from test")
293 self.cu.execute("insert into test(name) values ('foo')")
294 self.cu.execute("insert into test(name) values ('foo')")
295 self.cu.execute("update test set name='bar'")
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000296 self.assertEqual(self.cu.rowcount, 2)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000297
Georg Brandlf78e02b2008-06-10 17:40:04 +0000298 def CheckRowcountSelect(self):
299 """
300 pysqlite does not know the rowcount of SELECT statements, because we
301 don't fetch all rows after executing the select statement. The rowcount
302 has thus to be -1.
303 """
304 self.cu.execute("select 5 union select 6")
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000305 self.assertEqual(self.cu.rowcount, -1)
Georg Brandlf78e02b2008-06-10 17:40:04 +0000306
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000307 def CheckRowcountExecutemany(self):
308 self.cu.execute("delete from test")
309 self.cu.executemany("insert into test(name) values (?)", [(1,), (2,), (3,)])
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000310 self.assertEqual(self.cu.rowcount, 3)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000311
312 def CheckTotalChanges(self):
313 self.cu.execute("insert into test(name) values ('foo')")
314 self.cu.execute("insert into test(name) values ('foo')")
315 if self.cx.total_changes < 2:
316 self.fail("total changes reported wrong value")
317
318 # Checks for executemany:
319 # Sequences are required by the DB-API, iterators
320 # enhancements in pysqlite.
321
322 def CheckExecuteManySequence(self):
323 self.cu.executemany("insert into test(income) values (?)", [(x,) for x in range(100, 110)])
324
325 def CheckExecuteManyIterator(self):
326 class MyIter:
327 def __init__(self):
328 self.value = 5
329
Georg Brandla18af4e2007-04-21 15:47:16 +0000330 def __next__(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000331 if self.value == 10:
332 raise StopIteration
333 else:
334 self.value += 1
335 return (self.value,)
336
337 self.cu.executemany("insert into test(income) values (?)", MyIter())
338
339 def CheckExecuteManyGenerator(self):
340 def mygen():
341 for i in range(5):
342 yield (i,)
343
344 self.cu.executemany("insert into test(income) values (?)", mygen())
345
346 def CheckExecuteManyWrongSqlArg(self):
347 try:
348 self.cu.executemany(42, [(3,)])
349 self.fail("should have raised a ValueError")
350 except ValueError:
351 return
352 except:
353 self.fail("raised wrong exception.")
354
355 def CheckExecuteManySelect(self):
356 try:
357 self.cu.executemany("select ?", [(3,)])
358 self.fail("should have raised a ProgrammingError")
359 except sqlite.ProgrammingError:
360 return
361 except:
362 self.fail("raised wrong exception.")
363
364 def CheckExecuteManyNotIterable(self):
365 try:
366 self.cu.executemany("insert into test(income) values (?)", 42)
367 self.fail("should have raised a TypeError")
368 except TypeError:
369 return
Guido van Rossumb940e112007-01-10 16:19:56 +0000370 except Exception as e:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000371 print("raised", e.__class__)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000372 self.fail("raised wrong exception.")
373
374 def CheckFetchIter(self):
375 # Optional DB-API extension.
376 self.cu.execute("delete from test")
377 self.cu.execute("insert into test(id) values (?)", (5,))
378 self.cu.execute("insert into test(id) values (?)", (6,))
379 self.cu.execute("select id from test order by id")
380 lst = []
381 for row in self.cu:
382 lst.append(row[0])
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000383 self.assertEqual(lst[0], 5)
384 self.assertEqual(lst[1], 6)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000385
386 def CheckFetchone(self):
387 self.cu.execute("select name from test")
388 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000389 self.assertEqual(row[0], "foo")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000390 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000391 self.assertEqual(row, None)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000392
393 def CheckFetchoneNoStatement(self):
394 cur = self.cx.cursor()
395 row = cur.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000396 self.assertEqual(row, None)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000397
398 def CheckArraySize(self):
399 # must default ot 1
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000400 self.assertEqual(self.cu.arraysize, 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000401
402 # now set to 2
403 self.cu.arraysize = 2
404
405 # now make the query return 3 rows
406 self.cu.execute("delete from test")
407 self.cu.execute("insert into test(name) values ('A')")
408 self.cu.execute("insert into test(name) values ('B')")
409 self.cu.execute("insert into test(name) values ('C')")
410 self.cu.execute("select name from test")
411 res = self.cu.fetchmany()
412
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000413 self.assertEqual(len(res), 2)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000414
415 def CheckFetchmany(self):
416 self.cu.execute("select name from test")
417 res = self.cu.fetchmany(100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000418 self.assertEqual(len(res), 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000419 res = self.cu.fetchmany(100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000420 self.assertEqual(res, [])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000421
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000422 def CheckFetchmanyKwArg(self):
423 """Checks if fetchmany works with keyword arguments"""
424 self.cu.execute("select name from test")
425 res = self.cu.fetchmany(size=100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000426 self.assertEqual(len(res), 1)
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000427
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000428 def CheckFetchall(self):
429 self.cu.execute("select name from test")
430 res = self.cu.fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000431 self.assertEqual(len(res), 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000432 res = self.cu.fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000433 self.assertEqual(res, [])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000434
435 def CheckSetinputsizes(self):
436 self.cu.setinputsizes([3, 4, 5])
437
438 def CheckSetoutputsize(self):
439 self.cu.setoutputsize(5, 0)
440
441 def CheckSetoutputsizeNoColumn(self):
442 self.cu.setoutputsize(42)
443
444 def CheckCursorConnection(self):
445 # Optional DB-API extension.
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000446 self.assertEqual(self.cu.connection, self.cx)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000447
448 def CheckWrongCursorCallable(self):
449 try:
450 def f(): pass
451 cur = self.cx.cursor(f)
452 self.fail("should have raised a TypeError")
453 except TypeError:
454 return
455 self.fail("should have raised a ValueError")
456
457 def CheckCursorWrongClass(self):
458 class Foo: pass
459 foo = Foo()
460 try:
461 cur = sqlite.Cursor(foo)
462 self.fail("should have raised a ValueError")
463 except TypeError:
464 pass
465
Victor Stinner45df8202010-04-28 22:31:17 +0000466@unittest.skipUnless(threading, 'This test requires threading.')
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000467class ThreadTests(unittest.TestCase):
468 def setUp(self):
469 self.con = sqlite.connect(":memory:")
470 self.cur = self.con.cursor()
471 self.cur.execute("create table test(id integer primary key, name text, bin binary, ratio number, ts timestamp)")
472
473 def tearDown(self):
474 self.cur.close()
475 self.con.close()
476
477 def CheckConCursor(self):
478 def run(con, errors):
479 try:
480 cur = con.cursor()
481 errors.append("did not raise ProgrammingError")
482 return
483 except sqlite.ProgrammingError:
484 return
485 except:
486 errors.append("raised wrong exception")
487
488 errors = []
489 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
490 t.start()
491 t.join()
492 if len(errors) > 0:
493 self.fail("\n".join(errors))
494
495 def CheckConCommit(self):
496 def run(con, errors):
497 try:
498 con.commit()
499 errors.append("did not raise ProgrammingError")
500 return
501 except sqlite.ProgrammingError:
502 return
503 except:
504 errors.append("raised wrong exception")
505
506 errors = []
507 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
508 t.start()
509 t.join()
510 if len(errors) > 0:
511 self.fail("\n".join(errors))
512
513 def CheckConRollback(self):
514 def run(con, errors):
515 try:
516 con.rollback()
517 errors.append("did not raise ProgrammingError")
518 return
519 except sqlite.ProgrammingError:
520 return
521 except:
522 errors.append("raised wrong exception")
523
524 errors = []
525 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
526 t.start()
527 t.join()
528 if len(errors) > 0:
529 self.fail("\n".join(errors))
530
531 def CheckConClose(self):
532 def run(con, errors):
533 try:
534 con.close()
535 errors.append("did not raise ProgrammingError")
536 return
537 except sqlite.ProgrammingError:
538 return
539 except:
540 errors.append("raised wrong exception")
541
542 errors = []
543 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
544 t.start()
545 t.join()
546 if len(errors) > 0:
547 self.fail("\n".join(errors))
548
549 def CheckCurImplicitBegin(self):
550 def run(cur, errors):
551 try:
552 cur.execute("insert into test(name) values ('a')")
553 errors.append("did not raise ProgrammingError")
554 return
555 except sqlite.ProgrammingError:
556 return
557 except:
558 errors.append("raised wrong exception")
559
560 errors = []
561 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
562 t.start()
563 t.join()
564 if len(errors) > 0:
565 self.fail("\n".join(errors))
566
567 def CheckCurClose(self):
568 def run(cur, errors):
569 try:
570 cur.close()
571 errors.append("did not raise ProgrammingError")
572 return
573 except sqlite.ProgrammingError:
574 return
575 except:
576 errors.append("raised wrong exception")
577
578 errors = []
579 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
580 t.start()
581 t.join()
582 if len(errors) > 0:
583 self.fail("\n".join(errors))
584
585 def CheckCurExecute(self):
586 def run(cur, errors):
587 try:
588 cur.execute("select name from test")
589 errors.append("did not raise ProgrammingError")
590 return
591 except sqlite.ProgrammingError:
592 return
593 except:
594 errors.append("raised wrong exception")
595
596 errors = []
597 self.cur.execute("insert into test(name) values ('a')")
598 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
599 t.start()
600 t.join()
601 if len(errors) > 0:
602 self.fail("\n".join(errors))
603
604 def CheckCurIterNext(self):
605 def run(cur, errors):
606 try:
607 row = cur.fetchone()
608 errors.append("did not raise ProgrammingError")
609 return
610 except sqlite.ProgrammingError:
611 return
612 except:
613 errors.append("raised wrong exception")
614
615 errors = []
616 self.cur.execute("insert into test(name) values ('a')")
617 self.cur.execute("select name from test")
618 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
619 t.start()
620 t.join()
621 if len(errors) > 0:
622 self.fail("\n".join(errors))
623
624class ConstructorTests(unittest.TestCase):
625 def CheckDate(self):
626 d = sqlite.Date(2004, 10, 28)
627
628 def CheckTime(self):
629 t = sqlite.Time(12, 39, 35)
630
631 def CheckTimestamp(self):
632 ts = sqlite.Timestamp(2004, 10, 28, 12, 39, 35)
633
634 def CheckDateFromTicks(self):
635 d = sqlite.DateFromTicks(42)
636
637 def CheckTimeFromTicks(self):
638 t = sqlite.TimeFromTicks(42)
639
640 def CheckTimestampFromTicks(self):
641 ts = sqlite.TimestampFromTicks(42)
642
643 def CheckBinary(self):
Guido van Rossumbae07c92007-10-08 02:46:15 +0000644 b = sqlite.Binary(b"\0'")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000645
646class ExtensionTests(unittest.TestCase):
647 def CheckScriptStringSql(self):
648 con = sqlite.connect(":memory:")
649 cur = con.cursor()
650 cur.executescript("""
651 -- bla bla
652 /* a stupid comment */
653 create table a(i);
654 insert into a(i) values (5);
655 """)
656 cur.execute("select i from a")
657 res = cur.fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000658 self.assertEqual(res, 5)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000659
Gerhard Häringf9cee222010-03-05 15:20:03 +0000660 def CheckScriptSyntaxError(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000661 con = sqlite.connect(":memory:")
662 cur = con.cursor()
663 raised = False
664 try:
Gerhard Häringf9cee222010-03-05 15:20:03 +0000665 cur.executescript("create table test(x); asdf; create table test2(x)")
666 except sqlite.OperationalError:
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000667 raised = True
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000668 self.assertEqual(raised, True, "should have raised an exception")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000669
670 def CheckScriptErrorNormal(self):
671 con = sqlite.connect(":memory:")
672 cur = con.cursor()
673 raised = False
674 try:
675 cur.executescript("create table test(sadfsadfdsa); select foo from hurz;")
676 except sqlite.OperationalError:
677 raised = True
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000678 self.assertEqual(raised, True, "should have raised an exception")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000679
680 def CheckConnectionExecute(self):
681 con = sqlite.connect(":memory:")
682 result = con.execute("select 5").fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000683 self.assertEqual(result, 5, "Basic test of Connection.execute")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000684
685 def CheckConnectionExecutemany(self):
686 con = sqlite.connect(":memory:")
687 con.execute("create table test(foo)")
688 con.executemany("insert into test(foo) values (?)", [(3,), (4,)])
689 result = con.execute("select foo from test order by foo").fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000690 self.assertEqual(result[0][0], 3, "Basic test of Connection.executemany")
691 self.assertEqual(result[1][0], 4, "Basic test of Connection.executemany")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000692
693 def CheckConnectionExecutescript(self):
694 con = sqlite.connect(":memory:")
695 con.executescript("create table test(foo); insert into test(foo) values (5);")
696 result = con.execute("select foo from test").fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000697 self.assertEqual(result, 5, "Basic test of Connection.executescript")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000698
Gerhard Häringf9cee222010-03-05 15:20:03 +0000699class ClosedConTests(unittest.TestCase):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000700 def setUp(self):
701 pass
702
703 def tearDown(self):
704 pass
705
706 def CheckClosedConCursor(self):
707 con = sqlite.connect(":memory:")
708 con.close()
709 try:
710 cur = con.cursor()
711 self.fail("Should have raised a ProgrammingError")
712 except sqlite.ProgrammingError:
713 pass
714 except:
715 self.fail("Should have raised a ProgrammingError")
716
717 def CheckClosedConCommit(self):
718 con = sqlite.connect(":memory:")
719 con.close()
720 try:
721 con.commit()
722 self.fail("Should have raised a ProgrammingError")
723 except sqlite.ProgrammingError:
724 pass
725 except:
726 self.fail("Should have raised a ProgrammingError")
727
728 def CheckClosedConRollback(self):
729 con = sqlite.connect(":memory:")
730 con.close()
731 try:
732 con.rollback()
733 self.fail("Should have raised a ProgrammingError")
734 except sqlite.ProgrammingError:
735 pass
736 except:
737 self.fail("Should have raised a ProgrammingError")
738
739 def CheckClosedCurExecute(self):
740 con = sqlite.connect(":memory:")
741 cur = con.cursor()
742 con.close()
743 try:
744 cur.execute("select 4")
745 self.fail("Should have raised a ProgrammingError")
746 except sqlite.ProgrammingError:
747 pass
748 except:
749 self.fail("Should have raised a ProgrammingError")
750
Gerhard Häringf9cee222010-03-05 15:20:03 +0000751 def CheckClosedCreateFunction(self):
752 con = sqlite.connect(":memory:")
753 con.close()
754 def f(x): return 17
755 try:
756 con.create_function("foo", 1, f)
757 self.fail("Should have raised a ProgrammingError")
758 except sqlite.ProgrammingError:
759 pass
760 except:
761 self.fail("Should have raised a ProgrammingError")
762
763 def CheckClosedCreateAggregate(self):
764 con = sqlite.connect(":memory:")
765 con.close()
766 class Agg:
767 def __init__(self):
768 pass
769 def step(self, x):
770 pass
771 def finalize(self):
772 return 17
773 try:
774 con.create_aggregate("foo", 1, Agg)
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
781 def CheckClosedSetAuthorizer(self):
782 con = sqlite.connect(":memory:")
783 con.close()
784 def authorizer(*args):
785 return sqlite.DENY
786 try:
787 con.set_authorizer(authorizer)
788 self.fail("Should have raised a ProgrammingError")
789 except sqlite.ProgrammingError:
790 pass
791 except:
792 self.fail("Should have raised a ProgrammingError")
793
794 def CheckClosedSetProgressCallback(self):
795 con = sqlite.connect(":memory:")
796 con.close()
797 def progress(): pass
798 try:
799 con.set_progress_handler(progress, 100)
800 self.fail("Should have raised a ProgrammingError")
801 except sqlite.ProgrammingError:
802 pass
803 except:
804 self.fail("Should have raised a ProgrammingError")
805
806 def CheckClosedCall(self):
807 con = sqlite.connect(":memory:")
808 con.close()
809 try:
810 con()
811 self.fail("Should have raised a ProgrammingError")
812 except sqlite.ProgrammingError:
813 pass
814 except:
815 self.fail("Should have raised a ProgrammingError")
816
817class ClosedCurTests(unittest.TestCase):
818 def setUp(self):
819 pass
820
821 def tearDown(self):
822 pass
823
824 def CheckClosed(self):
825 con = sqlite.connect(":memory:")
826 cur = con.cursor()
827 cur.close()
828
829 for method_name in ("execute", "executemany", "executescript", "fetchall", "fetchmany", "fetchone"):
830 if method_name in ("execute", "executescript"):
831 params = ("select 4 union select 5",)
832 elif method_name == "executemany":
833 params = ("insert into foo(bar) values (?)", [(3,), (4,)])
834 else:
835 params = []
836
837 try:
838 method = getattr(cur, method_name)
839
840 method(*params)
841 self.fail("Should have raised a ProgrammingError: method " + method_name)
842 except sqlite.ProgrammingError:
843 pass
844 except:
845 self.fail("Should have raised a ProgrammingError: " + method_name)
846
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000847def suite():
848 module_suite = unittest.makeSuite(ModuleTests, "Check")
849 connection_suite = unittest.makeSuite(ConnectionTests, "Check")
850 cursor_suite = unittest.makeSuite(CursorTests, "Check")
851 thread_suite = unittest.makeSuite(ThreadTests, "Check")
852 constructor_suite = unittest.makeSuite(ConstructorTests, "Check")
853 ext_suite = unittest.makeSuite(ExtensionTests, "Check")
Gerhard Häringf9cee222010-03-05 15:20:03 +0000854 closed_con_suite = unittest.makeSuite(ClosedConTests, "Check")
855 closed_cur_suite = unittest.makeSuite(ClosedCurTests, "Check")
856 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 +0000857
858def test():
859 runner = unittest.TextTestRunner()
860 runner.run(suite())
861
862if __name__ == "__main__":
863 test()