Annotation of embedaddon/sqlite3/src/tclsqlite.c, revision 1.1.1.1
1.1 misho 1: /*
2: ** 2001 September 15
3: **
4: ** The author disclaims copyright to this source code. In place of
5: ** a legal notice, here is a blessing:
6: **
7: ** May you do good and not evil.
8: ** May you find forgiveness for yourself and forgive others.
9: ** May you share freely, never taking more than you give.
10: **
11: *************************************************************************
12: ** A TCL Interface to SQLite. Append this file to sqlite3.c and
13: ** compile the whole thing to build a TCL-enabled version of SQLite.
14: **
15: ** Compile-time options:
16: **
17: ** -DTCLSH=1 Add a "main()" routine that works as a tclsh.
18: **
19: ** -DSQLITE_TCLMD5 When used in conjuction with -DTCLSH=1, add
20: ** four new commands to the TCL interpreter for
21: ** generating MD5 checksums: md5, md5file,
22: ** md5-10x8, and md5file-10x8.
23: **
24: ** -DSQLITE_TEST When used in conjuction with -DTCLSH=1, add
25: ** hundreds of new commands used for testing
26: ** SQLite. This option implies -DSQLITE_TCLMD5.
27: */
28: #include "tcl.h"
29: #include <errno.h>
30:
31: /*
32: ** Some additional include files are needed if this file is not
33: ** appended to the amalgamation.
34: */
35: #ifndef SQLITE_AMALGAMATION
36: # include "sqlite3.h"
37: # include <stdlib.h>
38: # include <string.h>
39: # include <assert.h>
40: typedef unsigned char u8;
41: #endif
42: #include <ctype.h>
43:
44: /*
45: * Windows needs to know which symbols to export. Unix does not.
46: * BUILD_sqlite should be undefined for Unix.
47: */
48: #ifdef BUILD_sqlite
49: #undef TCL_STORAGE_CLASS
50: #define TCL_STORAGE_CLASS DLLEXPORT
51: #endif /* BUILD_sqlite */
52:
53: #define NUM_PREPARED_STMTS 10
54: #define MAX_PREPARED_STMTS 100
55:
56: /*
57: ** If TCL uses UTF-8 and SQLite is configured to use iso8859, then we
58: ** have to do a translation when going between the two. Set the
59: ** UTF_TRANSLATION_NEEDED macro to indicate that we need to do
60: ** this translation.
61: */
62: #if defined(TCL_UTF_MAX) && !defined(SQLITE_UTF8)
63: # define UTF_TRANSLATION_NEEDED 1
64: #endif
65:
66: /*
67: ** New SQL functions can be created as TCL scripts. Each such function
68: ** is described by an instance of the following structure.
69: */
70: typedef struct SqlFunc SqlFunc;
71: struct SqlFunc {
72: Tcl_Interp *interp; /* The TCL interpret to execute the function */
73: Tcl_Obj *pScript; /* The Tcl_Obj representation of the script */
74: int useEvalObjv; /* True if it is safe to use Tcl_EvalObjv */
75: char *zName; /* Name of this function */
76: SqlFunc *pNext; /* Next function on the list of them all */
77: };
78:
79: /*
80: ** New collation sequences function can be created as TCL scripts. Each such
81: ** function is described by an instance of the following structure.
82: */
83: typedef struct SqlCollate SqlCollate;
84: struct SqlCollate {
85: Tcl_Interp *interp; /* The TCL interpret to execute the function */
86: char *zScript; /* The script to be run */
87: SqlCollate *pNext; /* Next function on the list of them all */
88: };
89:
90: /*
91: ** Prepared statements are cached for faster execution. Each prepared
92: ** statement is described by an instance of the following structure.
93: */
94: typedef struct SqlPreparedStmt SqlPreparedStmt;
95: struct SqlPreparedStmt {
96: SqlPreparedStmt *pNext; /* Next in linked list */
97: SqlPreparedStmt *pPrev; /* Previous on the list */
98: sqlite3_stmt *pStmt; /* The prepared statement */
99: int nSql; /* chars in zSql[] */
100: const char *zSql; /* Text of the SQL statement */
101: int nParm; /* Size of apParm array */
102: Tcl_Obj **apParm; /* Array of referenced object pointers */
103: };
104:
105: typedef struct IncrblobChannel IncrblobChannel;
106:
107: /*
108: ** There is one instance of this structure for each SQLite database
109: ** that has been opened by the SQLite TCL interface.
110: **
111: ** If this module is built with SQLITE_TEST defined (to create the SQLite
112: ** testfixture executable), then it may be configured to use either
113: ** sqlite3_prepare_v2() or sqlite3_prepare() to prepare SQL statements.
114: ** If SqliteDb.bLegacyPrepare is true, sqlite3_prepare() is used.
115: */
116: typedef struct SqliteDb SqliteDb;
117: struct SqliteDb {
118: sqlite3 *db; /* The "real" database structure. MUST BE FIRST */
119: Tcl_Interp *interp; /* The interpreter used for this database */
120: char *zBusy; /* The busy callback routine */
121: char *zCommit; /* The commit hook callback routine */
122: char *zTrace; /* The trace callback routine */
123: char *zProfile; /* The profile callback routine */
124: char *zProgress; /* The progress callback routine */
125: char *zAuth; /* The authorization callback routine */
126: int disableAuth; /* Disable the authorizer if it exists */
127: char *zNull; /* Text to substitute for an SQL NULL value */
128: SqlFunc *pFunc; /* List of SQL functions */
129: Tcl_Obj *pUpdateHook; /* Update hook script (if any) */
130: Tcl_Obj *pRollbackHook; /* Rollback hook script (if any) */
131: Tcl_Obj *pWalHook; /* WAL hook script (if any) */
132: Tcl_Obj *pUnlockNotify; /* Unlock notify script (if any) */
133: SqlCollate *pCollate; /* List of SQL collation functions */
134: int rc; /* Return code of most recent sqlite3_exec() */
135: Tcl_Obj *pCollateNeeded; /* Collation needed script */
136: SqlPreparedStmt *stmtList; /* List of prepared statements*/
137: SqlPreparedStmt *stmtLast; /* Last statement in the list */
138: int maxStmt; /* The next maximum number of stmtList */
139: int nStmt; /* Number of statements in stmtList */
140: IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */
141: int nStep, nSort, nIndex; /* Statistics for most recent operation */
142: int nTransaction; /* Number of nested [transaction] methods */
143: #ifdef SQLITE_TEST
144: int bLegacyPrepare; /* True to use sqlite3_prepare() */
145: #endif
146: };
147:
148: struct IncrblobChannel {
149: sqlite3_blob *pBlob; /* sqlite3 blob handle */
150: SqliteDb *pDb; /* Associated database connection */
151: int iSeek; /* Current seek offset */
152: Tcl_Channel channel; /* Channel identifier */
153: IncrblobChannel *pNext; /* Linked list of all open incrblob channels */
154: IncrblobChannel *pPrev; /* Linked list of all open incrblob channels */
155: };
156:
157: /*
158: ** Compute a string length that is limited to what can be stored in
159: ** lower 30 bits of a 32-bit signed integer.
160: */
161: static int strlen30(const char *z){
162: const char *z2 = z;
163: while( *z2 ){ z2++; }
164: return 0x3fffffff & (int)(z2 - z);
165: }
166:
167:
168: #ifndef SQLITE_OMIT_INCRBLOB
169: /*
170: ** Close all incrblob channels opened using database connection pDb.
171: ** This is called when shutting down the database connection.
172: */
173: static void closeIncrblobChannels(SqliteDb *pDb){
174: IncrblobChannel *p;
175: IncrblobChannel *pNext;
176:
177: for(p=pDb->pIncrblob; p; p=pNext){
178: pNext = p->pNext;
179:
180: /* Note: Calling unregister here call Tcl_Close on the incrblob channel,
181: ** which deletes the IncrblobChannel structure at *p. So do not
182: ** call Tcl_Free() here.
183: */
184: Tcl_UnregisterChannel(pDb->interp, p->channel);
185: }
186: }
187:
188: /*
189: ** Close an incremental blob channel.
190: */
191: static int incrblobClose(ClientData instanceData, Tcl_Interp *interp){
192: IncrblobChannel *p = (IncrblobChannel *)instanceData;
193: int rc = sqlite3_blob_close(p->pBlob);
194: sqlite3 *db = p->pDb->db;
195:
196: /* Remove the channel from the SqliteDb.pIncrblob list. */
197: if( p->pNext ){
198: p->pNext->pPrev = p->pPrev;
199: }
200: if( p->pPrev ){
201: p->pPrev->pNext = p->pNext;
202: }
203: if( p->pDb->pIncrblob==p ){
204: p->pDb->pIncrblob = p->pNext;
205: }
206:
207: /* Free the IncrblobChannel structure */
208: Tcl_Free((char *)p);
209:
210: if( rc!=SQLITE_OK ){
211: Tcl_SetResult(interp, (char *)sqlite3_errmsg(db), TCL_VOLATILE);
212: return TCL_ERROR;
213: }
214: return TCL_OK;
215: }
216:
217: /*
218: ** Read data from an incremental blob channel.
219: */
220: static int incrblobInput(
221: ClientData instanceData,
222: char *buf,
223: int bufSize,
224: int *errorCodePtr
225: ){
226: IncrblobChannel *p = (IncrblobChannel *)instanceData;
227: int nRead = bufSize; /* Number of bytes to read */
228: int nBlob; /* Total size of the blob */
229: int rc; /* sqlite error code */
230:
231: nBlob = sqlite3_blob_bytes(p->pBlob);
232: if( (p->iSeek+nRead)>nBlob ){
233: nRead = nBlob-p->iSeek;
234: }
235: if( nRead<=0 ){
236: return 0;
237: }
238:
239: rc = sqlite3_blob_read(p->pBlob, (void *)buf, nRead, p->iSeek);
240: if( rc!=SQLITE_OK ){
241: *errorCodePtr = rc;
242: return -1;
243: }
244:
245: p->iSeek += nRead;
246: return nRead;
247: }
248:
249: /*
250: ** Write data to an incremental blob channel.
251: */
252: static int incrblobOutput(
253: ClientData instanceData,
254: CONST char *buf,
255: int toWrite,
256: int *errorCodePtr
257: ){
258: IncrblobChannel *p = (IncrblobChannel *)instanceData;
259: int nWrite = toWrite; /* Number of bytes to write */
260: int nBlob; /* Total size of the blob */
261: int rc; /* sqlite error code */
262:
263: nBlob = sqlite3_blob_bytes(p->pBlob);
264: if( (p->iSeek+nWrite)>nBlob ){
265: *errorCodePtr = EINVAL;
266: return -1;
267: }
268: if( nWrite<=0 ){
269: return 0;
270: }
271:
272: rc = sqlite3_blob_write(p->pBlob, (void *)buf, nWrite, p->iSeek);
273: if( rc!=SQLITE_OK ){
274: *errorCodePtr = EIO;
275: return -1;
276: }
277:
278: p->iSeek += nWrite;
279: return nWrite;
280: }
281:
282: /*
283: ** Seek an incremental blob channel.
284: */
285: static int incrblobSeek(
286: ClientData instanceData,
287: long offset,
288: int seekMode,
289: int *errorCodePtr
290: ){
291: IncrblobChannel *p = (IncrblobChannel *)instanceData;
292:
293: switch( seekMode ){
294: case SEEK_SET:
295: p->iSeek = offset;
296: break;
297: case SEEK_CUR:
298: p->iSeek += offset;
299: break;
300: case SEEK_END:
301: p->iSeek = sqlite3_blob_bytes(p->pBlob) + offset;
302: break;
303:
304: default: assert(!"Bad seekMode");
305: }
306:
307: return p->iSeek;
308: }
309:
310:
311: static void incrblobWatch(ClientData instanceData, int mode){
312: /* NO-OP */
313: }
314: static int incrblobHandle(ClientData instanceData, int dir, ClientData *hPtr){
315: return TCL_ERROR;
316: }
317:
318: static Tcl_ChannelType IncrblobChannelType = {
319: "incrblob", /* typeName */
320: TCL_CHANNEL_VERSION_2, /* version */
321: incrblobClose, /* closeProc */
322: incrblobInput, /* inputProc */
323: incrblobOutput, /* outputProc */
324: incrblobSeek, /* seekProc */
325: 0, /* setOptionProc */
326: 0, /* getOptionProc */
327: incrblobWatch, /* watchProc (this is a no-op) */
328: incrblobHandle, /* getHandleProc (always returns error) */
329: 0, /* close2Proc */
330: 0, /* blockModeProc */
331: 0, /* flushProc */
332: 0, /* handlerProc */
333: 0, /* wideSeekProc */
334: };
335:
336: /*
337: ** Create a new incrblob channel.
338: */
339: static int createIncrblobChannel(
340: Tcl_Interp *interp,
341: SqliteDb *pDb,
342: const char *zDb,
343: const char *zTable,
344: const char *zColumn,
345: sqlite_int64 iRow,
346: int isReadonly
347: ){
348: IncrblobChannel *p;
349: sqlite3 *db = pDb->db;
350: sqlite3_blob *pBlob;
351: int rc;
352: int flags = TCL_READABLE|(isReadonly ? 0 : TCL_WRITABLE);
353:
354: /* This variable is used to name the channels: "incrblob_[incr count]" */
355: static int count = 0;
356: char zChannel[64];
357:
358: rc = sqlite3_blob_open(db, zDb, zTable, zColumn, iRow, !isReadonly, &pBlob);
359: if( rc!=SQLITE_OK ){
360: Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
361: return TCL_ERROR;
362: }
363:
364: p = (IncrblobChannel *)Tcl_Alloc(sizeof(IncrblobChannel));
365: p->iSeek = 0;
366: p->pBlob = pBlob;
367:
368: sqlite3_snprintf(sizeof(zChannel), zChannel, "incrblob_%d", ++count);
369: p->channel = Tcl_CreateChannel(&IncrblobChannelType, zChannel, p, flags);
370: Tcl_RegisterChannel(interp, p->channel);
371:
372: /* Link the new channel into the SqliteDb.pIncrblob list. */
373: p->pNext = pDb->pIncrblob;
374: p->pPrev = 0;
375: if( p->pNext ){
376: p->pNext->pPrev = p;
377: }
378: pDb->pIncrblob = p;
379: p->pDb = pDb;
380:
381: Tcl_SetResult(interp, (char *)Tcl_GetChannelName(p->channel), TCL_VOLATILE);
382: return TCL_OK;
383: }
384: #else /* else clause for "#ifndef SQLITE_OMIT_INCRBLOB" */
385: #define closeIncrblobChannels(pDb)
386: #endif
387:
388: /*
389: ** Look at the script prefix in pCmd. We will be executing this script
390: ** after first appending one or more arguments. This routine analyzes
391: ** the script to see if it is safe to use Tcl_EvalObjv() on the script
392: ** rather than the more general Tcl_EvalEx(). Tcl_EvalObjv() is much
393: ** faster.
394: **
395: ** Scripts that are safe to use with Tcl_EvalObjv() consists of a
396: ** command name followed by zero or more arguments with no [...] or $
397: ** or {...} or ; to be seen anywhere. Most callback scripts consist
398: ** of just a single procedure name and they meet this requirement.
399: */
400: static int safeToUseEvalObjv(Tcl_Interp *interp, Tcl_Obj *pCmd){
401: /* We could try to do something with Tcl_Parse(). But we will instead
402: ** just do a search for forbidden characters. If any of the forbidden
403: ** characters appear in pCmd, we will report the string as unsafe.
404: */
405: const char *z;
406: int n;
407: z = Tcl_GetStringFromObj(pCmd, &n);
408: while( n-- > 0 ){
409: int c = *(z++);
410: if( c=='$' || c=='[' || c==';' ) return 0;
411: }
412: return 1;
413: }
414:
415: /*
416: ** Find an SqlFunc structure with the given name. Or create a new
417: ** one if an existing one cannot be found. Return a pointer to the
418: ** structure.
419: */
420: static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){
421: SqlFunc *p, *pNew;
422: int i;
423: pNew = (SqlFunc*)Tcl_Alloc( sizeof(*pNew) + strlen30(zName) + 1 );
424: pNew->zName = (char*)&pNew[1];
425: for(i=0; zName[i]; i++){ pNew->zName[i] = tolower(zName[i]); }
426: pNew->zName[i] = 0;
427: for(p=pDb->pFunc; p; p=p->pNext){
428: if( strcmp(p->zName, pNew->zName)==0 ){
429: Tcl_Free((char*)pNew);
430: return p;
431: }
432: }
433: pNew->interp = pDb->interp;
434: pNew->pScript = 0;
435: pNew->pNext = pDb->pFunc;
436: pDb->pFunc = pNew;
437: return pNew;
438: }
439:
440: /*
441: ** Free a single SqlPreparedStmt object.
442: */
443: static void dbFreeStmt(SqlPreparedStmt *pStmt){
444: #ifdef SQLITE_TEST
445: if( sqlite3_sql(pStmt->pStmt)==0 ){
446: Tcl_Free((char *)pStmt->zSql);
447: }
448: #endif
449: sqlite3_finalize(pStmt->pStmt);
450: Tcl_Free((char *)pStmt);
451: }
452:
453: /*
454: ** Finalize and free a list of prepared statements
455: */
456: static void flushStmtCache(SqliteDb *pDb){
457: SqlPreparedStmt *pPreStmt;
458: SqlPreparedStmt *pNext;
459:
460: for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pNext){
461: pNext = pPreStmt->pNext;
462: dbFreeStmt(pPreStmt);
463: }
464: pDb->nStmt = 0;
465: pDb->stmtLast = 0;
466: pDb->stmtList = 0;
467: }
468:
469: /*
470: ** TCL calls this procedure when an sqlite3 database command is
471: ** deleted.
472: */
473: static void DbDeleteCmd(void *db){
474: SqliteDb *pDb = (SqliteDb*)db;
475: flushStmtCache(pDb);
476: closeIncrblobChannels(pDb);
477: sqlite3_close(pDb->db);
478: while( pDb->pFunc ){
479: SqlFunc *pFunc = pDb->pFunc;
480: pDb->pFunc = pFunc->pNext;
481: Tcl_DecrRefCount(pFunc->pScript);
482: Tcl_Free((char*)pFunc);
483: }
484: while( pDb->pCollate ){
485: SqlCollate *pCollate = pDb->pCollate;
486: pDb->pCollate = pCollate->pNext;
487: Tcl_Free((char*)pCollate);
488: }
489: if( pDb->zBusy ){
490: Tcl_Free(pDb->zBusy);
491: }
492: if( pDb->zTrace ){
493: Tcl_Free(pDb->zTrace);
494: }
495: if( pDb->zProfile ){
496: Tcl_Free(pDb->zProfile);
497: }
498: if( pDb->zAuth ){
499: Tcl_Free(pDb->zAuth);
500: }
501: if( pDb->zNull ){
502: Tcl_Free(pDb->zNull);
503: }
504: if( pDb->pUpdateHook ){
505: Tcl_DecrRefCount(pDb->pUpdateHook);
506: }
507: if( pDb->pRollbackHook ){
508: Tcl_DecrRefCount(pDb->pRollbackHook);
509: }
510: if( pDb->pWalHook ){
511: Tcl_DecrRefCount(pDb->pWalHook);
512: }
513: if( pDb->pCollateNeeded ){
514: Tcl_DecrRefCount(pDb->pCollateNeeded);
515: }
516: Tcl_Free((char*)pDb);
517: }
518:
519: /*
520: ** This routine is called when a database file is locked while trying
521: ** to execute SQL.
522: */
523: static int DbBusyHandler(void *cd, int nTries){
524: SqliteDb *pDb = (SqliteDb*)cd;
525: int rc;
526: char zVal[30];
527:
528: sqlite3_snprintf(sizeof(zVal), zVal, "%d", nTries);
529: rc = Tcl_VarEval(pDb->interp, pDb->zBusy, " ", zVal, (char*)0);
530: if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
531: return 0;
532: }
533: return 1;
534: }
535:
536: #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
537: /*
538: ** This routine is invoked as the 'progress callback' for the database.
539: */
540: static int DbProgressHandler(void *cd){
541: SqliteDb *pDb = (SqliteDb*)cd;
542: int rc;
543:
544: assert( pDb->zProgress );
545: rc = Tcl_Eval(pDb->interp, pDb->zProgress);
546: if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
547: return 1;
548: }
549: return 0;
550: }
551: #endif
552:
553: #ifndef SQLITE_OMIT_TRACE
554: /*
555: ** This routine is called by the SQLite trace handler whenever a new
556: ** block of SQL is executed. The TCL script in pDb->zTrace is executed.
557: */
558: static void DbTraceHandler(void *cd, const char *zSql){
559: SqliteDb *pDb = (SqliteDb*)cd;
560: Tcl_DString str;
561:
562: Tcl_DStringInit(&str);
563: Tcl_DStringAppend(&str, pDb->zTrace, -1);
564: Tcl_DStringAppendElement(&str, zSql);
565: Tcl_Eval(pDb->interp, Tcl_DStringValue(&str));
566: Tcl_DStringFree(&str);
567: Tcl_ResetResult(pDb->interp);
568: }
569: #endif
570:
571: #ifndef SQLITE_OMIT_TRACE
572: /*
573: ** This routine is called by the SQLite profile handler after a statement
574: ** SQL has executed. The TCL script in pDb->zProfile is evaluated.
575: */
576: static void DbProfileHandler(void *cd, const char *zSql, sqlite_uint64 tm){
577: SqliteDb *pDb = (SqliteDb*)cd;
578: Tcl_DString str;
579: char zTm[100];
580:
581: sqlite3_snprintf(sizeof(zTm)-1, zTm, "%lld", tm);
582: Tcl_DStringInit(&str);
583: Tcl_DStringAppend(&str, pDb->zProfile, -1);
584: Tcl_DStringAppendElement(&str, zSql);
585: Tcl_DStringAppendElement(&str, zTm);
586: Tcl_Eval(pDb->interp, Tcl_DStringValue(&str));
587: Tcl_DStringFree(&str);
588: Tcl_ResetResult(pDb->interp);
589: }
590: #endif
591:
592: /*
593: ** This routine is called when a transaction is committed. The
594: ** TCL script in pDb->zCommit is executed. If it returns non-zero or
595: ** if it throws an exception, the transaction is rolled back instead
596: ** of being committed.
597: */
598: static int DbCommitHandler(void *cd){
599: SqliteDb *pDb = (SqliteDb*)cd;
600: int rc;
601:
602: rc = Tcl_Eval(pDb->interp, pDb->zCommit);
603: if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
604: return 1;
605: }
606: return 0;
607: }
608:
609: static void DbRollbackHandler(void *clientData){
610: SqliteDb *pDb = (SqliteDb*)clientData;
611: assert(pDb->pRollbackHook);
612: if( TCL_OK!=Tcl_EvalObjEx(pDb->interp, pDb->pRollbackHook, 0) ){
613: Tcl_BackgroundError(pDb->interp);
614: }
615: }
616:
617: /*
618: ** This procedure handles wal_hook callbacks.
619: */
620: static int DbWalHandler(
621: void *clientData,
622: sqlite3 *db,
623: const char *zDb,
624: int nEntry
625: ){
626: int ret = SQLITE_OK;
627: Tcl_Obj *p;
628: SqliteDb *pDb = (SqliteDb*)clientData;
629: Tcl_Interp *interp = pDb->interp;
630: assert(pDb->pWalHook);
631:
632: p = Tcl_DuplicateObj(pDb->pWalHook);
633: Tcl_IncrRefCount(p);
634: Tcl_ListObjAppendElement(interp, p, Tcl_NewStringObj(zDb, -1));
635: Tcl_ListObjAppendElement(interp, p, Tcl_NewIntObj(nEntry));
636: if( TCL_OK!=Tcl_EvalObjEx(interp, p, 0)
637: || TCL_OK!=Tcl_GetIntFromObj(interp, Tcl_GetObjResult(interp), &ret)
638: ){
639: Tcl_BackgroundError(interp);
640: }
641: Tcl_DecrRefCount(p);
642:
643: return ret;
644: }
645:
646: #if defined(SQLITE_TEST) && defined(SQLITE_ENABLE_UNLOCK_NOTIFY)
647: static void setTestUnlockNotifyVars(Tcl_Interp *interp, int iArg, int nArg){
648: char zBuf[64];
649: sprintf(zBuf, "%d", iArg);
650: Tcl_SetVar(interp, "sqlite_unlock_notify_arg", zBuf, TCL_GLOBAL_ONLY);
651: sprintf(zBuf, "%d", nArg);
652: Tcl_SetVar(interp, "sqlite_unlock_notify_argcount", zBuf, TCL_GLOBAL_ONLY);
653: }
654: #else
655: # define setTestUnlockNotifyVars(x,y,z)
656: #endif
657:
658: #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
659: static void DbUnlockNotify(void **apArg, int nArg){
660: int i;
661: for(i=0; i<nArg; i++){
662: const int flags = (TCL_EVAL_GLOBAL|TCL_EVAL_DIRECT);
663: SqliteDb *pDb = (SqliteDb *)apArg[i];
664: setTestUnlockNotifyVars(pDb->interp, i, nArg);
665: assert( pDb->pUnlockNotify);
666: Tcl_EvalObjEx(pDb->interp, pDb->pUnlockNotify, flags);
667: Tcl_DecrRefCount(pDb->pUnlockNotify);
668: pDb->pUnlockNotify = 0;
669: }
670: }
671: #endif
672:
673: static void DbUpdateHandler(
674: void *p,
675: int op,
676: const char *zDb,
677: const char *zTbl,
678: sqlite_int64 rowid
679: ){
680: SqliteDb *pDb = (SqliteDb *)p;
681: Tcl_Obj *pCmd;
682:
683: assert( pDb->pUpdateHook );
684: assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE );
685:
686: pCmd = Tcl_DuplicateObj(pDb->pUpdateHook);
687: Tcl_IncrRefCount(pCmd);
688: Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(
689: ( (op==SQLITE_INSERT)?"INSERT":(op==SQLITE_UPDATE)?"UPDATE":"DELETE"), -1));
690: Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zDb, -1));
691: Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zTbl, -1));
692: Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(rowid));
693: Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
694: Tcl_DecrRefCount(pCmd);
695: }
696:
697: static void tclCollateNeeded(
698: void *pCtx,
699: sqlite3 *db,
700: int enc,
701: const char *zName
702: ){
703: SqliteDb *pDb = (SqliteDb *)pCtx;
704: Tcl_Obj *pScript = Tcl_DuplicateObj(pDb->pCollateNeeded);
705: Tcl_IncrRefCount(pScript);
706: Tcl_ListObjAppendElement(0, pScript, Tcl_NewStringObj(zName, -1));
707: Tcl_EvalObjEx(pDb->interp, pScript, 0);
708: Tcl_DecrRefCount(pScript);
709: }
710:
711: /*
712: ** This routine is called to evaluate an SQL collation function implemented
713: ** using TCL script.
714: */
715: static int tclSqlCollate(
716: void *pCtx,
717: int nA,
718: const void *zA,
719: int nB,
720: const void *zB
721: ){
722: SqlCollate *p = (SqlCollate *)pCtx;
723: Tcl_Obj *pCmd;
724:
725: pCmd = Tcl_NewStringObj(p->zScript, -1);
726: Tcl_IncrRefCount(pCmd);
727: Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zA, nA));
728: Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zB, nB));
729: Tcl_EvalObjEx(p->interp, pCmd, TCL_EVAL_DIRECT);
730: Tcl_DecrRefCount(pCmd);
731: return (atoi(Tcl_GetStringResult(p->interp)));
732: }
733:
734: /*
735: ** This routine is called to evaluate an SQL function implemented
736: ** using TCL script.
737: */
738: static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
739: SqlFunc *p = sqlite3_user_data(context);
740: Tcl_Obj *pCmd;
741: int i;
742: int rc;
743:
744: if( argc==0 ){
745: /* If there are no arguments to the function, call Tcl_EvalObjEx on the
746: ** script object directly. This allows the TCL compiler to generate
747: ** bytecode for the command on the first invocation and thus make
748: ** subsequent invocations much faster. */
749: pCmd = p->pScript;
750: Tcl_IncrRefCount(pCmd);
751: rc = Tcl_EvalObjEx(p->interp, pCmd, 0);
752: Tcl_DecrRefCount(pCmd);
753: }else{
754: /* If there are arguments to the function, make a shallow copy of the
755: ** script object, lappend the arguments, then evaluate the copy.
756: **
757: ** By "shallow" copy, we mean a only the outer list Tcl_Obj is duplicated.
758: ** The new Tcl_Obj contains pointers to the original list elements.
759: ** That way, when Tcl_EvalObjv() is run and shimmers the first element
760: ** of the list to tclCmdNameType, that alternate representation will
761: ** be preserved and reused on the next invocation.
762: */
763: Tcl_Obj **aArg;
764: int nArg;
765: if( Tcl_ListObjGetElements(p->interp, p->pScript, &nArg, &aArg) ){
766: sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
767: return;
768: }
769: pCmd = Tcl_NewListObj(nArg, aArg);
770: Tcl_IncrRefCount(pCmd);
771: for(i=0; i<argc; i++){
772: sqlite3_value *pIn = argv[i];
773: Tcl_Obj *pVal;
774:
775: /* Set pVal to contain the i'th column of this row. */
776: switch( sqlite3_value_type(pIn) ){
777: case SQLITE_BLOB: {
778: int bytes = sqlite3_value_bytes(pIn);
779: pVal = Tcl_NewByteArrayObj(sqlite3_value_blob(pIn), bytes);
780: break;
781: }
782: case SQLITE_INTEGER: {
783: sqlite_int64 v = sqlite3_value_int64(pIn);
784: if( v>=-2147483647 && v<=2147483647 ){
785: pVal = Tcl_NewIntObj((int)v);
786: }else{
787: pVal = Tcl_NewWideIntObj(v);
788: }
789: break;
790: }
791: case SQLITE_FLOAT: {
792: double r = sqlite3_value_double(pIn);
793: pVal = Tcl_NewDoubleObj(r);
794: break;
795: }
796: case SQLITE_NULL: {
797: pVal = Tcl_NewStringObj("", 0);
798: break;
799: }
800: default: {
801: int bytes = sqlite3_value_bytes(pIn);
802: pVal = Tcl_NewStringObj((char *)sqlite3_value_text(pIn), bytes);
803: break;
804: }
805: }
806: rc = Tcl_ListObjAppendElement(p->interp, pCmd, pVal);
807: if( rc ){
808: Tcl_DecrRefCount(pCmd);
809: sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
810: return;
811: }
812: }
813: if( !p->useEvalObjv ){
814: /* Tcl_EvalObjEx() will automatically call Tcl_EvalObjv() if pCmd
815: ** is a list without a string representation. To prevent this from
816: ** happening, make sure pCmd has a valid string representation */
817: Tcl_GetString(pCmd);
818: }
819: rc = Tcl_EvalObjEx(p->interp, pCmd, TCL_EVAL_DIRECT);
820: Tcl_DecrRefCount(pCmd);
821: }
822:
823: if( rc && rc!=TCL_RETURN ){
824: sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
825: }else{
826: Tcl_Obj *pVar = Tcl_GetObjResult(p->interp);
827: int n;
828: u8 *data;
829: const char *zType = (pVar->typePtr ? pVar->typePtr->name : "");
830: char c = zType[0];
831: if( c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0 ){
832: /* Only return a BLOB type if the Tcl variable is a bytearray and
833: ** has no string representation. */
834: data = Tcl_GetByteArrayFromObj(pVar, &n);
835: sqlite3_result_blob(context, data, n, SQLITE_TRANSIENT);
836: }else if( c=='b' && strcmp(zType,"boolean")==0 ){
837: Tcl_GetIntFromObj(0, pVar, &n);
838: sqlite3_result_int(context, n);
839: }else if( c=='d' && strcmp(zType,"double")==0 ){
840: double r;
841: Tcl_GetDoubleFromObj(0, pVar, &r);
842: sqlite3_result_double(context, r);
843: }else if( (c=='w' && strcmp(zType,"wideInt")==0) ||
844: (c=='i' && strcmp(zType,"int")==0) ){
845: Tcl_WideInt v;
846: Tcl_GetWideIntFromObj(0, pVar, &v);
847: sqlite3_result_int64(context, v);
848: }else{
849: data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n);
850: sqlite3_result_text(context, (char *)data, n, SQLITE_TRANSIENT);
851: }
852: }
853: }
854:
855: #ifndef SQLITE_OMIT_AUTHORIZATION
856: /*
857: ** This is the authentication function. It appends the authentication
858: ** type code and the two arguments to zCmd[] then invokes the result
859: ** on the interpreter. The reply is examined to determine if the
860: ** authentication fails or succeeds.
861: */
862: static int auth_callback(
863: void *pArg,
864: int code,
865: const char *zArg1,
866: const char *zArg2,
867: const char *zArg3,
868: const char *zArg4
869: ){
870: char *zCode;
871: Tcl_DString str;
872: int rc;
873: const char *zReply;
874: SqliteDb *pDb = (SqliteDb*)pArg;
875: if( pDb->disableAuth ) return SQLITE_OK;
876:
877: switch( code ){
878: case SQLITE_COPY : zCode="SQLITE_COPY"; break;
879: case SQLITE_CREATE_INDEX : zCode="SQLITE_CREATE_INDEX"; break;
880: case SQLITE_CREATE_TABLE : zCode="SQLITE_CREATE_TABLE"; break;
881: case SQLITE_CREATE_TEMP_INDEX : zCode="SQLITE_CREATE_TEMP_INDEX"; break;
882: case SQLITE_CREATE_TEMP_TABLE : zCode="SQLITE_CREATE_TEMP_TABLE"; break;
883: case SQLITE_CREATE_TEMP_TRIGGER: zCode="SQLITE_CREATE_TEMP_TRIGGER"; break;
884: case SQLITE_CREATE_TEMP_VIEW : zCode="SQLITE_CREATE_TEMP_VIEW"; break;
885: case SQLITE_CREATE_TRIGGER : zCode="SQLITE_CREATE_TRIGGER"; break;
886: case SQLITE_CREATE_VIEW : zCode="SQLITE_CREATE_VIEW"; break;
887: case SQLITE_DELETE : zCode="SQLITE_DELETE"; break;
888: case SQLITE_DROP_INDEX : zCode="SQLITE_DROP_INDEX"; break;
889: case SQLITE_DROP_TABLE : zCode="SQLITE_DROP_TABLE"; break;
890: case SQLITE_DROP_TEMP_INDEX : zCode="SQLITE_DROP_TEMP_INDEX"; break;
891: case SQLITE_DROP_TEMP_TABLE : zCode="SQLITE_DROP_TEMP_TABLE"; break;
892: case SQLITE_DROP_TEMP_TRIGGER : zCode="SQLITE_DROP_TEMP_TRIGGER"; break;
893: case SQLITE_DROP_TEMP_VIEW : zCode="SQLITE_DROP_TEMP_VIEW"; break;
894: case SQLITE_DROP_TRIGGER : zCode="SQLITE_DROP_TRIGGER"; break;
895: case SQLITE_DROP_VIEW : zCode="SQLITE_DROP_VIEW"; break;
896: case SQLITE_INSERT : zCode="SQLITE_INSERT"; break;
897: case SQLITE_PRAGMA : zCode="SQLITE_PRAGMA"; break;
898: case SQLITE_READ : zCode="SQLITE_READ"; break;
899: case SQLITE_SELECT : zCode="SQLITE_SELECT"; break;
900: case SQLITE_TRANSACTION : zCode="SQLITE_TRANSACTION"; break;
901: case SQLITE_UPDATE : zCode="SQLITE_UPDATE"; break;
902: case SQLITE_ATTACH : zCode="SQLITE_ATTACH"; break;
903: case SQLITE_DETACH : zCode="SQLITE_DETACH"; break;
904: case SQLITE_ALTER_TABLE : zCode="SQLITE_ALTER_TABLE"; break;
905: case SQLITE_REINDEX : zCode="SQLITE_REINDEX"; break;
906: case SQLITE_ANALYZE : zCode="SQLITE_ANALYZE"; break;
907: case SQLITE_CREATE_VTABLE : zCode="SQLITE_CREATE_VTABLE"; break;
908: case SQLITE_DROP_VTABLE : zCode="SQLITE_DROP_VTABLE"; break;
909: case SQLITE_FUNCTION : zCode="SQLITE_FUNCTION"; break;
910: case SQLITE_SAVEPOINT : zCode="SQLITE_SAVEPOINT"; break;
911: default : zCode="????"; break;
912: }
913: Tcl_DStringInit(&str);
914: Tcl_DStringAppend(&str, pDb->zAuth, -1);
915: Tcl_DStringAppendElement(&str, zCode);
916: Tcl_DStringAppendElement(&str, zArg1 ? zArg1 : "");
917: Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : "");
918: Tcl_DStringAppendElement(&str, zArg3 ? zArg3 : "");
919: Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : "");
920: rc = Tcl_GlobalEval(pDb->interp, Tcl_DStringValue(&str));
921: Tcl_DStringFree(&str);
922: zReply = rc==TCL_OK ? Tcl_GetStringResult(pDb->interp) : "SQLITE_DENY";
923: if( strcmp(zReply,"SQLITE_OK")==0 ){
924: rc = SQLITE_OK;
925: }else if( strcmp(zReply,"SQLITE_DENY")==0 ){
926: rc = SQLITE_DENY;
927: }else if( strcmp(zReply,"SQLITE_IGNORE")==0 ){
928: rc = SQLITE_IGNORE;
929: }else{
930: rc = 999;
931: }
932: return rc;
933: }
934: #endif /* SQLITE_OMIT_AUTHORIZATION */
935:
936: /*
937: ** zText is a pointer to text obtained via an sqlite3_result_text()
938: ** or similar interface. This routine returns a Tcl string object,
939: ** reference count set to 0, containing the text. If a translation
940: ** between iso8859 and UTF-8 is required, it is preformed.
941: */
942: static Tcl_Obj *dbTextToObj(char const *zText){
943: Tcl_Obj *pVal;
944: #ifdef UTF_TRANSLATION_NEEDED
945: Tcl_DString dCol;
946: Tcl_DStringInit(&dCol);
947: Tcl_ExternalToUtfDString(NULL, zText, -1, &dCol);
948: pVal = Tcl_NewStringObj(Tcl_DStringValue(&dCol), -1);
949: Tcl_DStringFree(&dCol);
950: #else
951: pVal = Tcl_NewStringObj(zText, -1);
952: #endif
953: return pVal;
954: }
955:
956: /*
957: ** This routine reads a line of text from FILE in, stores
958: ** the text in memory obtained from malloc() and returns a pointer
959: ** to the text. NULL is returned at end of file, or if malloc()
960: ** fails.
961: **
962: ** The interface is like "readline" but no command-line editing
963: ** is done.
964: **
965: ** copied from shell.c from '.import' command
966: */
967: static char *local_getline(char *zPrompt, FILE *in){
968: char *zLine;
969: int nLine;
970: int n;
971:
972: nLine = 100;
973: zLine = malloc( nLine );
974: if( zLine==0 ) return 0;
975: n = 0;
976: while( 1 ){
977: if( n+100>nLine ){
978: nLine = nLine*2 + 100;
979: zLine = realloc(zLine, nLine);
980: if( zLine==0 ) return 0;
981: }
982: if( fgets(&zLine[n], nLine - n, in)==0 ){
983: if( n==0 ){
984: free(zLine);
985: return 0;
986: }
987: zLine[n] = 0;
988: break;
989: }
990: while( zLine[n] ){ n++; }
991: if( n>0 && zLine[n-1]=='\n' ){
992: n--;
993: zLine[n] = 0;
994: break;
995: }
996: }
997: zLine = realloc( zLine, n+1 );
998: return zLine;
999: }
1000:
1001:
1002: /*
1003: ** This function is part of the implementation of the command:
1004: **
1005: ** $db transaction [-deferred|-immediate|-exclusive] SCRIPT
1006: **
1007: ** It is invoked after evaluating the script SCRIPT to commit or rollback
1008: ** the transaction or savepoint opened by the [transaction] command.
1009: */
1010: static int DbTransPostCmd(
1011: ClientData data[], /* data[0] is the Sqlite3Db* for $db */
1012: Tcl_Interp *interp, /* Tcl interpreter */
1013: int result /* Result of evaluating SCRIPT */
1014: ){
1015: static const char *azEnd[] = {
1016: "RELEASE _tcl_transaction", /* rc==TCL_ERROR, nTransaction!=0 */
1017: "COMMIT", /* rc!=TCL_ERROR, nTransaction==0 */
1018: "ROLLBACK TO _tcl_transaction ; RELEASE _tcl_transaction",
1019: "ROLLBACK" /* rc==TCL_ERROR, nTransaction==0 */
1020: };
1021: SqliteDb *pDb = (SqliteDb*)data[0];
1022: int rc = result;
1023: const char *zEnd;
1024:
1025: pDb->nTransaction--;
1026: zEnd = azEnd[(rc==TCL_ERROR)*2 + (pDb->nTransaction==0)];
1027:
1028: pDb->disableAuth++;
1029: if( sqlite3_exec(pDb->db, zEnd, 0, 0, 0) ){
1030: /* This is a tricky scenario to handle. The most likely cause of an
1031: ** error is that the exec() above was an attempt to commit the
1032: ** top-level transaction that returned SQLITE_BUSY. Or, less likely,
1033: ** that an IO-error has occured. In either case, throw a Tcl exception
1034: ** and try to rollback the transaction.
1035: **
1036: ** But it could also be that the user executed one or more BEGIN,
1037: ** COMMIT, SAVEPOINT, RELEASE or ROLLBACK commands that are confusing
1038: ** this method's logic. Not clear how this would be best handled.
1039: */
1040: if( rc!=TCL_ERROR ){
1041: Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0);
1042: rc = TCL_ERROR;
1043: }
1044: sqlite3_exec(pDb->db, "ROLLBACK", 0, 0, 0);
1045: }
1046: pDb->disableAuth--;
1047:
1048: return rc;
1049: }
1050:
1051: /*
1052: ** Unless SQLITE_TEST is defined, this function is a simple wrapper around
1053: ** sqlite3_prepare_v2(). If SQLITE_TEST is defined, then it uses either
1054: ** sqlite3_prepare_v2() or legacy interface sqlite3_prepare(), depending
1055: ** on whether or not the [db_use_legacy_prepare] command has been used to
1056: ** configure the connection.
1057: */
1058: static int dbPrepare(
1059: SqliteDb *pDb, /* Database object */
1060: const char *zSql, /* SQL to compile */
1061: sqlite3_stmt **ppStmt, /* OUT: Prepared statement */
1062: const char **pzOut /* OUT: Pointer to next SQL statement */
1063: ){
1064: #ifdef SQLITE_TEST
1065: if( pDb->bLegacyPrepare ){
1066: return sqlite3_prepare(pDb->db, zSql, -1, ppStmt, pzOut);
1067: }
1068: #endif
1069: return sqlite3_prepare_v2(pDb->db, zSql, -1, ppStmt, pzOut);
1070: }
1071:
1072: /*
1073: ** Search the cache for a prepared-statement object that implements the
1074: ** first SQL statement in the buffer pointed to by parameter zIn. If
1075: ** no such prepared-statement can be found, allocate and prepare a new
1076: ** one. In either case, bind the current values of the relevant Tcl
1077: ** variables to any $var, :var or @var variables in the statement. Before
1078: ** returning, set *ppPreStmt to point to the prepared-statement object.
1079: **
1080: ** Output parameter *pzOut is set to point to the next SQL statement in
1081: ** buffer zIn, or to the '\0' byte at the end of zIn if there is no
1082: ** next statement.
1083: **
1084: ** If successful, TCL_OK is returned. Otherwise, TCL_ERROR is returned
1085: ** and an error message loaded into interpreter pDb->interp.
1086: */
1087: static int dbPrepareAndBind(
1088: SqliteDb *pDb, /* Database object */
1089: char const *zIn, /* SQL to compile */
1090: char const **pzOut, /* OUT: Pointer to next SQL statement */
1091: SqlPreparedStmt **ppPreStmt /* OUT: Object used to cache statement */
1092: ){
1093: const char *zSql = zIn; /* Pointer to first SQL statement in zIn */
1094: sqlite3_stmt *pStmt; /* Prepared statement object */
1095: SqlPreparedStmt *pPreStmt; /* Pointer to cached statement */
1096: int nSql; /* Length of zSql in bytes */
1097: int nVar; /* Number of variables in statement */
1098: int iParm = 0; /* Next free entry in apParm */
1099: int i;
1100: Tcl_Interp *interp = pDb->interp;
1101:
1102: *ppPreStmt = 0;
1103:
1104: /* Trim spaces from the start of zSql and calculate the remaining length. */
1105: while( isspace(zSql[0]) ){ zSql++; }
1106: nSql = strlen30(zSql);
1107:
1108: for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pPreStmt->pNext){
1109: int n = pPreStmt->nSql;
1110: if( nSql>=n
1111: && memcmp(pPreStmt->zSql, zSql, n)==0
1112: && (zSql[n]==0 || zSql[n-1]==';')
1113: ){
1114: pStmt = pPreStmt->pStmt;
1115: *pzOut = &zSql[pPreStmt->nSql];
1116:
1117: /* When a prepared statement is found, unlink it from the
1118: ** cache list. It will later be added back to the beginning
1119: ** of the cache list in order to implement LRU replacement.
1120: */
1121: if( pPreStmt->pPrev ){
1122: pPreStmt->pPrev->pNext = pPreStmt->pNext;
1123: }else{
1124: pDb->stmtList = pPreStmt->pNext;
1125: }
1126: if( pPreStmt->pNext ){
1127: pPreStmt->pNext->pPrev = pPreStmt->pPrev;
1128: }else{
1129: pDb->stmtLast = pPreStmt->pPrev;
1130: }
1131: pDb->nStmt--;
1132: nVar = sqlite3_bind_parameter_count(pStmt);
1133: break;
1134: }
1135: }
1136:
1137: /* If no prepared statement was found. Compile the SQL text. Also allocate
1138: ** a new SqlPreparedStmt structure. */
1139: if( pPreStmt==0 ){
1140: int nByte;
1141:
1142: if( SQLITE_OK!=dbPrepare(pDb, zSql, &pStmt, pzOut) ){
1143: Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
1144: return TCL_ERROR;
1145: }
1146: if( pStmt==0 ){
1147: if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){
1148: /* A compile-time error in the statement. */
1149: Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
1150: return TCL_ERROR;
1151: }else{
1152: /* The statement was a no-op. Continue to the next statement
1153: ** in the SQL string.
1154: */
1155: return TCL_OK;
1156: }
1157: }
1158:
1159: assert( pPreStmt==0 );
1160: nVar = sqlite3_bind_parameter_count(pStmt);
1161: nByte = sizeof(SqlPreparedStmt) + nVar*sizeof(Tcl_Obj *);
1162: pPreStmt = (SqlPreparedStmt*)Tcl_Alloc(nByte);
1163: memset(pPreStmt, 0, nByte);
1164:
1165: pPreStmt->pStmt = pStmt;
1166: pPreStmt->nSql = (*pzOut - zSql);
1167: pPreStmt->zSql = sqlite3_sql(pStmt);
1168: pPreStmt->apParm = (Tcl_Obj **)&pPreStmt[1];
1169: #ifdef SQLITE_TEST
1170: if( pPreStmt->zSql==0 ){
1171: char *zCopy = Tcl_Alloc(pPreStmt->nSql + 1);
1172: memcpy(zCopy, zSql, pPreStmt->nSql);
1173: zCopy[pPreStmt->nSql] = '\0';
1174: pPreStmt->zSql = zCopy;
1175: }
1176: #endif
1177: }
1178: assert( pPreStmt );
1179: assert( strlen30(pPreStmt->zSql)==pPreStmt->nSql );
1180: assert( 0==memcmp(pPreStmt->zSql, zSql, pPreStmt->nSql) );
1181:
1182: /* Bind values to parameters that begin with $ or : */
1183: for(i=1; i<=nVar; i++){
1184: const char *zVar = sqlite3_bind_parameter_name(pStmt, i);
1185: if( zVar!=0 && (zVar[0]=='$' || zVar[0]==':' || zVar[0]=='@') ){
1186: Tcl_Obj *pVar = Tcl_GetVar2Ex(interp, &zVar[1], 0, 0);
1187: if( pVar ){
1188: int n;
1189: u8 *data;
1190: const char *zType = (pVar->typePtr ? pVar->typePtr->name : "");
1191: char c = zType[0];
1192: if( zVar[0]=='@' ||
1193: (c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0) ){
1194: /* Load a BLOB type if the Tcl variable is a bytearray and
1195: ** it has no string representation or the host
1196: ** parameter name begins with "@". */
1197: data = Tcl_GetByteArrayFromObj(pVar, &n);
1198: sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC);
1199: Tcl_IncrRefCount(pVar);
1200: pPreStmt->apParm[iParm++] = pVar;
1201: }else if( c=='b' && strcmp(zType,"boolean")==0 ){
1202: Tcl_GetIntFromObj(interp, pVar, &n);
1203: sqlite3_bind_int(pStmt, i, n);
1204: }else if( c=='d' && strcmp(zType,"double")==0 ){
1205: double r;
1206: Tcl_GetDoubleFromObj(interp, pVar, &r);
1207: sqlite3_bind_double(pStmt, i, r);
1208: }else if( (c=='w' && strcmp(zType,"wideInt")==0) ||
1209: (c=='i' && strcmp(zType,"int")==0) ){
1210: Tcl_WideInt v;
1211: Tcl_GetWideIntFromObj(interp, pVar, &v);
1212: sqlite3_bind_int64(pStmt, i, v);
1213: }else{
1214: data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n);
1215: sqlite3_bind_text(pStmt, i, (char *)data, n, SQLITE_STATIC);
1216: Tcl_IncrRefCount(pVar);
1217: pPreStmt->apParm[iParm++] = pVar;
1218: }
1219: }else{
1220: sqlite3_bind_null(pStmt, i);
1221: }
1222: }
1223: }
1224: pPreStmt->nParm = iParm;
1225: *ppPreStmt = pPreStmt;
1226:
1227: return TCL_OK;
1228: }
1229:
1230: /*
1231: ** Release a statement reference obtained by calling dbPrepareAndBind().
1232: ** There should be exactly one call to this function for each call to
1233: ** dbPrepareAndBind().
1234: **
1235: ** If the discard parameter is non-zero, then the statement is deleted
1236: ** immediately. Otherwise it is added to the LRU list and may be returned
1237: ** by a subsequent call to dbPrepareAndBind().
1238: */
1239: static void dbReleaseStmt(
1240: SqliteDb *pDb, /* Database handle */
1241: SqlPreparedStmt *pPreStmt, /* Prepared statement handle to release */
1242: int discard /* True to delete (not cache) the pPreStmt */
1243: ){
1244: int i;
1245:
1246: /* Free the bound string and blob parameters */
1247: for(i=0; i<pPreStmt->nParm; i++){
1248: Tcl_DecrRefCount(pPreStmt->apParm[i]);
1249: }
1250: pPreStmt->nParm = 0;
1251:
1252: if( pDb->maxStmt<=0 || discard ){
1253: /* If the cache is turned off, deallocated the statement */
1254: dbFreeStmt(pPreStmt);
1255: }else{
1256: /* Add the prepared statement to the beginning of the cache list. */
1257: pPreStmt->pNext = pDb->stmtList;
1258: pPreStmt->pPrev = 0;
1259: if( pDb->stmtList ){
1260: pDb->stmtList->pPrev = pPreStmt;
1261: }
1262: pDb->stmtList = pPreStmt;
1263: if( pDb->stmtLast==0 ){
1264: assert( pDb->nStmt==0 );
1265: pDb->stmtLast = pPreStmt;
1266: }else{
1267: assert( pDb->nStmt>0 );
1268: }
1269: pDb->nStmt++;
1270:
1271: /* If we have too many statement in cache, remove the surplus from
1272: ** the end of the cache list. */
1273: while( pDb->nStmt>pDb->maxStmt ){
1274: SqlPreparedStmt *pLast = pDb->stmtLast;
1275: pDb->stmtLast = pLast->pPrev;
1276: pDb->stmtLast->pNext = 0;
1277: pDb->nStmt--;
1278: dbFreeStmt(pLast);
1279: }
1280: }
1281: }
1282:
1283: /*
1284: ** Structure used with dbEvalXXX() functions:
1285: **
1286: ** dbEvalInit()
1287: ** dbEvalStep()
1288: ** dbEvalFinalize()
1289: ** dbEvalRowInfo()
1290: ** dbEvalColumnValue()
1291: */
1292: typedef struct DbEvalContext DbEvalContext;
1293: struct DbEvalContext {
1294: SqliteDb *pDb; /* Database handle */
1295: Tcl_Obj *pSql; /* Object holding string zSql */
1296: const char *zSql; /* Remaining SQL to execute */
1297: SqlPreparedStmt *pPreStmt; /* Current statement */
1298: int nCol; /* Number of columns returned by pStmt */
1299: Tcl_Obj *pArray; /* Name of array variable */
1300: Tcl_Obj **apColName; /* Array of column names */
1301: };
1302:
1303: /*
1304: ** Release any cache of column names currently held as part of
1305: ** the DbEvalContext structure passed as the first argument.
1306: */
1307: static void dbReleaseColumnNames(DbEvalContext *p){
1308: if( p->apColName ){
1309: int i;
1310: for(i=0; i<p->nCol; i++){
1311: Tcl_DecrRefCount(p->apColName[i]);
1312: }
1313: Tcl_Free((char *)p->apColName);
1314: p->apColName = 0;
1315: }
1316: p->nCol = 0;
1317: }
1318:
1319: /*
1320: ** Initialize a DbEvalContext structure.
1321: **
1322: ** If pArray is not NULL, then it contains the name of a Tcl array
1323: ** variable. The "*" member of this array is set to a list containing
1324: ** the names of the columns returned by the statement as part of each
1325: ** call to dbEvalStep(), in order from left to right. e.g. if the names
1326: ** of the returned columns are a, b and c, it does the equivalent of the
1327: ** tcl command:
1328: **
1329: ** set ${pArray}(*) {a b c}
1330: */
1331: static void dbEvalInit(
1332: DbEvalContext *p, /* Pointer to structure to initialize */
1333: SqliteDb *pDb, /* Database handle */
1334: Tcl_Obj *pSql, /* Object containing SQL script */
1335: Tcl_Obj *pArray /* Name of Tcl array to set (*) element of */
1336: ){
1337: memset(p, 0, sizeof(DbEvalContext));
1338: p->pDb = pDb;
1339: p->zSql = Tcl_GetString(pSql);
1340: p->pSql = pSql;
1341: Tcl_IncrRefCount(pSql);
1342: if( pArray ){
1343: p->pArray = pArray;
1344: Tcl_IncrRefCount(pArray);
1345: }
1346: }
1347:
1348: /*
1349: ** Obtain information about the row that the DbEvalContext passed as the
1350: ** first argument currently points to.
1351: */
1352: static void dbEvalRowInfo(
1353: DbEvalContext *p, /* Evaluation context */
1354: int *pnCol, /* OUT: Number of column names */
1355: Tcl_Obj ***papColName /* OUT: Array of column names */
1356: ){
1357: /* Compute column names */
1358: if( 0==p->apColName ){
1359: sqlite3_stmt *pStmt = p->pPreStmt->pStmt;
1360: int i; /* Iterator variable */
1361: int nCol; /* Number of columns returned by pStmt */
1362: Tcl_Obj **apColName = 0; /* Array of column names */
1363:
1364: p->nCol = nCol = sqlite3_column_count(pStmt);
1365: if( nCol>0 && (papColName || p->pArray) ){
1366: apColName = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*)*nCol );
1367: for(i=0; i<nCol; i++){
1368: apColName[i] = dbTextToObj(sqlite3_column_name(pStmt,i));
1369: Tcl_IncrRefCount(apColName[i]);
1370: }
1371: p->apColName = apColName;
1372: }
1373:
1374: /* If results are being stored in an array variable, then create
1375: ** the array(*) entry for that array
1376: */
1377: if( p->pArray ){
1378: Tcl_Interp *interp = p->pDb->interp;
1379: Tcl_Obj *pColList = Tcl_NewObj();
1380: Tcl_Obj *pStar = Tcl_NewStringObj("*", -1);
1381:
1382: for(i=0; i<nCol; i++){
1383: Tcl_ListObjAppendElement(interp, pColList, apColName[i]);
1384: }
1385: Tcl_IncrRefCount(pStar);
1386: Tcl_ObjSetVar2(interp, p->pArray, pStar, pColList, 0);
1387: Tcl_DecrRefCount(pStar);
1388: }
1389: }
1390:
1391: if( papColName ){
1392: *papColName = p->apColName;
1393: }
1394: if( pnCol ){
1395: *pnCol = p->nCol;
1396: }
1397: }
1398:
1399: /*
1400: ** Return one of TCL_OK, TCL_BREAK or TCL_ERROR. If TCL_ERROR is
1401: ** returned, then an error message is stored in the interpreter before
1402: ** returning.
1403: **
1404: ** A return value of TCL_OK means there is a row of data available. The
1405: ** data may be accessed using dbEvalRowInfo() and dbEvalColumnValue(). This
1406: ** is analogous to a return of SQLITE_ROW from sqlite3_step(). If TCL_BREAK
1407: ** is returned, then the SQL script has finished executing and there are
1408: ** no further rows available. This is similar to SQLITE_DONE.
1409: */
1410: static int dbEvalStep(DbEvalContext *p){
1411: const char *zPrevSql = 0; /* Previous value of p->zSql */
1412:
1413: while( p->zSql[0] || p->pPreStmt ){
1414: int rc;
1415: if( p->pPreStmt==0 ){
1416: zPrevSql = (p->zSql==zPrevSql ? 0 : p->zSql);
1417: rc = dbPrepareAndBind(p->pDb, p->zSql, &p->zSql, &p->pPreStmt);
1418: if( rc!=TCL_OK ) return rc;
1419: }else{
1420: int rcs;
1421: SqliteDb *pDb = p->pDb;
1422: SqlPreparedStmt *pPreStmt = p->pPreStmt;
1423: sqlite3_stmt *pStmt = pPreStmt->pStmt;
1424:
1425: rcs = sqlite3_step(pStmt);
1426: if( rcs==SQLITE_ROW ){
1427: return TCL_OK;
1428: }
1429: if( p->pArray ){
1430: dbEvalRowInfo(p, 0, 0);
1431: }
1432: rcs = sqlite3_reset(pStmt);
1433:
1434: pDb->nStep = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_FULLSCAN_STEP,1);
1435: pDb->nSort = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_SORT,1);
1436: pDb->nIndex = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_AUTOINDEX,1);
1437: dbReleaseColumnNames(p);
1438: p->pPreStmt = 0;
1439:
1440: if( rcs!=SQLITE_OK ){
1441: /* If a run-time error occurs, report the error and stop reading
1442: ** the SQL. */
1443: dbReleaseStmt(pDb, pPreStmt, 1);
1444: #if SQLITE_TEST
1445: if( p->pDb->bLegacyPrepare && rcs==SQLITE_SCHEMA && zPrevSql ){
1446: /* If the runtime error was an SQLITE_SCHEMA, and the database
1447: ** handle is configured to use the legacy sqlite3_prepare()
1448: ** interface, retry prepare()/step() on the same SQL statement.
1449: ** This only happens once. If there is a second SQLITE_SCHEMA
1450: ** error, the error will be returned to the caller. */
1451: p->zSql = zPrevSql;
1452: continue;
1453: }
1454: #endif
1455: Tcl_SetObjResult(pDb->interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
1456: return TCL_ERROR;
1457: }else{
1458: dbReleaseStmt(pDb, pPreStmt, 0);
1459: }
1460: }
1461: }
1462:
1463: /* Finished */
1464: return TCL_BREAK;
1465: }
1466:
1467: /*
1468: ** Free all resources currently held by the DbEvalContext structure passed
1469: ** as the first argument. There should be exactly one call to this function
1470: ** for each call to dbEvalInit().
1471: */
1472: static void dbEvalFinalize(DbEvalContext *p){
1473: if( p->pPreStmt ){
1474: sqlite3_reset(p->pPreStmt->pStmt);
1475: dbReleaseStmt(p->pDb, p->pPreStmt, 0);
1476: p->pPreStmt = 0;
1477: }
1478: if( p->pArray ){
1479: Tcl_DecrRefCount(p->pArray);
1480: p->pArray = 0;
1481: }
1482: Tcl_DecrRefCount(p->pSql);
1483: dbReleaseColumnNames(p);
1484: }
1485:
1486: /*
1487: ** Return a pointer to a Tcl_Obj structure with ref-count 0 that contains
1488: ** the value for the iCol'th column of the row currently pointed to by
1489: ** the DbEvalContext structure passed as the first argument.
1490: */
1491: static Tcl_Obj *dbEvalColumnValue(DbEvalContext *p, int iCol){
1492: sqlite3_stmt *pStmt = p->pPreStmt->pStmt;
1493: switch( sqlite3_column_type(pStmt, iCol) ){
1494: case SQLITE_BLOB: {
1495: int bytes = sqlite3_column_bytes(pStmt, iCol);
1496: const char *zBlob = sqlite3_column_blob(pStmt, iCol);
1497: if( !zBlob ) bytes = 0;
1498: return Tcl_NewByteArrayObj((u8*)zBlob, bytes);
1499: }
1500: case SQLITE_INTEGER: {
1501: sqlite_int64 v = sqlite3_column_int64(pStmt, iCol);
1502: if( v>=-2147483647 && v<=2147483647 ){
1503: return Tcl_NewIntObj((int)v);
1504: }else{
1505: return Tcl_NewWideIntObj(v);
1506: }
1507: }
1508: case SQLITE_FLOAT: {
1509: return Tcl_NewDoubleObj(sqlite3_column_double(pStmt, iCol));
1510: }
1511: case SQLITE_NULL: {
1512: return dbTextToObj(p->pDb->zNull);
1513: }
1514: }
1515:
1516: return dbTextToObj((char *)sqlite3_column_text(pStmt, iCol));
1517: }
1518:
1519: /*
1520: ** If using Tcl version 8.6 or greater, use the NR functions to avoid
1521: ** recursive evalution of scripts by the [db eval] and [db trans]
1522: ** commands. Even if the headers used while compiling the extension
1523: ** are 8.6 or newer, the code still tests the Tcl version at runtime.
1524: ** This allows stubs-enabled builds to be used with older Tcl libraries.
1525: */
1526: #if TCL_MAJOR_VERSION>8 || (TCL_MAJOR_VERSION==8 && TCL_MINOR_VERSION>=6)
1527: # define SQLITE_TCL_NRE 1
1528: static int DbUseNre(void){
1529: int major, minor;
1530: Tcl_GetVersion(&major, &minor, 0, 0);
1531: return( (major==8 && minor>=6) || major>8 );
1532: }
1533: #else
1534: /*
1535: ** Compiling using headers earlier than 8.6. In this case NR cannot be
1536: ** used, so DbUseNre() to always return zero. Add #defines for the other
1537: ** Tcl_NRxxx() functions to prevent them from causing compilation errors,
1538: ** even though the only invocations of them are within conditional blocks
1539: ** of the form:
1540: **
1541: ** if( DbUseNre() ) { ... }
1542: */
1543: # define SQLITE_TCL_NRE 0
1544: # define DbUseNre() 0
1545: # define Tcl_NRAddCallback(a,b,c,d,e,f) 0
1546: # define Tcl_NREvalObj(a,b,c) 0
1547: # define Tcl_NRCreateCommand(a,b,c,d,e,f) 0
1548: #endif
1549:
1550: /*
1551: ** This function is part of the implementation of the command:
1552: **
1553: ** $db eval SQL ?ARRAYNAME? SCRIPT
1554: */
1555: static int DbEvalNextCmd(
1556: ClientData data[], /* data[0] is the (DbEvalContext*) */
1557: Tcl_Interp *interp, /* Tcl interpreter */
1558: int result /* Result so far */
1559: ){
1560: int rc = result; /* Return code */
1561:
1562: /* The first element of the data[] array is a pointer to a DbEvalContext
1563: ** structure allocated using Tcl_Alloc(). The second element of data[]
1564: ** is a pointer to a Tcl_Obj containing the script to run for each row
1565: ** returned by the queries encapsulated in data[0]. */
1566: DbEvalContext *p = (DbEvalContext *)data[0];
1567: Tcl_Obj *pScript = (Tcl_Obj *)data[1];
1568: Tcl_Obj *pArray = p->pArray;
1569:
1570: while( (rc==TCL_OK || rc==TCL_CONTINUE) && TCL_OK==(rc = dbEvalStep(p)) ){
1571: int i;
1572: int nCol;
1573: Tcl_Obj **apColName;
1574: dbEvalRowInfo(p, &nCol, &apColName);
1575: for(i=0; i<nCol; i++){
1576: Tcl_Obj *pVal = dbEvalColumnValue(p, i);
1577: if( pArray==0 ){
1578: Tcl_ObjSetVar2(interp, apColName[i], 0, pVal, 0);
1579: }else{
1580: Tcl_ObjSetVar2(interp, pArray, apColName[i], pVal, 0);
1581: }
1582: }
1583:
1584: /* The required interpreter variables are now populated with the data
1585: ** from the current row. If using NRE, schedule callbacks to evaluate
1586: ** script pScript, then to invoke this function again to fetch the next
1587: ** row (or clean up if there is no next row or the script throws an
1588: ** exception). After scheduling the callbacks, return control to the
1589: ** caller.
1590: **
1591: ** If not using NRE, evaluate pScript directly and continue with the
1592: ** next iteration of this while(...) loop. */
1593: if( DbUseNre() ){
1594: Tcl_NRAddCallback(interp, DbEvalNextCmd, (void*)p, (void*)pScript, 0, 0);
1595: return Tcl_NREvalObj(interp, pScript, 0);
1596: }else{
1597: rc = Tcl_EvalObjEx(interp, pScript, 0);
1598: }
1599: }
1600:
1601: Tcl_DecrRefCount(pScript);
1602: dbEvalFinalize(p);
1603: Tcl_Free((char *)p);
1604:
1605: if( rc==TCL_OK || rc==TCL_BREAK ){
1606: Tcl_ResetResult(interp);
1607: rc = TCL_OK;
1608: }
1609: return rc;
1610: }
1611:
1612: /*
1613: ** The "sqlite" command below creates a new Tcl command for each
1614: ** connection it opens to an SQLite database. This routine is invoked
1615: ** whenever one of those connection-specific commands is executed
1616: ** in Tcl. For example, if you run Tcl code like this:
1617: **
1618: ** sqlite3 db1 "my_database"
1619: ** db1 close
1620: **
1621: ** The first command opens a connection to the "my_database" database
1622: ** and calls that connection "db1". The second command causes this
1623: ** subroutine to be invoked.
1624: */
1625: static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
1626: SqliteDb *pDb = (SqliteDb*)cd;
1627: int choice;
1628: int rc = TCL_OK;
1629: static const char *DB_strs[] = {
1630: "authorizer", "backup", "busy",
1631: "cache", "changes", "close",
1632: "collate", "collation_needed", "commit_hook",
1633: "complete", "copy", "enable_load_extension",
1634: "errorcode", "eval", "exists",
1635: "function", "incrblob", "interrupt",
1636: "last_insert_rowid", "nullvalue", "onecolumn",
1637: "profile", "progress", "rekey",
1638: "restore", "rollback_hook", "status",
1639: "timeout", "total_changes", "trace",
1640: "transaction", "unlock_notify", "update_hook",
1641: "version", "wal_hook", 0
1642: };
1643: enum DB_enum {
1644: DB_AUTHORIZER, DB_BACKUP, DB_BUSY,
1645: DB_CACHE, DB_CHANGES, DB_CLOSE,
1646: DB_COLLATE, DB_COLLATION_NEEDED, DB_COMMIT_HOOK,
1647: DB_COMPLETE, DB_COPY, DB_ENABLE_LOAD_EXTENSION,
1648: DB_ERRORCODE, DB_EVAL, DB_EXISTS,
1649: DB_FUNCTION, DB_INCRBLOB, DB_INTERRUPT,
1650: DB_LAST_INSERT_ROWID, DB_NULLVALUE, DB_ONECOLUMN,
1651: DB_PROFILE, DB_PROGRESS, DB_REKEY,
1652: DB_RESTORE, DB_ROLLBACK_HOOK, DB_STATUS,
1653: DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE,
1654: DB_TRANSACTION, DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK,
1655: DB_VERSION, DB_WAL_HOOK
1656: };
1657: /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */
1658:
1659: if( objc<2 ){
1660: Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");
1661: return TCL_ERROR;
1662: }
1663: if( Tcl_GetIndexFromObj(interp, objv[1], DB_strs, "option", 0, &choice) ){
1664: return TCL_ERROR;
1665: }
1666:
1667: switch( (enum DB_enum)choice ){
1668:
1669: /* $db authorizer ?CALLBACK?
1670: **
1671: ** Invoke the given callback to authorize each SQL operation as it is
1672: ** compiled. 5 arguments are appended to the callback before it is
1673: ** invoked:
1674: **
1675: ** (1) The authorization type (ex: SQLITE_CREATE_TABLE, SQLITE_INSERT, ...)
1676: ** (2) First descriptive name (depends on authorization type)
1677: ** (3) Second descriptive name
1678: ** (4) Name of the database (ex: "main", "temp")
1679: ** (5) Name of trigger that is doing the access
1680: **
1681: ** The callback should return on of the following strings: SQLITE_OK,
1682: ** SQLITE_IGNORE, or SQLITE_DENY. Any other return value is an error.
1683: **
1684: ** If this method is invoked with no arguments, the current authorization
1685: ** callback string is returned.
1686: */
1687: case DB_AUTHORIZER: {
1688: #ifdef SQLITE_OMIT_AUTHORIZATION
1689: Tcl_AppendResult(interp, "authorization not available in this build", 0);
1690: return TCL_ERROR;
1691: #else
1692: if( objc>3 ){
1693: Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
1694: return TCL_ERROR;
1695: }else if( objc==2 ){
1696: if( pDb->zAuth ){
1697: Tcl_AppendResult(interp, pDb->zAuth, 0);
1698: }
1699: }else{
1700: char *zAuth;
1701: int len;
1702: if( pDb->zAuth ){
1703: Tcl_Free(pDb->zAuth);
1704: }
1705: zAuth = Tcl_GetStringFromObj(objv[2], &len);
1706: if( zAuth && len>0 ){
1707: pDb->zAuth = Tcl_Alloc( len + 1 );
1708: memcpy(pDb->zAuth, zAuth, len+1);
1709: }else{
1710: pDb->zAuth = 0;
1711: }
1712: if( pDb->zAuth ){
1713: pDb->interp = interp;
1714: sqlite3_set_authorizer(pDb->db, auth_callback, pDb);
1715: }else{
1716: sqlite3_set_authorizer(pDb->db, 0, 0);
1717: }
1718: }
1719: #endif
1720: break;
1721: }
1722:
1723: /* $db backup ?DATABASE? FILENAME
1724: **
1725: ** Open or create a database file named FILENAME. Transfer the
1726: ** content of local database DATABASE (default: "main") into the
1727: ** FILENAME database.
1728: */
1729: case DB_BACKUP: {
1730: const char *zDestFile;
1731: const char *zSrcDb;
1732: sqlite3 *pDest;
1733: sqlite3_backup *pBackup;
1734:
1735: if( objc==3 ){
1736: zSrcDb = "main";
1737: zDestFile = Tcl_GetString(objv[2]);
1738: }else if( objc==4 ){
1739: zSrcDb = Tcl_GetString(objv[2]);
1740: zDestFile = Tcl_GetString(objv[3]);
1741: }else{
1742: Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME");
1743: return TCL_ERROR;
1744: }
1745: rc = sqlite3_open(zDestFile, &pDest);
1746: if( rc!=SQLITE_OK ){
1747: Tcl_AppendResult(interp, "cannot open target database: ",
1748: sqlite3_errmsg(pDest), (char*)0);
1749: sqlite3_close(pDest);
1750: return TCL_ERROR;
1751: }
1752: pBackup = sqlite3_backup_init(pDest, "main", pDb->db, zSrcDb);
1753: if( pBackup==0 ){
1754: Tcl_AppendResult(interp, "backup failed: ",
1755: sqlite3_errmsg(pDest), (char*)0);
1756: sqlite3_close(pDest);
1757: return TCL_ERROR;
1758: }
1759: while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
1760: sqlite3_backup_finish(pBackup);
1761: if( rc==SQLITE_DONE ){
1762: rc = TCL_OK;
1763: }else{
1764: Tcl_AppendResult(interp, "backup failed: ",
1765: sqlite3_errmsg(pDest), (char*)0);
1766: rc = TCL_ERROR;
1767: }
1768: sqlite3_close(pDest);
1769: break;
1770: }
1771:
1772: /* $db busy ?CALLBACK?
1773: **
1774: ** Invoke the given callback if an SQL statement attempts to open
1775: ** a locked database file.
1776: */
1777: case DB_BUSY: {
1778: if( objc>3 ){
1779: Tcl_WrongNumArgs(interp, 2, objv, "CALLBACK");
1780: return TCL_ERROR;
1781: }else if( objc==2 ){
1782: if( pDb->zBusy ){
1783: Tcl_AppendResult(interp, pDb->zBusy, 0);
1784: }
1785: }else{
1786: char *zBusy;
1787: int len;
1788: if( pDb->zBusy ){
1789: Tcl_Free(pDb->zBusy);
1790: }
1791: zBusy = Tcl_GetStringFromObj(objv[2], &len);
1792: if( zBusy && len>0 ){
1793: pDb->zBusy = Tcl_Alloc( len + 1 );
1794: memcpy(pDb->zBusy, zBusy, len+1);
1795: }else{
1796: pDb->zBusy = 0;
1797: }
1798: if( pDb->zBusy ){
1799: pDb->interp = interp;
1800: sqlite3_busy_handler(pDb->db, DbBusyHandler, pDb);
1801: }else{
1802: sqlite3_busy_handler(pDb->db, 0, 0);
1803: }
1804: }
1805: break;
1806: }
1807:
1808: /* $db cache flush
1809: ** $db cache size n
1810: **
1811: ** Flush the prepared statement cache, or set the maximum number of
1812: ** cached statements.
1813: */
1814: case DB_CACHE: {
1815: char *subCmd;
1816: int n;
1817:
1818: if( objc<=2 ){
1819: Tcl_WrongNumArgs(interp, 1, objv, "cache option ?arg?");
1820: return TCL_ERROR;
1821: }
1822: subCmd = Tcl_GetStringFromObj( objv[2], 0 );
1823: if( *subCmd=='f' && strcmp(subCmd,"flush")==0 ){
1824: if( objc!=3 ){
1825: Tcl_WrongNumArgs(interp, 2, objv, "flush");
1826: return TCL_ERROR;
1827: }else{
1828: flushStmtCache( pDb );
1829: }
1830: }else if( *subCmd=='s' && strcmp(subCmd,"size")==0 ){
1831: if( objc!=4 ){
1832: Tcl_WrongNumArgs(interp, 2, objv, "size n");
1833: return TCL_ERROR;
1834: }else{
1835: if( TCL_ERROR==Tcl_GetIntFromObj(interp, objv[3], &n) ){
1836: Tcl_AppendResult( interp, "cannot convert \"",
1837: Tcl_GetStringFromObj(objv[3],0), "\" to integer", 0);
1838: return TCL_ERROR;
1839: }else{
1840: if( n<0 ){
1841: flushStmtCache( pDb );
1842: n = 0;
1843: }else if( n>MAX_PREPARED_STMTS ){
1844: n = MAX_PREPARED_STMTS;
1845: }
1846: pDb->maxStmt = n;
1847: }
1848: }
1849: }else{
1850: Tcl_AppendResult( interp, "bad option \"",
1851: Tcl_GetStringFromObj(objv[2],0), "\": must be flush or size", 0);
1852: return TCL_ERROR;
1853: }
1854: break;
1855: }
1856:
1857: /* $db changes
1858: **
1859: ** Return the number of rows that were modified, inserted, or deleted by
1860: ** the most recent INSERT, UPDATE or DELETE statement, not including
1861: ** any changes made by trigger programs.
1862: */
1863: case DB_CHANGES: {
1864: Tcl_Obj *pResult;
1865: if( objc!=2 ){
1866: Tcl_WrongNumArgs(interp, 2, objv, "");
1867: return TCL_ERROR;
1868: }
1869: pResult = Tcl_GetObjResult(interp);
1870: Tcl_SetIntObj(pResult, sqlite3_changes(pDb->db));
1871: break;
1872: }
1873:
1874: /* $db close
1875: **
1876: ** Shutdown the database
1877: */
1878: case DB_CLOSE: {
1879: Tcl_DeleteCommand(interp, Tcl_GetStringFromObj(objv[0], 0));
1880: break;
1881: }
1882:
1883: /*
1884: ** $db collate NAME SCRIPT
1885: **
1886: ** Create a new SQL collation function called NAME. Whenever
1887: ** that function is called, invoke SCRIPT to evaluate the function.
1888: */
1889: case DB_COLLATE: {
1890: SqlCollate *pCollate;
1891: char *zName;
1892: char *zScript;
1893: int nScript;
1894: if( objc!=4 ){
1895: Tcl_WrongNumArgs(interp, 2, objv, "NAME SCRIPT");
1896: return TCL_ERROR;
1897: }
1898: zName = Tcl_GetStringFromObj(objv[2], 0);
1899: zScript = Tcl_GetStringFromObj(objv[3], &nScript);
1900: pCollate = (SqlCollate*)Tcl_Alloc( sizeof(*pCollate) + nScript + 1 );
1901: if( pCollate==0 ) return TCL_ERROR;
1902: pCollate->interp = interp;
1903: pCollate->pNext = pDb->pCollate;
1904: pCollate->zScript = (char*)&pCollate[1];
1905: pDb->pCollate = pCollate;
1906: memcpy(pCollate->zScript, zScript, nScript+1);
1907: if( sqlite3_create_collation(pDb->db, zName, SQLITE_UTF8,
1908: pCollate, tclSqlCollate) ){
1909: Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
1910: return TCL_ERROR;
1911: }
1912: break;
1913: }
1914:
1915: /*
1916: ** $db collation_needed SCRIPT
1917: **
1918: ** Create a new SQL collation function called NAME. Whenever
1919: ** that function is called, invoke SCRIPT to evaluate the function.
1920: */
1921: case DB_COLLATION_NEEDED: {
1922: if( objc!=3 ){
1923: Tcl_WrongNumArgs(interp, 2, objv, "SCRIPT");
1924: return TCL_ERROR;
1925: }
1926: if( pDb->pCollateNeeded ){
1927: Tcl_DecrRefCount(pDb->pCollateNeeded);
1928: }
1929: pDb->pCollateNeeded = Tcl_DuplicateObj(objv[2]);
1930: Tcl_IncrRefCount(pDb->pCollateNeeded);
1931: sqlite3_collation_needed(pDb->db, pDb, tclCollateNeeded);
1932: break;
1933: }
1934:
1935: /* $db commit_hook ?CALLBACK?
1936: **
1937: ** Invoke the given callback just before committing every SQL transaction.
1938: ** If the callback throws an exception or returns non-zero, then the
1939: ** transaction is aborted. If CALLBACK is an empty string, the callback
1940: ** is disabled.
1941: */
1942: case DB_COMMIT_HOOK: {
1943: if( objc>3 ){
1944: Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
1945: return TCL_ERROR;
1946: }else if( objc==2 ){
1947: if( pDb->zCommit ){
1948: Tcl_AppendResult(interp, pDb->zCommit, 0);
1949: }
1950: }else{
1951: char *zCommit;
1952: int len;
1953: if( pDb->zCommit ){
1954: Tcl_Free(pDb->zCommit);
1955: }
1956: zCommit = Tcl_GetStringFromObj(objv[2], &len);
1957: if( zCommit && len>0 ){
1958: pDb->zCommit = Tcl_Alloc( len + 1 );
1959: memcpy(pDb->zCommit, zCommit, len+1);
1960: }else{
1961: pDb->zCommit = 0;
1962: }
1963: if( pDb->zCommit ){
1964: pDb->interp = interp;
1965: sqlite3_commit_hook(pDb->db, DbCommitHandler, pDb);
1966: }else{
1967: sqlite3_commit_hook(pDb->db, 0, 0);
1968: }
1969: }
1970: break;
1971: }
1972:
1973: /* $db complete SQL
1974: **
1975: ** Return TRUE if SQL is a complete SQL statement. Return FALSE if
1976: ** additional lines of input are needed. This is similar to the
1977: ** built-in "info complete" command of Tcl.
1978: */
1979: case DB_COMPLETE: {
1980: #ifndef SQLITE_OMIT_COMPLETE
1981: Tcl_Obj *pResult;
1982: int isComplete;
1983: if( objc!=3 ){
1984: Tcl_WrongNumArgs(interp, 2, objv, "SQL");
1985: return TCL_ERROR;
1986: }
1987: isComplete = sqlite3_complete( Tcl_GetStringFromObj(objv[2], 0) );
1988: pResult = Tcl_GetObjResult(interp);
1989: Tcl_SetBooleanObj(pResult, isComplete);
1990: #endif
1991: break;
1992: }
1993:
1994: /* $db copy conflict-algorithm table filename ?SEPARATOR? ?NULLINDICATOR?
1995: **
1996: ** Copy data into table from filename, optionally using SEPARATOR
1997: ** as column separators. If a column contains a null string, or the
1998: ** value of NULLINDICATOR, a NULL is inserted for the column.
1999: ** conflict-algorithm is one of the sqlite conflict algorithms:
2000: ** rollback, abort, fail, ignore, replace
2001: ** On success, return the number of lines processed, not necessarily same
2002: ** as 'db changes' due to conflict-algorithm selected.
2003: **
2004: ** This code is basically an implementation/enhancement of
2005: ** the sqlite3 shell.c ".import" command.
2006: **
2007: ** This command usage is equivalent to the sqlite2.x COPY statement,
2008: ** which imports file data into a table using the PostgreSQL COPY file format:
2009: ** $db copy $conflit_algo $table_name $filename \t \\N
2010: */
2011: case DB_COPY: {
2012: char *zTable; /* Insert data into this table */
2013: char *zFile; /* The file from which to extract data */
2014: char *zConflict; /* The conflict algorithm to use */
2015: sqlite3_stmt *pStmt; /* A statement */
2016: int nCol; /* Number of columns in the table */
2017: int nByte; /* Number of bytes in an SQL string */
2018: int i, j; /* Loop counters */
2019: int nSep; /* Number of bytes in zSep[] */
2020: int nNull; /* Number of bytes in zNull[] */
2021: char *zSql; /* An SQL statement */
2022: char *zLine; /* A single line of input from the file */
2023: char **azCol; /* zLine[] broken up into columns */
2024: char *zCommit; /* How to commit changes */
2025: FILE *in; /* The input file */
2026: int lineno = 0; /* Line number of input file */
2027: char zLineNum[80]; /* Line number print buffer */
2028: Tcl_Obj *pResult; /* interp result */
2029:
2030: char *zSep;
2031: char *zNull;
2032: if( objc<5 || objc>7 ){
2033: Tcl_WrongNumArgs(interp, 2, objv,
2034: "CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?");
2035: return TCL_ERROR;
2036: }
2037: if( objc>=6 ){
2038: zSep = Tcl_GetStringFromObj(objv[5], 0);
2039: }else{
2040: zSep = "\t";
2041: }
2042: if( objc>=7 ){
2043: zNull = Tcl_GetStringFromObj(objv[6], 0);
2044: }else{
2045: zNull = "";
2046: }
2047: zConflict = Tcl_GetStringFromObj(objv[2], 0);
2048: zTable = Tcl_GetStringFromObj(objv[3], 0);
2049: zFile = Tcl_GetStringFromObj(objv[4], 0);
2050: nSep = strlen30(zSep);
2051: nNull = strlen30(zNull);
2052: if( nSep==0 ){
2053: Tcl_AppendResult(interp,"Error: non-null separator required for copy",0);
2054: return TCL_ERROR;
2055: }
2056: if(strcmp(zConflict, "rollback") != 0 &&
2057: strcmp(zConflict, "abort" ) != 0 &&
2058: strcmp(zConflict, "fail" ) != 0 &&
2059: strcmp(zConflict, "ignore" ) != 0 &&
2060: strcmp(zConflict, "replace" ) != 0 ) {
2061: Tcl_AppendResult(interp, "Error: \"", zConflict,
2062: "\", conflict-algorithm must be one of: rollback, "
2063: "abort, fail, ignore, or replace", 0);
2064: return TCL_ERROR;
2065: }
2066: zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
2067: if( zSql==0 ){
2068: Tcl_AppendResult(interp, "Error: no such table: ", zTable, 0);
2069: return TCL_ERROR;
2070: }
2071: nByte = strlen30(zSql);
2072: rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0);
2073: sqlite3_free(zSql);
2074: if( rc ){
2075: Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), 0);
2076: nCol = 0;
2077: }else{
2078: nCol = sqlite3_column_count(pStmt);
2079: }
2080: sqlite3_finalize(pStmt);
2081: if( nCol==0 ) {
2082: return TCL_ERROR;
2083: }
2084: zSql = malloc( nByte + 50 + nCol*2 );
2085: if( zSql==0 ) {
2086: Tcl_AppendResult(interp, "Error: can't malloc()", 0);
2087: return TCL_ERROR;
2088: }
2089: sqlite3_snprintf(nByte+50, zSql, "INSERT OR %q INTO '%q' VALUES(?",
2090: zConflict, zTable);
2091: j = strlen30(zSql);
2092: for(i=1; i<nCol; i++){
2093: zSql[j++] = ',';
2094: zSql[j++] = '?';
2095: }
2096: zSql[j++] = ')';
2097: zSql[j] = 0;
2098: rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0);
2099: free(zSql);
2100: if( rc ){
2101: Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), 0);
2102: sqlite3_finalize(pStmt);
2103: return TCL_ERROR;
2104: }
2105: in = fopen(zFile, "rb");
2106: if( in==0 ){
2107: Tcl_AppendResult(interp, "Error: cannot open file: ", zFile, NULL);
2108: sqlite3_finalize(pStmt);
2109: return TCL_ERROR;
2110: }
2111: azCol = malloc( sizeof(azCol[0])*(nCol+1) );
2112: if( azCol==0 ) {
2113: Tcl_AppendResult(interp, "Error: can't malloc()", 0);
2114: fclose(in);
2115: return TCL_ERROR;
2116: }
2117: (void)sqlite3_exec(pDb->db, "BEGIN", 0, 0, 0);
2118: zCommit = "COMMIT";
2119: while( (zLine = local_getline(0, in))!=0 ){
2120: char *z;
2121: lineno++;
2122: azCol[0] = zLine;
2123: for(i=0, z=zLine; *z; z++){
2124: if( *z==zSep[0] && strncmp(z, zSep, nSep)==0 ){
2125: *z = 0;
2126: i++;
2127: if( i<nCol ){
2128: azCol[i] = &z[nSep];
2129: z += nSep-1;
2130: }
2131: }
2132: }
2133: if( i+1!=nCol ){
2134: char *zErr;
2135: int nErr = strlen30(zFile) + 200;
2136: zErr = malloc(nErr);
2137: if( zErr ){
2138: sqlite3_snprintf(nErr, zErr,
2139: "Error: %s line %d: expected %d columns of data but found %d",
2140: zFile, lineno, nCol, i+1);
2141: Tcl_AppendResult(interp, zErr, 0);
2142: free(zErr);
2143: }
2144: zCommit = "ROLLBACK";
2145: break;
2146: }
2147: for(i=0; i<nCol; i++){
2148: /* check for null data, if so, bind as null */
2149: if( (nNull>0 && strcmp(azCol[i], zNull)==0)
2150: || strlen30(azCol[i])==0
2151: ){
2152: sqlite3_bind_null(pStmt, i+1);
2153: }else{
2154: sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
2155: }
2156: }
2157: sqlite3_step(pStmt);
2158: rc = sqlite3_reset(pStmt);
2159: free(zLine);
2160: if( rc!=SQLITE_OK ){
2161: Tcl_AppendResult(interp,"Error: ", sqlite3_errmsg(pDb->db), 0);
2162: zCommit = "ROLLBACK";
2163: break;
2164: }
2165: }
2166: free(azCol);
2167: fclose(in);
2168: sqlite3_finalize(pStmt);
2169: (void)sqlite3_exec(pDb->db, zCommit, 0, 0, 0);
2170:
2171: if( zCommit[0] == 'C' ){
2172: /* success, set result as number of lines processed */
2173: pResult = Tcl_GetObjResult(interp);
2174: Tcl_SetIntObj(pResult, lineno);
2175: rc = TCL_OK;
2176: }else{
2177: /* failure, append lineno where failed */
2178: sqlite3_snprintf(sizeof(zLineNum), zLineNum,"%d",lineno);
2179: Tcl_AppendResult(interp,", failed while processing line: ",zLineNum,0);
2180: rc = TCL_ERROR;
2181: }
2182: break;
2183: }
2184:
2185: /*
2186: ** $db enable_load_extension BOOLEAN
2187: **
2188: ** Turn the extension loading feature on or off. It if off by
2189: ** default.
2190: */
2191: case DB_ENABLE_LOAD_EXTENSION: {
2192: #ifndef SQLITE_OMIT_LOAD_EXTENSION
2193: int onoff;
2194: if( objc!=3 ){
2195: Tcl_WrongNumArgs(interp, 2, objv, "BOOLEAN");
2196: return TCL_ERROR;
2197: }
2198: if( Tcl_GetBooleanFromObj(interp, objv[2], &onoff) ){
2199: return TCL_ERROR;
2200: }
2201: sqlite3_enable_load_extension(pDb->db, onoff);
2202: break;
2203: #else
2204: Tcl_AppendResult(interp, "extension loading is turned off at compile-time",
2205: 0);
2206: return TCL_ERROR;
2207: #endif
2208: }
2209:
2210: /*
2211: ** $db errorcode
2212: **
2213: ** Return the numeric error code that was returned by the most recent
2214: ** call to sqlite3_exec().
2215: */
2216: case DB_ERRORCODE: {
2217: Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_errcode(pDb->db)));
2218: break;
2219: }
2220:
2221: /*
2222: ** $db exists $sql
2223: ** $db onecolumn $sql
2224: **
2225: ** The onecolumn method is the equivalent of:
2226: ** lindex [$db eval $sql] 0
2227: */
2228: case DB_EXISTS:
2229: case DB_ONECOLUMN: {
2230: DbEvalContext sEval;
2231: if( objc!=3 ){
2232: Tcl_WrongNumArgs(interp, 2, objv, "SQL");
2233: return TCL_ERROR;
2234: }
2235:
2236: dbEvalInit(&sEval, pDb, objv[2], 0);
2237: rc = dbEvalStep(&sEval);
2238: if( choice==DB_ONECOLUMN ){
2239: if( rc==TCL_OK ){
2240: Tcl_SetObjResult(interp, dbEvalColumnValue(&sEval, 0));
2241: }else if( rc==TCL_BREAK ){
2242: Tcl_ResetResult(interp);
2243: }
2244: }else if( rc==TCL_BREAK || rc==TCL_OK ){
2245: Tcl_SetObjResult(interp, Tcl_NewBooleanObj(rc==TCL_OK));
2246: }
2247: dbEvalFinalize(&sEval);
2248:
2249: if( rc==TCL_BREAK ){
2250: rc = TCL_OK;
2251: }
2252: break;
2253: }
2254:
2255: /*
2256: ** $db eval $sql ?array? ?{ ...code... }?
2257: **
2258: ** The SQL statement in $sql is evaluated. For each row, the values are
2259: ** placed in elements of the array named "array" and ...code... is executed.
2260: ** If "array" and "code" are omitted, then no callback is every invoked.
2261: ** If "array" is an empty string, then the values are placed in variables
2262: ** that have the same name as the fields extracted by the query.
2263: */
2264: case DB_EVAL: {
2265: if( objc<3 || objc>5 ){
2266: Tcl_WrongNumArgs(interp, 2, objv, "SQL ?ARRAY-NAME? ?SCRIPT?");
2267: return TCL_ERROR;
2268: }
2269:
2270: if( objc==3 ){
2271: DbEvalContext sEval;
2272: Tcl_Obj *pRet = Tcl_NewObj();
2273: Tcl_IncrRefCount(pRet);
2274: dbEvalInit(&sEval, pDb, objv[2], 0);
2275: while( TCL_OK==(rc = dbEvalStep(&sEval)) ){
2276: int i;
2277: int nCol;
2278: dbEvalRowInfo(&sEval, &nCol, 0);
2279: for(i=0; i<nCol; i++){
2280: Tcl_ListObjAppendElement(interp, pRet, dbEvalColumnValue(&sEval, i));
2281: }
2282: }
2283: dbEvalFinalize(&sEval);
2284: if( rc==TCL_BREAK ){
2285: Tcl_SetObjResult(interp, pRet);
2286: rc = TCL_OK;
2287: }
2288: Tcl_DecrRefCount(pRet);
2289: }else{
2290: ClientData cd[2];
2291: DbEvalContext *p;
2292: Tcl_Obj *pArray = 0;
2293: Tcl_Obj *pScript;
2294:
2295: if( objc==5 && *(char *)Tcl_GetString(objv[3]) ){
2296: pArray = objv[3];
2297: }
2298: pScript = objv[objc-1];
2299: Tcl_IncrRefCount(pScript);
2300:
2301: p = (DbEvalContext *)Tcl_Alloc(sizeof(DbEvalContext));
2302: dbEvalInit(p, pDb, objv[2], pArray);
2303:
2304: cd[0] = (void *)p;
2305: cd[1] = (void *)pScript;
2306: rc = DbEvalNextCmd(cd, interp, TCL_OK);
2307: }
2308: break;
2309: }
2310:
2311: /*
2312: ** $db function NAME [-argcount N] SCRIPT
2313: **
2314: ** Create a new SQL function called NAME. Whenever that function is
2315: ** called, invoke SCRIPT to evaluate the function.
2316: */
2317: case DB_FUNCTION: {
2318: SqlFunc *pFunc;
2319: Tcl_Obj *pScript;
2320: char *zName;
2321: int nArg = -1;
2322: if( objc==6 ){
2323: const char *z = Tcl_GetString(objv[3]);
2324: int n = strlen30(z);
2325: if( n>2 && strncmp(z, "-argcount",n)==0 ){
2326: if( Tcl_GetIntFromObj(interp, objv[4], &nArg) ) return TCL_ERROR;
2327: if( nArg<0 ){
2328: Tcl_AppendResult(interp, "number of arguments must be non-negative",
2329: (char*)0);
2330: return TCL_ERROR;
2331: }
2332: }
2333: pScript = objv[5];
2334: }else if( objc!=4 ){
2335: Tcl_WrongNumArgs(interp, 2, objv, "NAME [-argcount N] SCRIPT");
2336: return TCL_ERROR;
2337: }else{
2338: pScript = objv[3];
2339: }
2340: zName = Tcl_GetStringFromObj(objv[2], 0);
2341: pFunc = findSqlFunc(pDb, zName);
2342: if( pFunc==0 ) return TCL_ERROR;
2343: if( pFunc->pScript ){
2344: Tcl_DecrRefCount(pFunc->pScript);
2345: }
2346: pFunc->pScript = pScript;
2347: Tcl_IncrRefCount(pScript);
2348: pFunc->useEvalObjv = safeToUseEvalObjv(interp, pScript);
2349: rc = sqlite3_create_function(pDb->db, zName, nArg, SQLITE_UTF8,
2350: pFunc, tclSqlFunc, 0, 0);
2351: if( rc!=SQLITE_OK ){
2352: rc = TCL_ERROR;
2353: Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
2354: }
2355: break;
2356: }
2357:
2358: /*
2359: ** $db incrblob ?-readonly? ?DB? TABLE COLUMN ROWID
2360: */
2361: case DB_INCRBLOB: {
2362: #ifdef SQLITE_OMIT_INCRBLOB
2363: Tcl_AppendResult(interp, "incrblob not available in this build", 0);
2364: return TCL_ERROR;
2365: #else
2366: int isReadonly = 0;
2367: const char *zDb = "main";
2368: const char *zTable;
2369: const char *zColumn;
2370: sqlite_int64 iRow;
2371:
2372: /* Check for the -readonly option */
2373: if( objc>3 && strcmp(Tcl_GetString(objv[2]), "-readonly")==0 ){
2374: isReadonly = 1;
2375: }
2376:
2377: if( objc!=(5+isReadonly) && objc!=(6+isReadonly) ){
2378: Tcl_WrongNumArgs(interp, 2, objv, "?-readonly? ?DB? TABLE COLUMN ROWID");
2379: return TCL_ERROR;
2380: }
2381:
2382: if( objc==(6+isReadonly) ){
2383: zDb = Tcl_GetString(objv[2]);
2384: }
2385: zTable = Tcl_GetString(objv[objc-3]);
2386: zColumn = Tcl_GetString(objv[objc-2]);
2387: rc = Tcl_GetWideIntFromObj(interp, objv[objc-1], &iRow);
2388:
2389: if( rc==TCL_OK ){
2390: rc = createIncrblobChannel(
2391: interp, pDb, zDb, zTable, zColumn, iRow, isReadonly
2392: );
2393: }
2394: #endif
2395: break;
2396: }
2397:
2398: /*
2399: ** $db interrupt
2400: **
2401: ** Interrupt the execution of the inner-most SQL interpreter. This
2402: ** causes the SQL statement to return an error of SQLITE_INTERRUPT.
2403: */
2404: case DB_INTERRUPT: {
2405: sqlite3_interrupt(pDb->db);
2406: break;
2407: }
2408:
2409: /*
2410: ** $db nullvalue ?STRING?
2411: **
2412: ** Change text used when a NULL comes back from the database. If ?STRING?
2413: ** is not present, then the current string used for NULL is returned.
2414: ** If STRING is present, then STRING is returned.
2415: **
2416: */
2417: case DB_NULLVALUE: {
2418: if( objc!=2 && objc!=3 ){
2419: Tcl_WrongNumArgs(interp, 2, objv, "NULLVALUE");
2420: return TCL_ERROR;
2421: }
2422: if( objc==3 ){
2423: int len;
2424: char *zNull = Tcl_GetStringFromObj(objv[2], &len);
2425: if( pDb->zNull ){
2426: Tcl_Free(pDb->zNull);
2427: }
2428: if( zNull && len>0 ){
2429: pDb->zNull = Tcl_Alloc( len + 1 );
2430: memcpy(pDb->zNull, zNull, len);
2431: pDb->zNull[len] = '\0';
2432: }else{
2433: pDb->zNull = 0;
2434: }
2435: }
2436: Tcl_SetObjResult(interp, dbTextToObj(pDb->zNull));
2437: break;
2438: }
2439:
2440: /*
2441: ** $db last_insert_rowid
2442: **
2443: ** Return an integer which is the ROWID for the most recent insert.
2444: */
2445: case DB_LAST_INSERT_ROWID: {
2446: Tcl_Obj *pResult;
2447: Tcl_WideInt rowid;
2448: if( objc!=2 ){
2449: Tcl_WrongNumArgs(interp, 2, objv, "");
2450: return TCL_ERROR;
2451: }
2452: rowid = sqlite3_last_insert_rowid(pDb->db);
2453: pResult = Tcl_GetObjResult(interp);
2454: Tcl_SetWideIntObj(pResult, rowid);
2455: break;
2456: }
2457:
2458: /*
2459: ** The DB_ONECOLUMN method is implemented together with DB_EXISTS.
2460: */
2461:
2462: /* $db progress ?N CALLBACK?
2463: **
2464: ** Invoke the given callback every N virtual machine opcodes while executing
2465: ** queries.
2466: */
2467: case DB_PROGRESS: {
2468: if( objc==2 ){
2469: if( pDb->zProgress ){
2470: Tcl_AppendResult(interp, pDb->zProgress, 0);
2471: }
2472: }else if( objc==4 ){
2473: char *zProgress;
2474: int len;
2475: int N;
2476: if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &N) ){
2477: return TCL_ERROR;
2478: };
2479: if( pDb->zProgress ){
2480: Tcl_Free(pDb->zProgress);
2481: }
2482: zProgress = Tcl_GetStringFromObj(objv[3], &len);
2483: if( zProgress && len>0 ){
2484: pDb->zProgress = Tcl_Alloc( len + 1 );
2485: memcpy(pDb->zProgress, zProgress, len+1);
2486: }else{
2487: pDb->zProgress = 0;
2488: }
2489: #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
2490: if( pDb->zProgress ){
2491: pDb->interp = interp;
2492: sqlite3_progress_handler(pDb->db, N, DbProgressHandler, pDb);
2493: }else{
2494: sqlite3_progress_handler(pDb->db, 0, 0, 0);
2495: }
2496: #endif
2497: }else{
2498: Tcl_WrongNumArgs(interp, 2, objv, "N CALLBACK");
2499: return TCL_ERROR;
2500: }
2501: break;
2502: }
2503:
2504: /* $db profile ?CALLBACK?
2505: **
2506: ** Make arrangements to invoke the CALLBACK routine after each SQL statement
2507: ** that has run. The text of the SQL and the amount of elapse time are
2508: ** appended to CALLBACK before the script is run.
2509: */
2510: case DB_PROFILE: {
2511: if( objc>3 ){
2512: Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
2513: return TCL_ERROR;
2514: }else if( objc==2 ){
2515: if( pDb->zProfile ){
2516: Tcl_AppendResult(interp, pDb->zProfile, 0);
2517: }
2518: }else{
2519: char *zProfile;
2520: int len;
2521: if( pDb->zProfile ){
2522: Tcl_Free(pDb->zProfile);
2523: }
2524: zProfile = Tcl_GetStringFromObj(objv[2], &len);
2525: if( zProfile && len>0 ){
2526: pDb->zProfile = Tcl_Alloc( len + 1 );
2527: memcpy(pDb->zProfile, zProfile, len+1);
2528: }else{
2529: pDb->zProfile = 0;
2530: }
2531: #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
2532: if( pDb->zProfile ){
2533: pDb->interp = interp;
2534: sqlite3_profile(pDb->db, DbProfileHandler, pDb);
2535: }else{
2536: sqlite3_profile(pDb->db, 0, 0);
2537: }
2538: #endif
2539: }
2540: break;
2541: }
2542:
2543: /*
2544: ** $db rekey KEY
2545: **
2546: ** Change the encryption key on the currently open database.
2547: */
2548: case DB_REKEY: {
2549: #ifdef SQLITE_HAS_CODEC
2550: int nKey;
2551: void *pKey;
2552: #endif
2553: if( objc!=3 ){
2554: Tcl_WrongNumArgs(interp, 2, objv, "KEY");
2555: return TCL_ERROR;
2556: }
2557: #ifdef SQLITE_HAS_CODEC
2558: pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey);
2559: rc = sqlite3_rekey(pDb->db, pKey, nKey);
2560: if( rc ){
2561: Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0);
2562: rc = TCL_ERROR;
2563: }
2564: #endif
2565: break;
2566: }
2567:
2568: /* $db restore ?DATABASE? FILENAME
2569: **
2570: ** Open a database file named FILENAME. Transfer the content
2571: ** of FILENAME into the local database DATABASE (default: "main").
2572: */
2573: case DB_RESTORE: {
2574: const char *zSrcFile;
2575: const char *zDestDb;
2576: sqlite3 *pSrc;
2577: sqlite3_backup *pBackup;
2578: int nTimeout = 0;
2579:
2580: if( objc==3 ){
2581: zDestDb = "main";
2582: zSrcFile = Tcl_GetString(objv[2]);
2583: }else if( objc==4 ){
2584: zDestDb = Tcl_GetString(objv[2]);
2585: zSrcFile = Tcl_GetString(objv[3]);
2586: }else{
2587: Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME");
2588: return TCL_ERROR;
2589: }
2590: rc = sqlite3_open_v2(zSrcFile, &pSrc, SQLITE_OPEN_READONLY, 0);
2591: if( rc!=SQLITE_OK ){
2592: Tcl_AppendResult(interp, "cannot open source database: ",
2593: sqlite3_errmsg(pSrc), (char*)0);
2594: sqlite3_close(pSrc);
2595: return TCL_ERROR;
2596: }
2597: pBackup = sqlite3_backup_init(pDb->db, zDestDb, pSrc, "main");
2598: if( pBackup==0 ){
2599: Tcl_AppendResult(interp, "restore failed: ",
2600: sqlite3_errmsg(pDb->db), (char*)0);
2601: sqlite3_close(pSrc);
2602: return TCL_ERROR;
2603: }
2604: while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
2605: || rc==SQLITE_BUSY ){
2606: if( rc==SQLITE_BUSY ){
2607: if( nTimeout++ >= 3 ) break;
2608: sqlite3_sleep(100);
2609: }
2610: }
2611: sqlite3_backup_finish(pBackup);
2612: if( rc==SQLITE_DONE ){
2613: rc = TCL_OK;
2614: }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
2615: Tcl_AppendResult(interp, "restore failed: source database busy",
2616: (char*)0);
2617: rc = TCL_ERROR;
2618: }else{
2619: Tcl_AppendResult(interp, "restore failed: ",
2620: sqlite3_errmsg(pDb->db), (char*)0);
2621: rc = TCL_ERROR;
2622: }
2623: sqlite3_close(pSrc);
2624: break;
2625: }
2626:
2627: /*
2628: ** $db status (step|sort|autoindex)
2629: **
2630: ** Display SQLITE_STMTSTATUS_FULLSCAN_STEP or
2631: ** SQLITE_STMTSTATUS_SORT for the most recent eval.
2632: */
2633: case DB_STATUS: {
2634: int v;
2635: const char *zOp;
2636: if( objc!=3 ){
2637: Tcl_WrongNumArgs(interp, 2, objv, "(step|sort|autoindex)");
2638: return TCL_ERROR;
2639: }
2640: zOp = Tcl_GetString(objv[2]);
2641: if( strcmp(zOp, "step")==0 ){
2642: v = pDb->nStep;
2643: }else if( strcmp(zOp, "sort")==0 ){
2644: v = pDb->nSort;
2645: }else if( strcmp(zOp, "autoindex")==0 ){
2646: v = pDb->nIndex;
2647: }else{
2648: Tcl_AppendResult(interp,
2649: "bad argument: should be autoindex, step, or sort",
2650: (char*)0);
2651: return TCL_ERROR;
2652: }
2653: Tcl_SetObjResult(interp, Tcl_NewIntObj(v));
2654: break;
2655: }
2656:
2657: /*
2658: ** $db timeout MILLESECONDS
2659: **
2660: ** Delay for the number of milliseconds specified when a file is locked.
2661: */
2662: case DB_TIMEOUT: {
2663: int ms;
2664: if( objc!=3 ){
2665: Tcl_WrongNumArgs(interp, 2, objv, "MILLISECONDS");
2666: return TCL_ERROR;
2667: }
2668: if( Tcl_GetIntFromObj(interp, objv[2], &ms) ) return TCL_ERROR;
2669: sqlite3_busy_timeout(pDb->db, ms);
2670: break;
2671: }
2672:
2673: /*
2674: ** $db total_changes
2675: **
2676: ** Return the number of rows that were modified, inserted, or deleted
2677: ** since the database handle was created.
2678: */
2679: case DB_TOTAL_CHANGES: {
2680: Tcl_Obj *pResult;
2681: if( objc!=2 ){
2682: Tcl_WrongNumArgs(interp, 2, objv, "");
2683: return TCL_ERROR;
2684: }
2685: pResult = Tcl_GetObjResult(interp);
2686: Tcl_SetIntObj(pResult, sqlite3_total_changes(pDb->db));
2687: break;
2688: }
2689:
2690: /* $db trace ?CALLBACK?
2691: **
2692: ** Make arrangements to invoke the CALLBACK routine for each SQL statement
2693: ** that is executed. The text of the SQL is appended to CALLBACK before
2694: ** it is executed.
2695: */
2696: case DB_TRACE: {
2697: if( objc>3 ){
2698: Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
2699: return TCL_ERROR;
2700: }else if( objc==2 ){
2701: if( pDb->zTrace ){
2702: Tcl_AppendResult(interp, pDb->zTrace, 0);
2703: }
2704: }else{
2705: char *zTrace;
2706: int len;
2707: if( pDb->zTrace ){
2708: Tcl_Free(pDb->zTrace);
2709: }
2710: zTrace = Tcl_GetStringFromObj(objv[2], &len);
2711: if( zTrace && len>0 ){
2712: pDb->zTrace = Tcl_Alloc( len + 1 );
2713: memcpy(pDb->zTrace, zTrace, len+1);
2714: }else{
2715: pDb->zTrace = 0;
2716: }
2717: #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
2718: if( pDb->zTrace ){
2719: pDb->interp = interp;
2720: sqlite3_trace(pDb->db, DbTraceHandler, pDb);
2721: }else{
2722: sqlite3_trace(pDb->db, 0, 0);
2723: }
2724: #endif
2725: }
2726: break;
2727: }
2728:
2729: /* $db transaction [-deferred|-immediate|-exclusive] SCRIPT
2730: **
2731: ** Start a new transaction (if we are not already in the midst of a
2732: ** transaction) and execute the TCL script SCRIPT. After SCRIPT
2733: ** completes, either commit the transaction or roll it back if SCRIPT
2734: ** throws an exception. Or if no new transation was started, do nothing.
2735: ** pass the exception on up the stack.
2736: **
2737: ** This command was inspired by Dave Thomas's talk on Ruby at the
2738: ** 2005 O'Reilly Open Source Convention (OSCON).
2739: */
2740: case DB_TRANSACTION: {
2741: Tcl_Obj *pScript;
2742: const char *zBegin = "SAVEPOINT _tcl_transaction";
2743: if( objc!=3 && objc!=4 ){
2744: Tcl_WrongNumArgs(interp, 2, objv, "[TYPE] SCRIPT");
2745: return TCL_ERROR;
2746: }
2747:
2748: if( pDb->nTransaction==0 && objc==4 ){
2749: static const char *TTYPE_strs[] = {
2750: "deferred", "exclusive", "immediate", 0
2751: };
2752: enum TTYPE_enum {
2753: TTYPE_DEFERRED, TTYPE_EXCLUSIVE, TTYPE_IMMEDIATE
2754: };
2755: int ttype;
2756: if( Tcl_GetIndexFromObj(interp, objv[2], TTYPE_strs, "transaction type",
2757: 0, &ttype) ){
2758: return TCL_ERROR;
2759: }
2760: switch( (enum TTYPE_enum)ttype ){
2761: case TTYPE_DEFERRED: /* no-op */; break;
2762: case TTYPE_EXCLUSIVE: zBegin = "BEGIN EXCLUSIVE"; break;
2763: case TTYPE_IMMEDIATE: zBegin = "BEGIN IMMEDIATE"; break;
2764: }
2765: }
2766: pScript = objv[objc-1];
2767:
2768: /* Run the SQLite BEGIN command to open a transaction or savepoint. */
2769: pDb->disableAuth++;
2770: rc = sqlite3_exec(pDb->db, zBegin, 0, 0, 0);
2771: pDb->disableAuth--;
2772: if( rc!=SQLITE_OK ){
2773: Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0);
2774: return TCL_ERROR;
2775: }
2776: pDb->nTransaction++;
2777:
2778: /* If using NRE, schedule a callback to invoke the script pScript, then
2779: ** a second callback to commit (or rollback) the transaction or savepoint
2780: ** opened above. If not using NRE, evaluate the script directly, then
2781: ** call function DbTransPostCmd() to commit (or rollback) the transaction
2782: ** or savepoint. */
2783: if( DbUseNre() ){
2784: Tcl_NRAddCallback(interp, DbTransPostCmd, cd, 0, 0, 0);
2785: Tcl_NREvalObj(interp, pScript, 0);
2786: }else{
2787: rc = DbTransPostCmd(&cd, interp, Tcl_EvalObjEx(interp, pScript, 0));
2788: }
2789: break;
2790: }
2791:
2792: /*
2793: ** $db unlock_notify ?script?
2794: */
2795: case DB_UNLOCK_NOTIFY: {
2796: #ifndef SQLITE_ENABLE_UNLOCK_NOTIFY
2797: Tcl_AppendResult(interp, "unlock_notify not available in this build", 0);
2798: rc = TCL_ERROR;
2799: #else
2800: if( objc!=2 && objc!=3 ){
2801: Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?");
2802: rc = TCL_ERROR;
2803: }else{
2804: void (*xNotify)(void **, int) = 0;
2805: void *pNotifyArg = 0;
2806:
2807: if( pDb->pUnlockNotify ){
2808: Tcl_DecrRefCount(pDb->pUnlockNotify);
2809: pDb->pUnlockNotify = 0;
2810: }
2811:
2812: if( objc==3 ){
2813: xNotify = DbUnlockNotify;
2814: pNotifyArg = (void *)pDb;
2815: pDb->pUnlockNotify = objv[2];
2816: Tcl_IncrRefCount(pDb->pUnlockNotify);
2817: }
2818:
2819: if( sqlite3_unlock_notify(pDb->db, xNotify, pNotifyArg) ){
2820: Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0);
2821: rc = TCL_ERROR;
2822: }
2823: }
2824: #endif
2825: break;
2826: }
2827:
2828: /*
2829: ** $db wal_hook ?script?
2830: ** $db update_hook ?script?
2831: ** $db rollback_hook ?script?
2832: */
2833: case DB_WAL_HOOK:
2834: case DB_UPDATE_HOOK:
2835: case DB_ROLLBACK_HOOK: {
2836:
2837: /* set ppHook to point at pUpdateHook or pRollbackHook, depending on
2838: ** whether [$db update_hook] or [$db rollback_hook] was invoked.
2839: */
2840: Tcl_Obj **ppHook;
2841: if( choice==DB_UPDATE_HOOK ){
2842: ppHook = &pDb->pUpdateHook;
2843: }else if( choice==DB_WAL_HOOK ){
2844: ppHook = &pDb->pWalHook;
2845: }else{
2846: ppHook = &pDb->pRollbackHook;
2847: }
2848:
2849: if( objc!=2 && objc!=3 ){
2850: Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?");
2851: return TCL_ERROR;
2852: }
2853: if( *ppHook ){
2854: Tcl_SetObjResult(interp, *ppHook);
2855: if( objc==3 ){
2856: Tcl_DecrRefCount(*ppHook);
2857: *ppHook = 0;
2858: }
2859: }
2860: if( objc==3 ){
2861: assert( !(*ppHook) );
2862: if( Tcl_GetCharLength(objv[2])>0 ){
2863: *ppHook = objv[2];
2864: Tcl_IncrRefCount(*ppHook);
2865: }
2866: }
2867:
2868: sqlite3_update_hook(pDb->db, (pDb->pUpdateHook?DbUpdateHandler:0), pDb);
2869: sqlite3_rollback_hook(pDb->db,(pDb->pRollbackHook?DbRollbackHandler:0),pDb);
2870: sqlite3_wal_hook(pDb->db,(pDb->pWalHook?DbWalHandler:0),pDb);
2871:
2872: break;
2873: }
2874:
2875: /* $db version
2876: **
2877: ** Return the version string for this database.
2878: */
2879: case DB_VERSION: {
2880: Tcl_SetResult(interp, (char *)sqlite3_libversion(), TCL_STATIC);
2881: break;
2882: }
2883:
2884:
2885: } /* End of the SWITCH statement */
2886: return rc;
2887: }
2888:
2889: #if SQLITE_TCL_NRE
2890: /*
2891: ** Adaptor that provides an objCmd interface to the NRE-enabled
2892: ** interface implementation.
2893: */
2894: static int DbObjCmdAdaptor(
2895: void *cd,
2896: Tcl_Interp *interp,
2897: int objc,
2898: Tcl_Obj *const*objv
2899: ){
2900: return Tcl_NRCallObjProc(interp, DbObjCmd, cd, objc, objv);
2901: }
2902: #endif /* SQLITE_TCL_NRE */
2903:
2904: /*
2905: ** sqlite3 DBNAME FILENAME ?-vfs VFSNAME? ?-key KEY? ?-readonly BOOLEAN?
2906: ** ?-create BOOLEAN? ?-nomutex BOOLEAN?
2907: **
2908: ** This is the main Tcl command. When the "sqlite" Tcl command is
2909: ** invoked, this routine runs to process that command.
2910: **
2911: ** The first argument, DBNAME, is an arbitrary name for a new
2912: ** database connection. This command creates a new command named
2913: ** DBNAME that is used to control that connection. The database
2914: ** connection is deleted when the DBNAME command is deleted.
2915: **
2916: ** The second argument is the name of the database file.
2917: **
2918: */
2919: static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
2920: SqliteDb *p;
2921: const char *zArg;
2922: char *zErrMsg;
2923: int i;
2924: const char *zFile;
2925: const char *zVfs = 0;
2926: int flags;
2927: Tcl_DString translatedFilename;
2928: #ifdef SQLITE_HAS_CODEC
2929: void *pKey = 0;
2930: int nKey = 0;
2931: #endif
2932:
2933: /* In normal use, each TCL interpreter runs in a single thread. So
2934: ** by default, we can turn of mutexing on SQLite database connections.
2935: ** However, for testing purposes it is useful to have mutexes turned
2936: ** on. So, by default, mutexes default off. But if compiled with
2937: ** SQLITE_TCL_DEFAULT_FULLMUTEX then mutexes default on.
2938: */
2939: #ifdef SQLITE_TCL_DEFAULT_FULLMUTEX
2940: flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX;
2941: #else
2942: flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX;
2943: #endif
2944:
2945: if( objc==2 ){
2946: zArg = Tcl_GetStringFromObj(objv[1], 0);
2947: if( strcmp(zArg,"-version")==0 ){
2948: Tcl_AppendResult(interp,sqlite3_version,0);
2949: return TCL_OK;
2950: }
2951: if( strcmp(zArg,"-has-codec")==0 ){
2952: #ifdef SQLITE_HAS_CODEC
2953: Tcl_AppendResult(interp,"1",0);
2954: #else
2955: Tcl_AppendResult(interp,"0",0);
2956: #endif
2957: return TCL_OK;
2958: }
2959: }
2960: for(i=3; i+1<objc; i+=2){
2961: zArg = Tcl_GetString(objv[i]);
2962: if( strcmp(zArg,"-key")==0 ){
2963: #ifdef SQLITE_HAS_CODEC
2964: pKey = Tcl_GetByteArrayFromObj(objv[i+1], &nKey);
2965: #endif
2966: }else if( strcmp(zArg, "-vfs")==0 ){
2967: zVfs = Tcl_GetString(objv[i+1]);
2968: }else if( strcmp(zArg, "-readonly")==0 ){
2969: int b;
2970: if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
2971: if( b ){
2972: flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
2973: flags |= SQLITE_OPEN_READONLY;
2974: }else{
2975: flags &= ~SQLITE_OPEN_READONLY;
2976: flags |= SQLITE_OPEN_READWRITE;
2977: }
2978: }else if( strcmp(zArg, "-create")==0 ){
2979: int b;
2980: if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
2981: if( b && (flags & SQLITE_OPEN_READONLY)==0 ){
2982: flags |= SQLITE_OPEN_CREATE;
2983: }else{
2984: flags &= ~SQLITE_OPEN_CREATE;
2985: }
2986: }else if( strcmp(zArg, "-nomutex")==0 ){
2987: int b;
2988: if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
2989: if( b ){
2990: flags |= SQLITE_OPEN_NOMUTEX;
2991: flags &= ~SQLITE_OPEN_FULLMUTEX;
2992: }else{
2993: flags &= ~SQLITE_OPEN_NOMUTEX;
2994: }
2995: }else if( strcmp(zArg, "-fullmutex")==0 ){
2996: int b;
2997: if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
2998: if( b ){
2999: flags |= SQLITE_OPEN_FULLMUTEX;
3000: flags &= ~SQLITE_OPEN_NOMUTEX;
3001: }else{
3002: flags &= ~SQLITE_OPEN_FULLMUTEX;
3003: }
3004: }else if( strcmp(zArg, "-uri")==0 ){
3005: int b;
3006: if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
3007: if( b ){
3008: flags |= SQLITE_OPEN_URI;
3009: }else{
3010: flags &= ~SQLITE_OPEN_URI;
3011: }
3012: }else{
3013: Tcl_AppendResult(interp, "unknown option: ", zArg, (char*)0);
3014: return TCL_ERROR;
3015: }
3016: }
3017: if( objc<3 || (objc&1)!=1 ){
3018: Tcl_WrongNumArgs(interp, 1, objv,
3019: "HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?"
3020: " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
3021: #ifdef SQLITE_HAS_CODEC
3022: " ?-key CODECKEY?"
3023: #endif
3024: );
3025: return TCL_ERROR;
3026: }
3027: zErrMsg = 0;
3028: p = (SqliteDb*)Tcl_Alloc( sizeof(*p) );
3029: if( p==0 ){
3030: Tcl_SetResult(interp, "malloc failed", TCL_STATIC);
3031: return TCL_ERROR;
3032: }
3033: memset(p, 0, sizeof(*p));
3034: zFile = Tcl_GetStringFromObj(objv[2], 0);
3035: zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename);
3036: sqlite3_open_v2(zFile, &p->db, flags, zVfs);
3037: Tcl_DStringFree(&translatedFilename);
3038: if( SQLITE_OK!=sqlite3_errcode(p->db) ){
3039: zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db));
3040: sqlite3_close(p->db);
3041: p->db = 0;
3042: }
3043: #ifdef SQLITE_HAS_CODEC
3044: if( p->db ){
3045: sqlite3_key(p->db, pKey, nKey);
3046: }
3047: #endif
3048: if( p->db==0 ){
3049: Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE);
3050: Tcl_Free((char*)p);
3051: sqlite3_free(zErrMsg);
3052: return TCL_ERROR;
3053: }
3054: p->maxStmt = NUM_PREPARED_STMTS;
3055: p->interp = interp;
3056: zArg = Tcl_GetStringFromObj(objv[1], 0);
3057: if( DbUseNre() ){
3058: Tcl_NRCreateCommand(interp, zArg, DbObjCmdAdaptor, DbObjCmd,
3059: (char*)p, DbDeleteCmd);
3060: }else{
3061: Tcl_CreateObjCommand(interp, zArg, DbObjCmd, (char*)p, DbDeleteCmd);
3062: }
3063: return TCL_OK;
3064: }
3065:
3066: /*
3067: ** Provide a dummy Tcl_InitStubs if we are using this as a static
3068: ** library.
3069: */
3070: #ifndef USE_TCL_STUBS
3071: # undef Tcl_InitStubs
3072: # define Tcl_InitStubs(a,b,c)
3073: #endif
3074:
3075: /*
3076: ** Make sure we have a PACKAGE_VERSION macro defined. This will be
3077: ** defined automatically by the TEA makefile. But other makefiles
3078: ** do not define it.
3079: */
3080: #ifndef PACKAGE_VERSION
3081: # define PACKAGE_VERSION SQLITE_VERSION
3082: #endif
3083:
3084: /*
3085: ** Initialize this module.
3086: **
3087: ** This Tcl module contains only a single new Tcl command named "sqlite".
3088: ** (Hence there is no namespace. There is no point in using a namespace
3089: ** if the extension only supplies one new name!) The "sqlite" command is
3090: ** used to open a new SQLite database. See the DbMain() routine above
3091: ** for additional information.
3092: **
3093: ** The EXTERN macros are required by TCL in order to work on windows.
3094: */
3095: EXTERN int Sqlite3_Init(Tcl_Interp *interp){
3096: Tcl_InitStubs(interp, "8.4", 0);
3097: Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0);
3098: Tcl_PkgProvide(interp, "sqlite3", PACKAGE_VERSION);
3099:
3100: #ifndef SQLITE_3_SUFFIX_ONLY
3101: /* The "sqlite" alias is undocumented. It is here only to support
3102: ** legacy scripts. All new scripts should use only the "sqlite3"
3103: ** command.
3104: */
3105: Tcl_CreateObjCommand(interp, "sqlite", (Tcl_ObjCmdProc*)DbMain, 0, 0);
3106: #endif
3107:
3108: return TCL_OK;
3109: }
3110: EXTERN int Tclsqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
3111: EXTERN int Sqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
3112: EXTERN int Tclsqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
3113: EXTERN int Sqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
3114: EXTERN int Tclsqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
3115: EXTERN int Sqlite3_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK; }
3116: EXTERN int Tclsqlite3_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK;}
3117:
3118:
3119: #ifndef SQLITE_3_SUFFIX_ONLY
3120: int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
3121: int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
3122: int Sqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
3123: int Tclsqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
3124: int Sqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
3125: int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
3126: int Sqlite_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK; }
3127: int Tclsqlite_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK;}
3128: #endif
3129:
3130: #ifdef TCLSH
3131: /*****************************************************************************
3132: ** All of the code that follows is used to build standalone TCL interpreters
3133: ** that are statically linked with SQLite. Enable these by compiling
3134: ** with -DTCLSH=n where n can be 1 or 2. An n of 1 generates a standard
3135: ** tclsh but with SQLite built in. An n of 2 generates the SQLite space
3136: ** analysis program.
3137: */
3138:
3139: #if defined(SQLITE_TEST) || defined(SQLITE_TCLMD5)
3140: /*
3141: * This code implements the MD5 message-digest algorithm.
3142: * The algorithm is due to Ron Rivest. This code was
3143: * written by Colin Plumb in 1993, no copyright is claimed.
3144: * This code is in the public domain; do with it what you wish.
3145: *
3146: * Equivalent code is available from RSA Data Security, Inc.
3147: * This code has been tested against that, and is equivalent,
3148: * except that you don't need to include two pages of legalese
3149: * with every copy.
3150: *
3151: * To compute the message digest of a chunk of bytes, declare an
3152: * MD5Context structure, pass it to MD5Init, call MD5Update as
3153: * needed on buffers full of bytes, and then call MD5Final, which
3154: * will fill a supplied 16-byte array with the digest.
3155: */
3156:
3157: /*
3158: * If compiled on a machine that doesn't have a 32-bit integer,
3159: * you just set "uint32" to the appropriate datatype for an
3160: * unsigned 32-bit integer. For example:
3161: *
3162: * cc -Duint32='unsigned long' md5.c
3163: *
3164: */
3165: #ifndef uint32
3166: # define uint32 unsigned int
3167: #endif
3168:
3169: struct MD5Context {
3170: int isInit;
3171: uint32 buf[4];
3172: uint32 bits[2];
3173: unsigned char in[64];
3174: };
3175: typedef struct MD5Context MD5Context;
3176:
3177: /*
3178: * Note: this code is harmless on little-endian machines.
3179: */
3180: static void byteReverse (unsigned char *buf, unsigned longs){
3181: uint32 t;
3182: do {
3183: t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 |
3184: ((unsigned)buf[1]<<8 | buf[0]);
3185: *(uint32 *)buf = t;
3186: buf += 4;
3187: } while (--longs);
3188: }
3189: /* The four core functions - F1 is optimized somewhat */
3190:
3191: /* #define F1(x, y, z) (x & y | ~x & z) */
3192: #define F1(x, y, z) (z ^ (x & (y ^ z)))
3193: #define F2(x, y, z) F1(z, x, y)
3194: #define F3(x, y, z) (x ^ y ^ z)
3195: #define F4(x, y, z) (y ^ (x | ~z))
3196:
3197: /* This is the central step in the MD5 algorithm. */
3198: #define MD5STEP(f, w, x, y, z, data, s) \
3199: ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
3200:
3201: /*
3202: * The core of the MD5 algorithm, this alters an existing MD5 hash to
3203: * reflect the addition of 16 longwords of new data. MD5Update blocks
3204: * the data and converts bytes into longwords for this routine.
3205: */
3206: static void MD5Transform(uint32 buf[4], const uint32 in[16]){
3207: register uint32 a, b, c, d;
3208:
3209: a = buf[0];
3210: b = buf[1];
3211: c = buf[2];
3212: d = buf[3];
3213:
3214: MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478, 7);
3215: MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
3216: MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
3217: MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
3218: MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf, 7);
3219: MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
3220: MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
3221: MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
3222: MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8, 7);
3223: MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
3224: MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
3225: MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
3226: MD5STEP(F1, a, b, c, d, in[12]+0x6b901122, 7);
3227: MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
3228: MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
3229: MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
3230:
3231: MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562, 5);
3232: MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340, 9);
3233: MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
3234: MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
3235: MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d, 5);
3236: MD5STEP(F2, d, a, b, c, in[10]+0x02441453, 9);
3237: MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
3238: MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
3239: MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6, 5);
3240: MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6, 9);
3241: MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
3242: MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
3243: MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905, 5);
3244: MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9);
3245: MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
3246: MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
3247:
3248: MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942, 4);
3249: MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
3250: MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
3251: MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
3252: MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44, 4);
3253: MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
3254: MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
3255: MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
3256: MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6, 4);
3257: MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
3258: MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
3259: MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
3260: MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039, 4);
3261: MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
3262: MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
3263: MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
3264:
3265: MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244, 6);
3266: MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
3267: MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
3268: MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
3269: MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3, 6);
3270: MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
3271: MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
3272: MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
3273: MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6);
3274: MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
3275: MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
3276: MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
3277: MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82, 6);
3278: MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
3279: MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
3280: MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
3281:
3282: buf[0] += a;
3283: buf[1] += b;
3284: buf[2] += c;
3285: buf[3] += d;
3286: }
3287:
3288: /*
3289: * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
3290: * initialization constants.
3291: */
3292: static void MD5Init(MD5Context *ctx){
3293: ctx->isInit = 1;
3294: ctx->buf[0] = 0x67452301;
3295: ctx->buf[1] = 0xefcdab89;
3296: ctx->buf[2] = 0x98badcfe;
3297: ctx->buf[3] = 0x10325476;
3298: ctx->bits[0] = 0;
3299: ctx->bits[1] = 0;
3300: }
3301:
3302: /*
3303: * Update context to reflect the concatenation of another buffer full
3304: * of bytes.
3305: */
3306: static
3307: void MD5Update(MD5Context *ctx, const unsigned char *buf, unsigned int len){
3308: uint32 t;
3309:
3310: /* Update bitcount */
3311:
3312: t = ctx->bits[0];
3313: if ((ctx->bits[0] = t + ((uint32)len << 3)) < t)
3314: ctx->bits[1]++; /* Carry from low to high */
3315: ctx->bits[1] += len >> 29;
3316:
3317: t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
3318:
3319: /* Handle any leading odd-sized chunks */
3320:
3321: if ( t ) {
3322: unsigned char *p = (unsigned char *)ctx->in + t;
3323:
3324: t = 64-t;
3325: if (len < t) {
3326: memcpy(p, buf, len);
3327: return;
3328: }
3329: memcpy(p, buf, t);
3330: byteReverse(ctx->in, 16);
3331: MD5Transform(ctx->buf, (uint32 *)ctx->in);
3332: buf += t;
3333: len -= t;
3334: }
3335:
3336: /* Process data in 64-byte chunks */
3337:
3338: while (len >= 64) {
3339: memcpy(ctx->in, buf, 64);
3340: byteReverse(ctx->in, 16);
3341: MD5Transform(ctx->buf, (uint32 *)ctx->in);
3342: buf += 64;
3343: len -= 64;
3344: }
3345:
3346: /* Handle any remaining bytes of data. */
3347:
3348: memcpy(ctx->in, buf, len);
3349: }
3350:
3351: /*
3352: * Final wrapup - pad to 64-byte boundary with the bit pattern
3353: * 1 0* (64-bit count of bits processed, MSB-first)
3354: */
3355: static void MD5Final(unsigned char digest[16], MD5Context *ctx){
3356: unsigned count;
3357: unsigned char *p;
3358:
3359: /* Compute number of bytes mod 64 */
3360: count = (ctx->bits[0] >> 3) & 0x3F;
3361:
3362: /* Set the first char of padding to 0x80. This is safe since there is
3363: always at least one byte free */
3364: p = ctx->in + count;
3365: *p++ = 0x80;
3366:
3367: /* Bytes of padding needed to make 64 bytes */
3368: count = 64 - 1 - count;
3369:
3370: /* Pad out to 56 mod 64 */
3371: if (count < 8) {
3372: /* Two lots of padding: Pad the first block to 64 bytes */
3373: memset(p, 0, count);
3374: byteReverse(ctx->in, 16);
3375: MD5Transform(ctx->buf, (uint32 *)ctx->in);
3376:
3377: /* Now fill the next block with 56 bytes */
3378: memset(ctx->in, 0, 56);
3379: } else {
3380: /* Pad block to 56 bytes */
3381: memset(p, 0, count-8);
3382: }
3383: byteReverse(ctx->in, 14);
3384:
3385: /* Append length in bits and transform */
3386: ((uint32 *)ctx->in)[ 14 ] = ctx->bits[0];
3387: ((uint32 *)ctx->in)[ 15 ] = ctx->bits[1];
3388:
3389: MD5Transform(ctx->buf, (uint32 *)ctx->in);
3390: byteReverse((unsigned char *)ctx->buf, 4);
3391: memcpy(digest, ctx->buf, 16);
3392: memset(ctx, 0, sizeof(ctx)); /* In case it is sensitive */
3393: }
3394:
3395: /*
3396: ** Convert a 128-bit MD5 digest into a 32-digit base-16 number.
3397: */
3398: static void MD5DigestToBase16(unsigned char *digest, char *zBuf){
3399: static char const zEncode[] = "0123456789abcdef";
3400: int i, j;
3401:
3402: for(j=i=0; i<16; i++){
3403: int a = digest[i];
3404: zBuf[j++] = zEncode[(a>>4)&0xf];
3405: zBuf[j++] = zEncode[a & 0xf];
3406: }
3407: zBuf[j] = 0;
3408: }
3409:
3410:
3411: /*
3412: ** Convert a 128-bit MD5 digest into sequency of eight 5-digit integers
3413: ** each representing 16 bits of the digest and separated from each
3414: ** other by a "-" character.
3415: */
3416: static void MD5DigestToBase10x8(unsigned char digest[16], char zDigest[50]){
3417: int i, j;
3418: unsigned int x;
3419: for(i=j=0; i<16; i+=2){
3420: x = digest[i]*256 + digest[i+1];
3421: if( i>0 ) zDigest[j++] = '-';
3422: sprintf(&zDigest[j], "%05u", x);
3423: j += 5;
3424: }
3425: zDigest[j] = 0;
3426: }
3427:
3428: /*
3429: ** A TCL command for md5. The argument is the text to be hashed. The
3430: ** Result is the hash in base64.
3431: */
3432: static int md5_cmd(void*cd, Tcl_Interp *interp, int argc, const char **argv){
3433: MD5Context ctx;
3434: unsigned char digest[16];
3435: char zBuf[50];
3436: void (*converter)(unsigned char*, char*);
3437:
3438: if( argc!=2 ){
3439: Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
3440: " TEXT\"", 0);
3441: return TCL_ERROR;
3442: }
3443: MD5Init(&ctx);
3444: MD5Update(&ctx, (unsigned char*)argv[1], (unsigned)strlen(argv[1]));
3445: MD5Final(digest, &ctx);
3446: converter = (void(*)(unsigned char*,char*))cd;
3447: converter(digest, zBuf);
3448: Tcl_AppendResult(interp, zBuf, (char*)0);
3449: return TCL_OK;
3450: }
3451:
3452: /*
3453: ** A TCL command to take the md5 hash of a file. The argument is the
3454: ** name of the file.
3455: */
3456: static int md5file_cmd(void*cd, Tcl_Interp*interp, int argc, const char **argv){
3457: FILE *in;
3458: MD5Context ctx;
3459: void (*converter)(unsigned char*, char*);
3460: unsigned char digest[16];
3461: char zBuf[10240];
3462:
3463: if( argc!=2 ){
3464: Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
3465: " FILENAME\"", 0);
3466: return TCL_ERROR;
3467: }
3468: in = fopen(argv[1],"rb");
3469: if( in==0 ){
3470: Tcl_AppendResult(interp,"unable to open file \"", argv[1],
3471: "\" for reading", 0);
3472: return TCL_ERROR;
3473: }
3474: MD5Init(&ctx);
3475: for(;;){
3476: int n;
3477: n = fread(zBuf, 1, sizeof(zBuf), in);
3478: if( n<=0 ) break;
3479: MD5Update(&ctx, (unsigned char*)zBuf, (unsigned)n);
3480: }
3481: fclose(in);
3482: MD5Final(digest, &ctx);
3483: converter = (void(*)(unsigned char*,char*))cd;
3484: converter(digest, zBuf);
3485: Tcl_AppendResult(interp, zBuf, (char*)0);
3486: return TCL_OK;
3487: }
3488:
3489: /*
3490: ** Register the four new TCL commands for generating MD5 checksums
3491: ** with the TCL interpreter.
3492: */
3493: int Md5_Init(Tcl_Interp *interp){
3494: Tcl_CreateCommand(interp, "md5", (Tcl_CmdProc*)md5_cmd,
3495: MD5DigestToBase16, 0);
3496: Tcl_CreateCommand(interp, "md5-10x8", (Tcl_CmdProc*)md5_cmd,
3497: MD5DigestToBase10x8, 0);
3498: Tcl_CreateCommand(interp, "md5file", (Tcl_CmdProc*)md5file_cmd,
3499: MD5DigestToBase16, 0);
3500: Tcl_CreateCommand(interp, "md5file-10x8", (Tcl_CmdProc*)md5file_cmd,
3501: MD5DigestToBase10x8, 0);
3502: return TCL_OK;
3503: }
3504: #endif /* defined(SQLITE_TEST) || defined(SQLITE_TCLMD5) */
3505:
3506: #if defined(SQLITE_TEST)
3507: /*
3508: ** During testing, the special md5sum() aggregate function is available.
3509: ** inside SQLite. The following routines implement that function.
3510: */
3511: static void md5step(sqlite3_context *context, int argc, sqlite3_value **argv){
3512: MD5Context *p;
3513: int i;
3514: if( argc<1 ) return;
3515: p = sqlite3_aggregate_context(context, sizeof(*p));
3516: if( p==0 ) return;
3517: if( !p->isInit ){
3518: MD5Init(p);
3519: }
3520: for(i=0; i<argc; i++){
3521: const char *zData = (char*)sqlite3_value_text(argv[i]);
3522: if( zData ){
3523: MD5Update(p, (unsigned char*)zData, strlen(zData));
3524: }
3525: }
3526: }
3527: static void md5finalize(sqlite3_context *context){
3528: MD5Context *p;
3529: unsigned char digest[16];
3530: char zBuf[33];
3531: p = sqlite3_aggregate_context(context, sizeof(*p));
3532: MD5Final(digest,p);
3533: MD5DigestToBase16(digest, zBuf);
3534: sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
3535: }
3536: int Md5_Register(sqlite3 *db){
3537: int rc = sqlite3_create_function(db, "md5sum", -1, SQLITE_UTF8, 0, 0,
3538: md5step, md5finalize);
3539: sqlite3_overload_function(db, "md5sum", -1); /* To exercise this API */
3540: return rc;
3541: }
3542: #endif /* defined(SQLITE_TEST) */
3543:
3544:
3545: /*
3546: ** If the macro TCLSH is one, then put in code this for the
3547: ** "main" routine that will initialize Tcl and take input from
3548: ** standard input, or if a file is named on the command line
3549: ** the TCL interpreter reads and evaluates that file.
3550: */
3551: #if TCLSH==1
3552: static const char *tclsh_main_loop(void){
3553: static const char zMainloop[] =
3554: "set line {}\n"
3555: "while {![eof stdin]} {\n"
3556: "if {$line!=\"\"} {\n"
3557: "puts -nonewline \"> \"\n"
3558: "} else {\n"
3559: "puts -nonewline \"% \"\n"
3560: "}\n"
3561: "flush stdout\n"
3562: "append line [gets stdin]\n"
3563: "if {[info complete $line]} {\n"
3564: "if {[catch {uplevel #0 $line} result]} {\n"
3565: "puts stderr \"Error: $result\"\n"
3566: "} elseif {$result!=\"\"} {\n"
3567: "puts $result\n"
3568: "}\n"
3569: "set line {}\n"
3570: "} else {\n"
3571: "append line \\n\n"
3572: "}\n"
3573: "}\n"
3574: ;
3575: return zMainloop;
3576: }
3577: #endif
3578: #if TCLSH==2
3579: static const char *tclsh_main_loop(void);
3580: #endif
3581:
3582: #ifdef SQLITE_TEST
3583: static void init_all(Tcl_Interp *);
3584: static int init_all_cmd(
3585: ClientData cd,
3586: Tcl_Interp *interp,
3587: int objc,
3588: Tcl_Obj *CONST objv[]
3589: ){
3590:
3591: Tcl_Interp *slave;
3592: if( objc!=2 ){
3593: Tcl_WrongNumArgs(interp, 1, objv, "SLAVE");
3594: return TCL_ERROR;
3595: }
3596:
3597: slave = Tcl_GetSlave(interp, Tcl_GetString(objv[1]));
3598: if( !slave ){
3599: return TCL_ERROR;
3600: }
3601:
3602: init_all(slave);
3603: return TCL_OK;
3604: }
3605:
3606: /*
3607: ** Tclcmd: db_use_legacy_prepare DB BOOLEAN
3608: **
3609: ** The first argument to this command must be a database command created by
3610: ** [sqlite3]. If the second argument is true, then the handle is configured
3611: ** to use the sqlite3_prepare_v2() function to prepare statements. If it
3612: ** is false, sqlite3_prepare().
3613: */
3614: static int db_use_legacy_prepare_cmd(
3615: ClientData cd,
3616: Tcl_Interp *interp,
3617: int objc,
3618: Tcl_Obj *CONST objv[]
3619: ){
3620: Tcl_CmdInfo cmdInfo;
3621: SqliteDb *pDb;
3622: int bPrepare;
3623:
3624: if( objc!=3 ){
3625: Tcl_WrongNumArgs(interp, 1, objv, "DB BOOLEAN");
3626: return TCL_ERROR;
3627: }
3628:
3629: if( !Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){
3630: Tcl_AppendResult(interp, "no such db: ", Tcl_GetString(objv[1]), (char*)0);
3631: return TCL_ERROR;
3632: }
3633: pDb = (SqliteDb*)cmdInfo.objClientData;
3634: if( Tcl_GetBooleanFromObj(interp, objv[2], &bPrepare) ){
3635: return TCL_ERROR;
3636: }
3637:
3638: pDb->bLegacyPrepare = bPrepare;
3639:
3640: Tcl_ResetResult(interp);
3641: return TCL_OK;
3642: }
3643: #endif
3644:
3645: /*
3646: ** Configure the interpreter passed as the first argument to have access
3647: ** to the commands and linked variables that make up:
3648: **
3649: ** * the [sqlite3] extension itself,
3650: **
3651: ** * If SQLITE_TCLMD5 or SQLITE_TEST is defined, the Md5 commands, and
3652: **
3653: ** * If SQLITE_TEST is set, the various test interfaces used by the Tcl
3654: ** test suite.
3655: */
3656: static void init_all(Tcl_Interp *interp){
3657: Sqlite3_Init(interp);
3658:
3659: #if defined(SQLITE_TEST) || defined(SQLITE_TCLMD5)
3660: Md5_Init(interp);
3661: #endif
3662:
3663: /* Install the [register_dbstat_vtab] command to access the implementation
3664: ** of virtual table dbstat (source file test_stat.c). This command is
3665: ** required for testfixture and sqlite3_analyzer, but not by the production
3666: ** Tcl extension. */
3667: #if defined(SQLITE_TEST) || TCLSH==2
3668: {
3669: extern int SqlitetestStat_Init(Tcl_Interp*);
3670: SqlitetestStat_Init(interp);
3671: }
3672: #endif
3673:
3674: #ifdef SQLITE_TEST
3675: {
3676: extern int Sqliteconfig_Init(Tcl_Interp*);
3677: extern int Sqlitetest1_Init(Tcl_Interp*);
3678: extern int Sqlitetest2_Init(Tcl_Interp*);
3679: extern int Sqlitetest3_Init(Tcl_Interp*);
3680: extern int Sqlitetest4_Init(Tcl_Interp*);
3681: extern int Sqlitetest5_Init(Tcl_Interp*);
3682: extern int Sqlitetest6_Init(Tcl_Interp*);
3683: extern int Sqlitetest7_Init(Tcl_Interp*);
3684: extern int Sqlitetest8_Init(Tcl_Interp*);
3685: extern int Sqlitetest9_Init(Tcl_Interp*);
3686: extern int Sqlitetestasync_Init(Tcl_Interp*);
3687: extern int Sqlitetest_autoext_Init(Tcl_Interp*);
3688: extern int Sqlitetest_demovfs_Init(Tcl_Interp *);
3689: extern int Sqlitetest_func_Init(Tcl_Interp*);
3690: extern int Sqlitetest_hexio_Init(Tcl_Interp*);
3691: extern int Sqlitetest_init_Init(Tcl_Interp*);
3692: extern int Sqlitetest_malloc_Init(Tcl_Interp*);
3693: extern int Sqlitetest_mutex_Init(Tcl_Interp*);
3694: extern int Sqlitetestschema_Init(Tcl_Interp*);
3695: extern int Sqlitetestsse_Init(Tcl_Interp*);
3696: extern int Sqlitetesttclvar_Init(Tcl_Interp*);
3697: extern int SqlitetestThread_Init(Tcl_Interp*);
3698: extern int SqlitetestOnefile_Init();
3699: extern int SqlitetestOsinst_Init(Tcl_Interp*);
3700: extern int Sqlitetestbackup_Init(Tcl_Interp*);
3701: extern int Sqlitetestintarray_Init(Tcl_Interp*);
3702: extern int Sqlitetestvfs_Init(Tcl_Interp *);
3703: extern int Sqlitetestrtree_Init(Tcl_Interp*);
3704: extern int Sqlitequota_Init(Tcl_Interp*);
3705: extern int Sqlitemultiplex_Init(Tcl_Interp*);
3706: extern int SqliteSuperlock_Init(Tcl_Interp*);
3707: extern int SqlitetestSyscall_Init(Tcl_Interp*);
3708: extern int Sqlitetestfuzzer_Init(Tcl_Interp*);
3709: extern int Sqlitetestwholenumber_Init(Tcl_Interp*);
3710:
3711: #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
3712: extern int Sqlitetestfts3_Init(Tcl_Interp *interp);
3713: #endif
3714:
3715: #ifdef SQLITE_ENABLE_ZIPVFS
3716: extern int Zipvfs_Init(Tcl_Interp*);
3717: Zipvfs_Init(interp);
3718: #endif
3719:
3720: Sqliteconfig_Init(interp);
3721: Sqlitetest1_Init(interp);
3722: Sqlitetest2_Init(interp);
3723: Sqlitetest3_Init(interp);
3724: Sqlitetest4_Init(interp);
3725: Sqlitetest5_Init(interp);
3726: Sqlitetest6_Init(interp);
3727: Sqlitetest7_Init(interp);
3728: Sqlitetest8_Init(interp);
3729: Sqlitetest9_Init(interp);
3730: Sqlitetestasync_Init(interp);
3731: Sqlitetest_autoext_Init(interp);
3732: Sqlitetest_demovfs_Init(interp);
3733: Sqlitetest_func_Init(interp);
3734: Sqlitetest_hexio_Init(interp);
3735: Sqlitetest_init_Init(interp);
3736: Sqlitetest_malloc_Init(interp);
3737: Sqlitetest_mutex_Init(interp);
3738: Sqlitetestschema_Init(interp);
3739: Sqlitetesttclvar_Init(interp);
3740: SqlitetestThread_Init(interp);
3741: SqlitetestOnefile_Init(interp);
3742: SqlitetestOsinst_Init(interp);
3743: Sqlitetestbackup_Init(interp);
3744: Sqlitetestintarray_Init(interp);
3745: Sqlitetestvfs_Init(interp);
3746: Sqlitetestrtree_Init(interp);
3747: Sqlitequota_Init(interp);
3748: Sqlitemultiplex_Init(interp);
3749: SqliteSuperlock_Init(interp);
3750: SqlitetestSyscall_Init(interp);
3751: Sqlitetestfuzzer_Init(interp);
3752: Sqlitetestwholenumber_Init(interp);
3753:
3754: #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
3755: Sqlitetestfts3_Init(interp);
3756: #endif
3757:
3758: Tcl_CreateObjCommand(
3759: interp, "load_testfixture_extensions", init_all_cmd, 0, 0
3760: );
3761: Tcl_CreateObjCommand(
3762: interp, "db_use_legacy_prepare", db_use_legacy_prepare_cmd, 0, 0
3763: );
3764:
3765: #ifdef SQLITE_SSE
3766: Sqlitetestsse_Init(interp);
3767: #endif
3768: }
3769: #endif
3770: }
3771:
3772: #define TCLSH_MAIN main /* Needed to fake out mktclapp */
3773: int TCLSH_MAIN(int argc, char **argv){
3774: Tcl_Interp *interp;
3775:
3776: /* Call sqlite3_shutdown() once before doing anything else. This is to
3777: ** test that sqlite3_shutdown() can be safely called by a process before
3778: ** sqlite3_initialize() is. */
3779: sqlite3_shutdown();
3780:
3781: Tcl_FindExecutable(argv[0]);
3782: interp = Tcl_CreateInterp();
3783:
3784: #if TCLSH==2
3785: sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
3786: #endif
3787:
3788: init_all(interp);
3789: if( argc>=2 ){
3790: int i;
3791: char zArgc[32];
3792: sqlite3_snprintf(sizeof(zArgc), zArgc, "%d", argc-(3-TCLSH));
3793: Tcl_SetVar(interp,"argc", zArgc, TCL_GLOBAL_ONLY);
3794: Tcl_SetVar(interp,"argv0",argv[1],TCL_GLOBAL_ONLY);
3795: Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY);
3796: for(i=3-TCLSH; i<argc; i++){
3797: Tcl_SetVar(interp, "argv", argv[i],
3798: TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE);
3799: }
3800: if( TCLSH==1 && Tcl_EvalFile(interp, argv[1])!=TCL_OK ){
3801: const char *zInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
3802: if( zInfo==0 ) zInfo = Tcl_GetStringResult(interp);
3803: fprintf(stderr,"%s: %s\n", *argv, zInfo);
3804: return 1;
3805: }
3806: }
3807: if( TCLSH==2 || argc<=1 ){
3808: Tcl_GlobalEval(interp, tclsh_main_loop());
3809: }
3810: return 0;
3811: }
3812: #endif /* TCLSH */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>