modernc.org/cc@v1.0.1/v2/testdata/_sqlite/test/shell5.test (about) 1 # 2010 August 4 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 # 12 # The focus of this file is testing the CLI shell tool. 13 # These tests are specific to the .import command. 14 # 15 # $Id: shell5.test,v 1.7 2009/07/17 16:54:48 shaneh Exp $ 16 # 17 18 # Test plan: 19 # 20 # shell5-1.*: Basic tests specific to the ".import" command. 21 # 22 set testdir [file dirname $argv0] 23 source $testdir/tester.tcl 24 set CLI [test_find_cli] 25 db close 26 forcedelete test.db test.db-journal test.db-wal 27 28 #---------------------------------------------------------------------------- 29 # Test cases shell5-1.*: Basic handling of the .import and .separator commands. 30 # 31 32 # .import FILE TABLE Import data from FILE into TABLE 33 do_test shell5-1.1.1 { 34 catchcmd "test.db" ".import" 35 } {1 {Usage: .import FILE TABLE}} 36 do_test shell5-1.1.2 { 37 catchcmd "test.db" ".import FOO" 38 } {1 {Usage: .import FILE TABLE}} 39 #do_test shell5-1.1.2 { 40 # catchcmd "test.db" ".import FOO BAR" 41 #} {1 {Error: no such table: BAR}} 42 do_test shell5-1.1.3 { 43 # too many arguments 44 catchcmd "test.db" ".import FOO BAR BAD" 45 } {1 {Usage: .import FILE TABLE}} 46 47 # .separator STRING Change separator used by output mode and .import 48 do_test shell5-1.2.1 { 49 catchcmd "test.db" ".separator" 50 } {1 {Usage: .separator COL ?ROW?}} 51 do_test shell5-1.2.2 { 52 catchcmd "test.db" ".separator ONE" 53 } {0 {}} 54 do_test shell5-1.2.3 { 55 catchcmd "test.db" ".separator ONE TWO" 56 } {0 {}} 57 do_test shell5-1.2.4 { 58 # too many arguments 59 catchcmd "test.db" ".separator ONE TWO THREE" 60 } {1 {Usage: .separator COL ?ROW?}} 61 62 # column separator should default to "|" 63 do_test shell5-1.3.1.1 { 64 set res [catchcmd "test.db" ".show"] 65 list [regexp {colseparator: \"\|\"} $res] 66 } {1} 67 68 # row separator should default to "\n" 69 do_test shell5-1.3.1.2 { 70 set res [catchcmd "test.db" ".show"] 71 list [regexp {rowseparator: \"\\n\"} $res] 72 } {1} 73 74 # set separator to different value. 75 # check that .show reports new value 76 do_test shell5-1.3.2 { 77 set res [catchcmd "test.db" {.separator , 78 .show}] 79 list [regexp {separator: \",\"} $res] 80 } {1} 81 82 # import file doesn't exist 83 do_test shell5-1.4.1 { 84 forcedelete FOO 85 set res [catchcmd "test.db" {CREATE TABLE t1(a, b); 86 .import FOO t1}] 87 } {1 {Error: cannot open "FOO"}} 88 89 # empty import file 90 do_test shell5-1.4.2 { 91 forcedelete shell5.csv 92 set in [open shell5.csv w] 93 close $in 94 set res [catchcmd "test.db" {.import shell5.csv t1 95 SELECT COUNT(*) FROM t1;}] 96 } {0 0} 97 98 # import file with 1 row, 1 column (expecting 2 cols) 99 do_test shell5-1.4.3 { 100 set in [open shell5.csv w] 101 puts $in "1" 102 close $in 103 set res [catchcmd "test.db" {.import shell5.csv t1}] 104 } {1 {shell5.csv:1: expected 2 columns but found 1 - filling the rest with NULL}} 105 106 # import file with 1 row, 3 columns (expecting 2 cols) 107 do_test shell5-1.4.4 { 108 set in [open shell5.csv w] 109 puts $in "1|2|3" 110 close $in 111 set res [catchcmd "test.db" {.import shell5.csv t1}] 112 } {1 {shell5.csv:1: expected 2 columns but found 3 - extras ignored}} 113 114 # import file with 1 row, 2 columns 115 do_test shell5-1.4.5 { 116 set in [open shell5.csv w] 117 puts $in "1|2" 118 close $in 119 set res [catchcmd "test.db" {DELETE FROM t1; 120 .import shell5.csv t1 121 SELECT COUNT(*) FROM t1;}] 122 } {0 1} 123 124 # import file with 2 rows, 2 columns 125 # note we end up with 3 rows because of the 1 row 126 # imported above. 127 do_test shell5-1.4.6 { 128 set in [open shell5.csv w] 129 puts $in "2|3" 130 puts $in "3|4" 131 close $in 132 set res [catchcmd "test.db" {.import shell5.csv t1 133 SELECT COUNT(*) FROM t1;}] 134 } {0 3} 135 136 # import file with 1 row, 2 columns, using a comma 137 do_test shell5-1.4.7 { 138 set in [open shell5.csv w] 139 puts $in "4,5" 140 close $in 141 set res [catchcmd "test.db" {.separator , 142 .import shell5.csv t1 143 SELECT COUNT(*) FROM t1;}] 144 } {0 4} 145 146 # import file with 1 row, 2 columns, text data 147 do_test shell5-1.4.8.1 { 148 set in [open shell5.csv w] 149 puts $in "5|Now is the time for all good men to come to the aid of their country." 150 close $in 151 set res [catchcmd "test.db" {.import shell5.csv t1 152 SELECT COUNT(*) FROM t1;}] 153 } {0 5} 154 155 do_test shell5-1.4.8.2 { 156 catchcmd "test.db" {SELECT b FROM t1 WHERE a='5';} 157 } {0 {Now is the time for all good men to come to the aid of their country.}} 158 159 # import file with 1 row, 2 columns, quoted text data 160 # note that currently sqlite doesn't support quoted fields, and 161 # imports the entire field, quotes and all. 162 do_test shell5-1.4.9.1 { 163 set in [open shell5.csv w] 164 puts $in "6|'Now is the time for all good men to come to the aid of their country.'" 165 close $in 166 set res [catchcmd "test.db" {.import shell5.csv t1 167 SELECT COUNT(*) FROM t1;}] 168 } {0 6} 169 170 do_test shell5-1.4.9.2 { 171 catchcmd "test.db" {SELECT b FROM t1 WHERE a='6';} 172 } {0 {'Now is the time for all good men to come to the aid of their country.'}} 173 174 # import file with 1 row, 2 columns, quoted text data 175 do_test shell5-1.4.10.1 { 176 set in [open shell5.csv w] 177 puts $in "7|\"Now is the time for all good men to come to the aid of their country.\"" 178 close $in 179 set res [catchcmd "test.db" {.import shell5.csv t1 180 SELECT COUNT(*) FROM t1;}] 181 } {0 7} 182 183 do_test shell5-1.4.10.2 { 184 catchcmd "test.db" {SELECT b FROM t1 WHERE a='7';} 185 } {0 {Now is the time for all good men to come to the aid of their country.}} 186 187 # import file with 2 rows, 2 columns and an initial BOM 188 # 189 do_test shell5-1.4.11 { 190 set in [open shell5.csv wb] 191 puts -nonewline $in "\xef\xbb\xbf" 192 puts $in "2|3" 193 puts $in "4|5" 194 close $in 195 set res [catchcmd "test.db" {CREATE TABLE t2(x INT, y INT); 196 .import shell5.csv t2 197 .mode quote 198 .header on 199 SELECT * FROM t2;}] 200 string map {\n | \n\r |} $res 201 } {0 {'x','y'|2,3|4,5}} 202 203 # import file with 2 rows, 2 columns or text with an initial BOM 204 # 205 do_test shell5-1.4.12 { 206 set in [open shell5.csv wb] 207 puts $in "\xef\xbb\xbf\"two\"|3" 208 puts $in "4|5" 209 close $in 210 set res [catchcmd "test.db" {DELETE FROM t2; 211 .import shell5.csv t2 212 .mode quote 213 .header on 214 SELECT * FROM t2;}] 215 string map {\n | \n\r |} $res 216 } {0 {'x','y'|'two',3|4,5}} 217 218 # check importing very long field 219 do_test shell5-1.5.1 { 220 set str [string repeat X 999] 221 set in [open shell5.csv w] 222 puts $in "8|$str" 223 close $in 224 set res [catchcmd "test.db" {.import shell5.csv t1 225 SELECT length(b) FROM t1 WHERE a='8';}] 226 } {0 999} 227 228 # try importing into a table with a large number of columns. 229 # This is limited by SQLITE_MAX_VARIABLE_NUMBER, which defaults to 999. 230 set cols 999 231 do_test shell5-1.6.1 { 232 set data {} 233 for {set i 1} {$i<$cols} {incr i} { 234 append data "c$i|" 235 } 236 append data "c$cols\n"; 237 for {set i 1} {$i<$cols} {incr i} { 238 append data "$i|" 239 } 240 append data "$cols" 241 set in [open shell5.csv w] 242 puts $in $data 243 close $in 244 set res [catchcmd "test.db" {DROP TABLE IF EXISTS t2; 245 .import shell5.csv t2 246 SELECT COUNT(*) FROM t2;}] 247 } {0 1} 248 249 # try importing a large number of rows 250 set rows 9999 251 do_test shell5-1.7.1 { 252 set in [open shell5.csv w] 253 puts $in a 254 for {set i 1} {$i<=$rows} {incr i} { 255 puts $in $i 256 } 257 close $in 258 set res [catchcmd "test.db" {.mode csv 259 .import shell5.csv t3 260 SELECT COUNT(*) FROM t3;}] 261 } [list 0 $rows] 262 263 # Inport from a pipe. (Unix only, as it requires "awk") 264 if {$tcl_platform(platform)=="unix"} { 265 do_test shell5-1.8 { 266 forcedelete test.db 267 catchcmd test.db {.mode csv 268 .import "|awk 'END{print \"x,y\";for(i=1;i<=5;i++){print i \",this is \" i}}'" t1 269 SELECT * FROM t1;} 270 } {0 {1,"this is 1" 271 2,"this is 2" 272 3,"this is 3" 273 4,"this is 4" 274 5,"this is 5"}} 275 } 276 277 # Import columns containing quoted strings 278 do_test shell5-1.9 { 279 set out [open shell5.csv w] 280 fconfigure $out -translation lf 281 puts $out {1,"",11} 282 puts $out {2,"x",22} 283 puts $out {3,"""",33} 284 puts $out {4,"hello",44} 285 puts $out "5,55,\"\"\r" 286 puts $out {6,66,"x"} 287 puts $out {7,77,""""} 288 puts $out {8,88,"hello"} 289 puts $out {"",9,99} 290 puts $out {"x",10,110} 291 puts $out {"""",11,121} 292 puts $out {"hello",12,132} 293 close $out 294 forcedelete test.db 295 catchcmd test.db {.mode csv 296 CREATE TABLE t1(a,b,c); 297 .import shell5.csv t1 298 } 299 sqlite3 db test.db 300 db eval {SELECT *, '|' FROM t1 ORDER BY rowid} 301 } {1 {} 11 | 2 x 22 | 3 {"} 33 | 4 hello 44 | 5 55 {} | 6 66 x | 7 77 {"} | 8 88 hello | {} 9 99 | x 10 110 | {"} 11 121 | hello 12 132 |} 302 db close 303 304 # Import columns containing quoted strings 305 do_test shell5-1.10 { 306 set out [open shell5.csv w] 307 fconfigure $out -translation lf 308 puts $out {column1,column2,column3,column4} 309 puts $out "field1,field2,\"x3 \"\"\r\ndata\"\" 3\",field4" 310 puts $out "x1,x2,\"x3 \"\"\ndata\"\" 3\",x4" 311 close $out 312 forcedelete test.db 313 catchcmd test.db {.mode csv 314 CREATE TABLE t1(a,b,c,d); 315 .import shell5.csv t1 316 } 317 sqlite3 db test.db 318 db eval {SELECT hex(c) FROM t1 ORDER BY rowid} 319 } {636F6C756D6E33 783320220D0A64617461222033 783320220A64617461222033} 320 321 # Blank last column with \r\n line endings. 322 do_test shell5-1.11 { 323 set out [open shell5.csv w] 324 fconfigure $out -translation binary 325 puts $out "column1,column2,column3\r" 326 puts $out "a,b, \r" 327 puts $out "x,y,\r" 328 puts $out "p,q,r\r" 329 close $out 330 catch {db close} 331 forcedelete test.db 332 catchcmd test.db {.mode csv 333 .import shell5.csv t1 334 } 335 sqlite3 db test.db 336 db eval {SELECT *, '|' FROM t1} 337 } {a b { } | x y {} | p q r |} 338 db close 339 340 #---------------------------------------------------------------------------- 341 # 342 reset_db 343 sqlite3 db test.db 344 do_test shell5-2.1 { 345 set fd [open shell5.csv w] 346 puts $fd ",hello" 347 close $fd 348 catchcmd test.db [string trim { 349 .mode csv 350 CREATE TABLE t1(a, b); 351 .import shell5.csv t1 352 }] 353 db eval { SELECT * FROM t1 } 354 } {{} hello} 355 356 do_test shell5-2.2 { 357 set fd [open shell5.csv w] 358 puts $fd {"",hello} 359 close $fd 360 catchcmd test.db [string trim { 361 .mode csv 362 CREATE TABLE t2(a, b); 363 .import shell5.csv t2 364 }] 365 db eval { SELECT * FROM t2 } 366 } {{} hello} 367 368 do_test shell5-2.3 { 369 set fd [open shell5.csv w] 370 puts $fd {"x""y",hello} 371 close $fd 372 catchcmd test.db [string trim { 373 .mode csv 374 CREATE TABLE t3(a, b); 375 .import shell5.csv t3 376 }] 377 db eval { SELECT * FROM t3 } 378 } {x\"y hello} 379 380 do_test shell5-2.4 { 381 set fd [open shell5.csv w] 382 puts $fd {"xy""",hello} 383 close $fd 384 catchcmd test.db [string trim { 385 .mode csv 386 CREATE TABLE t4(a, b); 387 .import shell5.csv t4 388 }] 389 db eval { SELECT * FROM t4 } 390 } {xy\" hello} 391 392 do_test shell5-2.5 { 393 set fd [open shell5.csv w] 394 puts $fd {"one","2"} 395 puts $fd {} 396 close $fd 397 catchcmd test.db [string trim { 398 .mode csv 399 CREATE TABLE t4(a, b); 400 .import shell5.csv t4 401 }] 402 db eval { SELECT * FROM t4 } 403 } {xy\" hello one 2 {} {}} 404 405 #---------------------------------------------------------------------------- 406 # Tests for the shell "ascii" import/export mode. 407 # 408 do_test shell5-3.1 { 409 set fd [open shell5.csv w] 410 fconfigure $fd -encoding binary -translation binary 411 puts -nonewline $fd "\"test 1\"\x1F,test 2\r\n\x1E" 412 puts -nonewline $fd "test 3\x1Ftest 4\n" 413 close $fd 414 catchcmd test.db { 415 .mode ascii 416 CREATE TABLE t5(a, b); 417 .import shell5.csv t5 418 } 419 db eval { SELECT * FROM t5 } 420 } "\{\"test 1\"} \{,test 2\r\n\} \{test 3\} \{test 4\n\}" 421 422 do_test shell5-3.2 { 423 set x [catchcmd test.db { 424 .mode ascii 425 SELECT * FROM t5; 426 }] 427 # Handle platform end-of-line differences 428 regsub -all {[\n\r]?\n} $x <EOL> x 429 set x 430 } "0 \{\"test 1\"\x1F,test 2<EOL>\x1Etest 3\x1Ftest 4<EOL>\x1E\}" 431 432 do_test shell5-4.1 { 433 forcedelete shell5.csv 434 set fd [open shell5.csv w] 435 puts $fd "1,2,3" 436 puts $fd "4,5" 437 puts $fd "6,7,8" 438 close $fd 439 catchcmd test.db [string trim { 440 .mode csv 441 CREATE TABLE t6(a, b, c); 442 .import shell5.csv t6 443 }] 444 db eval { SELECT * FROM t6 ORDER BY a } 445 } {1 2 3 4 5 {} 6 7 8} 446 447 do_test shell5-4.2 { 448 forcedelete shell5.csv 449 set fd [open shell5.csv w] 450 puts $fd "1,2,3" 451 puts $fd "4,5" 452 puts $fd "6,7,8,9" 453 close $fd 454 catchcmd test.db [string trim { 455 .mode csv 456 CREATE TABLE t7(a, b, c); 457 .import shell5.csv t7 458 }] 459 db eval { SELECT * FROM t7 ORDER BY a } 460 } {1 2 3 4 5 {} 6 7 8} 461 462 finish_test