xref: /sqlite-3.40.0/src/test1.c (revision afa4a020)
1d1bf3512Sdrh /*
2b19a2bc6Sdrh ** 2001 September 15
3d1bf3512Sdrh **
4b19a2bc6Sdrh ** The author disclaims copyright to this source code.  In place of
5b19a2bc6Sdrh ** a legal notice, here is a blessing:
6d1bf3512Sdrh **
7b19a2bc6Sdrh **    May you do good and not evil.
8b19a2bc6Sdrh **    May you find forgiveness for yourself and forgive others.
9b19a2bc6Sdrh **    May you share freely, never taking more than you give.
10d1bf3512Sdrh **
11d1bf3512Sdrh *************************************************************************
12d1bf3512Sdrh ** Code for testing the printf() interface to SQLite.  This code
13d1bf3512Sdrh ** is not included in the SQLite library.  It is used for automated
14d1bf3512Sdrh ** testing of the SQLite library.
15d1bf3512Sdrh **
16*afa4a020Sdrh ** $Id: test1.c,v 1.4 2001/09/24 03:12:40 drh Exp $
17d1bf3512Sdrh */
18d1bf3512Sdrh #include "sqliteInt.h"
19d1bf3512Sdrh #include "tcl.h"
20d1bf3512Sdrh #include <stdlib.h>
21d1bf3512Sdrh #include <string.h>
22d1bf3512Sdrh 
23d1bf3512Sdrh /*
24d1bf3512Sdrh ** Usage:   sqlite_open filename
25d1bf3512Sdrh **
26d1bf3512Sdrh ** Returns:  The name of an open database.
27d1bf3512Sdrh */
28d1bf3512Sdrh static int sqlite_test_open(
29d1bf3512Sdrh   void *NotUsed,
30d1bf3512Sdrh   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
31d1bf3512Sdrh   int argc,              /* Number of arguments */
32d1bf3512Sdrh   char **argv            /* Text of each argument */
33d1bf3512Sdrh ){
34d1bf3512Sdrh   sqlite *db;
35d1bf3512Sdrh   char *zErr = 0;
36d1bf3512Sdrh   char zBuf[100];
37d1bf3512Sdrh   if( argc!=2 ){
38d1bf3512Sdrh     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
39d1bf3512Sdrh        " FILENAME\"", 0);
40d1bf3512Sdrh     return TCL_ERROR;
41d1bf3512Sdrh   }
42d1bf3512Sdrh   db = sqlite_open(argv[1], 0666, &zErr);
43d1bf3512Sdrh   if( db==0 ){
44d1bf3512Sdrh     Tcl_AppendResult(interp, zErr, 0);
45d1bf3512Sdrh     free(zErr);
46d1bf3512Sdrh     return TCL_ERROR;
47d1bf3512Sdrh   }
48d1bf3512Sdrh   sprintf(zBuf,"%d",(int)db);
49d1bf3512Sdrh   Tcl_AppendResult(interp, zBuf, 0);
50d1bf3512Sdrh   return TCL_OK;
51d1bf3512Sdrh }
52d1bf3512Sdrh 
53d1bf3512Sdrh /*
54d1bf3512Sdrh ** The callback routine for sqlite_exec_printf().
55d1bf3512Sdrh */
56d1bf3512Sdrh static int exec_printf_cb(void *pArg, int argc, char **argv, char **name){
57d1bf3512Sdrh   Tcl_DString *str = (Tcl_DString*)pArg;
58d1bf3512Sdrh   int i;
59d1bf3512Sdrh 
60d1bf3512Sdrh   if( Tcl_DStringLength(str)==0 ){
61d1bf3512Sdrh     for(i=0; i<argc; i++){
62d1bf3512Sdrh       Tcl_DStringAppendElement(str, name[i] ? name[i] : "NULL");
63d1bf3512Sdrh     }
64d1bf3512Sdrh   }
65d1bf3512Sdrh   for(i=0; i<argc; i++){
66d1bf3512Sdrh     Tcl_DStringAppendElement(str, argv[i] ? argv[i] : "NULL");
67d1bf3512Sdrh   }
68d1bf3512Sdrh   return 0;
69d1bf3512Sdrh }
70d1bf3512Sdrh 
71d1bf3512Sdrh /*
72d1bf3512Sdrh ** Usage:  sqlite_exec_printf  DB  FORMAT  STRING
73d1bf3512Sdrh **
74d1bf3512Sdrh ** Invoke the sqlite_exec_printf() interface using the open database
75d1bf3512Sdrh ** DB.  The SQL is the string FORMAT.  The format string should contain
76d1bf3512Sdrh ** one %s or %q.  STRING is the value inserted into %s or %q.
77d1bf3512Sdrh */
78d1bf3512Sdrh static int test_exec_printf(
79d1bf3512Sdrh   void *NotUsed,
80d1bf3512Sdrh   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
81d1bf3512Sdrh   int argc,              /* Number of arguments */
82d1bf3512Sdrh   char **argv            /* Text of each argument */
83d1bf3512Sdrh ){
84d1bf3512Sdrh   sqlite *db;
85d1bf3512Sdrh   Tcl_DString str;
86d1bf3512Sdrh   int rc;
87d1bf3512Sdrh   char *zErr = 0;
88d1bf3512Sdrh   char zBuf[30];
89d1bf3512Sdrh   if( argc!=4 ){
90d1bf3512Sdrh     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
91d1bf3512Sdrh        " DB FORMAT STRING", 0);
92d1bf3512Sdrh     return TCL_ERROR;
93d1bf3512Sdrh   }
94d1bf3512Sdrh   db = (sqlite*)atoi(argv[1]);
95d1bf3512Sdrh   Tcl_DStringInit(&str);
96d1bf3512Sdrh   rc = sqlite_exec_printf(db, argv[2], exec_printf_cb, &str, &zErr, argv[3]);
97d1bf3512Sdrh   sprintf(zBuf, "%d", rc);
98d1bf3512Sdrh   Tcl_AppendElement(interp, zBuf);
99d1bf3512Sdrh   Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr);
100d1bf3512Sdrh   Tcl_DStringFree(&str);
101d1bf3512Sdrh   if( zErr ) free(zErr);
102d1bf3512Sdrh   return TCL_OK;
103d1bf3512Sdrh }
104d1bf3512Sdrh 
105d1bf3512Sdrh /*
106d1bf3512Sdrh ** Usage:  sqlite_get_table_printf  DB  FORMAT  STRING
107d1bf3512Sdrh **
108d1bf3512Sdrh ** Invoke the sqlite_get_table_printf() interface using the open database
109d1bf3512Sdrh ** DB.  The SQL is the string FORMAT.  The format string should contain
110d1bf3512Sdrh ** one %s or %q.  STRING is the value inserted into %s or %q.
111d1bf3512Sdrh */
112d1bf3512Sdrh static int test_get_table_printf(
113d1bf3512Sdrh   void *NotUsed,
114d1bf3512Sdrh   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
115d1bf3512Sdrh   int argc,              /* Number of arguments */
116d1bf3512Sdrh   char **argv            /* Text of each argument */
117d1bf3512Sdrh ){
118d1bf3512Sdrh   sqlite *db;
119d1bf3512Sdrh   Tcl_DString str;
120d1bf3512Sdrh   int rc;
121d1bf3512Sdrh   char *zErr = 0;
122d1bf3512Sdrh   int nRow, nCol;
123d1bf3512Sdrh   char **aResult;
124d1bf3512Sdrh   int i;
125d1bf3512Sdrh   char zBuf[30];
126d1bf3512Sdrh   if( argc!=4 ){
127d1bf3512Sdrh     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
128d1bf3512Sdrh        " DB FORMAT STRING", 0);
129d1bf3512Sdrh     return TCL_ERROR;
130d1bf3512Sdrh   }
131d1bf3512Sdrh   db = (sqlite*)atoi(argv[1]);
132d1bf3512Sdrh   Tcl_DStringInit(&str);
133d1bf3512Sdrh   rc = sqlite_get_table_printf(db, argv[2], &aResult, &nRow, &nCol,
134d1bf3512Sdrh                &zErr, argv[3]);
135d1bf3512Sdrh   sprintf(zBuf, "%d", rc);
136d1bf3512Sdrh   Tcl_AppendElement(interp, zBuf);
137d1bf3512Sdrh   if( rc==SQLITE_OK ){
138d1bf3512Sdrh     sprintf(zBuf, "%d", nRow);
139d1bf3512Sdrh     Tcl_AppendElement(interp, zBuf);
140d1bf3512Sdrh     sprintf(zBuf, "%d", nCol);
141d1bf3512Sdrh     Tcl_AppendElement(interp, zBuf);
142d1bf3512Sdrh     for(i=0; i<(nRow+1)*nCol; i++){
143d1bf3512Sdrh       Tcl_AppendElement(interp, aResult[i] ? aResult[i] : "NULL");
144d1bf3512Sdrh     }
145d1bf3512Sdrh   }else{
146d1bf3512Sdrh     Tcl_AppendElement(interp, zErr);
147d1bf3512Sdrh   }
148d1bf3512Sdrh   sqlite_free_table(aResult);
149d1bf3512Sdrh   if( zErr ) free(zErr);
150d1bf3512Sdrh   return TCL_OK;
151d1bf3512Sdrh }
152d1bf3512Sdrh 
153d1bf3512Sdrh /*
154d1bf3512Sdrh ** Usage:  sqlite_close DB
155d1bf3512Sdrh **
156d1bf3512Sdrh ** Closes the database opened by sqlite_open.
157d1bf3512Sdrh */
158d1bf3512Sdrh static int sqlite_test_close(
159d1bf3512Sdrh   void *NotUsed,
160d1bf3512Sdrh   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
161d1bf3512Sdrh   int argc,              /* Number of arguments */
162d1bf3512Sdrh   char **argv            /* Text of each argument */
163d1bf3512Sdrh ){
164d1bf3512Sdrh   sqlite *db;
165d1bf3512Sdrh   if( argc!=2 ){
166d1bf3512Sdrh     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
167d1bf3512Sdrh        " FILENAME\"", 0);
168d1bf3512Sdrh     return TCL_ERROR;
169d1bf3512Sdrh   }
170d1bf3512Sdrh   db = (sqlite*)atoi(argv[1]);
171d1bf3512Sdrh   sqlite_close(db);
172d1bf3512Sdrh   return TCL_OK;
173d1bf3512Sdrh }
174d1bf3512Sdrh 
175d1bf3512Sdrh /*
176d1bf3512Sdrh ** Usage:  sqlite_mprintf_int FORMAT INTEGER INTEGER INTEGER
177d1bf3512Sdrh **
178d1bf3512Sdrh ** Call mprintf with three integer arguments
179d1bf3512Sdrh */
180d1bf3512Sdrh static int sqlite_mprintf_int(
181d1bf3512Sdrh   void *NotUsed,
182d1bf3512Sdrh   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
183d1bf3512Sdrh   int argc,              /* Number of arguments */
184d1bf3512Sdrh   char **argv            /* Text of each argument */
185d1bf3512Sdrh ){
186d1bf3512Sdrh   int a[3], i;
187d1bf3512Sdrh   char *z;
188d1bf3512Sdrh   if( argc!=5 ){
189d1bf3512Sdrh     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
190d1bf3512Sdrh        " FORMAT INT INT INT\"", 0);
191d1bf3512Sdrh     return TCL_ERROR;
192d1bf3512Sdrh   }
193d1bf3512Sdrh   for(i=2; i<5; i++){
194d1bf3512Sdrh     if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR;
195d1bf3512Sdrh   }
196d1bf3512Sdrh   z = sqlite_mprintf(argv[1], a[0], a[1], a[2]);
197d1bf3512Sdrh   Tcl_AppendResult(interp, z, 0);
198d1bf3512Sdrh   sqliteFree(z);
199d1bf3512Sdrh   return TCL_OK;
200d1bf3512Sdrh }
201d1bf3512Sdrh 
202d1bf3512Sdrh /*
203d1bf3512Sdrh ** Usage:  sqlite_mprintf_str FORMAT INTEGER INTEGER STRING
204d1bf3512Sdrh **
205d1bf3512Sdrh ** Call mprintf with two integer arguments and one string argument
206d1bf3512Sdrh */
207d1bf3512Sdrh static int sqlite_mprintf_str(
208d1bf3512Sdrh   void *NotUsed,
209d1bf3512Sdrh   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
210d1bf3512Sdrh   int argc,              /* Number of arguments */
211d1bf3512Sdrh   char **argv            /* Text of each argument */
212d1bf3512Sdrh ){
213d1bf3512Sdrh   int a[3], i;
214d1bf3512Sdrh   char *z;
215d1bf3512Sdrh   if( argc!=5 ){
216d1bf3512Sdrh     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
217d1bf3512Sdrh        " FORMAT INT INT STRING\"", 0);
218d1bf3512Sdrh     return TCL_ERROR;
219d1bf3512Sdrh   }
220d1bf3512Sdrh   for(i=2; i<4; i++){
221d1bf3512Sdrh     if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR;
222d1bf3512Sdrh   }
223d1bf3512Sdrh   z = sqlite_mprintf(argv[1], a[0], a[1], argv[4]);
224d1bf3512Sdrh   Tcl_AppendResult(interp, z, 0);
225d1bf3512Sdrh   sqliteFree(z);
226d1bf3512Sdrh   return TCL_OK;
227d1bf3512Sdrh }
228d1bf3512Sdrh 
229d1bf3512Sdrh /*
230d1bf3512Sdrh ** Usage:  sqlite_mprintf_str FORMAT INTEGER INTEGER DOUBLE
231d1bf3512Sdrh **
232d1bf3512Sdrh ** Call mprintf with two integer arguments and one double argument
233d1bf3512Sdrh */
234d1bf3512Sdrh static int sqlite_mprintf_double(
235d1bf3512Sdrh   void *NotUsed,
236d1bf3512Sdrh   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
237d1bf3512Sdrh   int argc,              /* Number of arguments */
238d1bf3512Sdrh   char **argv            /* Text of each argument */
239d1bf3512Sdrh ){
240d1bf3512Sdrh   int a[3], i;
241d1bf3512Sdrh   double r;
242d1bf3512Sdrh   char *z;
243d1bf3512Sdrh   if( argc!=5 ){
244d1bf3512Sdrh     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
245d1bf3512Sdrh        " FORMAT INT INT STRING\"", 0);
246d1bf3512Sdrh     return TCL_ERROR;
247d1bf3512Sdrh   }
248d1bf3512Sdrh   for(i=2; i<4; i++){
249d1bf3512Sdrh     if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR;
250d1bf3512Sdrh   }
251d1bf3512Sdrh   if( Tcl_GetDouble(interp, argv[4], &r) ) return TCL_ERROR;
252d1bf3512Sdrh   z = sqlite_mprintf(argv[1], a[0], a[1], r);
253d1bf3512Sdrh   Tcl_AppendResult(interp, z, 0);
254d1bf3512Sdrh   sqliteFree(z);
255d1bf3512Sdrh   return TCL_OK;
256d1bf3512Sdrh }
257d1bf3512Sdrh 
258d1bf3512Sdrh /*
259daffd0e5Sdrh ** Usage: sqlite_malloc_fail N
260daffd0e5Sdrh **
261*afa4a020Sdrh ** Rig sqliteMalloc() to fail on the N-th call.  Turn off this mechanism
262daffd0e5Sdrh ** and reset the sqlite_malloc_failed variable is N==0.
263daffd0e5Sdrh */
264daffd0e5Sdrh #ifdef MEMORY_DEBUG
265daffd0e5Sdrh static int sqlite_malloc_fail(
266daffd0e5Sdrh   void *NotUsed,
267daffd0e5Sdrh   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
268daffd0e5Sdrh   int argc,              /* Number of arguments */
269daffd0e5Sdrh   char **argv            /* Text of each argument */
270daffd0e5Sdrh ){
271daffd0e5Sdrh   int n;
272daffd0e5Sdrh   if( argc!=2 ){
273daffd0e5Sdrh     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " N\"", 0);
274daffd0e5Sdrh     return TCL_ERROR;
275daffd0e5Sdrh   }
276daffd0e5Sdrh   if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR;
277daffd0e5Sdrh   sqlite_iMallocFail = n;
278daffd0e5Sdrh   sqlite_malloc_failed = 0;
279daffd0e5Sdrh   return TCL_OK;
280daffd0e5Sdrh }
281daffd0e5Sdrh #endif
282daffd0e5Sdrh 
283daffd0e5Sdrh /*
284daffd0e5Sdrh ** Usage: sqlite_malloc_stat
285daffd0e5Sdrh **
286daffd0e5Sdrh ** Return the number of prior calls to sqliteMalloc() and sqliteFree().
287daffd0e5Sdrh */
288daffd0e5Sdrh #ifdef MEMORY_DEBUG
289daffd0e5Sdrh static int sqlite_malloc_stat(
290daffd0e5Sdrh   void *NotUsed,
291daffd0e5Sdrh   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
292daffd0e5Sdrh   int argc,              /* Number of arguments */
293daffd0e5Sdrh   char **argv            /* Text of each argument */
294daffd0e5Sdrh ){
295daffd0e5Sdrh   char zBuf[200];
296daffd0e5Sdrh   sprintf(zBuf, "%d %d %d", sqlite_nMalloc, sqlite_nFree, sqlite_iMallocFail);
297daffd0e5Sdrh   Tcl_AppendResult(interp, zBuf, 0);
298daffd0e5Sdrh   return TCL_OK;
299daffd0e5Sdrh }
300daffd0e5Sdrh #endif
301daffd0e5Sdrh 
302daffd0e5Sdrh /*
303d1bf3512Sdrh ** Register commands with the TCL interpreter.
304d1bf3512Sdrh */
305d1bf3512Sdrh int Sqlitetest1_Init(Tcl_Interp *interp){
306d1bf3512Sdrh   Tcl_CreateCommand(interp, "sqlite_mprintf_int", sqlite_mprintf_int, 0, 0);
307d1bf3512Sdrh   Tcl_CreateCommand(interp, "sqlite_mprintf_str", sqlite_mprintf_str, 0, 0);
308d1bf3512Sdrh   Tcl_CreateCommand(interp, "sqlite_mprintf_double", sqlite_mprintf_double,0,0);
309d1bf3512Sdrh   Tcl_CreateCommand(interp, "sqlite_open", sqlite_test_open, 0, 0);
310d1bf3512Sdrh   Tcl_CreateCommand(interp, "sqlite_exec_printf", test_exec_printf, 0, 0);
311d1bf3512Sdrh   Tcl_CreateCommand(interp, "sqlite_get_table_printf", test_get_table_printf,
312d1bf3512Sdrh       0, 0);
313d1bf3512Sdrh   Tcl_CreateCommand(interp, "sqlite_close", sqlite_test_close, 0, 0);
314daffd0e5Sdrh #ifdef MEMORY_DEBUG
315daffd0e5Sdrh   Tcl_CreateCommand(interp, "sqlite_malloc_fail", sqlite_malloc_fail, 0, 0);
316daffd0e5Sdrh   Tcl_CreateCommand(interp, "sqlite_malloc_stat", sqlite_malloc_stat, 0, 0);
317daffd0e5Sdrh #endif
318d1bf3512Sdrh   return TCL_OK;
319d1bf3512Sdrh }
320