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