blob: 903e5990316d7a3c1c2dd3e8e72a17a088d0a739 [file] [log] [blame]
Petri Lehtinenf8547992012-02-02 17:17:36 +02001#-*- coding: iso-8859-1 -*-
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002# pysqlite2/test/dbapi.py: tests for DB-API compliance
3#
Gerhard Häringf9cee222010-03-05 15:20:03 +00004# Copyright (C) 2004-2010 Gerhard Häring <gh@ghaering.de>
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005#
6# This file is part of pysqlite.
7#
8# This software is provided 'as-is', without any express or implied
9# warranty. In no event will the authors be held liable for any damages
10# arising from the use of this software.
11#
12# Permission is granted to anyone to use this software for any purpose,
13# including commercial applications, and to alter it and redistribute it
14# freely, subject to the following restrictions:
15#
16# 1. The origin of this software must not be misrepresented; you must not
17# claim that you wrote the original software. If you use this software
18# in a product, an acknowledgment in the product documentation would be
19# appreciated but is not required.
20# 2. Altered source versions must be plainly marked as such, and must not be
21# misrepresented as being the original software.
22# 3. This notice may not be removed or altered from any source distribution.
23
24import unittest
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000025import sqlite3 as sqlite
Victor Stinner45df8202010-04-28 22:31:17 +000026try:
27 import threading
Brett Cannoncd171c82013-07-04 17:43:24 -040028except ImportError:
Victor Stinner45df8202010-04-28 22:31:17 +000029 threading = None
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000030
Antoine Pitrou902fc8b2013-02-10 00:02:44 +010031from test.support import TESTFN, unlink
32
33
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000034class ModuleTests(unittest.TestCase):
35 def CheckAPILevel(self):
36 self.assertEqual(sqlite.apilevel, "2.0",
37 "apilevel is %s, should be 2.0" % sqlite.apilevel)
38
39 def CheckThreadSafety(self):
40 self.assertEqual(sqlite.threadsafety, 1,
41 "threadsafety is %d, should be 1" % sqlite.threadsafety)
42
43 def CheckParamStyle(self):
44 self.assertEqual(sqlite.paramstyle, "qmark",
45 "paramstyle is '%s', should be 'qmark'" %
46 sqlite.paramstyle)
47
48 def CheckWarning(self):
Ezio Melottib3aedd42010-11-20 19:04:17 +000049 self.assertTrue(issubclass(sqlite.Warning, Exception),
Guido van Rossumcd16bf62007-06-13 18:07:49 +000050 "Warning is not a subclass of Exception")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000051
52 def CheckError(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000053 self.assertTrue(issubclass(sqlite.Error, Exception),
Guido van Rossumcd16bf62007-06-13 18:07:49 +000054 "Error is not a subclass of Exception")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000055
56 def CheckInterfaceError(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000057 self.assertTrue(issubclass(sqlite.InterfaceError, sqlite.Error),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000058 "InterfaceError is not a subclass of Error")
59
60 def CheckDatabaseError(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000061 self.assertTrue(issubclass(sqlite.DatabaseError, sqlite.Error),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000062 "DatabaseError is not a subclass of Error")
63
64 def CheckDataError(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000065 self.assertTrue(issubclass(sqlite.DataError, sqlite.DatabaseError),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000066 "DataError is not a subclass of DatabaseError")
67
68 def CheckOperationalError(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000069 self.assertTrue(issubclass(sqlite.OperationalError, sqlite.DatabaseError),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000070 "OperationalError is not a subclass of DatabaseError")
71
72 def CheckIntegrityError(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000073 self.assertTrue(issubclass(sqlite.IntegrityError, sqlite.DatabaseError),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000074 "IntegrityError is not a subclass of DatabaseError")
75
76 def CheckInternalError(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000077 self.assertTrue(issubclass(sqlite.InternalError, sqlite.DatabaseError),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000078 "InternalError is not a subclass of DatabaseError")
79
80 def CheckProgrammingError(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000081 self.assertTrue(issubclass(sqlite.ProgrammingError, sqlite.DatabaseError),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000082 "ProgrammingError is not a subclass of DatabaseError")
83
84 def CheckNotSupportedError(self):
Gregory P. Smith04cecaf2009-07-04 08:32:15 +000085 self.assertTrue(issubclass(sqlite.NotSupportedError,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000086 sqlite.DatabaseError),
87 "NotSupportedError is not a subclass of DatabaseError")
88
89class ConnectionTests(unittest.TestCase):
R. David Murrayd35251d2010-06-01 01:32:12 +000090
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000091 def setUp(self):
92 self.cx = sqlite.connect(":memory:")
93 cu = self.cx.cursor()
94 cu.execute("create table test(id integer primary key, name text)")
95 cu.execute("insert into test(name) values (?)", ("foo",))
96
97 def tearDown(self):
98 self.cx.close()
99
100 def CheckCommit(self):
101 self.cx.commit()
102
103 def CheckCommitAfterNoChanges(self):
104 """
105 A commit should also work when no changes were made to the database.
106 """
107 self.cx.commit()
108 self.cx.commit()
109
110 def CheckRollback(self):
111 self.cx.rollback()
112
113 def CheckRollbackAfterNoChanges(self):
114 """
115 A rollback should also work when no changes were made to the database.
116 """
117 self.cx.rollback()
118 self.cx.rollback()
119
120 def CheckCursor(self):
121 cu = self.cx.cursor()
122
123 def CheckFailedOpen(self):
124 YOU_CANNOT_OPEN_THIS = "/foo/bar/bla/23534/mydb.db"
Berker Peksag1003b342016-06-12 22:34:49 +0300125 with self.assertRaises(sqlite.OperationalError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000126 con = sqlite.connect(YOU_CANNOT_OPEN_THIS)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000127
128 def CheckClose(self):
129 self.cx.close()
130
131 def CheckExceptions(self):
132 # Optional DB-API extension.
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000133 self.assertEqual(self.cx.Warning, sqlite.Warning)
134 self.assertEqual(self.cx.Error, sqlite.Error)
135 self.assertEqual(self.cx.InterfaceError, sqlite.InterfaceError)
136 self.assertEqual(self.cx.DatabaseError, sqlite.DatabaseError)
137 self.assertEqual(self.cx.DataError, sqlite.DataError)
138 self.assertEqual(self.cx.OperationalError, sqlite.OperationalError)
139 self.assertEqual(self.cx.IntegrityError, sqlite.IntegrityError)
140 self.assertEqual(self.cx.InternalError, sqlite.InternalError)
141 self.assertEqual(self.cx.ProgrammingError, sqlite.ProgrammingError)
142 self.assertEqual(self.cx.NotSupportedError, sqlite.NotSupportedError)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000143
R. David Murrayd35251d2010-06-01 01:32:12 +0000144 def CheckInTransaction(self):
145 # Can't use db from setUp because we want to test initial state.
146 cx = sqlite.connect(":memory:")
147 cu = cx.cursor()
148 self.assertEqual(cx.in_transaction, False)
149 cu.execute("create table transactiontest(id integer primary key, name text)")
150 self.assertEqual(cx.in_transaction, False)
151 cu.execute("insert into transactiontest(name) values (?)", ("foo",))
152 self.assertEqual(cx.in_transaction, True)
153 cu.execute("select name from transactiontest where name=?", ["foo"])
154 row = cu.fetchone()
155 self.assertEqual(cx.in_transaction, True)
156 cx.commit()
157 self.assertEqual(cx.in_transaction, False)
158 cu.execute("select name from transactiontest where name=?", ["foo"])
159 row = cu.fetchone()
160 self.assertEqual(cx.in_transaction, False)
161
162 def CheckInTransactionRO(self):
163 with self.assertRaises(AttributeError):
164 self.cx.in_transaction = True
165
Antoine Pitrou902fc8b2013-02-10 00:02:44 +0100166 def CheckOpenUri(self):
167 if sqlite.sqlite_version_info < (3, 7, 7):
168 with self.assertRaises(sqlite.NotSupportedError):
169 sqlite.connect(':memory:', uri=True)
170 return
171 self.addCleanup(unlink, TESTFN)
172 with sqlite.connect(TESTFN) as cx:
173 cx.execute('create table test(id integer)')
174 with sqlite.connect('file:' + TESTFN, uri=True) as cx:
175 cx.execute('insert into test(id) values(0)')
176 with sqlite.connect('file:' + TESTFN + '?mode=ro', uri=True) as cx:
177 with self.assertRaises(sqlite.OperationalError):
178 cx.execute('insert into test(id) values(1)')
179
Berker Peksag7bea2342016-06-12 14:09:51 +0300180 def CheckSameThreadErrorOnOldVersion(self):
181 if sqlite.sqlite_version_info >= (3, 3, 1):
182 self.skipTest('test needs sqlite3 versions older than 3.3.1')
183 with self.assertRaises(sqlite.NotSupportedError) as cm:
184 sqlite.connect(':memory:', check_same_thread=False)
185 self.assertEqual(str(cm.exception), 'shared connections not available')
Antoine Pitrou902fc8b2013-02-10 00:02:44 +0100186
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000187class CursorTests(unittest.TestCase):
188 def setUp(self):
189 self.cx = sqlite.connect(":memory:")
190 self.cu = self.cx.cursor()
191 self.cu.execute("create table test(id integer primary key, name text, income number)")
192 self.cu.execute("insert into test(name) values (?)", ("foo",))
193
194 def tearDown(self):
195 self.cu.close()
196 self.cx.close()
197
198 def CheckExecuteNoArgs(self):
199 self.cu.execute("delete from test")
200
201 def CheckExecuteIllegalSql(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300202 with self.assertRaises(sqlite.OperationalError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000203 self.cu.execute("select asdf")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000204
205 def CheckExecuteTooMuchSql(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300206 with self.assertRaises(sqlite.Warning):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000207 self.cu.execute("select 5+4; select 4+5")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000208
209 def CheckExecuteTooMuchSql2(self):
210 self.cu.execute("select 5+4; -- foo bar")
211
212 def CheckExecuteTooMuchSql3(self):
213 self.cu.execute("""
214 select 5+4;
215
216 /*
217 foo
218 */
219 """)
220
221 def CheckExecuteWrongSqlArg(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300222 with self.assertRaises(ValueError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000223 self.cu.execute(42)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000224
225 def CheckExecuteArgInt(self):
226 self.cu.execute("insert into test(id) values (?)", (42,))
227
228 def CheckExecuteArgFloat(self):
229 self.cu.execute("insert into test(income) values (?)", (2500.32,))
230
231 def CheckExecuteArgString(self):
232 self.cu.execute("insert into test(name) values (?)", ("Hugo",))
233
Petri Lehtinen023fe332012-02-01 22:18:19 +0200234 def CheckExecuteArgStringWithZeroByte(self):
235 self.cu.execute("insert into test(name) values (?)", ("Hu\x00go",))
236
237 self.cu.execute("select name from test where id=?", (self.cu.lastrowid,))
238 row = self.cu.fetchone()
239 self.assertEqual(row[0], "Hu\x00go")
240
Berker Peksagc4154402016-06-12 13:41:47 +0300241 def CheckExecuteNonIterable(self):
242 with self.assertRaises(ValueError) as cm:
243 self.cu.execute("insert into test(id) values (?)", 42)
244 self.assertEqual(str(cm.exception), 'parameters are of unsupported type')
245
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000246 def CheckExecuteWrongNoOfArgs1(self):
247 # too many parameters
Berker Peksag1003b342016-06-12 22:34:49 +0300248 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000249 self.cu.execute("insert into test(id) values (?)", (17, "Egon"))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000250
251 def CheckExecuteWrongNoOfArgs2(self):
252 # too little parameters
Berker Peksag1003b342016-06-12 22:34:49 +0300253 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000254 self.cu.execute("insert into test(id) values (?)")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000255
256 def CheckExecuteWrongNoOfArgs3(self):
257 # no parameters, parameters are needed
Berker Peksag1003b342016-06-12 22:34:49 +0300258 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000259 self.cu.execute("insert into test(id) values (?)")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000260
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000261 def CheckExecuteParamList(self):
262 self.cu.execute("insert into test(name) values ('foo')")
263 self.cu.execute("select name from test where name=?", ["foo"])
264 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000265 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000266
267 def CheckExecuteParamSequence(self):
268 class L(object):
269 def __len__(self):
270 return 1
271 def __getitem__(self, x):
272 assert x == 0
273 return "foo"
274
275 self.cu.execute("insert into test(name) values ('foo')")
276 self.cu.execute("select name from test where name=?", L())
277 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000278 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000279
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000280 def CheckExecuteDictMapping(self):
281 self.cu.execute("insert into test(name) values ('foo')")
282 self.cu.execute("select name from test where name=:name", {"name": "foo"})
283 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000284 self.assertEqual(row[0], "foo")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000285
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000286 def CheckExecuteDictMapping_Mapping(self):
287 class D(dict):
288 def __missing__(self, key):
289 return "foo"
290
291 self.cu.execute("insert into test(name) values ('foo')")
292 self.cu.execute("select name from test where name=:name", D())
293 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000294 self.assertEqual(row[0], "foo")
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000295
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000296 def CheckExecuteDictMappingTooLittleArgs(self):
297 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag1003b342016-06-12 22:34:49 +0300298 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000299 self.cu.execute("select name from test where name=:name and id=:id", {"name": "foo"})
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000300
301 def CheckExecuteDictMappingNoArgs(self):
302 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag1003b342016-06-12 22:34:49 +0300303 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000304 self.cu.execute("select name from test where name=:name")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000305
306 def CheckExecuteDictMappingUnnamed(self):
307 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag1003b342016-06-12 22:34:49 +0300308 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000309 self.cu.execute("select name from test where name=?", {"name": "foo"})
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000310
311 def CheckClose(self):
312 self.cu.close()
313
314 def CheckRowcountExecute(self):
315 self.cu.execute("delete from test")
316 self.cu.execute("insert into test(name) values ('foo')")
317 self.cu.execute("insert into test(name) values ('foo')")
318 self.cu.execute("update test set name='bar'")
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000319 self.assertEqual(self.cu.rowcount, 2)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000320
Georg Brandlf78e02b2008-06-10 17:40:04 +0000321 def CheckRowcountSelect(self):
322 """
323 pysqlite does not know the rowcount of SELECT statements, because we
324 don't fetch all rows after executing the select statement. The rowcount
325 has thus to be -1.
326 """
327 self.cu.execute("select 5 union select 6")
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000328 self.assertEqual(self.cu.rowcount, -1)
Georg Brandlf78e02b2008-06-10 17:40:04 +0000329
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000330 def CheckRowcountExecutemany(self):
331 self.cu.execute("delete from test")
332 self.cu.executemany("insert into test(name) values (?)", [(1,), (2,), (3,)])
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000333 self.assertEqual(self.cu.rowcount, 3)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000334
335 def CheckTotalChanges(self):
336 self.cu.execute("insert into test(name) values ('foo')")
337 self.cu.execute("insert into test(name) values ('foo')")
Berker Peksag48b5c982016-06-14 00:42:50 +0300338 self.assertLess(2, self.cx.total_changes, msg='total changes reported wrong value')
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000339
340 # Checks for executemany:
341 # Sequences are required by the DB-API, iterators
342 # enhancements in pysqlite.
343
344 def CheckExecuteManySequence(self):
345 self.cu.executemany("insert into test(income) values (?)", [(x,) for x in range(100, 110)])
346
347 def CheckExecuteManyIterator(self):
348 class MyIter:
349 def __init__(self):
350 self.value = 5
351
Georg Brandla18af4e2007-04-21 15:47:16 +0000352 def __next__(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000353 if self.value == 10:
354 raise StopIteration
355 else:
356 self.value += 1
357 return (self.value,)
358
359 self.cu.executemany("insert into test(income) values (?)", MyIter())
360
361 def CheckExecuteManyGenerator(self):
362 def mygen():
363 for i in range(5):
364 yield (i,)
365
366 self.cu.executemany("insert into test(income) values (?)", mygen())
367
368 def CheckExecuteManyWrongSqlArg(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300369 with self.assertRaises(ValueError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000370 self.cu.executemany(42, [(3,)])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000371
372 def CheckExecuteManySelect(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300373 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000374 self.cu.executemany("select ?", [(3,)])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000375
376 def CheckExecuteManyNotIterable(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300377 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000378 self.cu.executemany("insert into test(income) values (?)", 42)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000379
380 def CheckFetchIter(self):
381 # Optional DB-API extension.
382 self.cu.execute("delete from test")
383 self.cu.execute("insert into test(id) values (?)", (5,))
384 self.cu.execute("insert into test(id) values (?)", (6,))
385 self.cu.execute("select id from test order by id")
386 lst = []
387 for row in self.cu:
388 lst.append(row[0])
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000389 self.assertEqual(lst[0], 5)
390 self.assertEqual(lst[1], 6)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000391
392 def CheckFetchone(self):
393 self.cu.execute("select name from test")
394 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000395 self.assertEqual(row[0], "foo")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000396 row = self.cu.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000397 self.assertEqual(row, None)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000398
399 def CheckFetchoneNoStatement(self):
400 cur = self.cx.cursor()
401 row = cur.fetchone()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000402 self.assertEqual(row, None)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000403
404 def CheckArraySize(self):
405 # must default ot 1
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000406 self.assertEqual(self.cu.arraysize, 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000407
408 # now set to 2
409 self.cu.arraysize = 2
410
411 # now make the query return 3 rows
412 self.cu.execute("delete from test")
413 self.cu.execute("insert into test(name) values ('A')")
414 self.cu.execute("insert into test(name) values ('B')")
415 self.cu.execute("insert into test(name) values ('C')")
416 self.cu.execute("select name from test")
417 res = self.cu.fetchmany()
418
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000419 self.assertEqual(len(res), 2)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000420
421 def CheckFetchmany(self):
422 self.cu.execute("select name from test")
423 res = self.cu.fetchmany(100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000424 self.assertEqual(len(res), 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000425 res = self.cu.fetchmany(100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000426 self.assertEqual(res, [])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000427
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000428 def CheckFetchmanyKwArg(self):
429 """Checks if fetchmany works with keyword arguments"""
430 self.cu.execute("select name from test")
431 res = self.cu.fetchmany(size=100)
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000432 self.assertEqual(len(res), 1)
Gerhard Häringe7ea7452008-03-29 00:45:29 +0000433
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000434 def CheckFetchall(self):
435 self.cu.execute("select name from test")
436 res = self.cu.fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000437 self.assertEqual(len(res), 1)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000438 res = self.cu.fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000439 self.assertEqual(res, [])
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000440
441 def CheckSetinputsizes(self):
442 self.cu.setinputsizes([3, 4, 5])
443
444 def CheckSetoutputsize(self):
445 self.cu.setoutputsize(5, 0)
446
447 def CheckSetoutputsizeNoColumn(self):
448 self.cu.setoutputsize(42)
449
450 def CheckCursorConnection(self):
451 # Optional DB-API extension.
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000452 self.assertEqual(self.cu.connection, self.cx)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000453
454 def CheckWrongCursorCallable(self):
Berker Peksag1003b342016-06-12 22:34:49 +0300455 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000456 def f(): pass
457 cur = self.cx.cursor(f)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000458
459 def CheckCursorWrongClass(self):
460 class Foo: pass
461 foo = Foo()
Berker Peksag1003b342016-06-12 22:34:49 +0300462 with self.assertRaises(TypeError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000463 cur = sqlite.Cursor(foo)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000464
Victor Stinner45df8202010-04-28 22:31:17 +0000465@unittest.skipUnless(threading, 'This test requires threading.')
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000466class ThreadTests(unittest.TestCase):
467 def setUp(self):
468 self.con = sqlite.connect(":memory:")
469 self.cur = self.con.cursor()
470 self.cur.execute("create table test(id integer primary key, name text, bin binary, ratio number, ts timestamp)")
471
472 def tearDown(self):
473 self.cur.close()
474 self.con.close()
475
476 def CheckConCursor(self):
477 def run(con, errors):
478 try:
479 cur = con.cursor()
480 errors.append("did not raise ProgrammingError")
481 return
482 except sqlite.ProgrammingError:
483 return
484 except:
485 errors.append("raised wrong exception")
486
487 errors = []
488 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
489 t.start()
490 t.join()
491 if len(errors) > 0:
492 self.fail("\n".join(errors))
493
494 def CheckConCommit(self):
495 def run(con, errors):
496 try:
497 con.commit()
498 errors.append("did not raise ProgrammingError")
499 return
500 except sqlite.ProgrammingError:
501 return
502 except:
503 errors.append("raised wrong exception")
504
505 errors = []
506 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
507 t.start()
508 t.join()
509 if len(errors) > 0:
510 self.fail("\n".join(errors))
511
512 def CheckConRollback(self):
513 def run(con, errors):
514 try:
515 con.rollback()
516 errors.append("did not raise ProgrammingError")
517 return
518 except sqlite.ProgrammingError:
519 return
520 except:
521 errors.append("raised wrong exception")
522
523 errors = []
524 t = threading.Thread(target=run, kwargs={"con": self.con, "errors": errors})
525 t.start()
526 t.join()
527 if len(errors) > 0:
528 self.fail("\n".join(errors))
529
530 def CheckConClose(self):
531 def run(con, errors):
532 try:
533 con.close()
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 CheckCurImplicitBegin(self):
549 def run(cur, errors):
550 try:
551 cur.execute("insert into test(name) values ('a')")
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={"cur": self.cur, "errors": errors})
561 t.start()
562 t.join()
563 if len(errors) > 0:
564 self.fail("\n".join(errors))
565
566 def CheckCurClose(self):
567 def run(cur, errors):
568 try:
569 cur.close()
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={"cur": self.cur, "errors": errors})
579 t.start()
580 t.join()
581 if len(errors) > 0:
582 self.fail("\n".join(errors))
583
584 def CheckCurExecute(self):
585 def run(cur, errors):
586 try:
587 cur.execute("select name from test")
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 self.cur.execute("insert into test(name) values ('a')")
597 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
598 t.start()
599 t.join()
600 if len(errors) > 0:
601 self.fail("\n".join(errors))
602
603 def CheckCurIterNext(self):
604 def run(cur, errors):
605 try:
606 row = cur.fetchone()
607 errors.append("did not raise ProgrammingError")
608 return
609 except sqlite.ProgrammingError:
610 return
611 except:
612 errors.append("raised wrong exception")
613
614 errors = []
615 self.cur.execute("insert into test(name) values ('a')")
616 self.cur.execute("select name from test")
617 t = threading.Thread(target=run, kwargs={"cur": self.cur, "errors": errors})
618 t.start()
619 t.join()
620 if len(errors) > 0:
621 self.fail("\n".join(errors))
622
623class ConstructorTests(unittest.TestCase):
624 def CheckDate(self):
625 d = sqlite.Date(2004, 10, 28)
626
627 def CheckTime(self):
628 t = sqlite.Time(12, 39, 35)
629
630 def CheckTimestamp(self):
631 ts = sqlite.Timestamp(2004, 10, 28, 12, 39, 35)
632
633 def CheckDateFromTicks(self):
634 d = sqlite.DateFromTicks(42)
635
636 def CheckTimeFromTicks(self):
637 t = sqlite.TimeFromTicks(42)
638
639 def CheckTimestampFromTicks(self):
640 ts = sqlite.TimestampFromTicks(42)
641
642 def CheckBinary(self):
Guido van Rossumbae07c92007-10-08 02:46:15 +0000643 b = sqlite.Binary(b"\0'")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000644
645class ExtensionTests(unittest.TestCase):
646 def CheckScriptStringSql(self):
647 con = sqlite.connect(":memory:")
648 cur = con.cursor()
649 cur.executescript("""
650 -- bla bla
651 /* a stupid comment */
652 create table a(i);
653 insert into a(i) values (5);
654 """)
655 cur.execute("select i from a")
656 res = cur.fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000657 self.assertEqual(res, 5)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000658
Gerhard Häringf9cee222010-03-05 15:20:03 +0000659 def CheckScriptSyntaxError(self):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000660 con = sqlite.connect(":memory:")
661 cur = con.cursor()
Berker Peksag1003b342016-06-12 22:34:49 +0300662 with self.assertRaises(sqlite.OperationalError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000663 cur.executescript("create table test(x); asdf; create table test2(x)")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000664
665 def CheckScriptErrorNormal(self):
666 con = sqlite.connect(":memory:")
667 cur = con.cursor()
Berker Peksag1003b342016-06-12 22:34:49 +0300668 with self.assertRaises(sqlite.OperationalError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000669 cur.executescript("create table test(sadfsadfdsa); select foo from hurz;")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000670
Berker Peksagc4154402016-06-12 13:41:47 +0300671 def CheckCursorExecutescriptAsBytes(self):
672 con = sqlite.connect(":memory:")
673 cur = con.cursor()
674 with self.assertRaises(ValueError) as cm:
675 cur.executescript(b"create table test(foo); insert into test(foo) values (5);")
676 self.assertEqual(str(cm.exception), 'script argument must be unicode.')
677
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000678 def CheckConnectionExecute(self):
679 con = sqlite.connect(":memory:")
680 result = con.execute("select 5").fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000681 self.assertEqual(result, 5, "Basic test of Connection.execute")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000682
683 def CheckConnectionExecutemany(self):
684 con = sqlite.connect(":memory:")
685 con.execute("create table test(foo)")
686 con.executemany("insert into test(foo) values (?)", [(3,), (4,)])
687 result = con.execute("select foo from test order by foo").fetchall()
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000688 self.assertEqual(result[0][0], 3, "Basic test of Connection.executemany")
689 self.assertEqual(result[1][0], 4, "Basic test of Connection.executemany")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000690
691 def CheckConnectionExecutescript(self):
692 con = sqlite.connect(":memory:")
693 con.executescript("create table test(foo); insert into test(foo) values (5);")
694 result = con.execute("select foo from test").fetchone()[0]
Gregory P. Smith04cecaf2009-07-04 08:32:15 +0000695 self.assertEqual(result, 5, "Basic test of Connection.executescript")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000696
Gerhard Häringf9cee222010-03-05 15:20:03 +0000697class ClosedConTests(unittest.TestCase):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000698 def setUp(self):
699 pass
700
701 def tearDown(self):
702 pass
703
704 def CheckClosedConCursor(self):
705 con = sqlite.connect(":memory:")
706 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300707 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000708 cur = con.cursor()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000709
710 def CheckClosedConCommit(self):
711 con = sqlite.connect(":memory:")
712 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300713 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000714 con.commit()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000715
716 def CheckClosedConRollback(self):
717 con = sqlite.connect(":memory:")
718 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300719 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000720 con.rollback()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000721
722 def CheckClosedCurExecute(self):
723 con = sqlite.connect(":memory:")
724 cur = con.cursor()
725 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300726 with self.assertRaises(sqlite.ProgrammingError):
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000727 cur.execute("select 4")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000728
Gerhard Häringf9cee222010-03-05 15:20:03 +0000729 def CheckClosedCreateFunction(self):
730 con = sqlite.connect(":memory:")
731 con.close()
732 def f(x): return 17
Berker Peksag1003b342016-06-12 22:34:49 +0300733 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000734 con.create_function("foo", 1, f)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000735
736 def CheckClosedCreateAggregate(self):
737 con = sqlite.connect(":memory:")
738 con.close()
739 class Agg:
740 def __init__(self):
741 pass
742 def step(self, x):
743 pass
744 def finalize(self):
745 return 17
Berker Peksag1003b342016-06-12 22:34:49 +0300746 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000747 con.create_aggregate("foo", 1, Agg)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000748
749 def CheckClosedSetAuthorizer(self):
750 con = sqlite.connect(":memory:")
751 con.close()
752 def authorizer(*args):
753 return sqlite.DENY
Berker Peksag1003b342016-06-12 22:34:49 +0300754 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000755 con.set_authorizer(authorizer)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000756
757 def CheckClosedSetProgressCallback(self):
758 con = sqlite.connect(":memory:")
759 con.close()
760 def progress(): pass
Berker Peksag1003b342016-06-12 22:34:49 +0300761 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000762 con.set_progress_handler(progress, 100)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000763
764 def CheckClosedCall(self):
765 con = sqlite.connect(":memory:")
766 con.close()
Berker Peksag1003b342016-06-12 22:34:49 +0300767 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000768 con()
Gerhard Häringf9cee222010-03-05 15:20:03 +0000769
770class ClosedCurTests(unittest.TestCase):
771 def setUp(self):
772 pass
773
774 def tearDown(self):
775 pass
776
777 def CheckClosed(self):
778 con = sqlite.connect(":memory:")
779 cur = con.cursor()
780 cur.close()
781
782 for method_name in ("execute", "executemany", "executescript", "fetchall", "fetchmany", "fetchone"):
783 if method_name in ("execute", "executescript"):
784 params = ("select 4 union select 5",)
785 elif method_name == "executemany":
786 params = ("insert into foo(bar) values (?)", [(3,), (4,)])
787 else:
788 params = []
789
Berker Peksag1003b342016-06-12 22:34:49 +0300790 with self.assertRaises(sqlite.ProgrammingError):
Gerhard Häringf9cee222010-03-05 15:20:03 +0000791 method = getattr(cur, method_name)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000792 method(*params)
Gerhard Häringf9cee222010-03-05 15:20:03 +0000793
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000794def suite():
795 module_suite = unittest.makeSuite(ModuleTests, "Check")
796 connection_suite = unittest.makeSuite(ConnectionTests, "Check")
797 cursor_suite = unittest.makeSuite(CursorTests, "Check")
798 thread_suite = unittest.makeSuite(ThreadTests, "Check")
799 constructor_suite = unittest.makeSuite(ConstructorTests, "Check")
800 ext_suite = unittest.makeSuite(ExtensionTests, "Check")
Gerhard Häringf9cee222010-03-05 15:20:03 +0000801 closed_con_suite = unittest.makeSuite(ClosedConTests, "Check")
802 closed_cur_suite = unittest.makeSuite(ClosedCurTests, "Check")
803 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 +0000804
805def test():
806 runner = unittest.TextTestRunner()
807 runner.run(suite())
808
809if __name__ == "__main__":
810 test()