2060
2506
#cur.execute("insert into foo values(1,2)") # cache hit, but invalid sql
2061
2507
cur.executemany("insert into foo values(?)", [[1],[2]])
2062
2508
# overflow the statement cache
2063
l=[self.db.cursor().execute("select x from foo") for i in xrange(40)]
2509
l=[self.db.cursor().execute("select x from foo") for i in range(scsize+200)]
2065
2511
for _ in cur.execute("select * from foo"): pass
2066
db2=apsw.Connection("testdb")
2512
db2=apsw.Connection("testdb", statementcachesize=scsize)
2067
2513
cur2=db2.cursor()
2068
2514
cur2.execute("create table bar(x,y)")
2069
2515
for _ in cur.execute("select * from foo"): pass
2074
# note that a directory must be specified otherwise $LD_LIBRARY_PATH is used
2075
LOADEXTENSIONFILENAME="./testextension.sqlext"
2518
def testStatementCacheZeroSize(self):
2519
self.db=apsw.Connection("testdb", statementcachesize=-1)
2520
self.testStatementCache(-1)
2522
def testWikipedia(self):
2523
"Use front page of wikipedia to check unicode handling"
2524
# the text also includes characters that can't be represented in 16 bits
2525
text=u(r"""WIKIPEDIA\nEnglish\nThe Free Encyclopedia\n2 386 000+ articles\nDeutsch\nDie freie Enzyklop\\u00e4die\n753 000+ Artikel\nFran\\u00e7ais\nL\\u2019encyclop\\u00e9die libre\n662 000+ articles\nPolski\nWolna encyklopedia\n503 000+ hase\\u0142\n\\u65e5\\u672c\\u8a9e\n\\u30d5\\u30ea\\u30fc\\u767e\\u79d1\\u4e8b\\u5178\n492 000+ \\u8a18\\u4e8b\nItaliano\nL\\u2019enciclopedia libera\n456 000+ voci\nNederlands\nDe vrije encyclopedie\n440 000+ artikelen\nPortugu\\u00eas\nA enciclop\\u00e9dia livre\n380 000+ artigos\nEspa\\u00f1ol\nLa enciclopedia libre\n363 000+ art\\u00edculos\n\\u0420\\u0443\\u0441\\u0441\\u043a\\u0438\\u0439\n\\u0421\\u0432\\u043e\\u0431\\u043e\\u0434\\u043d\\u0430\\u044f \\u044d\\u043d\\u0446\\u0438\\u043a\\u043b\\u043e\\u043f\\u0435\\u0434\\u0438\\u044f\n285 000+ \\u0441\\u0442\\u0430\\u0442\\u0435\\u0439\nSearch \\u00b7 Suche \\u00b7 Rechercher \\u00b7 Szukaj \\u00b7 \\u691c\\u7d22 \\u00b7 Ricerca \\u00b7 Zoeken \\u00b7 Busca \\u00b7 Buscar\n\\u041f\\u043e\\u0438\\u0441\\u043a \\u00b7 S\\u00f6k \\u00b7 \\u641c\\u7d22 \\u00b7 S\\u00f8k \\u00b7 Haku \\u00b7 Cerca \\u00b7 Suk \\u00b7 \\u041f\\u043e\\u0448\\u0443\\u043a \\u00b7 C\\u0103utare \\u00b7 Ara\n 100 000+ \nCatal\\u00e0 \\u00b7 Deutsch \\u00b7 English \\u00b7 Espa\\u00f1ol \\u00b7 Fran\\u00e7ais \\u00b7 Italiano \\u00b7 Nederlands \\u00b7 \\u65e5\\u672c\\u8a9e \\u00b7 Norsk (bokm\\u00e5l) \\u00b7 Polski \\u00b7 Portugu\\u00eas \\u00b7 \\u0420\\u0443\\u0441\\u0441\\u043a\\u0438\\u0439 \\u00b7 Rom\\u00e2n\\u0103 \\u00b7 Suomi \\u00b7 Svenska \\u00b7 T\\u00fcrk\\u00e7e \\u00b7 \\u0423\\u043a\\u0440\\u0430\\u0457\\u043d\\u0441\\u044c\\u043a\\u0430 \\u00b7 Volap\\u00fck \\u00b7 \\u4e2d\\u6587\n 10 000+ \n\\u0627\\u0644\\u0639\\u0631\\u0628\\u064a\\u0629 \\u00b7 Asturianu \\u00b7 Krey\\u00f2l Ayisyen \\u00b7 Az\\u0259rbaycan / \\u0622\\u0630\\u0631\\u0628\\u0627\\u064a\\u062c\\u0627\\u0646 \\u062f\\u064a\\u0644\\u06cc \\u00b7 \\u09ac\\u09be\\u0982\\u09b2\\u09be \\u00b7 \\u0411\\u0435\\u043b\\u0430\\u0440\\u0443\\u0441\\u043a\\u0430\\u044f (\\u0410\\u043a\\u0430\\u0434\\u044d\\u043c\\u0456\\u0447\\u043d\\u0430\\u044f) \\u00b7 \\u09ac\\u09bf\\u09b7\\u09cd\\u09a3\\u09c1\\u09aa\\u09cd\\u09b0\\u09bf\\u09af\\u09bc\\u09be \\u09ae\\u09a3\\u09bf\\u09aa\\u09c1\\u09b0\\u09c0 \\u00b7 Bosanski \\u00b7 Brezhoneg \\u00b7 \\u0411\\u044a\\u043b\\u0433\\u0430\\u0440\\u0441\\u043a\\u0438 \\u00b7 \\u010cesky \\u00b7 Cymraeg \\u00b7 Dansk \\u00b7 Eesti \\u00b7 \\u0395\\u03bb\\u03bb\\u03b7\\u03bd\\u03b9\\u03ba\\u03ac \\u00b7 Esperanto \\u00b7 Euskara \\u00b7 \\u0641\\u0627\\u0631\\u0633\\u06cc \\u00b7 Galego \\u00b7 \\ud55c\\uad6d\\uc5b4 \\u00b7 \\u0939\\u093f\\u0928\\u094d\\u0926\\u0940 \\u00b7 Hrvatski \\u00b7 Ido \\u00b7 Bahasa Indonesia \\u00b7 \\u00cdslenska \\u00b7 \\u05e2\\u05d1\\u05e8\\u05d9\\u05ea \\u00b7 Basa Jawa \\u00b7 \\u10e5\\u10d0\\u10e0\\u10d7\\u10e3\\u10da\\u10d8 \\u00b7 Kurd\\u00ee / \\u0643\\u0648\\u0631\\u062f\\u06cc \\u00b7 Latina \\u00b7 Lumbaart \\u00b7 Latvie\\u0161u \\u00b7 L\\u00ebtzebuergesch \\u00b7 Lietuvi\\u0173 \\u00b7 Magyar \\u00b7 \\u041c\\u0430\\u043a\\u0435\\u0434\\u043e\\u043d\\u0441\\u043a\\u0438 \\u00b7 \\u092e\\u0930\\u093e\\u0920\\u0940 \\u00b7 Bahasa Melayu \\u00b7 \\u0928\\u0947\\u092a\\u093e\\u0932 \\u092d\\u093e\\u0937\\u093e \\u00b7 Norsk (nynorsk) \\u00b7 Nnapulitano \\u00b7 Occitan \\u00b7 Piemont\\u00e8is \\u00b7 Plattd\\u00fc\\u00fctsch \\u00b7 Shqip \\u00b7 Sicilianu \\u00b7 Simple English \\u00b7 Sinugboanon \\u00b7 Sloven\\u010dina \\u00b7 Sloven\\u0161\\u010dina \\u00b7 \\u0421\\u0440\\u043f\\u0441\\u043a\\u0438 \\u00b7 Srpskohrvatski / \\u0421\\u0440\\u043f\\u0441\\u043a\\u043e\\u0445\\u0440\\u0432\\u0430\\u0442\\u0441\\u043a\\u0438 \\u00b7 Basa Sunda \\u00b7 Tagalog \\u00b7 \\u0ba4\\u0bae\\u0bbf\\u0bb4\\u0bcd \\u00b7 \\u0c24\\u0c46\\u0c32\\u0c41\\u0c17\\u0c41 \\u00b7 \\u0e44\\u0e17\\u0e22 \\u00b7 Ti\\u1ebfng Vi\\u1ec7t \\u00b7 Walon\n 1 000+ \nAfrikaans \\u00b7 Alemannisch \\u00b7 \\u12a0\\u121b\\u122d\\u129b \\u00b7 Aragon\\u00e9s \\u00b7 Arm\\u00e3neashce \\u00b7 Arpitan \\u00b7 B\\u00e2n-l\\u00e2m-g\\u00fa \\u00b7 Basa Banyumasan \\u00b7 \\u0411\\u0435\\u043b\\u0430\\u0440\\u0443\\u0441\\u043a\\u0430\\u044f (\\u0422\\u0430\\u0440\\u0430\\u0448\\u043a\\u0435\\u0432i\\u0446\\u0430) \\u00b7 \\u092d\\u094b\\u091c\\u092a\\u0941\\u0930\\u0940 \\u00b7 Boarisch \\u00b7 Corsu \\u00b7 \\u0427\\u0103\\u0432\\u0430\\u0448 \\u00b7 Deitsch \\u00b7 \\u078b\\u07a8\\u0788\\u07ac\\u0780\\u07a8 \\u00b7 Eald Englisc \\u00b7 F\\u00f8royskt \\u00b7 Frysk \\u00b7 Furlan \\u00b7 Gaeilge \\u00b7 Gaelg \\u00b7 G\\u00e0idhlig \\u00b7 \\u53e4\\u6587 / \\u6587\\u8a00\\u6587 \\u00b7 \\u02bb\\u014clelo Hawai\\u02bbi \\u00b7 \\u0540\\u0561\\u0575\\u0565\\u0580\\u0565\\u0576 \\u00b7 Hornjoserbsce \\u00b7 Ilokano \\u00b7 Interlingua \\u00b7 \\u0418\\u0440\\u043e\\u043d \\u00e6\\u0432\\u0437\\u0430\\u0433 \\u00b7 \\u0c95\\u0ca8\\u0ccd\\u0ca8\\u0ca1 \\u00b7 Kapampangan \\u00b7 Kasz\\u00ebbsczi \\u00b7 Kernewek \\u00b7 \\u1797\\u17b6\\u179f\\u17b6\\u1781\\u17d2\\u1798\\u17c2\\u179a \\u00b7 Ladino / \\u05dc\\u05d0\\u05d3\\u05d9\\u05e0\\u05d5 \\u00b7 Ligure \\u00b7 Limburgs \\u00b7 Ling\\u00e1la \\u00b7 \\u0d2e\\u0d32\\u0d2f\\u0d3e\\u0d33\\u0d02 \\u00b7 Malti \\u00b7 M\\u0101ori \\u00b7 \\u041c\\u043e\\u043d\\u0433\\u043e\\u043b \\u00b7 N\\u0101huatlaht\\u014dlli \\u00b7 Nedersaksisch \\u00b7 \\u0928\\u0947\\u092a\\u093e\\u0932\\u0940 \\u00b7 Nouormand \\u00b7 Novial \\u00b7 O\\u2018zbek \\u00b7 \\u092a\\u093e\\u0934\\u093f \\u00b7 Pangasin\\u00e1n \\u00b7 \\u067e\\u069a\\u062a\\u0648 \\u00b7 \\u049a\\u0430\\u0437\\u0430\\u049b\\u0448\\u0430 \\u00b7 Ripoarisch \\u00b7 Rumantsch \\u00b7 Runa Simi \\u00b7 \\u0938\\u0902\\u0938\\u094d\\u0915\\u0943\\u0924\\u092e\\u094d \\u00b7 S\\u00e1megiella \\u00b7 Scots \\u00b7 Kiswahili \\u00b7 Tarand\\u00edne \\u00b7 Tatar\\u00e7a \\u00b7 \\u0422\\u043e\\u04b7\\u0438\\u043a\\u04e3 \\u00b7 Lea faka-Tonga \\u00b7 T\\u00fcrkmen \\u00b7 \\u0627\\u0631\\u062f\\u0648 \\u00b7 V\\u00e8neto \\u00b7 V\\u00f5ro \\u00b7 West-Vlams \\u00b7 Winaray \\u00b7 \\u5434\\u8bed \\u00b7 \\u05d9\\u05d9\\u05b4\\u05d3\\u05d9\\u05e9 \\u00b7 \\u7cb5\\u8a9e \\u00b7 Yor\\u00f9b\\u00e1 \\u00b7 Zazaki \\u00b7 \\u017demait\\u0117\\u0161ka\n 100+ \n\\u0710\\u072a\\u0721\\u071d\\u0710 \\u00b7 Ava\\u00f1e\\u2019\\u1ebd \\u00b7 \\u0410\\u0432\\u0430\\u0440 \\u00b7 Aymara \\u00b7 Bamanankan \\u00b7 \\u0411\\u0430\\u0448\\u04a1\\u043e\\u0440\\u0442 \\u00b7 Bikol Central \\u00b7 \\u0f56\\u0f7c\\u0f51\\u0f0b\\u0f61\\u0f72\\u0f42 \\u00b7 Chamoru \\u00b7 Chavacano de Zamboanga \\u00b7 Bislama \\u00b7 Din\\u00e9 Bizaad \\u00b7 Dolnoserbski \\u00b7 Emigli\\u00e0n-Rumagn\\u00f2l \\u00b7 E\\u028begbe \\u00b7 \\u06af\\u06cc\\u0644\\u06a9\\u06cc \\u00b7 \\u0a97\\u0ac1\\u0a9c\\u0ab0\\u0abe\\u0aa4\\u0ac0 \\u00b7 \\U00010332\\U0001033f\\U00010344\\U00010339\\U00010343\\U0001033a \\u00b7 Hak-k\\u00e2-fa / \\u5ba2\\u5bb6\\u8a71 \\u00b7 Igbo \\u00b7 \\u1403\\u14c4\\u1483\\u144e\\u1450\\u1466 / Inuktitut \\u00b7 Interlingue \\u00b7 \\u0915\\u0936\\u094d\\u092e\\u0940\\u0930\\u0940 / \\u0643\\u0634\\u0645\\u064a\\u0631\\u064a \\u00b7 Kongo \\u00b7 \\u041a\\u044b\\u0440\\u0433\\u044b\\u0437\\u0447\\u0430 \\u00b7 \\u0e9e\\u0eb2\\u0eaa\\u0eb2\\u0ea5\\u0eb2\\u0ea7 \\u00b7 lojban \\u00b7 Malagasy \\u00b7 M\\u0101z\\u0259r\\u016bni / \\u0645\\u0627\\u0632\\u0650\\u0631\\u0648\\u0646\\u06cc \\u00b7 M\\u00ecng-d\\u0115\\u0324ng-ng\\u1e73\\u0304 \\u00b7 \\u041c\\u043e\\u043b\\u0434\\u043e\\u0432\\u0435\\u043d\\u044f\\u0441\\u043a\\u044d \\u00b7 \\u1017\\u1019\\u102c\\u1005\\u102c \\u00b7 Ekakair\\u0169 Naoero \\u00b7 N\\u0113hiyaw\\u0113win / \\u14c0\\u1426\\u1403\\u152d\\u140d\\u140f\\u1423 \\u00b7 Norfuk / Pitkern \\u00b7 \\u041d\\u043e\\u0445\\u0447\\u0438\\u0439\\u043d \\u00b7 \\u0b13\\u0b21\\u0b3c\\u0b3f\\u0b06 \\u00b7 Afaan Oromoo \\u00b7 \\u0985\\u09b8\\u09ae\\u09c0\\u09af\\u09bc\\u09be \\u00b7 \\u0a2a\\u0a70\\u0a1c\\u0a3e\\u0a2c\\u0a40 / \\u067e\\u0646\\u062c\\u0627\\u0628\\u06cc \\u00b7 Papiamentu \\u00b7 Q\\u0131r\\u0131mtatarca \\u00b7 Romani / \\u0930\\u094b\\u092e\\u093e\\u0928\\u0940 \\u00b7 Kinyarwanda \\u00b7 Gagana S\\u0101moa \\u00b7 Sardu \\u00b7 Seeltersk \\u00b7 \\u0dc3\\u0dd2\\u0d82\\u0dc4\\u0dbd \\u00b7 \\u0633\\u0646\\u068c\\u064a \\u00b7 \\u0421\\u043b\\u043e\\u0432\\u0463\\u043d\\u044c\\u0441\\u043a\\u044a \\u00b7 Af Soomaali \\u00b7 SiSwati \\u00b7 Reo Tahiti \\u00b7 Taqbaylit \\u00b7 Tetun \\u00b7 \\u1275\\u130d\\u122d\\u129b \\u00b7 Tok Pisin \\u00b7 \\u13e3\\u13b3\\u13a9 \\u00b7 \\u0423\\u0434\\u043c\\u0443\\u0440\\u0442 \\u00b7 Uyghur / \\u0626\\u06c7\\u064a\\u063a\\u06c7\\u0631\\u0686\\u0647 \\u00b7 Tshiven\\u1e13a \\u00b7 Wollof \\u00b7 isiXhosa \\u00b7 Ze\\u00eauws \\u00b7 isiZulu\nOther languages \\u00b7 Weitere Sprachen \\u00b7 \\u4ed6\\u306e\\u8a00\\u8a9e \\u00b7 Kompletna lista j\\u0119zyk\\u00f3w \\u00b7 \\u5176\\u4ed6\\u8bed\\u8a00 \\u00b7 \\u0414\\u0440\\u0443\\u0433\\u0438\\u0435 \\u044f\\u0437\\u044b\\u043a\\u0438 \\u00b7 Aliaj lingvoj \\u00b7 \\ub2e4\\ub978 \\uc5b8\\uc5b4 \\u00b7 Ng\\u00f4n ng\\u1eef kh\\u00e1c""")
2529
for encoding in "UTF-16", "UTF-16le", "UTF-16be", "UTF-8":
2530
if os.path.exists("testdb"):
2532
db=apsw.Connection("testdb")
2534
c.execute("pragma encoding=\"%s\"" % (encoding,))
2535
for row in c.execute("pragma encoding"):
2536
# we use startswith as UTF-16 will be returned with le/be suffix
2537
self.assert_(row[0].startswith(encoding))
2538
c.execute("create table foo(x); insert into foo values(?)", (text,))
2539
for row in c.execute("select * from foo"):
2540
self.failUnlessEqual(row[0], text)
2544
def sourceCheckFunction(self, name, lines):
2545
# Checks an individual function does things right
2546
if name.startswith("ZeroBlobBind_"):
2549
if name.startswith("APSWCursor_"):
2550
# these methods aren't publically exported so the checks
2551
# will already have been done by their callers
2552
if name[len("APSWCursor_"):] in ("dealloc", "init", "dobinding", "dobindings", "doexectrace", "dorowtrace", "step", "close"):
2556
for i,line in enumerate(lines):
2557
if "CHECK_USE" in line and use is None:
2559
if "CHECK_CLOSED" in line and closed is None:
2562
self.fail("CHECK_USE missing in "+name)
2564
self.fail("CHECK_CLOSED missing in "+name)
2566
self.fail("CHECK_CLOSED should be after CHECK_USE in "+name)
2569
if name.startswith("Connection_"):
2570
# these methods aren't publically exported so the checks
2571
# will already have been done by their callers
2572
if name[len("Connection_"):] in ("internal_cleanup", "dealloc", "init", "close", "interrupt"):
2576
for i,line in enumerate(lines):
2577
if "CHECK_USE" in line and use is None:
2579
if "CHECK_CLOSED" in line and closed is None:
2582
self.fail("CHECK_USE missing in "+name)
2584
self.fail("CHECK_CLOSED missing in "+name)
2586
self.fail("CHECK_CLOSED should be after CHECK_USE in "+name)
2589
if name.startswith("APSWBlob_"):
2590
# these methods aren't publically exported so the checks
2591
# will already have been done by their callers
2592
if name[len("APSWBlob_"):] in ("dealloc", "init", "close"):
2596
for i,line in enumerate(lines):
2597
if "CHECK_USE" in line and use is None:
2599
if "CHECK_BLOB_CLOSED" in line and closed is None:
2602
self.fail("CHECK_USE missing in "+name)
2604
self.fail("CHECK_BLOB_CLOSED missing in "+name)
2606
self.fail("CHECK_BLOB_CLOSED should be after CHECK_USE in "+name)
2609
self.fail(name+" doesn't have source check")
2611
def testSourceChecks(self):
2612
"Check various source code issues"
2613
# We expect a coding style where the functions are named
2614
# Object_method, are at the start of the line and have a first
2615
# parameter named self.
2616
if not os.path.exists("apsw.c"): return
2617
funcpat=re.compile(r"^(\w+_\w+)\s*\(\s*\w+\s*\*\s*self")
2621
for line in open("apsw.c", "rtU"):
2622
if line.startswith("}") and infunc:
2624
self.sourceCheckFunction(name, lines)
2628
if name and line.startswith("{"):
2634
m=funcpat.match(line)
2639
def testZeroBlob(self):
2640
"Verify handling of zero blobs"
2641
self.assertRaises(TypeError, apsw.zeroblob)
2642
self.assertRaises(TypeError, apsw.zeroblob, "foo")
2643
self.assertRaises(TypeError, apsw.zeroblob, -7)
2644
self.assertRaises(TypeError, apsw.zeroblob, size=27)
2645
self.assertRaises(OverflowError, apsw.zeroblob, 4000000000)
2646
cur=self.db.cursor()
2647
cur.execute("create table foo(x)")
2648
cur.execute("insert into foo values(?)", (apsw.zeroblob(27),))
2649
v=next(cur.execute("select * from foo"))[0]
2650
self.assertEqual(v, b(r"\x00"*27))
2651
# Make sure inheritance works
2653
def __init__(self, *args):
2655
class derived(apsw.zeroblob):
2656
def __init__(self, num):
2657
#multi.__init__(self)
2658
apsw.zeroblob.__init__(self, num)
2659
cur.execute("delete from foo; insert into foo values(?)", (derived(28),))
2660
v=next(cur.execute("select * from foo"))[0]
2661
self.assertEqual(v, b(r"\x00"*28))
2663
def testBlobIO(self):
2664
"Verify Blob input/output"
2665
cur=self.db.cursor()
2666
rowid=next(cur.execute("create table foo(x blob); insert into foo values(zeroblob(98765)); select rowid from foo"))[0]
2667
self.assertRaises(TypeError, self.db.blobopen, 1)
2668
self.assertRaises(TypeError, self.db.blobopen, u("main"), "foo\xf3")
2669
if sys.version_info>=(2,4):
2670
# Bug in python 2.3 gives internal error when complex is
2671
# passed to PyArg_ParseTuple for Long instead of raising
2672
# TypeError. Corrected in 2.4
2673
self.assertRaises(TypeError, self.db.blobopen, u("main"), "foo", "x", complex(-1,-1), True)
2674
self.assertRaises(TypeError, self.db.blobopen, u("main"), "foo", "x", rowid, True, False)
2675
self.assertRaises(apsw.SQLError, self.db.blobopen, "main", "foo", "x", rowid+27, False)
2676
self.assertRaises(apsw.SQLError, self.db.blobopen, "foo", "foo" , "x", rowid, False)
2677
self.assertRaises(apsw.SQLError, self.db.blobopen, "main", "x" , "x", rowid, False)
2678
self.assertRaises(apsw.SQLError, self.db.blobopen, "main", "foo" , "y", rowid, False)
2679
blobro=self.db.blobopen("main", "foo", "x", rowid, False)
2680
# sidebar: check they can't be manually created
2681
self.assertRaises(TypeError, type(blobro))
2683
self.assertEqual(blobro.length(), 98765)
2684
self.assertEqual(blobro.length(), 98765)
2685
self.failUnlessEqual(blobro.read(0), BYTES(""))
2686
for i in range(98765):
2688
self.assertEqual(BYTES(r"\x00"), x)
2690
self.assertEqual(x, None)
2692
self.assertEqual(blobro.tell(), 98765)
2694
self.assertEqual(blobro.tell(), 0)
2695
self.failUnlessEqual(len(blobro.read(11119999)), 98765)
2697
self.assertEqual(blobro.tell(), 2222)
2699
self.assertEqual(blobro.tell(), 0)
2700
self.assertEqual(blobro.read(), BYTES(r"\x00"*98765))
2702
self.assertEqual(blobro.read(), BYTES(r"\x00"*3))
2704
self.assertRaises(TypeError, blobro.read, "foo")
2705
self.assertRaises(TypeError, blobro.tell, "foo")
2706
self.assertRaises(TypeError, blobro.seek)
2707
self.assertRaises(TypeError, blobro.seek, "foo", 1)
2708
self.assertRaises(TypeError, blobro.seek, 0, 1, 2)
2709
self.assertRaises(ValueError, blobro.seek, 0, -3)
2710
self.assertRaises(ValueError, blobro.seek, 0, 3)
2711
# can't seek before begining or after end of file
2712
self.assertRaises(ValueError, blobro.seek, -1, 0)
2713
self.assertRaises(ValueError, blobro.seek, 25, 1)
2714
self.assertRaises(ValueError, blobro.seek, 25, 2)
2715
self.assertRaises(ValueError, blobro.seek, 100000, 0)
2716
self.assertRaises(ValueError, blobro.seek, -100000, 1)
2717
self.assertRaises(ValueError, blobro.seek, -100000, 2)
2719
self.assertRaises(apsw.ReadOnlyError, blobro.write, b("kermit was here"))
2720
# you get the error on the close too, and blob is always closed - sqlite ticket #2815
2721
self.assertRaises(apsw.ReadOnlyError, blobro.close)
2722
# check can't work on closed blob
2723
self.assertRaises(ValueError, blobro.read)
2724
self.assertRaises(ValueError, blobro.seek, 0, 0)
2725
self.assertRaises(ValueError, blobro.tell)
2726
self.assertRaises(ValueError, blobro.write, "abc")
2728
blobrw=self.db.blobopen("main", "foo", "x", rowid, True)
2729
self.assertEqual(blobrw.length(), 98765)
2730
blobrw.write(b("abcd"))
2732
self.assertEqual(blobrw.read(4), BYTES("abcd"))
2733
blobrw.write(b("efg"))
2735
self.assertEqual(blobrw.read(7), BYTES("abcdefg"))
2737
blobrw.write(b("hijkl"))
2738
blobrw.seek(-98765, 2)
2739
self.assertEqual(blobrw.read(55), BYTES("abcdefg"+r"\x00"*43+"hijkl"))
2740
self.assertRaises(TypeError, blobrw.write, 12)
2741
self.assertRaises(TypeError, blobrw.write)
2742
# try to go beyond end
2743
self.assertRaises(ValueError, blobrw.write, b(" "*100000))
2744
self.assertRaises(TypeError, blobrw.close, "elephant")
2746
def testBlobReadError(self):
2747
"Ensure blob read errors are handled well"
2748
cur=self.db.cursor()
2749
cur.execute("create table ioerror (x, blob)")
2750
cur.execute("insert into ioerror (rowid,x,blob) values (2,3,x'deadbeef')")
2751
blob=self.db.blobopen("main", "ioerror", "blob", 2, False)
2753
cur.execute("update ioerror set blob='fsdfdsfasd' where x=3")
2758
klass,value=sys.exc_info()[:2]
2759
self.assert_(klass is apsw.AbortError)
2761
# Note that faults fire only once, so there is no need to reset
2762
# them. The testing for objects bigger than 2GB is done in
2764
def testzzFaultInjection(self):
2765
if not hasattr(apsw, "faultdict"):
2774
# The 1/0 in these tests is to cause a ZeroDivisionError so
2775
# that an exception is always thrown. If we catch that then
2776
# it means earlier expected exceptions were not thrown.
2778
## UnknownSQLiteErrorCode
2779
apsw.faultdict["UnknownSQLiteErrorCode"]=True
2781
self.db.cursor().execute("select '")
2784
klass,value=sys.exc_info()[:2]
2785
self.assert_(klass is apsw.Error)
2786
self.assert_("254" in str(value))
2788
## AsWriteBufferFails
2790
apsw.faultdict["AsWriteBufferFails"]=True
2792
for row in self.db.cursor().execute("select x'1234ccddeeff'"):
2796
klass,value=sys.exc_info()[:2]
2797
self.assert_(klass is MemoryError)
2799
## ConnectionCloseFail
2800
apsw.faultdict["ConnectionCloseFail"]=True
2802
db=apsw.Connection(":memory:")
2803
db.cursor().execute("select 3")
2807
klass,value=sys.exc_info()[:2]
2808
self.assert_(klass is apsw.IOError)
2810
## DestructorCloseFail
2811
if not os.getenv("APSW_NO_MEMLEAK"):
2812
# save existing excepthook
2816
def ehook(t,v,tb, called=called):
2818
sys.excepthook=ehook
2820
apsw.faultdict["DestructorCloseFail"]=True
2821
db=apsw.Connection(":memory:")
2822
db.cursor().execute("select 3")
2825
# check there was an unraiseable
2826
self.failUnlessEqual(called[0], 1)
2831
apsw.faultdict["BlobAllocFails"]=True
2833
db=apsw.Connection(":memory:")
2834
db.cursor().execute("create table foo(ablob); insert into foo (ROWID, ablob) values (1,x'aabbccddeeff')")
2835
blob=db.blobopen("main", "foo", "ablob", 1, False)
2838
klass,value=sys.exc_info()[:2]
2839
self.assert_(klass is MemoryError)
2842
apsw.faultdict["CursorAllocFails"]=True
2844
db=apsw.Connection(":memory:")
2845
db.cursor().execute("select 3")
2848
klass,value=sys.exc_info()[:2]
2849
self.assert_(klass is MemoryError)
2851
## RollbackHookExistingError
2852
apsw.faultdict["RollbackHookExistingError"]=True
2854
db=apsw.Connection(":memory:")
2855
db.setrollbackhook(dummy)
2856
db.cursor().execute("create table foo(a); begin ; insert into foo values(3); rollback")
2859
klass,value=sys.exc_info()[:2]
2860
self.assert_(klass is MemoryError)
2862
## CommitHookExceptionAlready
2863
apsw.faultdict["CommitHookExistingError"]=True
2865
db=apsw.Connection(":memory:")
2866
db.setcommithook(dummy)
2867
db.cursor().execute("begin; create table foo(a); insert into foo values(3); commit")
2870
klass,value=sys.exc_info()[:2]
2871
self.assert_(klass is MemoryError)
2873
## AuthorizerExistingError
2874
apsw.faultdict["AuthorizerExistingError"]=True
2876
db=apsw.Connection(":memory:")
2877
db.setauthorizer(dummy)
2878
db.cursor().execute("create table foo(a)")
2881
klass,value=sys.exc_info()[:2]
2882
self.assert_(klass is MemoryError)
2884
## SetAuthorizerNullFail
2885
apsw.faultdict["SetAuthorizerNullFail"]=True
2887
db=apsw.Connection(":memory:")
2888
db.setauthorizer(None)
2891
klass,value=sys.exc_info()[:2]
2892
self.assert_(klass is apsw.IOError)
2894
## SetAuthorizerFail
2895
apsw.faultdict["SetAuthorizerFail"]=True
2897
db=apsw.Connection(":memory:")
2898
db.setauthorizer(dummy)
2901
klass,value=sys.exc_info()[:2]
2902
self.assert_(klass is apsw.IOError)
2904
## CollationNeededNullFail
2905
apsw.faultdict["CollationNeededNullFail"]=True
2907
db=apsw.Connection(":memory:")
2908
db.collationneeded(None)
2911
klass,value=sys.exc_info()[:2]
2912
self.assert_(klass is apsw.IOError)
2914
## CollationNeededFail
2915
apsw.faultdict["CollationNeededFail"]=True
2917
db=apsw.Connection(":memory:")
2918
db.collationneeded(dummy)
2921
klass,value=sys.exc_info()[:2]
2922
self.assert_(klass is apsw.IOError)
2924
##EnableLoadExtensionFail
2925
apsw.faultdict["EnableLoadExtensionFail"]=True
2927
db=apsw.Connection(":memory:")
2928
db.enableloadextension(True)
2931
klass,value=sys.exc_info()[:2]
2932
self.assert_(klass is apsw.IOError)
2934
## SetBusyHandlerNullFail
2935
apsw.faultdict["SetBusyHandlerNullFail"]=True
2937
db=apsw.Connection(":memory:")
2938
db.setbusyhandler(None)
2941
klass,value=sys.exc_info()[:2]
2942
self.assert_(klass is apsw.IOError)
2944
## SetBusyHandlerFail
2945
apsw.faultdict["SetBusyHandlerFail"]=True
2947
db=apsw.Connection(":memory:")
2948
db.setbusyhandler(dummy)
2951
klass,value=sys.exc_info()[:2]
2952
self.assert_(klass is apsw.IOError)
2955
apsw.faultdict["UnknownValueType"]=True
2957
db=apsw.Connection(":memory:")
2958
db.createscalarfunction("dummy", dummy)
2959
db.cursor().execute("select dummy(4)")
2962
klass,value=sys.exc_info()[:2]
2963
self.assert_(klass is apsw.Error)
2964
self.assert_("123456" in str(value))
2966
## UnknownColumnType
2967
apsw.faultdict["UnknownColumnType"]=True
2969
db=apsw.Connection(":memory:")
2970
for row in db.cursor().execute("select 3"):
2974
klass,value=sys.exc_info()[:2]
2975
self.assert_(klass is apsw.Error)
2976
self.assert_("12348" in str(value))
2978
## SetContextResultUnicodeConversionFails
2979
apsw.faultdict["SetContextResultUnicodeConversionFails"]=True
2981
db=apsw.Connection(":memory:")
2982
db.createscalarfunction("foo", lambda x: u("another unicode string"))
2983
for row in db.cursor().execute("select foo(3)"):
2987
klass,value=sys.exc_info()[:2]
2988
self.assert_(klass is MemoryError)
2990
## SetContextResultStringUnicodeConversionFails
2991
if sys.version_info<(3,0):
2992
apsw.faultdict["SetContextResultStringUnicodeConversionFails"]=True
2994
db=apsw.Connection(":memory:")
2995
db.createscalarfunction("foo", lambda x: "another string"*10000)
2996
for row in db.cursor().execute("select foo(3)"):
3000
klass,value=sys.exc_info()[:2]
3001
self.assert_(klass is MemoryError)
3003
## SetContextResultAsReadBufferFail
3004
apsw.faultdict["SetContextResultAsReadBufferFail"]=True
3006
db=apsw.Connection(":memory:")
3007
db.createscalarfunction("foo", lambda x: b("another string"))
3008
for row in db.cursor().execute("select foo(3)"):
3012
klass,value=sys.exc_info()[:2]
3013
self.assert_(klass is MemoryError)
3015
## GFAPyTuple_NewFail
3016
apsw.faultdict["GFAPyTuple_NewFail"]=True
3018
db=apsw.Connection(":memory:")
3019
db.createscalarfunction("foo", dummy)
3020
for row in db.cursor().execute("select foo(3)"):
3024
klass,value=sys.exc_info()[:2]
3025
self.assert_(klass is MemoryError)
3028
apsw.faultdict["GFAPyTuple_NewFail"]=True
3030
db=apsw.Connection(":memory:")
3032
return None, dummy2, dummy2
3033
db.createaggregatefunction("foo", foo)
3034
for row in db.cursor().execute("create table bar(x);insert into bar values(3); select foo(x) from bar"):
3038
klass,value=sys.exc_info()[:2]
3039
self.assert_(klass is MemoryError)
3041
## CBDispatchExistingError
3042
apsw.faultdict["CBDispatchExistingError"]=True
3044
db=apsw.Connection(":memory:")
3045
db.createscalarfunction("foo", dummy)
3046
db.cursor().execute("select foo(3)")
3049
klass,value=sys.exc_info()[:2]
3050
self.assert_(klass is MemoryError)
3052
## CBDispatchFinalError
3053
apsw.faultdict["CBDispatchFinalError"]=True
3055
# save existing excepthook
3059
def ehook(t,v,tb, called=called):
3061
sys.excepthook=ehook
3063
db=apsw.Connection(":memory:")
3065
return None, dummy, dummy2
3066
db.createaggregatefunction("foo", foo)
3067
for row in db.cursor().execute("create table bar(x);insert into bar values(3); select foo(x) from bar"):
3071
klass,value=sys.exc_info()[:2]
3072
self.assert_(klass is ZeroDivisionError)
3075
# check there was an unraiseable
3076
self.failUnlessEqual(called[0], 1)
3078
## Virtual table code
3080
def Create(self, *args):
3081
return "create table foo(x,y)", Table()
3085
self.data=[ #("rowid", "x", "y"),
3091
def BestIndex(self, *args): return None
3093
def UpdateChangeRow(self, rowid, newrowid, fields):
3094
for i, row in enumerate(self.data):
3096
self.data[i]=[newrowid]+list(fields)
3098
def __init__(self, table):
3102
return self.row>=len(self.table.data)
3104
return self.table.data[self.row][0]
3105
def Column(self, col):
3106
return self.table.data[self.row][1+col]
3107
def Filter(self, *args):
3111
def Close(self): pass
3113
## VtabCreateBadString
3114
apsw.faultdict["VtabCreateBadString"]=True
3116
db=apsw.Connection(":memory:")
3117
db.createmodule("nonsense", None)
3118
db.cursor().execute("create virtual table foo using nonsense(3,4)")
3121
klass,value=sys.exc_info()[:2]
3122
self.assert_(klass is MemoryError)
3124
## VtabUpdateChangeRowFail
3125
apsw.faultdict["VtabUpdateChangeRowFail"]=True
3127
db=apsw.Connection(":memory:")
3128
db.createmodule("foo", Source())
3129
db.cursor().execute("create virtual table foo using foo();update foo set x=3 where y=2")
3132
klass,value=sys.exc_info()[:2]
3133
self.assert_(klass is MemoryError)
3135
## VtabUpdateBadField
3136
apsw.faultdict["VtabUpdateBadField"]=True
3138
db=apsw.Connection(":memory:")
3139
db.createmodule("foo", Source())
3140
db.cursor().execute("create virtual table foo using foo();update foo set x=3 where y=2")
3143
klass,value=sys.exc_info()[:2]
3144
self.assert_(klass is MemoryError)
3146
## VtabRenameBadName
3147
apsw.faultdict["VtabRenameBadName"]=True
3149
db=apsw.Connection(":memory:")
3150
db.createmodule("foo", Source())
3151
db.cursor().execute("create virtual table foo using foo(); alter table foo rename to bar")
3154
klass,value=sys.exc_info()[:2]
3155
self.assert_(klass is MemoryError)
3157
## VtabRenameBadName
3158
apsw.faultdict["CreateModuleFail"]=True
3160
db=apsw.Connection(":memory:")
3161
db.createmodule("foo", Source())
3164
klass,value=sys.exc_info()[:2]
3165
self.assert_(klass is apsw.IOError)
3168
if sys.platform!="win32":
3169
# note that a directory must be specified otherwise $LD_LIBRARY_PATH is used
3170
LOADEXTENSIONFILENAME="./testextension.sqlext"
3172
LOADEXTENSIONFILENAME="testextension.sqlext"
2077
3174
MEMLEAKITERATIONS=1000
2078
3175
PROFILESTEPS=100000
2080
3177
if __name__=='__main__':
2082
if not getattr(apsw, "enableloadextension", None):
3179
memdb=apsw.Connection(":memory:")
3180
if not getattr(memdb, "enableloadextension", None):
2083
3181
del APSW.testLoadExtension
2085
if getattr(apsw, "enableloadextension", None) and not os.path.exists(LOADEXTENSIONFILENAME):
2086
print "Not doing LoadExtension test. You need to compile the extension first"
3183
# We can do extension loading but no extension present ...
3184
if getattr(memdb, "enableloadextension", None) and not os.path.exists(LOADEXTENSIONFILENAME):
3185
write("Not doing LoadExtension test. You need to compile the extension first\n")
2087
3186
if sys.platform.startswith("darwin"):
2088
print " gcc -fPIC -bundle -o "+LOADEXTENSIONFILENAME+" -Isqlite3 testextension.c"
3187
write(" gcc -fPIC -bundle -o "+LOADEXTENSIONFILENAME+" -Isqlite3 testextension.c\n")
2090
print " gcc -fPIC -shared -o "+LOADEXTENSIONFILENAME+" -Isqlite3 testextension.c"
3189
write(" gcc -fPIC -shared -o "+LOADEXTENSIONFILENAME+" -Isqlite3 testextension.c\n")
2091
3190
del APSW.testLoadExtension
2093
# This test has to deliberately leak memory
2094
3195
if os.getenv("APSW_NO_MEMLEAK"):
2095
del APSW.testWriteUnraiseable
3196
# Delete tests that have to deliberately leak memory
3197
# del APSW.testWriteUnraiseable (used to but no more)
2097
3200
v=os.getenv("APSW_TEST_ITERATIONS")
2099
3202
unittest.main()