18df9185cSdrh# 2009 Nov 11 28df9185cSdrh# 38df9185cSdrh# The author disclaims copyright to this source code. In place of 48df9185cSdrh# a legal notice, here is a blessing: 58df9185cSdrh# 68df9185cSdrh# May you do good and not evil. 78df9185cSdrh# May you find forgiveness for yourself and forgive others. 88df9185cSdrh# May you share freely, never taking more than you give. 98df9185cSdrh# 108df9185cSdrh#*********************************************************************** 118df9185cSdrh# 128df9185cSdrh# The focus of this file is testing the CLI shell tool. 138df9185cSdrh# 148df9185cSdrh# 158df9185cSdrh 168df9185cSdrh# Test plan: 178df9185cSdrh# 188df9185cSdrh# shell1-1.*: Basic command line option handling. 198df9185cSdrh# shell1-2.*: Basic "dot" command token parsing. 208df9185cSdrh# shell1-3.*: Basic test that "dot" command can be called. 218df9185cSdrh# 228df9185cSdrhset testdir [file dirname $argv0] 238df9185cSdrhsource $testdir/tester.tcl 24089555c8Sdanset CLI [test_find_cli] 258df9185cSdrhdb close 268df9185cSdrhforcedelete test.db test.db-journal test.db-wal 278df9185cSdrhsqlite3 db test.db 288df9185cSdrh 298df9185cSdrh#---------------------------------------------------------------------------- 308df9185cSdrh# Test cases shell1-1.*: Basic command line option handling. 318df9185cSdrh# 328df9185cSdrh 338df9185cSdrh# invalid option 348df9185cSdrhdo_test shell1-1.1.1 { 358df9185cSdrh set res [catchcmd "-bad test.db" ""] 368df9185cSdrh set rc [lindex $res 0] 378df9185cSdrh list $rc \ 388df9185cSdrh [regexp {Error: unknown option: -bad} $res] 398df9185cSdrh} {1 1} 40ac5649a9Sdrhdo_test shell1-1.1.1b { 41ac5649a9Sdrh set res [catchcmd "test.db -bad" ""] 42ac5649a9Sdrh set rc [lindex $res 0] 43ac5649a9Sdrh list $rc \ 44ac5649a9Sdrh [regexp {Error: unknown option: -bad} $res] 45ac5649a9Sdrh} {1 1} 468df9185cSdrh# error on extra options 478df9185cSdrhdo_test shell1-1.1.2 { 4860c4249fSdrh catchcmd "test.db \"select+3\" \"select+4\"" "" 49ac5649a9Sdrh} {0 {3 50ac5649a9Sdrh4}} 518df9185cSdrh# error on extra options 528df9185cSdrhdo_test shell1-1.1.3 { 53ac5649a9Sdrh catchcmd "test.db FOO test.db BAD" ".quit" 54ac5649a9Sdrh} {1 {Error: near "FOO": syntax error}} 558df9185cSdrh 568df9185cSdrh# -help 578df9185cSdrhdo_test shell1-1.2.1 { 588df9185cSdrh set res [catchcmd "-help test.db" ""] 598df9185cSdrh set rc [lindex $res 0] 608df9185cSdrh list $rc \ 618df9185cSdrh [regexp {Usage} $res] \ 628df9185cSdrh [regexp {\-init} $res] \ 638df9185cSdrh [regexp {\-version} $res] 648df9185cSdrh} {1 1 1 1} 658df9185cSdrh 668df9185cSdrh# -init filename read/process named file 678df9185cSdrhdo_test shell1-1.3.1 { 688df9185cSdrh catchcmd "-init FOO test.db" "" 698df9185cSdrh} {0 {}} 708df9185cSdrhdo_test shell1-1.3.2 { 71ac5649a9Sdrh catchcmd "-init FOO test.db .quit BAD" "" 72ac5649a9Sdrh} {0 {}} 73ac5649a9Sdrhdo_test shell1-1.3.3 { 74ac5649a9Sdrh catchcmd "-init FOO test.db BAD .quit" "" 75ac5649a9Sdrh} {1 {Error: near "BAD": syntax error}} 768df9185cSdrh 778df9185cSdrh# -echo print commands before execution 788df9185cSdrhdo_test shell1-1.4.1 { 798df9185cSdrh catchcmd "-echo test.db" "" 808df9185cSdrh} {0 {}} 818df9185cSdrh 828df9185cSdrh# -[no]header turn headers on or off 838df9185cSdrhdo_test shell1-1.5.1 { 848df9185cSdrh catchcmd "-header test.db" "" 858df9185cSdrh} {0 {}} 868df9185cSdrhdo_test shell1-1.5.2 { 878df9185cSdrh catchcmd "-noheader test.db" "" 888df9185cSdrh} {0 {}} 898df9185cSdrh 908df9185cSdrh# -bail stop after hitting an error 918df9185cSdrhdo_test shell1-1.6.1 { 928df9185cSdrh catchcmd "-bail test.db" "" 938df9185cSdrh} {0 {}} 948df9185cSdrh 958df9185cSdrh# -interactive force interactive I/O 968df9185cSdrhdo_test shell1-1.7.1 { 978df9185cSdrh set res [catchcmd "-interactive test.db" ".quit"] 988df9185cSdrh set rc [lindex $res 0] 998df9185cSdrh list $rc \ 1008df9185cSdrh [regexp {SQLite version} $res] \ 10139a3088dSdrh [regexp {Enter ".help" for usage hints} $res] 1028df9185cSdrh} {0 1 1} 1038df9185cSdrh 1048df9185cSdrh# -batch force batch I/O 1058df9185cSdrhdo_test shell1-1.8.1 { 1068df9185cSdrh catchcmd "-batch test.db" "" 1078df9185cSdrh} {0 {}} 1088df9185cSdrh 1098df9185cSdrh# -column set output mode to 'column' 1108df9185cSdrhdo_test shell1-1.9.1 { 1118df9185cSdrh catchcmd "-column test.db" "" 1128df9185cSdrh} {0 {}} 1138df9185cSdrh 1148df9185cSdrh# -csv set output mode to 'csv' 1158df9185cSdrhdo_test shell1-1.10.1 { 1168df9185cSdrh catchcmd "-csv test.db" "" 1178df9185cSdrh} {0 {}} 1188df9185cSdrh 1198df9185cSdrh# -html set output mode to HTML 1208df9185cSdrhdo_test shell1-1.11.1 { 1218df9185cSdrh catchcmd "-html test.db" "" 1228df9185cSdrh} {0 {}} 1238df9185cSdrh 1248df9185cSdrh# -line set output mode to 'line' 1258df9185cSdrhdo_test shell1-1.12.1 { 1268df9185cSdrh catchcmd "-line test.db" "" 1278df9185cSdrh} {0 {}} 1288df9185cSdrh 1298df9185cSdrh# -list set output mode to 'list' 1308df9185cSdrhdo_test shell1-1.13.1 { 1318df9185cSdrh catchcmd "-list test.db" "" 1328df9185cSdrh} {0 {}} 1338df9185cSdrh 1348df9185cSdrh# -separator 'x' set output field separator (|) 1358df9185cSdrhdo_test shell1-1.14.1 { 1368df9185cSdrh catchcmd "-separator 'x' test.db" "" 1378df9185cSdrh} {0 {}} 1388df9185cSdrhdo_test shell1-1.14.2 { 1398df9185cSdrh catchcmd "-separator x test.db" "" 1408df9185cSdrh} {0 {}} 1418df9185cSdrhdo_test shell1-1.14.3 { 1428df9185cSdrh set res [catchcmd "-separator" ""] 1438df9185cSdrh set rc [lindex $res 0] 1448df9185cSdrh list $rc \ 14598d312fcSdrh [regexp {Error: missing argument to -separator} $res] 1468df9185cSdrh} {1 1} 1478df9185cSdrh 1488df9185cSdrh# -stats print memory stats before each finalize 1498df9185cSdrhdo_test shell1-1.14b.1 { 1508df9185cSdrh catchcmd "-stats test.db" "" 1518df9185cSdrh} {0 {}} 1528df9185cSdrh 1538df9185cSdrh# -nullvalue 'text' set text string for NULL values 1548df9185cSdrhdo_test shell1-1.15.1 { 1558df9185cSdrh catchcmd "-nullvalue 'x' test.db" "" 1568df9185cSdrh} {0 {}} 1578df9185cSdrhdo_test shell1-1.15.2 { 1588df9185cSdrh catchcmd "-nullvalue x test.db" "" 1598df9185cSdrh} {0 {}} 1608df9185cSdrhdo_test shell1-1.15.3 { 1618df9185cSdrh set res [catchcmd "-nullvalue" ""] 1628df9185cSdrh set rc [lindex $res 0] 1638df9185cSdrh list $rc \ 16498d312fcSdrh [regexp {Error: missing argument to -nullvalue} $res] 1658df9185cSdrh} {1 1} 1668df9185cSdrh 1678df9185cSdrh# -version show SQLite version 1688df9185cSdrhdo_test shell1-1.16.1 { 1698df9185cSdrh set x [catchcmd "-version test.db" ""] 170b24c61a2Sdrh} {/3.[0-9.]+ 20\d\d-[01]\d-\d\d \d\d:\d\d:\d\d [0-9a-f]+/} 1718df9185cSdrh 1728df9185cSdrh#---------------------------------------------------------------------------- 1738df9185cSdrh# Test cases shell1-2.*: Basic "dot" command token parsing. 1748df9185cSdrh# 1758df9185cSdrh 1768df9185cSdrh# check first token handling 1778df9185cSdrhdo_test shell1-2.1.1 { 1788df9185cSdrh catchcmd "test.db" ".foo" 1798df9185cSdrh} {1 {Error: unknown command or invalid arguments: "foo". Enter ".help" for help}} 1808df9185cSdrhdo_test shell1-2.1.2 { 1818df9185cSdrh catchcmd "test.db" ".\"foo OFF\"" 1828df9185cSdrh} {1 {Error: unknown command or invalid arguments: "foo OFF". Enter ".help" for help}} 1838df9185cSdrhdo_test shell1-2.1.3 { 1848df9185cSdrh catchcmd "test.db" ".\'foo OFF\'" 1858df9185cSdrh} {1 {Error: unknown command or invalid arguments: "foo OFF". Enter ".help" for help}} 1868df9185cSdrh 1878df9185cSdrh# unbalanced quotes 1888df9185cSdrhdo_test shell1-2.2.1 { 1898df9185cSdrh catchcmd "test.db" ".\"foo OFF" 1908df9185cSdrh} {1 {Error: unknown command or invalid arguments: "foo OFF". Enter ".help" for help}} 1918df9185cSdrhdo_test shell1-2.2.2 { 1928df9185cSdrh catchcmd "test.db" ".\'foo OFF" 1938df9185cSdrh} {1 {Error: unknown command or invalid arguments: "foo OFF". Enter ".help" for help}} 1948df9185cSdrhdo_test shell1-2.2.3 { 1958df9185cSdrh catchcmd "test.db" ".explain \"OFF" 1968df9185cSdrh} {0 {}} 1978df9185cSdrhdo_test shell1-2.2.4 { 1988df9185cSdrh catchcmd "test.db" ".explain \'OFF" 1998df9185cSdrh} {0 {}} 2008df9185cSdrhdo_test shell1-2.2.5 { 2018df9185cSdrh catchcmd "test.db" ".mode \"insert FOO" 202636bf9f7Smistachkin} {1 {Error: mode should be one of: ascii column csv html insert line list tabs tcl}} 2038df9185cSdrhdo_test shell1-2.2.6 { 2048df9185cSdrh catchcmd "test.db" ".mode \'insert FOO" 205636bf9f7Smistachkin} {1 {Error: mode should be one of: ascii column csv html insert line list tabs tcl}} 2068df9185cSdrh 2078df9185cSdrh# check multiple tokens, and quoted tokens 2088df9185cSdrhdo_test shell1-2.3.1 { 2098df9185cSdrh catchcmd "test.db" ".explain 1" 2108df9185cSdrh} {0 {}} 2118df9185cSdrhdo_test shell1-2.3.2 { 2128df9185cSdrh catchcmd "test.db" ".explain on" 2138df9185cSdrh} {0 {}} 2148df9185cSdrhdo_test shell1-2.3.3 { 2158df9185cSdrh catchcmd "test.db" ".explain \"1 2 3\"" 216173ba099Sdrh} {1 {ERROR: Not a boolean value: "1 2 3". Assuming "no".}} 2178df9185cSdrhdo_test shell1-2.3.4 { 2188df9185cSdrh catchcmd "test.db" ".explain \"OFF\"" 2198df9185cSdrh} {0 {}} 2208df9185cSdrhdo_test shell1-2.3.5 { 2218df9185cSdrh catchcmd "test.db" ".\'explain\' \'OFF\'" 2228df9185cSdrh} {0 {}} 2238df9185cSdrhdo_test shell1-2.3.6 { 2248df9185cSdrh catchcmd "test.db" ".explain \'OFF\'" 2258df9185cSdrh} {0 {}} 2268df9185cSdrhdo_test shell1-2.3.7 { 2278df9185cSdrh catchcmd "test.db" ".\'explain\' \'OFF\'" 2288df9185cSdrh} {0 {}} 2298df9185cSdrh 2308df9185cSdrh# check quoted args are unquoted 2318df9185cSdrhdo_test shell1-2.4.1 { 2328df9185cSdrh catchcmd "test.db" ".mode FOO" 233636bf9f7Smistachkin} {1 {Error: mode should be one of: ascii column csv html insert line list tabs tcl}} 2348df9185cSdrhdo_test shell1-2.4.2 { 2358df9185cSdrh catchcmd "test.db" ".mode csv" 2368df9185cSdrh} {0 {}} 2378df9185cSdrhdo_test shell1-2.4.2 { 2388df9185cSdrh catchcmd "test.db" ".mode \"csv\"" 2398df9185cSdrh} {0 {}} 2408df9185cSdrh 2418df9185cSdrh 2428df9185cSdrh#---------------------------------------------------------------------------- 2438df9185cSdrh# Test cases shell1-3.*: Basic test that "dot" command can be called. 2448df9185cSdrh# 2458df9185cSdrh 2468df9185cSdrh# .backup ?DB? FILE Backup DB (default "main") to FILE 2478df9185cSdrhdo_test shell1-3.1.1 { 2488df9185cSdrh catchcmd "test.db" ".backup" 249bc46f02cSdrh} {1 {missing FILENAME argument on .backup}} 2508df9185cSdrhdo_test shell1-3.1.2 { 2518df9185cSdrh catchcmd "test.db" ".backup FOO" 2528df9185cSdrh} {0 {}} 2538df9185cSdrhdo_test shell1-3.1.3 { 2548df9185cSdrh catchcmd "test.db" ".backup FOO BAR" 2558df9185cSdrh} {1 {Error: unknown database FOO}} 2568df9185cSdrhdo_test shell1-3.1.4 { 2578df9185cSdrh # too many arguments 2588df9185cSdrh catchcmd "test.db" ".backup FOO BAR BAD" 259bc46f02cSdrh} {1 {too many arguments to .backup}} 2608df9185cSdrh 2618df9185cSdrh# .bail ON|OFF Stop after hitting an error. Default OFF 2628df9185cSdrhdo_test shell1-3.2.1 { 2638df9185cSdrh catchcmd "test.db" ".bail" 264c2ce0beaSdrh} {1 {Usage: .bail on|off}} 2658df9185cSdrhdo_test shell1-3.2.2 { 2668df9185cSdrh catchcmd "test.db" ".bail ON" 2678df9185cSdrh} {0 {}} 2688df9185cSdrhdo_test shell1-3.2.3 { 2698df9185cSdrh catchcmd "test.db" ".bail OFF" 2708df9185cSdrh} {0 {}} 2718df9185cSdrhdo_test shell1-3.2.4 { 2728df9185cSdrh # too many arguments 2738df9185cSdrh catchcmd "test.db" ".bail OFF BAD" 274c2ce0beaSdrh} {1 {Usage: .bail on|off}} 2758df9185cSdrh 2768df9185cSdrh# .databases List names and files of attached databases 2778df9185cSdrhdo_test shell1-3.3.1 { 278eaa544d4Sdrh catchcmd "-csv test.db" ".databases" 27915707ac9Sdrh} "/0.+main.+[string map {/ ".{1,2}"} [string range [get_pwd] 0 10]].*/" 2808df9185cSdrhdo_test shell1-3.3.2 { 281c2ce0beaSdrh # extra arguments ignored 282eaa544d4Sdrh catchcmd "test.db" ".databases BAD" 28315707ac9Sdrh} "/0.+main.+[string map {/ ".{1,2}"} [string range [get_pwd] 0 10]].*/" 2848df9185cSdrh 2858df9185cSdrh# .dump ?TABLE? ... Dump the database in an SQL text format 2868df9185cSdrh# If TABLE specified, only dump tables matching 2878df9185cSdrh# LIKE pattern TABLE. 2888df9185cSdrhdo_test shell1-3.4.1 { 2898df9185cSdrh set res [catchcmd "test.db" ".dump"] 2908df9185cSdrh list [regexp {BEGIN TRANSACTION;} $res] \ 2918df9185cSdrh [regexp {COMMIT;} $res] 2928df9185cSdrh} {1 1} 2938df9185cSdrhdo_test shell1-3.4.2 { 2948df9185cSdrh set res [catchcmd "test.db" ".dump FOO"] 2958df9185cSdrh list [regexp {BEGIN TRANSACTION;} $res] \ 2968df9185cSdrh [regexp {COMMIT;} $res] 2978df9185cSdrh} {1 1} 2988df9185cSdrhdo_test shell1-3.4.3 { 2998df9185cSdrh # too many arguments 3008df9185cSdrh catchcmd "test.db" ".dump FOO BAD" 301c2ce0beaSdrh} {1 {Usage: .dump ?LIKE-PATTERN?}} 3028df9185cSdrh 3038df9185cSdrh# .echo ON|OFF Turn command echo on or off 3048df9185cSdrhdo_test shell1-3.5.1 { 3058df9185cSdrh catchcmd "test.db" ".echo" 306c2ce0beaSdrh} {1 {Usage: .echo on|off}} 3078df9185cSdrhdo_test shell1-3.5.2 { 3088df9185cSdrh catchcmd "test.db" ".echo ON" 3098df9185cSdrh} {0 {}} 3108df9185cSdrhdo_test shell1-3.5.3 { 3118df9185cSdrh catchcmd "test.db" ".echo OFF" 3128df9185cSdrh} {0 {}} 3138df9185cSdrhdo_test shell1-3.5.4 { 3148df9185cSdrh # too many arguments 3158df9185cSdrh catchcmd "test.db" ".echo OFF BAD" 316c2ce0beaSdrh} {1 {Usage: .echo on|off}} 3178df9185cSdrh 3188df9185cSdrh# .exit Exit this program 3198df9185cSdrhdo_test shell1-3.6.1 { 3208df9185cSdrh catchcmd "test.db" ".exit" 3218df9185cSdrh} {0 {}} 3228df9185cSdrh 3238df9185cSdrh# .explain ON|OFF Turn output mode suitable for EXPLAIN on or off. 3248df9185cSdrhdo_test shell1-3.7.1 { 3258df9185cSdrh catchcmd "test.db" ".explain" 3268df9185cSdrh # explain is the exception to the booleans. without an option, it turns it on. 3278df9185cSdrh} {0 {}} 3288df9185cSdrhdo_test shell1-3.7.2 { 3298df9185cSdrh catchcmd "test.db" ".explain ON" 3308df9185cSdrh} {0 {}} 3318df9185cSdrhdo_test shell1-3.7.3 { 3328df9185cSdrh catchcmd "test.db" ".explain OFF" 3338df9185cSdrh} {0 {}} 3348df9185cSdrhdo_test shell1-3.7.4 { 335c2ce0beaSdrh # extra arguments ignored 3368df9185cSdrh catchcmd "test.db" ".explain OFF BAD" 337c2ce0beaSdrh} {0 {}} 3388df9185cSdrh 3398df9185cSdrh 3408df9185cSdrh# .header(s) ON|OFF Turn display of headers on or off 3418df9185cSdrhdo_test shell1-3.9.1 { 3428df9185cSdrh catchcmd "test.db" ".header" 343c2ce0beaSdrh} {1 {Usage: .headers on|off}} 3448df9185cSdrhdo_test shell1-3.9.2 { 3458df9185cSdrh catchcmd "test.db" ".header ON" 3468df9185cSdrh} {0 {}} 3478df9185cSdrhdo_test shell1-3.9.3 { 3488df9185cSdrh catchcmd "test.db" ".header OFF" 3498df9185cSdrh} {0 {}} 3508df9185cSdrhdo_test shell1-3.9.4 { 3518df9185cSdrh # too many arguments 3528df9185cSdrh catchcmd "test.db" ".header OFF BAD" 353c2ce0beaSdrh} {1 {Usage: .headers on|off}} 3548df9185cSdrh 3558df9185cSdrhdo_test shell1-3.9.5 { 3568df9185cSdrh catchcmd "test.db" ".headers" 357c2ce0beaSdrh} {1 {Usage: .headers on|off}} 3588df9185cSdrhdo_test shell1-3.9.6 { 3598df9185cSdrh catchcmd "test.db" ".headers ON" 3608df9185cSdrh} {0 {}} 3618df9185cSdrhdo_test shell1-3.9.7 { 3628df9185cSdrh catchcmd "test.db" ".headers OFF" 3638df9185cSdrh} {0 {}} 3648df9185cSdrhdo_test shell1-3.9.8 { 3658df9185cSdrh # too many arguments 3668df9185cSdrh catchcmd "test.db" ".headers OFF BAD" 367c2ce0beaSdrh} {1 {Usage: .headers on|off}} 3688df9185cSdrh 3698df9185cSdrh# .help Show this message 3708df9185cSdrhdo_test shell1-3.10.1 { 3718df9185cSdrh set res [catchcmd "test.db" ".help"] 3728df9185cSdrh # look for a few of the possible help commands 3738df9185cSdrh list [regexp {.help} $res] \ 3748df9185cSdrh [regexp {.quit} $res] \ 3758df9185cSdrh [regexp {.show} $res] 3768df9185cSdrh} {1 1 1} 3778df9185cSdrhdo_test shell1-3.10.2 { 3788df9185cSdrh # we allow .help to take extra args (it is help after all) 3798df9185cSdrh set res [catchcmd "test.db" ".help BAD"] 3808df9185cSdrh # look for a few of the possible help commands 3818df9185cSdrh list [regexp {.help} $res] \ 3828df9185cSdrh [regexp {.quit} $res] \ 3838df9185cSdrh [regexp {.show} $res] 3848df9185cSdrh} {1 1 1} 3858df9185cSdrh 3868df9185cSdrh# .import FILE TABLE Import data from FILE into TABLE 3878df9185cSdrhdo_test shell1-3.11.1 { 3888df9185cSdrh catchcmd "test.db" ".import" 389c2ce0beaSdrh} {1 {Usage: .import FILE TABLE}} 3908df9185cSdrhdo_test shell1-3.11.2 { 3918df9185cSdrh catchcmd "test.db" ".import FOO" 392c2ce0beaSdrh} {1 {Usage: .import FILE TABLE}} 393db95f68bSdrh#do_test shell1-3.11.2 { 394db95f68bSdrh# catchcmd "test.db" ".import FOO BAR" 395db95f68bSdrh#} {1 {Error: no such table: BAR}} 3968df9185cSdrhdo_test shell1-3.11.3 { 3978df9185cSdrh # too many arguments 3988df9185cSdrh catchcmd "test.db" ".import FOO BAR BAD" 399c2ce0beaSdrh} {1 {Usage: .import FILE TABLE}} 4008df9185cSdrh 4010e55db1cSdrh# .indexes ?TABLE? Show names of all indexes 4020e55db1cSdrh# If TABLE specified, only show indexes for tables 4038df9185cSdrh# matching LIKE pattern TABLE. 4048df9185cSdrhdo_test shell1-3.12.1 { 4050e55db1cSdrh catchcmd "test.db" ".indexes" 4068df9185cSdrh} {0 {}} 4078df9185cSdrhdo_test shell1-3.12.2 { 4080e55db1cSdrh catchcmd "test.db" ".indexes FOO" 4090e55db1cSdrh} {0 {}} 4100e55db1cSdrhdo_test shell1-3.12.2-legacy { 4118df9185cSdrh catchcmd "test.db" ".indices FOO" 4128df9185cSdrh} {0 {}} 4138df9185cSdrhdo_test shell1-3.12.3 { 4148df9185cSdrh # too many arguments 4150e55db1cSdrh catchcmd "test.db" ".indexes FOO BAD" 4160e55db1cSdrh} {1 {Usage: .indexes ?LIKE-PATTERN?}} 4178df9185cSdrh 4188df9185cSdrh# .mode MODE ?TABLE? Set output mode where MODE is one of: 419e0d6885fSmistachkin# ascii Columns/rows delimited by 0x1F and 0x1E 4208df9185cSdrh# csv Comma-separated values 4218df9185cSdrh# column Left-aligned columns. (See .width) 4228df9185cSdrh# html HTML <table> code 4238df9185cSdrh# insert SQL insert statements for TABLE 4248df9185cSdrh# line One value per line 425e0d6885fSmistachkin# list Values delimited by .separator strings 4268df9185cSdrh# tabs Tab-separated values 4278df9185cSdrh# tcl TCL list elements 4288df9185cSdrhdo_test shell1-3.13.1 { 4298df9185cSdrh catchcmd "test.db" ".mode" 430636bf9f7Smistachkin} {1 {Error: mode should be one of: ascii column csv html insert line list tabs tcl}} 4318df9185cSdrhdo_test shell1-3.13.2 { 4328df9185cSdrh catchcmd "test.db" ".mode FOO" 433636bf9f7Smistachkin} {1 {Error: mode should be one of: ascii column csv html insert line list tabs tcl}} 4348df9185cSdrhdo_test shell1-3.13.3 { 4358df9185cSdrh catchcmd "test.db" ".mode csv" 4368df9185cSdrh} {0 {}} 4378df9185cSdrhdo_test shell1-3.13.4 { 4388df9185cSdrh catchcmd "test.db" ".mode column" 4398df9185cSdrh} {0 {}} 4408df9185cSdrhdo_test shell1-3.13.5 { 4418df9185cSdrh catchcmd "test.db" ".mode html" 4428df9185cSdrh} {0 {}} 4438df9185cSdrhdo_test shell1-3.13.6 { 4448df9185cSdrh catchcmd "test.db" ".mode insert" 4458df9185cSdrh} {0 {}} 4468df9185cSdrhdo_test shell1-3.13.7 { 4478df9185cSdrh catchcmd "test.db" ".mode line" 4488df9185cSdrh} {0 {}} 4498df9185cSdrhdo_test shell1-3.13.8 { 4508df9185cSdrh catchcmd "test.db" ".mode list" 4518df9185cSdrh} {0 {}} 4528df9185cSdrhdo_test shell1-3.13.9 { 4538df9185cSdrh catchcmd "test.db" ".mode tabs" 4548df9185cSdrh} {0 {}} 4558df9185cSdrhdo_test shell1-3.13.10 { 4568df9185cSdrh catchcmd "test.db" ".mode tcl" 4578df9185cSdrh} {0 {}} 4588df9185cSdrhdo_test shell1-3.13.11 { 459c2ce0beaSdrh # extra arguments ignored 4608df9185cSdrh catchcmd "test.db" ".mode tcl BAD" 461c2ce0beaSdrh} {0 {}} 4628df9185cSdrh 4638df9185cSdrh# don't allow partial mode type matches 4648df9185cSdrhdo_test shell1-3.13.12 { 4658df9185cSdrh catchcmd "test.db" ".mode l" 466636bf9f7Smistachkin} {1 {Error: mode should be one of: ascii column csv html insert line list tabs tcl}} 4678df9185cSdrhdo_test shell1-3.13.13 { 4688df9185cSdrh catchcmd "test.db" ".mode li" 469636bf9f7Smistachkin} {1 {Error: mode should be one of: ascii column csv html insert line list tabs tcl}} 4708df9185cSdrhdo_test shell1-3.13.14 { 4718df9185cSdrh catchcmd "test.db" ".mode lin" 472c2ce0beaSdrh} {0 {}} 4738df9185cSdrh 4748df9185cSdrh# .nullvalue STRING Print STRING in place of NULL values 4758df9185cSdrhdo_test shell1-3.14.1 { 4768df9185cSdrh catchcmd "test.db" ".nullvalue" 477c2ce0beaSdrh} {1 {Usage: .nullvalue STRING}} 4788df9185cSdrhdo_test shell1-3.14.2 { 4798df9185cSdrh catchcmd "test.db" ".nullvalue FOO" 4808df9185cSdrh} {0 {}} 4818df9185cSdrhdo_test shell1-3.14.3 { 4828df9185cSdrh # too many arguments 4838df9185cSdrh catchcmd "test.db" ".nullvalue FOO BAD" 484c2ce0beaSdrh} {1 {Usage: .nullvalue STRING}} 4858df9185cSdrh 4868df9185cSdrh# .output FILENAME Send output to FILENAME 4878df9185cSdrhdo_test shell1-3.15.1 { 4888df9185cSdrh catchcmd "test.db" ".output" 489c2ce0beaSdrh} {0 {}} 4908df9185cSdrhdo_test shell1-3.15.2 { 4918df9185cSdrh catchcmd "test.db" ".output FOO" 4928df9185cSdrh} {0 {}} 4938df9185cSdrhdo_test shell1-3.15.3 { 4948df9185cSdrh # too many arguments 4958df9185cSdrh catchcmd "test.db" ".output FOO BAD" 496c2ce0beaSdrh} {1 {Usage: .output FILE}} 4978df9185cSdrh 4988df9185cSdrh# .output stdout Send output to the screen 4998df9185cSdrhdo_test shell1-3.16.1 { 5008df9185cSdrh catchcmd "test.db" ".output stdout" 5018df9185cSdrh} {0 {}} 5028df9185cSdrhdo_test shell1-3.16.2 { 5038df9185cSdrh # too many arguments 5048df9185cSdrh catchcmd "test.db" ".output stdout BAD" 505c2ce0beaSdrh} {1 {Usage: .output FILE}} 5068df9185cSdrh 5078df9185cSdrh# .prompt MAIN CONTINUE Replace the standard prompts 5088df9185cSdrhdo_test shell1-3.17.1 { 5098df9185cSdrh catchcmd "test.db" ".prompt" 510c2ce0beaSdrh} {0 {}} 5118df9185cSdrhdo_test shell1-3.17.2 { 5128df9185cSdrh catchcmd "test.db" ".prompt FOO" 5138df9185cSdrh} {0 {}} 5148df9185cSdrhdo_test shell1-3.17.3 { 5158df9185cSdrh catchcmd "test.db" ".prompt FOO BAR" 5168df9185cSdrh} {0 {}} 5178df9185cSdrhdo_test shell1-3.17.4 { 5188df9185cSdrh # too many arguments 5198df9185cSdrh catchcmd "test.db" ".prompt FOO BAR BAD" 520c2ce0beaSdrh} {0 {}} 5218df9185cSdrh 5228df9185cSdrh# .quit Exit this program 5238df9185cSdrhdo_test shell1-3.18.1 { 5248df9185cSdrh catchcmd "test.db" ".quit" 5258df9185cSdrh} {0 {}} 5268df9185cSdrhdo_test shell1-3.18.2 { 5278df9185cSdrh # too many arguments 5288df9185cSdrh catchcmd "test.db" ".quit BAD" 529c2ce0beaSdrh} {0 {}} 5308df9185cSdrh 5318df9185cSdrh# .read FILENAME Execute SQL in FILENAME 5328df9185cSdrhdo_test shell1-3.19.1 { 5338df9185cSdrh catchcmd "test.db" ".read" 534c2ce0beaSdrh} {1 {Usage: .read FILE}} 5358df9185cSdrhdo_test shell1-3.19.2 { 5369ac99313Smistachkin forcedelete FOO 5378df9185cSdrh catchcmd "test.db" ".read FOO" 5388df9185cSdrh} {1 {Error: cannot open "FOO"}} 5398df9185cSdrhdo_test shell1-3.19.3 { 5408df9185cSdrh # too many arguments 5418df9185cSdrh catchcmd "test.db" ".read FOO BAD" 542c2ce0beaSdrh} {1 {Usage: .read FILE}} 5438df9185cSdrh 5448df9185cSdrh# .restore ?DB? FILE Restore content of DB (default "main") from FILE 5458df9185cSdrhdo_test shell1-3.20.1 { 5468df9185cSdrh catchcmd "test.db" ".restore" 547c2ce0beaSdrh} {1 {Usage: .restore ?DB? FILE}} 5488df9185cSdrhdo_test shell1-3.20.2 { 5498df9185cSdrh catchcmd "test.db" ".restore FOO" 5508df9185cSdrh} {0 {}} 5518df9185cSdrhdo_test shell1-3.20.3 { 5528df9185cSdrh catchcmd "test.db" ".restore FOO BAR" 5538df9185cSdrh} {1 {Error: unknown database FOO}} 5548df9185cSdrhdo_test shell1-3.20.4 { 5558df9185cSdrh # too many arguments 5568df9185cSdrh catchcmd "test.db" ".restore FOO BAR BAD" 557c2ce0beaSdrh} {1 {Usage: .restore ?DB? FILE}} 5588df9185cSdrh 5598df9185cSdrh# .schema ?TABLE? Show the CREATE statements 5608df9185cSdrh# If TABLE specified, only show tables matching 5618df9185cSdrh# LIKE pattern TABLE. 5628df9185cSdrhdo_test shell1-3.21.1 { 5638df9185cSdrh catchcmd "test.db" ".schema" 5648df9185cSdrh} {0 {}} 5658df9185cSdrhdo_test shell1-3.21.2 { 5668df9185cSdrh catchcmd "test.db" ".schema FOO" 5678df9185cSdrh} {0 {}} 5688df9185cSdrhdo_test shell1-3.21.3 { 5698df9185cSdrh # too many arguments 5708df9185cSdrh catchcmd "test.db" ".schema FOO BAD" 5714926fec9Sdrh} {1 {Usage: .schema ?--indent? ?LIKE-PATTERN?}} 5728df9185cSdrh 573ac43e98dSdrhdo_test shell1-3.21.4 { 574ac43e98dSdrh catchcmd "test.db" { 575ac43e98dSdrh CREATE TABLE t1(x); 576ac43e98dSdrh CREATE VIEW v2 AS SELECT x+1 AS y FROM t1; 577ac43e98dSdrh CREATE VIEW v1 AS SELECT y+1 FROM v2; 578ac43e98dSdrh } 579ac43e98dSdrh catchcmd "test.db" ".schema" 580ac43e98dSdrh} {0 {CREATE TABLE t1(x); 581ac43e98dSdrhCREATE VIEW v2 AS SELECT x+1 AS y FROM t1; 582ac43e98dSdrhCREATE VIEW v1 AS SELECT y+1 FROM v2;}} 583ac43e98dSdrhdb eval {DROP VIEW v1; DROP VIEW v2; DROP TABLE t1;} 584ac43e98dSdrh 585636bf9f7Smistachkin# .separator STRING Change column separator used by output and .import 5868df9185cSdrhdo_test shell1-3.22.1 { 5878df9185cSdrh catchcmd "test.db" ".separator" 588e0d6885fSmistachkin} {1 {Usage: .separator COL ?ROW?}} 5898df9185cSdrhdo_test shell1-3.22.2 { 5908df9185cSdrh catchcmd "test.db" ".separator FOO" 5918df9185cSdrh} {0 {}} 5928df9185cSdrhdo_test shell1-3.22.3 { 5936976c212Sdrh catchcmd "test.db" ".separator ABC XYZ" 5946976c212Sdrh} {0 {}} 5956976c212Sdrhdo_test shell1-3.22.4 { 5968df9185cSdrh # too many arguments 5976976c212Sdrh catchcmd "test.db" ".separator FOO BAD BAD2" 598e0d6885fSmistachkin} {1 {Usage: .separator COL ?ROW?}} 5998df9185cSdrh 6008df9185cSdrh# .show Show the current values for various settings 6018df9185cSdrhdo_test shell1-3.23.1 { 6028df9185cSdrh set res [catchcmd "test.db" ".show"] 6038df9185cSdrh list [regexp {echo:} $res] \ 6048df9185cSdrh [regexp {explain:} $res] \ 6058df9185cSdrh [regexp {headers:} $res] \ 6068df9185cSdrh [regexp {mode:} $res] \ 6078df9185cSdrh [regexp {nullvalue:} $res] \ 6088df9185cSdrh [regexp {output:} $res] \ 609636bf9f7Smistachkin [regexp {colseparator:} $res] \ 610636bf9f7Smistachkin [regexp {rowseparator:} $res] \ 6118df9185cSdrh [regexp {stats:} $res] \ 6128df9185cSdrh [regexp {width:} $res] 613e0d6885fSmistachkin} {1 1 1 1 1 1 1 1 1 1} 6148df9185cSdrhdo_test shell1-3.23.2 { 6158df9185cSdrh # too many arguments 6168df9185cSdrh catchcmd "test.db" ".show BAD" 617c2ce0beaSdrh} {1 {Usage: .show}} 6188df9185cSdrh 6198df9185cSdrh# .stats ON|OFF Turn stats on or off 62034784903Sdrh#do_test shell1-3.23b.1 { 62134784903Sdrh# catchcmd "test.db" ".stats" 62234784903Sdrh#} {1 {Usage: .stats on|off}} 6238df9185cSdrhdo_test shell1-3.23b.2 { 6248df9185cSdrh catchcmd "test.db" ".stats ON" 6258df9185cSdrh} {0 {}} 6268df9185cSdrhdo_test shell1-3.23b.3 { 6278df9185cSdrh catchcmd "test.db" ".stats OFF" 6288df9185cSdrh} {0 {}} 6298df9185cSdrhdo_test shell1-3.23b.4 { 6308df9185cSdrh # too many arguments 6318df9185cSdrh catchcmd "test.db" ".stats OFF BAD" 63234784903Sdrh} {1 {Usage: .stats ?on|off?}} 6338df9185cSdrh 6348df9185cSdrh# .tables ?TABLE? List names of tables 6358df9185cSdrh# If TABLE specified, only list tables matching 6368df9185cSdrh# LIKE pattern TABLE. 6378df9185cSdrhdo_test shell1-3.24.1 { 6388df9185cSdrh catchcmd "test.db" ".tables" 6398df9185cSdrh} {0 {}} 6408df9185cSdrhdo_test shell1-3.24.2 { 6418df9185cSdrh catchcmd "test.db" ".tables FOO" 6428df9185cSdrh} {0 {}} 6438df9185cSdrhdo_test shell1-3.24.3 { 6448df9185cSdrh # too many arguments 6458df9185cSdrh catchcmd "test.db" ".tables FOO BAD" 646c2ce0beaSdrh} {0 {}} 6478df9185cSdrh 6488df9185cSdrh# .timeout MS Try opening locked tables for MS milliseconds 6498df9185cSdrhdo_test shell1-3.25.1 { 6508df9185cSdrh catchcmd "test.db" ".timeout" 651c2ce0beaSdrh} {0 {}} 6528df9185cSdrhdo_test shell1-3.25.2 { 6538df9185cSdrh catchcmd "test.db" ".timeout zzz" 6548df9185cSdrh # this should be treated the same as a '0' timeout 6558df9185cSdrh} {0 {}} 6568df9185cSdrhdo_test shell1-3.25.3 { 6578df9185cSdrh catchcmd "test.db" ".timeout 1" 6588df9185cSdrh} {0 {}} 6598df9185cSdrhdo_test shell1-3.25.4 { 6608df9185cSdrh # too many arguments 6618df9185cSdrh catchcmd "test.db" ".timeout 1 BAD" 662c2ce0beaSdrh} {0 {}} 6638df9185cSdrh 6648df9185cSdrh# .width NUM NUM ... Set column widths for "column" mode 6658df9185cSdrhdo_test shell1-3.26.1 { 6668df9185cSdrh catchcmd "test.db" ".width" 667c2ce0beaSdrh} {0 {}} 6688df9185cSdrhdo_test shell1-3.26.2 { 6698df9185cSdrh catchcmd "test.db" ".width xxx" 6708df9185cSdrh # this should be treated the same as a '0' width for col 1 6718df9185cSdrh} {0 {}} 6728df9185cSdrhdo_test shell1-3.26.3 { 6738df9185cSdrh catchcmd "test.db" ".width xxx yyy" 6748df9185cSdrh # this should be treated the same as a '0' width for col 1 and 2 6758df9185cSdrh} {0 {}} 6768df9185cSdrhdo_test shell1-3.26.4 { 6778df9185cSdrh catchcmd "test.db" ".width 1 1" 6788df9185cSdrh # this should be treated the same as a '1' width for col 1 and 2 6798df9185cSdrh} {0 {}} 680078b1fdaSdrhdo_test shell1-3.26.5 { 681078b1fdaSdrh catchcmd "test.db" ".mode column\n.width 10 -10\nSELECT 'abcdefg', 123456;" 682078b1fdaSdrh # this should be treated the same as a '1' width for col 1 and 2 683078b1fdaSdrh} {0 {abcdefg 123456}} 684078b1fdaSdrhdo_test shell1-3.26.6 { 685078b1fdaSdrh catchcmd "test.db" ".mode column\n.width -10 10\nSELECT 'abcdefg', 123456;" 686078b1fdaSdrh # this should be treated the same as a '1' width for col 1 and 2 687078b1fdaSdrh} {0 { abcdefg 123456 }} 688078b1fdaSdrh 6898df9185cSdrh 6908df9185cSdrh# .timer ON|OFF Turn the CPU timer measurement on or off 6918df9185cSdrhdo_test shell1-3.27.1 { 6928df9185cSdrh catchcmd "test.db" ".timer" 693c2ce0beaSdrh} {1 {Usage: .timer on|off}} 6948df9185cSdrhdo_test shell1-3.27.2 { 6958df9185cSdrh catchcmd "test.db" ".timer ON" 6968df9185cSdrh} {0 {}} 6978df9185cSdrhdo_test shell1-3.27.3 { 6988df9185cSdrh catchcmd "test.db" ".timer OFF" 6998df9185cSdrh} {0 {}} 7008df9185cSdrhdo_test shell1-3.27.4 { 7018df9185cSdrh # too many arguments 7028df9185cSdrh catchcmd "test.db" ".timer OFF BAD" 703c2ce0beaSdrh} {1 {Usage: .timer on|off}} 7048df9185cSdrh 7058df9185cSdrhdo_test shell1-3-28.1 { 7068df9185cSdrh catchcmd test.db \ 7078df9185cSdrh ".log stdout\nSELECT coalesce(sqlite_log(123,'hello'),'456');" 7088df9185cSdrh} "0 {(123) hello\n456}" 7098df9185cSdrh 710078b1fdaSdrhdo_test shell1-3-29.1 { 711078b1fdaSdrh catchcmd "test.db" ".print this is a test" 712078b1fdaSdrh} {0 {this is a test}} 713078b1fdaSdrh 7144c56b99fSdrh# dot-command argument quoting 7154c56b99fSdrhdo_test shell1-3-30.1 { 7164c56b99fSdrh catchcmd {test.db} {.print "this\"is'a\055test" 'this\"is\\a\055test'} 7174c56b99fSdrh} {0 {this"is'a-test this\"is\\a\055test}} 7184c56b99fSdrhdo_test shell1-3-31.1 { 7194c56b99fSdrh catchcmd {test.db} {.print "this\nis\ta\\test" 'this\nis\ta\\test'} 7204c56b99fSdrh} [list 0 "this\nis\ta\\test this\\nis\\ta\\\\test"] 7214c56b99fSdrh 7224c56b99fSdrh 7235128e85cSdrh# Test the output of the ".dump" command 7245128e85cSdrh# 7255128e85cSdrhdo_test shell1-4.1 { 72655a1b308Sdrh db close 72755a1b308Sdrh forcedelete test.db 72855a1b308Sdrh sqlite3 db test.db 7295128e85cSdrh db eval { 73055a1b308Sdrh PRAGMA encoding=UTF16; 7315128e85cSdrh CREATE TABLE t1(x); 732585dcb25Smistachkin INSERT INTO t1 VALUES(null), (''), (1), (2.25), ('hello'), (x'807f'); 733151c75adSmistachkin CREATE TABLE t3(x,y); 734151c75adSmistachkin INSERT INTO t3 VALUES(1,null), (2,''), (3,1), 735151c75adSmistachkin (4,2.25), (5,'hello'), (6,x'807f'); 7365128e85cSdrh } 7375128e85cSdrh catchcmd test.db {.dump} 7385128e85cSdrh} {0 {PRAGMA foreign_keys=OFF; 7395128e85cSdrhBEGIN TRANSACTION; 7405128e85cSdrhCREATE TABLE t1(x); 7415128e85cSdrhINSERT INTO "t1" VALUES(NULL); 742585dcb25SmistachkinINSERT INTO "t1" VALUES(''); 7435128e85cSdrhINSERT INTO "t1" VALUES(1); 7445128e85cSdrhINSERT INTO "t1" VALUES(2.25); 7455128e85cSdrhINSERT INTO "t1" VALUES('hello'); 7465128e85cSdrhINSERT INTO "t1" VALUES(X'807F'); 747151c75adSmistachkinCREATE TABLE t3(x,y); 748151c75adSmistachkinINSERT INTO "t3" VALUES(1,NULL); 749151c75adSmistachkinINSERT INTO "t3" VALUES(2,''); 750151c75adSmistachkinINSERT INTO "t3" VALUES(3,1); 751151c75adSmistachkinINSERT INTO "t3" VALUES(4,2.25); 752151c75adSmistachkinINSERT INTO "t3" VALUES(5,'hello'); 753151c75adSmistachkinINSERT INTO "t3" VALUES(6,X'807F'); 7545128e85cSdrhCOMMIT;}} 7555128e85cSdrh 7565128e85cSdrh# Test the output of ".mode insert" 7575128e85cSdrh# 758151c75adSmistachkindo_test shell1-4.2.1 { 7595128e85cSdrh catchcmd test.db ".mode insert t1\nselect * from t1;" 7605128e85cSdrh} {0 {INSERT INTO t1 VALUES(NULL); 761585dcb25SmistachkinINSERT INTO t1 VALUES(''); 7625128e85cSdrhINSERT INTO t1 VALUES(1); 7635128e85cSdrhINSERT INTO t1 VALUES(2.25); 7645128e85cSdrhINSERT INTO t1 VALUES('hello'); 7655128e85cSdrhINSERT INTO t1 VALUES(X'807f');}} 7665128e85cSdrh 767151c75adSmistachkin# Test the output of ".mode insert" with headers 768151c75adSmistachkin# 769151c75adSmistachkindo_test shell1-4.2.2 { 770151c75adSmistachkin catchcmd test.db ".mode insert t1\n.headers on\nselect * from t1;" 771151c75adSmistachkin} {0 {INSERT INTO t1(x) VALUES(NULL); 772151c75adSmistachkinINSERT INTO t1(x) VALUES(''); 773151c75adSmistachkinINSERT INTO t1(x) VALUES(1); 774151c75adSmistachkinINSERT INTO t1(x) VALUES(2.25); 775151c75adSmistachkinINSERT INTO t1(x) VALUES('hello'); 776151c75adSmistachkinINSERT INTO t1(x) VALUES(X'807f');}} 777151c75adSmistachkin 778151c75adSmistachkin# Test the output of ".mode insert" 779151c75adSmistachkin# 780151c75adSmistachkindo_test shell1-4.2.3 { 781151c75adSmistachkin catchcmd test.db ".mode insert t3\nselect * from t3;" 782151c75adSmistachkin} {0 {INSERT INTO t3 VALUES(1,NULL); 783151c75adSmistachkinINSERT INTO t3 VALUES(2,''); 784151c75adSmistachkinINSERT INTO t3 VALUES(3,1); 785151c75adSmistachkinINSERT INTO t3 VALUES(4,2.25); 786151c75adSmistachkinINSERT INTO t3 VALUES(5,'hello'); 787151c75adSmistachkinINSERT INTO t3 VALUES(6,X'807f');}} 788151c75adSmistachkin 789151c75adSmistachkin# Test the output of ".mode insert" with headers 790151c75adSmistachkin# 791cc445402Smistachkindo_test shell1-4.2.4 { 792151c75adSmistachkin catchcmd test.db ".mode insert t3\n.headers on\nselect * from t3;" 793151c75adSmistachkin} {0 {INSERT INTO t3(x,y) VALUES(1,NULL); 794151c75adSmistachkinINSERT INTO t3(x,y) VALUES(2,''); 795151c75adSmistachkinINSERT INTO t3(x,y) VALUES(3,1); 796151c75adSmistachkinINSERT INTO t3(x,y) VALUES(4,2.25); 797151c75adSmistachkinINSERT INTO t3(x,y) VALUES(5,'hello'); 798151c75adSmistachkinINSERT INTO t3(x,y) VALUES(6,X'807f');}} 799151c75adSmistachkin 800585dcb25Smistachkin# Test the output of ".mode tcl" 801585dcb25Smistachkin# 802585dcb25Smistachkindo_test shell1-4.3 { 80355a1b308Sdrh db close 80455a1b308Sdrh forcedelete test.db 80555a1b308Sdrh sqlite3 db test.db 80655a1b308Sdrh db eval { 80755a1b308Sdrh PRAGMA encoding=UTF8; 80855a1b308Sdrh CREATE TABLE t1(x); 80955a1b308Sdrh INSERT INTO t1 VALUES(null), (''), (1), (2.25), ('hello'), (x'807f'); 81055a1b308Sdrh } 811585dcb25Smistachkin catchcmd test.db ".mode tcl\nselect * from t1;" 812585dcb25Smistachkin} {0 {"" 813585dcb25Smistachkin"" 814585dcb25Smistachkin"1" 815585dcb25Smistachkin"2.25" 816585dcb25Smistachkin"hello" 817585dcb25Smistachkin"\200\177"}} 818585dcb25Smistachkin 819585dcb25Smistachkin# Test the output of ".mode tcl" with multiple columns 820585dcb25Smistachkin# 821585dcb25Smistachkindo_test shell1-4.4 { 822585dcb25Smistachkin db eval { 823585dcb25Smistachkin CREATE TABLE t2(x,y); 824585dcb25Smistachkin INSERT INTO t2 VALUES(null, ''), (1, 2.25), ('hello', x'807f'); 825585dcb25Smistachkin } 826585dcb25Smistachkin catchcmd test.db ".mode tcl\nselect * from t2;" 827585dcb25Smistachkin} {0 {"" "" 828585dcb25Smistachkin"1" "2.25" 829585dcb25Smistachkin"hello" "\200\177"}} 830585dcb25Smistachkin 831585dcb25Smistachkin# Test the output of ".mode tcl" with ".nullvalue" 832585dcb25Smistachkin# 833585dcb25Smistachkindo_test shell1-4.5 { 834585dcb25Smistachkin catchcmd test.db ".mode tcl\n.nullvalue NULL\nselect * from t2;" 835585dcb25Smistachkin} {0 {"NULL" "" 836585dcb25Smistachkin"1" "2.25" 837585dcb25Smistachkin"hello" "\200\177"}} 838585dcb25Smistachkin 839585dcb25Smistachkin# Test the output of ".mode tcl" with Tcl reserved characters 840585dcb25Smistachkin# 841585dcb25Smistachkindo_test shell1-4.6 { 842585dcb25Smistachkin db eval { 843585dcb25Smistachkin CREATE TABLE tcl1(x); 844585dcb25Smistachkin INSERT INTO tcl1 VALUES('"'), ('['), (']'), ('\{'), ('\}'), (';'), ('$'); 845585dcb25Smistachkin } 846585dcb25Smistachkin foreach {x y} [catchcmd test.db ".mode tcl\nselect * from tcl1;"] break 847585dcb25Smistachkin list $x $y [llength $y] 848585dcb25Smistachkin} {0 {"\"" 849585dcb25Smistachkin"[" 850585dcb25Smistachkin"]" 851585dcb25Smistachkin"\\{" 852585dcb25Smistachkin"\\}" 853585dcb25Smistachkin";" 854585dcb25Smistachkin"$"} 7} 8555128e85cSdrh 856f21979dfSmistachkin# Test using arbitrary byte data with the shell via standard input/output. 857f21979dfSmistachkin# 858f21979dfSmistachkindo_test shell1-5.0 { 859f21979dfSmistachkin # 860f21979dfSmistachkin # NOTE: Skip NUL byte because it appears to be incompatible with command 861f21979dfSmistachkin # shell argument parsing. 862f21979dfSmistachkin # 863f21979dfSmistachkin for {set i 1} {$i < 256} {incr i} { 864f21979dfSmistachkin # 86546a6b994Smistachkin # NOTE: Due to how the Tcl [exec] command works (i.e. where it treats 86646a6b994Smistachkin # command channels opened for it as textual ones), the carriage 86746a6b994Smistachkin # return character (and on Windows, the end-of-file character) 86846a6b994Smistachkin # cannot be used here. 869f21979dfSmistachkin # 87046a6b994Smistachkin if {$i==0x0D || ($tcl_platform(platform)=="windows" && $i==0x1A)} { 871f21979dfSmistachkin continue 872f21979dfSmistachkin } 873f21979dfSmistachkin set hex [format %02X $i] 874f21979dfSmistachkin set char [subst \\x$hex]; set oldChar $char 8750acee513Smistachkin set escapes [list] 8760acee513Smistachkin if {$tcl_platform(platform)=="windows"} { 8770acee513Smistachkin # 8780acee513Smistachkin # NOTE: On Windows, we need to escape all the whitespace characters, 8790acee513Smistachkin # the alarm (\a) character, and those with special meaning to 8800acee513Smistachkin # the SQLite shell itself. 8810acee513Smistachkin # 8820acee513Smistachkin set escapes [list \ 883f21979dfSmistachkin \a \\a \b \\b \t \\t \n \\n \v \\v \f \\f \r \\r \ 8840acee513Smistachkin " " "\" \"" \" \\\" ' \"'\" \\ \\\\] 8850acee513Smistachkin } else { 8860acee513Smistachkin # 8870acee513Smistachkin # NOTE: On Unix, we need to escape most of the whitespace characters 8880acee513Smistachkin # and those with special meaning to the SQLite shell itself. 8890acee513Smistachkin # The alarm (\a), backspace (\b), and carriage-return (\r) 8900acee513Smistachkin # characters do not appear to require escaping on Unix. For 8910acee513Smistachkin # the alarm and backspace characters, this is probably due to 8920acee513Smistachkin # differences in the command shell. For the carriage-return, 8930acee513Smistachkin # it is probably due to differences in how Tcl handles command 8940acee513Smistachkin # channel end-of-line translations. 8950acee513Smistachkin # 8960acee513Smistachkin set escapes [list \ 8970acee513Smistachkin \t \\t \n \\n \v \\v \f \\f \ 8980acee513Smistachkin " " "\" \"" \" \\\" ' \"'\" \\ \\\\] 8990acee513Smistachkin } 9000acee513Smistachkin set char [string map $escapes $char] 901bfefa4c2Smistachkin set x [catchcmdex test.db ".print $char\n"] 902f21979dfSmistachkin set code [lindex $x 0] 903f21979dfSmistachkin set res [lindex $x 1] 904f21979dfSmistachkin if {$code ne "0"} { 905f21979dfSmistachkin error "failed with error: $res" 906f21979dfSmistachkin } 907f21979dfSmistachkin if {$res ne "$oldChar\n"} { 90848dcf2b6Smistachkin if {[llength $res] > 0} { 90948dcf2b6Smistachkin set got [format %02X [scan $res %c]] 91048dcf2b6Smistachkin } else { 91148dcf2b6Smistachkin set got <empty> 91248dcf2b6Smistachkin } 91348dcf2b6Smistachkin error "failed with byte $hex mismatch, got $got" 914f21979dfSmistachkin } 915f21979dfSmistachkin } 9161fe36bb8Smistachkin} {} 9171fe36bb8Smistachkin 918*697c9eaaSdrh# These test cases do not work on MinGW 919*697c9eaaSdrhif 0 { 920*697c9eaaSdrh 92149e1125bSmistachkin# The string used here is the word "test" in Chinese. 9221fe36bb8Smistachkin# In UTF-8, it is encoded as: \xE6\xB5\x8B\xE8\xAF\x95 92349e1125bSmistachkinset test \u6D4B\u8BD5 92449e1125bSmistachkin 92549e1125bSmistachkindo_test shell1-6.0 { 92649e1125bSmistachkin set fileName $test; append fileName .db 92749e1125bSmistachkin catch {forcedelete $fileName} 9281fe36bb8Smistachkin set x [catchcmdex $fileName "CREATE TABLE t1(x);\n.schema\n"] 9291fe36bb8Smistachkin set code [lindex $x 0] 9301fe36bb8Smistachkin set res [string trim [lindex $x 1]] 9311fe36bb8Smistachkin if {$code ne "0"} { 9321fe36bb8Smistachkin error "failed with error: $res" 9331fe36bb8Smistachkin } 9341fe36bb8Smistachkin if {$res ne "CREATE TABLE t1(x);"} { 9351fe36bb8Smistachkin error "failed with mismatch: $res" 9361fe36bb8Smistachkin } 9371fe36bb8Smistachkin if {![file exists $fileName]} { 9381810f228Smistachkin error "file \"$fileName\" (Unicode) does not exist" 9391fe36bb8Smistachkin } 9401fe36bb8Smistachkin forcedelete $fileName 941f21979dfSmistachkin} {} 942f21979dfSmistachkin 94349e1125bSmistachkindo_test shell1-6.1 { 94449e1125bSmistachkin catch {forcedelete test3.db} 94549e1125bSmistachkin set x [catchcmdex test3.db \ 94649e1125bSmistachkin "CREATE TABLE [encoding convertto utf-8 $test](x);\n.schema\n"] 94749e1125bSmistachkin set code [lindex $x 0] 94849e1125bSmistachkin set res [string trim [lindex $x 1]] 94949e1125bSmistachkin if {$code ne "0"} { 95049e1125bSmistachkin error "failed with error: $res" 95149e1125bSmistachkin } 95249e1125bSmistachkin if {$res ne "CREATE TABLE ${test}(x);"} { 95349e1125bSmistachkin error "failed with mismatch: $res" 95449e1125bSmistachkin } 95549e1125bSmistachkin forcedelete test3.db 95649e1125bSmistachkin} {} 957*697c9eaaSdrh} 95849e1125bSmistachkin 9598df9185cSdrhfinish_test 960