xref: /sqlite-3.40.0/src/tclsqlite.c (revision dcc581cc)
175897234Sdrh /*
275897234Sdrh ** Copyright (c) 1999, 2000 D. Richard Hipp
375897234Sdrh **
475897234Sdrh ** This program is free software; you can redistribute it and/or
575897234Sdrh ** modify it under the terms of the GNU General Public
675897234Sdrh ** License as published by the Free Software Foundation; either
775897234Sdrh ** version 2 of the License, or (at your option) any later version.
875897234Sdrh **
975897234Sdrh ** This program is distributed in the hope that it will be useful,
1075897234Sdrh ** but WITHOUT ANY WARRANTY; without even the implied warranty of
1175897234Sdrh ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1275897234Sdrh ** General Public License for more details.
1375897234Sdrh **
1475897234Sdrh ** You should have received a copy of the GNU General Public
1575897234Sdrh ** License along with this library; if not, write to the
1675897234Sdrh ** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
1775897234Sdrh ** Boston, MA  02111-1307, USA.
1875897234Sdrh **
1975897234Sdrh ** Author contact information:
2075897234Sdrh **   [email protected]
2175897234Sdrh **   http://www.hwaci.com/drh/
2275897234Sdrh **
2375897234Sdrh *************************************************************************
2475897234Sdrh ** A TCL Interface to SQLite
2575897234Sdrh **
26*dcc581ccSdrh ** $Id: tclsqlite.c,v 1.3 2000/05/30 13:44:20 drh Exp $
2775897234Sdrh */
2875897234Sdrh #include "sqlite.h"
2975897234Sdrh #include <tcl.h>
3075897234Sdrh #include <stdlib.h>
3175897234Sdrh #include <string.h>
3275897234Sdrh 
3375897234Sdrh /*
3475897234Sdrh ** An instance of this structure passes information thru the sqlite
3575897234Sdrh ** logic from the original TCL command into the callback routine.
3675897234Sdrh */
3775897234Sdrh typedef struct CallbackData CallbackData;
3875897234Sdrh struct CallbackData {
3975897234Sdrh   Tcl_Interp *interp;       /* The TCL interpreter */
4075897234Sdrh   char *zArray;             /* The array into which data is written */
4175897234Sdrh   char *zCode;              /* The code to execute for each row */
4275897234Sdrh   int once;                 /* Set only for the first invocation of callback */
4375897234Sdrh };
4475897234Sdrh 
4575897234Sdrh /*
4675897234Sdrh ** Called for each row of the result.
4775897234Sdrh */
4875897234Sdrh static int DbEvalCallback(
4975897234Sdrh   void *clientData,      /* An instance of CallbackData */
5075897234Sdrh   int nCol,              /* Number of columns in the result */
5175897234Sdrh   char ** azCol,         /* Data for each column */
5275897234Sdrh   char ** azN            /* Name for each column */
5375897234Sdrh ){
5475897234Sdrh   CallbackData *cbData = (CallbackData*)clientData;
5575897234Sdrh   int i, rc;
5675897234Sdrh   if( cbData->zArray[0] ){
5775897234Sdrh     if( cbData->once ){
5875897234Sdrh       for(i=0; i<nCol; i++){
5975897234Sdrh         Tcl_SetVar2(cbData->interp, cbData->zArray, "*", azN[i],
6075897234Sdrh            TCL_LIST_ELEMENT|TCL_APPEND_VALUE);
6175897234Sdrh       }
6275897234Sdrh     }
6375897234Sdrh     for(i=0; i<nCol; i++){
6475897234Sdrh       Tcl_SetVar2(cbData->interp, cbData->zArray, azN[i], azCol[i], 0);
6575897234Sdrh     }
6675897234Sdrh   }else{
6775897234Sdrh     for(i=0; i<nCol; i++){
6875897234Sdrh       Tcl_SetVar(cbData->interp, azN[i], azCol[i], 0);
6975897234Sdrh     }
7075897234Sdrh   }
7175897234Sdrh   cbData->once = 0;
7275897234Sdrh   rc = Tcl_Eval(cbData->interp, cbData->zCode);
7375897234Sdrh   return rc;
7475897234Sdrh }
7575897234Sdrh 
7675897234Sdrh /*
7775897234Sdrh ** Called when the command is deleted.
7875897234Sdrh */
7975897234Sdrh static void DbDeleteCmd(void *db){
8075897234Sdrh   sqlite_close((sqlite*)db);
8175897234Sdrh }
8275897234Sdrh 
8375897234Sdrh /*
8475897234Sdrh ** The "sqlite" command below creates a new Tcl command for each
8575897234Sdrh ** connection it opens to an SQLite database.  This routine is invoked
8675897234Sdrh ** whenever one of those connection-specific commands is executed
8775897234Sdrh ** in Tcl.  For example, if you run Tcl code like this:
8875897234Sdrh **
8975897234Sdrh **       sqlite db1  "my_database"
9075897234Sdrh **       db1 close
9175897234Sdrh **
9275897234Sdrh ** The first command opens a connection to the "my_database" database
9375897234Sdrh ** and calls that connection "db1".  The second command causes this
9475897234Sdrh ** subroutine to be invoked.
9575897234Sdrh */
9675897234Sdrh static int DbCmd(void *cd, Tcl_Interp *interp, int argc, char **argv){
9775897234Sdrh   char *z;
9875897234Sdrh   int n, c;
9975897234Sdrh   sqlite *db = cd;
10075897234Sdrh   if( argc<2 ){
10175897234Sdrh     Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
10275897234Sdrh         " SUBCOMMAND ...\"", 0);
10375897234Sdrh     return TCL_ERROR;
10475897234Sdrh   }
10575897234Sdrh   z = argv[1];
10675897234Sdrh   n = strlen(z);
10775897234Sdrh   c = z[0];
10875897234Sdrh 
10975897234Sdrh   /*    $db close
11075897234Sdrh   **
11175897234Sdrh   ** Shutdown the database
11275897234Sdrh   */
11375897234Sdrh   if( c=='c' && n>=2 && strncmp(z,"close",n)==0 ){
11475897234Sdrh     Tcl_DeleteCommand(interp, argv[0]);
11575897234Sdrh   }else
11675897234Sdrh 
11775897234Sdrh   /*    $db complete SQL
11875897234Sdrh   **
11975897234Sdrh   ** Return TRUE if SQL is a complete SQL statement.  Return FALSE if
12075897234Sdrh   ** additional lines of input are needed.  This is similar to the
12175897234Sdrh   ** built-in "info complete" command of Tcl.
12275897234Sdrh   */
12375897234Sdrh   if( c=='c' && n>=2 && strncmp(z,"complete",n)==0 ){
12475897234Sdrh     char *zRes;
12575897234Sdrh     if( argc!=3 ){
12675897234Sdrh       Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
12775897234Sdrh           " complete SQL\"", 0);
12875897234Sdrh       return TCL_ERROR;
12975897234Sdrh     }
13075897234Sdrh     zRes = sqlite_complete(argv[2]) ? "1" : "0";
13175897234Sdrh     Tcl_SetResult(interp, zRes, TCL_VOLATILE);
13275897234Sdrh   }else
13375897234Sdrh 
13475897234Sdrh   /*
13575897234Sdrh   **    $db eval $sql ?array {  ...code... }?
13675897234Sdrh   **
13775897234Sdrh   ** The SQL statement in $sql is evaluated.  For each row, the values are
13875897234Sdrh   ** placed in elements of the array named "array" and ...code.. is executed.
13975897234Sdrh   ** If "array" and "code" are omitted, then no callback is every invoked.
14075897234Sdrh   ** If "array" is an empty string, then the values are placed in variables
14175897234Sdrh   ** that have the same name as the fields extracted by the query.
14275897234Sdrh   */
14375897234Sdrh   if( c=='e' && strncmp(z,"eval",n)==0 ){
14475897234Sdrh     CallbackData cbData;
14575897234Sdrh     char *zErrMsg;
14675897234Sdrh     int rc;
14775897234Sdrh 
14875897234Sdrh     if( argc!=5 && argc!=3 ){
14975897234Sdrh       Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
15075897234Sdrh          " eval SQL ?ARRAY-NAME CODE?", 0);
15175897234Sdrh       return TCL_ERROR;
15275897234Sdrh     }
15375897234Sdrh     if( argc==5 ){
15475897234Sdrh       cbData.interp = interp;
155*dcc581ccSdrh       cbData.once = 1;
15675897234Sdrh       cbData.zArray = argv[3];
15775897234Sdrh       cbData.zCode = argv[4];
15875897234Sdrh       zErrMsg = 0;
15975897234Sdrh       rc = sqlite_exec(db, argv[2], DbEvalCallback, &cbData, &zErrMsg);
16075897234Sdrh     }else{
16175897234Sdrh       rc = sqlite_exec(db, argv[2], 0, 0, &zErrMsg);
16275897234Sdrh     }
16375897234Sdrh     if( zErrMsg ){
16475897234Sdrh       Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE);
16575897234Sdrh       free(zErrMsg);
16675897234Sdrh     }
16775897234Sdrh     return rc;
16875897234Sdrh   }
16975897234Sdrh 
17075897234Sdrh   /* The default
17175897234Sdrh   */
17275897234Sdrh   else{
17375897234Sdrh     Tcl_AppendResult(interp,"unknown subcommand \"", z,
17475897234Sdrh         "\" - should be one of: close complete eval", 0);
17575897234Sdrh     return TCL_ERROR;
17675897234Sdrh   }
17775897234Sdrh   return TCL_OK;
17875897234Sdrh }
17975897234Sdrh 
18075897234Sdrh /*
18175897234Sdrh **   sqlite DBNAME FILENAME ?MODE?
18275897234Sdrh **
18375897234Sdrh ** This is the main Tcl command.  When the "sqlite" Tcl command is
18475897234Sdrh ** invoked, this routine runs to process that command.
18575897234Sdrh **
18675897234Sdrh ** The first argument, DBNAME, is an arbitrary name for a new
18775897234Sdrh ** database connection.  This command creates a new command named
18875897234Sdrh ** DBNAME that is used to control that connection.  The database
18975897234Sdrh ** connection is deleted when the DBNAME command is deleted.
19075897234Sdrh **
19175897234Sdrh ** The second argument is the name of the directory that contains
19275897234Sdrh ** the sqlite database that is to be accessed.
19375897234Sdrh */
19475897234Sdrh static int DbMain(void *cd, Tcl_Interp *interp, int argc, char **argv){
19575897234Sdrh   int mode;
19675897234Sdrh   sqlite *p;
19775897234Sdrh   char *zErrMsg;
19875897234Sdrh   if( argc!=3 && argc!=4 ){
19975897234Sdrh     Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
20075897234Sdrh        " HANDLE FILENAME ?MODE?\"", 0);
20175897234Sdrh     return TCL_ERROR;
20275897234Sdrh   }
20375897234Sdrh   if( argc==3 ){
20475897234Sdrh     mode = 0;
20575897234Sdrh   }else if( Tcl_GetInt(interp, argv[3], &mode)!=TCL_OK ){
20675897234Sdrh     return TCL_ERROR;
20775897234Sdrh   }
20875897234Sdrh   zErrMsg = 0;
20975897234Sdrh   p = sqlite_open(argv[2], mode, &zErrMsg);
21075897234Sdrh   if( p==0 ){
21175897234Sdrh     Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE);
21275897234Sdrh     free(zErrMsg);
21375897234Sdrh     return TCL_ERROR;
21475897234Sdrh   }
21575897234Sdrh   Tcl_CreateCommand(interp, argv[1], DbCmd, p, DbDeleteCmd);
21675897234Sdrh   return TCL_OK;
21775897234Sdrh }
21875897234Sdrh 
21975897234Sdrh /*
22075897234Sdrh ** Initialize this module.
22175897234Sdrh **
22275897234Sdrh ** This Tcl module contains only a single new Tcl command named "sqlite".
22375897234Sdrh ** (Hence there is no namespace.  There is no point in using a namespace
22475897234Sdrh ** if the extension only supplies one new name!)  The "sqlite" command is
22575897234Sdrh ** used to open a new SQLite database.  See the DbMain() routine above
22675897234Sdrh ** for additional information.
22775897234Sdrh */
22875897234Sdrh int Sqlite_Init(Tcl_Interp *interp){
22975897234Sdrh   Tcl_CreateCommand(interp, "sqlite", DbMain, 0, 0);
23075897234Sdrh   return TCL_OK;
23175897234Sdrh }
23275897234Sdrh int Sqlite_SafeInit(Tcl_Interp *interp){
23375897234Sdrh   return TCL_OK;
23475897234Sdrh }
23575897234Sdrh 
23675897234Sdrh /*
23775897234Sdrh ** If compiled using mktclapp, this routine runs to initialize
23875897234Sdrh ** everything.
23975897234Sdrh */
24075897234Sdrh int Et_AppInit(Tcl_Interp *interp){
24175897234Sdrh   return Sqlite_Init(interp);
24275897234Sdrh }
243348784efSdrh 
244348784efSdrh /*
245348784efSdrh ** If the macro TCLSH is defined and is one, then put in code for the
246348784efSdrh ** "main" routine that will initialize Tcl.
247348784efSdrh */
248348784efSdrh #if defined(TCLSH) && TCLSH==1
249348784efSdrh static char zMainloop[] =
250348784efSdrh   "set line {}\n"
251348784efSdrh   "while {![eof stdin]} {\n"
252348784efSdrh     "if {$line!=\"\"} {\n"
253348784efSdrh       "puts -nonewline \"> \"\n"
254348784efSdrh     "} else {\n"
255348784efSdrh       "puts -nonewline \"% \"\n"
256348784efSdrh     "}\n"
257348784efSdrh     "flush stdout\n"
258348784efSdrh     "append line [gets stdin]\n"
259348784efSdrh     "if {[info complete $line]} {\n"
260348784efSdrh       "if {[catch {uplevel #0 $line} result]} {\n"
261348784efSdrh         "puts stderr \"Error: $result\"\n"
262348784efSdrh       "} elseif {$result!=\"\"} {\n"
263348784efSdrh         "puts $result\n"
264348784efSdrh       "}\n"
265348784efSdrh       "set line {}\n"
266348784efSdrh     "} else {\n"
267348784efSdrh       "append line \\n\n"
268348784efSdrh     "}\n"
269348784efSdrh   "}\n"
270348784efSdrh ;
271348784efSdrh 
272348784efSdrh #define TCLSH_MAIN main   /* Needed to fake out mktclapp */
273348784efSdrh int TCLSH_MAIN(int argc, char **argv){
274348784efSdrh   Tcl_Interp *interp;
275348784efSdrh   interp = Tcl_CreateInterp();
276348784efSdrh   Sqlite_Init(interp);
277348784efSdrh   if( argc>=2 ){
278348784efSdrh     int i;
279348784efSdrh     Tcl_SetVar(interp,"argv0",argv[1],TCL_GLOBAL_ONLY);
280348784efSdrh     Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY);
281348784efSdrh     for(i=2; i<argc; i++){
282348784efSdrh       Tcl_SetVar(interp, "argv", argv[i],
283348784efSdrh           TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE);
284348784efSdrh     }
285348784efSdrh     if( Tcl_EvalFile(interp, argv[1])!=TCL_OK ){
286348784efSdrh       fprintf(stderr,"%s: %s\n", *argv,
287348784efSdrh          Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY)
288348784efSdrh       );
289348784efSdrh       return 1;
290348784efSdrh     }
291348784efSdrh   }else{
292348784efSdrh     Tcl_GlobalEval(interp, zMainloop);
293348784efSdrh   }
294348784efSdrh   return 0;
295348784efSdrh }
296348784efSdrh #endif /* TCLSH */
297