1# 2003 January 29 2# 3# The author disclaims copyright to this source code. In place of 4# a legal notice, here is a blessing: 5# 6# May you do good and not evil. 7# May you find forgiveness for yourself and forgive others. 8# May you share freely, never taking more than you give. 9# 10#*********************************************************************** 11# This file implements regression tests for SQLite library. The 12# focus of this script testing the callback-free C/C++ API. 13# 14# $Id: capi3.test,v 1.10 2004/05/28 13:13:04 danielk1977 Exp $ 15# 16 17set testdir [file dirname $argv0] 18source $testdir/tester.tcl 19 20# Return the UTF-16 representation of the supplied UTF-8 string $str. 21# If $nt is true, append two 0x00 bytes as a nul terminator. 22proc utf16 {str {nt 1}} { 23 set r [encoding convertto unicode $str] 24 if {$nt} { 25 append r "\x00\x00" 26 } 27 return $r 28} 29 30# Return the UTF-8 representation of the supplied UTF-16 string $str. 31proc utf8 {str} { 32 # If $str ends in two 0x00 0x00 bytes, knock these off before 33 # converting to UTF-8 using TCL. 34 binary scan $str \c* vals 35 if {[lindex $vals end]==0 && [lindex $vals end-1]==0} { 36 set str [binary format \c* [lrange $vals 0 end-2]] 37 } 38 39 set r [encoding convertfrom unicode $str] 40 return $r 41} 42 43# These tests complement those in capi2.test. They are organized 44# as follows: 45# 46# capi3-1.*: Test sqlite3_prepare 47# capi3-2.*: Test sqlite3_prepare16 48# capi3-3.*: Test sqlite3_open 49# capi3-4.*: Test sqlite3_open16 50# capi3-5.*: Test the various sqlite3_result_* APIs 51# 52 53db close 54set DB [sqlite db test.db] 55 56do_test capi3-1.1 { 57 set STMT [sqlite3_prepare $DB {SELECT name FROM sqlite_master} -1 TAIL] 58 sqlite3_finalize $STMT 59 set TAIL 60} {} 61do_test capi3-1.2 { 62 sqlite3_errcode $DB 63} {SQLITE_OK} 64do_test capi3-1.3 { 65 sqlite3_errmsg $DB 66} {not an error} 67do_test capi3-1.4 { 68 set sql {SELECT name FROM sqlite_master;SELECT 10} 69 set STMT [sqlite3_prepare $DB $sql -1 TAIL] 70 sqlite3_finalize $STMT 71 set TAIL 72} {SELECT 10} 73do_test capi3-1.5 { 74 set sql {SELECT namex FROM sqlite_master} 75 catch { 76 set STMT [sqlite3_prepare $DB $sql -1 TAIL] 77 } 78} {1} 79do_test capi3-1.6 { 80 sqlite3_errcode $DB 81} {SQLITE_ERROR} 82do_test capi3-1.7 { 83 sqlite3_errmsg $DB 84} {no such column: namex} 85 86do_test capi3-2.1 { 87 set sql16 [utf16 {SELECT name FROM sqlite_master}] 88 set STMT [sqlite3_prepare16 $DB $sql16 -1 ::TAIL] 89 sqlite3_finalize $STMT 90 utf8 $::TAIL 91} {} 92do_test capi3-2.2 { 93 set sql [utf16 {SELECT name FROM sqlite_master;SELECT 10}] 94 set STMT [sqlite3_prepare16 $DB $sql -1 TAIL] 95 sqlite3_finalize $STMT 96 utf8 $TAIL 97} {SELECT 10} 98do_test capi3-2.3 { 99 set sql [utf16 {SELECT namex FROM sqlite_master}] 100 catch { 101 set STMT [sqlite3_prepare16 $DB $sql -1 TAIL] 102 } 103} {1} 104do_test capi3-2.4 { 105 sqlite3_errcode $DB 106} {SQLITE_ERROR} 107do_test capi3-2.5 { 108 sqlite3_errmsg $DB 109} {no such column: namex} 110 111# rename sqlite3_open sqlite3_open_old 112# proc sqlite3_open {fname options} {sqlite3_open_new $fname $options} 113 114do_test capi3-3.1 { 115 set db2 [sqlite3_open test.db {}] 116 sqlite3_errcode $db2 117} {SQLITE_OK} 118# FIX ME: Should test the db handle works. 119do_test capi3-3.2 { 120 sqlite3_close $db2 121} {} 122do_test capi3-3.3 { 123 catch { 124 set db2 [sqlite3_open /bogus/path/test.db {}] 125 } 126 sqlite3_errcode $db2 127} {SQLITE_CANTOPEN} 128do_test capi3-3.4 { 129 sqlite3_errmsg $db2 130} {unable to open database file} 131do_test capi3-3.4 { 132 sqlite3_close $db2 133} {} 134 135# rename sqlite3_open "" 136# rename sqlite3_open_old sqlite3_open 137 138do_test capi3-4.1 { 139 set db2 [sqlite3_open16 [utf16 test.db] {}] 140 sqlite3_errcode $db2 141} {SQLITE_OK} 142# FIX ME: Should test the db handle works. 143do_test capi3-4.2 { 144 sqlite3_close $db2 145} {} 146do_test capi3-4.3 { 147 catch { 148 set db2 [sqlite3_open16 [utf16 /bogus/path/test.db] {}] 149 } 150 sqlite3_errcode $db2 151} {SQLITE_CANTOPEN} 152do_test capi3-4.4 { 153 utf8 [sqlite3_errmsg16 $db2] 154} {unable to open database file} 155do_test capi3-4.5 { 156 sqlite3_close $db2 157} {} 158 159# This proc is used to test the following API calls: 160# 161# sqlite3_column_count 162# sqlite3_column_name 163# sqlite3_column_name16 164# sqlite3_column_decltype 165# sqlite3_column_decltype16 166# 167# $STMT is a compiled SQL statement. $test is a prefix 168# to use for test names within this proc. $names is a list 169# of the column names that should be returned by $STMT. 170# $decltypes is a list of column declaration types for $STMT. 171# 172# Example: 173# 174# set STMT [sqlite3_prepare "SELECT 1, 2, 2;" -1 DUMMY] 175# check_header test1.1 {1 2 3} {"" "" ""} 176# 177proc check_header {STMT test names decltypes} { 178 179 # Use the return value of sqlite3_column_count() to build 180 # a list of column indexes. i.e. If sqlite3_column_count 181 # is 3, build the list {0 1 2}. 182 set ::idxlist [list] 183 set numcols [sqlite3_column_count $STMT] 184 for {set i 0} {$i < $numcols} {incr i} {lappend ::idxlist $i} 185 186 # Column names in UTF-8 187 do_test $test.1 { 188 set cnamelist [list] 189 foreach i $idxlist {lappend cnamelist [sqlite3_column_name $STMT $i]} 190 set cnamelist 191 } $names 192 193 # Column names in UTF-16 194 do_test $test.2 { 195 set cnamelist [list] 196 foreach i $idxlist { 197 lappend cnamelist [utf8 [sqlite3_column_name16 $STMT $i]] 198 } 199 set cnamelist 200 } $names 201 202 # Column names in UTF-8 203 do_test $test.3 { 204 set cnamelist [list] 205 foreach i $idxlist {lappend cnamelist [sqlite3_column_name $STMT $i]} 206 set cnamelist 207 } $names 208 209 # Column names in UTF-16 210 do_test $test.4 { 211 set cnamelist [list] 212 foreach i $idxlist { 213 lappend cnamelist [utf8 [sqlite3_column_name16 $STMT $i]] 214 } 215 set cnamelist 216 } $names 217 218 # Column names in UTF-8 219 do_test $test.5 { 220 set cnamelist [list] 221 foreach i $idxlist {lappend cnamelist [sqlite3_column_decltype $STMT $i]} 222 set cnamelist 223 } $decltypes 224 225 # Column declaration types in UTF-16 226 do_test $test.6 { 227 set cnamelist [list] 228 foreach i $idxlist { 229 lappend cnamelist [utf8 [sqlite3_column_decltype16 $STMT $i]] 230 } 231 set cnamelist 232 } $decltypes 233 234} 235 236# This proc is used to test the following APIs: 237# 238# sqlite3_data_count 239# sqlite3_column_type 240# sqlite3_column_int 241# sqlite3_column_text 242# sqlite3_column_text16 243# sqlite3_column_double 244# 245# $STMT is a compiled SQL statement for which the previous call 246# to sqlite3_step returned SQLITE_ROW. $test is a prefix to use 247# for test names within this proc. $types is a list of the 248# manifest types for the current row. $ints, $doubles and $strings 249# are lists of the integer, real and string representations of 250# the values in the current row. 251# 252# Example: 253# 254# set STMT [sqlite3_prepare "SELECT 'hello', 1.1, NULL" -1 DUMMY] 255# sqlite3_step $STMT 256# check_data test1.2 {TEXT REAL NULL} {0 1 0} {0 1.1 0} {hello 1.1 {}} 257# 258proc check_data {STMT test types ints doubles strings} { 259 260 # Use the return value of sqlite3_column_count() to build 261 # a list of column indexes. i.e. If sqlite3_column_count 262 # is 3, build the list {0 1 2}. 263 set ::idxlist [list] 264 set numcols [sqlite3_data_count $STMT] 265 for {set i 0} {$i < $numcols} {incr i} {lappend ::idxlist $i} 266 267# types 268do_test $test.1 { 269 set types [list] 270 foreach i $idxlist {lappend types [sqlite3_column_type $STMT $i]} 271 set types 272} $types 273 274# Integers 275do_test $test.2 { 276 set ints [list] 277 foreach i $idxlist {lappend ints [sqlite3_column_int $STMT $i]} 278 set ints 279} $ints 280 281# UTF-8 282do_test $test.3 { 283 set utf8 [list] 284 foreach i $idxlist {lappend utf8 [sqlite3_column_text $STMT $i]} 285 set utf8 286} $strings 287 288# Floats 289do_test $test.4 { 290 set utf8 [list] 291 foreach i $idxlist {lappend utf8 [sqlite3_column_double $STMT $i]} 292 set utf8 293} $doubles 294 295# UTF-16 296do_test $test.5 { 297 set utf8 [list] 298 foreach i $idxlist {lappend utf8 [utf8 [sqlite3_column_text16 $STMT $i]]} 299 set utf8 300} $strings 301 302# Integers 303do_test $test.6 { 304 set ints [list] 305 foreach i $idxlist {lappend ints [sqlite3_column_int $STMT $i]} 306 set ints 307} $ints 308 309# Floats 310do_test $test.7 { 311 set utf8 [list] 312 foreach i $idxlist {lappend utf8 [sqlite3_column_double $STMT $i]} 313 set utf8 314} $doubles 315 316# UTF-8 317do_test $test.8 { 318 set utf8 [list] 319 foreach i $idxlist {lappend utf8 [sqlite3_column_text $STMT $i]} 320 set utf8 321} $strings 322 323# Types 324do_test $test.9 { 325 set types [list] 326 foreach i $idxlist {lappend types [sqlite3_column_type $STMT $i]} 327 set types 328} $types 329 330} 331 332do_test capi3-5.0 { 333 execsql { 334 CREATE TABLE t1(a VARINT, b BLOB, c VARCHAR(16)); 335 INSERT INTO t1 VALUES(1, 2, 3); 336 INSERT INTO t1 VALUES('one', 'two', NULL); 337 INSERT INTO t1 VALUES(1.2, 1.3, 1.4); 338 } 339 set sql "SELECT * FROM t1" 340 set STMT [sqlite3_prepare $DB $sql -1 TAIL] 341 342 sqlite3_column_count $STMT 343} 3 344 345check_header $STMT capi3-5.1 {a b c} {VARINT BLOB VARCHAR(16)} 346 347do_test capi3-5.2 { 348 sqlite3_step $STMT 349} SQLITE_ROW 350 351check_header $STMT capi3-5.3 {a b c} {VARINT BLOB VARCHAR(16)} 352check_data $STMT capi3-5.4 {INTEGER INTEGER TEXT} {1 2 3} {1.0 2.0 3.0} {1 2 3} 353 354do_test capi3-5.5 { 355 sqlite3_step $STMT 356} SQLITE_ROW 357 358check_header $STMT capi3-5.6 {a b c} {VARINT BLOB VARCHAR(16)} 359check_data $STMT capi3-5.7 {TEXT TEXT NULL} {0 0 0} {0.0 0.0 0.0} {one two {}} 360 361do_test capi3-5.8 { 362 sqlite3_step $STMT 363} SQLITE_ROW 364 365check_header $STMT capi3-5.9 {a b c} {VARINT BLOB VARCHAR(16)} 366check_data $STMT capi3-5.10 {FLOAT FLOAT TEXT} {1 1 1} {1.2 1.3 1.4} {1.2 1.3 1.4} 367 368do_test capi3-5.11 { 369 sqlite3_step $STMT 370} SQLITE_DONE 371 372do_test capi3-5.12 { 373 sqlite3_finalize $STMT 374} SQLITE_OK 375 376db close 377 378finish_test 379 380 381