blob: 3b58df75c3cddcdf8ea7a2a31acf6609de0ff6e1 [file] [log] [blame]
drh75897232000-05-29 14:26:00 +00001/*
drhb19a2bc2001-09-16 00:13:26 +00002** 2001 September 15
drh75897232000-05-29 14:26:00 +00003**
drhb19a2bc2001-09-16 00:13:26 +00004** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
drh75897232000-05-29 14:26:00 +00006**
drhb19a2bc2001-09-16 00:13:26 +00007** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
drh75897232000-05-29 14:26:00 +000010**
11*************************************************************************
12** A TCL Interface to SQLite
13**
danielk19777ddad962005-12-12 06:53:03 +000014** $Id: tclsqlite.c,v 1.137 2005/12/12 06:53:05 danielk1977 Exp $
drh75897232000-05-29 14:26:00 +000015*/
drh6d313162000-09-21 13:01:35 +000016#ifndef NO_TCL /* Omit this whole file if TCL is unavailable */
17
drh06b27182002-06-26 20:06:05 +000018#include "sqliteInt.h"
drh895d7472004-08-20 16:02:39 +000019#include "hash.h"
drh17a68932001-01-31 13:28:08 +000020#include "tcl.h"
drh75897232000-05-29 14:26:00 +000021#include <stdlib.h>
22#include <string.h>
drhce927062001-11-09 13:41:09 +000023#include <assert.h>
drhd1e47332005-06-26 17:55:33 +000024#include <ctype.h>
drh75897232000-05-29 14:26:00 +000025
drh29bc4612005-10-05 10:40:15 +000026/*
27 * Windows needs to know which symbols to export. Unix does not.
28 * BUILD_sqlite should be undefined for Unix.
29 */
30
31#ifdef BUILD_sqlite
32#undef TCL_STORAGE_CLASS
33#define TCL_STORAGE_CLASS DLLEXPORT
34#endif /* BUILD_sqlite */
35
danielk1977a21c6b62005-01-24 10:25:59 +000036#define NUM_PREPARED_STMTS 10
drhfb7e7652005-01-24 00:28:42 +000037#define MAX_PREPARED_STMTS 100
38
drh75897232000-05-29 14:26:00 +000039/*
drh98808ba2001-10-18 12:34:46 +000040** If TCL uses UTF-8 and SQLite is configured to use iso8859, then we
41** have to do a translation when going between the two. Set the
42** UTF_TRANSLATION_NEEDED macro to indicate that we need to do
43** this translation.
44*/
45#if defined(TCL_UTF_MAX) && !defined(SQLITE_UTF8)
46# define UTF_TRANSLATION_NEEDED 1
47#endif
48
49/*
drhcabb0812002-09-14 13:47:32 +000050** New SQL functions can be created as TCL scripts. Each such function
51** is described by an instance of the following structure.
52*/
53typedef struct SqlFunc SqlFunc;
54struct SqlFunc {
55 Tcl_Interp *interp; /* The TCL interpret to execute the function */
drhd1e47332005-06-26 17:55:33 +000056 Tcl_Obj *pScript; /* The Tcl_Obj representation of the script */
57 int useEvalObjv; /* True if it is safe to use Tcl_EvalObjv */
58 char *zName; /* Name of this function */
drhcabb0812002-09-14 13:47:32 +000059 SqlFunc *pNext; /* Next function on the list of them all */
60};
61
62/*
danielk19770202b292004-06-09 09:55:16 +000063** New collation sequences function can be created as TCL scripts. Each such
64** function is described by an instance of the following structure.
65*/
66typedef struct SqlCollate SqlCollate;
67struct SqlCollate {
68 Tcl_Interp *interp; /* The TCL interpret to execute the function */
69 char *zScript; /* The script to be run */
drhd1e47332005-06-26 17:55:33 +000070 SqlCollate *pNext; /* Next function on the list of them all */
danielk19770202b292004-06-09 09:55:16 +000071};
72
73/*
drhfb7e7652005-01-24 00:28:42 +000074** Prepared statements are cached for faster execution. Each prepared
75** statement is described by an instance of the following structure.
76*/
77typedef struct SqlPreparedStmt SqlPreparedStmt;
78struct SqlPreparedStmt {
79 SqlPreparedStmt *pNext; /* Next in linked list */
80 SqlPreparedStmt *pPrev; /* Previous on the list */
81 sqlite3_stmt *pStmt; /* The prepared statement */
82 int nSql; /* chars in zSql[] */
83 char zSql[1]; /* Text of the SQL statement */
84};
85
86/*
drhbec3f402000-08-04 13:49:02 +000087** There is one instance of this structure for each SQLite database
88** that has been opened by the SQLite TCL interface.
89*/
90typedef struct SqliteDb SqliteDb;
91struct SqliteDb {
drhd1e47332005-06-26 17:55:33 +000092 sqlite3 *db; /* The "real" database structure */
93 Tcl_Interp *interp; /* The interpreter used for this database */
94 char *zBusy; /* The busy callback routine */
95 char *zCommit; /* The commit hook callback routine */
96 char *zTrace; /* The trace callback routine */
drh19e2d372005-08-29 23:00:03 +000097 char *zProfile; /* The profile callback routine */
drhd1e47332005-06-26 17:55:33 +000098 char *zProgress; /* The progress callback routine */
99 char *zAuth; /* The authorization callback routine */
100 char *zNull; /* Text to substitute for an SQL NULL value */
101 SqlFunc *pFunc; /* List of SQL functions */
102 SqlCollate *pCollate; /* List of SQL collation functions */
103 int rc; /* Return code of most recent sqlite3_exec() */
104 Tcl_Obj *pCollateNeeded; /* Collation needed script */
drhfb7e7652005-01-24 00:28:42 +0000105 SqlPreparedStmt *stmtList; /* List of prepared statements*/
106 SqlPreparedStmt *stmtLast; /* Last statement in the list */
107 int maxStmt; /* The next maximum number of stmtList */
108 int nStmt; /* Number of statements in stmtList */
drh98808ba2001-10-18 12:34:46 +0000109};
drh297ecf12001-04-05 15:57:13 +0000110
drh6d313162000-09-21 13:01:35 +0000111/*
drhd1e47332005-06-26 17:55:33 +0000112** Look at the script prefix in pCmd. We will be executing this script
113** after first appending one or more arguments. This routine analyzes
114** the script to see if it is safe to use Tcl_EvalObjv() on the script
115** rather than the more general Tcl_EvalEx(). Tcl_EvalObjv() is much
116** faster.
117**
118** Scripts that are safe to use with Tcl_EvalObjv() consists of a
119** command name followed by zero or more arguments with no [...] or $
120** or {...} or ; to be seen anywhere. Most callback scripts consist
121** of just a single procedure name and they meet this requirement.
122*/
123static int safeToUseEvalObjv(Tcl_Interp *interp, Tcl_Obj *pCmd){
124 /* We could try to do something with Tcl_Parse(). But we will instead
125 ** just do a search for forbidden characters. If any of the forbidden
126 ** characters appear in pCmd, we will report the string as unsafe.
127 */
128 const char *z;
129 int n;
130 z = Tcl_GetStringFromObj(pCmd, &n);
131 while( n-- > 0 ){
132 int c = *(z++);
133 if( c=='$' || c=='[' || c==';' ) return 0;
134 }
135 return 1;
136}
137
138/*
139** Find an SqlFunc structure with the given name. Or create a new
140** one if an existing one cannot be found. Return a pointer to the
141** structure.
142*/
143static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){
144 SqlFunc *p, *pNew;
145 int i;
146 pNew = (SqlFunc*)Tcl_Alloc( sizeof(*pNew) + strlen(zName) + 1 );
147 pNew->zName = (char*)&pNew[1];
148 for(i=0; zName[i]; i++){ pNew->zName[i] = tolower(zName[i]); }
149 pNew->zName[i] = 0;
150 for(p=pDb->pFunc; p; p=p->pNext){
151 if( strcmp(p->zName, pNew->zName)==0 ){
152 Tcl_Free((char*)pNew);
153 return p;
154 }
155 }
156 pNew->interp = pDb->interp;
157 pNew->pScript = 0;
158 pNew->pNext = pDb->pFunc;
159 pDb->pFunc = pNew;
160 return pNew;
161}
162
163/*
drhfb7e7652005-01-24 00:28:42 +0000164** Finalize and free a list of prepared statements
165*/
166static void flushStmtCache( SqliteDb *pDb ){
167 SqlPreparedStmt *pPreStmt;
168
169 while( pDb->stmtList ){
170 sqlite3_finalize( pDb->stmtList->pStmt );
171 pPreStmt = pDb->stmtList;
172 pDb->stmtList = pDb->stmtList->pNext;
173 Tcl_Free( (char*)pPreStmt );
174 }
175 pDb->nStmt = 0;
176 pDb->stmtLast = 0;
177}
178
179/*
drh895d7472004-08-20 16:02:39 +0000180** TCL calls this procedure when an sqlite3 database command is
181** deleted.
drh75897232000-05-29 14:26:00 +0000182*/
183static void DbDeleteCmd(void *db){
drhbec3f402000-08-04 13:49:02 +0000184 SqliteDb *pDb = (SqliteDb*)db;
drhfb7e7652005-01-24 00:28:42 +0000185 flushStmtCache(pDb);
danielk19776f8a5032004-05-10 10:34:51 +0000186 sqlite3_close(pDb->db);
drhcabb0812002-09-14 13:47:32 +0000187 while( pDb->pFunc ){
188 SqlFunc *pFunc = pDb->pFunc;
189 pDb->pFunc = pFunc->pNext;
drhd1e47332005-06-26 17:55:33 +0000190 Tcl_DecrRefCount(pFunc->pScript);
drhcabb0812002-09-14 13:47:32 +0000191 Tcl_Free((char*)pFunc);
192 }
danielk19770202b292004-06-09 09:55:16 +0000193 while( pDb->pCollate ){
194 SqlCollate *pCollate = pDb->pCollate;
195 pDb->pCollate = pCollate->pNext;
196 Tcl_Free((char*)pCollate);
197 }
drhbec3f402000-08-04 13:49:02 +0000198 if( pDb->zBusy ){
199 Tcl_Free(pDb->zBusy);
200 }
drhb5a20d32003-04-23 12:25:23 +0000201 if( pDb->zTrace ){
202 Tcl_Free(pDb->zTrace);
drh0d1a6432003-04-03 15:46:04 +0000203 }
drh19e2d372005-08-29 23:00:03 +0000204 if( pDb->zProfile ){
205 Tcl_Free(pDb->zProfile);
206 }
drhe22a3342003-04-22 20:30:37 +0000207 if( pDb->zAuth ){
208 Tcl_Free(pDb->zAuth);
209 }
danielk197755c45f22005-04-03 23:54:43 +0000210 if( pDb->zNull ){
211 Tcl_Free(pDb->zNull);
212 }
drhbec3f402000-08-04 13:49:02 +0000213 Tcl_Free((char*)pDb);
214}
215
216/*
217** This routine is called when a database file is locked while trying
218** to execute SQL.
219*/
danielk19772a764eb2004-06-12 01:43:26 +0000220static int DbBusyHandler(void *cd, int nTries){
drhbec3f402000-08-04 13:49:02 +0000221 SqliteDb *pDb = (SqliteDb*)cd;
222 int rc;
223 char zVal[30];
drhbec3f402000-08-04 13:49:02 +0000224
danielk19772a764eb2004-06-12 01:43:26 +0000225 sprintf(zVal, "%d", nTries);
drhd1e47332005-06-26 17:55:33 +0000226 rc = Tcl_VarEval(pDb->interp, pDb->zBusy, " ", zVal, (char*)0);
drhbec3f402000-08-04 13:49:02 +0000227 if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
228 return 0;
229 }
230 return 1;
drh75897232000-05-29 14:26:00 +0000231}
232
233/*
danielk1977348bb5d2003-10-18 09:37:26 +0000234** This routine is invoked as the 'progress callback' for the database.
235*/
236static int DbProgressHandler(void *cd){
237 SqliteDb *pDb = (SqliteDb*)cd;
238 int rc;
239
240 assert( pDb->zProgress );
241 rc = Tcl_Eval(pDb->interp, pDb->zProgress);
242 if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
243 return 1;
244 }
245 return 0;
246}
247
248/*
drhb5a20d32003-04-23 12:25:23 +0000249** This routine is called by the SQLite trace handler whenever a new
250** block of SQL is executed. The TCL script in pDb->zTrace is executed.
drh0d1a6432003-04-03 15:46:04 +0000251*/
drhb5a20d32003-04-23 12:25:23 +0000252static void DbTraceHandler(void *cd, const char *zSql){
drh0d1a6432003-04-03 15:46:04 +0000253 SqliteDb *pDb = (SqliteDb*)cd;
drhb5a20d32003-04-23 12:25:23 +0000254 Tcl_DString str;
drh0d1a6432003-04-03 15:46:04 +0000255
drhb5a20d32003-04-23 12:25:23 +0000256 Tcl_DStringInit(&str);
257 Tcl_DStringAppend(&str, pDb->zTrace, -1);
258 Tcl_DStringAppendElement(&str, zSql);
259 Tcl_Eval(pDb->interp, Tcl_DStringValue(&str));
260 Tcl_DStringFree(&str);
261 Tcl_ResetResult(pDb->interp);
drh0d1a6432003-04-03 15:46:04 +0000262}
263
264/*
drh19e2d372005-08-29 23:00:03 +0000265** This routine is called by the SQLite profile handler after a statement
266** SQL has executed. The TCL script in pDb->zProfile is evaluated.
267*/
268static void DbProfileHandler(void *cd, const char *zSql, sqlite_uint64 tm){
269 SqliteDb *pDb = (SqliteDb*)cd;
270 Tcl_DString str;
271 char zTm[100];
272
273 sqlite3_snprintf(sizeof(zTm)-1, zTm, "%lld", tm);
274 Tcl_DStringInit(&str);
275 Tcl_DStringAppend(&str, pDb->zProfile, -1);
276 Tcl_DStringAppendElement(&str, zSql);
277 Tcl_DStringAppendElement(&str, zTm);
278 Tcl_Eval(pDb->interp, Tcl_DStringValue(&str));
279 Tcl_DStringFree(&str);
280 Tcl_ResetResult(pDb->interp);
281}
282
283/*
drhaa940ea2004-01-15 02:44:03 +0000284** This routine is called when a transaction is committed. The
285** TCL script in pDb->zCommit is executed. If it returns non-zero or
286** if it throws an exception, the transaction is rolled back instead
287** of being committed.
288*/
289static int DbCommitHandler(void *cd){
290 SqliteDb *pDb = (SqliteDb*)cd;
291 int rc;
292
293 rc = Tcl_Eval(pDb->interp, pDb->zCommit);
294 if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
295 return 1;
296 }
297 return 0;
298}
299
danielk19777cedc8d2004-06-10 10:50:08 +0000300static void tclCollateNeeded(
301 void *pCtx,
drh9bb575f2004-09-06 17:24:11 +0000302 sqlite3 *db,
danielk19777cedc8d2004-06-10 10:50:08 +0000303 int enc,
304 const char *zName
305){
306 SqliteDb *pDb = (SqliteDb *)pCtx;
307 Tcl_Obj *pScript = Tcl_DuplicateObj(pDb->pCollateNeeded);
308 Tcl_IncrRefCount(pScript);
309 Tcl_ListObjAppendElement(0, pScript, Tcl_NewStringObj(zName, -1));
310 Tcl_EvalObjEx(pDb->interp, pScript, 0);
311 Tcl_DecrRefCount(pScript);
312}
313
drhaa940ea2004-01-15 02:44:03 +0000314/*
danielk19770202b292004-06-09 09:55:16 +0000315** This routine is called to evaluate an SQL collation function implemented
316** using TCL script.
317*/
318static int tclSqlCollate(
319 void *pCtx,
320 int nA,
321 const void *zA,
322 int nB,
323 const void *zB
324){
325 SqlCollate *p = (SqlCollate *)pCtx;
326 Tcl_Obj *pCmd;
327
328 pCmd = Tcl_NewStringObj(p->zScript, -1);
329 Tcl_IncrRefCount(pCmd);
330 Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zA, nA));
331 Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zB, nB));
drhd1e47332005-06-26 17:55:33 +0000332 Tcl_EvalObjEx(p->interp, pCmd, TCL_EVAL_DIRECT);
danielk19770202b292004-06-09 09:55:16 +0000333 Tcl_DecrRefCount(pCmd);
334 return (atoi(Tcl_GetStringResult(p->interp)));
335}
336
337/*
drhcabb0812002-09-14 13:47:32 +0000338** This routine is called to evaluate an SQL function implemented
339** using TCL script.
340*/
drhfb7e7652005-01-24 00:28:42 +0000341static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
danielk19776f8a5032004-05-10 10:34:51 +0000342 SqlFunc *p = sqlite3_user_data(context);
drhd1e47332005-06-26 17:55:33 +0000343 Tcl_Obj *pCmd;
drhcabb0812002-09-14 13:47:32 +0000344 int i;
345 int rc;
346
drhd1e47332005-06-26 17:55:33 +0000347 if( argc==0 ){
348 /* If there are no arguments to the function, call Tcl_EvalObjEx on the
349 ** script object directly. This allows the TCL compiler to generate
350 ** bytecode for the command on the first invocation and thus make
351 ** subsequent invocations much faster. */
352 pCmd = p->pScript;
353 Tcl_IncrRefCount(pCmd);
354 rc = Tcl_EvalObjEx(p->interp, pCmd, 0);
355 Tcl_DecrRefCount(pCmd);
356 }else{
357 /* If there are arguments to the function, make a shallow copy of the
358 ** script object, lappend the arguments, then evaluate the copy.
359 **
360 ** By "shallow" copy, we mean a only the outer list Tcl_Obj is duplicated.
361 ** The new Tcl_Obj contains pointers to the original list elements.
362 ** That way, when Tcl_EvalObjv() is run and shimmers the first element
363 ** of the list to tclCmdNameType, that alternate representation will
364 ** be preserved and reused on the next invocation.
365 */
366 Tcl_Obj **aArg;
367 int nArg;
368 if( Tcl_ListObjGetElements(p->interp, p->pScript, &nArg, &aArg) ){
369 sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
370 return;
371 }
372 pCmd = Tcl_NewListObj(nArg, aArg);
373 Tcl_IncrRefCount(pCmd);
374 for(i=0; i<argc; i++){
375 sqlite3_value *pIn = argv[i];
376 Tcl_Obj *pVal;
377
378 /* Set pVal to contain the i'th column of this row. */
379 switch( sqlite3_value_type(pIn) ){
380 case SQLITE_BLOB: {
381 int bytes = sqlite3_value_bytes(pIn);
382 pVal = Tcl_NewByteArrayObj(sqlite3_value_blob(pIn), bytes);
383 break;
384 }
385 case SQLITE_INTEGER: {
386 sqlite_int64 v = sqlite3_value_int64(pIn);
387 if( v>=-2147483647 && v<=2147483647 ){
388 pVal = Tcl_NewIntObj(v);
389 }else{
390 pVal = Tcl_NewWideIntObj(v);
391 }
392 break;
393 }
394 case SQLITE_FLOAT: {
395 double r = sqlite3_value_double(pIn);
396 pVal = Tcl_NewDoubleObj(r);
397 break;
398 }
399 case SQLITE_NULL: {
400 pVal = Tcl_NewStringObj("", 0);
401 break;
402 }
403 default: {
404 int bytes = sqlite3_value_bytes(pIn);
danielk197700fd9572005-12-07 06:27:43 +0000405 pVal = Tcl_NewStringObj((char *)sqlite3_value_text(pIn), bytes);
drhd1e47332005-06-26 17:55:33 +0000406 break;
407 }
408 }
409 rc = Tcl_ListObjAppendElement(p->interp, pCmd, pVal);
410 if( rc ){
411 Tcl_DecrRefCount(pCmd);
412 sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
413 return;
414 }
danielk197751ad0ec2004-05-24 12:39:02 +0000415 }
drhd1e47332005-06-26 17:55:33 +0000416 if( !p->useEvalObjv ){
417 /* Tcl_EvalObjEx() will automatically call Tcl_EvalObjv() if pCmd
418 ** is a list without a string representation. To prevent this from
419 ** happening, make sure pCmd has a valid string representation */
420 Tcl_GetString(pCmd);
421 }
422 rc = Tcl_EvalObjEx(p->interp, pCmd, TCL_EVAL_DIRECT);
423 Tcl_DecrRefCount(pCmd);
drhcabb0812002-09-14 13:47:32 +0000424 }
danielk1977562e8d32005-05-20 09:40:55 +0000425
drhc7f269d2005-05-05 10:30:29 +0000426 if( rc && rc!=TCL_RETURN ){
danielk19777e18c252004-05-25 11:47:24 +0000427 sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
drhcabb0812002-09-14 13:47:32 +0000428 }else{
drhc7f269d2005-05-05 10:30:29 +0000429 Tcl_Obj *pVar = Tcl_GetObjResult(p->interp);
430 int n;
431 u8 *data;
432 char *zType = pVar->typePtr ? pVar->typePtr->name : "";
433 char c = zType[0];
drhdf0bdda2005-06-25 19:31:48 +0000434 if( c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0 ){
drhd1e47332005-06-26 17:55:33 +0000435 /* Only return a BLOB type if the Tcl variable is a bytearray and
drhdf0bdda2005-06-25 19:31:48 +0000436 ** has no string representation. */
drhc7f269d2005-05-05 10:30:29 +0000437 data = Tcl_GetByteArrayFromObj(pVar, &n);
438 sqlite3_result_blob(context, data, n, SQLITE_TRANSIENT);
drhc7f269d2005-05-05 10:30:29 +0000439 }else if( (c=='b' && strcmp(zType,"boolean")==0) ||
440 (c=='i' && strcmp(zType,"int")==0) ){
441 Tcl_GetIntFromObj(0, pVar, &n);
442 sqlite3_result_int(context, n);
443 }else if( c=='d' && strcmp(zType,"double")==0 ){
444 double r;
445 Tcl_GetDoubleFromObj(0, pVar, &r);
446 sqlite3_result_double(context, r);
drhdf0bdda2005-06-25 19:31:48 +0000447 }else if( c=='w' && strcmp(zType,"wideInt")==0 ){
448 Tcl_WideInt v;
449 Tcl_GetWideIntFromObj(0, pVar, &v);
450 sqlite3_result_int64(context, v);
drhc7f269d2005-05-05 10:30:29 +0000451 }else{
danielk197700fd9572005-12-07 06:27:43 +0000452 data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n);
453 sqlite3_result_text(context, (char *)data, n, SQLITE_TRANSIENT);
drhc7f269d2005-05-05 10:30:29 +0000454 }
drhcabb0812002-09-14 13:47:32 +0000455 }
456}
drh895d7472004-08-20 16:02:39 +0000457
drhe22a3342003-04-22 20:30:37 +0000458#ifndef SQLITE_OMIT_AUTHORIZATION
459/*
460** This is the authentication function. It appends the authentication
461** type code and the two arguments to zCmd[] then invokes the result
462** on the interpreter. The reply is examined to determine if the
463** authentication fails or succeeds.
464*/
465static int auth_callback(
466 void *pArg,
467 int code,
468 const char *zArg1,
469 const char *zArg2,
470 const char *zArg3,
471 const char *zArg4
472){
473 char *zCode;
474 Tcl_DString str;
475 int rc;
476 const char *zReply;
477 SqliteDb *pDb = (SqliteDb*)pArg;
478
479 switch( code ){
480 case SQLITE_COPY : zCode="SQLITE_COPY"; break;
481 case SQLITE_CREATE_INDEX : zCode="SQLITE_CREATE_INDEX"; break;
482 case SQLITE_CREATE_TABLE : zCode="SQLITE_CREATE_TABLE"; break;
483 case SQLITE_CREATE_TEMP_INDEX : zCode="SQLITE_CREATE_TEMP_INDEX"; break;
484 case SQLITE_CREATE_TEMP_TABLE : zCode="SQLITE_CREATE_TEMP_TABLE"; break;
485 case SQLITE_CREATE_TEMP_TRIGGER: zCode="SQLITE_CREATE_TEMP_TRIGGER"; break;
486 case SQLITE_CREATE_TEMP_VIEW : zCode="SQLITE_CREATE_TEMP_VIEW"; break;
487 case SQLITE_CREATE_TRIGGER : zCode="SQLITE_CREATE_TRIGGER"; break;
488 case SQLITE_CREATE_VIEW : zCode="SQLITE_CREATE_VIEW"; break;
489 case SQLITE_DELETE : zCode="SQLITE_DELETE"; break;
490 case SQLITE_DROP_INDEX : zCode="SQLITE_DROP_INDEX"; break;
491 case SQLITE_DROP_TABLE : zCode="SQLITE_DROP_TABLE"; break;
492 case SQLITE_DROP_TEMP_INDEX : zCode="SQLITE_DROP_TEMP_INDEX"; break;
493 case SQLITE_DROP_TEMP_TABLE : zCode="SQLITE_DROP_TEMP_TABLE"; break;
494 case SQLITE_DROP_TEMP_TRIGGER : zCode="SQLITE_DROP_TEMP_TRIGGER"; break;
495 case SQLITE_DROP_TEMP_VIEW : zCode="SQLITE_DROP_TEMP_VIEW"; break;
496 case SQLITE_DROP_TRIGGER : zCode="SQLITE_DROP_TRIGGER"; break;
497 case SQLITE_DROP_VIEW : zCode="SQLITE_DROP_VIEW"; break;
498 case SQLITE_INSERT : zCode="SQLITE_INSERT"; break;
499 case SQLITE_PRAGMA : zCode="SQLITE_PRAGMA"; break;
500 case SQLITE_READ : zCode="SQLITE_READ"; break;
501 case SQLITE_SELECT : zCode="SQLITE_SELECT"; break;
502 case SQLITE_TRANSACTION : zCode="SQLITE_TRANSACTION"; break;
503 case SQLITE_UPDATE : zCode="SQLITE_UPDATE"; break;
drh81e293b2003-06-06 19:00:42 +0000504 case SQLITE_ATTACH : zCode="SQLITE_ATTACH"; break;
505 case SQLITE_DETACH : zCode="SQLITE_DETACH"; break;
danielk19771c8c23c2004-11-12 15:53:37 +0000506 case SQLITE_ALTER_TABLE : zCode="SQLITE_ALTER_TABLE"; break;
danielk19771d54df82004-11-23 15:41:16 +0000507 case SQLITE_REINDEX : zCode="SQLITE_REINDEX"; break;
drhe6e04962005-07-23 02:17:03 +0000508 case SQLITE_ANALYZE : zCode="SQLITE_ANALYZE"; break;
drhe22a3342003-04-22 20:30:37 +0000509 default : zCode="????"; break;
510 }
511 Tcl_DStringInit(&str);
512 Tcl_DStringAppend(&str, pDb->zAuth, -1);
513 Tcl_DStringAppendElement(&str, zCode);
514 Tcl_DStringAppendElement(&str, zArg1 ? zArg1 : "");
515 Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : "");
516 Tcl_DStringAppendElement(&str, zArg3 ? zArg3 : "");
517 Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : "");
518 rc = Tcl_GlobalEval(pDb->interp, Tcl_DStringValue(&str));
519 Tcl_DStringFree(&str);
520 zReply = Tcl_GetStringResult(pDb->interp);
521 if( strcmp(zReply,"SQLITE_OK")==0 ){
522 rc = SQLITE_OK;
523 }else if( strcmp(zReply,"SQLITE_DENY")==0 ){
524 rc = SQLITE_DENY;
525 }else if( strcmp(zReply,"SQLITE_IGNORE")==0 ){
526 rc = SQLITE_IGNORE;
527 }else{
528 rc = 999;
529 }
530 return rc;
531}
532#endif /* SQLITE_OMIT_AUTHORIZATION */
drhcabb0812002-09-14 13:47:32 +0000533
534/*
danielk1977ef2cb632004-05-29 02:37:19 +0000535** zText is a pointer to text obtained via an sqlite3_result_text()
536** or similar interface. This routine returns a Tcl string object,
537** reference count set to 0, containing the text. If a translation
538** between iso8859 and UTF-8 is required, it is preformed.
539*/
540static Tcl_Obj *dbTextToObj(char const *zText){
541 Tcl_Obj *pVal;
542#ifdef UTF_TRANSLATION_NEEDED
543 Tcl_DString dCol;
544 Tcl_DStringInit(&dCol);
545 Tcl_ExternalToUtfDString(NULL, zText, -1, &dCol);
546 pVal = Tcl_NewStringObj(Tcl_DStringValue(&dCol), -1);
547 Tcl_DStringFree(&dCol);
548#else
549 pVal = Tcl_NewStringObj(zText, -1);
550#endif
551 return pVal;
552}
553
554/*
tpoindex1067fe12004-12-17 15:41:11 +0000555** This routine reads a line of text from FILE in, stores
556** the text in memory obtained from malloc() and returns a pointer
557** to the text. NULL is returned at end of file, or if malloc()
558** fails.
559**
560** The interface is like "readline" but no command-line editing
561** is done.
562**
563** copied from shell.c from '.import' command
564*/
565static char *local_getline(char *zPrompt, FILE *in){
566 char *zLine;
567 int nLine;
568 int n;
569 int eol;
570
571 nLine = 100;
572 zLine = malloc( nLine );
573 if( zLine==0 ) return 0;
574 n = 0;
575 eol = 0;
576 while( !eol ){
577 if( n+100>nLine ){
578 nLine = nLine*2 + 100;
579 zLine = realloc(zLine, nLine);
580 if( zLine==0 ) return 0;
581 }
582 if( fgets(&zLine[n], nLine - n, in)==0 ){
583 if( n==0 ){
584 free(zLine);
585 return 0;
586 }
587 zLine[n] = 0;
588 eol = 1;
589 break;
590 }
591 while( zLine[n] ){ n++; }
592 if( n>0 && zLine[n-1]=='\n' ){
593 n--;
594 zLine[n] = 0;
595 eol = 1;
596 }
597 }
598 zLine = realloc( zLine, n+1 );
599 return zLine;
600}
601
602/*
drh75897232000-05-29 14:26:00 +0000603** The "sqlite" command below creates a new Tcl command for each
604** connection it opens to an SQLite database. This routine is invoked
605** whenever one of those connection-specific commands is executed
606** in Tcl. For example, if you run Tcl code like this:
607**
drh9bb575f2004-09-06 17:24:11 +0000608** sqlite3 db1 "my_database"
drh75897232000-05-29 14:26:00 +0000609** db1 close
610**
611** The first command opens a connection to the "my_database" database
612** and calls that connection "db1". The second command causes this
613** subroutine to be invoked.
614*/
drh6d313162000-09-21 13:01:35 +0000615static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
drhbec3f402000-08-04 13:49:02 +0000616 SqliteDb *pDb = (SqliteDb*)cd;
drh6d313162000-09-21 13:01:35 +0000617 int choice;
drh22fbcb82004-02-01 01:22:50 +0000618 int rc = TCL_OK;
drh0de8c112002-07-06 16:32:14 +0000619 static const char *DB_strs[] = {
drhfb7e7652005-01-24 00:28:42 +0000620 "authorizer", "busy", "cache",
621 "changes", "close", "collate",
622 "collation_needed", "commit_hook", "complete",
623 "copy", "errorcode", "eval",
drh97f2ebc2005-12-10 21:19:04 +0000624 "exists", "function", "last_insert_rowid",
625 "nullvalue", "onecolumn", "profile",
danielk19777ddad962005-12-12 06:53:03 +0000626 "progress", "rekey", "soft_heap_limit",
627 "timeout", "total_changes", "trace",
628 "transaction", "version", 0
drh6d313162000-09-21 13:01:35 +0000629 };
drh411995d2002-06-25 19:31:18 +0000630 enum DB_enum {
drhfb7e7652005-01-24 00:28:42 +0000631 DB_AUTHORIZER, DB_BUSY, DB_CACHE,
632 DB_CHANGES, DB_CLOSE, DB_COLLATE,
633 DB_COLLATION_NEEDED, DB_COMMIT_HOOK, DB_COMPLETE,
634 DB_COPY, DB_ERRORCODE, DB_EVAL,
drh97f2ebc2005-12-10 21:19:04 +0000635 DB_EXISTS, DB_FUNCTION, DB_LAST_INSERT_ROWID,
636 DB_NULLVALUE, DB_ONECOLUMN, DB_PROFILE,
danielk19777ddad962005-12-12 06:53:03 +0000637 DB_PROGRESS, DB_REKEY, DB_SOFT_HEAP_LIMIT,
638 DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE,
639 DB_TRANSACTION, DB_VERSION
drh6d313162000-09-21 13:01:35 +0000640 };
tpoindex1067fe12004-12-17 15:41:11 +0000641 /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */
drh6d313162000-09-21 13:01:35 +0000642
643 if( objc<2 ){
644 Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");
drh75897232000-05-29 14:26:00 +0000645 return TCL_ERROR;
646 }
drh411995d2002-06-25 19:31:18 +0000647 if( Tcl_GetIndexFromObj(interp, objv[1], DB_strs, "option", 0, &choice) ){
drh6d313162000-09-21 13:01:35 +0000648 return TCL_ERROR;
649 }
650
drh411995d2002-06-25 19:31:18 +0000651 switch( (enum DB_enum)choice ){
drh75897232000-05-29 14:26:00 +0000652
drhe22a3342003-04-22 20:30:37 +0000653 /* $db authorizer ?CALLBACK?
654 **
655 ** Invoke the given callback to authorize each SQL operation as it is
656 ** compiled. 5 arguments are appended to the callback before it is
657 ** invoked:
658 **
659 ** (1) The authorization type (ex: SQLITE_CREATE_TABLE, SQLITE_INSERT, ...)
660 ** (2) First descriptive name (depends on authorization type)
661 ** (3) Second descriptive name
662 ** (4) Name of the database (ex: "main", "temp")
663 ** (5) Name of trigger that is doing the access
664 **
665 ** The callback should return on of the following strings: SQLITE_OK,
666 ** SQLITE_IGNORE, or SQLITE_DENY. Any other return value is an error.
667 **
668 ** If this method is invoked with no arguments, the current authorization
669 ** callback string is returned.
670 */
671 case DB_AUTHORIZER: {
drh1211de32004-07-26 12:24:22 +0000672#ifdef SQLITE_OMIT_AUTHORIZATION
673 Tcl_AppendResult(interp, "authorization not available in this build", 0);
674 return TCL_ERROR;
675#else
drhe22a3342003-04-22 20:30:37 +0000676 if( objc>3 ){
677 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
drh0f14e2e2004-06-29 12:39:08 +0000678 return TCL_ERROR;
drhe22a3342003-04-22 20:30:37 +0000679 }else if( objc==2 ){
drhb5a20d32003-04-23 12:25:23 +0000680 if( pDb->zAuth ){
drhe22a3342003-04-22 20:30:37 +0000681 Tcl_AppendResult(interp, pDb->zAuth, 0);
682 }
683 }else{
684 char *zAuth;
685 int len;
686 if( pDb->zAuth ){
687 Tcl_Free(pDb->zAuth);
688 }
689 zAuth = Tcl_GetStringFromObj(objv[2], &len);
690 if( zAuth && len>0 ){
691 pDb->zAuth = Tcl_Alloc( len + 1 );
692 strcpy(pDb->zAuth, zAuth);
693 }else{
694 pDb->zAuth = 0;
695 }
drhe22a3342003-04-22 20:30:37 +0000696 if( pDb->zAuth ){
697 pDb->interp = interp;
danielk19776f8a5032004-05-10 10:34:51 +0000698 sqlite3_set_authorizer(pDb->db, auth_callback, pDb);
drhe22a3342003-04-22 20:30:37 +0000699 }else{
danielk19776f8a5032004-05-10 10:34:51 +0000700 sqlite3_set_authorizer(pDb->db, 0, 0);
drhe22a3342003-04-22 20:30:37 +0000701 }
drhe22a3342003-04-22 20:30:37 +0000702 }
drh1211de32004-07-26 12:24:22 +0000703#endif
drhe22a3342003-04-22 20:30:37 +0000704 break;
705 }
706
drhbec3f402000-08-04 13:49:02 +0000707 /* $db busy ?CALLBACK?
708 **
709 ** Invoke the given callback if an SQL statement attempts to open
710 ** a locked database file.
711 */
drh6d313162000-09-21 13:01:35 +0000712 case DB_BUSY: {
713 if( objc>3 ){
714 Tcl_WrongNumArgs(interp, 2, objv, "CALLBACK");
drhbec3f402000-08-04 13:49:02 +0000715 return TCL_ERROR;
drh6d313162000-09-21 13:01:35 +0000716 }else if( objc==2 ){
drhbec3f402000-08-04 13:49:02 +0000717 if( pDb->zBusy ){
718 Tcl_AppendResult(interp, pDb->zBusy, 0);
719 }
720 }else{
drh6d313162000-09-21 13:01:35 +0000721 char *zBusy;
722 int len;
drhbec3f402000-08-04 13:49:02 +0000723 if( pDb->zBusy ){
724 Tcl_Free(pDb->zBusy);
drhbec3f402000-08-04 13:49:02 +0000725 }
drh6d313162000-09-21 13:01:35 +0000726 zBusy = Tcl_GetStringFromObj(objv[2], &len);
727 if( zBusy && len>0 ){
728 pDb->zBusy = Tcl_Alloc( len + 1 );
729 strcpy(pDb->zBusy, zBusy);
730 }else{
731 pDb->zBusy = 0;
drhbec3f402000-08-04 13:49:02 +0000732 }
733 if( pDb->zBusy ){
734 pDb->interp = interp;
danielk19776f8a5032004-05-10 10:34:51 +0000735 sqlite3_busy_handler(pDb->db, DbBusyHandler, pDb);
drh6d313162000-09-21 13:01:35 +0000736 }else{
danielk19776f8a5032004-05-10 10:34:51 +0000737 sqlite3_busy_handler(pDb->db, 0, 0);
drhbec3f402000-08-04 13:49:02 +0000738 }
739 }
drh6d313162000-09-21 13:01:35 +0000740 break;
741 }
drhbec3f402000-08-04 13:49:02 +0000742
drhfb7e7652005-01-24 00:28:42 +0000743 /* $db cache flush
744 ** $db cache size n
745 **
746 ** Flush the prepared statement cache, or set the maximum number of
747 ** cached statements.
748 */
749 case DB_CACHE: {
750 char *subCmd;
751 int n;
752
753 if( objc<=2 ){
754 Tcl_WrongNumArgs(interp, 1, objv, "cache option ?arg?");
755 return TCL_ERROR;
756 }
757 subCmd = Tcl_GetStringFromObj( objv[2], 0 );
758 if( *subCmd=='f' && strcmp(subCmd,"flush")==0 ){
759 if( objc!=3 ){
760 Tcl_WrongNumArgs(interp, 2, objv, "flush");
761 return TCL_ERROR;
762 }else{
763 flushStmtCache( pDb );
764 }
765 }else if( *subCmd=='s' && strcmp(subCmd,"size")==0 ){
766 if( objc!=4 ){
767 Tcl_WrongNumArgs(interp, 2, objv, "size n");
768 return TCL_ERROR;
769 }else{
770 if( TCL_ERROR==Tcl_GetIntFromObj(interp, objv[3], &n) ){
771 Tcl_AppendResult( interp, "cannot convert \"",
772 Tcl_GetStringFromObj(objv[3],0), "\" to integer", 0);
773 return TCL_ERROR;
774 }else{
775 if( n<0 ){
776 flushStmtCache( pDb );
777 n = 0;
778 }else if( n>MAX_PREPARED_STMTS ){
779 n = MAX_PREPARED_STMTS;
780 }
781 pDb->maxStmt = n;
782 }
783 }
784 }else{
785 Tcl_AppendResult( interp, "bad option \"",
786 Tcl_GetStringFromObj(objv[0],0), "\": must be flush or size", 0);
787 return TCL_ERROR;
788 }
789 break;
790 }
791
danielk1977b28af712004-06-21 06:50:26 +0000792 /* $db changes
drhc8d30ac2002-04-12 10:08:59 +0000793 **
794 ** Return the number of rows that were modified, inserted, or deleted by
danielk1977b28af712004-06-21 06:50:26 +0000795 ** the most recent INSERT, UPDATE or DELETE statement, not including
796 ** any changes made by trigger programs.
drhc8d30ac2002-04-12 10:08:59 +0000797 */
798 case DB_CHANGES: {
799 Tcl_Obj *pResult;
drhc8d30ac2002-04-12 10:08:59 +0000800 if( objc!=2 ){
801 Tcl_WrongNumArgs(interp, 2, objv, "");
802 return TCL_ERROR;
803 }
drhc8d30ac2002-04-12 10:08:59 +0000804 pResult = Tcl_GetObjResult(interp);
danielk1977b28af712004-06-21 06:50:26 +0000805 Tcl_SetIntObj(pResult, sqlite3_changes(pDb->db));
rdcf146a772004-02-25 22:51:06 +0000806 break;
807 }
808
drh75897232000-05-29 14:26:00 +0000809 /* $db close
810 **
811 ** Shutdown the database
812 */
drh6d313162000-09-21 13:01:35 +0000813 case DB_CLOSE: {
814 Tcl_DeleteCommand(interp, Tcl_GetStringFromObj(objv[0], 0));
815 break;
816 }
drh75897232000-05-29 14:26:00 +0000817
drh0f14e2e2004-06-29 12:39:08 +0000818 /*
819 ** $db collate NAME SCRIPT
820 **
821 ** Create a new SQL collation function called NAME. Whenever
822 ** that function is called, invoke SCRIPT to evaluate the function.
823 */
824 case DB_COLLATE: {
825 SqlCollate *pCollate;
826 char *zName;
827 char *zScript;
828 int nScript;
829 if( objc!=4 ){
830 Tcl_WrongNumArgs(interp, 2, objv, "NAME SCRIPT");
831 return TCL_ERROR;
832 }
833 zName = Tcl_GetStringFromObj(objv[2], 0);
834 zScript = Tcl_GetStringFromObj(objv[3], &nScript);
835 pCollate = (SqlCollate*)Tcl_Alloc( sizeof(*pCollate) + nScript + 1 );
836 if( pCollate==0 ) return TCL_ERROR;
837 pCollate->interp = interp;
838 pCollate->pNext = pDb->pCollate;
839 pCollate->zScript = (char*)&pCollate[1];
840 pDb->pCollate = pCollate;
841 strcpy(pCollate->zScript, zScript);
842 if( sqlite3_create_collation(pDb->db, zName, SQLITE_UTF8,
843 pCollate, tclSqlCollate) ){
danielk19779636c4e2005-01-25 04:27:54 +0000844 Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
drh0f14e2e2004-06-29 12:39:08 +0000845 return TCL_ERROR;
846 }
847 break;
848 }
849
850 /*
851 ** $db collation_needed SCRIPT
852 **
853 ** Create a new SQL collation function called NAME. Whenever
854 ** that function is called, invoke SCRIPT to evaluate the function.
855 */
856 case DB_COLLATION_NEEDED: {
857 if( objc!=3 ){
858 Tcl_WrongNumArgs(interp, 2, objv, "SCRIPT");
859 return TCL_ERROR;
860 }
861 if( pDb->pCollateNeeded ){
862 Tcl_DecrRefCount(pDb->pCollateNeeded);
863 }
864 pDb->pCollateNeeded = Tcl_DuplicateObj(objv[2]);
865 Tcl_IncrRefCount(pDb->pCollateNeeded);
866 sqlite3_collation_needed(pDb->db, pDb, tclCollateNeeded);
867 break;
868 }
869
drh19e2d372005-08-29 23:00:03 +0000870 /* $db commit_hook ?CALLBACK?
871 **
872 ** Invoke the given callback just before committing every SQL transaction.
873 ** If the callback throws an exception or returns non-zero, then the
874 ** transaction is aborted. If CALLBACK is an empty string, the callback
875 ** is disabled.
876 */
877 case DB_COMMIT_HOOK: {
878 if( objc>3 ){
879 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
880 return TCL_ERROR;
881 }else if( objc==2 ){
882 if( pDb->zCommit ){
883 Tcl_AppendResult(interp, pDb->zCommit, 0);
884 }
885 }else{
886 char *zCommit;
887 int len;
888 if( pDb->zCommit ){
889 Tcl_Free(pDb->zCommit);
890 }
891 zCommit = Tcl_GetStringFromObj(objv[2], &len);
892 if( zCommit && len>0 ){
893 pDb->zCommit = Tcl_Alloc( len + 1 );
894 strcpy(pDb->zCommit, zCommit);
895 }else{
896 pDb->zCommit = 0;
897 }
898 if( pDb->zCommit ){
899 pDb->interp = interp;
900 sqlite3_commit_hook(pDb->db, DbCommitHandler, pDb);
901 }else{
902 sqlite3_commit_hook(pDb->db, 0, 0);
903 }
904 }
905 break;
906 }
907
drh75897232000-05-29 14:26:00 +0000908 /* $db complete SQL
909 **
910 ** Return TRUE if SQL is a complete SQL statement. Return FALSE if
911 ** additional lines of input are needed. This is similar to the
912 ** built-in "info complete" command of Tcl.
913 */
drh6d313162000-09-21 13:01:35 +0000914 case DB_COMPLETE: {
drhccae6022005-02-26 17:31:26 +0000915#ifndef SQLITE_OMIT_COMPLETE
drh6d313162000-09-21 13:01:35 +0000916 Tcl_Obj *pResult;
917 int isComplete;
918 if( objc!=3 ){
919 Tcl_WrongNumArgs(interp, 2, objv, "SQL");
drh75897232000-05-29 14:26:00 +0000920 return TCL_ERROR;
921 }
danielk19776f8a5032004-05-10 10:34:51 +0000922 isComplete = sqlite3_complete( Tcl_GetStringFromObj(objv[2], 0) );
drh6d313162000-09-21 13:01:35 +0000923 pResult = Tcl_GetObjResult(interp);
924 Tcl_SetBooleanObj(pResult, isComplete);
drhccae6022005-02-26 17:31:26 +0000925#endif
drh6d313162000-09-21 13:01:35 +0000926 break;
927 }
drhdcd997e2003-01-31 17:21:49 +0000928
drh19e2d372005-08-29 23:00:03 +0000929 /* $db copy conflict-algorithm table filename ?SEPARATOR? ?NULLINDICATOR?
930 **
931 ** Copy data into table from filename, optionally using SEPARATOR
932 ** as column separators. If a column contains a null string, or the
933 ** value of NULLINDICATOR, a NULL is inserted for the column.
934 ** conflict-algorithm is one of the sqlite conflict algorithms:
935 ** rollback, abort, fail, ignore, replace
936 ** On success, return the number of lines processed, not necessarily same
937 ** as 'db changes' due to conflict-algorithm selected.
938 **
939 ** This code is basically an implementation/enhancement of
940 ** the sqlite3 shell.c ".import" command.
941 **
942 ** This command usage is equivalent to the sqlite2.x COPY statement,
943 ** which imports file data into a table using the PostgreSQL COPY file format:
944 ** $db copy $conflit_algo $table_name $filename \t \\N
945 */
946 case DB_COPY: {
947 char *zTable; /* Insert data into this table */
948 char *zFile; /* The file from which to extract data */
949 char *zConflict; /* The conflict algorithm to use */
950 sqlite3_stmt *pStmt; /* A statement */
951 int rc; /* Result code */
952 int nCol; /* Number of columns in the table */
953 int nByte; /* Number of bytes in an SQL string */
954 int i, j; /* Loop counters */
955 int nSep; /* Number of bytes in zSep[] */
956 int nNull; /* Number of bytes in zNull[] */
957 char *zSql; /* An SQL statement */
958 char *zLine; /* A single line of input from the file */
959 char **azCol; /* zLine[] broken up into columns */
960 char *zCommit; /* How to commit changes */
961 FILE *in; /* The input file */
962 int lineno = 0; /* Line number of input file */
963 char zLineNum[80]; /* Line number print buffer */
964 Tcl_Obj *pResult; /* interp result */
965
966 char *zSep;
967 char *zNull;
968 if( objc<5 || objc>7 ){
969 Tcl_WrongNumArgs(interp, 2, objv,
970 "CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?");
971 return TCL_ERROR;
972 }
973 if( objc>=6 ){
974 zSep = Tcl_GetStringFromObj(objv[5], 0);
975 }else{
976 zSep = "\t";
977 }
978 if( objc>=7 ){
979 zNull = Tcl_GetStringFromObj(objv[6], 0);
980 }else{
981 zNull = "";
982 }
983 zConflict = Tcl_GetStringFromObj(objv[2], 0);
984 zTable = Tcl_GetStringFromObj(objv[3], 0);
985 zFile = Tcl_GetStringFromObj(objv[4], 0);
986 nSep = strlen(zSep);
987 nNull = strlen(zNull);
988 if( nSep==0 ){
989 Tcl_AppendResult(interp, "Error: non-null separator required for copy", 0);
990 return TCL_ERROR;
991 }
992 if(sqlite3StrICmp(zConflict, "rollback") != 0 &&
993 sqlite3StrICmp(zConflict, "abort" ) != 0 &&
994 sqlite3StrICmp(zConflict, "fail" ) != 0 &&
995 sqlite3StrICmp(zConflict, "ignore" ) != 0 &&
996 sqlite3StrICmp(zConflict, "replace" ) != 0 ) {
997 Tcl_AppendResult(interp, "Error: \"", zConflict,
998 "\", conflict-algorithm must be one of: rollback, "
999 "abort, fail, ignore, or replace", 0);
1000 return TCL_ERROR;
1001 }
1002 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
1003 if( zSql==0 ){
1004 Tcl_AppendResult(interp, "Error: no such table: ", zTable, 0);
1005 return TCL_ERROR;
1006 }
1007 nByte = strlen(zSql);
1008 rc = sqlite3_prepare(pDb->db, zSql, 0, &pStmt, 0);
1009 sqlite3_free(zSql);
1010 if( rc ){
1011 Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), 0);
1012 nCol = 0;
1013 }else{
1014 nCol = sqlite3_column_count(pStmt);
1015 }
1016 sqlite3_finalize(pStmt);
1017 if( nCol==0 ) {
1018 return TCL_ERROR;
1019 }
1020 zSql = malloc( nByte + 50 + nCol*2 );
1021 if( zSql==0 ) {
1022 Tcl_AppendResult(interp, "Error: can't malloc()", 0);
1023 return TCL_ERROR;
1024 }
1025 sqlite3_snprintf(nByte+50, zSql, "INSERT OR %q INTO '%q' VALUES(?",
1026 zConflict, zTable);
1027 j = strlen(zSql);
1028 for(i=1; i<nCol; i++){
1029 zSql[j++] = ',';
1030 zSql[j++] = '?';
1031 }
1032 zSql[j++] = ')';
1033 zSql[j] = 0;
1034 rc = sqlite3_prepare(pDb->db, zSql, 0, &pStmt, 0);
1035 free(zSql);
1036 if( rc ){
1037 Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), 0);
1038 sqlite3_finalize(pStmt);
1039 return TCL_ERROR;
1040 }
1041 in = fopen(zFile, "rb");
1042 if( in==0 ){
1043 Tcl_AppendResult(interp, "Error: cannot open file: ", zFile, NULL);
1044 sqlite3_finalize(pStmt);
1045 return TCL_ERROR;
1046 }
1047 azCol = malloc( sizeof(azCol[0])*(nCol+1) );
1048 if( azCol==0 ) {
1049 Tcl_AppendResult(interp, "Error: can't malloc()", 0);
1050 return TCL_ERROR;
1051 }
1052 sqlite3_exec(pDb->db, "BEGIN", 0, 0, 0);
1053 zCommit = "COMMIT";
1054 while( (zLine = local_getline(0, in))!=0 ){
1055 char *z;
1056 i = 0;
1057 lineno++;
1058 azCol[0] = zLine;
1059 for(i=0, z=zLine; *z; z++){
1060 if( *z==zSep[0] && strncmp(z, zSep, nSep)==0 ){
1061 *z = 0;
1062 i++;
1063 if( i<nCol ){
1064 azCol[i] = &z[nSep];
1065 z += nSep-1;
1066 }
1067 }
1068 }
1069 if( i+1!=nCol ){
1070 char *zErr;
1071 zErr = malloc(200 + strlen(zFile));
1072 sprintf(zErr,"Error: %s line %d: expected %d columns of data but found %d",
1073 zFile, lineno, nCol, i+1);
1074 Tcl_AppendResult(interp, zErr, 0);
1075 free(zErr);
1076 zCommit = "ROLLBACK";
1077 break;
1078 }
1079 for(i=0; i<nCol; i++){
1080 /* check for null data, if so, bind as null */
1081 if ((nNull>0 && strcmp(azCol[i], zNull)==0) || strlen(azCol[i])==0) {
1082 sqlite3_bind_null(pStmt, i+1);
1083 }else{
1084 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
1085 }
1086 }
1087 sqlite3_step(pStmt);
1088 rc = sqlite3_reset(pStmt);
1089 free(zLine);
1090 if( rc!=SQLITE_OK ){
1091 Tcl_AppendResult(interp,"Error: ", sqlite3_errmsg(pDb->db), 0);
1092 zCommit = "ROLLBACK";
1093 break;
1094 }
1095 }
1096 free(azCol);
1097 fclose(in);
1098 sqlite3_finalize(pStmt);
1099 sqlite3_exec(pDb->db, zCommit, 0, 0, 0);
1100
1101 if( zCommit[0] == 'C' ){
1102 /* success, set result as number of lines processed */
1103 pResult = Tcl_GetObjResult(interp);
1104 Tcl_SetIntObj(pResult, lineno);
1105 rc = TCL_OK;
1106 }else{
1107 /* failure, append lineno where failed */
1108 sprintf(zLineNum,"%d",lineno);
1109 Tcl_AppendResult(interp,", failed while processing line: ",zLineNum,0);
1110 rc = TCL_ERROR;
1111 }
1112 break;
1113 }
1114
drhdcd997e2003-01-31 17:21:49 +00001115 /*
1116 ** $db errorcode
1117 **
1118 ** Return the numeric error code that was returned by the most recent
danielk19776f8a5032004-05-10 10:34:51 +00001119 ** call to sqlite3_exec().
drhdcd997e2003-01-31 17:21:49 +00001120 */
1121 case DB_ERRORCODE: {
danielk1977f3ce83f2004-06-14 11:43:46 +00001122 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_errcode(pDb->db)));
drhdcd997e2003-01-31 17:21:49 +00001123 break;
1124 }
drh75897232000-05-29 14:26:00 +00001125
1126 /*
drh895d7472004-08-20 16:02:39 +00001127 ** $db eval $sql ?array? ?{ ...code... }?
drh1807ce32004-09-07 13:20:35 +00001128 ** $db onecolumn $sql
drh75897232000-05-29 14:26:00 +00001129 **
1130 ** The SQL statement in $sql is evaluated. For each row, the values are
drhbec3f402000-08-04 13:49:02 +00001131 ** placed in elements of the array named "array" and ...code... is executed.
drh75897232000-05-29 14:26:00 +00001132 ** If "array" and "code" are omitted, then no callback is every invoked.
1133 ** If "array" is an empty string, then the values are placed in variables
1134 ** that have the same name as the fields extracted by the query.
drh1807ce32004-09-07 13:20:35 +00001135 **
1136 ** The onecolumn method is the equivalent of:
1137 ** lindex [$db eval $sql] 0
drh75897232000-05-29 14:26:00 +00001138 */
drh1807ce32004-09-07 13:20:35 +00001139 case DB_ONECOLUMN:
drh97f2ebc2005-12-10 21:19:04 +00001140 case DB_EVAL:
1141 case DB_EXISTS: {
drh9d74b4c2004-08-24 15:23:34 +00001142 char const *zSql; /* Next SQL statement to execute */
1143 char const *zLeft; /* What is left after first stmt in zSql */
1144 sqlite3_stmt *pStmt; /* Compiled SQL statment */
drh92febd92004-08-20 18:34:20 +00001145 Tcl_Obj *pArray; /* Name of array into which results are written */
1146 Tcl_Obj *pScript; /* Script to run for each result set */
drh1d895032004-08-26 00:56:05 +00001147 Tcl_Obj **apParm; /* Parameters that need a Tcl_DecrRefCount() */
1148 int nParm; /* Number of entries used in apParm[] */
1149 Tcl_Obj *aParm[10]; /* Static space for apParm[] in the common case */
drh1807ce32004-09-07 13:20:35 +00001150 Tcl_Obj *pRet; /* Value to be returned */
drhfb7e7652005-01-24 00:28:42 +00001151 SqlPreparedStmt *pPreStmt; /* Pointer to a prepared statement */
1152 int rc2;
danielk1977ef2cb632004-05-29 02:37:19 +00001153
drh97f2ebc2005-12-10 21:19:04 +00001154 if( choice==DB_EVAL ){
drh1807ce32004-09-07 13:20:35 +00001155 if( objc<3 || objc>5 ){
1156 Tcl_WrongNumArgs(interp, 2, objv, "SQL ?ARRAY-NAME? ?SCRIPT?");
1157 return TCL_ERROR;
1158 }
1159 pRet = Tcl_NewObj();
1160 Tcl_IncrRefCount(pRet);
drh97f2ebc2005-12-10 21:19:04 +00001161 }else{
1162 if( objc!=3 ){
1163 Tcl_WrongNumArgs(interp, 2, objv, "SQL");
1164 return TCL_ERROR;
1165 }
1166 pRet = 0;
1167 if( choice==DB_EXISTS ){
1168 Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
1169 }
danielk197730ccda12004-05-27 12:11:31 +00001170 }
drh92febd92004-08-20 18:34:20 +00001171 if( objc==3 ){
1172 pArray = pScript = 0;
1173 }else if( objc==4 ){
1174 pArray = 0;
1175 pScript = objv[3];
1176 }else{
1177 pArray = objv[3];
1178 if( Tcl_GetString(pArray)[0]==0 ) pArray = 0;
1179 pScript = objv[4];
1180 }
danielk197730ccda12004-05-27 12:11:31 +00001181
drh1d895032004-08-26 00:56:05 +00001182 Tcl_IncrRefCount(objv[2]);
danielk197730ccda12004-05-27 12:11:31 +00001183 zSql = Tcl_GetStringFromObj(objv[2], 0);
drh90b6bb12004-09-13 13:16:31 +00001184 while( rc==TCL_OK && zSql[0] ){
drhfb7e7652005-01-24 00:28:42 +00001185 int i; /* Loop counter */
1186 int nVar; /* Number of bind parameters in the pStmt */
1187 int nCol; /* Number of columns in the result set */
drh92febd92004-08-20 18:34:20 +00001188 Tcl_Obj **apColName = 0; /* Array of column names */
drhfb7e7652005-01-24 00:28:42 +00001189 int len; /* String length of zSql */
danielk197730ccda12004-05-27 12:11:31 +00001190
drhfb7e7652005-01-24 00:28:42 +00001191 /* Try to find a SQL statement that has already been compiled and
1192 ** which matches the next sequence of SQL.
1193 */
1194 pStmt = 0;
1195 pPreStmt = pDb->stmtList;
1196 len = strlen(zSql);
1197 if( pPreStmt && sqlite3_expired(pPreStmt->pStmt) ){
1198 flushStmtCache(pDb);
1199 pPreStmt = 0;
danielk197730ccda12004-05-27 12:11:31 +00001200 }
drhfb7e7652005-01-24 00:28:42 +00001201 for(; pPreStmt; pPreStmt=pPreStmt->pNext){
1202 int n = pPreStmt->nSql;
1203 if( len>=n
1204 && memcmp(pPreStmt->zSql, zSql, n)==0
1205 && (zSql[n]==0 || zSql[n-1]==';')
1206 ){
1207 pStmt = pPreStmt->pStmt;
1208 zLeft = &zSql[pPreStmt->nSql];
1209
1210 /* When a prepared statement is found, unlink it from the
1211 ** cache list. It will later be added back to the beginning
1212 ** of the cache list in order to implement LRU replacement.
1213 */
1214 if( pPreStmt->pPrev ){
1215 pPreStmt->pPrev->pNext = pPreStmt->pNext;
1216 }else{
1217 pDb->stmtList = pPreStmt->pNext;
1218 }
1219 if( pPreStmt->pNext ){
1220 pPreStmt->pNext->pPrev = pPreStmt->pPrev;
1221 }else{
1222 pDb->stmtLast = pPreStmt->pPrev;
1223 }
1224 pDb->nStmt--;
1225 break;
1226 }
1227 }
1228
1229 /* If no prepared statement was found. Compile the SQL text
1230 */
drh92febd92004-08-20 18:34:20 +00001231 if( pStmt==0 ){
drhfb7e7652005-01-24 00:28:42 +00001232 if( SQLITE_OK!=sqlite3_prepare(pDb->db, zSql, -1, &pStmt, &zLeft) ){
drh92febd92004-08-20 18:34:20 +00001233 Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
1234 rc = TCL_ERROR;
1235 break;
danielk197730ccda12004-05-27 12:11:31 +00001236 }
drhfb7e7652005-01-24 00:28:42 +00001237 if( pStmt==0 ){
1238 if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){
1239 /* A compile-time error in the statement
1240 */
1241 Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
1242 rc = TCL_ERROR;
1243 break;
1244 }else{
1245 /* The statement was a no-op. Continue to the next statement
1246 ** in the SQL string.
1247 */
1248 zSql = zLeft;
1249 continue;
1250 }
1251 }
1252 assert( pPreStmt==0 );
danielk197730ccda12004-05-27 12:11:31 +00001253 }
1254
drhfb7e7652005-01-24 00:28:42 +00001255 /* Bind values to parameters that begin with $ or :
1256 */
drh92febd92004-08-20 18:34:20 +00001257 nVar = sqlite3_bind_parameter_count(pStmt);
drh1d895032004-08-26 00:56:05 +00001258 nParm = 0;
1259 if( nVar>sizeof(aParm)/sizeof(aParm[0]) ){
1260 apParm = (Tcl_Obj**)Tcl_Alloc(nVar*sizeof(apParm[0]));
1261 }else{
1262 apParm = aParm;
1263 }
drh92febd92004-08-20 18:34:20 +00001264 for(i=1; i<=nVar; i++){
1265 const char *zVar = sqlite3_bind_parameter_name(pStmt, i);
drhc8f90792005-01-12 00:08:24 +00001266 if( zVar!=0 && (zVar[0]=='$' || zVar[0]==':') ){
drh92febd92004-08-20 18:34:20 +00001267 Tcl_Obj *pVar = Tcl_GetVar2Ex(interp, &zVar[1], 0, 0);
1268 if( pVar ){
1269 int n;
1270 u8 *data;
1271 char *zType = pVar->typePtr ? pVar->typePtr->name : "";
1272 char c = zType[0];
drhdf0bdda2005-06-25 19:31:48 +00001273 if( c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0 ){
1274 /* Only load a BLOB type if the Tcl variable is a bytearray and
1275 ** has no string representation. */
drh92febd92004-08-20 18:34:20 +00001276 data = Tcl_GetByteArrayFromObj(pVar, &n);
1277 sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC);
drh1d895032004-08-26 00:56:05 +00001278 Tcl_IncrRefCount(pVar);
1279 apParm[nParm++] = pVar;
drh92febd92004-08-20 18:34:20 +00001280 }else if( (c=='b' && strcmp(zType,"boolean")==0) ||
1281 (c=='i' && strcmp(zType,"int")==0) ){
1282 Tcl_GetIntFromObj(interp, pVar, &n);
1283 sqlite3_bind_int(pStmt, i, n);
1284 }else if( c=='d' && strcmp(zType,"double")==0 ){
1285 double r;
1286 Tcl_GetDoubleFromObj(interp, pVar, &r);
1287 sqlite3_bind_double(pStmt, i, r);
drhdf0bdda2005-06-25 19:31:48 +00001288 }else if( c=='w' && strcmp(zType,"wideInt")==0 ){
1289 Tcl_WideInt v;
1290 Tcl_GetWideIntFromObj(interp, pVar, &v);
1291 sqlite3_bind_int64(pStmt, i, v);
drh92febd92004-08-20 18:34:20 +00001292 }else{
danielk197700fd9572005-12-07 06:27:43 +00001293 data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n);
1294 sqlite3_bind_text(pStmt, i, (char *)data, n, SQLITE_STATIC);
drh1d895032004-08-26 00:56:05 +00001295 Tcl_IncrRefCount(pVar);
1296 apParm[nParm++] = pVar;
drh92febd92004-08-20 18:34:20 +00001297 }
drhfb7e7652005-01-24 00:28:42 +00001298 }else{
1299 sqlite3_bind_null( pStmt, i );
drh92febd92004-08-20 18:34:20 +00001300 }
1301 }
1302 }
drh92febd92004-08-20 18:34:20 +00001303
1304 /* Compute column names */
1305 nCol = sqlite3_column_count(pStmt);
1306 if( pScript ){
1307 apColName = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*)*nCol );
1308 if( apColName==0 ) break;
1309 for(i=0; i<nCol; i++){
1310 apColName[i] = dbTextToObj(sqlite3_column_name(pStmt,i));
1311 Tcl_IncrRefCount(apColName[i]);
1312 }
1313 }
1314
1315 /* If results are being stored in an array variable, then create
1316 ** the array(*) entry for that array
1317 */
1318 if( pArray ){
1319 Tcl_Obj *pColList = Tcl_NewObj();
drh3ced14a2005-03-31 18:26:20 +00001320 Tcl_Obj *pStar = Tcl_NewStringObj("*", -1);
drh92febd92004-08-20 18:34:20 +00001321 Tcl_IncrRefCount(pColList);
1322 for(i=0; i<nCol; i++){
1323 Tcl_ListObjAppendElement(interp, pColList, apColName[i]);
1324 }
drh3ced14a2005-03-31 18:26:20 +00001325 Tcl_ObjSetVar2(interp, pArray, pStar, pColList,0);
1326 Tcl_DecrRefCount(pColList);
1327 Tcl_DecrRefCount(pStar);
drh92febd92004-08-20 18:34:20 +00001328 }
1329
1330 /* Execute the SQL
1331 */
drh90b6bb12004-09-13 13:16:31 +00001332 while( rc==TCL_OK && pStmt && SQLITE_ROW==sqlite3_step(pStmt) ){
drh92febd92004-08-20 18:34:20 +00001333 for(i=0; i<nCol; i++){
danielk197730ccda12004-05-27 12:11:31 +00001334 Tcl_Obj *pVal;
1335
1336 /* Set pVal to contain the i'th column of this row. */
drh92febd92004-08-20 18:34:20 +00001337 switch( sqlite3_column_type(pStmt, i) ){
1338 case SQLITE_BLOB: {
1339 int bytes = sqlite3_column_bytes(pStmt, i);
1340 pVal = Tcl_NewByteArrayObj(sqlite3_column_blob(pStmt, i), bytes);
1341 break;
1342 }
1343 case SQLITE_INTEGER: {
1344 sqlite_int64 v = sqlite3_column_int64(pStmt, i);
1345 if( v>=-2147483647 && v<=2147483647 ){
1346 pVal = Tcl_NewIntObj(v);
1347 }else{
1348 pVal = Tcl_NewWideIntObj(v);
1349 }
1350 break;
1351 }
1352 case SQLITE_FLOAT: {
1353 double r = sqlite3_column_double(pStmt, i);
1354 pVal = Tcl_NewDoubleObj(r);
1355 break;
1356 }
danielk197755c45f22005-04-03 23:54:43 +00001357 case SQLITE_NULL: {
1358 pVal = dbTextToObj(pDb->zNull);
1359 break;
1360 }
drh92febd92004-08-20 18:34:20 +00001361 default: {
danielk197700fd9572005-12-07 06:27:43 +00001362 pVal = dbTextToObj((char *)sqlite3_column_text(pStmt, i));
drh92febd92004-08-20 18:34:20 +00001363 break;
1364 }
danielk197730ccda12004-05-27 12:11:31 +00001365 }
1366
drh92febd92004-08-20 18:34:20 +00001367 if( pScript ){
1368 if( pArray==0 ){
1369 Tcl_ObjSetVar2(interp, apColName[i], 0, pVal, 0);
danielk197730ccda12004-05-27 12:11:31 +00001370 }else{
drh92febd92004-08-20 18:34:20 +00001371 Tcl_ObjSetVar2(interp, pArray, apColName[i], pVal, 0);
danielk197730ccda12004-05-27 12:11:31 +00001372 }
drh1807ce32004-09-07 13:20:35 +00001373 }else if( choice==DB_ONECOLUMN ){
drh97f2ebc2005-12-10 21:19:04 +00001374 assert( pRet==0 );
drh1807ce32004-09-07 13:20:35 +00001375 if( pRet==0 ){
1376 pRet = pVal;
1377 Tcl_IncrRefCount(pRet);
1378 }
drh90b6bb12004-09-13 13:16:31 +00001379 rc = TCL_BREAK;
drh97f2ebc2005-12-10 21:19:04 +00001380 i = nCol;
1381 }else if( choice==DB_EXISTS ){
1382 assert( pRet==0 );
1383 Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
1384 rc = TCL_BREAK;
1385 i = nCol;
danielk197730ccda12004-05-27 12:11:31 +00001386 }else{
danielk197730ccda12004-05-27 12:11:31 +00001387 Tcl_ListObjAppendElement(interp, pRet, pVal);
1388 }
1389 }
1390
drh92febd92004-08-20 18:34:20 +00001391 if( pScript ){
1392 rc = Tcl_EvalObjEx(interp, pScript, 0);
drh90b6bb12004-09-13 13:16:31 +00001393 if( rc==TCL_CONTINUE ){
1394 rc = TCL_OK;
1395 }
danielk197730ccda12004-05-27 12:11:31 +00001396 }
1397 }
drh90b6bb12004-09-13 13:16:31 +00001398 if( rc==TCL_BREAK ){
1399 rc = TCL_OK;
1400 }
drh92febd92004-08-20 18:34:20 +00001401
1402 /* Free the column name objects */
1403 if( pScript ){
1404 for(i=0; i<nCol; i++){
1405 Tcl_DecrRefCount(apColName[i]);
1406 }
1407 Tcl_Free((char*)apColName);
1408 }
1409
drh1d895032004-08-26 00:56:05 +00001410 /* Free the bound string and blob parameters */
1411 for(i=0; i<nParm; i++){
1412 Tcl_DecrRefCount(apParm[i]);
1413 }
1414 if( apParm!=aParm ){
1415 Tcl_Free((char*)apParm);
1416 }
1417
drhfb7e7652005-01-24 00:28:42 +00001418 /* Reset the statement. If the result code is SQLITE_SCHEMA, then
1419 ** flush the statement cache and try the statement again.
drh92febd92004-08-20 18:34:20 +00001420 */
drhfb7e7652005-01-24 00:28:42 +00001421 rc2 = sqlite3_reset(pStmt);
1422 if( SQLITE_SCHEMA==rc2 ){
1423 /* After a schema change, flush the cache and try to run the
1424 ** statement again
1425 */
1426 flushStmtCache( pDb );
1427 sqlite3_finalize(pStmt);
1428 if( pPreStmt ) Tcl_Free((char*)pPreStmt);
danielk197730ccda12004-05-27 12:11:31 +00001429 continue;
drhfb7e7652005-01-24 00:28:42 +00001430 }else if( SQLITE_OK!=rc2 ){
1431 /* If a run-time error occurs, report the error and stop reading
1432 ** the SQL
1433 */
danielk1977ef2cb632004-05-29 02:37:19 +00001434 Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
drhfb7e7652005-01-24 00:28:42 +00001435 sqlite3_finalize(pStmt);
danielk197730ccda12004-05-27 12:11:31 +00001436 rc = TCL_ERROR;
drhfb7e7652005-01-24 00:28:42 +00001437 if( pPreStmt ) Tcl_Free((char*)pPreStmt);
danielk197730ccda12004-05-27 12:11:31 +00001438 break;
drhfb7e7652005-01-24 00:28:42 +00001439 }else if( pDb->maxStmt<=0 ){
1440 /* If the cache is turned off, deallocated the statement */
1441 if( pPreStmt ) Tcl_Free((char*)pPreStmt);
1442 sqlite3_finalize(pStmt);
1443 }else{
1444 /* Everything worked and the cache is operational.
1445 ** Create a new SqlPreparedStmt structure if we need one.
1446 ** (If we already have one we can just reuse it.)
1447 */
1448 if( pPreStmt==0 ){
1449 len = zLeft - zSql;
1450 pPreStmt = (SqlPreparedStmt*)Tcl_Alloc( sizeof(*pPreStmt) + len );
1451 if( pPreStmt==0 ) return TCL_ERROR;
1452 pPreStmt->pStmt = pStmt;
1453 pPreStmt->nSql = len;
1454 memcpy(pPreStmt->zSql, zSql, len);
1455 pPreStmt->zSql[len] = 0;
1456 }
1457
1458 /* Add the prepared statement to the beginning of the cache list
1459 */
1460 pPreStmt->pNext = pDb->stmtList;
1461 pPreStmt->pPrev = 0;
1462 if( pDb->stmtList ){
1463 pDb->stmtList->pPrev = pPreStmt;
1464 }
1465 pDb->stmtList = pPreStmt;
1466 if( pDb->stmtLast==0 ){
1467 assert( pDb->nStmt==0 );
1468 pDb->stmtLast = pPreStmt;
1469 }else{
1470 assert( pDb->nStmt>0 );
1471 }
1472 pDb->nStmt++;
1473
1474 /* If we have too many statement in cache, remove the surplus from the
1475 ** end of the cache list.
1476 */
1477 while( pDb->nStmt>pDb->maxStmt ){
1478 sqlite3_finalize(pDb->stmtLast->pStmt);
1479 pDb->stmtLast = pDb->stmtLast->pPrev;
1480 Tcl_Free((char*)pDb->stmtLast->pNext);
1481 pDb->stmtLast->pNext = 0;
1482 pDb->nStmt--;
1483 }
danielk197730ccda12004-05-27 12:11:31 +00001484 }
1485
drhfb7e7652005-01-24 00:28:42 +00001486 /* Proceed to the next statement */
danielk197730ccda12004-05-27 12:11:31 +00001487 zSql = zLeft;
1488 }
drh1d895032004-08-26 00:56:05 +00001489 Tcl_DecrRefCount(objv[2]);
danielk197730ccda12004-05-27 12:11:31 +00001490
drh1807ce32004-09-07 13:20:35 +00001491 if( pRet ){
1492 if( rc==TCL_OK ){
1493 Tcl_SetObjResult(interp, pRet);
1494 }
1495 Tcl_DecrRefCount(pRet);
danielk197730ccda12004-05-27 12:11:31 +00001496 }
danielk197730ccda12004-05-27 12:11:31 +00001497 break;
1498 }
drhbec3f402000-08-04 13:49:02 +00001499
1500 /*
drhcabb0812002-09-14 13:47:32 +00001501 ** $db function NAME SCRIPT
1502 **
1503 ** Create a new SQL function called NAME. Whenever that function is
1504 ** called, invoke SCRIPT to evaluate the function.
1505 */
1506 case DB_FUNCTION: {
1507 SqlFunc *pFunc;
drhd1e47332005-06-26 17:55:33 +00001508 Tcl_Obj *pScript;
drhcabb0812002-09-14 13:47:32 +00001509 char *zName;
drhcabb0812002-09-14 13:47:32 +00001510 if( objc!=4 ){
1511 Tcl_WrongNumArgs(interp, 2, objv, "NAME SCRIPT");
1512 return TCL_ERROR;
1513 }
1514 zName = Tcl_GetStringFromObj(objv[2], 0);
drhd1e47332005-06-26 17:55:33 +00001515 pScript = objv[3];
1516 pFunc = findSqlFunc(pDb, zName);
drhcabb0812002-09-14 13:47:32 +00001517 if( pFunc==0 ) return TCL_ERROR;
drhd1e47332005-06-26 17:55:33 +00001518 if( pFunc->pScript ){
1519 Tcl_DecrRefCount(pFunc->pScript);
1520 }
1521 pFunc->pScript = pScript;
1522 Tcl_IncrRefCount(pScript);
1523 pFunc->useEvalObjv = safeToUseEvalObjv(interp, pScript);
danielk1977c8c11582004-06-29 13:41:21 +00001524 rc = sqlite3_create_function(pDb->db, zName, -1, SQLITE_UTF8,
danielk1977d8123362004-06-12 09:25:12 +00001525 pFunc, tclSqlFunc, 0, 0);
drhfb7e7652005-01-24 00:28:42 +00001526 if( rc!=SQLITE_OK ){
danielk19779636c4e2005-01-25 04:27:54 +00001527 rc = TCL_ERROR;
1528 Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
drhfb7e7652005-01-24 00:28:42 +00001529 }else{
1530 /* Must flush any cached statements */
1531 flushStmtCache( pDb );
1532 }
drhcabb0812002-09-14 13:47:32 +00001533 break;
1534 }
1535
1536 /*
drh19e2d372005-08-29 23:00:03 +00001537 ** $db nullvalue ?STRING?
1538 **
1539 ** Change text used when a NULL comes back from the database. If ?STRING?
1540 ** is not present, then the current string used for NULL is returned.
1541 ** If STRING is present, then STRING is returned.
1542 **
1543 */
1544 case DB_NULLVALUE: {
1545 if( objc!=2 && objc!=3 ){
1546 Tcl_WrongNumArgs(interp, 2, objv, "NULLVALUE");
1547 return TCL_ERROR;
1548 }
1549 if( objc==3 ){
1550 int len;
1551 char *zNull = Tcl_GetStringFromObj(objv[2], &len);
1552 if( pDb->zNull ){
1553 Tcl_Free(pDb->zNull);
1554 }
1555 if( zNull && len>0 ){
1556 pDb->zNull = Tcl_Alloc( len + 1 );
1557 strncpy(pDb->zNull, zNull, len);
1558 pDb->zNull[len] = '\0';
1559 }else{
1560 pDb->zNull = 0;
1561 }
1562 }
1563 Tcl_SetObjResult(interp, dbTextToObj(pDb->zNull));
1564 break;
1565 }
1566
1567 /*
drhaf9ff332002-01-16 21:00:27 +00001568 ** $db last_insert_rowid
1569 **
1570 ** Return an integer which is the ROWID for the most recent insert.
1571 */
1572 case DB_LAST_INSERT_ROWID: {
1573 Tcl_Obj *pResult;
1574 int rowid;
1575 if( objc!=2 ){
1576 Tcl_WrongNumArgs(interp, 2, objv, "");
1577 return TCL_ERROR;
1578 }
danielk19776f8a5032004-05-10 10:34:51 +00001579 rowid = sqlite3_last_insert_rowid(pDb->db);
drhaf9ff332002-01-16 21:00:27 +00001580 pResult = Tcl_GetObjResult(interp);
1581 Tcl_SetIntObj(pResult, rowid);
1582 break;
1583 }
1584
1585 /*
drh1807ce32004-09-07 13:20:35 +00001586 ** The DB_ONECOLUMN method is implemented together with DB_EVAL.
drh5d9d7572003-08-19 14:31:01 +00001587 */
drh1807ce32004-09-07 13:20:35 +00001588
1589 /* $db progress ?N CALLBACK?
1590 **
1591 ** Invoke the given callback every N virtual machine opcodes while executing
1592 ** queries.
1593 */
1594 case DB_PROGRESS: {
1595 if( objc==2 ){
1596 if( pDb->zProgress ){
1597 Tcl_AppendResult(interp, pDb->zProgress, 0);
1598 }
1599 }else if( objc==4 ){
1600 char *zProgress;
1601 int len;
1602 int N;
1603 if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &N) ){
1604 return TCL_ERROR;
1605 };
1606 if( pDb->zProgress ){
1607 Tcl_Free(pDb->zProgress);
1608 }
1609 zProgress = Tcl_GetStringFromObj(objv[3], &len);
1610 if( zProgress && len>0 ){
1611 pDb->zProgress = Tcl_Alloc( len + 1 );
1612 strcpy(pDb->zProgress, zProgress);
1613 }else{
1614 pDb->zProgress = 0;
1615 }
1616#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
1617 if( pDb->zProgress ){
1618 pDb->interp = interp;
1619 sqlite3_progress_handler(pDb->db, N, DbProgressHandler, pDb);
1620 }else{
1621 sqlite3_progress_handler(pDb->db, 0, 0, 0);
1622 }
1623#endif
1624 }else{
1625 Tcl_WrongNumArgs(interp, 2, objv, "N CALLBACK");
drh5d9d7572003-08-19 14:31:01 +00001626 return TCL_ERROR;
1627 }
drh5d9d7572003-08-19 14:31:01 +00001628 break;
1629 }
1630
drh19e2d372005-08-29 23:00:03 +00001631 /* $db profile ?CALLBACK?
1632 **
1633 ** Make arrangements to invoke the CALLBACK routine after each SQL statement
1634 ** that has run. The text of the SQL and the amount of elapse time are
1635 ** appended to CALLBACK before the script is run.
1636 */
1637 case DB_PROFILE: {
1638 if( objc>3 ){
1639 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
1640 return TCL_ERROR;
1641 }else if( objc==2 ){
1642 if( pDb->zProfile ){
1643 Tcl_AppendResult(interp, pDb->zProfile, 0);
1644 }
1645 }else{
1646 char *zProfile;
1647 int len;
1648 if( pDb->zProfile ){
1649 Tcl_Free(pDb->zProfile);
1650 }
1651 zProfile = Tcl_GetStringFromObj(objv[2], &len);
1652 if( zProfile && len>0 ){
1653 pDb->zProfile = Tcl_Alloc( len + 1 );
1654 strcpy(pDb->zProfile, zProfile);
1655 }else{
1656 pDb->zProfile = 0;
1657 }
1658#ifndef SQLITE_OMIT_TRACE
1659 if( pDb->zProfile ){
1660 pDb->interp = interp;
1661 sqlite3_profile(pDb->db, DbProfileHandler, pDb);
1662 }else{
1663 sqlite3_profile(pDb->db, 0, 0);
1664 }
1665#endif
1666 }
1667 break;
1668 }
1669
drh5d9d7572003-08-19 14:31:01 +00001670 /*
drh22fbcb82004-02-01 01:22:50 +00001671 ** $db rekey KEY
1672 **
1673 ** Change the encryption key on the currently open database.
1674 */
1675 case DB_REKEY: {
1676 int nKey;
1677 void *pKey;
1678 if( objc!=3 ){
1679 Tcl_WrongNumArgs(interp, 2, objv, "KEY");
1680 return TCL_ERROR;
1681 }
1682 pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey);
drh9eb9e262004-02-11 02:18:05 +00001683#ifdef SQLITE_HAS_CODEC
drh2011d5f2004-07-22 02:40:37 +00001684 rc = sqlite3_rekey(pDb->db, pKey, nKey);
drh22fbcb82004-02-01 01:22:50 +00001685 if( rc ){
danielk1977f20b21c2004-05-31 23:56:42 +00001686 Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0);
drh22fbcb82004-02-01 01:22:50 +00001687 rc = TCL_ERROR;
1688 }
1689#endif
1690 break;
1691 }
1692
1693 /*
drhbec3f402000-08-04 13:49:02 +00001694 ** $db timeout MILLESECONDS
1695 **
1696 ** Delay for the number of milliseconds specified when a file is locked.
1697 */
drh6d313162000-09-21 13:01:35 +00001698 case DB_TIMEOUT: {
drhbec3f402000-08-04 13:49:02 +00001699 int ms;
drh6d313162000-09-21 13:01:35 +00001700 if( objc!=3 ){
1701 Tcl_WrongNumArgs(interp, 2, objv, "MILLISECONDS");
drhbec3f402000-08-04 13:49:02 +00001702 return TCL_ERROR;
1703 }
drh6d313162000-09-21 13:01:35 +00001704 if( Tcl_GetIntFromObj(interp, objv[2], &ms) ) return TCL_ERROR;
danielk19776f8a5032004-05-10 10:34:51 +00001705 sqlite3_busy_timeout(pDb->db, ms);
drh6d313162000-09-21 13:01:35 +00001706 break;
drh75897232000-05-29 14:26:00 +00001707 }
danielk19777ddad962005-12-12 06:53:03 +00001708
1709 /*
1710 ** $db soft_heap_limit N
1711 **
1712 ** Set the soft-heap-limit for this thread. Note that the limit is
1713 ** per-thread, not per-database.
1714 */
1715 case DB_SOFT_HEAP_LIMIT: {
1716 int n;
1717 if( objc!=3 ){
1718 Tcl_WrongNumArgs(interp, 2, objv, "BYTES");
1719 return TCL_ERROR;
1720 }
1721 if( Tcl_GetIntFromObj(interp, objv[2], &n) ){
1722 return TCL_ERROR;
1723 }
1724 sqlite3_soft_heap_limit(n);
1725 Tcl_ResetResult(interp);
1726 break;
1727 }
danielk197755c45f22005-04-03 23:54:43 +00001728
1729 /*
drh0f14e2e2004-06-29 12:39:08 +00001730 ** $db total_changes
1731 **
1732 ** Return the number of rows that were modified, inserted, or deleted
1733 ** since the database handle was created.
1734 */
1735 case DB_TOTAL_CHANGES: {
1736 Tcl_Obj *pResult;
1737 if( objc!=2 ){
1738 Tcl_WrongNumArgs(interp, 2, objv, "");
1739 return TCL_ERROR;
1740 }
1741 pResult = Tcl_GetObjResult(interp);
1742 Tcl_SetIntObj(pResult, sqlite3_total_changes(pDb->db));
1743 break;
1744 }
1745
drhb5a20d32003-04-23 12:25:23 +00001746 /* $db trace ?CALLBACK?
1747 **
1748 ** Make arrangements to invoke the CALLBACK routine for each SQL statement
1749 ** that is executed. The text of the SQL is appended to CALLBACK before
1750 ** it is executed.
1751 */
1752 case DB_TRACE: {
1753 if( objc>3 ){
1754 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
drhb97759e2004-06-29 11:26:59 +00001755 return TCL_ERROR;
drhb5a20d32003-04-23 12:25:23 +00001756 }else if( objc==2 ){
1757 if( pDb->zTrace ){
1758 Tcl_AppendResult(interp, pDb->zTrace, 0);
1759 }
1760 }else{
1761 char *zTrace;
1762 int len;
1763 if( pDb->zTrace ){
1764 Tcl_Free(pDb->zTrace);
1765 }
1766 zTrace = Tcl_GetStringFromObj(objv[2], &len);
1767 if( zTrace && len>0 ){
1768 pDb->zTrace = Tcl_Alloc( len + 1 );
1769 strcpy(pDb->zTrace, zTrace);
1770 }else{
1771 pDb->zTrace = 0;
1772 }
drh19e2d372005-08-29 23:00:03 +00001773#ifndef SQLITE_OMIT_TRACE
drhb5a20d32003-04-23 12:25:23 +00001774 if( pDb->zTrace ){
1775 pDb->interp = interp;
danielk19776f8a5032004-05-10 10:34:51 +00001776 sqlite3_trace(pDb->db, DbTraceHandler, pDb);
drhb5a20d32003-04-23 12:25:23 +00001777 }else{
danielk19776f8a5032004-05-10 10:34:51 +00001778 sqlite3_trace(pDb->db, 0, 0);
drhb5a20d32003-04-23 12:25:23 +00001779 }
drh19e2d372005-08-29 23:00:03 +00001780#endif
drhb5a20d32003-04-23 12:25:23 +00001781 }
1782 break;
1783 }
1784
drh3d214232005-08-02 12:21:08 +00001785 /* $db transaction [-deferred|-immediate|-exclusive] SCRIPT
1786 **
1787 ** Start a new transaction (if we are not already in the midst of a
1788 ** transaction) and execute the TCL script SCRIPT. After SCRIPT
1789 ** completes, either commit the transaction or roll it back if SCRIPT
1790 ** throws an exception. Or if no new transation was started, do nothing.
1791 ** pass the exception on up the stack.
1792 **
1793 ** This command was inspired by Dave Thomas's talk on Ruby at the
1794 ** 2005 O'Reilly Open Source Convention (OSCON).
1795 */
1796 case DB_TRANSACTION: {
1797 int inTrans;
1798 Tcl_Obj *pScript;
1799 const char *zBegin = "BEGIN";
1800 if( objc!=3 && objc!=4 ){
1801 Tcl_WrongNumArgs(interp, 2, objv, "[TYPE] SCRIPT");
1802 return TCL_ERROR;
1803 }
1804 if( objc==3 ){
1805 pScript = objv[2];
1806 } else {
1807 static const char *TTYPE_strs[] = {
drhce604012005-08-16 11:11:34 +00001808 "deferred", "exclusive", "immediate", 0
drh3d214232005-08-02 12:21:08 +00001809 };
1810 enum TTYPE_enum {
1811 TTYPE_DEFERRED, TTYPE_EXCLUSIVE, TTYPE_IMMEDIATE
1812 };
1813 int ttype;
drhb5555e72005-08-02 17:15:14 +00001814 if( Tcl_GetIndexFromObj(interp, objv[2], TTYPE_strs, "transaction type",
drh3d214232005-08-02 12:21:08 +00001815 0, &ttype) ){
1816 return TCL_ERROR;
1817 }
1818 switch( (enum TTYPE_enum)ttype ){
1819 case TTYPE_DEFERRED: /* no-op */; break;
1820 case TTYPE_EXCLUSIVE: zBegin = "BEGIN EXCLUSIVE"; break;
1821 case TTYPE_IMMEDIATE: zBegin = "BEGIN IMMEDIATE"; break;
1822 }
1823 pScript = objv[3];
1824 }
1825 inTrans = !sqlite3_get_autocommit(pDb->db);
1826 if( !inTrans ){
1827 sqlite3_exec(pDb->db, zBegin, 0, 0, 0);
1828 }
1829 rc = Tcl_EvalObjEx(interp, pScript, 0);
1830 if( !inTrans ){
1831 const char *zEnd;
1832 if( rc==TCL_ERROR ){
1833 zEnd = "ROLLBACK";
1834 } else {
1835 zEnd = "COMMIT";
1836 }
1837 sqlite3_exec(pDb->db, zEnd, 0, 0, 0);
1838 }
1839 break;
1840 }
1841
danielk19774397de52005-01-12 12:44:03 +00001842 /* $db version
1843 **
1844 ** Return the version string for this database.
1845 */
1846 case DB_VERSION: {
1847 Tcl_SetResult(interp, (char *)sqlite3_libversion(), TCL_STATIC);
1848 break;
1849 }
1850
tpoindex1067fe12004-12-17 15:41:11 +00001851
drh6d313162000-09-21 13:01:35 +00001852 } /* End of the SWITCH statement */
drh22fbcb82004-02-01 01:22:50 +00001853 return rc;
drh75897232000-05-29 14:26:00 +00001854}
1855
1856/*
drh9bb575f2004-09-06 17:24:11 +00001857** sqlite3 DBNAME FILENAME ?MODE? ?-key KEY?
drh75897232000-05-29 14:26:00 +00001858**
1859** This is the main Tcl command. When the "sqlite" Tcl command is
1860** invoked, this routine runs to process that command.
1861**
1862** The first argument, DBNAME, is an arbitrary name for a new
1863** database connection. This command creates a new command named
1864** DBNAME that is used to control that connection. The database
1865** connection is deleted when the DBNAME command is deleted.
1866**
1867** The second argument is the name of the directory that contains
1868** the sqlite database that is to be accessed.
drhfbc3eab2001-04-06 16:13:42 +00001869**
1870** For testing purposes, we also support the following:
1871**
drh9bb575f2004-09-06 17:24:11 +00001872** sqlite3 -encoding
drhfbc3eab2001-04-06 16:13:42 +00001873**
1874** Return the encoding used by LIKE and GLOB operators. Choices
1875** are UTF-8 and iso8859.
1876**
drh9bb575f2004-09-06 17:24:11 +00001877** sqlite3 -version
drh647cb0e2002-11-04 19:32:25 +00001878**
1879** Return the version number of the SQLite library.
1880**
drh9bb575f2004-09-06 17:24:11 +00001881** sqlite3 -tcl-uses-utf
drhfbc3eab2001-04-06 16:13:42 +00001882**
1883** Return "1" if compiled with a Tcl uses UTF-8. Return "0" if
1884** not. Used by tests to make sure the library was compiled
1885** correctly.
drh75897232000-05-29 14:26:00 +00001886*/
drh22fbcb82004-02-01 01:22:50 +00001887static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
drhbec3f402000-08-04 13:49:02 +00001888 SqliteDb *p;
drh22fbcb82004-02-01 01:22:50 +00001889 void *pKey = 0;
1890 int nKey = 0;
1891 const char *zArg;
drh75897232000-05-29 14:26:00 +00001892 char *zErrMsg;
drh22fbcb82004-02-01 01:22:50 +00001893 const char *zFile;
drh06b27182002-06-26 20:06:05 +00001894 char zBuf[80];
drh22fbcb82004-02-01 01:22:50 +00001895 if( objc==2 ){
1896 zArg = Tcl_GetStringFromObj(objv[1], 0);
drh22fbcb82004-02-01 01:22:50 +00001897 if( strcmp(zArg,"-version")==0 ){
danielk19776f8a5032004-05-10 10:34:51 +00001898 Tcl_AppendResult(interp,sqlite3_version,0);
drh647cb0e2002-11-04 19:32:25 +00001899 return TCL_OK;
1900 }
drh9eb9e262004-02-11 02:18:05 +00001901 if( strcmp(zArg,"-has-codec")==0 ){
1902#ifdef SQLITE_HAS_CODEC
drh22fbcb82004-02-01 01:22:50 +00001903 Tcl_AppendResult(interp,"1",0);
1904#else
1905 Tcl_AppendResult(interp,"0",0);
1906#endif
1907 return TCL_OK;
1908 }
1909 if( strcmp(zArg,"-tcl-uses-utf")==0 ){
drhfbc3eab2001-04-06 16:13:42 +00001910#ifdef TCL_UTF_MAX
1911 Tcl_AppendResult(interp,"1",0);
1912#else
1913 Tcl_AppendResult(interp,"0",0);
1914#endif
1915 return TCL_OK;
1916 }
1917 }
drh22fbcb82004-02-01 01:22:50 +00001918 if( objc==5 || objc==6 ){
1919 zArg = Tcl_GetStringFromObj(objv[objc-2], 0);
1920 if( strcmp(zArg,"-key")==0 ){
1921 pKey = Tcl_GetByteArrayFromObj(objv[objc-1], &nKey);
1922 objc -= 2;
1923 }
1924 }
1925 if( objc!=3 && objc!=4 ){
1926 Tcl_WrongNumArgs(interp, 1, objv,
drh9eb9e262004-02-11 02:18:05 +00001927#ifdef SQLITE_HAS_CODEC
1928 "HANDLE FILENAME ?-key CODEC-KEY?"
drh22fbcb82004-02-01 01:22:50 +00001929#else
1930 "HANDLE FILENAME ?MODE?"
1931#endif
1932 );
drh75897232000-05-29 14:26:00 +00001933 return TCL_ERROR;
1934 }
drh75897232000-05-29 14:26:00 +00001935 zErrMsg = 0;
drh4cdc9e82000-08-04 14:56:24 +00001936 p = (SqliteDb*)Tcl_Alloc( sizeof(*p) );
drh75897232000-05-29 14:26:00 +00001937 if( p==0 ){
drhbec3f402000-08-04 13:49:02 +00001938 Tcl_SetResult(interp, "malloc failed", TCL_STATIC);
1939 return TCL_ERROR;
1940 }
1941 memset(p, 0, sizeof(*p));
drh22fbcb82004-02-01 01:22:50 +00001942 zFile = Tcl_GetStringFromObj(objv[2], 0);
danielk19774f057f92004-06-08 00:02:33 +00001943 sqlite3_open(zFile, &p->db);
danielk197780290862004-05-22 09:21:21 +00001944 if( SQLITE_OK!=sqlite3_errcode(p->db) ){
1945 zErrMsg = strdup(sqlite3_errmsg(p->db));
1946 sqlite3_close(p->db);
1947 p->db = 0;
1948 }
drh2011d5f2004-07-22 02:40:37 +00001949#ifdef SQLITE_HAS_CODEC
1950 sqlite3_key(p->db, pKey, nKey);
drheb8ed702004-02-11 10:37:23 +00001951#endif
drhbec3f402000-08-04 13:49:02 +00001952 if( p->db==0 ){
drh75897232000-05-29 14:26:00 +00001953 Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE);
drhbec3f402000-08-04 13:49:02 +00001954 Tcl_Free((char*)p);
drh75897232000-05-29 14:26:00 +00001955 free(zErrMsg);
1956 return TCL_ERROR;
1957 }
drhfb7e7652005-01-24 00:28:42 +00001958 p->maxStmt = NUM_PREPARED_STMTS;
drh22fbcb82004-02-01 01:22:50 +00001959 zArg = Tcl_GetStringFromObj(objv[1], 0);
1960 Tcl_CreateObjCommand(interp, zArg, DbObjCmd, (char*)p, DbDeleteCmd);
drhc22bd472002-05-10 13:14:07 +00001961
drh06b27182002-06-26 20:06:05 +00001962 /* The return value is the value of the sqlite* pointer
1963 */
1964 sprintf(zBuf, "%p", p->db);
drh5e5377f2002-07-07 17:12:36 +00001965 if( strncmp(zBuf,"0x",2) ){
1966 sprintf(zBuf, "0x%p", p->db);
1967 }
drh06b27182002-06-26 20:06:05 +00001968 Tcl_AppendResult(interp, zBuf, 0);
1969
drhc22bd472002-05-10 13:14:07 +00001970 /* If compiled with SQLITE_TEST turned on, then register the "md5sum"
drh06b27182002-06-26 20:06:05 +00001971 ** SQL function.
drhc22bd472002-05-10 13:14:07 +00001972 */
drh28b4e482002-03-11 02:06:13 +00001973#ifdef SQLITE_TEST
1974 {
drh9bb575f2004-09-06 17:24:11 +00001975 extern void Md5_Register(sqlite3*);
drh3b93bc82005-01-13 23:54:32 +00001976#ifdef SQLITE_MEMDEBUG
danielk197713073932004-06-30 11:54:06 +00001977 int mallocfail = sqlite3_iMallocFail;
1978 sqlite3_iMallocFail = 0;
danielk19775b59af82004-06-30 12:42:59 +00001979#endif
drhc22bd472002-05-10 13:14:07 +00001980 Md5_Register(p->db);
drh3b93bc82005-01-13 23:54:32 +00001981#ifdef SQLITE_MEMDEBUG
danielk197713073932004-06-30 11:54:06 +00001982 sqlite3_iMallocFail = mallocfail;
danielk19775b59af82004-06-30 12:42:59 +00001983#endif
danielk19777ddad962005-12-12 06:53:03 +00001984 }
drh28b4e482002-03-11 02:06:13 +00001985#endif
danielk19777cedc8d2004-06-10 10:50:08 +00001986 p->interp = interp;
drh75897232000-05-29 14:26:00 +00001987 return TCL_OK;
1988}
1989
1990/*
drh90ca9752001-09-28 17:47:14 +00001991** Provide a dummy Tcl_InitStubs if we are using this as a static
1992** library.
1993*/
1994#ifndef USE_TCL_STUBS
1995# undef Tcl_InitStubs
1996# define Tcl_InitStubs(a,b,c)
1997#endif
1998
1999/*
drh29bc4612005-10-05 10:40:15 +00002000** Make sure we have a PACKAGE_VERSION macro defined. This will be
2001** defined automatically by the TEA makefile. But other makefiles
2002** do not define it.
2003*/
2004#ifndef PACKAGE_VERSION
2005# define PACKAGE_VERSION SQLITE_VERSION
2006#endif
2007
2008/*
drh75897232000-05-29 14:26:00 +00002009** Initialize this module.
2010**
2011** This Tcl module contains only a single new Tcl command named "sqlite".
2012** (Hence there is no namespace. There is no point in using a namespace
2013** if the extension only supplies one new name!) The "sqlite" command is
2014** used to open a new SQLite database. See the DbMain() routine above
2015** for additional information.
2016*/
drh29bc4612005-10-05 10:40:15 +00002017EXTERN int Sqlite3_Init(Tcl_Interp *interp){
drh92febd92004-08-20 18:34:20 +00002018 Tcl_InitStubs(interp, "8.4", 0);
drhef4ac8f2004-06-19 00:16:31 +00002019 Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0);
drh29bc4612005-10-05 10:40:15 +00002020 Tcl_PkgProvide(interp, "sqlite3", PACKAGE_VERSION);
drh49766d62005-01-08 18:42:28 +00002021 Tcl_CreateObjCommand(interp, "sqlite", (Tcl_ObjCmdProc*)DbMain, 0, 0);
drh29bc4612005-10-05 10:40:15 +00002022 Tcl_PkgProvide(interp, "sqlite", PACKAGE_VERSION);
drh90ca9752001-09-28 17:47:14 +00002023 return TCL_OK;
2024}
drh29bc4612005-10-05 10:40:15 +00002025EXTERN int Tclsqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
2026EXTERN int Sqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
2027EXTERN int Tclsqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
drh49766d62005-01-08 18:42:28 +00002028
2029#ifndef SQLITE_3_SUFFIX_ONLY
drh29bc4612005-10-05 10:40:15 +00002030EXTERN int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
2031EXTERN int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
2032EXTERN int Sqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
2033EXTERN int Tclsqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
drh49766d62005-01-08 18:42:28 +00002034#endif
drh75897232000-05-29 14:26:00 +00002035
drh3e27c022004-07-23 00:01:38 +00002036#ifdef TCLSH
2037/*****************************************************************************
2038** The code that follows is used to build standalone TCL interpreters
drh75897232000-05-29 14:26:00 +00002039*/
drh348784e2000-05-29 20:41:49 +00002040
2041/*
drh3e27c022004-07-23 00:01:38 +00002042** If the macro TCLSH is one, then put in code this for the
2043** "main" routine that will initialize Tcl and take input from
2044** standard input.
drh348784e2000-05-29 20:41:49 +00002045*/
drh3e27c022004-07-23 00:01:38 +00002046#if TCLSH==1
drh348784e2000-05-29 20:41:49 +00002047static char zMainloop[] =
2048 "set line {}\n"
2049 "while {![eof stdin]} {\n"
2050 "if {$line!=\"\"} {\n"
2051 "puts -nonewline \"> \"\n"
2052 "} else {\n"
2053 "puts -nonewline \"% \"\n"
2054 "}\n"
2055 "flush stdout\n"
2056 "append line [gets stdin]\n"
2057 "if {[info complete $line]} {\n"
2058 "if {[catch {uplevel #0 $line} result]} {\n"
2059 "puts stderr \"Error: $result\"\n"
2060 "} elseif {$result!=\"\"} {\n"
2061 "puts $result\n"
2062 "}\n"
2063 "set line {}\n"
2064 "} else {\n"
2065 "append line \\n\n"
2066 "}\n"
2067 "}\n"
2068;
drh3e27c022004-07-23 00:01:38 +00002069#endif
2070
2071/*
2072** If the macro TCLSH is two, then get the main loop code out of
2073** the separate file "spaceanal_tcl.h".
2074*/
2075#if TCLSH==2
2076static char zMainloop[] =
2077#include "spaceanal_tcl.h"
2078;
2079#endif
drh348784e2000-05-29 20:41:49 +00002080
2081#define TCLSH_MAIN main /* Needed to fake out mktclapp */
2082int TCLSH_MAIN(int argc, char **argv){
2083 Tcl_Interp *interp;
drh297ecf12001-04-05 15:57:13 +00002084 Tcl_FindExecutable(argv[0]);
drh348784e2000-05-29 20:41:49 +00002085 interp = Tcl_CreateInterp();
drh38f82712004-06-18 17:10:16 +00002086 Sqlite3_Init(interp);
drhd9b02572001-04-15 00:37:09 +00002087#ifdef SQLITE_TEST
drhd1bf3512001-04-07 15:24:33 +00002088 {
2089 extern int Sqlitetest1_Init(Tcl_Interp*);
drh5c4d9702001-08-20 00:33:58 +00002090 extern int Sqlitetest2_Init(Tcl_Interp*);
2091 extern int Sqlitetest3_Init(Tcl_Interp*);
drha6064dc2003-12-19 02:52:05 +00002092 extern int Sqlitetest4_Init(Tcl_Interp*);
danielk1977998b56c2004-05-06 23:37:52 +00002093 extern int Sqlitetest5_Init(Tcl_Interp*);
drh9c06c952005-11-26 00:25:00 +00002094 extern int Sqlitetest6_Init(Tcl_Interp*);
drhefc251d2001-07-01 22:12:01 +00002095 extern int Md5_Init(Tcl_Interp*);
drh2e66f0b2005-04-28 17:18:48 +00002096 extern int Sqlitetestsse_Init(Tcl_Interp*);
2097
danielk19776490beb2004-05-11 06:17:21 +00002098 Sqlitetest1_Init(interp);
drh5c4d9702001-08-20 00:33:58 +00002099 Sqlitetest2_Init(interp);
drhde647132004-05-07 17:57:49 +00002100 Sqlitetest3_Init(interp);
danielk1977fc57d7b2004-05-26 02:04:57 +00002101 Sqlitetest4_Init(interp);
danielk1977998b56c2004-05-06 23:37:52 +00002102 Sqlitetest5_Init(interp);
drh9c06c952005-11-26 00:25:00 +00002103 Sqlitetest6_Init(interp);
drhefc251d2001-07-01 22:12:01 +00002104 Md5_Init(interp);
drh89dec812005-04-28 19:03:37 +00002105#ifdef SQLITE_SSE
drh2e66f0b2005-04-28 17:18:48 +00002106 Sqlitetestsse_Init(interp);
2107#endif
drhd1bf3512001-04-07 15:24:33 +00002108 }
2109#endif
drh3e27c022004-07-23 00:01:38 +00002110 if( argc>=2 || TCLSH==2 ){
drh348784e2000-05-29 20:41:49 +00002111 int i;
2112 Tcl_SetVar(interp,"argv0",argv[1],TCL_GLOBAL_ONLY);
2113 Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY);
drh61212b62004-12-02 20:17:00 +00002114 for(i=3-TCLSH; i<argc; i++){
drh348784e2000-05-29 20:41:49 +00002115 Tcl_SetVar(interp, "argv", argv[i],
2116 TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE);
2117 }
drh3e27c022004-07-23 00:01:38 +00002118 if( TCLSH==1 && Tcl_EvalFile(interp, argv[1])!=TCL_OK ){
drh0de8c112002-07-06 16:32:14 +00002119 const char *zInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
drhc61053b2000-06-04 12:58:36 +00002120 if( zInfo==0 ) zInfo = interp->result;
2121 fprintf(stderr,"%s: %s\n", *argv, zInfo);
drh348784e2000-05-29 20:41:49 +00002122 return 1;
2123 }
drh3e27c022004-07-23 00:01:38 +00002124 }
2125 if( argc<=1 || TCLSH==2 ){
drh348784e2000-05-29 20:41:49 +00002126 Tcl_GlobalEval(interp, zMainloop);
2127 }
2128 return 0;
2129}
2130#endif /* TCLSH */
drh6d313162000-09-21 13:01:35 +00002131
2132#endif /* !defined(NO_TCL) */