xref: /sqlite-3.40.0/test/capi3.test (revision ef5ecb41)
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