1b19a2bc6Sdrh# 2001 September 15 2960e8c63Sdrh# 3b19a2bc6Sdrh# The author disclaims copyright to this source code. In place of 4b19a2bc6Sdrh# a legal notice, here is a blessing: 5960e8c63Sdrh# 6b19a2bc6Sdrh# May you do good and not evil. 7b19a2bc6Sdrh# May you find forgiveness for yourself and forgive others. 8b19a2bc6Sdrh# May you share freely, never taking more than you give. 9960e8c63Sdrh# 10960e8c63Sdrh#*********************************************************************** 11960e8c63Sdrh# This file implements regression tests for TCL interface to the 12960e8c63Sdrh# SQLite library. 13960e8c63Sdrh# 14960e8c63Sdrh# Actually, all tests are based on the TCL interface, so the main 15960e8c63Sdrh# interface is pretty well tested. This file contains some addition 16960e8c63Sdrh# tests for fringe issues that the main test suite does not cover. 17960e8c63Sdrh# 18404ca075Sdanielk1977# $Id: tclsqlite.test,v 1.73 2009/03/16 13:19:36 danielk1977 Exp $ 19960e8c63Sdrh 20960e8c63Sdrhset testdir [file dirname $argv0] 21960e8c63Sdrhsource $testdir/tester.tcl 22960e8c63Sdrh 23960e8c63Sdrh# Check the error messages generated by tclsqlite 24960e8c63Sdrh# 25ef4ac8f9Sdrhif {[sqlite3 -has-codec]} { 269eb9e26bSdrh set r "sqlite_orig HANDLE FILENAME ?-key CODEC-KEY?" 2722fbcb8dSdrh} else { 28039963adSdrh set r "sqlite3 HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN? ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN?" 2922fbcb8dSdrh} 30960e8c63Sdrhdo_test tcl-1.1 { 31ef4ac8f9Sdrh set v [catch {sqlite3 bogus} msg] 32df81a25aSdrh regsub {really_sqlite3} $msg {sqlite3} msg 33960e8c63Sdrh lappend v $msg 3422fbcb8dSdrh} [list 1 "wrong # args: should be \"$r\""] 35960e8c63Sdrhdo_test tcl-1.2 { 36960e8c63Sdrh set v [catch {db bogus} msg] 37960e8c63Sdrh lappend v $msg 38404ca075Sdanielk1977} {1 {bad option "bogus": must be authorizer, backup, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, copy, enable_load_extension, errorcode, eval, exists, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, profile, progress, rekey, restore, rollback_hook, status, timeout, total_changes, trace, transaction, unlock_notify, update_hook, or version}} 39191fadcfSdanielk1977do_test tcl-1.2.1 { 40191fadcfSdanielk1977 set v [catch {db cache bogus} msg] 41191fadcfSdanielk1977 lappend v $msg 42191fadcfSdanielk1977} {1 {bad option "bogus": must be flush or size}} 43191fadcfSdanielk1977do_test tcl-1.2.2 { 44191fadcfSdanielk1977 set v [catch {db cache} msg] 45191fadcfSdanielk1977 lappend v $msg 46191fadcfSdanielk1977} {1 {wrong # args: should be "db cache option ?arg?"}} 47960e8c63Sdrhdo_test tcl-1.3 { 48960e8c63Sdrh execsql {CREATE TABLE t1(a int, b int)} 49960e8c63Sdrh execsql {INSERT INTO t1 VALUES(10,20)} 50960e8c63Sdrh set v [catch { 51960e8c63Sdrh db eval {SELECT * FROM t1} data { 52960e8c63Sdrh error "The error message" 53960e8c63Sdrh } 54960e8c63Sdrh } msg] 55960e8c63Sdrh lappend v $msg 56960e8c63Sdrh} {1 {The error message}} 57960e8c63Sdrhdo_test tcl-1.4 { 58960e8c63Sdrh set v [catch { 59960e8c63Sdrh db eval {SELECT * FROM t2} data { 60960e8c63Sdrh error "The error message" 61960e8c63Sdrh } 62960e8c63Sdrh } msg] 63960e8c63Sdrh lappend v $msg 64960e8c63Sdrh} {1 {no such table: t2}} 65960e8c63Sdrhdo_test tcl-1.5 { 66960e8c63Sdrh set v [catch { 67960e8c63Sdrh db eval {SELECT * FROM t1} data { 68960e8c63Sdrh break 69960e8c63Sdrh } 70960e8c63Sdrh } msg] 71960e8c63Sdrh lappend v $msg 72960e8c63Sdrh} {0 {}} 73d65e530bSdrhcatch {expr x*} msg 74960e8c63Sdrhdo_test tcl-1.6 { 75960e8c63Sdrh set v [catch { 76960e8c63Sdrh db eval {SELECT * FROM t1} data { 77960e8c63Sdrh expr x* 78960e8c63Sdrh } 79960e8c63Sdrh } msg] 80960e8c63Sdrh lappend v $msg 81d65e530bSdrh} [list 1 $msg] 820f14e2ebSdrhdo_test tcl-1.7 { 830f14e2ebSdrh set v [catch {db} msg] 840f14e2ebSdrh lappend v $msg 850f14e2ebSdrh} {1 {wrong # args: should be "db SUBCOMMAND ..."}} 861211de37Sdrhif {[catch {db auth {}}]==0} { 870f14e2ebSdrh do_test tcl-1.8 { 880f14e2ebSdrh set v [catch {db authorizer 1 2 3} msg] 890f14e2ebSdrh lappend v $msg 900f14e2ebSdrh } {1 {wrong # args: should be "db authorizer ?CALLBACK?"}} 911211de37Sdrh} 920f14e2ebSdrhdo_test tcl-1.9 { 930f14e2ebSdrh set v [catch {db busy 1 2 3} msg] 940f14e2ebSdrh lappend v $msg 950f14e2ebSdrh} {1 {wrong # args: should be "db busy CALLBACK"}} 960f14e2ebSdrhdo_test tcl-1.10 { 970f14e2ebSdrh set v [catch {db progress 1} msg] 980f14e2ebSdrh lappend v $msg 990f14e2ebSdrh} {1 {wrong # args: should be "db progress N CALLBACK"}} 1000f14e2ebSdrhdo_test tcl-1.11 { 1010f14e2ebSdrh set v [catch {db changes xyz} msg] 1020f14e2ebSdrh lappend v $msg 1030f14e2ebSdrh} {1 {wrong # args: should be "db changes "}} 1040f14e2ebSdrhdo_test tcl-1.12 { 1050f14e2ebSdrh set v [catch {db commit_hook a b c} msg] 1060f14e2ebSdrh lappend v $msg 1070f14e2ebSdrh} {1 {wrong # args: should be "db commit_hook ?CALLBACK?"}} 108ccae6026Sdrhifcapable {complete} { 1090f14e2ebSdrh do_test tcl-1.13 { 1100f14e2ebSdrh set v [catch {db complete} msg] 1110f14e2ebSdrh lappend v $msg 1120f14e2ebSdrh } {1 {wrong # args: should be "db complete SQL"}} 113ccae6026Sdrh} 1140f14e2ebSdrhdo_test tcl-1.14 { 1150f14e2ebSdrh set v [catch {db eval} msg] 1160f14e2ebSdrh lappend v $msg 117895d7472Sdrh} {1 {wrong # args: should be "db eval SQL ?ARRAY-NAME? ?SCRIPT?"}} 1180f14e2ebSdrhdo_test tcl-1.15 { 1190f14e2ebSdrh set v [catch {db function} msg] 1200f14e2ebSdrh lappend v $msg 121e3602be8Sdrh} {1 {wrong # args: should be "db function NAME [-argcount N] SCRIPT"}} 1227ddad969Sdanielk1977do_test tcl-1.16 { 1230f14e2ebSdrh set v [catch {db last_insert_rowid xyz} msg] 1240f14e2ebSdrh lappend v $msg 1250f14e2ebSdrh} {1 {wrong # args: should be "db last_insert_rowid "}} 1267ddad969Sdanielk1977do_test tcl-1.17 { 1270f14e2ebSdrh set v [catch {db rekey} msg] 1280f14e2ebSdrh lappend v $msg 1290f14e2ebSdrh} {1 {wrong # args: should be "db rekey KEY"}} 1307ddad969Sdanielk1977do_test tcl-1.18 { 1310f14e2ebSdrh set v [catch {db timeout} msg] 1320f14e2ebSdrh lappend v $msg 1330f14e2ebSdrh} {1 {wrong # args: should be "db timeout MILLISECONDS"}} 1347ddad969Sdanielk1977do_test tcl-1.19 { 1350f14e2ebSdrh set v [catch {db collate} msg] 1360f14e2ebSdrh lappend v $msg 1370f14e2ebSdrh} {1 {wrong # args: should be "db collate NAME SCRIPT"}} 1387ddad969Sdanielk1977do_test tcl-1.20 { 1390f14e2ebSdrh set v [catch {db collation_needed} msg] 1400f14e2ebSdrh lappend v $msg 1410f14e2ebSdrh} {1 {wrong # args: should be "db collation_needed SCRIPT"}} 1427ddad969Sdanielk1977do_test tcl-1.21 { 1430f14e2ebSdrh set v [catch {db total_changes xyz} msg] 1440f14e2ebSdrh lappend v $msg 1450f14e2ebSdrh} {1 {wrong # args: should be "db total_changes "}} 1461067fe11Stpoindexdo_test tcl-1.20 { 1471067fe11Stpoindex set v [catch {db copy} msg] 1481067fe11Stpoindex lappend v $msg 1491067fe11Stpoindex} {1 {wrong # args: should be "db copy CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?"}} 15095c8a54cSdanielk1977do_test tcl-1.21 { 15195c8a54cSdanielk1977 set v [catch {sqlite3 db2 test.db -vfs nosuchvfs} msg] 15295c8a54cSdanielk1977 lappend v $msg 15395c8a54cSdanielk1977} {1 {no such vfs: nosuchvfs}} 154960e8c63Sdrh 155c275b4eaSdrhcatch {unset ::result} 1566d4abfbeSdrhdo_test tcl-2.1 { 1576d4abfbeSdrh execsql "CREATE TABLE t\u0123x(a int, b\u1235 float)" 15827188fb5Sdanielk1977} {} 15927188fb5Sdanielk1977ifcapable schema_pragmas { 16027188fb5Sdanielk1977 do_test tcl-2.2 { 1616d4abfbeSdrh execsql "PRAGMA table_info(t\u0123x)" 1629f6696acSdrh } "0 a int 0 {} 0 1 b\u1235 float 0 {} 0" 16327188fb5Sdanielk1977} 16427188fb5Sdanielk1977do_test tcl-2.3 { 1656d4abfbeSdrh execsql "INSERT INTO t\u0123x VALUES(1,2.3)" 1666d4abfbeSdrh db eval "SELECT * FROM t\u0123x" result break 1676d4abfbeSdrh set result(*) 1686d4abfbeSdrh} "a b\u1235" 1696d4abfbeSdrh 1706d4abfbeSdrh 1715d9d7576Sdrh# Test the onecolumn method 1725d9d7576Sdrh# 1735d9d7576Sdrhdo_test tcl-3.1 { 1745d9d7576Sdrh execsql { 1755d9d7576Sdrh INSERT INTO t1 SELECT a*2, b*2 FROM t1; 1765d9d7576Sdrh INSERT INTO t1 SELECT a*2+1, b*2+1 FROM t1; 1775d9d7576Sdrh INSERT INTO t1 SELECT a*2+3, b*2+3 FROM t1; 1785d9d7576Sdrh } 17922fbcb8dSdrh set rc [catch {db onecolumn {SELECT * FROM t1 ORDER BY a}} msg] 18022fbcb8dSdrh lappend rc $msg 18122fbcb8dSdrh} {0 10} 1825d9d7576Sdrhdo_test tcl-3.2 { 1835d9d7576Sdrh db onecolumn {SELECT * FROM t1 WHERE a<0} 1845d9d7576Sdrh} {} 1855d9d7576Sdrhdo_test tcl-3.3 { 1865d9d7576Sdrh set rc [catch {db onecolumn} errmsg] 1875d9d7576Sdrh lappend rc $errmsg 1885d9d7576Sdrh} {1 {wrong # args: should be "db onecolumn SQL"}} 1890f14e2ebSdrhdo_test tcl-3.4 { 1900f14e2ebSdrh set rc [catch {db onecolumn {SELECT bogus}} errmsg] 1910f14e2ebSdrh lappend rc $errmsg 1920f14e2ebSdrh} {1 {no such column: bogus}} 1936bf89570Sdrhifcapable {tclvar} { 1941807ce37Sdrh do_test tcl-3.5 { 1951807ce37Sdrh set b 50 1961807ce37Sdrh set rc [catch {db one {SELECT * FROM t1 WHERE b>$b}} msg] 1971807ce37Sdrh lappend rc $msg 1981807ce37Sdrh } {0 41} 1991807ce37Sdrh do_test tcl-3.6 { 2001807ce37Sdrh set b 500 2011807ce37Sdrh set rc [catch {db one {SELECT * FROM t1 WHERE b>$b}} msg] 2021807ce37Sdrh lappend rc $msg 2031807ce37Sdrh } {0 {}} 2041807ce37Sdrh do_test tcl-3.7 { 2051807ce37Sdrh set b 500 2061807ce37Sdrh set rc [catch {db one { 2071807ce37Sdrh INSERT INTO t1 VALUES(99,510); 2081807ce37Sdrh SELECT * FROM t1 WHERE b>$b 2091807ce37Sdrh }} msg] 2101807ce37Sdrh lappend rc $msg 2111807ce37Sdrh } {0 99} 2126bf89570Sdrh} 2136bf89570Sdrhifcapable {!tclvar} { 2146bf89570Sdrh execsql {INSERT INTO t1 VALUES(99,510)} 2156bf89570Sdrh} 2165d9d7576Sdrh 2170f14e2ebSdrh# Turn the busy handler on and off 2180f14e2ebSdrh# 2190f14e2ebSdrhdo_test tcl-4.1 { 2200f14e2ebSdrh proc busy_callback {cnt} { 2210f14e2ebSdrh break 2220f14e2ebSdrh } 2230f14e2ebSdrh db busy busy_callback 2240f14e2ebSdrh db busy 2250f14e2ebSdrh} {busy_callback} 2260f14e2ebSdrhdo_test tcl-4.2 { 2270f14e2ebSdrh db busy {} 2280f14e2ebSdrh db busy 2290f14e2ebSdrh} {} 2306d4abfbeSdrh 2316bf89570Sdrhifcapable {tclvar} { 23292febd92Sdrh # Parsing of TCL variable names within SQL into bound parameters. 23392febd92Sdrh # 23492febd92Sdrh do_test tcl-5.1 { 23592febd92Sdrh execsql {CREATE TABLE t3(a,b,c)} 23692febd92Sdrh catch {unset x} 2377a1d17f1Sdanielk1977 set x(1) A 2387a1d17f1Sdanielk1977 set x(2) B 23992febd92Sdrh execsql { 24092febd92Sdrh INSERT INTO t3 VALUES($::x(1),$::x(2),$::x(3)); 24192febd92Sdrh SELECT * FROM t3 24292febd92Sdrh } 2437a1d17f1Sdanielk1977 } {A B {}} 24492febd92Sdrh do_test tcl-5.2 { 24592febd92Sdrh execsql { 24692febd92Sdrh SELECT typeof(a), typeof(b), typeof(c) FROM t3 24792febd92Sdrh } 24892febd92Sdrh } {text text null} 24992febd92Sdrh do_test tcl-5.3 { 25092febd92Sdrh catch {unset x} 25192febd92Sdrh set x [binary format h12 686900686f00] 25292febd92Sdrh execsql { 25392febd92Sdrh UPDATE t3 SET a=$::x; 25492febd92Sdrh } 25592febd92Sdrh db eval { 25692febd92Sdrh SELECT a FROM t3 25792febd92Sdrh } break 25892febd92Sdrh binary scan $a h12 adata 25992febd92Sdrh set adata 26092febd92Sdrh } {686900686f00} 26192febd92Sdrh do_test tcl-5.4 { 26292febd92Sdrh execsql { 26392febd92Sdrh SELECT typeof(a), typeof(b), typeof(c) FROM t3 26492febd92Sdrh } 26592febd92Sdrh } {blob text null} 2666bf89570Sdrh} 26792febd92Sdrh 268fd241b0eSdrh# Operation of "break" and "continue" within row scripts 269fd241b0eSdrh# 270fd241b0eSdrhdo_test tcl-6.1 { 271fd241b0eSdrh db eval {SELECT * FROM t1} { 272fd241b0eSdrh break 273fd241b0eSdrh } 274fd241b0eSdrh lappend a $b 275fd241b0eSdrh} {10 20} 276fd241b0eSdrhdo_test tcl-6.2 { 277fd241b0eSdrh set cnt 0 278fd241b0eSdrh db eval {SELECT * FROM t1} { 279fd241b0eSdrh if {$a>40} continue 280fd241b0eSdrh incr cnt 281fd241b0eSdrh } 282fd241b0eSdrh set cnt 283fd241b0eSdrh} {4} 284fd241b0eSdrhdo_test tcl-6.3 { 285fd241b0eSdrh set cnt 0 286fd241b0eSdrh db eval {SELECT * FROM t1} { 287fd241b0eSdrh if {$a<40} continue 288fd241b0eSdrh incr cnt 289fd241b0eSdrh } 290fd241b0eSdrh set cnt 291fd241b0eSdrh} {5} 292fd241b0eSdrhdo_test tcl-6.4 { 293fd241b0eSdrh proc return_test {x} { 294fd241b0eSdrh db eval {SELECT * FROM t1} { 295fd241b0eSdrh if {$a==$x} {return $b} 296fd241b0eSdrh } 297fd241b0eSdrh } 298fd241b0eSdrh return_test 10 299fd241b0eSdrh} 20 300fd241b0eSdrhdo_test tcl-6.5 { 301fd241b0eSdrh return_test 20 302fd241b0eSdrh} 40 303fd241b0eSdrhdo_test tcl-6.6 { 304fd241b0eSdrh return_test 99 305fd241b0eSdrh} 510 306fd241b0eSdrhdo_test tcl-6.7 { 307fd241b0eSdrh return_test 0 308fd241b0eSdrh} {} 309fd241b0eSdrh 3104397de57Sdanielk1977do_test tcl-7.1 { 3114397de57Sdanielk1977 db version 3124397de57Sdanielk1977 expr 0 3134397de57Sdanielk1977} {0} 3144397de57Sdanielk1977 31555c45f2eSdanielk1977# modify and reset the NULL representation 31655c45f2eSdanielk1977# 31755c45f2eSdanielk1977do_test tcl-8.1 { 31855c45f2eSdanielk1977 db nullvalue NaN 31955c45f2eSdanielk1977 execsql {INSERT INTO t1 VALUES(30,NULL)} 32055c45f2eSdanielk1977 db eval {SELECT * FROM t1 WHERE b IS NULL} 32155c45f2eSdanielk1977} {30 NaN} 32255c45f2eSdanielk1977do_test tcl-8.2 { 32355c45f2eSdanielk1977 db nullvalue NULL 32455c45f2eSdanielk1977 db nullvalue 32555c45f2eSdanielk1977} {NULL} 32655c45f2eSdanielk1977do_test tcl-8.3 { 32755c45f2eSdanielk1977 db nullvalue {} 32855c45f2eSdanielk1977 db eval {SELECT * FROM t1 WHERE b IS NULL} 32955c45f2eSdanielk1977} {30 {}} 33055c45f2eSdanielk1977 331c7f269d5Sdrh# Test the return type of user-defined functions 332c7f269d5Sdrh# 333c7f269d5Sdrhdo_test tcl-9.1 { 334c7f269d5Sdrh db function ret_str {return "hi"} 335c7f269d5Sdrh execsql {SELECT typeof(ret_str())} 336c7f269d5Sdrh} {text} 337c7f269d5Sdrhdo_test tcl-9.2 { 3389645d8d4Sdrh db function ret_dbl {return [expr {rand()*0.5}]} 339c7f269d5Sdrh execsql {SELECT typeof(ret_dbl())} 340c7f269d5Sdrh} {real} 341c7f269d5Sdrhdo_test tcl-9.3 { 3429645d8d4Sdrh db function ret_int {return [expr {int(rand()*200)}]} 343c7f269d5Sdrh execsql {SELECT typeof(ret_int())} 344c7f269d5Sdrh} {integer} 345c7f269d5Sdrh 346d1e4733dSdrh# Recursive calls to the same user-defined function 347d1e4733dSdrh# 3483bdca9c9Sdanielk1977ifcapable tclvar { 349d1e4733dSdrh do_test tcl-9.10 { 350d1e4733dSdrh proc userfunc_r1 {n} { 351d1e4733dSdrh if {$n<=0} {return 0} 352d1e4733dSdrh set nm1 [expr {$n-1}] 353d1e4733dSdrh return [expr {[db eval {SELECT r1($nm1)}]+$n}] 354d1e4733dSdrh } 355d1e4733dSdrh db function r1 userfunc_r1 356d1e4733dSdrh execsql {SELECT r1(10)} 357d1e4733dSdrh } {55} 358d1e4733dSdrh do_test tcl-9.11 { 359d1e4733dSdrh execsql {SELECT r1(100)} 360d1e4733dSdrh } {5050} 3613bdca9c9Sdanielk1977} 362d1e4733dSdrh 363b5555e7eSdrh# Tests for the new transaction method 364b5555e7eSdrh# 365b5555e7eSdrhdo_test tcl-10.1 { 366b5555e7eSdrh db transaction {} 367b5555e7eSdrh} {} 368b5555e7eSdrhdo_test tcl-10.2 { 369b5555e7eSdrh db transaction deferred {} 370b5555e7eSdrh} {} 371b5555e7eSdrhdo_test tcl-10.3 { 372b5555e7eSdrh db transaction immediate {} 373b5555e7eSdrh} {} 374b5555e7eSdrhdo_test tcl-10.4 { 375b5555e7eSdrh db transaction exclusive {} 376b5555e7eSdrh} {} 377b5555e7eSdrhdo_test tcl-10.5 { 378b5555e7eSdrh set rc [catch {db transaction xyzzy {}} msg] 379b5555e7eSdrh lappend rc $msg 380b5555e7eSdrh} {1 {bad transaction type "xyzzy": must be deferred, exclusive, or immediate}} 381b5555e7eSdrhdo_test tcl-10.6 { 382b5555e7eSdrh set rc [catch {db transaction {error test-error}} msg] 383b5555e7eSdrh lappend rc $msg 384b5555e7eSdrh} {1 test-error} 385b5555e7eSdrhdo_test tcl-10.7 { 386b5555e7eSdrh db transaction { 387b5555e7eSdrh db eval {CREATE TABLE t4(x)} 388b5555e7eSdrh db transaction { 389b5555e7eSdrh db eval {INSERT INTO t4 VALUES(1)} 390b5555e7eSdrh } 391b5555e7eSdrh } 392b5555e7eSdrh db eval {SELECT * FROM t4} 393b5555e7eSdrh} 1 394b5555e7eSdrhdo_test tcl-10.8 { 395b5555e7eSdrh catch { 396b5555e7eSdrh db transaction { 397b5555e7eSdrh db eval {INSERT INTO t4 VALUES(2)} 398b5555e7eSdrh db eval {INSERT INTO t4 VALUES(3)} 399b5555e7eSdrh db eval {INSERT INTO t4 VALUES(4)} 400b5555e7eSdrh error test-error 401b5555e7eSdrh } 402b5555e7eSdrh } 403b5555e7eSdrh db eval {SELECT * FROM t4} 404b5555e7eSdrh} 1 405b5555e7eSdrhdo_test tcl-10.9 { 406b5555e7eSdrh db transaction { 407b5555e7eSdrh db eval {INSERT INTO t4 VALUES(2)} 408b5555e7eSdrh catch { 409b5555e7eSdrh db transaction { 410b5555e7eSdrh db eval {INSERT INTO t4 VALUES(3)} 411b5555e7eSdrh db eval {INSERT INTO t4 VALUES(4)} 412b5555e7eSdrh error test-error 413b5555e7eSdrh } 414b5555e7eSdrh } 415b5555e7eSdrh } 416b5555e7eSdrh db eval {SELECT * FROM t4} 417cd38d520Sdanielk1977} {1 2} 418b5555e7eSdrhdo_test tcl-10.10 { 419b5555e7eSdrh for {set i 0} {$i<1} {incr i} { 420b5555e7eSdrh db transaction { 421b5555e7eSdrh db eval {INSERT INTO t4 VALUES(5)} 422b5555e7eSdrh continue 423b5555e7eSdrh } 424cd38d520Sdanielk1977 error "This line should not be run" 425b5555e7eSdrh } 426b5555e7eSdrh db eval {SELECT * FROM t4} 427cd38d520Sdanielk1977} {1 2 5} 428b5555e7eSdrhdo_test tcl-10.11 { 429b5555e7eSdrh for {set i 0} {$i<10} {incr i} { 430b5555e7eSdrh db transaction { 431b5555e7eSdrh db eval {INSERT INTO t4 VALUES(6)} 432b5555e7eSdrh break 433b5555e7eSdrh } 434b5555e7eSdrh } 435b5555e7eSdrh db eval {SELECT * FROM t4} 436cd38d520Sdanielk1977} {1 2 5 6} 437b5555e7eSdrhdo_test tcl-10.12 { 438b5555e7eSdrh set rc [catch { 439b5555e7eSdrh for {set i 0} {$i<10} {incr i} { 440b5555e7eSdrh db transaction { 441b5555e7eSdrh db eval {INSERT INTO t4 VALUES(7)} 442b5555e7eSdrh return 443b5555e7eSdrh } 444b5555e7eSdrh } 445b5555e7eSdrh }] 446b5555e7eSdrh} {2} 447b5555e7eSdrhdo_test tcl-10.13 { 448b5555e7eSdrh db eval {SELECT * FROM t4} 449cd38d520Sdanielk1977} {1 2 5 6 7} 450cd38d520Sdanielk1977 451cd38d520Sdanielk1977# Now test that [db transaction] commands may be nested with 452cd38d520Sdanielk1977# the expected results. 453cd38d520Sdanielk1977# 454cd38d520Sdanielk1977do_test tcl-10.14 { 455cd38d520Sdanielk1977 db transaction { 456cd38d520Sdanielk1977 db eval { 457cd38d520Sdanielk1977 DELETE FROM t4; 458cd38d520Sdanielk1977 INSERT INTO t4 VALUES('one'); 459cd38d520Sdanielk1977 } 460cd38d520Sdanielk1977 461cd38d520Sdanielk1977 catch { 462cd38d520Sdanielk1977 db transaction { 463cd38d520Sdanielk1977 db eval { INSERT INTO t4 VALUES('two') } 464cd38d520Sdanielk1977 db transaction { 465cd38d520Sdanielk1977 db eval { INSERT INTO t4 VALUES('three') } 466cd38d520Sdanielk1977 error "throw an error!" 467cd38d520Sdanielk1977 } 468cd38d520Sdanielk1977 } 469cd38d520Sdanielk1977 } 470cd38d520Sdanielk1977 } 471cd38d520Sdanielk1977 472cd38d520Sdanielk1977 db eval {SELECT * FROM t4} 473cd38d520Sdanielk1977} {one} 474cd38d520Sdanielk1977do_test tcl-10.15 { 475cd38d520Sdanielk1977 # Make sure a transaction has not been left open. 476cd38d520Sdanielk1977 db eval {BEGIN ; COMMIT} 477cd38d520Sdanielk1977} {} 478cd38d520Sdanielk1977do_test tcl-10.16 { 479cd38d520Sdanielk1977 db transaction { 480cd38d520Sdanielk1977 db eval { INSERT INTO t4 VALUES('two'); } 481cd38d520Sdanielk1977 db transaction { 482cd38d520Sdanielk1977 db eval { INSERT INTO t4 VALUES('three') } 483cd38d520Sdanielk1977 db transaction { 484cd38d520Sdanielk1977 db eval { INSERT INTO t4 VALUES('four') } 485cd38d520Sdanielk1977 } 486cd38d520Sdanielk1977 } 487cd38d520Sdanielk1977 } 488cd38d520Sdanielk1977 db eval {SELECT * FROM t4} 489cd38d520Sdanielk1977} {one two three four} 490cd38d520Sdanielk1977do_test tcl-10.17 { 491cd38d520Sdanielk1977 catch { 492cd38d520Sdanielk1977 db transaction { 493cd38d520Sdanielk1977 db eval { INSERT INTO t4 VALUES('A'); } 494cd38d520Sdanielk1977 db transaction { 495cd38d520Sdanielk1977 db eval { INSERT INTO t4 VALUES('B') } 496cd38d520Sdanielk1977 db transaction { 497cd38d520Sdanielk1977 db eval { INSERT INTO t4 VALUES('C') } 498cd38d520Sdanielk1977 error "throw an error!" 499cd38d520Sdanielk1977 } 500cd38d520Sdanielk1977 } 501cd38d520Sdanielk1977 } 502cd38d520Sdanielk1977 } 503cd38d520Sdanielk1977 db eval {SELECT * FROM t4} 504cd38d520Sdanielk1977} {one two three four} 505cd38d520Sdanielk1977do_test tcl-10.18 { 506cd38d520Sdanielk1977 # Make sure a transaction has not been left open. 507cd38d520Sdanielk1977 db eval {BEGIN ; COMMIT} 508cd38d520Sdanielk1977} {} 509cd38d520Sdanielk1977 510cd38d520Sdanielk1977# Mess up a [db transaction] command by locking the database using a 511cd38d520Sdanielk1977# second connection when it tries to commit. Make sure the transaction 512cd38d520Sdanielk1977# is not still open after the "database is locked" exception is thrown. 513cd38d520Sdanielk1977# 514cd38d520Sdanielk1977do_test tcl-10.18 { 515cd38d520Sdanielk1977 sqlite3 db2 test.db 516cd38d520Sdanielk1977 db2 eval { 517cd38d520Sdanielk1977 BEGIN; 518cd38d520Sdanielk1977 SELECT * FROM sqlite_master; 519cd38d520Sdanielk1977 } 520cd38d520Sdanielk1977 521cd38d520Sdanielk1977 set rc [catch { 522cd38d520Sdanielk1977 db transaction { 523cd38d520Sdanielk1977 db eval {INSERT INTO t4 VALUES('five')} 524cd38d520Sdanielk1977 } 525cd38d520Sdanielk1977 } msg] 526cd38d520Sdanielk1977 list $rc $msg 527cd38d520Sdanielk1977} {1 {database is locked}} 528cd38d520Sdanielk1977do_test tcl-10.19 { 529cd38d520Sdanielk1977 db eval {BEGIN ; COMMIT} 530cd38d520Sdanielk1977} {} 531cd38d520Sdanielk1977 532cd38d520Sdanielk1977# Thwart a [db transaction] command by locking the database using a 533cd38d520Sdanielk1977# second connection with "BEGIN EXCLUSIVE". Make sure no transaction is 534cd38d520Sdanielk1977# open after the "database is locked" exception is thrown. 535cd38d520Sdanielk1977# 536cd38d520Sdanielk1977do_test tcl-10.20 { 537cd38d520Sdanielk1977 db2 eval { 538cd38d520Sdanielk1977 COMMIT; 539cd38d520Sdanielk1977 BEGIN EXCLUSIVE; 540cd38d520Sdanielk1977 } 541cd38d520Sdanielk1977 set rc [catch { 542cd38d520Sdanielk1977 db transaction { 543cd38d520Sdanielk1977 db eval {INSERT INTO t4 VALUES('five')} 544cd38d520Sdanielk1977 } 545cd38d520Sdanielk1977 } msg] 546cd38d520Sdanielk1977 list $rc $msg 547cd38d520Sdanielk1977} {1 {database is locked}} 548cd38d520Sdanielk1977do_test tcl-10.21 { 549cd38d520Sdanielk1977 db2 close 550cd38d520Sdanielk1977 db eval {BEGIN ; COMMIT} 551cd38d520Sdanielk1977} {} 552cd38d520Sdanielk1977do_test tcl-10.22 { 553cd38d520Sdanielk1977 sqlite3 db2 test.db 554cd38d520Sdanielk1977 db transaction exclusive { 555cd38d520Sdanielk1977 catch { db2 eval {SELECT * FROM sqlite_master} } msg 556cd38d520Sdanielk1977 set msg "db2: $msg" 557cd38d520Sdanielk1977 } 558cd38d520Sdanielk1977 set msg 559cd38d520Sdanielk1977} {db2: database is locked} 560cd38d520Sdanielk1977db2 close 561c7f269d5Sdrh 56297f2ebc1Sdrhdo_test tcl-11.1 { 563cd38d520Sdanielk1977 db eval {INSERT INTO t4 VALUES(6)} 564cd38d520Sdanielk1977 db exists {SELECT x,x*2,x+x FROM t4 WHERE x==6} 56597f2ebc1Sdrh} {1} 56697f2ebc1Sdrhdo_test tcl-11.2 { 567cd38d520Sdanielk1977 db exists {SELECT 0 FROM t4 WHERE x==6} 56897f2ebc1Sdrh} {1} 56997f2ebc1Sdrhdo_test tcl-11.3 { 57097f2ebc1Sdrh db exists {SELECT 1 FROM t4 WHERE x==8} 57197f2ebc1Sdrh} {0} 572*a2c8a95bSdrhdo_test tcl-11.3.1 { 573*a2c8a95bSdrh tcl_objproc db exists {SELECT 1 FROM t4 WHERE x==8} 574*a2c8a95bSdrh} {0} 57597f2ebc1Sdrh 576161fb796Sdanielk1977do_test tcl-12.1 { 577161fb796Sdanielk1977 unset -nocomplain a b c version 578161fb796Sdanielk1977 set version [db version] 579161fb796Sdanielk1977 scan $version "%d.%d.%d" a b c 580161fb796Sdanielk1977 expr $a*1000000 + $b*1000 + $c 581161fb796Sdanielk1977} [sqlite3_libversion_number] 582161fb796Sdanielk1977 5834f5e80f9Sdrh 5844f5e80f9Sdrh# Check to see that when bindings of the form @aaa are used instead 5851c747819Sdrh# of $aaa, that objects are treated as bytearray and are inserted 5861c747819Sdrh# as BLOBs. 5874f5e80f9Sdrh# 5884152e677Sdanielk1977ifcapable tclvar { 5894f5e80f9Sdrh do_test tcl-13.1 { 5904f5e80f9Sdrh db eval {CREATE TABLE t5(x BLOB)} 5914f5e80f9Sdrh set x abc123 5924f5e80f9Sdrh db eval {INSERT INTO t5 VALUES($x)} 5934f5e80f9Sdrh db eval {SELECT typeof(x) FROM t5} 5944f5e80f9Sdrh } {text} 5954f5e80f9Sdrh do_test tcl-13.2 { 5964f5e80f9Sdrh binary scan $x H notUsed 5974f5e80f9Sdrh db eval { 5984f5e80f9Sdrh DELETE FROM t5; 5994f5e80f9Sdrh INSERT INTO t5 VALUES($x); 6004f5e80f9Sdrh SELECT typeof(x) FROM t5; 6014f5e80f9Sdrh } 6024f5e80f9Sdrh } {text} 6034f5e80f9Sdrh do_test tcl-13.3 { 6044f5e80f9Sdrh db eval { 6054f5e80f9Sdrh DELETE FROM t5; 6064f5e80f9Sdrh INSERT INTO t5 VALUES(@x); 6074f5e80f9Sdrh SELECT typeof(x) FROM t5; 6084f5e80f9Sdrh } 6094f5e80f9Sdrh } {blob} 6101c747819Sdrh do_test tcl-13.4 { 6111c747819Sdrh set y 1234 6121c747819Sdrh db eval { 6131c747819Sdrh DELETE FROM t5; 6141c747819Sdrh INSERT INTO t5 VALUES(@y); 6151c747819Sdrh SELECT hex(x), typeof(x) FROM t5 6161c747819Sdrh } 6171c747819Sdrh } {31323334 blob} 6184152e677Sdanielk1977} 6191c747819Sdrh 6204f5e80f9Sdrh 621960e8c63Sdrhfinish_test 622