000001 /* 000002 ** 2001 September 15 000003 ** 000004 ** The author disclaims copyright to this source code. In place of 000005 ** a legal notice, here is a blessing: 000006 ** 000007 ** May you do good and not evil. 000008 ** May you find forgiveness for yourself and forgive others. 000009 ** May you share freely, never taking more than you give. 000010 ** 000011 ************************************************************************* 000012 ** A TCL Interface to SQLite. Append this file to sqlite3.c and 000013 ** compile the whole thing to build a TCL-enabled version of SQLite. 000014 ** 000015 ** Compile-time options: 000016 ** 000017 ** -DTCLSH Add a "main()" routine that works as a tclsh. 000018 ** 000019 ** -DTCLSH_INIT_PROC=name 000020 ** 000021 ** Invoke name(interp) to initialize the Tcl interpreter. 000022 ** If name(interp) returns a non-NULL string, then run 000023 ** that string as a Tcl script to launch the application. 000024 ** If name(interp) returns NULL, then run the regular 000025 ** tclsh-emulator code. 000026 */ 000027 #ifdef TCLSH_INIT_PROC 000028 # define TCLSH 1 000029 #endif 000030 000031 /* 000032 ** If requested, include the SQLite compiler options file for MSVC. 000033 */ 000034 #if defined(INCLUDE_MSVC_H) 000035 # include "msvc.h" 000036 #endif 000037 000038 #if defined(INCLUDE_SQLITE_TCL_H) 000039 # include "sqlite_tcl.h" 000040 #else 000041 # include "tcl.h" 000042 # ifndef SQLITE_TCLAPI 000043 # define SQLITE_TCLAPI 000044 # endif 000045 #endif 000046 #include <errno.h> 000047 000048 /* 000049 ** Some additional include files are needed if this file is not 000050 ** appended to the amalgamation. 000051 */ 000052 #ifndef SQLITE_AMALGAMATION 000053 # include "sqlite3.h" 000054 # include <stdlib.h> 000055 # include <string.h> 000056 # include <assert.h> 000057 typedef unsigned char u8; 000058 # ifndef SQLITE_PTRSIZE 000059 # if defined(__SIZEOF_POINTER__) 000060 # define SQLITE_PTRSIZE __SIZEOF_POINTER__ 000061 # elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \ 000062 defined(_M_ARM) || defined(__arm__) || defined(__x86) || \ 000063 (defined(__APPLE__) && defined(__POWERPC__)) || \ 000064 (defined(__TOS_AIX__) && !defined(__64BIT__)) 000065 # define SQLITE_PTRSIZE 4 000066 # else 000067 # define SQLITE_PTRSIZE 8 000068 # endif 000069 # endif /* SQLITE_PTRSIZE */ 000070 # if defined(HAVE_STDINT_H) 000071 typedef uintptr_t uptr; 000072 # elif SQLITE_PTRSIZE==4 000073 typedef unsigned int uptr; 000074 # else 000075 typedef sqlite3_uint64 uptr; 000076 # endif 000077 #endif 000078 #include <ctype.h> 000079 000080 /* Used to get the current process ID */ 000081 #if !defined(_WIN32) 000082 # include <signal.h> 000083 # include <unistd.h> 000084 # define GETPID getpid 000085 #elif !defined(_WIN32_WCE) 000086 # ifndef SQLITE_AMALGAMATION 000087 # ifndef WIN32_LEAN_AND_MEAN 000088 # define WIN32_LEAN_AND_MEAN 000089 # endif 000090 # include <windows.h> 000091 # endif 000092 # include <io.h> 000093 # define isatty(h) _isatty(h) 000094 # define GETPID (int)GetCurrentProcessId 000095 #endif 000096 000097 /* 000098 * Windows needs to know which symbols to export. Unix does not. 000099 * BUILD_sqlite should be undefined for Unix. 000100 */ 000101 #ifdef BUILD_sqlite 000102 #undef TCL_STORAGE_CLASS 000103 #define TCL_STORAGE_CLASS DLLEXPORT 000104 #endif /* BUILD_sqlite */ 000105 000106 #define NUM_PREPARED_STMTS 10 000107 #define MAX_PREPARED_STMTS 100 000108 000109 /* Forward declaration */ 000110 typedef struct SqliteDb SqliteDb; 000111 000112 /* 000113 ** New SQL functions can be created as TCL scripts. Each such function 000114 ** is described by an instance of the following structure. 000115 ** 000116 ** Variable eType may be set to SQLITE_INTEGER, SQLITE_FLOAT, SQLITE_TEXT, 000117 ** SQLITE_BLOB or SQLITE_NULL. If it is SQLITE_NULL, then the implementation 000118 ** attempts to determine the type of the result based on the Tcl object. 000119 ** If it is SQLITE_TEXT or SQLITE_BLOB, then a text (sqlite3_result_text()) 000120 ** or blob (sqlite3_result_blob()) is returned. If it is SQLITE_INTEGER 000121 ** or SQLITE_FLOAT, then an attempt is made to return an integer or float 000122 ** value, falling back to float and then text if this is not possible. 000123 */ 000124 typedef struct SqlFunc SqlFunc; 000125 struct SqlFunc { 000126 Tcl_Interp *interp; /* The TCL interpret to execute the function */ 000127 Tcl_Obj *pScript; /* The Tcl_Obj representation of the script */ 000128 SqliteDb *pDb; /* Database connection that owns this function */ 000129 int useEvalObjv; /* True if it is safe to use Tcl_EvalObjv */ 000130 int eType; /* Type of value to return */ 000131 char *zName; /* Name of this function */ 000132 SqlFunc *pNext; /* Next function on the list of them all */ 000133 }; 000134 000135 /* 000136 ** New collation sequences function can be created as TCL scripts. Each such 000137 ** function is described by an instance of the following structure. 000138 */ 000139 typedef struct SqlCollate SqlCollate; 000140 struct SqlCollate { 000141 Tcl_Interp *interp; /* The TCL interpret to execute the function */ 000142 char *zScript; /* The script to be run */ 000143 SqlCollate *pNext; /* Next function on the list of them all */ 000144 }; 000145 000146 /* 000147 ** Prepared statements are cached for faster execution. Each prepared 000148 ** statement is described by an instance of the following structure. 000149 */ 000150 typedef struct SqlPreparedStmt SqlPreparedStmt; 000151 struct SqlPreparedStmt { 000152 SqlPreparedStmt *pNext; /* Next in linked list */ 000153 SqlPreparedStmt *pPrev; /* Previous on the list */ 000154 sqlite3_stmt *pStmt; /* The prepared statement */ 000155 int nSql; /* chars in zSql[] */ 000156 const char *zSql; /* Text of the SQL statement */ 000157 int nParm; /* Size of apParm array */ 000158 Tcl_Obj **apParm; /* Array of referenced object pointers */ 000159 }; 000160 000161 typedef struct IncrblobChannel IncrblobChannel; 000162 000163 /* 000164 ** There is one instance of this structure for each SQLite database 000165 ** that has been opened by the SQLite TCL interface. 000166 ** 000167 ** If this module is built with SQLITE_TEST defined (to create the SQLite 000168 ** testfixture executable), then it may be configured to use either 000169 ** sqlite3_prepare_v2() or sqlite3_prepare() to prepare SQL statements. 000170 ** If SqliteDb.bLegacyPrepare is true, sqlite3_prepare() is used. 000171 */ 000172 struct SqliteDb { 000173 sqlite3 *db; /* The "real" database structure. MUST BE FIRST */ 000174 Tcl_Interp *interp; /* The interpreter used for this database */ 000175 char *zBusy; /* The busy callback routine */ 000176 char *zCommit; /* The commit hook callback routine */ 000177 char *zTrace; /* The trace callback routine */ 000178 char *zTraceV2; /* The trace_v2 callback routine */ 000179 char *zProfile; /* The profile callback routine */ 000180 char *zProgress; /* The progress callback routine */ 000181 char *zBindFallback; /* Callback to invoke on a binding miss */ 000182 char *zAuth; /* The authorization callback routine */ 000183 int disableAuth; /* Disable the authorizer if it exists */ 000184 char *zNull; /* Text to substitute for an SQL NULL value */ 000185 SqlFunc *pFunc; /* List of SQL functions */ 000186 Tcl_Obj *pUpdateHook; /* Update hook script (if any) */ 000187 Tcl_Obj *pPreUpdateHook; /* Pre-update hook script (if any) */ 000188 Tcl_Obj *pRollbackHook; /* Rollback hook script (if any) */ 000189 Tcl_Obj *pWalHook; /* WAL hook script (if any) */ 000190 Tcl_Obj *pUnlockNotify; /* Unlock notify script (if any) */ 000191 SqlCollate *pCollate; /* List of SQL collation functions */ 000192 int rc; /* Return code of most recent sqlite3_exec() */ 000193 Tcl_Obj *pCollateNeeded; /* Collation needed script */ 000194 SqlPreparedStmt *stmtList; /* List of prepared statements*/ 000195 SqlPreparedStmt *stmtLast; /* Last statement in the list */ 000196 int maxStmt; /* The next maximum number of stmtList */ 000197 int nStmt; /* Number of statements in stmtList */ 000198 IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */ 000199 int nStep, nSort, nIndex; /* Statistics for most recent operation */ 000200 int nVMStep; /* Another statistic for most recent operation */ 000201 int nTransaction; /* Number of nested [transaction] methods */ 000202 int openFlags; /* Flags used to open. (SQLITE_OPEN_URI) */ 000203 int nRef; /* Delete object when this reaches 0 */ 000204 #ifdef SQLITE_TEST 000205 int bLegacyPrepare; /* True to use sqlite3_prepare() */ 000206 #endif 000207 }; 000208 000209 struct IncrblobChannel { 000210 sqlite3_blob *pBlob; /* sqlite3 blob handle */ 000211 SqliteDb *pDb; /* Associated database connection */ 000212 int iSeek; /* Current seek offset */ 000213 Tcl_Channel channel; /* Channel identifier */ 000214 IncrblobChannel *pNext; /* Linked list of all open incrblob channels */ 000215 IncrblobChannel *pPrev; /* Linked list of all open incrblob channels */ 000216 }; 000217 000218 /* 000219 ** Compute a string length that is limited to what can be stored in 000220 ** lower 30 bits of a 32-bit signed integer. 000221 */ 000222 static int strlen30(const char *z){ 000223 const char *z2 = z; 000224 while( *z2 ){ z2++; } 000225 return 0x3fffffff & (int)(z2 - z); 000226 } 000227 000228 000229 #ifndef SQLITE_OMIT_INCRBLOB 000230 /* 000231 ** Close all incrblob channels opened using database connection pDb. 000232 ** This is called when shutting down the database connection. 000233 */ 000234 static void closeIncrblobChannels(SqliteDb *pDb){ 000235 IncrblobChannel *p; 000236 IncrblobChannel *pNext; 000237 000238 for(p=pDb->pIncrblob; p; p=pNext){ 000239 pNext = p->pNext; 000240 000241 /* Note: Calling unregister here call Tcl_Close on the incrblob channel, 000242 ** which deletes the IncrblobChannel structure at *p. So do not 000243 ** call Tcl_Free() here. 000244 */ 000245 Tcl_UnregisterChannel(pDb->interp, p->channel); 000246 } 000247 } 000248 000249 /* 000250 ** Close an incremental blob channel. 000251 */ 000252 static int SQLITE_TCLAPI incrblobClose( 000253 ClientData instanceData, 000254 Tcl_Interp *interp 000255 ){ 000256 IncrblobChannel *p = (IncrblobChannel *)instanceData; 000257 int rc = sqlite3_blob_close(p->pBlob); 000258 sqlite3 *db = p->pDb->db; 000259 000260 /* Remove the channel from the SqliteDb.pIncrblob list. */ 000261 if( p->pNext ){ 000262 p->pNext->pPrev = p->pPrev; 000263 } 000264 if( p->pPrev ){ 000265 p->pPrev->pNext = p->pNext; 000266 } 000267 if( p->pDb->pIncrblob==p ){ 000268 p->pDb->pIncrblob = p->pNext; 000269 } 000270 000271 /* Free the IncrblobChannel structure */ 000272 Tcl_Free((char *)p); 000273 000274 if( rc!=SQLITE_OK ){ 000275 Tcl_SetResult(interp, (char *)sqlite3_errmsg(db), TCL_VOLATILE); 000276 return TCL_ERROR; 000277 } 000278 return TCL_OK; 000279 } 000280 000281 /* 000282 ** Read data from an incremental blob channel. 000283 */ 000284 static int SQLITE_TCLAPI incrblobInput( 000285 ClientData instanceData, 000286 char *buf, 000287 int bufSize, 000288 int *errorCodePtr 000289 ){ 000290 IncrblobChannel *p = (IncrblobChannel *)instanceData; 000291 int nRead = bufSize; /* Number of bytes to read */ 000292 int nBlob; /* Total size of the blob */ 000293 int rc; /* sqlite error code */ 000294 000295 nBlob = sqlite3_blob_bytes(p->pBlob); 000296 if( (p->iSeek+nRead)>nBlob ){ 000297 nRead = nBlob-p->iSeek; 000298 } 000299 if( nRead<=0 ){ 000300 return 0; 000301 } 000302 000303 rc = sqlite3_blob_read(p->pBlob, (void *)buf, nRead, p->iSeek); 000304 if( rc!=SQLITE_OK ){ 000305 *errorCodePtr = rc; 000306 return -1; 000307 } 000308 000309 p->iSeek += nRead; 000310 return nRead; 000311 } 000312 000313 /* 000314 ** Write data to an incremental blob channel. 000315 */ 000316 static int SQLITE_TCLAPI incrblobOutput( 000317 ClientData instanceData, 000318 CONST char *buf, 000319 int toWrite, 000320 int *errorCodePtr 000321 ){ 000322 IncrblobChannel *p = (IncrblobChannel *)instanceData; 000323 int nWrite = toWrite; /* Number of bytes to write */ 000324 int nBlob; /* Total size of the blob */ 000325 int rc; /* sqlite error code */ 000326 000327 nBlob = sqlite3_blob_bytes(p->pBlob); 000328 if( (p->iSeek+nWrite)>nBlob ){ 000329 *errorCodePtr = EINVAL; 000330 return -1; 000331 } 000332 if( nWrite<=0 ){ 000333 return 0; 000334 } 000335 000336 rc = sqlite3_blob_write(p->pBlob, (void *)buf, nWrite, p->iSeek); 000337 if( rc!=SQLITE_OK ){ 000338 *errorCodePtr = EIO; 000339 return -1; 000340 } 000341 000342 p->iSeek += nWrite; 000343 return nWrite; 000344 } 000345 000346 /* 000347 ** Seek an incremental blob channel. 000348 */ 000349 static int SQLITE_TCLAPI incrblobSeek( 000350 ClientData instanceData, 000351 long offset, 000352 int seekMode, 000353 int *errorCodePtr 000354 ){ 000355 IncrblobChannel *p = (IncrblobChannel *)instanceData; 000356 000357 switch( seekMode ){ 000358 case SEEK_SET: 000359 p->iSeek = offset; 000360 break; 000361 case SEEK_CUR: 000362 p->iSeek += offset; 000363 break; 000364 case SEEK_END: 000365 p->iSeek = sqlite3_blob_bytes(p->pBlob) + offset; 000366 break; 000367 000368 default: assert(!"Bad seekMode"); 000369 } 000370 000371 return p->iSeek; 000372 } 000373 000374 000375 static void SQLITE_TCLAPI incrblobWatch( 000376 ClientData instanceData, 000377 int mode 000378 ){ 000379 /* NO-OP */ 000380 } 000381 static int SQLITE_TCLAPI incrblobHandle( 000382 ClientData instanceData, 000383 int dir, 000384 ClientData *hPtr 000385 ){ 000386 return TCL_ERROR; 000387 } 000388 000389 static Tcl_ChannelType IncrblobChannelType = { 000390 "incrblob", /* typeName */ 000391 TCL_CHANNEL_VERSION_2, /* version */ 000392 incrblobClose, /* closeProc */ 000393 incrblobInput, /* inputProc */ 000394 incrblobOutput, /* outputProc */ 000395 incrblobSeek, /* seekProc */ 000396 0, /* setOptionProc */ 000397 0, /* getOptionProc */ 000398 incrblobWatch, /* watchProc (this is a no-op) */ 000399 incrblobHandle, /* getHandleProc (always returns error) */ 000400 0, /* close2Proc */ 000401 0, /* blockModeProc */ 000402 0, /* flushProc */ 000403 0, /* handlerProc */ 000404 0, /* wideSeekProc */ 000405 }; 000406 000407 /* 000408 ** Create a new incrblob channel. 000409 */ 000410 static int createIncrblobChannel( 000411 Tcl_Interp *interp, 000412 SqliteDb *pDb, 000413 const char *zDb, 000414 const char *zTable, 000415 const char *zColumn, 000416 sqlite_int64 iRow, 000417 int isReadonly 000418 ){ 000419 IncrblobChannel *p; 000420 sqlite3 *db = pDb->db; 000421 sqlite3_blob *pBlob; 000422 int rc; 000423 int flags = TCL_READABLE|(isReadonly ? 0 : TCL_WRITABLE); 000424 000425 /* This variable is used to name the channels: "incrblob_[incr count]" */ 000426 static int count = 0; 000427 char zChannel[64]; 000428 000429 rc = sqlite3_blob_open(db, zDb, zTable, zColumn, iRow, !isReadonly, &pBlob); 000430 if( rc!=SQLITE_OK ){ 000431 Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE); 000432 return TCL_ERROR; 000433 } 000434 000435 p = (IncrblobChannel *)Tcl_Alloc(sizeof(IncrblobChannel)); 000436 p->iSeek = 0; 000437 p->pBlob = pBlob; 000438 000439 sqlite3_snprintf(sizeof(zChannel), zChannel, "incrblob_%d", ++count); 000440 p->channel = Tcl_CreateChannel(&IncrblobChannelType, zChannel, p, flags); 000441 Tcl_RegisterChannel(interp, p->channel); 000442 000443 /* Link the new channel into the SqliteDb.pIncrblob list. */ 000444 p->pNext = pDb->pIncrblob; 000445 p->pPrev = 0; 000446 if( p->pNext ){ 000447 p->pNext->pPrev = p; 000448 } 000449 pDb->pIncrblob = p; 000450 p->pDb = pDb; 000451 000452 Tcl_SetResult(interp, (char *)Tcl_GetChannelName(p->channel), TCL_VOLATILE); 000453 return TCL_OK; 000454 } 000455 #else /* else clause for "#ifndef SQLITE_OMIT_INCRBLOB" */ 000456 #define closeIncrblobChannels(pDb) 000457 #endif 000458 000459 /* 000460 ** Look at the script prefix in pCmd. We will be executing this script 000461 ** after first appending one or more arguments. This routine analyzes 000462 ** the script to see if it is safe to use Tcl_EvalObjv() on the script 000463 ** rather than the more general Tcl_EvalEx(). Tcl_EvalObjv() is much 000464 ** faster. 000465 ** 000466 ** Scripts that are safe to use with Tcl_EvalObjv() consists of a 000467 ** command name followed by zero or more arguments with no [...] or $ 000468 ** or {...} or ; to be seen anywhere. Most callback scripts consist 000469 ** of just a single procedure name and they meet this requirement. 000470 */ 000471 static int safeToUseEvalObjv(Tcl_Interp *interp, Tcl_Obj *pCmd){ 000472 /* We could try to do something with Tcl_Parse(). But we will instead 000473 ** just do a search for forbidden characters. If any of the forbidden 000474 ** characters appear in pCmd, we will report the string as unsafe. 000475 */ 000476 const char *z; 000477 int n; 000478 z = Tcl_GetStringFromObj(pCmd, &n); 000479 while( n-- > 0 ){ 000480 int c = *(z++); 000481 if( c=='$' || c=='[' || c==';' ) return 0; 000482 } 000483 return 1; 000484 } 000485 000486 /* 000487 ** Find an SqlFunc structure with the given name. Or create a new 000488 ** one if an existing one cannot be found. Return a pointer to the 000489 ** structure. 000490 */ 000491 static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){ 000492 SqlFunc *p, *pNew; 000493 int nName = strlen30(zName); 000494 pNew = (SqlFunc*)Tcl_Alloc( sizeof(*pNew) + nName + 1 ); 000495 pNew->zName = (char*)&pNew[1]; 000496 memcpy(pNew->zName, zName, nName+1); 000497 for(p=pDb->pFunc; p; p=p->pNext){ 000498 if( sqlite3_stricmp(p->zName, pNew->zName)==0 ){ 000499 Tcl_Free((char*)pNew); 000500 return p; 000501 } 000502 } 000503 pNew->interp = pDb->interp; 000504 pNew->pDb = pDb; 000505 pNew->pScript = 0; 000506 pNew->pNext = pDb->pFunc; 000507 pDb->pFunc = pNew; 000508 return pNew; 000509 } 000510 000511 /* 000512 ** Free a single SqlPreparedStmt object. 000513 */ 000514 static void dbFreeStmt(SqlPreparedStmt *pStmt){ 000515 #ifdef SQLITE_TEST 000516 if( sqlite3_sql(pStmt->pStmt)==0 ){ 000517 Tcl_Free((char *)pStmt->zSql); 000518 } 000519 #endif 000520 sqlite3_finalize(pStmt->pStmt); 000521 Tcl_Free((char *)pStmt); 000522 } 000523 000524 /* 000525 ** Finalize and free a list of prepared statements 000526 */ 000527 static void flushStmtCache(SqliteDb *pDb){ 000528 SqlPreparedStmt *pPreStmt; 000529 SqlPreparedStmt *pNext; 000530 000531 for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pNext){ 000532 pNext = pPreStmt->pNext; 000533 dbFreeStmt(pPreStmt); 000534 } 000535 pDb->nStmt = 0; 000536 pDb->stmtLast = 0; 000537 pDb->stmtList = 0; 000538 } 000539 000540 /* 000541 ** Increment the reference counter on the SqliteDb object. The reference 000542 ** should be released by calling delDatabaseRef(). 000543 */ 000544 static void addDatabaseRef(SqliteDb *pDb){ 000545 pDb->nRef++; 000546 } 000547 000548 /* 000549 ** Decrement the reference counter associated with the SqliteDb object. 000550 ** If it reaches zero, delete the object. 000551 */ 000552 static void delDatabaseRef(SqliteDb *pDb){ 000553 assert( pDb->nRef>0 ); 000554 pDb->nRef--; 000555 if( pDb->nRef==0 ){ 000556 flushStmtCache(pDb); 000557 closeIncrblobChannels(pDb); 000558 sqlite3_close(pDb->db); 000559 while( pDb->pFunc ){ 000560 SqlFunc *pFunc = pDb->pFunc; 000561 pDb->pFunc = pFunc->pNext; 000562 assert( pFunc->pDb==pDb ); 000563 Tcl_DecrRefCount(pFunc->pScript); 000564 Tcl_Free((char*)pFunc); 000565 } 000566 while( pDb->pCollate ){ 000567 SqlCollate *pCollate = pDb->pCollate; 000568 pDb->pCollate = pCollate->pNext; 000569 Tcl_Free((char*)pCollate); 000570 } 000571 if( pDb->zBusy ){ 000572 Tcl_Free(pDb->zBusy); 000573 } 000574 if( pDb->zTrace ){ 000575 Tcl_Free(pDb->zTrace); 000576 } 000577 if( pDb->zTraceV2 ){ 000578 Tcl_Free(pDb->zTraceV2); 000579 } 000580 if( pDb->zProfile ){ 000581 Tcl_Free(pDb->zProfile); 000582 } 000583 if( pDb->zBindFallback ){ 000584 Tcl_Free(pDb->zBindFallback); 000585 } 000586 if( pDb->zAuth ){ 000587 Tcl_Free(pDb->zAuth); 000588 } 000589 if( pDb->zNull ){ 000590 Tcl_Free(pDb->zNull); 000591 } 000592 if( pDb->pUpdateHook ){ 000593 Tcl_DecrRefCount(pDb->pUpdateHook); 000594 } 000595 if( pDb->pPreUpdateHook ){ 000596 Tcl_DecrRefCount(pDb->pPreUpdateHook); 000597 } 000598 if( pDb->pRollbackHook ){ 000599 Tcl_DecrRefCount(pDb->pRollbackHook); 000600 } 000601 if( pDb->pWalHook ){ 000602 Tcl_DecrRefCount(pDb->pWalHook); 000603 } 000604 if( pDb->pCollateNeeded ){ 000605 Tcl_DecrRefCount(pDb->pCollateNeeded); 000606 } 000607 Tcl_Free((char*)pDb); 000608 } 000609 } 000610 000611 /* 000612 ** TCL calls this procedure when an sqlite3 database command is 000613 ** deleted. 000614 */ 000615 static void SQLITE_TCLAPI DbDeleteCmd(void *db){ 000616 SqliteDb *pDb = (SqliteDb*)db; 000617 delDatabaseRef(pDb); 000618 } 000619 000620 /* 000621 ** This routine is called when a database file is locked while trying 000622 ** to execute SQL. 000623 */ 000624 static int DbBusyHandler(void *cd, int nTries){ 000625 SqliteDb *pDb = (SqliteDb*)cd; 000626 int rc; 000627 char zVal[30]; 000628 000629 sqlite3_snprintf(sizeof(zVal), zVal, "%d", nTries); 000630 rc = Tcl_VarEval(pDb->interp, pDb->zBusy, " ", zVal, (char*)0); 000631 if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){ 000632 return 0; 000633 } 000634 return 1; 000635 } 000636 000637 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK 000638 /* 000639 ** This routine is invoked as the 'progress callback' for the database. 000640 */ 000641 static int DbProgressHandler(void *cd){ 000642 SqliteDb *pDb = (SqliteDb*)cd; 000643 int rc; 000644 000645 assert( pDb->zProgress ); 000646 rc = Tcl_Eval(pDb->interp, pDb->zProgress); 000647 if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){ 000648 return 1; 000649 } 000650 return 0; 000651 } 000652 #endif 000653 000654 #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \ 000655 !defined(SQLITE_OMIT_DEPRECATED) 000656 /* 000657 ** This routine is called by the SQLite trace handler whenever a new 000658 ** block of SQL is executed. The TCL script in pDb->zTrace is executed. 000659 */ 000660 static void DbTraceHandler(void *cd, const char *zSql){ 000661 SqliteDb *pDb = (SqliteDb*)cd; 000662 Tcl_DString str; 000663 000664 Tcl_DStringInit(&str); 000665 Tcl_DStringAppend(&str, pDb->zTrace, -1); 000666 Tcl_DStringAppendElement(&str, zSql); 000667 Tcl_Eval(pDb->interp, Tcl_DStringValue(&str)); 000668 Tcl_DStringFree(&str); 000669 Tcl_ResetResult(pDb->interp); 000670 } 000671 #endif 000672 000673 #ifndef SQLITE_OMIT_TRACE 000674 /* 000675 ** This routine is called by the SQLite trace_v2 handler whenever a new 000676 ** supported event is generated. Unsupported event types are ignored. 000677 ** The TCL script in pDb->zTraceV2 is executed, with the arguments for 000678 ** the event appended to it (as list elements). 000679 */ 000680 static int DbTraceV2Handler( 000681 unsigned type, /* One of the SQLITE_TRACE_* event types. */ 000682 void *cd, /* The original context data pointer. */ 000683 void *pd, /* Primary event data, depends on event type. */ 000684 void *xd /* Extra event data, depends on event type. */ 000685 ){ 000686 SqliteDb *pDb = (SqliteDb*)cd; 000687 Tcl_Obj *pCmd; 000688 000689 switch( type ){ 000690 case SQLITE_TRACE_STMT: { 000691 sqlite3_stmt *pStmt = (sqlite3_stmt *)pd; 000692 char *zSql = (char *)xd; 000693 000694 pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1); 000695 Tcl_IncrRefCount(pCmd); 000696 Tcl_ListObjAppendElement(pDb->interp, pCmd, 000697 Tcl_NewWideIntObj((Tcl_WideInt)(uptr)pStmt)); 000698 Tcl_ListObjAppendElement(pDb->interp, pCmd, 000699 Tcl_NewStringObj(zSql, -1)); 000700 Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT); 000701 Tcl_DecrRefCount(pCmd); 000702 Tcl_ResetResult(pDb->interp); 000703 break; 000704 } 000705 case SQLITE_TRACE_PROFILE: { 000706 sqlite3_stmt *pStmt = (sqlite3_stmt *)pd; 000707 sqlite3_int64 ns = *(sqlite3_int64*)xd; 000708 000709 pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1); 000710 Tcl_IncrRefCount(pCmd); 000711 Tcl_ListObjAppendElement(pDb->interp, pCmd, 000712 Tcl_NewWideIntObj((Tcl_WideInt)(uptr)pStmt)); 000713 Tcl_ListObjAppendElement(pDb->interp, pCmd, 000714 Tcl_NewWideIntObj((Tcl_WideInt)ns)); 000715 Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT); 000716 Tcl_DecrRefCount(pCmd); 000717 Tcl_ResetResult(pDb->interp); 000718 break; 000719 } 000720 case SQLITE_TRACE_ROW: { 000721 sqlite3_stmt *pStmt = (sqlite3_stmt *)pd; 000722 000723 pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1); 000724 Tcl_IncrRefCount(pCmd); 000725 Tcl_ListObjAppendElement(pDb->interp, pCmd, 000726 Tcl_NewWideIntObj((Tcl_WideInt)(uptr)pStmt)); 000727 Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT); 000728 Tcl_DecrRefCount(pCmd); 000729 Tcl_ResetResult(pDb->interp); 000730 break; 000731 } 000732 case SQLITE_TRACE_CLOSE: { 000733 sqlite3 *db = (sqlite3 *)pd; 000734 000735 pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1); 000736 Tcl_IncrRefCount(pCmd); 000737 Tcl_ListObjAppendElement(pDb->interp, pCmd, 000738 Tcl_NewWideIntObj((Tcl_WideInt)(uptr)db)); 000739 Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT); 000740 Tcl_DecrRefCount(pCmd); 000741 Tcl_ResetResult(pDb->interp); 000742 break; 000743 } 000744 } 000745 return SQLITE_OK; 000746 } 000747 #endif 000748 000749 #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \ 000750 !defined(SQLITE_OMIT_DEPRECATED) 000751 /* 000752 ** This routine is called by the SQLite profile handler after a statement 000753 ** SQL has executed. The TCL script in pDb->zProfile is evaluated. 000754 */ 000755 static void DbProfileHandler(void *cd, const char *zSql, sqlite_uint64 tm){ 000756 SqliteDb *pDb = (SqliteDb*)cd; 000757 Tcl_DString str; 000758 char zTm[100]; 000759 000760 sqlite3_snprintf(sizeof(zTm)-1, zTm, "%lld", tm); 000761 Tcl_DStringInit(&str); 000762 Tcl_DStringAppend(&str, pDb->zProfile, -1); 000763 Tcl_DStringAppendElement(&str, zSql); 000764 Tcl_DStringAppendElement(&str, zTm); 000765 Tcl_Eval(pDb->interp, Tcl_DStringValue(&str)); 000766 Tcl_DStringFree(&str); 000767 Tcl_ResetResult(pDb->interp); 000768 } 000769 #endif 000770 000771 /* 000772 ** This routine is called when a transaction is committed. The 000773 ** TCL script in pDb->zCommit is executed. If it returns non-zero or 000774 ** if it throws an exception, the transaction is rolled back instead 000775 ** of being committed. 000776 */ 000777 static int DbCommitHandler(void *cd){ 000778 SqliteDb *pDb = (SqliteDb*)cd; 000779 int rc; 000780 000781 rc = Tcl_Eval(pDb->interp, pDb->zCommit); 000782 if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){ 000783 return 1; 000784 } 000785 return 0; 000786 } 000787 000788 static void DbRollbackHandler(void *clientData){ 000789 SqliteDb *pDb = (SqliteDb*)clientData; 000790 assert(pDb->pRollbackHook); 000791 if( TCL_OK!=Tcl_EvalObjEx(pDb->interp, pDb->pRollbackHook, 0) ){ 000792 Tcl_BackgroundError(pDb->interp); 000793 } 000794 } 000795 000796 /* 000797 ** This procedure handles wal_hook callbacks. 000798 */ 000799 static int DbWalHandler( 000800 void *clientData, 000801 sqlite3 *db, 000802 const char *zDb, 000803 int nEntry 000804 ){ 000805 int ret = SQLITE_OK; 000806 Tcl_Obj *p; 000807 SqliteDb *pDb = (SqliteDb*)clientData; 000808 Tcl_Interp *interp = pDb->interp; 000809 assert(pDb->pWalHook); 000810 000811 assert( db==pDb->db ); 000812 p = Tcl_DuplicateObj(pDb->pWalHook); 000813 Tcl_IncrRefCount(p); 000814 Tcl_ListObjAppendElement(interp, p, Tcl_NewStringObj(zDb, -1)); 000815 Tcl_ListObjAppendElement(interp, p, Tcl_NewIntObj(nEntry)); 000816 if( TCL_OK!=Tcl_EvalObjEx(interp, p, 0) 000817 || TCL_OK!=Tcl_GetIntFromObj(interp, Tcl_GetObjResult(interp), &ret) 000818 ){ 000819 Tcl_BackgroundError(interp); 000820 } 000821 Tcl_DecrRefCount(p); 000822 000823 return ret; 000824 } 000825 000826 #if defined(SQLITE_TEST) && defined(SQLITE_ENABLE_UNLOCK_NOTIFY) 000827 static void setTestUnlockNotifyVars(Tcl_Interp *interp, int iArg, int nArg){ 000828 char zBuf[64]; 000829 sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", iArg); 000830 Tcl_SetVar(interp, "sqlite_unlock_notify_arg", zBuf, TCL_GLOBAL_ONLY); 000831 sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", nArg); 000832 Tcl_SetVar(interp, "sqlite_unlock_notify_argcount", zBuf, TCL_GLOBAL_ONLY); 000833 } 000834 #else 000835 # define setTestUnlockNotifyVars(x,y,z) 000836 #endif 000837 000838 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY 000839 static void DbUnlockNotify(void **apArg, int nArg){ 000840 int i; 000841 for(i=0; i<nArg; i++){ 000842 const int flags = (TCL_EVAL_GLOBAL|TCL_EVAL_DIRECT); 000843 SqliteDb *pDb = (SqliteDb *)apArg[i]; 000844 setTestUnlockNotifyVars(pDb->interp, i, nArg); 000845 assert( pDb->pUnlockNotify); 000846 Tcl_EvalObjEx(pDb->interp, pDb->pUnlockNotify, flags); 000847 Tcl_DecrRefCount(pDb->pUnlockNotify); 000848 pDb->pUnlockNotify = 0; 000849 } 000850 } 000851 #endif 000852 000853 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK 000854 /* 000855 ** Pre-update hook callback. 000856 */ 000857 static void DbPreUpdateHandler( 000858 void *p, 000859 sqlite3 *db, 000860 int op, 000861 const char *zDb, 000862 const char *zTbl, 000863 sqlite_int64 iKey1, 000864 sqlite_int64 iKey2 000865 ){ 000866 SqliteDb *pDb = (SqliteDb *)p; 000867 Tcl_Obj *pCmd; 000868 static const char *azStr[] = {"DELETE", "INSERT", "UPDATE"}; 000869 000870 assert( (SQLITE_DELETE-1)/9 == 0 ); 000871 assert( (SQLITE_INSERT-1)/9 == 1 ); 000872 assert( (SQLITE_UPDATE-1)/9 == 2 ); 000873 assert( pDb->pPreUpdateHook ); 000874 assert( db==pDb->db ); 000875 assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE ); 000876 000877 pCmd = Tcl_DuplicateObj(pDb->pPreUpdateHook); 000878 Tcl_IncrRefCount(pCmd); 000879 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(azStr[(op-1)/9], -1)); 000880 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zDb, -1)); 000881 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zTbl, -1)); 000882 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(iKey1)); 000883 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(iKey2)); 000884 Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT); 000885 Tcl_DecrRefCount(pCmd); 000886 } 000887 #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ 000888 000889 static void DbUpdateHandler( 000890 void *p, 000891 int op, 000892 const char *zDb, 000893 const char *zTbl, 000894 sqlite_int64 rowid 000895 ){ 000896 SqliteDb *pDb = (SqliteDb *)p; 000897 Tcl_Obj *pCmd; 000898 static const char *azStr[] = {"DELETE", "INSERT", "UPDATE"}; 000899 000900 assert( (SQLITE_DELETE-1)/9 == 0 ); 000901 assert( (SQLITE_INSERT-1)/9 == 1 ); 000902 assert( (SQLITE_UPDATE-1)/9 == 2 ); 000903 000904 assert( pDb->pUpdateHook ); 000905 assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE ); 000906 000907 pCmd = Tcl_DuplicateObj(pDb->pUpdateHook); 000908 Tcl_IncrRefCount(pCmd); 000909 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(azStr[(op-1)/9], -1)); 000910 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zDb, -1)); 000911 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zTbl, -1)); 000912 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(rowid)); 000913 Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT); 000914 Tcl_DecrRefCount(pCmd); 000915 } 000916 000917 static void tclCollateNeeded( 000918 void *pCtx, 000919 sqlite3 *db, 000920 int enc, 000921 const char *zName 000922 ){ 000923 SqliteDb *pDb = (SqliteDb *)pCtx; 000924 Tcl_Obj *pScript = Tcl_DuplicateObj(pDb->pCollateNeeded); 000925 Tcl_IncrRefCount(pScript); 000926 Tcl_ListObjAppendElement(0, pScript, Tcl_NewStringObj(zName, -1)); 000927 Tcl_EvalObjEx(pDb->interp, pScript, 0); 000928 Tcl_DecrRefCount(pScript); 000929 } 000930 000931 /* 000932 ** This routine is called to evaluate an SQL collation function implemented 000933 ** using TCL script. 000934 */ 000935 static int tclSqlCollate( 000936 void *pCtx, 000937 int nA, 000938 const void *zA, 000939 int nB, 000940 const void *zB 000941 ){ 000942 SqlCollate *p = (SqlCollate *)pCtx; 000943 Tcl_Obj *pCmd; 000944 000945 pCmd = Tcl_NewStringObj(p->zScript, -1); 000946 Tcl_IncrRefCount(pCmd); 000947 Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zA, nA)); 000948 Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zB, nB)); 000949 Tcl_EvalObjEx(p->interp, pCmd, TCL_EVAL_DIRECT); 000950 Tcl_DecrRefCount(pCmd); 000951 return (atoi(Tcl_GetStringResult(p->interp))); 000952 } 000953 000954 /* 000955 ** This routine is called to evaluate an SQL function implemented 000956 ** using TCL script. 000957 */ 000958 static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){ 000959 SqlFunc *p = sqlite3_user_data(context); 000960 Tcl_Obj *pCmd; 000961 int i; 000962 int rc; 000963 000964 if( argc==0 ){ 000965 /* If there are no arguments to the function, call Tcl_EvalObjEx on the 000966 ** script object directly. This allows the TCL compiler to generate 000967 ** bytecode for the command on the first invocation and thus make 000968 ** subsequent invocations much faster. */ 000969 pCmd = p->pScript; 000970 Tcl_IncrRefCount(pCmd); 000971 rc = Tcl_EvalObjEx(p->interp, pCmd, 0); 000972 Tcl_DecrRefCount(pCmd); 000973 }else{ 000974 /* If there are arguments to the function, make a shallow copy of the 000975 ** script object, lappend the arguments, then evaluate the copy. 000976 ** 000977 ** By "shallow" copy, we mean only the outer list Tcl_Obj is duplicated. 000978 ** The new Tcl_Obj contains pointers to the original list elements. 000979 ** That way, when Tcl_EvalObjv() is run and shimmers the first element 000980 ** of the list to tclCmdNameType, that alternate representation will 000981 ** be preserved and reused on the next invocation. 000982 */ 000983 Tcl_Obj **aArg; 000984 int nArg; 000985 if( Tcl_ListObjGetElements(p->interp, p->pScript, &nArg, &aArg) ){ 000986 sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); 000987 return; 000988 } 000989 pCmd = Tcl_NewListObj(nArg, aArg); 000990 Tcl_IncrRefCount(pCmd); 000991 for(i=0; i<argc; i++){ 000992 sqlite3_value *pIn = argv[i]; 000993 Tcl_Obj *pVal; 000994 000995 /* Set pVal to contain the i'th column of this row. */ 000996 switch( sqlite3_value_type(pIn) ){ 000997 case SQLITE_BLOB: { 000998 int bytes = sqlite3_value_bytes(pIn); 000999 pVal = Tcl_NewByteArrayObj(sqlite3_value_blob(pIn), bytes); 001000 break; 001001 } 001002 case SQLITE_INTEGER: { 001003 sqlite_int64 v = sqlite3_value_int64(pIn); 001004 if( v>=-2147483647 && v<=2147483647 ){ 001005 pVal = Tcl_NewIntObj((int)v); 001006 }else{ 001007 pVal = Tcl_NewWideIntObj(v); 001008 } 001009 break; 001010 } 001011 case SQLITE_FLOAT: { 001012 double r = sqlite3_value_double(pIn); 001013 pVal = Tcl_NewDoubleObj(r); 001014 break; 001015 } 001016 case SQLITE_NULL: { 001017 pVal = Tcl_NewStringObj(p->pDb->zNull, -1); 001018 break; 001019 } 001020 default: { 001021 int bytes = sqlite3_value_bytes(pIn); 001022 pVal = Tcl_NewStringObj((char *)sqlite3_value_text(pIn), bytes); 001023 break; 001024 } 001025 } 001026 rc = Tcl_ListObjAppendElement(p->interp, pCmd, pVal); 001027 if( rc ){ 001028 Tcl_DecrRefCount(pCmd); 001029 sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); 001030 return; 001031 } 001032 } 001033 if( !p->useEvalObjv ){ 001034 /* Tcl_EvalObjEx() will automatically call Tcl_EvalObjv() if pCmd 001035 ** is a list without a string representation. To prevent this from 001036 ** happening, make sure pCmd has a valid string representation */ 001037 Tcl_GetString(pCmd); 001038 } 001039 rc = Tcl_EvalObjEx(p->interp, pCmd, TCL_EVAL_DIRECT); 001040 Tcl_DecrRefCount(pCmd); 001041 } 001042 001043 if( rc && rc!=TCL_RETURN ){ 001044 sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); 001045 }else{ 001046 Tcl_Obj *pVar = Tcl_GetObjResult(p->interp); 001047 int n; 001048 u8 *data; 001049 const char *zType = (pVar->typePtr ? pVar->typePtr->name : ""); 001050 char c = zType[0]; 001051 int eType = p->eType; 001052 001053 if( eType==SQLITE_NULL ){ 001054 if( c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0 ){ 001055 /* Only return a BLOB type if the Tcl variable is a bytearray and 001056 ** has no string representation. */ 001057 eType = SQLITE_BLOB; 001058 }else if( (c=='b' && strcmp(zType,"boolean")==0) 001059 || (c=='w' && strcmp(zType,"wideInt")==0) 001060 || (c=='i' && strcmp(zType,"int")==0) 001061 ){ 001062 eType = SQLITE_INTEGER; 001063 }else if( c=='d' && strcmp(zType,"double")==0 ){ 001064 eType = SQLITE_FLOAT; 001065 }else{ 001066 eType = SQLITE_TEXT; 001067 } 001068 } 001069 001070 switch( eType ){ 001071 case SQLITE_BLOB: { 001072 data = Tcl_GetByteArrayFromObj(pVar, &n); 001073 sqlite3_result_blob(context, data, n, SQLITE_TRANSIENT); 001074 break; 001075 } 001076 case SQLITE_INTEGER: { 001077 Tcl_WideInt v; 001078 if( TCL_OK==Tcl_GetWideIntFromObj(0, pVar, &v) ){ 001079 sqlite3_result_int64(context, v); 001080 break; 001081 } 001082 /* fall-through */ 001083 } 001084 case SQLITE_FLOAT: { 001085 double r; 001086 if( TCL_OK==Tcl_GetDoubleFromObj(0, pVar, &r) ){ 001087 sqlite3_result_double(context, r); 001088 break; 001089 } 001090 /* fall-through */ 001091 } 001092 default: { 001093 data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n); 001094 sqlite3_result_text(context, (char *)data, n, SQLITE_TRANSIENT); 001095 break; 001096 } 001097 } 001098 001099 } 001100 } 001101 001102 #ifndef SQLITE_OMIT_AUTHORIZATION 001103 /* 001104 ** This is the authentication function. It appends the authentication 001105 ** type code and the two arguments to zCmd[] then invokes the result 001106 ** on the interpreter. The reply is examined to determine if the 001107 ** authentication fails or succeeds. 001108 */ 001109 static int auth_callback( 001110 void *pArg, 001111 int code, 001112 const char *zArg1, 001113 const char *zArg2, 001114 const char *zArg3, 001115 const char *zArg4 001116 #ifdef SQLITE_USER_AUTHENTICATION 001117 ,const char *zArg5 001118 #endif 001119 ){ 001120 const char *zCode; 001121 Tcl_DString str; 001122 int rc; 001123 const char *zReply; 001124 /* EVIDENCE-OF: R-38590-62769 The first parameter to the authorizer 001125 ** callback is a copy of the third parameter to the 001126 ** sqlite3_set_authorizer() interface. 001127 */ 001128 SqliteDb *pDb = (SqliteDb*)pArg; 001129 if( pDb->disableAuth ) return SQLITE_OK; 001130 001131 /* EVIDENCE-OF: R-56518-44310 The second parameter to the callback is an 001132 ** integer action code that specifies the particular action to be 001133 ** authorized. */ 001134 switch( code ){ 001135 case SQLITE_COPY : zCode="SQLITE_COPY"; break; 001136 case SQLITE_CREATE_INDEX : zCode="SQLITE_CREATE_INDEX"; break; 001137 case SQLITE_CREATE_TABLE : zCode="SQLITE_CREATE_TABLE"; break; 001138 case SQLITE_CREATE_TEMP_INDEX : zCode="SQLITE_CREATE_TEMP_INDEX"; break; 001139 case SQLITE_CREATE_TEMP_TABLE : zCode="SQLITE_CREATE_TEMP_TABLE"; break; 001140 case SQLITE_CREATE_TEMP_TRIGGER: zCode="SQLITE_CREATE_TEMP_TRIGGER"; break; 001141 case SQLITE_CREATE_TEMP_VIEW : zCode="SQLITE_CREATE_TEMP_VIEW"; break; 001142 case SQLITE_CREATE_TRIGGER : zCode="SQLITE_CREATE_TRIGGER"; break; 001143 case SQLITE_CREATE_VIEW : zCode="SQLITE_CREATE_VIEW"; break; 001144 case SQLITE_DELETE : zCode="SQLITE_DELETE"; break; 001145 case SQLITE_DROP_INDEX : zCode="SQLITE_DROP_INDEX"; break; 001146 case SQLITE_DROP_TABLE : zCode="SQLITE_DROP_TABLE"; break; 001147 case SQLITE_DROP_TEMP_INDEX : zCode="SQLITE_DROP_TEMP_INDEX"; break; 001148 case SQLITE_DROP_TEMP_TABLE : zCode="SQLITE_DROP_TEMP_TABLE"; break; 001149 case SQLITE_DROP_TEMP_TRIGGER : zCode="SQLITE_DROP_TEMP_TRIGGER"; break; 001150 case SQLITE_DROP_TEMP_VIEW : zCode="SQLITE_DROP_TEMP_VIEW"; break; 001151 case SQLITE_DROP_TRIGGER : zCode="SQLITE_DROP_TRIGGER"; break; 001152 case SQLITE_DROP_VIEW : zCode="SQLITE_DROP_VIEW"; break; 001153 case SQLITE_INSERT : zCode="SQLITE_INSERT"; break; 001154 case SQLITE_PRAGMA : zCode="SQLITE_PRAGMA"; break; 001155 case SQLITE_READ : zCode="SQLITE_READ"; break; 001156 case SQLITE_SELECT : zCode="SQLITE_SELECT"; break; 001157 case SQLITE_TRANSACTION : zCode="SQLITE_TRANSACTION"; break; 001158 case SQLITE_UPDATE : zCode="SQLITE_UPDATE"; break; 001159 case SQLITE_ATTACH : zCode="SQLITE_ATTACH"; break; 001160 case SQLITE_DETACH : zCode="SQLITE_DETACH"; break; 001161 case SQLITE_ALTER_TABLE : zCode="SQLITE_ALTER_TABLE"; break; 001162 case SQLITE_REINDEX : zCode="SQLITE_REINDEX"; break; 001163 case SQLITE_ANALYZE : zCode="SQLITE_ANALYZE"; break; 001164 case SQLITE_CREATE_VTABLE : zCode="SQLITE_CREATE_VTABLE"; break; 001165 case SQLITE_DROP_VTABLE : zCode="SQLITE_DROP_VTABLE"; break; 001166 case SQLITE_FUNCTION : zCode="SQLITE_FUNCTION"; break; 001167 case SQLITE_SAVEPOINT : zCode="SQLITE_SAVEPOINT"; break; 001168 case SQLITE_RECURSIVE : zCode="SQLITE_RECURSIVE"; break; 001169 default : zCode="????"; break; 001170 } 001171 Tcl_DStringInit(&str); 001172 Tcl_DStringAppend(&str, pDb->zAuth, -1); 001173 Tcl_DStringAppendElement(&str, zCode); 001174 Tcl_DStringAppendElement(&str, zArg1 ? zArg1 : ""); 001175 Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : ""); 001176 Tcl_DStringAppendElement(&str, zArg3 ? zArg3 : ""); 001177 Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : ""); 001178 #ifdef SQLITE_USER_AUTHENTICATION 001179 Tcl_DStringAppendElement(&str, zArg5 ? zArg5 : ""); 001180 #endif 001181 rc = Tcl_GlobalEval(pDb->interp, Tcl_DStringValue(&str)); 001182 Tcl_DStringFree(&str); 001183 zReply = rc==TCL_OK ? Tcl_GetStringResult(pDb->interp) : "SQLITE_DENY"; 001184 if( strcmp(zReply,"SQLITE_OK")==0 ){ 001185 rc = SQLITE_OK; 001186 }else if( strcmp(zReply,"SQLITE_DENY")==0 ){ 001187 rc = SQLITE_DENY; 001188 }else if( strcmp(zReply,"SQLITE_IGNORE")==0 ){ 001189 rc = SQLITE_IGNORE; 001190 }else{ 001191 rc = 999; 001192 } 001193 return rc; 001194 } 001195 #endif /* SQLITE_OMIT_AUTHORIZATION */ 001196 001197 /* 001198 ** This routine reads a line of text from FILE in, stores 001199 ** the text in memory obtained from malloc() and returns a pointer 001200 ** to the text. NULL is returned at end of file, or if malloc() 001201 ** fails. 001202 ** 001203 ** The interface is like "readline" but no command-line editing 001204 ** is done. 001205 ** 001206 ** copied from shell.c from '.import' command 001207 */ 001208 static char *local_getline(char *zPrompt, FILE *in){ 001209 char *zLine; 001210 int nLine; 001211 int n; 001212 001213 nLine = 100; 001214 zLine = malloc( nLine ); 001215 if( zLine==0 ) return 0; 001216 n = 0; 001217 while( 1 ){ 001218 if( n+100>nLine ){ 001219 nLine = nLine*2 + 100; 001220 zLine = realloc(zLine, nLine); 001221 if( zLine==0 ) return 0; 001222 } 001223 if( fgets(&zLine[n], nLine - n, in)==0 ){ 001224 if( n==0 ){ 001225 free(zLine); 001226 return 0; 001227 } 001228 zLine[n] = 0; 001229 break; 001230 } 001231 while( zLine[n] ){ n++; } 001232 if( n>0 && zLine[n-1]=='\n' ){ 001233 n--; 001234 zLine[n] = 0; 001235 break; 001236 } 001237 } 001238 zLine = realloc( zLine, n+1 ); 001239 return zLine; 001240 } 001241 001242 001243 /* 001244 ** This function is part of the implementation of the command: 001245 ** 001246 ** $db transaction [-deferred|-immediate|-exclusive] SCRIPT 001247 ** 001248 ** It is invoked after evaluating the script SCRIPT to commit or rollback 001249 ** the transaction or savepoint opened by the [transaction] command. 001250 */ 001251 static int SQLITE_TCLAPI DbTransPostCmd( 001252 ClientData data[], /* data[0] is the Sqlite3Db* for $db */ 001253 Tcl_Interp *interp, /* Tcl interpreter */ 001254 int result /* Result of evaluating SCRIPT */ 001255 ){ 001256 static const char *const azEnd[] = { 001257 "RELEASE _tcl_transaction", /* rc==TCL_ERROR, nTransaction!=0 */ 001258 "COMMIT", /* rc!=TCL_ERROR, nTransaction==0 */ 001259 "ROLLBACK TO _tcl_transaction ; RELEASE _tcl_transaction", 001260 "ROLLBACK" /* rc==TCL_ERROR, nTransaction==0 */ 001261 }; 001262 SqliteDb *pDb = (SqliteDb*)data[0]; 001263 int rc = result; 001264 const char *zEnd; 001265 001266 pDb->nTransaction--; 001267 zEnd = azEnd[(rc==TCL_ERROR)*2 + (pDb->nTransaction==0)]; 001268 001269 pDb->disableAuth++; 001270 if( sqlite3_exec(pDb->db, zEnd, 0, 0, 0) ){ 001271 /* This is a tricky scenario to handle. The most likely cause of an 001272 ** error is that the exec() above was an attempt to commit the 001273 ** top-level transaction that returned SQLITE_BUSY. Or, less likely, 001274 ** that an IO-error has occurred. In either case, throw a Tcl exception 001275 ** and try to rollback the transaction. 001276 ** 001277 ** But it could also be that the user executed one or more BEGIN, 001278 ** COMMIT, SAVEPOINT, RELEASE or ROLLBACK commands that are confusing 001279 ** this method's logic. Not clear how this would be best handled. 001280 */ 001281 if( rc!=TCL_ERROR ){ 001282 Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0); 001283 rc = TCL_ERROR; 001284 } 001285 sqlite3_exec(pDb->db, "ROLLBACK", 0, 0, 0); 001286 } 001287 pDb->disableAuth--; 001288 001289 delDatabaseRef(pDb); 001290 return rc; 001291 } 001292 001293 /* 001294 ** Unless SQLITE_TEST is defined, this function is a simple wrapper around 001295 ** sqlite3_prepare_v2(). If SQLITE_TEST is defined, then it uses either 001296 ** sqlite3_prepare_v2() or legacy interface sqlite3_prepare(), depending 001297 ** on whether or not the [db_use_legacy_prepare] command has been used to 001298 ** configure the connection. 001299 */ 001300 static int dbPrepare( 001301 SqliteDb *pDb, /* Database object */ 001302 const char *zSql, /* SQL to compile */ 001303 sqlite3_stmt **ppStmt, /* OUT: Prepared statement */ 001304 const char **pzOut /* OUT: Pointer to next SQL statement */ 001305 ){ 001306 unsigned int prepFlags = 0; 001307 #ifdef SQLITE_TEST 001308 if( pDb->bLegacyPrepare ){ 001309 return sqlite3_prepare(pDb->db, zSql, -1, ppStmt, pzOut); 001310 } 001311 #endif 001312 /* If the statement cache is large, use the SQLITE_PREPARE_PERSISTENT 001313 ** flags, which uses less lookaside memory. But if the cache is small, 001314 ** omit that flag to make full use of lookaside */ 001315 if( pDb->maxStmt>5 ) prepFlags = SQLITE_PREPARE_PERSISTENT; 001316 001317 return sqlite3_prepare_v3(pDb->db, zSql, -1, prepFlags, ppStmt, pzOut); 001318 } 001319 001320 /* 001321 ** Search the cache for a prepared-statement object that implements the 001322 ** first SQL statement in the buffer pointed to by parameter zIn. If 001323 ** no such prepared-statement can be found, allocate and prepare a new 001324 ** one. In either case, bind the current values of the relevant Tcl 001325 ** variables to any $var, :var or @var variables in the statement. Before 001326 ** returning, set *ppPreStmt to point to the prepared-statement object. 001327 ** 001328 ** Output parameter *pzOut is set to point to the next SQL statement in 001329 ** buffer zIn, or to the '\0' byte at the end of zIn if there is no 001330 ** next statement. 001331 ** 001332 ** If successful, TCL_OK is returned. Otherwise, TCL_ERROR is returned 001333 ** and an error message loaded into interpreter pDb->interp. 001334 */ 001335 static int dbPrepareAndBind( 001336 SqliteDb *pDb, /* Database object */ 001337 char const *zIn, /* SQL to compile */ 001338 char const **pzOut, /* OUT: Pointer to next SQL statement */ 001339 SqlPreparedStmt **ppPreStmt /* OUT: Object used to cache statement */ 001340 ){ 001341 const char *zSql = zIn; /* Pointer to first SQL statement in zIn */ 001342 sqlite3_stmt *pStmt = 0; /* Prepared statement object */ 001343 SqlPreparedStmt *pPreStmt; /* Pointer to cached statement */ 001344 int nSql; /* Length of zSql in bytes */ 001345 int nVar = 0; /* Number of variables in statement */ 001346 int iParm = 0; /* Next free entry in apParm */ 001347 char c; 001348 int i; 001349 int needResultReset = 0; /* Need to invoke Tcl_ResetResult() */ 001350 int rc = SQLITE_OK; /* Value to return */ 001351 Tcl_Interp *interp = pDb->interp; 001352 001353 *ppPreStmt = 0; 001354 001355 /* Trim spaces from the start of zSql and calculate the remaining length. */ 001356 while( (c = zSql[0])==' ' || c=='\t' || c=='\r' || c=='\n' ){ zSql++; } 001357 nSql = strlen30(zSql); 001358 001359 for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pPreStmt->pNext){ 001360 int n = pPreStmt->nSql; 001361 if( nSql>=n 001362 && memcmp(pPreStmt->zSql, zSql, n)==0 001363 && (zSql[n]==0 || zSql[n-1]==';') 001364 ){ 001365 pStmt = pPreStmt->pStmt; 001366 *pzOut = &zSql[pPreStmt->nSql]; 001367 001368 /* When a prepared statement is found, unlink it from the 001369 ** cache list. It will later be added back to the beginning 001370 ** of the cache list in order to implement LRU replacement. 001371 */ 001372 if( pPreStmt->pPrev ){ 001373 pPreStmt->pPrev->pNext = pPreStmt->pNext; 001374 }else{ 001375 pDb->stmtList = pPreStmt->pNext; 001376 } 001377 if( pPreStmt->pNext ){ 001378 pPreStmt->pNext->pPrev = pPreStmt->pPrev; 001379 }else{ 001380 pDb->stmtLast = pPreStmt->pPrev; 001381 } 001382 pDb->nStmt--; 001383 nVar = sqlite3_bind_parameter_count(pStmt); 001384 break; 001385 } 001386 } 001387 001388 /* If no prepared statement was found. Compile the SQL text. Also allocate 001389 ** a new SqlPreparedStmt structure. */ 001390 if( pPreStmt==0 ){ 001391 int nByte; 001392 001393 if( SQLITE_OK!=dbPrepare(pDb, zSql, &pStmt, pzOut) ){ 001394 Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1)); 001395 return TCL_ERROR; 001396 } 001397 if( pStmt==0 ){ 001398 if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){ 001399 /* A compile-time error in the statement. */ 001400 Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1)); 001401 return TCL_ERROR; 001402 }else{ 001403 /* The statement was a no-op. Continue to the next statement 001404 ** in the SQL string. 001405 */ 001406 return TCL_OK; 001407 } 001408 } 001409 001410 assert( pPreStmt==0 ); 001411 nVar = sqlite3_bind_parameter_count(pStmt); 001412 nByte = sizeof(SqlPreparedStmt) + nVar*sizeof(Tcl_Obj *); 001413 pPreStmt = (SqlPreparedStmt*)Tcl_Alloc(nByte); 001414 memset(pPreStmt, 0, nByte); 001415 001416 pPreStmt->pStmt = pStmt; 001417 pPreStmt->nSql = (int)(*pzOut - zSql); 001418 pPreStmt->zSql = sqlite3_sql(pStmt); 001419 pPreStmt->apParm = (Tcl_Obj **)&pPreStmt[1]; 001420 #ifdef SQLITE_TEST 001421 if( pPreStmt->zSql==0 ){ 001422 char *zCopy = Tcl_Alloc(pPreStmt->nSql + 1); 001423 memcpy(zCopy, zSql, pPreStmt->nSql); 001424 zCopy[pPreStmt->nSql] = '\0'; 001425 pPreStmt->zSql = zCopy; 001426 } 001427 #endif 001428 } 001429 assert( pPreStmt ); 001430 assert( strlen30(pPreStmt->zSql)==pPreStmt->nSql ); 001431 assert( 0==memcmp(pPreStmt->zSql, zSql, pPreStmt->nSql) ); 001432 001433 /* Bind values to parameters that begin with $ or : */ 001434 for(i=1; i<=nVar; i++){ 001435 const char *zVar = sqlite3_bind_parameter_name(pStmt, i); 001436 if( zVar!=0 && (zVar[0]=='$' || zVar[0]==':' || zVar[0]=='@') ){ 001437 Tcl_Obj *pVar = Tcl_GetVar2Ex(interp, &zVar[1], 0, 0); 001438 if( pVar==0 && pDb->zBindFallback!=0 ){ 001439 Tcl_Obj *pCmd; 001440 int rx; 001441 pCmd = Tcl_NewStringObj(pDb->zBindFallback, -1); 001442 Tcl_IncrRefCount(pCmd); 001443 Tcl_ListObjAppendElement(interp, pCmd, Tcl_NewStringObj(zVar,-1)); 001444 if( needResultReset ) Tcl_ResetResult(interp); 001445 needResultReset = 1; 001446 rx = Tcl_EvalObjEx(interp, pCmd, TCL_EVAL_DIRECT); 001447 Tcl_DecrRefCount(pCmd); 001448 if( rx==TCL_OK ){ 001449 pVar = Tcl_GetObjResult(interp); 001450 }else if( rx==TCL_ERROR ){ 001451 rc = TCL_ERROR; 001452 break; 001453 }else{ 001454 pVar = 0; 001455 } 001456 } 001457 if( pVar ){ 001458 int n; 001459 u8 *data; 001460 const char *zType = (pVar->typePtr ? pVar->typePtr->name : ""); 001461 c = zType[0]; 001462 if( zVar[0]=='@' || 001463 (c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0) ){ 001464 /* Load a BLOB type if the Tcl variable is a bytearray and 001465 ** it has no string representation or the host 001466 ** parameter name begins with "@". */ 001467 data = Tcl_GetByteArrayFromObj(pVar, &n); 001468 sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC); 001469 Tcl_IncrRefCount(pVar); 001470 pPreStmt->apParm[iParm++] = pVar; 001471 }else if( c=='b' && strcmp(zType,"boolean")==0 ){ 001472 Tcl_GetIntFromObj(interp, pVar, &n); 001473 sqlite3_bind_int(pStmt, i, n); 001474 }else if( c=='d' && strcmp(zType,"double")==0 ){ 001475 double r; 001476 Tcl_GetDoubleFromObj(interp, pVar, &r); 001477 sqlite3_bind_double(pStmt, i, r); 001478 }else if( (c=='w' && strcmp(zType,"wideInt")==0) || 001479 (c=='i' && strcmp(zType,"int")==0) ){ 001480 Tcl_WideInt v; 001481 Tcl_GetWideIntFromObj(interp, pVar, &v); 001482 sqlite3_bind_int64(pStmt, i, v); 001483 }else{ 001484 data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n); 001485 sqlite3_bind_text(pStmt, i, (char *)data, n, SQLITE_STATIC); 001486 Tcl_IncrRefCount(pVar); 001487 pPreStmt->apParm[iParm++] = pVar; 001488 } 001489 }else{ 001490 sqlite3_bind_null(pStmt, i); 001491 } 001492 if( needResultReset ) Tcl_ResetResult(pDb->interp); 001493 } 001494 } 001495 pPreStmt->nParm = iParm; 001496 *ppPreStmt = pPreStmt; 001497 if( needResultReset && rc==TCL_OK ) Tcl_ResetResult(pDb->interp); 001498 001499 return rc; 001500 } 001501 001502 /* 001503 ** Release a statement reference obtained by calling dbPrepareAndBind(). 001504 ** There should be exactly one call to this function for each call to 001505 ** dbPrepareAndBind(). 001506 ** 001507 ** If the discard parameter is non-zero, then the statement is deleted 001508 ** immediately. Otherwise it is added to the LRU list and may be returned 001509 ** by a subsequent call to dbPrepareAndBind(). 001510 */ 001511 static void dbReleaseStmt( 001512 SqliteDb *pDb, /* Database handle */ 001513 SqlPreparedStmt *pPreStmt, /* Prepared statement handle to release */ 001514 int discard /* True to delete (not cache) the pPreStmt */ 001515 ){ 001516 int i; 001517 001518 /* Free the bound string and blob parameters */ 001519 for(i=0; i<pPreStmt->nParm; i++){ 001520 Tcl_DecrRefCount(pPreStmt->apParm[i]); 001521 } 001522 pPreStmt->nParm = 0; 001523 001524 if( pDb->maxStmt<=0 || discard ){ 001525 /* If the cache is turned off, deallocated the statement */ 001526 dbFreeStmt(pPreStmt); 001527 }else{ 001528 /* Add the prepared statement to the beginning of the cache list. */ 001529 pPreStmt->pNext = pDb->stmtList; 001530 pPreStmt->pPrev = 0; 001531 if( pDb->stmtList ){ 001532 pDb->stmtList->pPrev = pPreStmt; 001533 } 001534 pDb->stmtList = pPreStmt; 001535 if( pDb->stmtLast==0 ){ 001536 assert( pDb->nStmt==0 ); 001537 pDb->stmtLast = pPreStmt; 001538 }else{ 001539 assert( pDb->nStmt>0 ); 001540 } 001541 pDb->nStmt++; 001542 001543 /* If we have too many statement in cache, remove the surplus from 001544 ** the end of the cache list. */ 001545 while( pDb->nStmt>pDb->maxStmt ){ 001546 SqlPreparedStmt *pLast = pDb->stmtLast; 001547 pDb->stmtLast = pLast->pPrev; 001548 pDb->stmtLast->pNext = 0; 001549 pDb->nStmt--; 001550 dbFreeStmt(pLast); 001551 } 001552 } 001553 } 001554 001555 /* 001556 ** Structure used with dbEvalXXX() functions: 001557 ** 001558 ** dbEvalInit() 001559 ** dbEvalStep() 001560 ** dbEvalFinalize() 001561 ** dbEvalRowInfo() 001562 ** dbEvalColumnValue() 001563 */ 001564 typedef struct DbEvalContext DbEvalContext; 001565 struct DbEvalContext { 001566 SqliteDb *pDb; /* Database handle */ 001567 Tcl_Obj *pSql; /* Object holding string zSql */ 001568 const char *zSql; /* Remaining SQL to execute */ 001569 SqlPreparedStmt *pPreStmt; /* Current statement */ 001570 int nCol; /* Number of columns returned by pStmt */ 001571 int evalFlags; /* Flags used */ 001572 Tcl_Obj *pArray; /* Name of array variable */ 001573 Tcl_Obj **apColName; /* Array of column names */ 001574 }; 001575 001576 #define SQLITE_EVAL_WITHOUTNULLS 0x00001 /* Unset array(*) for NULL */ 001577 001578 /* 001579 ** Release any cache of column names currently held as part of 001580 ** the DbEvalContext structure passed as the first argument. 001581 */ 001582 static void dbReleaseColumnNames(DbEvalContext *p){ 001583 if( p->apColName ){ 001584 int i; 001585 for(i=0; i<p->nCol; i++){ 001586 Tcl_DecrRefCount(p->apColName[i]); 001587 } 001588 Tcl_Free((char *)p->apColName); 001589 p->apColName = 0; 001590 } 001591 p->nCol = 0; 001592 } 001593 001594 /* 001595 ** Initialize a DbEvalContext structure. 001596 ** 001597 ** If pArray is not NULL, then it contains the name of a Tcl array 001598 ** variable. The "*" member of this array is set to a list containing 001599 ** the names of the columns returned by the statement as part of each 001600 ** call to dbEvalStep(), in order from left to right. e.g. if the names 001601 ** of the returned columns are a, b and c, it does the equivalent of the 001602 ** tcl command: 001603 ** 001604 ** set ${pArray}(*) {a b c} 001605 */ 001606 static void dbEvalInit( 001607 DbEvalContext *p, /* Pointer to structure to initialize */ 001608 SqliteDb *pDb, /* Database handle */ 001609 Tcl_Obj *pSql, /* Object containing SQL script */ 001610 Tcl_Obj *pArray, /* Name of Tcl array to set (*) element of */ 001611 int evalFlags /* Flags controlling evaluation */ 001612 ){ 001613 memset(p, 0, sizeof(DbEvalContext)); 001614 p->pDb = pDb; 001615 p->zSql = Tcl_GetString(pSql); 001616 p->pSql = pSql; 001617 Tcl_IncrRefCount(pSql); 001618 if( pArray ){ 001619 p->pArray = pArray; 001620 Tcl_IncrRefCount(pArray); 001621 } 001622 p->evalFlags = evalFlags; 001623 addDatabaseRef(p->pDb); 001624 } 001625 001626 /* 001627 ** Obtain information about the row that the DbEvalContext passed as the 001628 ** first argument currently points to. 001629 */ 001630 static void dbEvalRowInfo( 001631 DbEvalContext *p, /* Evaluation context */ 001632 int *pnCol, /* OUT: Number of column names */ 001633 Tcl_Obj ***papColName /* OUT: Array of column names */ 001634 ){ 001635 /* Compute column names */ 001636 if( 0==p->apColName ){ 001637 sqlite3_stmt *pStmt = p->pPreStmt->pStmt; 001638 int i; /* Iterator variable */ 001639 int nCol; /* Number of columns returned by pStmt */ 001640 Tcl_Obj **apColName = 0; /* Array of column names */ 001641 001642 p->nCol = nCol = sqlite3_column_count(pStmt); 001643 if( nCol>0 && (papColName || p->pArray) ){ 001644 apColName = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*)*nCol ); 001645 for(i=0; i<nCol; i++){ 001646 apColName[i] = Tcl_NewStringObj(sqlite3_column_name(pStmt,i), -1); 001647 Tcl_IncrRefCount(apColName[i]); 001648 } 001649 p->apColName = apColName; 001650 } 001651 001652 /* If results are being stored in an array variable, then create 001653 ** the array(*) entry for that array 001654 */ 001655 if( p->pArray ){ 001656 Tcl_Interp *interp = p->pDb->interp; 001657 Tcl_Obj *pColList = Tcl_NewObj(); 001658 Tcl_Obj *pStar = Tcl_NewStringObj("*", -1); 001659 001660 for(i=0; i<nCol; i++){ 001661 Tcl_ListObjAppendElement(interp, pColList, apColName[i]); 001662 } 001663 Tcl_IncrRefCount(pStar); 001664 Tcl_ObjSetVar2(interp, p->pArray, pStar, pColList, 0); 001665 Tcl_DecrRefCount(pStar); 001666 } 001667 } 001668 001669 if( papColName ){ 001670 *papColName = p->apColName; 001671 } 001672 if( pnCol ){ 001673 *pnCol = p->nCol; 001674 } 001675 } 001676 001677 /* 001678 ** Return one of TCL_OK, TCL_BREAK or TCL_ERROR. If TCL_ERROR is 001679 ** returned, then an error message is stored in the interpreter before 001680 ** returning. 001681 ** 001682 ** A return value of TCL_OK means there is a row of data available. The 001683 ** data may be accessed using dbEvalRowInfo() and dbEvalColumnValue(). This 001684 ** is analogous to a return of SQLITE_ROW from sqlite3_step(). If TCL_BREAK 001685 ** is returned, then the SQL script has finished executing and there are 001686 ** no further rows available. This is similar to SQLITE_DONE. 001687 */ 001688 static int dbEvalStep(DbEvalContext *p){ 001689 const char *zPrevSql = 0; /* Previous value of p->zSql */ 001690 001691 while( p->zSql[0] || p->pPreStmt ){ 001692 int rc; 001693 if( p->pPreStmt==0 ){ 001694 zPrevSql = (p->zSql==zPrevSql ? 0 : p->zSql); 001695 rc = dbPrepareAndBind(p->pDb, p->zSql, &p->zSql, &p->pPreStmt); 001696 if( rc!=TCL_OK ) return rc; 001697 }else{ 001698 int rcs; 001699 SqliteDb *pDb = p->pDb; 001700 SqlPreparedStmt *pPreStmt = p->pPreStmt; 001701 sqlite3_stmt *pStmt = pPreStmt->pStmt; 001702 001703 rcs = sqlite3_step(pStmt); 001704 if( rcs==SQLITE_ROW ){ 001705 return TCL_OK; 001706 } 001707 if( p->pArray ){ 001708 dbEvalRowInfo(p, 0, 0); 001709 } 001710 rcs = sqlite3_reset(pStmt); 001711 001712 pDb->nStep = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_FULLSCAN_STEP,1); 001713 pDb->nSort = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_SORT,1); 001714 pDb->nIndex = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_AUTOINDEX,1); 001715 pDb->nVMStep = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_VM_STEP,1); 001716 dbReleaseColumnNames(p); 001717 p->pPreStmt = 0; 001718 001719 if( rcs!=SQLITE_OK ){ 001720 /* If a run-time error occurs, report the error and stop reading 001721 ** the SQL. */ 001722 dbReleaseStmt(pDb, pPreStmt, 1); 001723 #if SQLITE_TEST 001724 if( p->pDb->bLegacyPrepare && rcs==SQLITE_SCHEMA && zPrevSql ){ 001725 /* If the runtime error was an SQLITE_SCHEMA, and the database 001726 ** handle is configured to use the legacy sqlite3_prepare() 001727 ** interface, retry prepare()/step() on the same SQL statement. 001728 ** This only happens once. If there is a second SQLITE_SCHEMA 001729 ** error, the error will be returned to the caller. */ 001730 p->zSql = zPrevSql; 001731 continue; 001732 } 001733 #endif 001734 Tcl_SetObjResult(pDb->interp, 001735 Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1)); 001736 return TCL_ERROR; 001737 }else{ 001738 dbReleaseStmt(pDb, pPreStmt, 0); 001739 } 001740 } 001741 } 001742 001743 /* Finished */ 001744 return TCL_BREAK; 001745 } 001746 001747 /* 001748 ** Free all resources currently held by the DbEvalContext structure passed 001749 ** as the first argument. There should be exactly one call to this function 001750 ** for each call to dbEvalInit(). 001751 */ 001752 static void dbEvalFinalize(DbEvalContext *p){ 001753 if( p->pPreStmt ){ 001754 sqlite3_reset(p->pPreStmt->pStmt); 001755 dbReleaseStmt(p->pDb, p->pPreStmt, 0); 001756 p->pPreStmt = 0; 001757 } 001758 if( p->pArray ){ 001759 Tcl_DecrRefCount(p->pArray); 001760 p->pArray = 0; 001761 } 001762 Tcl_DecrRefCount(p->pSql); 001763 dbReleaseColumnNames(p); 001764 delDatabaseRef(p->pDb); 001765 } 001766 001767 /* 001768 ** Return a pointer to a Tcl_Obj structure with ref-count 0 that contains 001769 ** the value for the iCol'th column of the row currently pointed to by 001770 ** the DbEvalContext structure passed as the first argument. 001771 */ 001772 static Tcl_Obj *dbEvalColumnValue(DbEvalContext *p, int iCol){ 001773 sqlite3_stmt *pStmt = p->pPreStmt->pStmt; 001774 switch( sqlite3_column_type(pStmt, iCol) ){ 001775 case SQLITE_BLOB: { 001776 int bytes = sqlite3_column_bytes(pStmt, iCol); 001777 const char *zBlob = sqlite3_column_blob(pStmt, iCol); 001778 if( !zBlob ) bytes = 0; 001779 return Tcl_NewByteArrayObj((u8*)zBlob, bytes); 001780 } 001781 case SQLITE_INTEGER: { 001782 sqlite_int64 v = sqlite3_column_int64(pStmt, iCol); 001783 if( v>=-2147483647 && v<=2147483647 ){ 001784 return Tcl_NewIntObj((int)v); 001785 }else{ 001786 return Tcl_NewWideIntObj(v); 001787 } 001788 } 001789 case SQLITE_FLOAT: { 001790 return Tcl_NewDoubleObj(sqlite3_column_double(pStmt, iCol)); 001791 } 001792 case SQLITE_NULL: { 001793 return Tcl_NewStringObj(p->pDb->zNull, -1); 001794 } 001795 } 001796 001797 return Tcl_NewStringObj((char*)sqlite3_column_text(pStmt, iCol), -1); 001798 } 001799 001800 /* 001801 ** If using Tcl version 8.6 or greater, use the NR functions to avoid 001802 ** recursive evaluation of scripts by the [db eval] and [db trans] 001803 ** commands. Even if the headers used while compiling the extension 001804 ** are 8.6 or newer, the code still tests the Tcl version at runtime. 001805 ** This allows stubs-enabled builds to be used with older Tcl libraries. 001806 */ 001807 #if TCL_MAJOR_VERSION>8 || (TCL_MAJOR_VERSION==8 && TCL_MINOR_VERSION>=6) 001808 # define SQLITE_TCL_NRE 1 001809 static int DbUseNre(void){ 001810 int major, minor; 001811 Tcl_GetVersion(&major, &minor, 0, 0); 001812 return( (major==8 && minor>=6) || major>8 ); 001813 } 001814 #else 001815 /* 001816 ** Compiling using headers earlier than 8.6. In this case NR cannot be 001817 ** used, so DbUseNre() to always return zero. Add #defines for the other 001818 ** Tcl_NRxxx() functions to prevent them from causing compilation errors, 001819 ** even though the only invocations of them are within conditional blocks 001820 ** of the form: 001821 ** 001822 ** if( DbUseNre() ) { ... } 001823 */ 001824 # define SQLITE_TCL_NRE 0 001825 # define DbUseNre() 0 001826 # define Tcl_NRAddCallback(a,b,c,d,e,f) (void)0 001827 # define Tcl_NREvalObj(a,b,c) 0 001828 # define Tcl_NRCreateCommand(a,b,c,d,e,f) (void)0 001829 #endif 001830 001831 /* 001832 ** This function is part of the implementation of the command: 001833 ** 001834 ** $db eval SQL ?ARRAYNAME? SCRIPT 001835 */ 001836 static int SQLITE_TCLAPI DbEvalNextCmd( 001837 ClientData data[], /* data[0] is the (DbEvalContext*) */ 001838 Tcl_Interp *interp, /* Tcl interpreter */ 001839 int result /* Result so far */ 001840 ){ 001841 int rc = result; /* Return code */ 001842 001843 /* The first element of the data[] array is a pointer to a DbEvalContext 001844 ** structure allocated using Tcl_Alloc(). The second element of data[] 001845 ** is a pointer to a Tcl_Obj containing the script to run for each row 001846 ** returned by the queries encapsulated in data[0]. */ 001847 DbEvalContext *p = (DbEvalContext *)data[0]; 001848 Tcl_Obj *pScript = (Tcl_Obj *)data[1]; 001849 Tcl_Obj *pArray = p->pArray; 001850 001851 while( (rc==TCL_OK || rc==TCL_CONTINUE) && TCL_OK==(rc = dbEvalStep(p)) ){ 001852 int i; 001853 int nCol; 001854 Tcl_Obj **apColName; 001855 dbEvalRowInfo(p, &nCol, &apColName); 001856 for(i=0; i<nCol; i++){ 001857 if( pArray==0 ){ 001858 Tcl_ObjSetVar2(interp, apColName[i], 0, dbEvalColumnValue(p,i), 0); 001859 }else if( (p->evalFlags & SQLITE_EVAL_WITHOUTNULLS)!=0 001860 && sqlite3_column_type(p->pPreStmt->pStmt, i)==SQLITE_NULL 001861 ){ 001862 Tcl_UnsetVar2(interp, Tcl_GetString(pArray), 001863 Tcl_GetString(apColName[i]), 0); 001864 }else{ 001865 Tcl_ObjSetVar2(interp, pArray, apColName[i], dbEvalColumnValue(p,i), 0); 001866 } 001867 } 001868 001869 /* The required interpreter variables are now populated with the data 001870 ** from the current row. If using NRE, schedule callbacks to evaluate 001871 ** script pScript, then to invoke this function again to fetch the next 001872 ** row (or clean up if there is no next row or the script throws an 001873 ** exception). After scheduling the callbacks, return control to the 001874 ** caller. 001875 ** 001876 ** If not using NRE, evaluate pScript directly and continue with the 001877 ** next iteration of this while(...) loop. */ 001878 if( DbUseNre() ){ 001879 Tcl_NRAddCallback(interp, DbEvalNextCmd, (void*)p, (void*)pScript, 0, 0); 001880 return Tcl_NREvalObj(interp, pScript, 0); 001881 }else{ 001882 rc = Tcl_EvalObjEx(interp, pScript, 0); 001883 } 001884 } 001885 001886 Tcl_DecrRefCount(pScript); 001887 dbEvalFinalize(p); 001888 Tcl_Free((char *)p); 001889 001890 if( rc==TCL_OK || rc==TCL_BREAK ){ 001891 Tcl_ResetResult(interp); 001892 rc = TCL_OK; 001893 } 001894 return rc; 001895 } 001896 001897 /* 001898 ** This function is used by the implementations of the following database 001899 ** handle sub-commands: 001900 ** 001901 ** $db update_hook ?SCRIPT? 001902 ** $db wal_hook ?SCRIPT? 001903 ** $db commit_hook ?SCRIPT? 001904 ** $db preupdate hook ?SCRIPT? 001905 */ 001906 static void DbHookCmd( 001907 Tcl_Interp *interp, /* Tcl interpreter */ 001908 SqliteDb *pDb, /* Database handle */ 001909 Tcl_Obj *pArg, /* SCRIPT argument (or NULL) */ 001910 Tcl_Obj **ppHook /* Pointer to member of SqliteDb */ 001911 ){ 001912 sqlite3 *db = pDb->db; 001913 001914 if( *ppHook ){ 001915 Tcl_SetObjResult(interp, *ppHook); 001916 if( pArg ){ 001917 Tcl_DecrRefCount(*ppHook); 001918 *ppHook = 0; 001919 } 001920 } 001921 if( pArg ){ 001922 assert( !(*ppHook) ); 001923 if( Tcl_GetCharLength(pArg)>0 ){ 001924 *ppHook = pArg; 001925 Tcl_IncrRefCount(*ppHook); 001926 } 001927 } 001928 001929 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK 001930 sqlite3_preupdate_hook(db, (pDb->pPreUpdateHook?DbPreUpdateHandler:0), pDb); 001931 #endif 001932 sqlite3_update_hook(db, (pDb->pUpdateHook?DbUpdateHandler:0), pDb); 001933 sqlite3_rollback_hook(db, (pDb->pRollbackHook?DbRollbackHandler:0), pDb); 001934 sqlite3_wal_hook(db, (pDb->pWalHook?DbWalHandler:0), pDb); 001935 } 001936 001937 /* 001938 ** The "sqlite" command below creates a new Tcl command for each 001939 ** connection it opens to an SQLite database. This routine is invoked 001940 ** whenever one of those connection-specific commands is executed 001941 ** in Tcl. For example, if you run Tcl code like this: 001942 ** 001943 ** sqlite3 db1 "my_database" 001944 ** db1 close 001945 ** 001946 ** The first command opens a connection to the "my_database" database 001947 ** and calls that connection "db1". The second command causes this 001948 ** subroutine to be invoked. 001949 */ 001950 static int SQLITE_TCLAPI DbObjCmd( 001951 void *cd, 001952 Tcl_Interp *interp, 001953 int objc, 001954 Tcl_Obj *const*objv 001955 ){ 001956 SqliteDb *pDb = (SqliteDb*)cd; 001957 int choice; 001958 int rc = TCL_OK; 001959 static const char *DB_strs[] = { 001960 "authorizer", "backup", "bind_fallback", 001961 "busy", "cache", "changes", 001962 "close", "collate", "collation_needed", 001963 "commit_hook", "complete", "config", 001964 "copy", "deserialize", "enable_load_extension", 001965 "errorcode", "erroroffset", "eval", 001966 "exists", "function", "incrblob", 001967 "interrupt", "last_insert_rowid", "nullvalue", 001968 "onecolumn", "preupdate", "profile", 001969 "progress", "rekey", "restore", 001970 "rollback_hook", "serialize", "status", 001971 "timeout", "total_changes", "trace", 001972 "trace_v2", "transaction", "unlock_notify", 001973 "update_hook", "version", "wal_hook", 001974 0 001975 }; 001976 enum DB_enum { 001977 DB_AUTHORIZER, DB_BACKUP, DB_BIND_FALLBACK, 001978 DB_BUSY, DB_CACHE, DB_CHANGES, 001979 DB_CLOSE, DB_COLLATE, DB_COLLATION_NEEDED, 001980 DB_COMMIT_HOOK, DB_COMPLETE, DB_CONFIG, 001981 DB_COPY, DB_DESERIALIZE, DB_ENABLE_LOAD_EXTENSION, 001982 DB_ERRORCODE, DB_ERROROFFSET, DB_EVAL, 001983 DB_EXISTS, DB_FUNCTION, DB_INCRBLOB, 001984 DB_INTERRUPT, DB_LAST_INSERT_ROWID, DB_NULLVALUE, 001985 DB_ONECOLUMN, DB_PREUPDATE, DB_PROFILE, 001986 DB_PROGRESS, DB_REKEY, DB_RESTORE, 001987 DB_ROLLBACK_HOOK, DB_SERIALIZE, DB_STATUS, 001988 DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE, 001989 DB_TRACE_V2, DB_TRANSACTION, DB_UNLOCK_NOTIFY, 001990 DB_UPDATE_HOOK, DB_VERSION, DB_WAL_HOOK, 001991 }; 001992 /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */ 001993 001994 if( objc<2 ){ 001995 Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ..."); 001996 return TCL_ERROR; 001997 } 001998 if( Tcl_GetIndexFromObj(interp, objv[1], DB_strs, "option", 0, &choice) ){ 001999 return TCL_ERROR; 002000 } 002001 002002 switch( (enum DB_enum)choice ){ 002003 002004 /* $db authorizer ?CALLBACK? 002005 ** 002006 ** Invoke the given callback to authorize each SQL operation as it is 002007 ** compiled. 5 arguments are appended to the callback before it is 002008 ** invoked: 002009 ** 002010 ** (1) The authorization type (ex: SQLITE_CREATE_TABLE, SQLITE_INSERT, ...) 002011 ** (2) First descriptive name (depends on authorization type) 002012 ** (3) Second descriptive name 002013 ** (4) Name of the database (ex: "main", "temp") 002014 ** (5) Name of trigger that is doing the access 002015 ** 002016 ** The callback should return on of the following strings: SQLITE_OK, 002017 ** SQLITE_IGNORE, or SQLITE_DENY. Any other return value is an error. 002018 ** 002019 ** If this method is invoked with no arguments, the current authorization 002020 ** callback string is returned. 002021 */ 002022 case DB_AUTHORIZER: { 002023 #ifdef SQLITE_OMIT_AUTHORIZATION 002024 Tcl_AppendResult(interp, "authorization not available in this build", 002025 (char*)0); 002026 return TCL_ERROR; 002027 #else 002028 if( objc>3 ){ 002029 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); 002030 return TCL_ERROR; 002031 }else if( objc==2 ){ 002032 if( pDb->zAuth ){ 002033 Tcl_AppendResult(interp, pDb->zAuth, (char*)0); 002034 } 002035 }else{ 002036 char *zAuth; 002037 int len; 002038 if( pDb->zAuth ){ 002039 Tcl_Free(pDb->zAuth); 002040 } 002041 zAuth = Tcl_GetStringFromObj(objv[2], &len); 002042 if( zAuth && len>0 ){ 002043 pDb->zAuth = Tcl_Alloc( len + 1 ); 002044 memcpy(pDb->zAuth, zAuth, len+1); 002045 }else{ 002046 pDb->zAuth = 0; 002047 } 002048 if( pDb->zAuth ){ 002049 typedef int (*sqlite3_auth_cb)( 002050 void*,int,const char*,const char*, 002051 const char*,const char*); 002052 pDb->interp = interp; 002053 sqlite3_set_authorizer(pDb->db,(sqlite3_auth_cb)auth_callback,pDb); 002054 }else{ 002055 sqlite3_set_authorizer(pDb->db, 0, 0); 002056 } 002057 } 002058 #endif 002059 break; 002060 } 002061 002062 /* $db backup ?DATABASE? FILENAME 002063 ** 002064 ** Open or create a database file named FILENAME. Transfer the 002065 ** content of local database DATABASE (default: "main") into the 002066 ** FILENAME database. 002067 */ 002068 case DB_BACKUP: { 002069 const char *zDestFile; 002070 const char *zSrcDb; 002071 sqlite3 *pDest; 002072 sqlite3_backup *pBackup; 002073 002074 if( objc==3 ){ 002075 zSrcDb = "main"; 002076 zDestFile = Tcl_GetString(objv[2]); 002077 }else if( objc==4 ){ 002078 zSrcDb = Tcl_GetString(objv[2]); 002079 zDestFile = Tcl_GetString(objv[3]); 002080 }else{ 002081 Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME"); 002082 return TCL_ERROR; 002083 } 002084 rc = sqlite3_open_v2(zDestFile, &pDest, 002085 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE| pDb->openFlags, 0); 002086 if( rc!=SQLITE_OK ){ 002087 Tcl_AppendResult(interp, "cannot open target database: ", 002088 sqlite3_errmsg(pDest), (char*)0); 002089 sqlite3_close(pDest); 002090 return TCL_ERROR; 002091 } 002092 pBackup = sqlite3_backup_init(pDest, "main", pDb->db, zSrcDb); 002093 if( pBackup==0 ){ 002094 Tcl_AppendResult(interp, "backup failed: ", 002095 sqlite3_errmsg(pDest), (char*)0); 002096 sqlite3_close(pDest); 002097 return TCL_ERROR; 002098 } 002099 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){} 002100 sqlite3_backup_finish(pBackup); 002101 if( rc==SQLITE_DONE ){ 002102 rc = TCL_OK; 002103 }else{ 002104 Tcl_AppendResult(interp, "backup failed: ", 002105 sqlite3_errmsg(pDest), (char*)0); 002106 rc = TCL_ERROR; 002107 } 002108 sqlite3_close(pDest); 002109 break; 002110 } 002111 002112 /* $db bind_fallback ?CALLBACK? 002113 ** 002114 ** When resolving bind parameters in an SQL statement, if the parameter 002115 ** cannot be associated with a TCL variable then invoke CALLBACK with a 002116 ** single argument that is the name of the parameter and use the return 002117 ** value of the CALLBACK as the binding. If CALLBACK returns something 002118 ** other than TCL_OK or TCL_ERROR then bind a NULL. 002119 ** 002120 ** If CALLBACK is an empty string, then revert to the default behavior 002121 ** which is to set the binding to NULL. 002122 ** 002123 ** If CALLBACK returns an error, that causes the statement execution to 002124 ** abort. Hence, to configure a connection so that it throws an error 002125 ** on an attempt to bind an unknown variable, do something like this: 002126 ** 002127 ** proc bind_error {name} {error "no such variable: $name"} 002128 ** db bind_fallback bind_error 002129 */ 002130 case DB_BIND_FALLBACK: { 002131 if( objc>3 ){ 002132 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); 002133 return TCL_ERROR; 002134 }else if( objc==2 ){ 002135 if( pDb->zBindFallback ){ 002136 Tcl_AppendResult(interp, pDb->zBindFallback, (char*)0); 002137 } 002138 }else{ 002139 char *zCallback; 002140 int len; 002141 if( pDb->zBindFallback ){ 002142 Tcl_Free(pDb->zBindFallback); 002143 } 002144 zCallback = Tcl_GetStringFromObj(objv[2], &len); 002145 if( zCallback && len>0 ){ 002146 pDb->zBindFallback = Tcl_Alloc( len + 1 ); 002147 memcpy(pDb->zBindFallback, zCallback, len+1); 002148 }else{ 002149 pDb->zBindFallback = 0; 002150 } 002151 } 002152 break; 002153 } 002154 002155 /* $db busy ?CALLBACK? 002156 ** 002157 ** Invoke the given callback if an SQL statement attempts to open 002158 ** a locked database file. 002159 */ 002160 case DB_BUSY: { 002161 if( objc>3 ){ 002162 Tcl_WrongNumArgs(interp, 2, objv, "CALLBACK"); 002163 return TCL_ERROR; 002164 }else if( objc==2 ){ 002165 if( pDb->zBusy ){ 002166 Tcl_AppendResult(interp, pDb->zBusy, (char*)0); 002167 } 002168 }else{ 002169 char *zBusy; 002170 int len; 002171 if( pDb->zBusy ){ 002172 Tcl_Free(pDb->zBusy); 002173 } 002174 zBusy = Tcl_GetStringFromObj(objv[2], &len); 002175 if( zBusy && len>0 ){ 002176 pDb->zBusy = Tcl_Alloc( len + 1 ); 002177 memcpy(pDb->zBusy, zBusy, len+1); 002178 }else{ 002179 pDb->zBusy = 0; 002180 } 002181 if( pDb->zBusy ){ 002182 pDb->interp = interp; 002183 sqlite3_busy_handler(pDb->db, DbBusyHandler, pDb); 002184 }else{ 002185 sqlite3_busy_handler(pDb->db, 0, 0); 002186 } 002187 } 002188 break; 002189 } 002190 002191 /* $db cache flush 002192 ** $db cache size n 002193 ** 002194 ** Flush the prepared statement cache, or set the maximum number of 002195 ** cached statements. 002196 */ 002197 case DB_CACHE: { 002198 char *subCmd; 002199 int n; 002200 002201 if( objc<=2 ){ 002202 Tcl_WrongNumArgs(interp, 1, objv, "cache option ?arg?"); 002203 return TCL_ERROR; 002204 } 002205 subCmd = Tcl_GetStringFromObj( objv[2], 0 ); 002206 if( *subCmd=='f' && strcmp(subCmd,"flush")==0 ){ 002207 if( objc!=3 ){ 002208 Tcl_WrongNumArgs(interp, 2, objv, "flush"); 002209 return TCL_ERROR; 002210 }else{ 002211 flushStmtCache( pDb ); 002212 } 002213 }else if( *subCmd=='s' && strcmp(subCmd,"size")==0 ){ 002214 if( objc!=4 ){ 002215 Tcl_WrongNumArgs(interp, 2, objv, "size n"); 002216 return TCL_ERROR; 002217 }else{ 002218 if( TCL_ERROR==Tcl_GetIntFromObj(interp, objv[3], &n) ){ 002219 Tcl_AppendResult( interp, "cannot convert \"", 002220 Tcl_GetStringFromObj(objv[3],0), "\" to integer", (char*)0); 002221 return TCL_ERROR; 002222 }else{ 002223 if( n<0 ){ 002224 flushStmtCache( pDb ); 002225 n = 0; 002226 }else if( n>MAX_PREPARED_STMTS ){ 002227 n = MAX_PREPARED_STMTS; 002228 } 002229 pDb->maxStmt = n; 002230 } 002231 } 002232 }else{ 002233 Tcl_AppendResult( interp, "bad option \"", 002234 Tcl_GetStringFromObj(objv[2],0), "\": must be flush or size", 002235 (char*)0); 002236 return TCL_ERROR; 002237 } 002238 break; 002239 } 002240 002241 /* $db changes 002242 ** 002243 ** Return the number of rows that were modified, inserted, or deleted by 002244 ** the most recent INSERT, UPDATE or DELETE statement, not including 002245 ** any changes made by trigger programs. 002246 */ 002247 case DB_CHANGES: { 002248 Tcl_Obj *pResult; 002249 if( objc!=2 ){ 002250 Tcl_WrongNumArgs(interp, 2, objv, ""); 002251 return TCL_ERROR; 002252 } 002253 pResult = Tcl_GetObjResult(interp); 002254 Tcl_SetWideIntObj(pResult, sqlite3_changes64(pDb->db)); 002255 break; 002256 } 002257 002258 /* $db close 002259 ** 002260 ** Shutdown the database 002261 */ 002262 case DB_CLOSE: { 002263 Tcl_DeleteCommand(interp, Tcl_GetStringFromObj(objv[0], 0)); 002264 break; 002265 } 002266 002267 /* 002268 ** $db collate NAME SCRIPT 002269 ** 002270 ** Create a new SQL collation function called NAME. Whenever 002271 ** that function is called, invoke SCRIPT to evaluate the function. 002272 */ 002273 case DB_COLLATE: { 002274 SqlCollate *pCollate; 002275 char *zName; 002276 char *zScript; 002277 int nScript; 002278 if( objc!=4 ){ 002279 Tcl_WrongNumArgs(interp, 2, objv, "NAME SCRIPT"); 002280 return TCL_ERROR; 002281 } 002282 zName = Tcl_GetStringFromObj(objv[2], 0); 002283 zScript = Tcl_GetStringFromObj(objv[3], &nScript); 002284 pCollate = (SqlCollate*)Tcl_Alloc( sizeof(*pCollate) + nScript + 1 ); 002285 if( pCollate==0 ) return TCL_ERROR; 002286 pCollate->interp = interp; 002287 pCollate->pNext = pDb->pCollate; 002288 pCollate->zScript = (char*)&pCollate[1]; 002289 pDb->pCollate = pCollate; 002290 memcpy(pCollate->zScript, zScript, nScript+1); 002291 if( sqlite3_create_collation(pDb->db, zName, SQLITE_UTF8, 002292 pCollate, tclSqlCollate) ){ 002293 Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE); 002294 return TCL_ERROR; 002295 } 002296 break; 002297 } 002298 002299 /* 002300 ** $db collation_needed SCRIPT 002301 ** 002302 ** Create a new SQL collation function called NAME. Whenever 002303 ** that function is called, invoke SCRIPT to evaluate the function. 002304 */ 002305 case DB_COLLATION_NEEDED: { 002306 if( objc!=3 ){ 002307 Tcl_WrongNumArgs(interp, 2, objv, "SCRIPT"); 002308 return TCL_ERROR; 002309 } 002310 if( pDb->pCollateNeeded ){ 002311 Tcl_DecrRefCount(pDb->pCollateNeeded); 002312 } 002313 pDb->pCollateNeeded = Tcl_DuplicateObj(objv[2]); 002314 Tcl_IncrRefCount(pDb->pCollateNeeded); 002315 sqlite3_collation_needed(pDb->db, pDb, tclCollateNeeded); 002316 break; 002317 } 002318 002319 /* $db commit_hook ?CALLBACK? 002320 ** 002321 ** Invoke the given callback just before committing every SQL transaction. 002322 ** If the callback throws an exception or returns non-zero, then the 002323 ** transaction is aborted. If CALLBACK is an empty string, the callback 002324 ** is disabled. 002325 */ 002326 case DB_COMMIT_HOOK: { 002327 if( objc>3 ){ 002328 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); 002329 return TCL_ERROR; 002330 }else if( objc==2 ){ 002331 if( pDb->zCommit ){ 002332 Tcl_AppendResult(interp, pDb->zCommit, (char*)0); 002333 } 002334 }else{ 002335 const char *zCommit; 002336 int len; 002337 if( pDb->zCommit ){ 002338 Tcl_Free(pDb->zCommit); 002339 } 002340 zCommit = Tcl_GetStringFromObj(objv[2], &len); 002341 if( zCommit && len>0 ){ 002342 pDb->zCommit = Tcl_Alloc( len + 1 ); 002343 memcpy(pDb->zCommit, zCommit, len+1); 002344 }else{ 002345 pDb->zCommit = 0; 002346 } 002347 if( pDb->zCommit ){ 002348 pDb->interp = interp; 002349 sqlite3_commit_hook(pDb->db, DbCommitHandler, pDb); 002350 }else{ 002351 sqlite3_commit_hook(pDb->db, 0, 0); 002352 } 002353 } 002354 break; 002355 } 002356 002357 /* $db complete SQL 002358 ** 002359 ** Return TRUE if SQL is a complete SQL statement. Return FALSE if 002360 ** additional lines of input are needed. This is similar to the 002361 ** built-in "info complete" command of Tcl. 002362 */ 002363 case DB_COMPLETE: { 002364 #ifndef SQLITE_OMIT_COMPLETE 002365 Tcl_Obj *pResult; 002366 int isComplete; 002367 if( objc!=3 ){ 002368 Tcl_WrongNumArgs(interp, 2, objv, "SQL"); 002369 return TCL_ERROR; 002370 } 002371 isComplete = sqlite3_complete( Tcl_GetStringFromObj(objv[2], 0) ); 002372 pResult = Tcl_GetObjResult(interp); 002373 Tcl_SetBooleanObj(pResult, isComplete); 002374 #endif 002375 break; 002376 } 002377 002378 /* $db config ?OPTION? ?BOOLEAN? 002379 ** 002380 ** Configure the database connection using the sqlite3_db_config() 002381 ** interface. 002382 */ 002383 case DB_CONFIG: { 002384 static const struct DbConfigChoices { 002385 const char *zName; 002386 int op; 002387 } aDbConfig[] = { 002388 { "defensive", SQLITE_DBCONFIG_DEFENSIVE }, 002389 { "dqs_ddl", SQLITE_DBCONFIG_DQS_DDL }, 002390 { "dqs_dml", SQLITE_DBCONFIG_DQS_DML }, 002391 { "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY }, 002392 { "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG }, 002393 { "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER }, 002394 { "enable_view", SQLITE_DBCONFIG_ENABLE_VIEW }, 002395 { "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER }, 002396 { "legacy_alter_table", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE }, 002397 { "legacy_file_format", SQLITE_DBCONFIG_LEGACY_FILE_FORMAT }, 002398 { "load_extension", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION }, 002399 { "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE }, 002400 { "reset_database", SQLITE_DBCONFIG_RESET_DATABASE }, 002401 { "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP }, 002402 { "trusted_schema", SQLITE_DBCONFIG_TRUSTED_SCHEMA }, 002403 { "writable_schema", SQLITE_DBCONFIG_WRITABLE_SCHEMA }, 002404 }; 002405 Tcl_Obj *pResult; 002406 int ii; 002407 if( objc>4 ){ 002408 Tcl_WrongNumArgs(interp, 2, objv, "?OPTION? ?BOOLEAN?"); 002409 return TCL_ERROR; 002410 } 002411 if( objc==2 ){ 002412 /* With no arguments, list all configuration options and with the 002413 ** current value */ 002414 pResult = Tcl_NewListObj(0,0); 002415 for(ii=0; ii<sizeof(aDbConfig)/sizeof(aDbConfig[0]); ii++){ 002416 int v = 0; 002417 sqlite3_db_config(pDb->db, aDbConfig[ii].op, -1, &v); 002418 Tcl_ListObjAppendElement(interp, pResult, 002419 Tcl_NewStringObj(aDbConfig[ii].zName,-1)); 002420 Tcl_ListObjAppendElement(interp, pResult, 002421 Tcl_NewIntObj(v)); 002422 } 002423 }else{ 002424 const char *zOpt = Tcl_GetString(objv[2]); 002425 int onoff = -1; 002426 int v = 0; 002427 if( zOpt[0]=='-' ) zOpt++; 002428 for(ii=0; ii<sizeof(aDbConfig)/sizeof(aDbConfig[0]); ii++){ 002429 if( strcmp(aDbConfig[ii].zName, zOpt)==0 ) break; 002430 } 002431 if( ii>=sizeof(aDbConfig)/sizeof(aDbConfig[0]) ){ 002432 Tcl_AppendResult(interp, "unknown config option: \"", zOpt, 002433 "\"", (void*)0); 002434 return TCL_ERROR; 002435 } 002436 if( objc==4 ){ 002437 if( Tcl_GetBooleanFromObj(interp, objv[3], &onoff) ){ 002438 return TCL_ERROR; 002439 } 002440 } 002441 sqlite3_db_config(pDb->db, aDbConfig[ii].op, onoff, &v); 002442 pResult = Tcl_NewIntObj(v); 002443 } 002444 Tcl_SetObjResult(interp, pResult); 002445 break; 002446 } 002447 002448 /* $db copy conflict-algorithm table filename ?SEPARATOR? ?NULLINDICATOR? 002449 ** 002450 ** Copy data into table from filename, optionally using SEPARATOR 002451 ** as column separators. If a column contains a null string, or the 002452 ** value of NULLINDICATOR, a NULL is inserted for the column. 002453 ** conflict-algorithm is one of the sqlite conflict algorithms: 002454 ** rollback, abort, fail, ignore, replace 002455 ** On success, return the number of lines processed, not necessarily same 002456 ** as 'db changes' due to conflict-algorithm selected. 002457 ** 002458 ** This code is basically an implementation/enhancement of 002459 ** the sqlite3 shell.c ".import" command. 002460 ** 002461 ** This command usage is equivalent to the sqlite2.x COPY statement, 002462 ** which imports file data into a table using the PostgreSQL COPY file format: 002463 ** $db copy $conflict_algorithm $table_name $filename \t \\N 002464 */ 002465 case DB_COPY: { 002466 char *zTable; /* Insert data into this table */ 002467 char *zFile; /* The file from which to extract data */ 002468 char *zConflict; /* The conflict algorithm to use */ 002469 sqlite3_stmt *pStmt; /* A statement */ 002470 int nCol; /* Number of columns in the table */ 002471 int nByte; /* Number of bytes in an SQL string */ 002472 int i, j; /* Loop counters */ 002473 int nSep; /* Number of bytes in zSep[] */ 002474 int nNull; /* Number of bytes in zNull[] */ 002475 char *zSql; /* An SQL statement */ 002476 char *zLine; /* A single line of input from the file */ 002477 char **azCol; /* zLine[] broken up into columns */ 002478 const char *zCommit; /* How to commit changes */ 002479 FILE *in; /* The input file */ 002480 int lineno = 0; /* Line number of input file */ 002481 char zLineNum[80]; /* Line number print buffer */ 002482 Tcl_Obj *pResult; /* interp result */ 002483 002484 const char *zSep; 002485 const char *zNull; 002486 if( objc<5 || objc>7 ){ 002487 Tcl_WrongNumArgs(interp, 2, objv, 002488 "CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?"); 002489 return TCL_ERROR; 002490 } 002491 if( objc>=6 ){ 002492 zSep = Tcl_GetStringFromObj(objv[5], 0); 002493 }else{ 002494 zSep = "\t"; 002495 } 002496 if( objc>=7 ){ 002497 zNull = Tcl_GetStringFromObj(objv[6], 0); 002498 }else{ 002499 zNull = ""; 002500 } 002501 zConflict = Tcl_GetStringFromObj(objv[2], 0); 002502 zTable = Tcl_GetStringFromObj(objv[3], 0); 002503 zFile = Tcl_GetStringFromObj(objv[4], 0); 002504 nSep = strlen30(zSep); 002505 nNull = strlen30(zNull); 002506 if( nSep==0 ){ 002507 Tcl_AppendResult(interp,"Error: non-null separator required for copy", 002508 (char*)0); 002509 return TCL_ERROR; 002510 } 002511 if(strcmp(zConflict, "rollback") != 0 && 002512 strcmp(zConflict, "abort" ) != 0 && 002513 strcmp(zConflict, "fail" ) != 0 && 002514 strcmp(zConflict, "ignore" ) != 0 && 002515 strcmp(zConflict, "replace" ) != 0 ) { 002516 Tcl_AppendResult(interp, "Error: \"", zConflict, 002517 "\", conflict-algorithm must be one of: rollback, " 002518 "abort, fail, ignore, or replace", (char*)0); 002519 return TCL_ERROR; 002520 } 002521 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable); 002522 if( zSql==0 ){ 002523 Tcl_AppendResult(interp, "Error: no such table: ", zTable, (char*)0); 002524 return TCL_ERROR; 002525 } 002526 nByte = strlen30(zSql); 002527 rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0); 002528 sqlite3_free(zSql); 002529 if( rc ){ 002530 Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), (char*)0); 002531 nCol = 0; 002532 }else{ 002533 nCol = sqlite3_column_count(pStmt); 002534 } 002535 sqlite3_finalize(pStmt); 002536 if( nCol==0 ) { 002537 return TCL_ERROR; 002538 } 002539 zSql = malloc( nByte + 50 + nCol*2 ); 002540 if( zSql==0 ) { 002541 Tcl_AppendResult(interp, "Error: can't malloc()", (char*)0); 002542 return TCL_ERROR; 002543 } 002544 sqlite3_snprintf(nByte+50, zSql, "INSERT OR %q INTO '%q' VALUES(?", 002545 zConflict, zTable); 002546 j = strlen30(zSql); 002547 for(i=1; i<nCol; i++){ 002548 zSql[j++] = ','; 002549 zSql[j++] = '?'; 002550 } 002551 zSql[j++] = ')'; 002552 zSql[j] = 0; 002553 rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0); 002554 free(zSql); 002555 if( rc ){ 002556 Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), (char*)0); 002557 sqlite3_finalize(pStmt); 002558 return TCL_ERROR; 002559 } 002560 in = fopen(zFile, "rb"); 002561 if( in==0 ){ 002562 Tcl_AppendResult(interp, "Error: cannot open file: ", zFile, (char*)0); 002563 sqlite3_finalize(pStmt); 002564 return TCL_ERROR; 002565 } 002566 azCol = malloc( sizeof(azCol[0])*(nCol+1) ); 002567 if( azCol==0 ) { 002568 Tcl_AppendResult(interp, "Error: can't malloc()", (char*)0); 002569 fclose(in); 002570 return TCL_ERROR; 002571 } 002572 (void)sqlite3_exec(pDb->db, "BEGIN", 0, 0, 0); 002573 zCommit = "COMMIT"; 002574 while( (zLine = local_getline(0, in))!=0 ){ 002575 char *z; 002576 lineno++; 002577 azCol[0] = zLine; 002578 for(i=0, z=zLine; *z; z++){ 002579 if( *z==zSep[0] && strncmp(z, zSep, nSep)==0 ){ 002580 *z = 0; 002581 i++; 002582 if( i<nCol ){ 002583 azCol[i] = &z[nSep]; 002584 z += nSep-1; 002585 } 002586 } 002587 } 002588 if( i+1!=nCol ){ 002589 char *zErr; 002590 int nErr = strlen30(zFile) + 200; 002591 zErr = malloc(nErr); 002592 if( zErr ){ 002593 sqlite3_snprintf(nErr, zErr, 002594 "Error: %s line %d: expected %d columns of data but found %d", 002595 zFile, lineno, nCol, i+1); 002596 Tcl_AppendResult(interp, zErr, (char*)0); 002597 free(zErr); 002598 } 002599 zCommit = "ROLLBACK"; 002600 break; 002601 } 002602 for(i=0; i<nCol; i++){ 002603 /* check for null data, if so, bind as null */ 002604 if( (nNull>0 && strcmp(azCol[i], zNull)==0) 002605 || strlen30(azCol[i])==0 002606 ){ 002607 sqlite3_bind_null(pStmt, i+1); 002608 }else{ 002609 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC); 002610 } 002611 } 002612 sqlite3_step(pStmt); 002613 rc = sqlite3_reset(pStmt); 002614 free(zLine); 002615 if( rc!=SQLITE_OK ){ 002616 Tcl_AppendResult(interp,"Error: ", sqlite3_errmsg(pDb->db), (char*)0); 002617 zCommit = "ROLLBACK"; 002618 break; 002619 } 002620 } 002621 free(azCol); 002622 fclose(in); 002623 sqlite3_finalize(pStmt); 002624 (void)sqlite3_exec(pDb->db, zCommit, 0, 0, 0); 002625 002626 if( zCommit[0] == 'C' ){ 002627 /* success, set result as number of lines processed */ 002628 pResult = Tcl_GetObjResult(interp); 002629 Tcl_SetIntObj(pResult, lineno); 002630 rc = TCL_OK; 002631 }else{ 002632 /* failure, append lineno where failed */ 002633 sqlite3_snprintf(sizeof(zLineNum), zLineNum,"%d",lineno); 002634 Tcl_AppendResult(interp,", failed while processing line: ",zLineNum, 002635 (char*)0); 002636 rc = TCL_ERROR; 002637 } 002638 break; 002639 } 002640 002641 /* 002642 ** $db deserialize ?-maxsize N? ?-readonly BOOL? ?DATABASE? VALUE 002643 ** 002644 ** Reopen DATABASE (default "main") using the content in $VALUE 002645 */ 002646 case DB_DESERIALIZE: { 002647 #ifdef SQLITE_OMIT_DESERIALIZE 002648 Tcl_AppendResult(interp, "MEMDB not available in this build", 002649 (char*)0); 002650 rc = TCL_ERROR; 002651 #else 002652 const char *zSchema = 0; 002653 Tcl_Obj *pValue = 0; 002654 unsigned char *pBA; 002655 unsigned char *pData; 002656 int len, xrc; 002657 sqlite3_int64 mxSize = 0; 002658 int i; 002659 int isReadonly = 0; 002660 002661 002662 if( objc<3 ){ 002663 Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? VALUE"); 002664 rc = TCL_ERROR; 002665 break; 002666 } 002667 for(i=2; i<objc-1; i++){ 002668 const char *z = Tcl_GetString(objv[i]); 002669 if( strcmp(z,"-maxsize")==0 && i<objc-2 ){ 002670 Tcl_WideInt x; 002671 rc = Tcl_GetWideIntFromObj(interp, objv[++i], &x); 002672 if( rc ) goto deserialize_error; 002673 mxSize = x; 002674 continue; 002675 } 002676 if( strcmp(z,"-readonly")==0 && i<objc-2 ){ 002677 rc = Tcl_GetBooleanFromObj(interp, objv[++i], &isReadonly); 002678 if( rc ) goto deserialize_error; 002679 continue; 002680 } 002681 if( zSchema==0 && i==objc-2 && z[0]!='-' ){ 002682 zSchema = z; 002683 continue; 002684 } 002685 Tcl_AppendResult(interp, "unknown option: ", z, (char*)0); 002686 rc = TCL_ERROR; 002687 goto deserialize_error; 002688 } 002689 pValue = objv[objc-1]; 002690 pBA = Tcl_GetByteArrayFromObj(pValue, &len); 002691 pData = sqlite3_malloc64( len ); 002692 if( pData==0 && len>0 ){ 002693 Tcl_AppendResult(interp, "out of memory", (char*)0); 002694 rc = TCL_ERROR; 002695 }else{ 002696 int flags; 002697 if( len>0 ) memcpy(pData, pBA, len); 002698 if( isReadonly ){ 002699 flags = SQLITE_DESERIALIZE_FREEONCLOSE | SQLITE_DESERIALIZE_READONLY; 002700 }else{ 002701 flags = SQLITE_DESERIALIZE_FREEONCLOSE | SQLITE_DESERIALIZE_RESIZEABLE; 002702 } 002703 xrc = sqlite3_deserialize(pDb->db, zSchema, pData, len, len, flags); 002704 if( xrc ){ 002705 Tcl_AppendResult(interp, "unable to set MEMDB content", (char*)0); 002706 rc = TCL_ERROR; 002707 } 002708 if( mxSize>0 ){ 002709 sqlite3_file_control(pDb->db, zSchema,SQLITE_FCNTL_SIZE_LIMIT,&mxSize); 002710 } 002711 } 002712 deserialize_error: 002713 #endif 002714 break; 002715 } 002716 002717 /* 002718 ** $db enable_load_extension BOOLEAN 002719 ** 002720 ** Turn the extension loading feature on or off. It if off by 002721 ** default. 002722 */ 002723 case DB_ENABLE_LOAD_EXTENSION: { 002724 #ifndef SQLITE_OMIT_LOAD_EXTENSION 002725 int onoff; 002726 if( objc!=3 ){ 002727 Tcl_WrongNumArgs(interp, 2, objv, "BOOLEAN"); 002728 return TCL_ERROR; 002729 } 002730 if( Tcl_GetBooleanFromObj(interp, objv[2], &onoff) ){ 002731 return TCL_ERROR; 002732 } 002733 sqlite3_enable_load_extension(pDb->db, onoff); 002734 break; 002735 #else 002736 Tcl_AppendResult(interp, "extension loading is turned off at compile-time", 002737 (char*)0); 002738 return TCL_ERROR; 002739 #endif 002740 } 002741 002742 /* 002743 ** $db errorcode 002744 ** 002745 ** Return the numeric error code that was returned by the most recent 002746 ** call to sqlite3_exec(). 002747 */ 002748 case DB_ERRORCODE: { 002749 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_errcode(pDb->db))); 002750 break; 002751 } 002752 002753 /* 002754 ** $db erroroffset 002755 ** 002756 ** Return the numeric error code that was returned by the most recent 002757 ** call to sqlite3_exec(). 002758 */ 002759 case DB_ERROROFFSET: { 002760 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_error_offset(pDb->db))); 002761 break; 002762 } 002763 002764 /* 002765 ** $db exists $sql 002766 ** $db onecolumn $sql 002767 ** 002768 ** The onecolumn method is the equivalent of: 002769 ** lindex [$db eval $sql] 0 002770 */ 002771 case DB_EXISTS: 002772 case DB_ONECOLUMN: { 002773 Tcl_Obj *pResult = 0; 002774 DbEvalContext sEval; 002775 if( objc!=3 ){ 002776 Tcl_WrongNumArgs(interp, 2, objv, "SQL"); 002777 return TCL_ERROR; 002778 } 002779 002780 dbEvalInit(&sEval, pDb, objv[2], 0, 0); 002781 rc = dbEvalStep(&sEval); 002782 if( choice==DB_ONECOLUMN ){ 002783 if( rc==TCL_OK ){ 002784 pResult = dbEvalColumnValue(&sEval, 0); 002785 }else if( rc==TCL_BREAK ){ 002786 Tcl_ResetResult(interp); 002787 } 002788 }else if( rc==TCL_BREAK || rc==TCL_OK ){ 002789 pResult = Tcl_NewBooleanObj(rc==TCL_OK); 002790 } 002791 dbEvalFinalize(&sEval); 002792 if( pResult ) Tcl_SetObjResult(interp, pResult); 002793 002794 if( rc==TCL_BREAK ){ 002795 rc = TCL_OK; 002796 } 002797 break; 002798 } 002799 002800 /* 002801 ** $db eval ?options? $sql ?array? ?{ ...code... }? 002802 ** 002803 ** The SQL statement in $sql is evaluated. For each row, the values are 002804 ** placed in elements of the array named "array" and ...code... is executed. 002805 ** If "array" and "code" are omitted, then no callback is every invoked. 002806 ** If "array" is an empty string, then the values are placed in variables 002807 ** that have the same name as the fields extracted by the query. 002808 */ 002809 case DB_EVAL: { 002810 int evalFlags = 0; 002811 const char *zOpt; 002812 while( objc>3 && (zOpt = Tcl_GetString(objv[2]))!=0 && zOpt[0]=='-' ){ 002813 if( strcmp(zOpt, "-withoutnulls")==0 ){ 002814 evalFlags |= SQLITE_EVAL_WITHOUTNULLS; 002815 } 002816 else{ 002817 Tcl_AppendResult(interp, "unknown option: \"", zOpt, "\"", (void*)0); 002818 return TCL_ERROR; 002819 } 002820 objc--; 002821 objv++; 002822 } 002823 if( objc<3 || objc>5 ){ 002824 Tcl_WrongNumArgs(interp, 2, objv, 002825 "?OPTIONS? SQL ?ARRAY-NAME? ?SCRIPT?"); 002826 return TCL_ERROR; 002827 } 002828 002829 if( objc==3 ){ 002830 DbEvalContext sEval; 002831 Tcl_Obj *pRet = Tcl_NewObj(); 002832 Tcl_IncrRefCount(pRet); 002833 dbEvalInit(&sEval, pDb, objv[2], 0, 0); 002834 while( TCL_OK==(rc = dbEvalStep(&sEval)) ){ 002835 int i; 002836 int nCol; 002837 dbEvalRowInfo(&sEval, &nCol, 0); 002838 for(i=0; i<nCol; i++){ 002839 Tcl_ListObjAppendElement(interp, pRet, dbEvalColumnValue(&sEval, i)); 002840 } 002841 } 002842 dbEvalFinalize(&sEval); 002843 if( rc==TCL_BREAK ){ 002844 Tcl_SetObjResult(interp, pRet); 002845 rc = TCL_OK; 002846 } 002847 Tcl_DecrRefCount(pRet); 002848 }else{ 002849 ClientData cd2[2]; 002850 DbEvalContext *p; 002851 Tcl_Obj *pArray = 0; 002852 Tcl_Obj *pScript; 002853 002854 if( objc>=5 && *(char *)Tcl_GetString(objv[3]) ){ 002855 pArray = objv[3]; 002856 } 002857 pScript = objv[objc-1]; 002858 Tcl_IncrRefCount(pScript); 002859 002860 p = (DbEvalContext *)Tcl_Alloc(sizeof(DbEvalContext)); 002861 dbEvalInit(p, pDb, objv[2], pArray, evalFlags); 002862 002863 cd2[0] = (void *)p; 002864 cd2[1] = (void *)pScript; 002865 rc = DbEvalNextCmd(cd2, interp, TCL_OK); 002866 } 002867 break; 002868 } 002869 002870 /* 002871 ** $db function NAME [OPTIONS] SCRIPT 002872 ** 002873 ** Create a new SQL function called NAME. Whenever that function is 002874 ** called, invoke SCRIPT to evaluate the function. 002875 ** 002876 ** Options: 002877 ** --argcount N Function has exactly N arguments 002878 ** --deterministic The function is pure 002879 ** --directonly Prohibit use inside triggers and views 002880 ** --innocuous Has no side effects or information leaks 002881 ** --returntype TYPE Specify the return type of the function 002882 */ 002883 case DB_FUNCTION: { 002884 int flags = SQLITE_UTF8; 002885 SqlFunc *pFunc; 002886 Tcl_Obj *pScript; 002887 char *zName; 002888 int nArg = -1; 002889 int i; 002890 int eType = SQLITE_NULL; 002891 if( objc<4 ){ 002892 Tcl_WrongNumArgs(interp, 2, objv, "NAME ?SWITCHES? SCRIPT"); 002893 return TCL_ERROR; 002894 } 002895 for(i=3; i<(objc-1); i++){ 002896 const char *z = Tcl_GetString(objv[i]); 002897 int n = strlen30(z); 002898 if( n>1 && strncmp(z, "-argcount",n)==0 ){ 002899 if( i==(objc-2) ){ 002900 Tcl_AppendResult(interp, "option requires an argument: ", z,(char*)0); 002901 return TCL_ERROR; 002902 } 002903 if( Tcl_GetIntFromObj(interp, objv[i+1], &nArg) ) return TCL_ERROR; 002904 if( nArg<0 ){ 002905 Tcl_AppendResult(interp, "number of arguments must be non-negative", 002906 (char*)0); 002907 return TCL_ERROR; 002908 } 002909 i++; 002910 }else 002911 if( n>1 && strncmp(z, "-deterministic",n)==0 ){ 002912 flags |= SQLITE_DETERMINISTIC; 002913 }else 002914 if( n>1 && strncmp(z, "-directonly",n)==0 ){ 002915 flags |= SQLITE_DIRECTONLY; 002916 }else 002917 if( n>1 && strncmp(z, "-innocuous",n)==0 ){ 002918 flags |= SQLITE_INNOCUOUS; 002919 }else 002920 if( n>1 && strncmp(z, "-returntype", n)==0 ){ 002921 const char *azType[] = {"integer", "real", "text", "blob", "any", 0}; 002922 assert( SQLITE_INTEGER==1 && SQLITE_FLOAT==2 && SQLITE_TEXT==3 ); 002923 assert( SQLITE_BLOB==4 && SQLITE_NULL==5 ); 002924 if( i==(objc-2) ){ 002925 Tcl_AppendResult(interp, "option requires an argument: ", z,(char*)0); 002926 return TCL_ERROR; 002927 } 002928 i++; 002929 if( Tcl_GetIndexFromObj(interp, objv[i], azType, "type", 0, &eType) ){ 002930 return TCL_ERROR; 002931 } 002932 eType++; 002933 }else{ 002934 Tcl_AppendResult(interp, "bad option \"", z, 002935 "\": must be -argcount, -deterministic, -directonly," 002936 " -innocuous, or -returntype", (char*)0 002937 ); 002938 return TCL_ERROR; 002939 } 002940 } 002941 002942 pScript = objv[objc-1]; 002943 zName = Tcl_GetStringFromObj(objv[2], 0); 002944 pFunc = findSqlFunc(pDb, zName); 002945 if( pFunc==0 ) return TCL_ERROR; 002946 if( pFunc->pScript ){ 002947 Tcl_DecrRefCount(pFunc->pScript); 002948 } 002949 pFunc->pScript = pScript; 002950 Tcl_IncrRefCount(pScript); 002951 pFunc->useEvalObjv = safeToUseEvalObjv(interp, pScript); 002952 pFunc->eType = eType; 002953 rc = sqlite3_create_function(pDb->db, zName, nArg, flags, 002954 pFunc, tclSqlFunc, 0, 0); 002955 if( rc!=SQLITE_OK ){ 002956 rc = TCL_ERROR; 002957 Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE); 002958 } 002959 break; 002960 } 002961 002962 /* 002963 ** $db incrblob ?-readonly? ?DB? TABLE COLUMN ROWID 002964 */ 002965 case DB_INCRBLOB: { 002966 #ifdef SQLITE_OMIT_INCRBLOB 002967 Tcl_AppendResult(interp, "incrblob not available in this build", (char*)0); 002968 return TCL_ERROR; 002969 #else 002970 int isReadonly = 0; 002971 const char *zDb = "main"; 002972 const char *zTable; 002973 const char *zColumn; 002974 Tcl_WideInt iRow; 002975 002976 /* Check for the -readonly option */ 002977 if( objc>3 && strcmp(Tcl_GetString(objv[2]), "-readonly")==0 ){ 002978 isReadonly = 1; 002979 } 002980 002981 if( objc!=(5+isReadonly) && objc!=(6+isReadonly) ){ 002982 Tcl_WrongNumArgs(interp, 2, objv, "?-readonly? ?DB? TABLE COLUMN ROWID"); 002983 return TCL_ERROR; 002984 } 002985 002986 if( objc==(6+isReadonly) ){ 002987 zDb = Tcl_GetString(objv[2+isReadonly]); 002988 } 002989 zTable = Tcl_GetString(objv[objc-3]); 002990 zColumn = Tcl_GetString(objv[objc-2]); 002991 rc = Tcl_GetWideIntFromObj(interp, objv[objc-1], &iRow); 002992 002993 if( rc==TCL_OK ){ 002994 rc = createIncrblobChannel( 002995 interp, pDb, zDb, zTable, zColumn, (sqlite3_int64)iRow, isReadonly 002996 ); 002997 } 002998 #endif 002999 break; 003000 } 003001 003002 /* 003003 ** $db interrupt 003004 ** 003005 ** Interrupt the execution of the inner-most SQL interpreter. This 003006 ** causes the SQL statement to return an error of SQLITE_INTERRUPT. 003007 */ 003008 case DB_INTERRUPT: { 003009 sqlite3_interrupt(pDb->db); 003010 break; 003011 } 003012 003013 /* 003014 ** $db nullvalue ?STRING? 003015 ** 003016 ** Change text used when a NULL comes back from the database. If ?STRING? 003017 ** is not present, then the current string used for NULL is returned. 003018 ** If STRING is present, then STRING is returned. 003019 ** 003020 */ 003021 case DB_NULLVALUE: { 003022 if( objc!=2 && objc!=3 ){ 003023 Tcl_WrongNumArgs(interp, 2, objv, "NULLVALUE"); 003024 return TCL_ERROR; 003025 } 003026 if( objc==3 ){ 003027 int len; 003028 char *zNull = Tcl_GetStringFromObj(objv[2], &len); 003029 if( pDb->zNull ){ 003030 Tcl_Free(pDb->zNull); 003031 } 003032 if( zNull && len>0 ){ 003033 pDb->zNull = Tcl_Alloc( len + 1 ); 003034 memcpy(pDb->zNull, zNull, len); 003035 pDb->zNull[len] = '\0'; 003036 }else{ 003037 pDb->zNull = 0; 003038 } 003039 } 003040 Tcl_SetObjResult(interp, Tcl_NewStringObj(pDb->zNull, -1)); 003041 break; 003042 } 003043 003044 /* 003045 ** $db last_insert_rowid 003046 ** 003047 ** Return an integer which is the ROWID for the most recent insert. 003048 */ 003049 case DB_LAST_INSERT_ROWID: { 003050 Tcl_Obj *pResult; 003051 Tcl_WideInt rowid; 003052 if( objc!=2 ){ 003053 Tcl_WrongNumArgs(interp, 2, objv, ""); 003054 return TCL_ERROR; 003055 } 003056 rowid = sqlite3_last_insert_rowid(pDb->db); 003057 pResult = Tcl_GetObjResult(interp); 003058 Tcl_SetWideIntObj(pResult, rowid); 003059 break; 003060 } 003061 003062 /* 003063 ** The DB_ONECOLUMN method is implemented together with DB_EXISTS. 003064 */ 003065 003066 /* $db progress ?N CALLBACK? 003067 ** 003068 ** Invoke the given callback every N virtual machine opcodes while executing 003069 ** queries. 003070 */ 003071 case DB_PROGRESS: { 003072 if( objc==2 ){ 003073 if( pDb->zProgress ){ 003074 Tcl_AppendResult(interp, pDb->zProgress, (char*)0); 003075 } 003076 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK 003077 sqlite3_progress_handler(pDb->db, 0, 0, 0); 003078 #endif 003079 }else if( objc==4 ){ 003080 char *zProgress; 003081 int len; 003082 int N; 003083 if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &N) ){ 003084 return TCL_ERROR; 003085 }; 003086 if( pDb->zProgress ){ 003087 Tcl_Free(pDb->zProgress); 003088 } 003089 zProgress = Tcl_GetStringFromObj(objv[3], &len); 003090 if( zProgress && len>0 ){ 003091 pDb->zProgress = Tcl_Alloc( len + 1 ); 003092 memcpy(pDb->zProgress, zProgress, len+1); 003093 }else{ 003094 pDb->zProgress = 0; 003095 } 003096 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK 003097 if( pDb->zProgress ){ 003098 pDb->interp = interp; 003099 sqlite3_progress_handler(pDb->db, N, DbProgressHandler, pDb); 003100 }else{ 003101 sqlite3_progress_handler(pDb->db, 0, 0, 0); 003102 } 003103 #endif 003104 }else{ 003105 Tcl_WrongNumArgs(interp, 2, objv, "N CALLBACK"); 003106 return TCL_ERROR; 003107 } 003108 break; 003109 } 003110 003111 /* $db profile ?CALLBACK? 003112 ** 003113 ** Make arrangements to invoke the CALLBACK routine after each SQL statement 003114 ** that has run. The text of the SQL and the amount of elapse time are 003115 ** appended to CALLBACK before the script is run. 003116 */ 003117 case DB_PROFILE: { 003118 if( objc>3 ){ 003119 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); 003120 return TCL_ERROR; 003121 }else if( objc==2 ){ 003122 if( pDb->zProfile ){ 003123 Tcl_AppendResult(interp, pDb->zProfile, (char*)0); 003124 } 003125 }else{ 003126 char *zProfile; 003127 int len; 003128 if( pDb->zProfile ){ 003129 Tcl_Free(pDb->zProfile); 003130 } 003131 zProfile = Tcl_GetStringFromObj(objv[2], &len); 003132 if( zProfile && len>0 ){ 003133 pDb->zProfile = Tcl_Alloc( len + 1 ); 003134 memcpy(pDb->zProfile, zProfile, len+1); 003135 }else{ 003136 pDb->zProfile = 0; 003137 } 003138 #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \ 003139 !defined(SQLITE_OMIT_DEPRECATED) 003140 if( pDb->zProfile ){ 003141 pDb->interp = interp; 003142 sqlite3_profile(pDb->db, DbProfileHandler, pDb); 003143 }else{ 003144 sqlite3_profile(pDb->db, 0, 0); 003145 } 003146 #endif 003147 } 003148 break; 003149 } 003150 003151 /* 003152 ** $db rekey KEY 003153 ** 003154 ** Change the encryption key on the currently open database. 003155 */ 003156 case DB_REKEY: { 003157 if( objc!=3 ){ 003158 Tcl_WrongNumArgs(interp, 2, objv, "KEY"); 003159 return TCL_ERROR; 003160 } 003161 break; 003162 } 003163 003164 /* $db restore ?DATABASE? FILENAME 003165 ** 003166 ** Open a database file named FILENAME. Transfer the content 003167 ** of FILENAME into the local database DATABASE (default: "main"). 003168 */ 003169 case DB_RESTORE: { 003170 const char *zSrcFile; 003171 const char *zDestDb; 003172 sqlite3 *pSrc; 003173 sqlite3_backup *pBackup; 003174 int nTimeout = 0; 003175 003176 if( objc==3 ){ 003177 zDestDb = "main"; 003178 zSrcFile = Tcl_GetString(objv[2]); 003179 }else if( objc==4 ){ 003180 zDestDb = Tcl_GetString(objv[2]); 003181 zSrcFile = Tcl_GetString(objv[3]); 003182 }else{ 003183 Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME"); 003184 return TCL_ERROR; 003185 } 003186 rc = sqlite3_open_v2(zSrcFile, &pSrc, 003187 SQLITE_OPEN_READONLY | pDb->openFlags, 0); 003188 if( rc!=SQLITE_OK ){ 003189 Tcl_AppendResult(interp, "cannot open source database: ", 003190 sqlite3_errmsg(pSrc), (char*)0); 003191 sqlite3_close(pSrc); 003192 return TCL_ERROR; 003193 } 003194 pBackup = sqlite3_backup_init(pDb->db, zDestDb, pSrc, "main"); 003195 if( pBackup==0 ){ 003196 Tcl_AppendResult(interp, "restore failed: ", 003197 sqlite3_errmsg(pDb->db), (char*)0); 003198 sqlite3_close(pSrc); 003199 return TCL_ERROR; 003200 } 003201 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK 003202 || rc==SQLITE_BUSY ){ 003203 if( rc==SQLITE_BUSY ){ 003204 if( nTimeout++ >= 3 ) break; 003205 sqlite3_sleep(100); 003206 } 003207 } 003208 sqlite3_backup_finish(pBackup); 003209 if( rc==SQLITE_DONE ){ 003210 rc = TCL_OK; 003211 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){ 003212 Tcl_AppendResult(interp, "restore failed: source database busy", 003213 (char*)0); 003214 rc = TCL_ERROR; 003215 }else{ 003216 Tcl_AppendResult(interp, "restore failed: ", 003217 sqlite3_errmsg(pDb->db), (char*)0); 003218 rc = TCL_ERROR; 003219 } 003220 sqlite3_close(pSrc); 003221 break; 003222 } 003223 003224 /* 003225 ** $db serialize ?DATABASE? 003226 ** 003227 ** Return a serialization of a database. 003228 */ 003229 case DB_SERIALIZE: { 003230 #ifdef SQLITE_OMIT_DESERIALIZE 003231 Tcl_AppendResult(interp, "MEMDB not available in this build", 003232 (char*)0); 003233 rc = TCL_ERROR; 003234 #else 003235 const char *zSchema = objc>=3 ? Tcl_GetString(objv[2]) : "main"; 003236 sqlite3_int64 sz = 0; 003237 unsigned char *pData; 003238 if( objc!=2 && objc!=3 ){ 003239 Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE?"); 003240 rc = TCL_ERROR; 003241 }else{ 003242 int needFree; 003243 pData = sqlite3_serialize(pDb->db, zSchema, &sz, SQLITE_SERIALIZE_NOCOPY); 003244 if( pData ){ 003245 needFree = 0; 003246 }else{ 003247 pData = sqlite3_serialize(pDb->db, zSchema, &sz, 0); 003248 needFree = 1; 003249 } 003250 Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pData,sz)); 003251 if( needFree ) sqlite3_free(pData); 003252 } 003253 #endif 003254 break; 003255 } 003256 003257 /* 003258 ** $db status (step|sort|autoindex|vmstep) 003259 ** 003260 ** Display SQLITE_STMTSTATUS_FULLSCAN_STEP or 003261 ** SQLITE_STMTSTATUS_SORT for the most recent eval. 003262 */ 003263 case DB_STATUS: { 003264 int v; 003265 const char *zOp; 003266 if( objc!=3 ){ 003267 Tcl_WrongNumArgs(interp, 2, objv, "(step|sort|autoindex)"); 003268 return TCL_ERROR; 003269 } 003270 zOp = Tcl_GetString(objv[2]); 003271 if( strcmp(zOp, "step")==0 ){ 003272 v = pDb->nStep; 003273 }else if( strcmp(zOp, "sort")==0 ){ 003274 v = pDb->nSort; 003275 }else if( strcmp(zOp, "autoindex")==0 ){ 003276 v = pDb->nIndex; 003277 }else if( strcmp(zOp, "vmstep")==0 ){ 003278 v = pDb->nVMStep; 003279 }else{ 003280 Tcl_AppendResult(interp, 003281 "bad argument: should be autoindex, step, sort or vmstep", 003282 (char*)0); 003283 return TCL_ERROR; 003284 } 003285 Tcl_SetObjResult(interp, Tcl_NewIntObj(v)); 003286 break; 003287 } 003288 003289 /* 003290 ** $db timeout MILLESECONDS 003291 ** 003292 ** Delay for the number of milliseconds specified when a file is locked. 003293 */ 003294 case DB_TIMEOUT: { 003295 int ms; 003296 if( objc!=3 ){ 003297 Tcl_WrongNumArgs(interp, 2, objv, "MILLISECONDS"); 003298 return TCL_ERROR; 003299 } 003300 if( Tcl_GetIntFromObj(interp, objv[2], &ms) ) return TCL_ERROR; 003301 sqlite3_busy_timeout(pDb->db, ms); 003302 break; 003303 } 003304 003305 /* 003306 ** $db total_changes 003307 ** 003308 ** Return the number of rows that were modified, inserted, or deleted 003309 ** since the database handle was created. 003310 */ 003311 case DB_TOTAL_CHANGES: { 003312 Tcl_Obj *pResult; 003313 if( objc!=2 ){ 003314 Tcl_WrongNumArgs(interp, 2, objv, ""); 003315 return TCL_ERROR; 003316 } 003317 pResult = Tcl_GetObjResult(interp); 003318 Tcl_SetWideIntObj(pResult, sqlite3_total_changes64(pDb->db)); 003319 break; 003320 } 003321 003322 /* $db trace ?CALLBACK? 003323 ** 003324 ** Make arrangements to invoke the CALLBACK routine for each SQL statement 003325 ** that is executed. The text of the SQL is appended to CALLBACK before 003326 ** it is executed. 003327 */ 003328 case DB_TRACE: { 003329 if( objc>3 ){ 003330 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); 003331 return TCL_ERROR; 003332 }else if( objc==2 ){ 003333 if( pDb->zTrace ){ 003334 Tcl_AppendResult(interp, pDb->zTrace, (char*)0); 003335 } 003336 }else{ 003337 char *zTrace; 003338 int len; 003339 if( pDb->zTrace ){ 003340 Tcl_Free(pDb->zTrace); 003341 } 003342 zTrace = Tcl_GetStringFromObj(objv[2], &len); 003343 if( zTrace && len>0 ){ 003344 pDb->zTrace = Tcl_Alloc( len + 1 ); 003345 memcpy(pDb->zTrace, zTrace, len+1); 003346 }else{ 003347 pDb->zTrace = 0; 003348 } 003349 #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \ 003350 !defined(SQLITE_OMIT_DEPRECATED) 003351 if( pDb->zTrace ){ 003352 pDb->interp = interp; 003353 sqlite3_trace(pDb->db, DbTraceHandler, pDb); 003354 }else{ 003355 sqlite3_trace(pDb->db, 0, 0); 003356 } 003357 #endif 003358 } 003359 break; 003360 } 003361 003362 /* $db trace_v2 ?CALLBACK? ?MASK? 003363 ** 003364 ** Make arrangements to invoke the CALLBACK routine for each trace event 003365 ** matching the mask that is generated. The parameters are appended to 003366 ** CALLBACK before it is executed. 003367 */ 003368 case DB_TRACE_V2: { 003369 if( objc>4 ){ 003370 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK? ?MASK?"); 003371 return TCL_ERROR; 003372 }else if( objc==2 ){ 003373 if( pDb->zTraceV2 ){ 003374 Tcl_AppendResult(interp, pDb->zTraceV2, (char*)0); 003375 } 003376 }else{ 003377 char *zTraceV2; 003378 int len; 003379 Tcl_WideInt wMask = 0; 003380 if( objc==4 ){ 003381 static const char *TTYPE_strs[] = { 003382 "statement", "profile", "row", "close", 0 003383 }; 003384 enum TTYPE_enum { 003385 TTYPE_STMT, TTYPE_PROFILE, TTYPE_ROW, TTYPE_CLOSE 003386 }; 003387 int i; 003388 if( TCL_OK!=Tcl_ListObjLength(interp, objv[3], &len) ){ 003389 return TCL_ERROR; 003390 } 003391 for(i=0; i<len; i++){ 003392 Tcl_Obj *pObj; 003393 int ttype; 003394 if( TCL_OK!=Tcl_ListObjIndex(interp, objv[3], i, &pObj) ){ 003395 return TCL_ERROR; 003396 } 003397 if( Tcl_GetIndexFromObj(interp, pObj, TTYPE_strs, "trace type", 003398 0, &ttype)!=TCL_OK ){ 003399 Tcl_WideInt wType; 003400 Tcl_Obj *pError = Tcl_DuplicateObj(Tcl_GetObjResult(interp)); 003401 Tcl_IncrRefCount(pError); 003402 if( TCL_OK==Tcl_GetWideIntFromObj(interp, pObj, &wType) ){ 003403 Tcl_DecrRefCount(pError); 003404 wMask |= wType; 003405 }else{ 003406 Tcl_SetObjResult(interp, pError); 003407 Tcl_DecrRefCount(pError); 003408 return TCL_ERROR; 003409 } 003410 }else{ 003411 switch( (enum TTYPE_enum)ttype ){ 003412 case TTYPE_STMT: wMask |= SQLITE_TRACE_STMT; break; 003413 case TTYPE_PROFILE: wMask |= SQLITE_TRACE_PROFILE; break; 003414 case TTYPE_ROW: wMask |= SQLITE_TRACE_ROW; break; 003415 case TTYPE_CLOSE: wMask |= SQLITE_TRACE_CLOSE; break; 003416 } 003417 } 003418 } 003419 }else{ 003420 wMask = SQLITE_TRACE_STMT; /* use the "legacy" default */ 003421 } 003422 if( pDb->zTraceV2 ){ 003423 Tcl_Free(pDb->zTraceV2); 003424 } 003425 zTraceV2 = Tcl_GetStringFromObj(objv[2], &len); 003426 if( zTraceV2 && len>0 ){ 003427 pDb->zTraceV2 = Tcl_Alloc( len + 1 ); 003428 memcpy(pDb->zTraceV2, zTraceV2, len+1); 003429 }else{ 003430 pDb->zTraceV2 = 0; 003431 } 003432 #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) 003433 if( pDb->zTraceV2 ){ 003434 pDb->interp = interp; 003435 sqlite3_trace_v2(pDb->db, (unsigned)wMask, DbTraceV2Handler, pDb); 003436 }else{ 003437 sqlite3_trace_v2(pDb->db, 0, 0, 0); 003438 } 003439 #endif 003440 } 003441 break; 003442 } 003443 003444 /* $db transaction [-deferred|-immediate|-exclusive] SCRIPT 003445 ** 003446 ** Start a new transaction (if we are not already in the midst of a 003447 ** transaction) and execute the TCL script SCRIPT. After SCRIPT 003448 ** completes, either commit the transaction or roll it back if SCRIPT 003449 ** throws an exception. Or if no new transaction was started, do nothing. 003450 ** pass the exception on up the stack. 003451 ** 003452 ** This command was inspired by Dave Thomas's talk on Ruby at the 003453 ** 2005 O'Reilly Open Source Convention (OSCON). 003454 */ 003455 case DB_TRANSACTION: { 003456 Tcl_Obj *pScript; 003457 const char *zBegin = "SAVEPOINT _tcl_transaction"; 003458 if( objc!=3 && objc!=4 ){ 003459 Tcl_WrongNumArgs(interp, 2, objv, "[TYPE] SCRIPT"); 003460 return TCL_ERROR; 003461 } 003462 003463 if( pDb->nTransaction==0 && objc==4 ){ 003464 static const char *TTYPE_strs[] = { 003465 "deferred", "exclusive", "immediate", 0 003466 }; 003467 enum TTYPE_enum { 003468 TTYPE_DEFERRED, TTYPE_EXCLUSIVE, TTYPE_IMMEDIATE 003469 }; 003470 int ttype; 003471 if( Tcl_GetIndexFromObj(interp, objv[2], TTYPE_strs, "transaction type", 003472 0, &ttype) ){ 003473 return TCL_ERROR; 003474 } 003475 switch( (enum TTYPE_enum)ttype ){ 003476 case TTYPE_DEFERRED: /* no-op */; break; 003477 case TTYPE_EXCLUSIVE: zBegin = "BEGIN EXCLUSIVE"; break; 003478 case TTYPE_IMMEDIATE: zBegin = "BEGIN IMMEDIATE"; break; 003479 } 003480 } 003481 pScript = objv[objc-1]; 003482 003483 /* Run the SQLite BEGIN command to open a transaction or savepoint. */ 003484 pDb->disableAuth++; 003485 rc = sqlite3_exec(pDb->db, zBegin, 0, 0, 0); 003486 pDb->disableAuth--; 003487 if( rc!=SQLITE_OK ){ 003488 Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0); 003489 return TCL_ERROR; 003490 } 003491 pDb->nTransaction++; 003492 003493 /* If using NRE, schedule a callback to invoke the script pScript, then 003494 ** a second callback to commit (or rollback) the transaction or savepoint 003495 ** opened above. If not using NRE, evaluate the script directly, then 003496 ** call function DbTransPostCmd() to commit (or rollback) the transaction 003497 ** or savepoint. */ 003498 addDatabaseRef(pDb); /* DbTransPostCmd() calls delDatabaseRef() */ 003499 if( DbUseNre() ){ 003500 Tcl_NRAddCallback(interp, DbTransPostCmd, cd, 0, 0, 0); 003501 (void)Tcl_NREvalObj(interp, pScript, 0); 003502 }else{ 003503 rc = DbTransPostCmd(&cd, interp, Tcl_EvalObjEx(interp, pScript, 0)); 003504 } 003505 break; 003506 } 003507 003508 /* 003509 ** $db unlock_notify ?script? 003510 */ 003511 case DB_UNLOCK_NOTIFY: { 003512 #ifndef SQLITE_ENABLE_UNLOCK_NOTIFY 003513 Tcl_AppendResult(interp, "unlock_notify not available in this build", 003514 (char*)0); 003515 rc = TCL_ERROR; 003516 #else 003517 if( objc!=2 && objc!=3 ){ 003518 Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?"); 003519 rc = TCL_ERROR; 003520 }else{ 003521 void (*xNotify)(void **, int) = 0; 003522 void *pNotifyArg = 0; 003523 003524 if( pDb->pUnlockNotify ){ 003525 Tcl_DecrRefCount(pDb->pUnlockNotify); 003526 pDb->pUnlockNotify = 0; 003527 } 003528 003529 if( objc==3 ){ 003530 xNotify = DbUnlockNotify; 003531 pNotifyArg = (void *)pDb; 003532 pDb->pUnlockNotify = objv[2]; 003533 Tcl_IncrRefCount(pDb->pUnlockNotify); 003534 } 003535 003536 if( sqlite3_unlock_notify(pDb->db, xNotify, pNotifyArg) ){ 003537 Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0); 003538 rc = TCL_ERROR; 003539 } 003540 } 003541 #endif 003542 break; 003543 } 003544 003545 /* 003546 ** $db preupdate_hook count 003547 ** $db preupdate_hook hook ?SCRIPT? 003548 ** $db preupdate_hook new INDEX 003549 ** $db preupdate_hook old INDEX 003550 */ 003551 case DB_PREUPDATE: { 003552 #ifndef SQLITE_ENABLE_PREUPDATE_HOOK 003553 Tcl_AppendResult(interp, "preupdate_hook was omitted at compile-time", 003554 (char*)0); 003555 rc = TCL_ERROR; 003556 #else 003557 static const char *azSub[] = {"count", "depth", "hook", "new", "old", 0}; 003558 enum DbPreupdateSubCmd { 003559 PRE_COUNT, PRE_DEPTH, PRE_HOOK, PRE_NEW, PRE_OLD 003560 }; 003561 int iSub; 003562 003563 if( objc<3 ){ 003564 Tcl_WrongNumArgs(interp, 2, objv, "SUB-COMMAND ?ARGS?"); 003565 } 003566 if( Tcl_GetIndexFromObj(interp, objv[2], azSub, "sub-command", 0, &iSub) ){ 003567 return TCL_ERROR; 003568 } 003569 003570 switch( (enum DbPreupdateSubCmd)iSub ){ 003571 case PRE_COUNT: { 003572 int nCol = sqlite3_preupdate_count(pDb->db); 003573 Tcl_SetObjResult(interp, Tcl_NewIntObj(nCol)); 003574 break; 003575 } 003576 003577 case PRE_HOOK: { 003578 if( objc>4 ){ 003579 Tcl_WrongNumArgs(interp, 2, objv, "hook ?SCRIPT?"); 003580 return TCL_ERROR; 003581 } 003582 DbHookCmd(interp, pDb, (objc==4 ? objv[3] : 0), &pDb->pPreUpdateHook); 003583 break; 003584 } 003585 003586 case PRE_DEPTH: { 003587 Tcl_Obj *pRet; 003588 if( objc!=3 ){ 003589 Tcl_WrongNumArgs(interp, 3, objv, ""); 003590 return TCL_ERROR; 003591 } 003592 pRet = Tcl_NewIntObj(sqlite3_preupdate_depth(pDb->db)); 003593 Tcl_SetObjResult(interp, pRet); 003594 break; 003595 } 003596 003597 case PRE_NEW: 003598 case PRE_OLD: { 003599 int iIdx; 003600 sqlite3_value *pValue; 003601 if( objc!=4 ){ 003602 Tcl_WrongNumArgs(interp, 3, objv, "INDEX"); 003603 return TCL_ERROR; 003604 } 003605 if( Tcl_GetIntFromObj(interp, objv[3], &iIdx) ){ 003606 return TCL_ERROR; 003607 } 003608 003609 if( iSub==PRE_OLD ){ 003610 rc = sqlite3_preupdate_old(pDb->db, iIdx, &pValue); 003611 }else{ 003612 assert( iSub==PRE_NEW ); 003613 rc = sqlite3_preupdate_new(pDb->db, iIdx, &pValue); 003614 } 003615 003616 if( rc==SQLITE_OK ){ 003617 Tcl_Obj *pObj; 003618 pObj = Tcl_NewStringObj((char*)sqlite3_value_text(pValue), -1); 003619 Tcl_SetObjResult(interp, pObj); 003620 }else{ 003621 Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0); 003622 return TCL_ERROR; 003623 } 003624 } 003625 } 003626 #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ 003627 break; 003628 } 003629 003630 /* 003631 ** $db wal_hook ?script? 003632 ** $db update_hook ?script? 003633 ** $db rollback_hook ?script? 003634 */ 003635 case DB_WAL_HOOK: 003636 case DB_UPDATE_HOOK: 003637 case DB_ROLLBACK_HOOK: { 003638 /* set ppHook to point at pUpdateHook or pRollbackHook, depending on 003639 ** whether [$db update_hook] or [$db rollback_hook] was invoked. 003640 */ 003641 Tcl_Obj **ppHook = 0; 003642 if( choice==DB_WAL_HOOK ) ppHook = &pDb->pWalHook; 003643 if( choice==DB_UPDATE_HOOK ) ppHook = &pDb->pUpdateHook; 003644 if( choice==DB_ROLLBACK_HOOK ) ppHook = &pDb->pRollbackHook; 003645 if( objc>3 ){ 003646 Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?"); 003647 return TCL_ERROR; 003648 } 003649 003650 DbHookCmd(interp, pDb, (objc==3 ? objv[2] : 0), ppHook); 003651 break; 003652 } 003653 003654 /* $db version 003655 ** 003656 ** Return the version string for this database. 003657 */ 003658 case DB_VERSION: { 003659 int i; 003660 for(i=2; i<objc; i++){ 003661 const char *zArg = Tcl_GetString(objv[i]); 003662 /* Optional arguments to $db version are used for testing purpose */ 003663 #ifdef SQLITE_TEST 003664 /* $db version -use-legacy-prepare BOOLEAN 003665 ** 003666 ** Turn the use of legacy sqlite3_prepare() on or off. 003667 */ 003668 if( strcmp(zArg, "-use-legacy-prepare")==0 && i+1<objc ){ 003669 i++; 003670 if( Tcl_GetBooleanFromObj(interp, objv[i], &pDb->bLegacyPrepare) ){ 003671 return TCL_ERROR; 003672 } 003673 }else 003674 003675 /* $db version -last-stmt-ptr 003676 ** 003677 ** Return a string which is a hex encoding of the pointer to the 003678 ** most recent sqlite3_stmt in the statement cache. 003679 */ 003680 if( strcmp(zArg, "-last-stmt-ptr")==0 ){ 003681 char zBuf[100]; 003682 sqlite3_snprintf(sizeof(zBuf), zBuf, "%p", 003683 pDb->stmtList ? pDb->stmtList->pStmt: 0); 003684 Tcl_SetResult(interp, zBuf, TCL_VOLATILE); 003685 }else 003686 #endif /* SQLITE_TEST */ 003687 { 003688 Tcl_AppendResult(interp, "unknown argument: ", zArg, (char*)0); 003689 return TCL_ERROR; 003690 } 003691 } 003692 if( i==2 ){ 003693 Tcl_SetResult(interp, (char *)sqlite3_libversion(), TCL_STATIC); 003694 } 003695 break; 003696 } 003697 003698 003699 } /* End of the SWITCH statement */ 003700 return rc; 003701 } 003702 003703 #if SQLITE_TCL_NRE 003704 /* 003705 ** Adaptor that provides an objCmd interface to the NRE-enabled 003706 ** interface implementation. 003707 */ 003708 static int SQLITE_TCLAPI DbObjCmdAdaptor( 003709 void *cd, 003710 Tcl_Interp *interp, 003711 int objc, 003712 Tcl_Obj *const*objv 003713 ){ 003714 return Tcl_NRCallObjProc(interp, DbObjCmd, cd, objc, objv); 003715 } 003716 #endif /* SQLITE_TCL_NRE */ 003717 003718 /* 003719 ** Issue the usage message when the "sqlite3" command arguments are 003720 ** incorrect. 003721 */ 003722 static int sqliteCmdUsage( 003723 Tcl_Interp *interp, 003724 Tcl_Obj *const*objv 003725 ){ 003726 Tcl_WrongNumArgs(interp, 1, objv, 003727 "HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?" 003728 " ?-nofollow BOOLEAN?" 003729 " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?" 003730 ); 003731 return TCL_ERROR; 003732 } 003733 003734 /* 003735 ** sqlite3 DBNAME FILENAME ?-vfs VFSNAME? ?-key KEY? ?-readonly BOOLEAN? 003736 ** ?-create BOOLEAN? ?-nomutex BOOLEAN? 003737 ** ?-nofollow BOOLEAN? 003738 ** 003739 ** This is the main Tcl command. When the "sqlite" Tcl command is 003740 ** invoked, this routine runs to process that command. 003741 ** 003742 ** The first argument, DBNAME, is an arbitrary name for a new 003743 ** database connection. This command creates a new command named 003744 ** DBNAME that is used to control that connection. The database 003745 ** connection is deleted when the DBNAME command is deleted. 003746 ** 003747 ** The second argument is the name of the database file. 003748 ** 003749 */ 003750 static int SQLITE_TCLAPI DbMain( 003751 void *cd, 003752 Tcl_Interp *interp, 003753 int objc, 003754 Tcl_Obj *const*objv 003755 ){ 003756 SqliteDb *p; 003757 const char *zArg; 003758 char *zErrMsg; 003759 int i; 003760 const char *zFile = 0; 003761 const char *zVfs = 0; 003762 int flags; 003763 int bTranslateFileName = 1; 003764 Tcl_DString translatedFilename; 003765 int rc; 003766 003767 /* In normal use, each TCL interpreter runs in a single thread. So 003768 ** by default, we can turn off mutexing on SQLite database connections. 003769 ** However, for testing purposes it is useful to have mutexes turned 003770 ** on. So, by default, mutexes default off. But if compiled with 003771 ** SQLITE_TCL_DEFAULT_FULLMUTEX then mutexes default on. 003772 */ 003773 #ifdef SQLITE_TCL_DEFAULT_FULLMUTEX 003774 flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX; 003775 #else 003776 flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX; 003777 #endif 003778 003779 if( objc==1 ) return sqliteCmdUsage(interp, objv); 003780 if( objc==2 ){ 003781 zArg = Tcl_GetStringFromObj(objv[1], 0); 003782 if( strcmp(zArg,"-version")==0 ){ 003783 Tcl_AppendResult(interp,sqlite3_libversion(), (char*)0); 003784 return TCL_OK; 003785 } 003786 if( strcmp(zArg,"-sourceid")==0 ){ 003787 Tcl_AppendResult(interp,sqlite3_sourceid(), (char*)0); 003788 return TCL_OK; 003789 } 003790 if( strcmp(zArg,"-has-codec")==0 ){ 003791 Tcl_AppendResult(interp,"0",(char*)0); 003792 return TCL_OK; 003793 } 003794 if( zArg[0]=='-' ) return sqliteCmdUsage(interp, objv); 003795 } 003796 for(i=2; i<objc; i++){ 003797 zArg = Tcl_GetString(objv[i]); 003798 if( zArg[0]!='-' ){ 003799 if( zFile!=0 ) return sqliteCmdUsage(interp, objv); 003800 zFile = zArg; 003801 continue; 003802 } 003803 if( i==objc-1 ) return sqliteCmdUsage(interp, objv); 003804 i++; 003805 if( strcmp(zArg,"-key")==0 ){ 003806 /* no-op */ 003807 }else if( strcmp(zArg, "-vfs")==0 ){ 003808 zVfs = Tcl_GetString(objv[i]); 003809 }else if( strcmp(zArg, "-readonly")==0 ){ 003810 int b; 003811 if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR; 003812 if( b ){ 003813 flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); 003814 flags |= SQLITE_OPEN_READONLY; 003815 }else{ 003816 flags &= ~SQLITE_OPEN_READONLY; 003817 flags |= SQLITE_OPEN_READWRITE; 003818 } 003819 }else if( strcmp(zArg, "-create")==0 ){ 003820 int b; 003821 if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR; 003822 if( b && (flags & SQLITE_OPEN_READONLY)==0 ){ 003823 flags |= SQLITE_OPEN_CREATE; 003824 }else{ 003825 flags &= ~SQLITE_OPEN_CREATE; 003826 } 003827 }else if( strcmp(zArg, "-nofollow")==0 ){ 003828 int b; 003829 if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR; 003830 if( b ){ 003831 flags |= SQLITE_OPEN_NOFOLLOW; 003832 }else{ 003833 flags &= ~SQLITE_OPEN_NOFOLLOW; 003834 } 003835 }else if( strcmp(zArg, "-nomutex")==0 ){ 003836 int b; 003837 if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR; 003838 if( b ){ 003839 flags |= SQLITE_OPEN_NOMUTEX; 003840 flags &= ~SQLITE_OPEN_FULLMUTEX; 003841 }else{ 003842 flags &= ~SQLITE_OPEN_NOMUTEX; 003843 } 003844 }else if( strcmp(zArg, "-fullmutex")==0 ){ 003845 int b; 003846 if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR; 003847 if( b ){ 003848 flags |= SQLITE_OPEN_FULLMUTEX; 003849 flags &= ~SQLITE_OPEN_NOMUTEX; 003850 }else{ 003851 flags &= ~SQLITE_OPEN_FULLMUTEX; 003852 } 003853 }else if( strcmp(zArg, "-uri")==0 ){ 003854 int b; 003855 if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR; 003856 if( b ){ 003857 flags |= SQLITE_OPEN_URI; 003858 }else{ 003859 flags &= ~SQLITE_OPEN_URI; 003860 } 003861 }else if( strcmp(zArg, "-translatefilename")==0 ){ 003862 if( Tcl_GetBooleanFromObj(interp, objv[i], &bTranslateFileName) ){ 003863 return TCL_ERROR; 003864 } 003865 }else{ 003866 Tcl_AppendResult(interp, "unknown option: ", zArg, (char*)0); 003867 return TCL_ERROR; 003868 } 003869 } 003870 zErrMsg = 0; 003871 p = (SqliteDb*)Tcl_Alloc( sizeof(*p) ); 003872 memset(p, 0, sizeof(*p)); 003873 if( zFile==0 ) zFile = ""; 003874 if( bTranslateFileName ){ 003875 zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename); 003876 } 003877 rc = sqlite3_open_v2(zFile, &p->db, flags, zVfs); 003878 if( bTranslateFileName ){ 003879 Tcl_DStringFree(&translatedFilename); 003880 } 003881 if( p->db ){ 003882 if( SQLITE_OK!=sqlite3_errcode(p->db) ){ 003883 zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db)); 003884 sqlite3_close(p->db); 003885 p->db = 0; 003886 } 003887 }else{ 003888 zErrMsg = sqlite3_mprintf("%s", sqlite3_errstr(rc)); 003889 } 003890 if( p->db==0 ){ 003891 Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE); 003892 Tcl_Free((char*)p); 003893 sqlite3_free(zErrMsg); 003894 return TCL_ERROR; 003895 } 003896 p->maxStmt = NUM_PREPARED_STMTS; 003897 p->openFlags = flags & SQLITE_OPEN_URI; 003898 p->interp = interp; 003899 zArg = Tcl_GetStringFromObj(objv[1], 0); 003900 if( DbUseNre() ){ 003901 Tcl_NRCreateCommand(interp, zArg, DbObjCmdAdaptor, DbObjCmd, 003902 (char*)p, DbDeleteCmd); 003903 }else{ 003904 Tcl_CreateObjCommand(interp, zArg, DbObjCmd, (char*)p, DbDeleteCmd); 003905 } 003906 p->nRef = 1; 003907 return TCL_OK; 003908 } 003909 003910 /* 003911 ** Provide a dummy Tcl_InitStubs if we are using this as a static 003912 ** library. 003913 */ 003914 #ifndef USE_TCL_STUBS 003915 # undef Tcl_InitStubs 003916 # define Tcl_InitStubs(a,b,c) TCL_VERSION 003917 #endif 003918 003919 /* 003920 ** Make sure we have a PACKAGE_VERSION macro defined. This will be 003921 ** defined automatically by the TEA makefile. But other makefiles 003922 ** do not define it. 003923 */ 003924 #ifndef PACKAGE_VERSION 003925 # define PACKAGE_VERSION SQLITE_VERSION 003926 #endif 003927 003928 /* 003929 ** Initialize this module. 003930 ** 003931 ** This Tcl module contains only a single new Tcl command named "sqlite". 003932 ** (Hence there is no namespace. There is no point in using a namespace 003933 ** if the extension only supplies one new name!) The "sqlite" command is 003934 ** used to open a new SQLite database. See the DbMain() routine above 003935 ** for additional information. 003936 ** 003937 ** The EXTERN macros are required by TCL in order to work on windows. 003938 */ 003939 EXTERN int Sqlite3_Init(Tcl_Interp *interp){ 003940 int rc = Tcl_InitStubs(interp, "8.4", 0) ? TCL_OK : TCL_ERROR; 003941 if( rc==TCL_OK ){ 003942 Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0); 003943 #ifndef SQLITE_3_SUFFIX_ONLY 003944 /* The "sqlite" alias is undocumented. It is here only to support 003945 ** legacy scripts. All new scripts should use only the "sqlite3" 003946 ** command. */ 003947 Tcl_CreateObjCommand(interp, "sqlite", (Tcl_ObjCmdProc*)DbMain, 0, 0); 003948 #endif 003949 rc = Tcl_PkgProvide(interp, "sqlite3", PACKAGE_VERSION); 003950 } 003951 return rc; 003952 } 003953 EXTERN int Tclsqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } 003954 EXTERN int Sqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } 003955 EXTERN int Tclsqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } 003956 003957 /* Because it accesses the file-system and uses persistent state, SQLite 003958 ** is not considered appropriate for safe interpreters. Hence, we cause 003959 ** the _SafeInit() interfaces return TCL_ERROR. 003960 */ 003961 EXTERN int Sqlite3_SafeInit(Tcl_Interp *interp){ return TCL_ERROR; } 003962 EXTERN int Sqlite3_SafeUnload(Tcl_Interp *interp, int flags){return TCL_ERROR;} 003963 003964 003965 003966 #ifndef SQLITE_3_SUFFIX_ONLY 003967 int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } 003968 int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } 003969 int Sqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } 003970 int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } 003971 #endif 003972 003973 /* 003974 ** If the TCLSH macro is defined, add code to make a stand-alone program. 003975 */ 003976 #if defined(TCLSH) 003977 003978 /* This is the main routine for an ordinary TCL shell. If there are 003979 ** are arguments, run the first argument as a script. Otherwise, 003980 ** read TCL commands from standard input 003981 */ 003982 static const char *tclsh_main_loop(void){ 003983 static const char zMainloop[] = 003984 "if {[llength $argv]>=1} {\n" 003985 "set argv0 [lindex $argv 0]\n" 003986 "set argv [lrange $argv 1 end]\n" 003987 "source $argv0\n" 003988 "} else {\n" 003989 "set line {}\n" 003990 "while {![eof stdin]} {\n" 003991 "if {$line!=\"\"} {\n" 003992 "puts -nonewline \"> \"\n" 003993 "} else {\n" 003994 "puts -nonewline \"% \"\n" 003995 "}\n" 003996 "flush stdout\n" 003997 "append line [gets stdin]\n" 003998 "if {[info complete $line]} {\n" 003999 "if {[catch {uplevel #0 $line} result]} {\n" 004000 "puts stderr \"Error: $result\"\n" 004001 "} elseif {$result!=\"\"} {\n" 004002 "puts $result\n" 004003 "}\n" 004004 "set line {}\n" 004005 "} else {\n" 004006 "append line \\n\n" 004007 "}\n" 004008 "}\n" 004009 "}\n" 004010 ; 004011 return zMainloop; 004012 } 004013 004014 #ifndef TCLSH_MAIN 004015 # define TCLSH_MAIN main 004016 #endif 004017 int SQLITE_CDECL TCLSH_MAIN(int argc, char **argv){ 004018 Tcl_Interp *interp; 004019 int i; 004020 const char *zScript = 0; 004021 char zArgc[32]; 004022 #if defined(TCLSH_INIT_PROC) 004023 extern const char *TCLSH_INIT_PROC(Tcl_Interp*); 004024 #endif 004025 004026 #if !defined(_WIN32_WCE) 004027 if( getenv("SQLITE_DEBUG_BREAK") ){ 004028 if( isatty(0) && isatty(2) ){ 004029 fprintf(stderr, 004030 "attach debugger to process %d and press any key to continue.\n", 004031 GETPID()); 004032 fgetc(stdin); 004033 }else{ 004034 #if defined(_WIN32) || defined(WIN32) 004035 DebugBreak(); 004036 #elif defined(SIGTRAP) 004037 raise(SIGTRAP); 004038 #endif 004039 } 004040 } 004041 #endif 004042 004043 /* Call sqlite3_shutdown() once before doing anything else. This is to 004044 ** test that sqlite3_shutdown() can be safely called by a process before 004045 ** sqlite3_initialize() is. */ 004046 sqlite3_shutdown(); 004047 004048 Tcl_FindExecutable(argv[0]); 004049 Tcl_SetSystemEncoding(NULL, "utf-8"); 004050 interp = Tcl_CreateInterp(); 004051 Sqlite3_Init(interp); 004052 004053 sqlite3_snprintf(sizeof(zArgc), zArgc, "%d", argc-1); 004054 Tcl_SetVar(interp,"argc", zArgc, TCL_GLOBAL_ONLY); 004055 Tcl_SetVar(interp,"argv0",argv[0],TCL_GLOBAL_ONLY); 004056 Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY); 004057 for(i=1; i<argc; i++){ 004058 Tcl_SetVar(interp, "argv", argv[i], 004059 TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE); 004060 } 004061 #if defined(TCLSH_INIT_PROC) 004062 zScript = TCLSH_INIT_PROC(interp); 004063 #endif 004064 if( zScript==0 ){ 004065 zScript = tclsh_main_loop(); 004066 } 004067 if( Tcl_GlobalEval(interp, zScript)!=TCL_OK ){ 004068 const char *zInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY); 004069 if( zInfo==0 ) zInfo = Tcl_GetStringResult(interp); 004070 fprintf(stderr,"%s: %s\n", *argv, zInfo); 004071 return 1; 004072 } 004073 return 0; 004074 } 004075 #endif /* TCLSH */