examples/tip.tcl: Use 'writable' when sending output
[jimtcl.git] / sqlite3 / jim-sqlite3.c
blob260f1ee6cd1c59c4ff78d7ee04a06aff008e8c26
1 /* Jim Tcl version of the sqlite3 Tcl binding.
2 * From sqlite3 3.6.22
4 * This version is (c) Steve Bennett <steveb@workware.net.au>
5 * Copyright of the original version is below.
6 */
8 /*
9 ** 2001 September 15
11 ** The author disclaims copyright to this source code. In place of
12 ** a legal notice, here is a blessing:
14 ** May you do good and not evil.
15 ** May you find forgiveness for yourself and forgive others.
16 ** May you share freely, never taking more than you give.
18 *************************************************************************
19 ** A TCL Interface to SQLite. Append this file to sqlite3.c and
20 ** compile the whole thing to build a TCL-enabled version of SQLite.
22 ** Compile-time options:
24 ** -D SQLITE_TEST When used in conjuction with -DTCLSH=1, add
25 ** hundreds of new commands used for testing
26 ** SQLite. This option implies -DSQLITE_TCLMD5.
28 #include <jim.h>
29 #include <jim-config.h>
30 #include <jim-eventloop.h>
31 #include <errno.h>
34 ** Some additional include files are needed if this file is not
35 ** appended to the amalgamation.
37 #ifndef SQLITE_AMALGAMATION
38 # include "sqlite3.h"
39 # include <stdlib.h>
40 # include <string.h>
41 # include <assert.h>
42 typedef unsigned char u8;
43 #endif
44 #include <ctype.h>
46 #define NUM_PREPARED_STMTS 10
47 #define MAX_PREPARED_STMTS 100
50 ** If Jim Tcl uses UTF-8 and SQLite is configured to use iso8859, then we
51 #ifdef JIM_UTF8
52 #define SQLITE_UTF8
53 #endif
55 ** have to do a translation when going between the two. Set the
56 ** UTF_TRANSLATION_NEEDED macro to indicate that we need to do
57 ** this translation.
59 #if defined(JIM_UTF8) && !defined(SQLITE_UTF8)
60 # define UTF_TRANSLATION_NEEDED 1
61 # warning Jim Tcl can not translate encoding from iso8859 to utf-8
62 #endif
65 ** New SQL functions can be created as TCL scripts. Each such function
66 ** is described by an instance of the following structure.
68 typedef struct SqlFunc SqlFunc;
69 struct SqlFunc {
70 Jim_Interp *interp; /* The TCL interpret to execute the function */
71 Jim_Obj *pScript; /* The Jim_Obj representation of the script */
72 int useEvalObjv; /* True if it is safe to use Jim_EvalObjv */
73 char *zName; /* Name of this function */
74 SqlFunc *pNext; /* Next function on the list of them all */
78 ** New collation sequences function can be created as TCL scripts. Each such
79 ** function is described by an instance of the following structure.
81 typedef struct SqlCollate SqlCollate;
82 struct SqlCollate {
83 Jim_Interp *interp; /* The TCL interpret to execute the function */
84 char *zScript; /* The script to be run */
85 SqlCollate *pNext; /* Next function on the list of them all */
89 ** Prepared statements are cached for faster execution. Each prepared
90 ** statement is described by an instance of the following structure.
92 typedef struct SqlPreparedStmt SqlPreparedStmt;
93 struct SqlPreparedStmt {
94 SqlPreparedStmt *pNext; /* Next in linked list */
95 SqlPreparedStmt *pPrev; /* Previous on the list */
96 sqlite3_stmt *pStmt; /* The prepared statement */
97 int nSql; /* chars in zSql[] */
98 const char *zSql; /* Text of the SQL statement */
99 int nParm; /* Size of apParm array */
100 Jim_Obj **apParm; /* Array of referenced object pointers */
103 typedef struct IncrblobChannel IncrblobChannel;
106 ** There is one instance of this structure for each SQLite database
107 ** that has been opened by the SQLite TCL interface.
109 typedef struct SqliteDb SqliteDb;
110 struct SqliteDb {
111 sqlite3 *db; /* The "real" database structure. MUST BE FIRST */
112 Jim_Interp *interp; /* The interpreter used for this database */
113 char *zBusy; /* The busy callback routine */
114 char *zCommit; /* The commit hook callback routine */
115 char *zTrace; /* The trace callback routine */
116 char *zProfile; /* The profile callback routine */
117 char *zProgress; /* The progress callback routine */
118 char *zAuth; /* The authorization callback routine */
119 int disableAuth; /* Disable the authorizer if it exists */
120 char *zNull; /* Text to substitute for an SQL NULL value */
121 SqlFunc *pFunc; /* List of SQL functions */
122 Jim_Obj *pUpdateHook; /* Update hook script (if any) */
123 Jim_Obj *pRollbackHook; /* Rollback hook script (if any) */
124 Jim_Obj *pUnlockNotify; /* Unlock notify script (if any) */
125 SqlCollate *pCollate; /* List of SQL collation functions */
126 int rc; /* Return code of most recent sqlite3_exec() */
127 Jim_Obj *pCollateNeeded; /* Collation needed script */
128 SqlPreparedStmt *stmtList; /* List of prepared statements*/
129 SqlPreparedStmt *stmtLast; /* Last statement in the list */
130 int maxStmt; /* The next maximum number of stmtList */
131 int nStmt; /* Number of statements in stmtList */
132 IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */
133 int nStep, nSort; /* Statistics for most recent operation */
134 int nTransaction; /* Number of nested [transaction] methods */
137 struct IncrblobChannel {
138 sqlite3_blob *pBlob; /* sqlite3 blob handle */
139 SqliteDb *pDb; /* Associated database connection */
140 int iSeek; /* Current seek offset */
141 Jim_Obj *channel; /* Channel identifier */
142 IncrblobChannel *pNext; /* Linked list of all open incrblob channels */
143 IncrblobChannel *pPrev; /* Linked list of all open incrblob channels */
147 ** Compute a string length that is limited to what can be stored in
148 ** lower 30 bits of a 32-bit signed integer.
150 static int strlen30(const char *z){
151 const char *z2 = z;
152 while( *z2 ){ z2++; }
153 return 0x3fffffff & (int)(z2 - z);
157 #ifndef SQLITE_OMIT_INCRBLOB
159 ** Close all incrblob channels opened using database connection pDb.
160 ** This is called when shutting down the database connection.
162 static void closeIncrblobChannels(SqliteDb *pDb){
163 IncrblobChannel *p;
164 IncrblobChannel *pNext;
166 for(p=pDb->pIncrblob; p; p=pNext){
167 pNext = p->pNext;
169 /* Note: Calling unregister here call Jim_Close on the incrblob channel,
170 ** which deletes the IncrblobChannel structure at *p. So do not
171 ** call Jim_Free() here.
173 Jim_UnregisterChannel(pDb->interp, p->channel);
178 ** Close an incremental blob channel.
180 static int incrblobClose(ClientData instanceData, Jim_Interp *interp){
181 IncrblobChannel *p = (IncrblobChannel *)instanceData;
182 int rc = sqlite3_blob_close(p->pBlob);
183 sqlite3 *db = p->pDb->db;
185 /* Remove the channel from the SqliteDb.pIncrblob list. */
186 if( p->pNext ){
187 p->pNext->pPrev = p->pPrev;
189 if( p->pPrev ){
190 p->pPrev->pNext = p->pNext;
192 if( p->pDb->pIncrblob==p ){
193 p->pDb->pIncrblob = p->pNext;
196 /* Free the IncrblobChannel structure */
197 Jim_Free((char *)p);
199 if( rc!=SQLITE_OK ){
200 Jim_SetResult(interp, (char *)sqlite3_errmsg(db), JIM_VOLATILE);
201 return JIM_ERR;
203 return JIM_OK;
207 ** Read data from an incremental blob channel.
209 static int incrblobInput(
210 ClientData instanceData,
211 char *buf,
212 int bufSize,
213 int *errorCodePtr
215 IncrblobChannel *p = (IncrblobChannel *)instanceData;
216 int nRead = bufSize; /* Number of bytes to read */
217 int nBlob; /* Total size of the blob */
218 int rc; /* sqlite error code */
220 nBlob = sqlite3_blob_bytes(p->pBlob);
221 if( (p->iSeek+nRead)>nBlob ){
222 nRead = nBlob-p->iSeek;
224 if( nRead<=0 ){
225 return 0;
228 rc = sqlite3_blob_read(p->pBlob, (void *)buf, nRead, p->iSeek);
229 if( rc!=SQLITE_OK ){
230 *errorCodePtr = rc;
231 return -1;
234 p->iSeek += nRead;
235 return nRead;
239 ** Write data to an incremental blob channel.
241 static int incrblobOutput(
242 ClientData instanceData,
243 CONST char *buf,
244 int toWrite,
245 int *errorCodePtr
247 IncrblobChannel *p = (IncrblobChannel *)instanceData;
248 int nWrite = toWrite; /* Number of bytes to write */
249 int nBlob; /* Total size of the blob */
250 int rc; /* sqlite error code */
252 nBlob = sqlite3_blob_bytes(p->pBlob);
253 if( (p->iSeek+nWrite)>nBlob ){
254 *errorCodePtr = EINVAL;
255 return -1;
257 if( nWrite<=0 ){
258 return 0;
261 rc = sqlite3_blob_write(p->pBlob, (void *)buf, nWrite, p->iSeek);
262 if( rc!=SQLITE_OK ){
263 *errorCodePtr = EIO;
264 return -1;
267 p->iSeek += nWrite;
268 return nWrite;
272 ** Seek an incremental blob channel.
274 static int incrblobSeek(
275 ClientData instanceData,
276 long offset,
277 int seekMode,
278 int *errorCodePtr
280 IncrblobChannel *p = (IncrblobChannel *)instanceData;
282 switch( seekMode ){
283 case SEEK_SET:
284 p->iSeek = offset;
285 break;
286 case SEEK_CUR:
287 p->iSeek += offset;
288 break;
289 case SEEK_END:
290 p->iSeek = sqlite3_blob_bytes(p->pBlob) + offset;
291 break;
293 default: assert(!"Bad seekMode");
296 return p->iSeek;
300 static void incrblobWatch(ClientData instanceData, int mode){
301 /* NO-OP */
303 static int incrblobHandle(ClientData instanceData, int dir, ClientData *hPtr){
304 return JIM_ERR;
307 static Jim_ChannelType IncrblobChannelType = {
308 "incrblob", /* typeName */
309 JIM_CHANNEL_VERSION_2, /* version */
310 incrblobClose, /* closeProc */
311 incrblobInput, /* inputProc */
312 incrblobOutput, /* outputProc */
313 incrblobSeek, /* seekProc */
314 0, /* setOptionProc */
315 0, /* getOptionProc */
316 incrblobWatch, /* watchProc (this is a no-op) */
317 incrblobHandle, /* getHandleProc (always returns error) */
318 0, /* close2Proc */
319 0, /* blockModeProc */
320 0, /* flushProc */
321 0, /* handlerProc */
322 0, /* wideSeekProc */
326 ** Create a new incrblob channel.
328 static int createIncrblobChannel(
329 Jim_Interp *interp,
330 SqliteDb *pDb,
331 const char *zDb,
332 const char *zTable,
333 const char *zColumn,
334 sqlite_int64 iRow,
335 int isReadonly
337 IncrblobChannel *p;
338 sqlite3 *db = pDb->db;
339 sqlite3_blob *pBlob;
340 int rc;
341 int flags = JIM_READABLE|(isReadonly ? 0 : JIM_WRITABLE);
343 /* This variable is used to name the channels: "incrblob_[incr count]" */
344 static int count = 0;
345 char zChannel[64];
347 rc = sqlite3_blob_open(db, zDb, zTable, zColumn, iRow, !isReadonly, &pBlob);
348 if( rc!=SQLITE_OK ){
349 Jim_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), JIM_VOLATILE);
350 return JIM_ERR;
353 p = (IncrblobChannel *)Jim_Alloc(sizeof(IncrblobChannel));
354 p->iSeek = 0;
355 p->pBlob = pBlob;
357 sqlite3_snprintf(sizeof(zChannel), zChannel, "incrblob_%d", ++count);
358 p->channel = Jim_CreateChannel(&IncrblobChannelType, zChannel, p, flags);
359 Jim_RegisterChannel(interp, p->channel);
361 /* Link the new channel into the SqliteDb.pIncrblob list. */
362 p->pNext = pDb->pIncrblob;
363 p->pPrev = 0;
364 if( p->pNext ){
365 p->pNext->pPrev = p;
367 pDb->pIncrblob = p;
368 p->pDb = pDb;
370 Jim_SetResult(interp, (char *)Jim_GetChannelName(p->channel), JIM_VOLATILE);
371 return JIM_OK;
373 #else /* else clause for "#ifndef SQLITE_OMIT_INCRBLOB" */
374 #define closeIncrblobChannels(pDb)
375 #endif
378 ** Look at the script prefix in pCmd. We will be executing this script
379 ** after first appending one or more arguments. This routine analyzes
380 ** the script to see if it is safe to use Jim_EvalObjv() on the script
381 ** rather than the more general Jim_EvalEx(). Jim_EvalObjv() is much
382 ** faster.
384 ** Scripts that are safe to use with Jim_EvalObjv() consists of a
385 ** command name followed by zero or more arguments with no [...] or $
386 ** or {...} or ; to be seen anywhere. Most callback scripts consist
387 ** of just a single procedure name and they meet this requirement.
389 static int safeToUseEvalObjv(Jim_Interp *interp, Jim_Obj *pCmd){
390 /* We could try to do something with Jim_Parse(). But we will instead
391 ** just do a search for forbidden characters. If any of the forbidden
392 ** characters appear in pCmd, we will report the string as unsafe.
394 const char *z;
395 int n;
396 z = Jim_GetString(pCmd, &n);
397 while( n-- > 0 ){
398 int c = *(z++);
399 if( c=='$' || c=='[' || c==';' ) return 0;
401 return 1;
405 ** Find an SqlFunc structure with the given name. Or create a new
406 ** one if an existing one cannot be found. Return a pointer to the
407 ** structure.
409 static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){
410 SqlFunc *p, *pNew;
411 int i;
412 pNew = (SqlFunc*)Jim_Alloc( sizeof(*pNew) + strlen30(zName) + 1 );
413 pNew->zName = (char*)&pNew[1];
414 for(i=0; zName[i]; i++){ pNew->zName[i] = tolower((unsigned)zName[i]); }
415 pNew->zName[i] = 0;
416 for(p=pDb->pFunc; p; p=p->pNext){
417 if( strcmp(p->zName, pNew->zName)==0 ){
418 Jim_Free((char*)pNew);
419 return p;
422 pNew->interp = pDb->interp;
423 pNew->pScript = 0;
424 pNew->pNext = pDb->pFunc;
425 pDb->pFunc = pNew;
426 return pNew;
430 ** Finalize and free a list of prepared statements
432 static void flushStmtCache( SqliteDb *pDb ){
433 SqlPreparedStmt *pPreStmt;
435 while( pDb->stmtList ){
436 sqlite3_finalize( pDb->stmtList->pStmt );
437 pPreStmt = pDb->stmtList;
438 pDb->stmtList = pDb->stmtList->pNext;
439 Jim_Free( (char*)pPreStmt );
441 pDb->nStmt = 0;
442 pDb->stmtLast = 0;
446 ** TCL calls this procedure when an sqlite3 database command is
447 ** deleted.
449 static void DbDeleteCmd(Jim_Interp *interp, void *db){
450 SqliteDb *pDb = (SqliteDb*)db;
451 flushStmtCache(pDb);
452 closeIncrblobChannels(pDb);
453 sqlite3_close(pDb->db);
454 while( pDb->pFunc ){
455 SqlFunc *pFunc = pDb->pFunc;
456 pDb->pFunc = pFunc->pNext;
457 Jim_DecrRefCount(interp, pFunc->pScript);
458 Jim_Free((char*)pFunc);
460 while( pDb->pCollate ){
461 SqlCollate *pCollate = pDb->pCollate;
462 pDb->pCollate = pCollate->pNext;
463 Jim_Free((char*)pCollate);
465 if( pDb->zBusy ){
466 Jim_Free(pDb->zBusy);
468 if( pDb->zTrace ){
469 Jim_Free(pDb->zTrace);
471 if( pDb->zProfile ){
472 Jim_Free(pDb->zProfile);
474 if( pDb->zAuth ){
475 Jim_Free(pDb->zAuth);
477 if( pDb->zNull ){
478 Jim_Free(pDb->zNull);
480 if( pDb->pUpdateHook ){
481 Jim_DecrRefCount(interp, pDb->pUpdateHook);
483 if( pDb->pRollbackHook ){
484 Jim_DecrRefCount(interp, pDb->pRollbackHook);
486 if( pDb->pCollateNeeded ){
487 Jim_DecrRefCount(interp, pDb->pCollateNeeded);
489 Jim_Free((char*)pDb);
493 ** This routine is called when a database file is locked while trying
494 ** to execute SQL.
496 static int DbBusyHandler(void *cd, int nTries){
497 SqliteDb *pDb = (SqliteDb*)cd;
498 int rc;
499 char zVal[30];
500 Jim_Obj *objPtr;
502 sqlite3_snprintf(sizeof(zVal), zVal, "%d", nTries);
504 objPtr = Jim_NewStringObj(pDb->interp, pDb->zBusy, -1);
505 Jim_AppendStrings(pDb->interp, objPtr, " ", zVal, NULL);
506 rc = Jim_EvalObj(pDb->interp, objPtr);
507 if( rc!=JIM_OK || atoi(Jim_String(Jim_GetResult(pDb->interp))) ){
508 return 0;
510 return 1;
513 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
515 ** This routine is invoked as the 'progress callback' for the database.
517 static int DbProgressHandler(void *cd){
518 SqliteDb *pDb = (SqliteDb*)cd;
519 int rc;
521 assert( pDb->zProgress );
522 rc = Jim_Eval(pDb->interp, pDb->zProgress);
523 if( rc!=JIM_OK || atoi(Jim_String(Jim_GetResult(pDb->interp))) ){
524 return 1;
526 return 0;
528 #endif
530 #ifndef SQLITE_OMIT_TRACE
532 ** This routine is called by the SQLite trace handler whenever a new
533 ** block of SQL is executed. The TCL script in pDb->zTrace is executed.
535 static void DbTraceHandler(void *cd, const char *zSql){
536 SqliteDb *pDb = (SqliteDb*)cd;
538 Jim_Obj *str = Jim_NewStringObj(pDb->interp, pDb->zTrace, -1);
539 Jim_ListAppendElement(pDb->interp, str, Jim_NewStringObj(pDb->interp, zSql, -1));
540 Jim_Eval(pDb->interp, zSql);
541 Jim_SetEmptyResult(pDb->interp);
543 #endif
545 #ifndef SQLITE_OMIT_TRACE
547 ** This routine is called by the SQLite profile handler after a statement
548 ** SQL has executed. The TCL script in pDb->zProfile is evaluated.
550 static void DbProfileHandler(void *cd, const char *zSql, sqlite_uint64 tm){
551 SqliteDb *pDb = (SqliteDb*)cd;
552 Jim_Obj *str;
553 char zTm[100];
555 sqlite3_snprintf(sizeof(zTm)-1, zTm, "%lld", tm);
556 str = Jim_NewStringObj(pDb->interp, pDb->zProfile, -1);
557 Jim_ListAppendElement(pDb->interp, str, Jim_NewStringObj(pDb->interp, zSql, -1));
558 Jim_ListAppendElement(pDb->interp, str, Jim_NewStringObj(pDb->interp, zTm, -1));
559 Jim_EvalObj(pDb->interp, str);
560 Jim_SetEmptyResult(pDb->interp);
562 #endif
565 ** This routine is called when a transaction is committed. The
566 ** TCL script in pDb->zCommit is executed. If it returns non-zero or
567 ** if it throws an exception, the transaction is rolled back instead
568 ** of being committed.
570 static int DbCommitHandler(void *cd){
571 SqliteDb *pDb = (SqliteDb*)cd;
572 int rc;
574 rc = Jim_Eval(pDb->interp, pDb->zCommit);
575 if( rc!=JIM_OK || atoi(Jim_String(Jim_GetResult(pDb->interp))) ){
576 return 1;
578 return 0;
581 static void DbRollbackHandler(void *clientData){
582 SqliteDb *pDb = (SqliteDb*)clientData;
583 assert(pDb->pRollbackHook);
584 Jim_EvalObjBackground(pDb->interp, pDb->pRollbackHook);
587 #if defined(SQLITE_TEST) && defined(SQLITE_ENABLE_UNLOCK_NOTIFY)
588 static void setTestUnlockNotifyVars(Jim_Interp *interp, int iArg, int nArg){
589 char zBuf[64];
590 sprintf(zBuf, "%d", iArg);
591 Jim_SetVar(interp, "sqlite_unlock_notify_arg", zBuf, JIM_GLOBAL_ONLY);
592 sprintf(zBuf, "%d", nArg);
593 Jim_SetVar(interp, "sqlite_unlock_notify_argcount", zBuf, JIM_GLOBAL_ONLY);
595 #else
596 # define setTestUnlockNotifyVars(x,y,z)
597 #endif
599 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
600 static void DbUnlockNotify(void **apArg, int nArg){
601 int i;
602 for(i=0; i<nArg; i++){
603 const int flags = (JIM_EVAL_GLOBAL|JIM_EVAL_DIRECT);
604 SqliteDb *pDb = (SqliteDb *)apArg[i];
605 setTestUnlockNotifyVars(pDb->interp, i, nArg);
606 assert( pDb->pUnlockNotify);
607 Jim_EvalObjEx(pDb->interp, pDb->pUnlockNotify, flags);
608 Jim_DecrRefCount(interp, pDb->pUnlockNotify);
609 pDb->pUnlockNotify = 0;
612 #endif
614 static void DbUpdateHandler(
615 void *p,
616 int op,
617 const char *zDb,
618 const char *zTbl,
619 sqlite_int64 rowid
621 SqliteDb *pDb = (SqliteDb *)p;
622 Jim_Obj *pCmd;
624 assert( pDb->pUpdateHook );
625 assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE );
627 pCmd = Jim_DuplicateObj(pDb->interp, pDb->pUpdateHook);
628 Jim_IncrRefCount(pCmd);
629 Jim_ListAppendElement(0, pCmd, Jim_NewStringObj(pDb->interp,
630 ( (op==SQLITE_INSERT)?"INSERT":(op==SQLITE_UPDATE)?"UPDATE":"DELETE"), -1));
631 Jim_ListAppendElement(pDb->interp, pCmd, Jim_NewStringObj(pDb->interp, zDb, -1));
632 Jim_ListAppendElement(pDb->interp, pCmd, Jim_NewStringObj(pDb->interp, zTbl, -1));
633 Jim_ListAppendElement(pDb->interp, pCmd, Jim_NewIntObj(pDb->interp, rowid));
634 Jim_EvalObj(pDb->interp, pCmd);
637 static void tclCollateNeeded(
638 void *pCtx,
639 sqlite3 *db,
640 int enc,
641 const char *zName
643 SqliteDb *pDb = (SqliteDb *)pCtx;
644 Jim_Obj *pScript = Jim_DuplicateObj(pDb->interp, pDb->pCollateNeeded);
645 //Jim_IncrRefCount(pScript);
646 Jim_ListAppendElement(pDb->interp, pScript, Jim_NewStringObj(pDb->interp, zName, -1));
647 Jim_EvalObj(pDb->interp, pScript);
648 //Jim_DecrRefCount(pDb->interp, pScript);
652 ** This routine is called to evaluate an SQL collation function implemented
653 ** using TCL script.
655 static int tclSqlCollate(
656 void *pCtx,
657 int nA,
658 const void *zA,
659 int nB,
660 const void *zB
662 SqlCollate *p = (SqlCollate *)pCtx;
663 Jim_Obj *pCmd;
665 pCmd = Jim_NewStringObj(p->interp, p->zScript, -1);
666 //Jim_IncrRefCount(pCmd);
667 Jim_ListAppendElement(p->interp, pCmd, Jim_NewStringObj(p->interp, zA, nA));
668 Jim_ListAppendElement(p->interp, pCmd, Jim_NewStringObj(p->interp, zB, nB));
669 Jim_EvalObj(p->interp, pCmd);
670 //Jim_DecrRefCount(interp, pCmd);
671 return (atoi(Jim_String(Jim_GetResult(p->interp))));
675 ** This routine is called to evaluate an SQL function implemented
676 ** using TCL script.
678 static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
679 SqlFunc *p = sqlite3_user_data(context);
680 Jim_Obj *pCmd;
681 int i;
682 int rc;
684 if( argc==0 ){
685 /* If there are no arguments to the function, call Jim_EvalObjEx on the
686 ** script object directly. This allows the TCL compiler to generate
687 ** bytecode for the command on the first invocation and thus make
688 ** subsequent invocations much faster. */
689 pCmd = p->pScript;
690 //Jim_IncrRefCount(pCmd);
691 rc = Jim_EvalObj(p->interp, pCmd);
692 //Jim_DecrRefCount(interp, pCmd);
693 }else{
694 /* If there are arguments to the function, make a shallow copy of the
695 ** script object, lappend the arguments, then evaluate the copy.
697 ** By "shallow" copy, we mean a only the outer list Jim_Obj is duplicated.
698 ** The new Jim_Obj contains pointers to the original list elements.
699 ** That way, when Jim_EvalObjv() is run and shimmers the first element
700 ** of the list to tclCmdNameType, that alternate representation will
701 ** be preserved and reused on the next invocation.
703 pCmd = Jim_DuplicateObj(p->interp, p->pScript);
704 Jim_IncrRefCount(pCmd);
705 for(i=0; i<argc; i++){
706 sqlite3_value *pIn = argv[i];
707 Jim_Obj *pVal;
709 /* Set pVal to contain the i'th column of this row. */
710 switch( sqlite3_value_type(pIn) ){
711 case SQLITE_BLOB: {
712 int bytes = sqlite3_value_bytes(pIn);
713 pVal = Jim_NewStringObj(p->interp, sqlite3_value_blob(pIn), bytes);
714 break;
716 case SQLITE_INTEGER: {
717 sqlite_int64 v = sqlite3_value_int64(pIn);
718 pVal = Jim_NewIntObj(p->interp, v);
719 break;
721 case SQLITE_FLOAT: {
722 double r = sqlite3_value_double(pIn);
723 pVal = Jim_NewDoubleObj(p->interp, r);
724 break;
726 case SQLITE_NULL: {
727 pVal = Jim_NewStringObj(p->interp, "", 0);
728 break;
730 default: {
731 int bytes = sqlite3_value_bytes(pIn);
732 pVal = Jim_NewStringObj(p->interp, (char *)sqlite3_value_text(pIn), bytes);
733 break;
736 Jim_ListAppendElement(p->interp, pCmd, pVal);
738 if( !p->useEvalObjv ){
739 /* Jim_EvalOb() will automatically call Jim_EvalObjVector() if pCmd
740 ** is a list without a string representation. To prevent this from
741 ** happening, make sure pCmd has a valid string representation */
742 Jim_String(pCmd);
744 rc = Jim_EvalObj(p->interp, pCmd);
745 Jim_DecrRefCount(p->interp, pCmd);
748 if( rc && rc!=JIM_RETURN ){
749 sqlite3_result_error(context, Jim_String(Jim_GetResult(p->interp)), -1);
750 }else{
751 Jim_Obj *pVar = Jim_GetResult(p->interp);
752 int n;
753 u8 *data;
754 /* XXX: Jim Tcl doesn't have bytearray or boolean */
755 const char *zType = (pVar->typePtr ? pVar->typePtr->name : "");
756 char c = zType[0];
757 #if 0
758 if( c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0 ){
759 /* Only return a BLOB type if the Tcl variable is a bytearray and
760 ** has no string representation. */
761 data = Jim_GetByteArrayFromObj(pVar, &n);
762 sqlite3_result_blob(context, data, n, SQLITE_TRANSIENT);
763 }else if( c=='b' && strcmp(zType,"boolean")==0 ){
764 Jim_GetWide(0, pVar, &n);
765 sqlite3_result_int(context, n);
766 }else
767 #endif
768 if( c=='d' && strcmp(zType,"double")==0 ){
769 double r;
770 Jim_GetDouble(0, pVar, &r);
771 sqlite3_result_double(context, r);
772 /* XXX: Is a cooerced double better as a double or an int? */
773 }else if( (c=='c' && strcmp(zType,"coerced-double")==0) ||
774 (c=='i' && strcmp(zType,"int")==0) ){
775 jim_wide v;
776 Jim_GetWide(p->interp, pVar, &v);
777 sqlite3_result_int64(context, v);
778 }else{
779 data = (unsigned char *)Jim_GetString(pVar, &n);
780 sqlite3_result_text(context, (char *)data, n, SQLITE_TRANSIENT);
785 #ifndef SQLITE_OMIT_AUTHORIZATION
787 ** This is the authentication function. It appends the authentication
788 ** type code and the two arguments to zCmd[] then invokes the result
789 ** on the interpreter. The reply is examined to determine if the
790 ** authentication fails or succeeds.
792 static int auth_callback(
793 void *pArg,
794 int code,
795 const char *zArg1,
796 const char *zArg2,
797 const char *zArg3,
798 const char *zArg4
800 char *zCode;
801 Jim_Obj *str;
802 int rc;
803 const char *zReply;
804 SqliteDb *pDb = (SqliteDb*)pArg;
805 if( pDb->disableAuth ) return SQLITE_OK;
807 switch( code ){
808 case SQLITE_COPY : zCode="SQLITE_COPY"; break;
809 case SQLITE_CREATE_INDEX : zCode="SQLITE_CREATE_INDEX"; break;
810 case SQLITE_CREATE_TABLE : zCode="SQLITE_CREATE_TABLE"; break;
811 case SQLITE_CREATE_TEMP_INDEX : zCode="SQLITE_CREATE_TEMP_INDEX"; break;
812 case SQLITE_CREATE_TEMP_TABLE : zCode="SQLITE_CREATE_TEMP_TABLE"; break;
813 case SQLITE_CREATE_TEMP_TRIGGER: zCode="SQLITE_CREATE_TEMP_TRIGGER"; break;
814 case SQLITE_CREATE_TEMP_VIEW : zCode="SQLITE_CREATE_TEMP_VIEW"; break;
815 case SQLITE_CREATE_TRIGGER : zCode="SQLITE_CREATE_TRIGGER"; break;
816 case SQLITE_CREATE_VIEW : zCode="SQLITE_CREATE_VIEW"; break;
817 case SQLITE_DELETE : zCode="SQLITE_DELETE"; break;
818 case SQLITE_DROP_INDEX : zCode="SQLITE_DROP_INDEX"; break;
819 case SQLITE_DROP_TABLE : zCode="SQLITE_DROP_TABLE"; break;
820 case SQLITE_DROP_TEMP_INDEX : zCode="SQLITE_DROP_TEMP_INDEX"; break;
821 case SQLITE_DROP_TEMP_TABLE : zCode="SQLITE_DROP_TEMP_TABLE"; break;
822 case SQLITE_DROP_TEMP_TRIGGER : zCode="SQLITE_DROP_TEMP_TRIGGER"; break;
823 case SQLITE_DROP_TEMP_VIEW : zCode="SQLITE_DROP_TEMP_VIEW"; break;
824 case SQLITE_DROP_TRIGGER : zCode="SQLITE_DROP_TRIGGER"; break;
825 case SQLITE_DROP_VIEW : zCode="SQLITE_DROP_VIEW"; break;
826 case SQLITE_INSERT : zCode="SQLITE_INSERT"; break;
827 case SQLITE_PRAGMA : zCode="SQLITE_PRAGMA"; break;
828 case SQLITE_READ : zCode="SQLITE_READ"; break;
829 case SQLITE_SELECT : zCode="SQLITE_SELECT"; break;
830 case SQLITE_TRANSACTION : zCode="SQLITE_TRANSACTION"; break;
831 case SQLITE_UPDATE : zCode="SQLITE_UPDATE"; break;
832 case SQLITE_ATTACH : zCode="SQLITE_ATTACH"; break;
833 case SQLITE_DETACH : zCode="SQLITE_DETACH"; break;
834 case SQLITE_ALTER_TABLE : zCode="SQLITE_ALTER_TABLE"; break;
835 case SQLITE_REINDEX : zCode="SQLITE_REINDEX"; break;
836 case SQLITE_ANALYZE : zCode="SQLITE_ANALYZE"; break;
837 case SQLITE_CREATE_VTABLE : zCode="SQLITE_CREATE_VTABLE"; break;
838 case SQLITE_DROP_VTABLE : zCode="SQLITE_DROP_VTABLE"; break;
839 case SQLITE_FUNCTION : zCode="SQLITE_FUNCTION"; break;
840 case SQLITE_SAVEPOINT : zCode="SQLITE_SAVEPOINT"; break;
841 default : zCode="????"; break;
843 str = Jim_NewStringObj(pDb->interp, pDb->zAuth, -1);
844 /* XXX: list or string here? */
845 Jim_ListAppendElement(pDb->interp, str, Jim_NewStringObj(pDb->interp, zCode, -1));
846 if (zArg1) {
847 Jim_ListAppendElement(pDb->interp, str, Jim_NewStringObj(pDb->interp, zArg1, -1));
849 if (zArg2) {
850 Jim_ListAppendElement(pDb->interp, str, Jim_NewStringObj(pDb->interp, zArg2, -1));
852 if (zArg3) {
853 Jim_ListAppendElement(pDb->interp, str, Jim_NewStringObj(pDb->interp, zArg3, -1));
855 if (zArg4) {
856 Jim_ListAppendElement(pDb->interp, str, Jim_NewStringObj(pDb->interp, zArg4, -1));
858 Jim_IncrRefCount(str);
859 rc = Jim_EvalGlobal(pDb->interp, Jim_String(str));
860 Jim_DecrRefCount(pDb->interp, str);
861 zReply = Jim_String(Jim_GetResult(pDb->interp));
862 if( strcmp(zReply,"SQLITE_OK")==0 ){
863 rc = SQLITE_OK;
864 }else if( strcmp(zReply,"SQLITE_DENY")==0 ){
865 rc = SQLITE_DENY;
866 }else if( strcmp(zReply,"SQLITE_IGNORE")==0 ){
867 rc = SQLITE_IGNORE;
868 }else{
869 rc = 999;
871 return rc;
873 #endif /* SQLITE_OMIT_AUTHORIZATION */
876 ** Note that Jim Tcl can't do encoding conversion,
877 ** so this simply returns the string as an object.
879 static Jim_Obj *dbTextToObj(Jim_Interp *interp, char const *zText){
880 return Jim_NewStringObj(interp, zText ? zText : "", -1);
884 ** This routine reads a line of text from FILE in, stores
885 ** the text in memory obtained from malloc() and returns a pointer
886 ** to the text. NULL is returned at end of file.
888 ** The interface is like "readline" but no command-line editing
889 ** is done.
891 ** copied from shell.c from '.import' command
893 static char *local_getline(char *zPrompt, FILE *in){
894 char *zLine;
895 int nLine;
896 int n;
897 int eol;
899 nLine = 100;
900 zLine = Jim_Alloc( nLine );
901 n = 0;
902 eol = 0;
903 while( !eol ){
904 if( n+100>nLine ){
905 nLine = nLine*2 + 100;
906 zLine = Jim_Realloc(zLine, nLine);
907 if( zLine==0 ) return 0;
909 if( fgets(&zLine[n], nLine - n, in)==0 ){
910 if( n==0 ){
911 Jim_Free(zLine);
912 return 0;
914 zLine[n] = 0;
915 eol = 1;
916 break;
918 while( zLine[n] ){ n++; }
919 if( n>0 && zLine[n-1]=='\n' ){
920 n--;
921 zLine[n] = 0;
922 eol = 1;
925 zLine = Jim_Realloc( zLine, n+1 );
926 return zLine;
931 ** This function is part of the implementation of the command:
933 ** $db transaction [-deferred|-immediate|-exclusive] SCRIPT
935 ** It is invoked after evaluating the script SCRIPT to commit or rollback
936 ** the transaction or savepoint opened by the [transaction] command.
938 static int DbTransPostCmd(
939 Jim_Interp *interp, /* Tcl interpreter */
940 SqliteDb *pDb,
941 int result /* Result of evaluating SCRIPT */
943 static const char *azEnd[] = {
944 "RELEASE _tcl_transaction", /* rc==JIM_ERR, nTransaction!=0 */
945 "COMMIT", /* rc!=JIM_ERR, nTransaction==0 */
946 "ROLLBACK TO _tcl_transaction ; RELEASE _tcl_transaction",
947 "ROLLBACK" /* rc==JIM_ERR, nTransaction==0 */
949 int rc = result;
950 const char *zEnd;
952 pDb->nTransaction--;
953 zEnd = azEnd[(rc==JIM_ERR)*2 + (pDb->nTransaction==0)];
955 pDb->disableAuth++;
956 if( sqlite3_exec(pDb->db, zEnd, 0, 0, 0) ){
957 /* This is a tricky scenario to handle. The most likely cause of an
958 ** error is that the exec() above was an attempt to commit the
959 ** top-level transaction that returned SQLITE_BUSY. Or, less likely,
960 ** that an IO-error has occured. In either case, throw a Tcl exception
961 ** and try to rollback the transaction.
963 ** But it could also be that the user executed one or more BEGIN,
964 ** COMMIT, SAVEPOINT, RELEASE or ROLLBACK commands that are confusing
965 ** this method's logic. Not clear how this would be best handled.
967 if( rc!=JIM_ERR ){
968 Jim_AppendString(interp, Jim_GetResult(interp), sqlite3_errmsg(pDb->db), -1);
969 rc = JIM_ERR;
971 sqlite3_exec(pDb->db, "ROLLBACK", 0, 0, 0);
973 pDb->disableAuth--;
975 return rc;
979 ** Search the cache for a prepared-statement object that implements the
980 ** first SQL statement in the buffer pointed to by parameter zIn. If
981 ** no such prepared-statement can be found, allocate and prepare a new
982 ** one. In either case, bind the current values of the relevant Tcl
983 ** variables to any $var, :var or @var variables in the statement. Before
984 ** returning, set *ppPreStmt to point to the prepared-statement object.
986 ** Output parameter *pzOut is set to point to the next SQL statement in
987 ** buffer zIn, or to the '\0' byte at the end of zIn if there is no
988 ** next statement.
990 ** If successful, JIM_OK is returned. Otherwise, JIM_ERR is returned
991 ** and an error message loaded into interpreter pDb->interp.
993 static int dbPrepareAndBind(
994 SqliteDb *pDb, /* Database object */
995 char const *zIn, /* SQL to compile */
996 char const **pzOut, /* OUT: Pointer to next SQL statement */
997 SqlPreparedStmt **ppPreStmt /* OUT: Object used to cache statement */
999 const char *zSql = zIn; /* Pointer to first SQL statement in zIn */
1000 sqlite3_stmt *pStmt; /* Prepared statement object */
1001 SqlPreparedStmt *pPreStmt; /* Pointer to cached statement */
1002 int nSql; /* Length of zSql in bytes */
1003 int nVar; /* Number of variables in statement */
1004 int iParm = 0; /* Next free entry in apParm */
1005 int i;
1006 Jim_Interp *interp = pDb->interp;
1008 *ppPreStmt = 0;
1010 /* Trim spaces from the start of zSql and calculate the remaining length. */
1011 while( isspace((unsigned)zSql[0]) ){ zSql++; }
1012 nSql = strlen30(zSql);
1014 for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pPreStmt->pNext){
1015 int n = pPreStmt->nSql;
1016 if( nSql>=n
1017 && memcmp(pPreStmt->zSql, zSql, n)==0
1018 && (zSql[n]==0 || zSql[n-1]==';')
1020 pStmt = pPreStmt->pStmt;
1021 *pzOut = &zSql[pPreStmt->nSql];
1023 /* When a prepared statement is found, unlink it from the
1024 ** cache list. It will later be added back to the beginning
1025 ** of the cache list in order to implement LRU replacement.
1027 if( pPreStmt->pPrev ){
1028 pPreStmt->pPrev->pNext = pPreStmt->pNext;
1029 }else{
1030 pDb->stmtList = pPreStmt->pNext;
1032 if( pPreStmt->pNext ){
1033 pPreStmt->pNext->pPrev = pPreStmt->pPrev;
1034 }else{
1035 pDb->stmtLast = pPreStmt->pPrev;
1037 pDb->nStmt--;
1038 nVar = sqlite3_bind_parameter_count(pStmt);
1039 break;
1043 /* If no prepared statement was found. Compile the SQL text. Also allocate
1044 ** a new SqlPreparedStmt structure. */
1045 if( pPreStmt==0 ){
1046 int nByte;
1048 if( SQLITE_OK!=sqlite3_prepare_v2(pDb->db, zSql, -1, &pStmt, pzOut) ){
1049 Jim_SetResult(interp, dbTextToObj(pDb->interp, sqlite3_errmsg(pDb->db)));
1050 return JIM_ERR;
1052 if( pStmt==0 ){
1053 if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){
1054 /* A compile-time error in the statement. */
1055 Jim_SetResult(interp, dbTextToObj(pDb->interp, sqlite3_errmsg(pDb->db)));
1056 return JIM_ERR;
1057 }else{
1058 /* The statement was a no-op. Continue to the next statement
1059 ** in the SQL string.
1061 return JIM_OK;
1065 assert( pPreStmt==0 );
1066 nVar = sqlite3_bind_parameter_count(pStmt);
1067 nByte = sizeof(SqlPreparedStmt) + nVar*sizeof(Jim_Obj *);
1068 pPreStmt = (SqlPreparedStmt*)Jim_Alloc(nByte);
1069 memset(pPreStmt, 0, nByte);
1071 pPreStmt->pStmt = pStmt;
1072 pPreStmt->nSql = (*pzOut - zSql);
1073 pPreStmt->zSql = sqlite3_sql(pStmt);
1074 pPreStmt->apParm = (Jim_Obj **)&pPreStmt[1];
1076 assert( pPreStmt );
1077 assert( strlen30(pPreStmt->zSql)==pPreStmt->nSql );
1078 assert( 0==memcmp(pPreStmt->zSql, zSql, pPreStmt->nSql) );
1080 /* Bind values to parameters that begin with $ or : */
1081 for(i=1; i<=nVar; i++){
1082 const char *zVar = sqlite3_bind_parameter_name(pStmt, i);
1083 if( zVar!=0 && (zVar[0]=='$' || zVar[0]==':' || zVar[0]=='@') ){
1084 Jim_Obj *pVar = Jim_GetVariableStr(interp, &zVar[1], 0);
1085 if( pVar ){
1086 int n;
1087 u8 *data;
1088 const char *zType = (pVar->typePtr ? pVar->typePtr->name : "");
1089 char c = zType[0];
1090 /* XXX: Jim Tcl doesn't have bytearray or boolean */
1091 if( zVar[0]=='@') {
1092 #if 0
1094 (c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0) ){
1095 /* Load a BLOB type if the Tcl variable is a bytearray and
1096 ** it has no string representation or the host
1097 ** parameter name begins with "@". */
1098 data = Jim_GetByteArrayFromObj(pVar, &n);
1099 #else
1100 data = (unsigned char *)Jim_GetString(pVar, &n);
1101 #endif
1102 sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC);
1103 Jim_IncrRefCount(pVar);
1104 pPreStmt->apParm[iParm++] = pVar;
1105 #if 0
1106 }else if( c=='b' && strcmp(zType,"boolean")==0 ){
1107 Jim_GetWide(interp, pVar, &n);
1108 sqlite3_bind_int(pStmt, i, n);
1109 #endif
1110 }else if( c=='d' && strcmp(zType,"double")==0 ){
1111 double r;
1112 Jim_GetDouble(interp, pVar, &r);
1113 sqlite3_bind_double(pStmt, i, r);
1114 }else if( (c=='c' && strcmp(zType,"coerced-double")==0) ||
1115 (c=='i' && strcmp(zType,"int")==0) ){
1116 jim_wide v;
1117 Jim_GetWide(interp, pVar, &v);
1118 sqlite3_bind_int64(pStmt, i, v);
1119 }else{
1120 data = (unsigned char *)Jim_GetString(pVar, &n);
1121 sqlite3_bind_text(pStmt, i, (char *)data, n, SQLITE_STATIC);
1122 Jim_IncrRefCount(pVar);
1123 pPreStmt->apParm[iParm++] = pVar;
1125 }else{
1126 sqlite3_bind_null(pStmt, i);
1130 pPreStmt->nParm = iParm;
1131 *ppPreStmt = pPreStmt;
1133 return JIM_OK;
1138 ** Release a statement reference obtained by calling dbPrepareAndBind().
1139 ** There should be exactly one call to this function for each call to
1140 ** dbPrepareAndBind().
1142 ** If the discard parameter is non-zero, then the statement is deleted
1143 ** immediately. Otherwise it is added to the LRU list and may be returned
1144 ** by a subsequent call to dbPrepareAndBind().
1146 static void dbReleaseStmt(
1147 SqliteDb *pDb, /* Database handle */
1148 SqlPreparedStmt *pPreStmt, /* Prepared statement handle to release */
1149 int discard /* True to delete (not cache) the pPreStmt */
1151 int i;
1153 /* Free the bound string and blob parameters */
1154 for(i=0; i<pPreStmt->nParm; i++){
1155 Jim_DecrRefCount(pDb->interp, pPreStmt->apParm[i]);
1157 pPreStmt->nParm = 0;
1159 if( pDb->maxStmt<=0 || discard ){
1160 /* If the cache is turned off, deallocated the statement */
1161 sqlite3_finalize(pPreStmt->pStmt);
1162 Jim_Free((char *)pPreStmt);
1163 }else{
1164 /* Add the prepared statement to the beginning of the cache list. */
1165 pPreStmt->pNext = pDb->stmtList;
1166 pPreStmt->pPrev = 0;
1167 if( pDb->stmtList ){
1168 pDb->stmtList->pPrev = pPreStmt;
1170 pDb->stmtList = pPreStmt;
1171 if( pDb->stmtLast==0 ){
1172 assert( pDb->nStmt==0 );
1173 pDb->stmtLast = pPreStmt;
1174 }else{
1175 assert( pDb->nStmt>0 );
1177 pDb->nStmt++;
1179 /* If we have too many statement in cache, remove the surplus from
1180 ** the end of the cache list. */
1181 while( pDb->nStmt>pDb->maxStmt ){
1182 sqlite3_finalize(pDb->stmtLast->pStmt);
1183 pDb->stmtLast = pDb->stmtLast->pPrev;
1184 Jim_Free((char*)pDb->stmtLast->pNext);
1185 pDb->stmtLast->pNext = 0;
1186 pDb->nStmt--;
1192 ** Structure used with dbEvalXXX() functions:
1194 ** dbEvalInit()
1195 ** dbEvalStep()
1196 ** dbEvalFinalize()
1197 ** dbEvalRowInfo()
1198 ** dbEvalColumnValue()
1200 typedef struct DbEvalContext DbEvalContext;
1201 struct DbEvalContext {
1202 SqliteDb *pDb; /* Database handle */
1203 Jim_Obj *pSql; /* Object holding string zSql */
1204 const char *zSql; /* Remaining SQL to execute */
1205 SqlPreparedStmt *pPreStmt; /* Current statement */
1206 int nCol; /* Number of columns returned by pStmt */
1207 Jim_Obj *pArray; /* Name of array variable */
1208 Jim_Obj **apColName; /* Array of column names */
1212 ** Release any cache of column names currently held as part of
1213 ** the DbEvalContext structure passed as the first argument.
1215 static void dbReleaseColumnNames(DbEvalContext *p){
1216 if( p->apColName ){
1217 int i;
1218 for(i=0; i<p->nCol; i++){
1219 Jim_DecrRefCount(p->pDb->interp, p->apColName[i]);
1221 Jim_Free((char *)p->apColName);
1222 p->apColName = 0;
1224 p->nCol = 0;
1228 ** Initialize a DbEvalContext structure.
1230 ** If pArray is not NULL, then it contains the name of a Tcl array
1231 ** variable. The "*" member of this array is set to a list containing
1232 ** the names of the columns returned by the statement as part of each
1233 ** call to dbEvalStep(), in order from left to right. e.g. if the names
1234 ** of the returned columns are a, b and c, it does the equivalent of the
1235 ** tcl command:
1237 ** set ${pArray}(*) {a b c}
1239 static void dbEvalInit(
1240 DbEvalContext *p, /* Pointer to structure to initialize */
1241 SqliteDb *pDb, /* Database handle */
1242 Jim_Obj *pSql, /* Object containing SQL script */
1243 Jim_Obj *pArray /* Name of Tcl array to set (*) element of */
1245 memset(p, 0, sizeof(DbEvalContext));
1246 p->pDb = pDb;
1247 p->zSql = Jim_String(pSql);
1248 p->pSql = pSql;
1249 Jim_IncrRefCount(pSql);
1250 if( pArray ){
1251 p->pArray = pArray;
1252 Jim_IncrRefCount(pArray);
1257 ** Obtain information about the row that the DbEvalContext passed as the
1258 ** first argument currently points to.
1260 static void dbEvalRowInfo(
1261 DbEvalContext *p, /* Evaluation context */
1262 int *pnCol, /* OUT: Number of column names */
1263 Jim_Obj ***papColName /* OUT: Array of column names */
1265 /* Compute column names */
1266 if( 0==p->apColName ){
1267 sqlite3_stmt *pStmt = p->pPreStmt->pStmt;
1268 int i; /* Iterator variable */
1269 int nCol; /* Number of columns returned by pStmt */
1270 Jim_Obj **apColName = 0; /* Array of column names */
1272 p->nCol = nCol = sqlite3_column_count(pStmt);
1273 if( nCol>0 && (papColName || p->pArray) ){
1274 apColName = (Jim_Obj**)Jim_Alloc( sizeof(Jim_Obj*)*nCol );
1275 for(i=0; i<nCol; i++){
1276 apColName[i] = dbTextToObj(p->pDb->interp, sqlite3_column_name(pStmt,i));
1277 Jim_IncrRefCount(apColName[i]);
1279 p->apColName = apColName;
1282 /* If results are being stored in an array variable, then create
1283 ** the array(*) entry for that array
1285 if( p->pArray ){
1286 Jim_Interp *interp = p->pDb->interp;
1287 Jim_Obj *pColList = Jim_NewListObj(interp, apColName, nCol);
1288 Jim_Obj *pStar = Jim_NewStringObj(interp, "*", -1);
1289 Jim_IncrRefCount(pStar);
1290 Jim_SetDictKeysVector(interp, p->pArray, &pStar, 1, pColList, 0);
1291 Jim_DecrRefCount(interp, pStar);
1295 if( papColName ){
1296 *papColName = p->apColName;
1298 if( pnCol ){
1299 *pnCol = p->nCol;
1304 ** Return one of JIM_OK, JIM_BREAK or JIM_ERR. If JIM_ERR is
1305 ** returned, then an error message is stored in the interpreter before
1306 ** returning.
1308 ** A return value of JIM_OK means there is a row of data available. The
1309 ** data may be accessed using dbEvalRowInfo() and dbEvalColumnValue(). This
1310 ** is analogous to a return of SQLITE_ROW from sqlite3_step(). If JIM_BREAK
1311 ** is returned, then the SQL script has finished executing and there are
1312 ** no further rows available. This is similar to SQLITE_DONE.
1314 static int dbEvalStep(DbEvalContext *p){
1315 while( p->zSql[0] || p->pPreStmt ){
1316 int rc;
1317 if( p->pPreStmt==0 ){
1318 rc = dbPrepareAndBind(p->pDb, p->zSql, &p->zSql, &p->pPreStmt);
1319 if( rc!=JIM_OK ) return rc;
1320 }else{
1321 int rcs;
1322 SqliteDb *pDb = p->pDb;
1323 SqlPreparedStmt *pPreStmt = p->pPreStmt;
1324 sqlite3_stmt *pStmt = pPreStmt->pStmt;
1326 rcs = sqlite3_step(pStmt);
1327 if( rcs==SQLITE_ROW ){
1328 return JIM_OK;
1330 if( p->pArray ){
1331 dbEvalRowInfo(p, 0, 0);
1333 rcs = sqlite3_reset(pStmt);
1335 pDb->nStep = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_FULLSCAN_STEP,1);
1336 pDb->nSort = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_SORT,1);
1337 dbReleaseColumnNames(p);
1338 p->pPreStmt = 0;
1340 if( rcs!=SQLITE_OK ){
1341 /* If a run-time error occurs, report the error and stop reading
1342 ** the SQL. */
1343 Jim_SetResult(pDb->interp, dbTextToObj(pDb->interp, sqlite3_errmsg(pDb->db)));
1344 dbReleaseStmt(pDb, pPreStmt, 1);
1345 return JIM_ERR;
1346 }else{
1347 dbReleaseStmt(pDb, pPreStmt, 0);
1352 /* Finished */
1353 return JIM_BREAK;
1357 ** Free all resources currently held by the DbEvalContext structure passed
1358 ** as the first argument. There should be exactly one call to this function
1359 ** for each call to dbEvalInit().
1361 static void dbEvalFinalize(DbEvalContext *p){
1362 if( p->pPreStmt ){
1363 sqlite3_reset(p->pPreStmt->pStmt);
1364 dbReleaseStmt(p->pDb, p->pPreStmt, 0);
1365 p->pPreStmt = 0;
1367 if( p->pArray ){
1368 Jim_DecrRefCount(p->pDb->interp, p->pArray);
1369 p->pArray = 0;
1371 Jim_DecrRefCount(p->pDb->interp, p->pSql);
1372 dbReleaseColumnNames(p);
1376 ** Return a pointer to a Jim_Obj structure with ref-count 0 that contains
1377 ** the value for the iCol'th column of the row currently pointed to by
1378 ** the DbEvalContext structure passed as the first argument.
1380 static Jim_Obj *dbEvalColumnValue(DbEvalContext *p, int iCol){
1381 sqlite3_stmt *pStmt = p->pPreStmt->pStmt;
1382 switch( sqlite3_column_type(pStmt, iCol) ){
1383 case SQLITE_BLOB: {
1384 int bytes = sqlite3_column_bytes(pStmt, iCol);
1385 const char *zBlob = sqlite3_column_blob(pStmt, iCol);
1386 if( !zBlob ) bytes = 0;
1387 //return Jim_NewByteArrayObj((u8*)zBlob, bytes);
1388 return Jim_NewStringObj(p->pDb->interp, zBlob, bytes);
1390 case SQLITE_INTEGER: {
1391 sqlite_int64 v = sqlite3_column_int64(pStmt, iCol);
1392 return Jim_NewIntObj(p->pDb->interp, v);
1394 case SQLITE_FLOAT: {
1395 return Jim_NewDoubleObj(p->pDb->interp, sqlite3_column_double(pStmt, iCol));
1397 case SQLITE_NULL: {
1398 return dbTextToObj(p->pDb->interp, p->pDb->zNull);
1402 return dbTextToObj(p->pDb->interp, (char *)sqlite3_column_text(pStmt, iCol));
1405 static int Jim_ObjSetVar2(Jim_Interp *interp, Jim_Obj *nameObjPtr, Jim_Obj *keyObjPtr, Jim_Obj *valObjPtr)
1407 return Jim_SetDictKeysVector(interp, nameObjPtr, &keyObjPtr, 1, valObjPtr, 0);
1411 ** This function is part of the implementation of the command:
1413 ** $db eval SQL ?ARRAYNAME? SCRIPT
1415 static int DbEvalNextCmd(
1416 Jim_Interp *interp, /* Tcl interpreter */
1417 DbEvalContext *p,
1418 Jim_Obj *pScript,
1419 int result /* Result so far */
1421 int rc = result; /* Return code */
1423 Jim_Obj *pArray = p->pArray;
1425 while( (rc==JIM_OK || rc==JIM_CONTINUE) && JIM_OK==(rc = dbEvalStep(p)) ){
1426 int i;
1427 int nCol;
1428 Jim_Obj **apColName;
1429 dbEvalRowInfo(p, &nCol, &apColName);
1430 for(i=0; i<nCol; i++){
1431 Jim_Obj *pVal = dbEvalColumnValue(p, i);
1432 if( pArray==0 ){
1433 Jim_SetVariable(interp, apColName[i], pVal);
1434 }else{
1435 Jim_ObjSetVar2(interp, pArray, apColName[i], pVal);
1439 /* The required interpreter variables are now populated with the data
1440 ** from the current row.
1442 ** No NRE in Jim Tcl, so evaluate pScript directly and continue with the
1443 ** next iteration of this while(...) loop. */
1444 rc = Jim_EvalObj(interp, pScript);
1447 Jim_DecrRefCount(interp, pScript);
1448 dbEvalFinalize(p);
1449 Jim_Free((char *)p);
1451 if( rc==JIM_OK || rc==JIM_BREAK ){
1452 Jim_SetEmptyResult(interp);
1453 rc = JIM_OK;
1455 return rc;
1459 ** The "sqlite" command below creates a new Tcl command for each
1460 ** connection it opens to an SQLite database. This routine is invoked
1461 ** whenever one of those connection-specific commands is executed
1462 ** in Tcl. For example, if you run Tcl code like this:
1464 ** sqlite3 db1 "my_database"
1465 ** db1 close
1467 ** The first command opens a connection to the "my_database" database
1468 ** and calls that connection "db1". The second command causes this
1469 ** subroutine to be invoked.
1471 static int DbObjCmd(Jim_Interp *interp, int objc,Jim_Obj *const*objv){
1472 SqliteDb *pDb = (SqliteDb*)Jim_CmdPrivData(interp);
1473 int choice;
1474 int rc = JIM_OK;
1475 static const char *DB_strs[] = {
1476 "authorizer", "backup", "busy",
1477 "cache", "changes", "close",
1478 "collate", "collation_needed", "commit_hook",
1479 "complete", "copy", "enable_load_extension",
1480 "errorcode", "eval", "exists",
1481 "function", "incrblob", "interrupt",
1482 "last_insert_rowid", "nullvalue", "onecolumn",
1483 "profile", "progress", "rekey",
1484 "restore", "rollback_hook", "status",
1485 "timeout", "total_changes", "trace",
1486 "transaction", "unlock_notify", "update_hook",
1487 "version", 0
1489 enum DB_enum {
1490 DB_AUTHORIZER, DB_BACKUP, DB_BUSY,
1491 DB_CACHE, DB_CHANGES, DB_CLOSE,
1492 DB_COLLATE, DB_COLLATION_NEEDED, DB_COMMIT_HOOK,
1493 DB_COMPLETE, DB_COPY, DB_ENABLE_LOAD_EXTENSION,
1494 DB_ERRORCODE, DB_EVAL, DB_EXISTS,
1495 DB_FUNCTION, DB_INCRBLOB, DB_INTERRUPT,
1496 DB_LAST_INSERT_ROWID, DB_NULLVALUE, DB_ONECOLUMN,
1497 DB_PROFILE, DB_PROGRESS, DB_REKEY,
1498 DB_RESTORE, DB_ROLLBACK_HOOK, DB_STATUS,
1499 DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE,
1500 DB_TRANSACTION, DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK,
1501 DB_VERSION,
1503 /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */
1505 if( objc<2 ){
1506 Jim_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");
1507 return JIM_ERR;
1509 if( Jim_GetEnum(interp, objv[1], DB_strs, &choice, "option", JIM_ERRMSG | JIM_ENUM_ABBREV) ){
1510 return JIM_ERR;
1513 switch( (enum DB_enum)choice ){
1515 /* $db authorizer ?CALLBACK?
1517 ** Invoke the given callback to authorize each SQL operation as it is
1518 ** compiled. 5 arguments are appended to the callback before it is
1519 ** invoked:
1521 ** (1) The authorization type (ex: SQLITE_CREATE_TABLE, SQLITE_INSERT, ...)
1522 ** (2) First descriptive name (depends on authorization type)
1523 ** (3) Second descriptive name
1524 ** (4) Name of the database (ex: "main", "temp")
1525 ** (5) Name of trigger that is doing the access
1527 ** The callback should return on of the following strings: SQLITE_OK,
1528 ** SQLITE_IGNORE, or SQLITE_DENY. Any other return value is an error.
1530 ** If this method is invoked with no arguments, the current authorization
1531 ** callback string is returned.
1533 case DB_AUTHORIZER: {
1534 #ifdef SQLITE_OMIT_AUTHORIZATION
1535 Jim_SetResultString(interp, "authorization not available in this build", -1);
1536 return JIM_ERR;
1537 #else
1538 if( objc>3 ){
1539 Jim_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
1540 return JIM_ERR;
1541 }else if( objc==2 ){
1542 if( pDb->zAuth ){
1543 Jim_SetResultString(interp, pDb->zAuth, -1);
1545 }else{
1546 const char *zAuth;
1547 int len;
1548 if( pDb->zAuth ){
1549 Jim_Free(pDb->zAuth);
1551 zAuth = Jim_GetString(objv[2], &len);
1552 if( zAuth && len>0 ){
1553 pDb->zAuth = Jim_Alloc( len + 1 );
1554 memcpy(pDb->zAuth, zAuth, len+1);
1555 }else{
1556 pDb->zAuth = 0;
1558 if( pDb->zAuth ){
1559 pDb->interp = interp;
1560 sqlite3_set_authorizer(pDb->db, auth_callback, pDb);
1561 }else{
1562 sqlite3_set_authorizer(pDb->db, 0, 0);
1565 #endif
1566 break;
1569 /* $db backup ?DATABASE? FILENAME
1571 ** Open or create a database file named FILENAME. Transfer the
1572 ** content of local database DATABASE (default: "main") into the
1573 ** FILENAME database.
1575 case DB_BACKUP: {
1576 const char *zDestFile;
1577 const char *zSrcDb;
1578 sqlite3 *pDest;
1579 sqlite3_backup *pBackup;
1581 if( objc==3 ){
1582 zSrcDb = "main";
1583 zDestFile = Jim_String(objv[2]);
1584 }else if( objc==4 ){
1585 zSrcDb = Jim_String(objv[2]);
1586 zDestFile = Jim_String(objv[3]);
1587 }else{
1588 Jim_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME");
1589 return JIM_ERR;
1591 rc = sqlite3_open(zDestFile, &pDest);
1592 if( rc!=SQLITE_OK ){
1593 Jim_SetResultFormatted(interp, "cannot open target database: %s", sqlite3_errmsg(pDest));
1594 sqlite3_close(pDest);
1595 return JIM_ERR;
1597 pBackup = sqlite3_backup_init(pDest, "main", pDb->db, zSrcDb);
1598 if( pBackup==0 ){
1599 Jim_SetResultFormatted(interp, "backup failed: %s", sqlite3_errmsg(pDest));
1600 sqlite3_close(pDest);
1601 return JIM_ERR;
1603 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
1604 sqlite3_backup_finish(pBackup);
1605 if( rc==SQLITE_DONE ){
1606 rc = JIM_OK;
1607 }else{
1608 Jim_SetResultFormatted(interp, "backup failed: %s", sqlite3_errmsg(pDest));
1609 rc = JIM_ERR;
1611 sqlite3_close(pDest);
1612 break;
1615 /* $db busy ?CALLBACK?
1617 ** Invoke the given callback if an SQL statement attempts to open
1618 ** a locked database file.
1620 case DB_BUSY: {
1621 if( objc>3 ){
1622 Jim_WrongNumArgs(interp, 2, objv, "CALLBACK");
1623 return JIM_ERR;
1624 }else if( objc==2 ){
1625 if( pDb->zBusy ){
1626 Jim_SetResultString(interp, pDb->zBusy, -1);
1628 }else{
1629 const char *zBusy;
1630 int len;
1631 if( pDb->zBusy ){
1632 Jim_Free(pDb->zBusy);
1634 zBusy = Jim_GetString(objv[2], &len);
1635 if( zBusy && len>0 ){
1636 pDb->zBusy = Jim_Alloc( len + 1 );
1637 memcpy(pDb->zBusy, zBusy, len+1);
1638 }else{
1639 pDb->zBusy = 0;
1641 if( pDb->zBusy ){
1642 pDb->interp = interp;
1643 sqlite3_busy_handler(pDb->db, DbBusyHandler, pDb);
1644 }else{
1645 sqlite3_busy_handler(pDb->db, 0, 0);
1648 break;
1651 /* $db cache flush
1652 ** $db cache size n
1654 ** Flush the prepared statement cache, or set the maximum number of
1655 ** cached statements.
1657 case DB_CACHE: {
1658 const char *subCmd;
1660 if( objc<=2 ){
1661 Jim_WrongNumArgs(interp, 1, objv, "cache option ?arg?");
1662 return JIM_ERR;
1664 subCmd = Jim_String( objv[2]);
1665 if( *subCmd=='f' && strcmp(subCmd,"flush")==0 ){
1666 if( objc!=3 ){
1667 Jim_WrongNumArgs(interp, 2, objv, "flush");
1668 return JIM_ERR;
1669 }else{
1670 flushStmtCache( pDb );
1672 }else if( *subCmd=='s' && strcmp(subCmd,"size")==0 ){
1673 if( objc!=4 ){
1674 Jim_WrongNumArgs(interp, 2, objv, "size n");
1675 return JIM_ERR;
1676 }else{
1677 jim_wide w;
1678 if( JIM_ERR==Jim_GetWide(interp, objv[3], &w) ){
1679 return JIM_ERR;
1680 }else{
1681 if( w<0 ){
1682 flushStmtCache( pDb );
1683 w = 0;
1684 }else if( w>MAX_PREPARED_STMTS ){
1685 w = MAX_PREPARED_STMTS;
1687 pDb->maxStmt = w;
1690 }else{
1691 Jim_SetResultFormatted(interp, "bad option \"%#s\": must be flush or size", objv[2]);
1692 return JIM_ERR;
1694 break;
1697 /* $db changes
1699 ** Return the number of rows that were modified, inserted, or deleted by
1700 ** the most recent INSERT, UPDATE or DELETE statement, not including
1701 ** any changes made by trigger programs.
1703 case DB_CHANGES: {
1704 if( objc!=2 ){
1705 Jim_WrongNumArgs(interp, 2, objv, "");
1706 return JIM_ERR;
1708 Jim_SetResultInt(interp, sqlite3_changes(pDb->db));
1709 break;
1712 /* $db close
1714 ** Shutdown the database
1716 case DB_CLOSE: {
1717 Jim_DeleteCommand(interp, Jim_String(objv[0]));
1718 break;
1722 ** $db collate NAME SCRIPT
1724 ** Create a new SQL collation function called NAME. Whenever
1725 ** that function is called, invoke SCRIPT to evaluate the function.
1727 case DB_COLLATE: {
1728 SqlCollate *pCollate;
1729 const char *zName;
1730 const char *zScript;
1731 int nScript;
1732 if( objc!=4 ){
1733 Jim_WrongNumArgs(interp, 2, objv, "NAME SCRIPT");
1734 return JIM_ERR;
1736 zName = Jim_String(objv[2]);
1737 zScript = Jim_GetString(objv[3], &nScript);
1738 pCollate = (SqlCollate*)Jim_Alloc( sizeof(*pCollate) + nScript + 1 );
1739 if( pCollate==0 ) return JIM_ERR;
1740 pCollate->interp = interp;
1741 pCollate->pNext = pDb->pCollate;
1742 pCollate->zScript = (char*)&pCollate[1];
1743 pDb->pCollate = pCollate;
1744 memcpy(pCollate->zScript, zScript, nScript+1);
1745 if( sqlite3_create_collation(pDb->db, zName, SQLITE_UTF8,
1746 pCollate, tclSqlCollate) ){
1747 Jim_SetResultString(interp, (char *)sqlite3_errmsg(pDb->db), -1);
1748 return JIM_ERR;
1750 break;
1754 ** $db collation_needed SCRIPT
1756 ** Create a new SQL collation function called NAME. Whenever
1757 ** that function is called, invoke SCRIPT to evaluate the function.
1759 case DB_COLLATION_NEEDED: {
1760 if( objc!=3 ){
1761 Jim_WrongNumArgs(interp, 2, objv, "SCRIPT");
1762 return JIM_ERR;
1764 if( pDb->pCollateNeeded ){
1765 Jim_DecrRefCount(interp, pDb->pCollateNeeded);
1767 pDb->pCollateNeeded = Jim_DuplicateObj(pDb->interp, objv[2]);
1768 Jim_IncrRefCount(pDb->pCollateNeeded);
1769 sqlite3_collation_needed(pDb->db, pDb, tclCollateNeeded);
1770 break;
1773 /* $db commit_hook ?CALLBACK?
1775 ** Invoke the given callback just before committing every SQL transaction.
1776 ** If the callback throws an exception or returns non-zero, then the
1777 ** transaction is aborted. If CALLBACK is an empty string, the callback
1778 ** is disabled.
1780 case DB_COMMIT_HOOK: {
1781 if( objc>3 ){
1782 Jim_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
1783 return JIM_ERR;
1784 }else if( objc==2 ){
1785 if( pDb->zCommit ){
1786 Jim_SetResultString(interp, pDb->zCommit, -1);
1788 }else{
1789 const char *zCommit;
1790 int len;
1791 if( pDb->zCommit ){
1792 Jim_Free(pDb->zCommit);
1794 zCommit = Jim_GetString(objv[2], &len);
1795 if( zCommit && len>0 ){
1796 pDb->zCommit = Jim_Alloc( len + 1 );
1797 memcpy(pDb->zCommit, zCommit, len+1);
1798 }else{
1799 pDb->zCommit = 0;
1801 if( pDb->zCommit ){
1802 pDb->interp = interp;
1803 sqlite3_commit_hook(pDb->db, DbCommitHandler, pDb);
1804 }else{
1805 sqlite3_commit_hook(pDb->db, 0, 0);
1808 break;
1811 /* $db complete SQL
1813 ** Return TRUE if SQL is a complete SQL statement. Return FALSE if
1814 ** additional lines of input are needed. This is similar to the
1815 ** built-in "info complete" command of Tcl.
1817 case DB_COMPLETE: {
1818 #ifndef SQLITE_OMIT_COMPLETE
1819 if( objc!=3 ){
1820 Jim_WrongNumArgs(interp, 2, objv, "SQL");
1821 return JIM_ERR;
1823 Jim_SetResultInt(interp, sqlite3_complete( Jim_String(objv[2]) ));
1824 #endif
1825 break;
1828 /* $db copy conflict-algorithm table filename ?SEPARATOR? ?NULLINDICATOR?
1830 ** Copy data into table from filename, optionally using SEPARATOR
1831 ** as column separators. If a column contains a null string, or the
1832 ** value of NULLINDICATOR, a NULL is inserted for the column.
1833 ** conflict-algorithm is one of the sqlite conflict algorithms:
1834 ** rollback, abort, fail, ignore, replace
1835 ** On success, return the number of lines processed, not necessarily same
1836 ** as 'db changes' due to conflict-algorithm selected.
1838 ** This code is basically an implementation/enhancement of
1839 ** the sqlite3 shell.c ".import" command.
1841 ** This command usage is equivalent to the sqlite2.x COPY statement,
1842 ** which imports file data into a table using the PostgreSQL COPY file format:
1843 ** $db copy $conflit_algo $table_name $filename \t \\N
1845 case DB_COPY: {
1846 const char *zTable; /* Insert data into this table */
1847 const char *zFile; /* The file from which to extract data */
1848 const char *zConflict; /* The conflict algorithm to use */
1849 sqlite3_stmt *pStmt; /* A statement */
1850 int nCol; /* Number of columns in the table */
1851 int nByte; /* Number of bytes in an SQL string */
1852 int i, j; /* Loop counters */
1853 int nSep; /* Number of bytes in zSep[] */
1854 int nNull; /* Number of bytes in zNull[] */
1855 char *zSql; /* An SQL statement */
1856 char *zLine; /* A single line of input from the file */
1857 char **azCol; /* zLine[] broken up into columns */
1858 char *zCommit; /* How to commit changes */
1859 FILE *in; /* The input file */
1860 int lineno = 0; /* Line number of input file */
1861 char zLineNum[80]; /* Line number print buffer */
1863 const char *zSep;
1864 const char *zNull;
1865 if( objc<5 || objc>7 ){
1866 Jim_WrongNumArgs(interp, 2, objv,
1867 "CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?");
1868 return JIM_ERR;
1870 if( objc>=6 ){
1871 zSep = Jim_String(objv[5]);
1872 }else{
1873 zSep = "\t";
1875 if( objc>=7 ){
1876 zNull = Jim_String(objv[6]);
1877 }else{
1878 zNull = "";
1880 zConflict = Jim_String(objv[2]);
1881 zTable = Jim_String(objv[3]);
1882 zFile = Jim_String(objv[4]);
1883 nSep = strlen30(zSep);
1884 nNull = strlen30(zNull);
1885 if( nSep==0 ){
1886 Jim_SetResultString(interp, "Error: non-null separator required for copy", -1);
1887 return JIM_ERR;
1889 if(strcmp(zConflict, "rollback") != 0 &&
1890 strcmp(zConflict, "abort" ) != 0 &&
1891 strcmp(zConflict, "fail" ) != 0 &&
1892 strcmp(zConflict, "ignore" ) != 0 &&
1893 strcmp(zConflict, "replace" ) != 0 ) {
1894 Jim_SetResultFormatted(interp, "Error: \"%s\", conflict-algorithm must be one of: rollback, "
1895 "abort, fail, ignore, or replace", zConflict);
1896 return JIM_ERR;
1898 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
1899 if( zSql==0 ){
1900 Jim_SetResultFormatted(interp, "Error: no such table: %s", zTable);
1901 return JIM_ERR;
1903 nByte = strlen30(zSql);
1904 rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0);
1905 sqlite3_free(zSql);
1906 if( rc ){
1907 Jim_SetResultFormatted(interp, "Error: %s", sqlite3_errmsg(pDb->db));
1908 nCol = 0;
1909 }else{
1910 nCol = sqlite3_column_count(pStmt);
1912 sqlite3_finalize(pStmt);
1913 if( nCol==0 ) {
1914 return JIM_ERR;
1916 zSql = Jim_Alloc( nByte + 50 + nCol*2 );
1917 sqlite3_snprintf(nByte+50, zSql, "INSERT OR %q INTO '%q' VALUES(?",
1918 zConflict, zTable);
1919 j = strlen30(zSql);
1920 for(i=1; i<nCol; i++){
1921 zSql[j++] = ',';
1922 zSql[j++] = '?';
1924 zSql[j++] = ')';
1925 zSql[j] = 0;
1926 rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0);
1927 Jim_Free(zSql);
1928 if( rc ){
1929 Jim_SetResultFormatted(interp, "Error: %s", sqlite3_errmsg(pDb->db));
1930 sqlite3_finalize(pStmt);
1931 return JIM_ERR;
1933 in = fopen(zFile, "rb");
1934 if( in==0 ){
1935 Jim_SetResultFormatted(interp, "Error: cannot open file: %s", zFile);
1936 sqlite3_finalize(pStmt);
1937 return JIM_ERR;
1939 azCol = Jim_Alloc( sizeof(azCol[0])*(nCol+1) );
1940 (void)sqlite3_exec(pDb->db, "BEGIN", 0, 0, 0);
1941 zCommit = "COMMIT";
1942 while( (zLine = local_getline(0, in))!=0 ){
1943 char *z;
1944 i = 0;
1945 lineno++;
1946 azCol[0] = zLine;
1947 for(i=0, z=zLine; *z; z++){
1948 if( *z==zSep[0] && strncmp(z, zSep, nSep)==0 ){
1949 *z = 0;
1950 i++;
1951 if( i<nCol ){
1952 azCol[i] = &z[nSep];
1953 z += nSep-1;
1957 if( i+1!=nCol ){
1958 char *zErr;
1959 int nErr = strlen30(zFile) + 200;
1960 zErr = Jim_Alloc(nErr);
1961 sqlite3_snprintf(nErr, zErr,
1962 "Error: %s line %d: expected %d columns of data but found %d",
1963 zFile, lineno, nCol, i+1);
1964 Jim_SetResultString(interp, zErr, -1);
1965 Jim_Free(zErr);
1966 zCommit = "ROLLBACK";
1967 break;
1969 for(i=0; i<nCol; i++){
1970 /* check for null data, if so, bind as null */
1971 if( (nNull>0 && strcmp(azCol[i], zNull)==0)
1972 || strlen30(azCol[i])==0
1974 sqlite3_bind_null(pStmt, i+1);
1975 }else{
1976 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
1979 sqlite3_step(pStmt);
1980 rc = sqlite3_reset(pStmt);
1981 Jim_Free(zLine);
1982 if( rc!=SQLITE_OK ){
1983 Jim_SetResultFormatted(interp, "Error: %s", sqlite3_errmsg(pDb->db));
1984 zCommit = "ROLLBACK";
1985 break;
1988 Jim_Free(azCol);
1989 fclose(in);
1990 sqlite3_finalize(pStmt);
1991 (void)sqlite3_exec(pDb->db, zCommit, 0, 0, 0);
1993 if( zCommit[0] == 'C' ){
1994 /* success, set result as number of lines processed */
1995 Jim_SetResultInt(interp, lineno);
1996 rc = JIM_OK;
1997 }else{
1998 /* failure, append lineno where failed */
1999 sqlite3_snprintf(sizeof(zLineNum), zLineNum,"%d",lineno);
2000 Jim_AppendStrings(interp, Jim_GetResult(interp), ", failed while processing line: ", zLineNum, NULL);
2001 rc = JIM_ERR;
2003 break;
2007 ** $db enable_load_extension BOOLEAN
2009 ** Turn the extension loading feature on or off. It if off by
2010 ** default.
2012 case DB_ENABLE_LOAD_EXTENSION: {
2013 #ifndef SQLITE_OMIT_LOAD_EXTENSION
2014 long onoff;
2015 if( objc!=3 ){
2016 Jim_WrongNumArgs(interp, 2, objv, "BOOLEAN");
2017 return JIM_ERR;
2019 if( Jim_GetLong(interp, objv[2], &onoff) ){
2020 return JIM_ERR;
2022 sqlite3_enable_load_extension(pDb->db, onoff);
2023 break;
2024 #else
2025 Jim_SetResultString(interp, "extension loading is turned off at compile-time", -1);
2026 return JIM_ERR;
2027 #endif
2031 ** $db errorcode
2033 ** Return the numeric error code that was returned by the most recent
2034 ** call to sqlite3_exec().
2036 case DB_ERRORCODE: {
2037 Jim_SetResultInt(interp, sqlite3_errcode(pDb->db));
2038 break;
2042 ** $db exists $sql
2043 ** $db onecolumn $sql
2045 ** The onecolumn method is the equivalent of:
2046 ** lindex [$db eval $sql] 0
2048 case DB_EXISTS:
2049 case DB_ONECOLUMN: {
2050 DbEvalContext sEval;
2051 if( objc!=3 ){
2052 Jim_WrongNumArgs(interp, 2, objv, "SQL");
2053 return JIM_ERR;
2056 dbEvalInit(&sEval, pDb, objv[2], 0);
2057 rc = dbEvalStep(&sEval);
2058 if( choice==DB_ONECOLUMN ){
2059 if( rc==JIM_OK ){
2060 Jim_SetResult(interp, dbEvalColumnValue(&sEval, 0));
2062 }else if( rc==JIM_BREAK || rc==JIM_OK ){
2063 Jim_SetResultInt(interp, rc==JIM_OK);
2065 dbEvalFinalize(&sEval);
2067 if( rc==JIM_BREAK ){
2068 rc = JIM_OK;
2070 break;
2074 ** $db eval $sql ?array? ?{ ...code... }?
2076 ** The SQL statement in $sql is evaluated. For each row, the values are
2077 ** placed in elements of the array named "array" and ...code... is executed.
2078 ** If "array" and "code" are omitted, then no callback is every invoked.
2079 ** If "array" is an empty string, then the values are placed in variables
2080 ** that have the same name as the fields extracted by the query.
2082 case DB_EVAL: {
2083 if( objc<3 || objc>5 ){
2084 Jim_WrongNumArgs(interp, 2, objv, "SQL ?ARRAY-NAME? ?SCRIPT?");
2085 return JIM_ERR;
2088 if( objc==3 ){
2089 DbEvalContext sEval;
2090 Jim_Obj *pRet = Jim_NewListObj(interp, NULL, 0);
2091 Jim_IncrRefCount(pRet);
2092 dbEvalInit(&sEval, pDb, objv[2], 0);
2093 while( JIM_OK==(rc = dbEvalStep(&sEval)) ){
2094 int i;
2095 int nCol;
2096 dbEvalRowInfo(&sEval, &nCol, 0);
2097 for(i=0; i<nCol; i++){
2098 Jim_ListAppendElement(interp, pRet, dbEvalColumnValue(&sEval, i));
2101 dbEvalFinalize(&sEval);
2102 if( rc==JIM_BREAK ){
2103 Jim_SetResult(interp, pRet);
2104 rc = JIM_OK;
2106 Jim_DecrRefCount(interp, pRet);
2107 }else{
2108 DbEvalContext *p;
2109 Jim_Obj *pArray = 0;
2110 Jim_Obj *pScript;
2112 if( objc==5 && Jim_Length(objv[3]) ){
2113 pArray = objv[3];
2115 pScript = objv[objc-1];
2116 Jim_IncrRefCount(pScript);
2118 p = (DbEvalContext *)Jim_Alloc(sizeof(DbEvalContext));
2119 dbEvalInit(p, pDb, objv[2], pArray);
2121 rc = DbEvalNextCmd(interp, p, pScript, JIM_OK);
2123 break;
2127 ** $db function NAME [-argcount N] SCRIPT
2129 ** Create a new SQL function called NAME. Whenever that function is
2130 ** called, invoke SCRIPT to evaluate the function.
2132 case DB_FUNCTION: {
2133 SqlFunc *pFunc;
2134 Jim_Obj *pScript;
2135 const char *zName;
2136 long nArg = -1;
2137 if( objc==6 ){
2138 const char *z = Jim_String(objv[3]);
2139 int n = strlen30(z);
2140 if( n>2 && strncmp(z, "-argcount",n)==0 ){
2141 if( Jim_GetLong(interp, objv[4], &nArg) ) return JIM_ERR;
2142 if( nArg<0 ){
2143 Jim_SetResultString(interp, "number of arguments must be non-negative", -1);
2144 return JIM_ERR;
2147 pScript = objv[5];
2148 }else if( objc!=4 ){
2149 Jim_WrongNumArgs(interp, 2, objv, "NAME [-argcount N] SCRIPT");
2150 return JIM_ERR;
2151 }else{
2152 pScript = objv[3];
2154 zName = Jim_String(objv[2]);
2155 pFunc = findSqlFunc(pDb, zName);
2156 if( pFunc==0 ) return JIM_ERR;
2157 if( pFunc->pScript ){
2158 Jim_DecrRefCount(interp, pFunc->pScript);
2160 pFunc->pScript = pScript;
2161 Jim_IncrRefCount(pScript);
2162 pFunc->useEvalObjv = safeToUseEvalObjv(interp, pScript);
2163 rc = sqlite3_create_function(pDb->db, zName, nArg, SQLITE_UTF8,
2164 pFunc, tclSqlFunc, 0, 0);
2165 if( rc!=SQLITE_OK ){
2166 rc = JIM_ERR;
2167 Jim_SetResultString(interp, (char *)sqlite3_errmsg(pDb->db), -1);
2169 break;
2173 ** $db incrblob ?-readonly? ?DB? TABLE COLUMN ROWID
2175 case DB_INCRBLOB: {
2176 #ifdef SQLITE_OMIT_INCRBLOB
2177 Jim_SetResultString(interp, "incrblob not available in this build", -1);
2178 return JIM_ERR;
2179 #else
2180 int isReadonly = 0;
2181 const char *zDb = "main";
2182 const char *zTable;
2183 const char *zColumn;
2184 sqlite_int64 iRow;
2186 /* Check for the -readonly option */
2187 if( objc>3 && strcmp(Jim_GetString(objv[2]), "-readonly")==0 ){
2188 isReadonly = 1;
2191 if( objc!=(5+isReadonly) && objc!=(6+isReadonly) ){
2192 Jim_WrongNumArgs(interp, 2, objv, "?-readonly? ?DB? TABLE COLUMN ROWID");
2193 return JIM_ERR;
2196 if( objc==(6+isReadonly) ){
2197 zDb = Jim_GetString(objv[2]);
2199 zTable = Jim_GetString(objv[objc-3]);
2200 zColumn = Jim_GetString(objv[objc-2]);
2201 rc = Jim_GetWide(interp, objv[objc-1], &iRow);
2203 if( rc==JIM_OK ){
2204 rc = createIncrblobChannel(
2205 interp, pDb, zDb, zTable, zColumn, iRow, isReadonly
2208 #endif
2209 break;
2213 ** $db interrupt
2215 ** Interrupt the execution of the inner-most SQL interpreter. This
2216 ** causes the SQL statement to return an error of SQLITE_INTERRUPT.
2218 case DB_INTERRUPT: {
2219 sqlite3_interrupt(pDb->db);
2220 break;
2224 ** $db nullvalue ?STRING?
2226 ** Change text used when a NULL comes back from the database. If ?STRING?
2227 ** is not present, then the current string used for NULL is returned.
2228 ** If STRING is present, then STRING is returned.
2231 case DB_NULLVALUE: {
2232 if( objc!=2 && objc!=3 ){
2233 Jim_WrongNumArgs(interp, 2, objv, "NULLVALUE");
2234 return JIM_ERR;
2236 if( objc==3 ){
2237 int len;
2238 const char *zNull = Jim_GetString(objv[2], &len);
2239 if( pDb->zNull ){
2240 Jim_Free(pDb->zNull);
2242 if( zNull && len>0 ){
2243 pDb->zNull = Jim_Alloc( len + 1 );
2244 strncpy(pDb->zNull, zNull, len);
2245 pDb->zNull[len] = '\0';
2246 }else{
2247 pDb->zNull = 0;
2250 Jim_SetResult(interp, dbTextToObj(interp, pDb->zNull));
2251 break;
2255 ** $db last_insert_rowid
2257 ** Return an integer which is the ROWID for the most recent insert.
2259 case DB_LAST_INSERT_ROWID: {
2260 if( objc!=2 ){
2261 Jim_WrongNumArgs(interp, 2, objv, "");
2262 return JIM_ERR;
2264 Jim_SetResultInt(interp, sqlite3_last_insert_rowid(pDb->db));
2265 break;
2269 ** The DB_ONECOLUMN method is implemented together with DB_EXISTS.
2272 /* $db progress ?N CALLBACK?
2274 ** Invoke the given callback every N virtual machine opcodes while executing
2275 ** queries.
2277 case DB_PROGRESS: {
2278 if( objc==2 ){
2279 if( pDb->zProgress ){
2280 Jim_AppendString(interp, Jim_GetResult(interp), pDb->zProgress, -1);
2282 }else if( objc==4 ){
2283 const char *zProgress;
2284 int len;
2285 long N;
2286 if( JIM_OK!=Jim_GetLong(interp, objv[2], &N) ){
2287 return JIM_ERR;
2289 if( pDb->zProgress ){
2290 Jim_Free(pDb->zProgress);
2292 zProgress = Jim_GetString(objv[3], &len);
2293 if( zProgress && len>0 ){
2294 pDb->zProgress = Jim_Alloc( len + 1 );
2295 memcpy(pDb->zProgress, zProgress, len+1);
2296 }else{
2297 pDb->zProgress = 0;
2299 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
2300 if( pDb->zProgress ){
2301 pDb->interp = interp;
2302 sqlite3_progress_handler(pDb->db, N, DbProgressHandler, pDb);
2303 }else{
2304 sqlite3_progress_handler(pDb->db, 0, 0, 0);
2306 #endif
2307 }else{
2308 Jim_WrongNumArgs(interp, 2, objv, "N CALLBACK");
2309 return JIM_ERR;
2311 break;
2314 /* $db profile ?CALLBACK?
2316 ** Make arrangements to invoke the CALLBACK routine after each SQL statement
2317 ** that has run. The text of the SQL and the amount of elapse time are
2318 ** appended to CALLBACK before the script is run.
2320 case DB_PROFILE: {
2321 if( objc>3 ){
2322 Jim_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
2323 return JIM_ERR;
2324 }else if( objc==2 ){
2325 if( pDb->zProfile ){
2326 Jim_SetResultString(interp, pDb->zProfile, -1);
2328 }else{
2329 const char *zProfile;
2330 int len;
2331 if( pDb->zProfile ){
2332 Jim_Free(pDb->zProfile);
2334 zProfile = Jim_GetString(objv[2], &len);
2335 if( zProfile && len>0 ){
2336 pDb->zProfile = Jim_Alloc( len + 1 );
2337 memcpy(pDb->zProfile, zProfile, len+1);
2338 }else{
2339 pDb->zProfile = 0;
2341 #ifndef SQLITE_OMIT_TRACE
2342 if( pDb->zProfile ){
2343 pDb->interp = interp;
2344 sqlite3_profile(pDb->db, DbProfileHandler, pDb);
2345 }else{
2346 sqlite3_profile(pDb->db, 0, 0);
2348 #endif
2350 break;
2354 ** $db rekey KEY
2356 ** Change the encryption key on the currently open database.
2358 case DB_REKEY: {
2359 int nKey;
2360 const char *pKey;
2361 if( objc!=3 ){
2362 Jim_WrongNumArgs(interp, 2, objv, "KEY");
2363 return JIM_ERR;
2365 //pKey = Jim_GetByteArrayFromObj(objv[2], &nKey);
2366 pKey = Jim_GetString(objv[2], &nKey);
2367 #ifdef SQLITE_HAS_CODEC
2368 rc = sqlite3_rekey(pDb->db, pKey, nKey);
2369 if( rc ){
2370 Jim_SetResultString(interp, sqlite3ErrStr(rc), -1);
2371 rc = JIM_ERR;
2373 #endif
2374 break;
2377 /* $db restore ?DATABASE? FILENAME
2379 ** Open a database file named FILENAME. Transfer the content
2380 ** of FILENAME into the local database DATABASE (default: "main").
2382 case DB_RESTORE: {
2383 const char *zSrcFile;
2384 const char *zDestDb;
2385 sqlite3 *pSrc;
2386 sqlite3_backup *pBackup;
2387 int nTimeout = 0;
2389 if( objc==3 ){
2390 zDestDb = "main";
2391 zSrcFile = Jim_String(objv[2]);
2392 }else if( objc==4 ){
2393 zDestDb = Jim_String(objv[2]);
2394 zSrcFile = Jim_String(objv[3]);
2395 }else{
2396 Jim_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME");
2397 return JIM_ERR;
2399 rc = sqlite3_open_v2(zSrcFile, &pSrc, SQLITE_OPEN_READONLY, 0);
2400 if( rc!=SQLITE_OK ){
2401 Jim_SetResultFormatted(interp, "cannot open source database: %s", sqlite3_errmsg(pSrc));
2402 sqlite3_close(pSrc);
2403 return JIM_ERR;
2405 pBackup = sqlite3_backup_init(pDb->db, zDestDb, pSrc, "main");
2406 if( pBackup==0 ){
2407 Jim_SetResultFormatted(interp, "restore failed: %s", sqlite3_errmsg(pDb->db));
2408 sqlite3_close(pSrc);
2409 return JIM_ERR;
2411 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
2412 || rc==SQLITE_BUSY ){
2413 if( rc==SQLITE_BUSY ){
2414 if( nTimeout++ >= 3 ) break;
2415 sqlite3_sleep(100);
2418 sqlite3_backup_finish(pBackup);
2419 if( rc==SQLITE_DONE ){
2420 rc = JIM_OK;
2421 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
2422 Jim_SetResultString(interp, "restore failed: source database busy", -1);
2423 rc = JIM_ERR;
2424 }else{
2425 Jim_SetResultFormatted(interp, "restore failed: %s", sqlite3_errmsg(pDb->db));
2426 rc = JIM_ERR;
2428 sqlite3_close(pSrc);
2429 break;
2433 ** $db status (step|sort)
2435 ** Display SQLITE_STMTSTATUS_FULLSCAN_STEP or
2436 ** SQLITE_STMTSTATUS_SORT for the most recent eval.
2438 case DB_STATUS: {
2439 int v;
2440 const char *zOp;
2441 if( objc!=3 ){
2442 Jim_WrongNumArgs(interp, 2, objv, "(step|sort)");
2443 return JIM_ERR;
2445 zOp = Jim_String(objv[2]);
2446 if( strcmp(zOp, "step")==0 ){
2447 v = pDb->nStep;
2448 }else if( strcmp(zOp, "sort")==0 ){
2449 v = pDb->nSort;
2450 }else{
2451 Jim_SetResultString(interp, "bad argument: should be step or sort", -1);
2452 return JIM_ERR;
2454 Jim_SetResultInt(interp, v);
2455 break;
2459 ** $db timeout MILLESECONDS
2461 ** Delay for the number of milliseconds specified when a file is locked.
2463 case DB_TIMEOUT: {
2464 long ms;
2465 if( objc!=3 ){
2466 Jim_WrongNumArgs(interp, 2, objv, "MILLISECONDS");
2467 return JIM_ERR;
2469 if( Jim_GetLong(interp, objv[2], &ms) ) return JIM_ERR;
2470 sqlite3_busy_timeout(pDb->db, ms);
2471 break;
2475 ** $db total_changes
2477 ** Return the number of rows that were modified, inserted, or deleted
2478 ** since the database handle was created.
2480 case DB_TOTAL_CHANGES: {
2481 if( objc!=2 ){
2482 Jim_WrongNumArgs(interp, 2, objv, "");
2483 return JIM_ERR;
2485 Jim_SetResultInt(interp, sqlite3_total_changes(pDb->db));
2486 break;
2489 /* $db trace ?CALLBACK?
2491 ** Make arrangements to invoke the CALLBACK routine for each SQL statement
2492 ** that is executed. The text of the SQL is appended to CALLBACK before
2493 ** it is executed.
2495 case DB_TRACE: {
2496 if( objc>3 ){
2497 Jim_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
2498 return JIM_ERR;
2499 }else if( objc==2 ){
2500 if( pDb->zTrace ){
2501 Jim_AppendString(interp, Jim_GetResult(interp), pDb->zTrace, -1);
2503 }else{
2504 const char *zTrace;
2505 int len;
2506 if( pDb->zTrace ){
2507 Jim_Free(pDb->zTrace);
2509 zTrace = Jim_GetString(objv[2], &len);
2510 if( zTrace && len>0 ){
2511 pDb->zTrace = Jim_Alloc( len + 1 );
2512 memcpy(pDb->zTrace, zTrace, len+1);
2513 }else{
2514 pDb->zTrace = 0;
2516 #ifndef SQLITE_OMIT_TRACE
2517 if( pDb->zTrace ){
2518 pDb->interp = interp;
2519 sqlite3_trace(pDb->db, DbTraceHandler, pDb);
2520 }else{
2521 sqlite3_trace(pDb->db, 0, 0);
2523 #endif
2525 break;
2528 /* $db transaction [-deferred|-immediate|-exclusive] SCRIPT
2530 ** Start a new transaction (if we are not already in the midst of a
2531 ** transaction) and execute the TCL script SCRIPT. After SCRIPT
2532 ** completes, either commit the transaction or roll it back if SCRIPT
2533 ** throws an exception. Or if no new transation was started, do nothing.
2534 ** pass the exception on up the stack.
2536 ** This command was inspired by Dave Thomas's talk on Ruby at the
2537 ** 2005 O'Reilly Open Source Convention (OSCON).
2539 case DB_TRANSACTION: {
2540 Jim_Obj *pScript;
2541 const char *zBegin = "SAVEPOINT _tcl_transaction";
2542 if( objc!=3 && objc!=4 ){
2543 Jim_WrongNumArgs(interp, 2, objv, "[TYPE] SCRIPT");
2544 return JIM_ERR;
2547 if( pDb->nTransaction==0 && objc==4 ){
2548 static const char *TTYPE_strs[] = {
2549 "deferred", "exclusive", "immediate", 0
2551 enum TTYPE_enum {
2552 TTYPE_DEFERRED, TTYPE_EXCLUSIVE, TTYPE_IMMEDIATE
2554 int ttype;
2555 if( Jim_GetEnum(interp, objv[2], TTYPE_strs, &ttype, "transaction type", JIM_ERRMSG | JIM_ENUM_ABBREV) ){
2556 return JIM_ERR;
2558 switch( (enum TTYPE_enum)ttype ){
2559 case TTYPE_DEFERRED: /* no-op */; break;
2560 case TTYPE_EXCLUSIVE: zBegin = "BEGIN EXCLUSIVE"; break;
2561 case TTYPE_IMMEDIATE: zBegin = "BEGIN IMMEDIATE"; break;
2564 pScript = objv[objc-1];
2566 /* Run the SQLite BEGIN command to open a transaction or savepoint. */
2567 pDb->disableAuth++;
2568 rc = sqlite3_exec(pDb->db, zBegin, 0, 0, 0);
2569 pDb->disableAuth--;
2570 if( rc!=SQLITE_OK ){
2571 Jim_SetResultString(interp, sqlite3_errmsg(pDb->db), -1);
2572 return JIM_ERR;
2574 pDb->nTransaction++;
2576 /* No NRE in Jim Tcl, so evaluate the script directly, then
2577 ** call function DbTransPostCmd() to commit (or rollback) the transaction
2578 ** or savepoint. */
2579 rc = DbTransPostCmd(interp, pDb, Jim_EvalObj(interp, pScript));
2580 break;
2584 ** $db unlock_notify ?script?
2586 case DB_UNLOCK_NOTIFY: {
2587 #ifndef SQLITE_ENABLE_UNLOCK_NOTIFY
2588 Jim_SetResultString(interp, "unlock_notify not available in this build", -1);
2589 rc = JIM_ERR;
2590 #else
2591 if( objc!=2 && objc!=3 ){
2592 Jim_WrongNumArgs(interp, 2, objv, "?SCRIPT?");
2593 rc = JIM_ERR;
2594 }else{
2595 void (*xNotify)(void **, int) = 0;
2596 void *pNotifyArg = 0;
2598 if( pDb->pUnlockNotify ){
2599 Jim_DecrRefCount(interp, pDb->pUnlockNotify);
2600 pDb->pUnlockNotify = 0;
2603 if( objc==3 ){
2604 xNotify = DbUnlockNotify;
2605 pNotifyArg = (void *)pDb;
2606 pDb->pUnlockNotify = objv[2];
2607 Jim_IncrRefCount(pDb->pUnlockNotify);
2610 if( sqlite3_unlock_notify(pDb->db, xNotify, pNotifyArg) ){
2611 Jim_SetResultString(interp, sqlite3_errmsg(pDb->db), -1);
2612 rc = JIM_ERR;
2615 #endif
2616 break;
2620 ** $db update_hook ?script?
2621 ** $db rollback_hook ?script?
2623 case DB_UPDATE_HOOK:
2624 case DB_ROLLBACK_HOOK: {
2626 /* set ppHook to point at pUpdateHook or pRollbackHook, depending on
2627 ** whether [$db update_hook] or [$db rollback_hook] was invoked.
2629 Jim_Obj **ppHook;
2630 if( choice==DB_UPDATE_HOOK ){
2631 ppHook = &pDb->pUpdateHook;
2632 }else{
2633 ppHook = &pDb->pRollbackHook;
2636 if( objc!=2 && objc!=3 ){
2637 Jim_WrongNumArgs(interp, 2, objv, "?SCRIPT?");
2638 return JIM_ERR;
2640 if( *ppHook ){
2641 Jim_SetResult(interp, *ppHook);
2642 if( objc==3 ){
2643 Jim_DecrRefCount(interp, *ppHook);
2644 *ppHook = 0;
2647 if( objc==3 ){
2648 assert( !(*ppHook) );
2649 if( Jim_Length(objv[2])>0 ){
2650 *ppHook = objv[2];
2651 Jim_IncrRefCount(*ppHook);
2655 sqlite3_update_hook(pDb->db, (pDb->pUpdateHook?DbUpdateHandler:0), pDb);
2656 sqlite3_rollback_hook(pDb->db,(pDb->pRollbackHook?DbRollbackHandler:0),pDb);
2658 break;
2661 /* $db version
2663 ** Return the version string for this database.
2665 case DB_VERSION: {
2666 Jim_SetResultString(interp, sqlite3_libversion(), -1);
2667 break;
2671 } /* End of the SWITCH statement */
2672 return rc;
2676 ** sqlite3 DBNAME FILENAME ?-vfs VFSNAME? ?-key KEY? ?-readonly BOOLEAN?
2677 ** ?-create BOOLEAN? ?-nomutex BOOLEAN?
2679 ** This is the main Tcl command. When the "sqlite" Tcl command is
2680 ** invoked, this routine runs to process that command.
2682 ** The first argument, DBNAME, is an arbitrary name for a new
2683 ** database connection. This command creates a new command named
2684 ** DBNAME that is used to control that connection. The database
2685 ** connection is deleted when the DBNAME command is deleted.
2687 ** The second argument is the name of the database file.
2690 static int DbMain(Jim_Interp *interp, int objc, Jim_Obj *const*objv){
2691 SqliteDb *p;
2692 const char *pKey = 0;
2693 int nKey = 0;
2694 const char *zArg;
2695 char *zErrMsg;
2696 int i;
2697 const char *zFile;
2698 const char *zVfs = 0;
2699 int flags;
2701 /* Not threading in Jim, so no mutexing is needed */
2702 flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX;
2704 if( objc==2 ){
2705 zArg = Jim_String(objv[1]);
2706 if( strcmp(zArg,"-version")==0 ){
2707 Jim_SetResultString(interp, sqlite3_version, -1);
2708 return JIM_OK;
2710 if( strcmp(zArg,"-has-codec")==0 ){
2711 #ifdef SQLITE_HAS_CODEC
2712 Jim_SetResultInt(interp, 1);
2713 #else
2714 Jim_SetResultInt(interp, 0);
2715 #endif
2716 return JIM_OK;
2719 for(i=3; i+1<objc; i+=2){
2720 zArg = Jim_String(objv[i]);
2721 if( strcmp(zArg,"-key")==0 ){
2722 pKey = Jim_GetString(objv[i+1], &nKey);
2723 }else if( strcmp(zArg, "-vfs")==0 ){
2724 i++;
2725 zVfs = Jim_String(objv[i]);
2726 }else if( strcmp(zArg, "-readonly")==0 ){
2727 long b;
2728 if( Jim_GetLong(interp, objv[i+1], &b) ) return JIM_ERR;
2729 if( b ){
2730 flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
2731 flags |= SQLITE_OPEN_READONLY;
2732 }else{
2733 flags &= ~SQLITE_OPEN_READONLY;
2734 flags |= SQLITE_OPEN_READWRITE;
2736 }else if( strcmp(zArg, "-create")==0 ){
2737 long b;
2738 if( Jim_GetLong(interp, objv[i+1], &b) ) return JIM_ERR;
2739 if( b && (flags & SQLITE_OPEN_READONLY)==0 ){
2740 flags |= SQLITE_OPEN_CREATE;
2741 }else{
2742 flags &= ~SQLITE_OPEN_CREATE;
2744 }else if( strcmp(zArg, "-nomutex")==0 ){
2745 long b;
2746 if( Jim_GetLong(interp, objv[i+1], &b) ) return JIM_ERR;
2747 if( b ){
2748 flags |= SQLITE_OPEN_NOMUTEX;
2749 flags &= ~SQLITE_OPEN_FULLMUTEX;
2750 }else{
2751 flags &= ~SQLITE_OPEN_NOMUTEX;
2753 }else if( strcmp(zArg, "-fullmutex")==0 ){
2754 long b;
2755 if( Jim_GetLong(interp, objv[i+1], &b) ) return JIM_ERR;
2756 if( b ){
2757 flags |= SQLITE_OPEN_FULLMUTEX;
2758 flags &= ~SQLITE_OPEN_NOMUTEX;
2759 }else{
2760 flags &= ~SQLITE_OPEN_FULLMUTEX;
2762 }else{
2763 Jim_SetResultFormatted(interp, "unknown option: %s", zArg);
2764 return JIM_ERR;
2767 if( objc<3 || (objc&1)!=1 ){
2768 Jim_WrongNumArgs(interp, 1, objv,
2769 "HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?"
2770 " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN?"
2771 #ifdef SQLITE_HAS_CODEC
2772 " ?-key CODECKEY?"
2773 #endif
2775 return JIM_ERR;
2777 zErrMsg = 0;
2778 p = (SqliteDb*)Jim_Alloc( sizeof(*p) );
2779 memset(p, 0, sizeof(*p));
2780 zFile = Jim_String(objv[2]);
2781 sqlite3_open_v2(zFile, &p->db, flags, zVfs);
2782 if( SQLITE_OK!=sqlite3_errcode(p->db) ){
2783 zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db));
2784 sqlite3_close(p->db);
2785 p->db = 0;
2787 #ifdef SQLITE_HAS_CODEC
2788 if( p->db ){
2789 sqlite3_key(p->db, pKey, nKey);
2791 #endif
2792 if( p->db==0 ){
2793 Jim_SetResultString(interp, zErrMsg, -1);
2794 Jim_Free((char*)p);
2795 sqlite3_free(zErrMsg);
2796 return JIM_ERR;
2798 p->maxStmt = NUM_PREPARED_STMTS;
2799 p->interp = interp;
2800 zArg = Jim_String(objv[1]);
2801 Jim_CreateCommand(interp, zArg, DbObjCmd, p, DbDeleteCmd);
2802 return JIM_OK;
2806 ** Make sure we have a PACKAGE_VERSION macro defined. This will be
2807 ** defined automatically by the TEA makefile. But other makefiles
2808 ** do not define it.
2810 #ifndef PACKAGE_VERSION
2811 # define PACKAGE_VERSION SQLITE_VERSION
2812 #endif
2814 #define EXTERN
2816 ** Initialize this module.
2818 ** This Tcl module contains only a single new Tcl command named "sqlite".
2819 ** (Hence there is no namespace. There is no point in using a namespace
2820 ** if the extension only supplies one new name!) The "sqlite" command is
2821 ** used to open a new SQLite database. See the DbMain() routine above
2822 ** for additional information.
2824 EXTERN int Jim_sqlite3Init(Jim_Interp *interp){
2825 Jim_CreateCommand(interp, "sqlite3", DbMain, 0, 0);
2826 Jim_PackageProvide(interp, "sqlite3", PACKAGE_VERSION, 0);
2827 Jim_CreateCommand(interp, "sqlite", DbMain, 0, 0);
2828 Jim_PackageProvide(interp, "sqlite", PACKAGE_VERSION, 0);
2829 return JIM_OK;