xref: /sqlite-3.40.0/test/shell5.test (revision bd41d566)
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#
22set testdir [file dirname $argv0]
23source $testdir/tester.tcl
24if {$tcl_platform(platform)=="windows"} {
25  set CLI "sqlite3.exe"
26} else {
27  set CLI "./sqlite3"
28}
29if {![file executable $CLI]} {
30  finish_test
31  return
32}
33db close
34forcedelete test.db test.db-journal test.db-wal
35
36#----------------------------------------------------------------------------
37# Test cases shell5-1.*: Basic handling of the .import and .separator commands.
38#
39
40# .import FILE TABLE     Import data from FILE into TABLE
41do_test shell5-1.1.1 {
42  catchcmd "test.db" ".import"
43} {1 {Usage: .import FILE TABLE}}
44do_test shell5-1.1.2 {
45  catchcmd "test.db" ".import FOO"
46} {1 {Usage: .import FILE TABLE}}
47#do_test shell5-1.1.2 {
48#  catchcmd "test.db" ".import FOO BAR"
49#} {1 {Error: no such table: BAR}}
50do_test shell5-1.1.3 {
51  # too many arguments
52  catchcmd "test.db" ".import FOO BAR BAD"
53} {1 {Usage: .import FILE TABLE}}
54
55# .separator STRING      Change separator used by output mode and .import
56do_test shell5-1.2.1 {
57  catchcmd "test.db" ".separator"
58} {1 {Usage: .separator SEPARATOR ?NEWLINE?}}
59do_test shell5-1.2.2 {
60  catchcmd "test.db" ".separator ONE"
61} {0 {}}
62do_test shell5-1.2.3 {
63  catchcmd "test.db" ".separator ONE TWO"
64} {0 {}}
65do_test shell5-1.2.4 {
66  # too many arguments
67  catchcmd "test.db" ".separator ONE TWO THREE"
68} {1 {Usage: .separator SEPARATOR ?NEWLINE?}}
69
70# separator should default to "|"
71do_test shell5-1.3.1 {
72  set res [catchcmd "test.db" ".show"]
73  list [regexp {separator: \"\|\"} $res]
74} {1}
75
76# set separator to different value.
77# check that .show reports new value
78do_test shell5-1.3.2 {
79  set res [catchcmd "test.db" {.separator ,
80.show}]
81  list [regexp {separator: \",\"} $res]
82} {1}
83
84# import file doesn't exist
85do_test shell5-1.4.1 {
86  forcedelete FOO
87  set res [catchcmd "test.db" {CREATE TABLE t1(a, b);
88.import FOO t1}]
89} {1 {Error: cannot open "FOO"}}
90
91# empty import file
92do_test shell5-1.4.2 {
93  forcedelete shell5.csv
94  set in [open shell5.csv w]
95  close $in
96  set res [catchcmd "test.db" {.import shell5.csv t1
97SELECT COUNT(*) FROM t1;}]
98} {0 0}
99
100# import file with 1 row, 1 column (expecting 2 cols)
101do_test shell5-1.4.3 {
102  set in [open shell5.csv w]
103  puts $in "1"
104  close $in
105  set res [catchcmd "test.db" {.import shell5.csv t1}]
106} {1 {shell5.csv:1: expected 2 columns but found 1 - filling the rest with NULL}}
107
108# import file with 1 row, 3 columns (expecting 2 cols)
109do_test shell5-1.4.4 {
110  set in [open shell5.csv w]
111  puts $in "1|2|3"
112  close $in
113  set res [catchcmd "test.db" {.import shell5.csv t1}]
114} {1 {shell5.csv:1: expected 2 columns but found 3 - extras ignored}}
115
116# import file with 1 row, 2 columns
117do_test shell5-1.4.5 {
118  set in [open shell5.csv w]
119  puts $in "1|2"
120  close $in
121  set res [catchcmd "test.db" {DELETE FROM t1;
122.import shell5.csv t1
123SELECT COUNT(*) FROM t1;}]
124} {0 1}
125
126# import file with 2 rows, 2 columns
127# note we end up with 3 rows because of the 1 row
128# imported above.
129do_test shell5-1.4.6 {
130  set in [open shell5.csv w]
131  puts $in "2|3"
132  puts $in "3|4"
133  close $in
134  set res [catchcmd "test.db" {.import shell5.csv t1
135SELECT COUNT(*) FROM t1;}]
136} {0 3}
137
138# import file with 1 row, 2 columns, using a comma
139do_test shell5-1.4.7 {
140  set in [open shell5.csv w]
141  puts $in "4,5"
142  close $in
143  set res [catchcmd "test.db" {.separator ,
144.import shell5.csv t1
145SELECT COUNT(*) FROM t1;}]
146} {0 4}
147
148# import file with 1 row, 2 columns, text data
149do_test shell5-1.4.8.1 {
150  set in [open shell5.csv w]
151  puts $in "5|Now is the time for all good men to come to the aid of their country."
152  close $in
153  set res [catchcmd "test.db" {.import shell5.csv t1
154SELECT COUNT(*) FROM t1;}]
155} {0 5}
156
157do_test shell5-1.4.8.2 {
158  catchcmd "test.db" {SELECT b FROM t1 WHERE a='5';}
159} {0 {Now is the time for all good men to come to the aid of their country.}}
160
161# import file with 1 row, 2 columns, quoted text data
162# note that currently sqlite doesn't support quoted fields, and
163# imports the entire field, quotes and all.
164do_test shell5-1.4.9.1 {
165  set in [open shell5.csv w]
166  puts $in "6|'Now is the time for all good men to come to the aid of their country.'"
167  close $in
168  set res [catchcmd "test.db" {.import shell5.csv t1
169SELECT COUNT(*) FROM t1;}]
170} {0 6}
171
172do_test shell5-1.4.9.2 {
173  catchcmd "test.db" {SELECT b FROM t1 WHERE a='6';}
174} {0 {'Now is the time for all good men to come to the aid of their country.'}}
175
176# import file with 1 row, 2 columns, quoted text data
177do_test shell5-1.4.10.1 {
178  set in [open shell5.csv w]
179  puts $in "7|\"Now is the time for all good men to come to the aid of their country.\""
180  close $in
181  set res [catchcmd "test.db" {.import shell5.csv t1
182SELECT COUNT(*) FROM t1;}]
183} {0 7}
184
185do_test shell5-1.4.10.2 {
186  catchcmd "test.db" {SELECT b FROM t1 WHERE a='7';}
187} {0 {Now is the time for all good men to come to the aid of their country.}}
188
189# check importing very long field
190do_test shell5-1.5.1 {
191  set str [string repeat X 999]
192  set in [open shell5.csv w]
193  puts $in "8|$str"
194  close $in
195  set res [catchcmd "test.db" {.import shell5.csv t1
196SELECT length(b) FROM t1 WHERE a='8';}]
197} {0 999}
198
199# try importing into a table with a large number of columns.
200# This is limited by SQLITE_MAX_VARIABLE_NUMBER, which defaults to 999.
201set cols 999
202do_test shell5-1.6.1 {
203  set data {}
204  for {set i 1} {$i<$cols} {incr i} {
205    append data "c$i|"
206  }
207  append data "c$cols\n";
208  for {set i 1} {$i<$cols} {incr i} {
209    append data "$i|"
210  }
211  append data "$cols"
212  set in [open shell5.csv w]
213  puts $in $data
214  close $in
215  set res [catchcmd "test.db" {.import shell5.csv t2
216SELECT COUNT(*) FROM t2;}]
217} {0 1}
218
219# try importing a large number of rows
220set rows 9999
221do_test shell5-1.7.1 {
222  set in [open shell5.csv w]
223  puts $in a
224  for {set i 1} {$i<=$rows} {incr i} {
225    puts $in $i
226  }
227  close $in
228  set res [catchcmd "test.db" {.mode csv
229.import shell5.csv t3
230SELECT COUNT(*) FROM t3;}]
231} [list 0 $rows]
232
233# Inport from a pipe.  (Unix only, as it requires "awk")
234if {$tcl_platform(platform)=="unix"} {
235  do_test shell5-1.8 {
236    forcedelete test.db
237    catchcmd test.db {.mode csv
238.import "|awk 'END{print \"x,y\";for(i=1;i<=5;i++){print i \",this is \" i}}'" t1
239SELECT * FROM t1;}
240  } {0 {1,"this is 1"
2412,"this is 2"
2423,"this is 3"
2434,"this is 4"
2445,"this is 5"}}
245}
246
247# Import columns containing quoted strings
248do_test shell5-1.9 {
249  set out [open shell5.csv w]
250  fconfigure $out -translation lf
251  puts $out {1,"",11}
252  puts $out {2,"x",22}
253  puts $out {3,"""",33}
254  puts $out {4,"hello",44}
255  puts $out "5,55,\"\"\r"
256  puts $out {6,66,"x"}
257  puts $out {7,77,""""}
258  puts $out {8,88,"hello"}
259  puts $out {"",9,99}
260  puts $out {"x",10,110}
261  puts $out {"""",11,121}
262  puts $out {"hello",12,132}
263  close $out
264  forcedelete test.db
265  catchcmd test.db {.mode csv
266    CREATE TABLE t1(a,b,c);
267.import shell5.csv t1
268  }
269  sqlite3 db test.db
270  db eval {SELECT *, '|' FROM t1 ORDER BY rowid}
271} {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 |}
272db close
273
274# Import columns containing quoted strings
275do_test shell5-1.10 {
276  set out [open shell5.csv w]
277  fconfigure $out -translation lf
278  puts $out {column1,column2,column3,column4}
279  puts $out "field1,field2,\"x3 \"\"\r\ndata\"\" 3\",field4"
280  puts $out "x1,x2,\"x3 \"\"\ndata\"\" 3\",x4"
281  close $out
282  forcedelete test.db
283  catchcmd test.db {.mode csv
284    CREATE TABLE t1(a,b,c,d);
285.import shell5.csv t1
286  }
287  sqlite3 db test.db
288  db eval {SELECT hex(c) FROM t1 ORDER BY rowid}
289} {636F6C756D6E33 783320220D0A64617461222033 783320220A64617461222033}
290
291# Blank last column with \r\n line endings.
292do_test shell5-1.11 {
293  set out [open shell5.csv w]
294  fconfigure $out -translation binary
295  puts $out "column1,column2,column3\r"
296  puts $out "a,b, \r"
297  puts $out "x,y,\r"
298  puts $out "p,q,r\r"
299  close $out
300  catch {db close}
301  forcedelete test.db
302  catchcmd test.db {.mode csv
303.import shell5.csv t1
304  }
305  sqlite3 db test.db
306  db eval {SELECT *, '|' FROM t1}
307} {a b { } | x y {} | p q r |}
308db close
309
310#----------------------------------------------------------------------------
311#
312reset_db
313sqlite3 db test.db
314do_test shell5-2.1 {
315  set fd [open shell5.csv w]
316  puts $fd ",hello"
317  close $fd
318  catchcmd test.db [string trim {
319.mode csv
320CREATE TABLE t1(a, b);
321.import shell5.csv t1
322  }]
323  db eval { SELECT * FROM t1 }
324} {{} hello}
325
326do_test shell5-2.2 {
327  set fd [open shell5.csv w]
328  puts $fd {"",hello}
329  close $fd
330  catchcmd test.db [string trim {
331.mode csv
332CREATE TABLE t2(a, b);
333.import shell5.csv t2
334  }]
335  db eval { SELECT * FROM t2 }
336} {{} hello}
337
338do_test shell5-2.3 {
339  set fd [open shell5.csv w]
340  puts $fd {"x""y",hello}
341  close $fd
342  catchcmd test.db [string trim {
343.mode csv
344CREATE TABLE t3(a, b);
345.import shell5.csv t3
346  }]
347  db eval { SELECT * FROM t3 }
348} {x\"y hello}
349
350do_test shell5-2.4 {
351  set fd [open shell5.csv w]
352  puts $fd {"xy""",hello}
353  close $fd
354  catchcmd test.db [string trim {
355.mode csv
356CREATE TABLE t4(a, b);
357.import shell5.csv t4
358  }]
359  db eval { SELECT * FROM t4 }
360} {xy\" hello}
361
362do_test shell5-2.5 {
363  set fd [open shell5.csv w]
364  puts $fd {"one","2"}
365  puts $fd {}
366  close $fd
367  catchcmd test.db [string trim {
368.mode csv
369CREATE TABLE t4(a, b);
370.import shell5.csv t4
371  }]
372  db eval { SELECT * FROM t4 }
373} {xy\" hello one 2 {} {}}
374
375
376finish_test
377