OLD | NEW |
1 /* | 1 /* |
2 ** 2001 September 15 | 2 ** 2001 September 15 |
3 ** | 3 ** |
4 ** The author disclaims copyright to this source code. In place of | 4 ** The author disclaims copyright to this source code. In place of |
5 ** a legal notice, here is a blessing: | 5 ** a legal notice, here is a blessing: |
6 ** | 6 ** |
7 ** May you do good and not evil. | 7 ** May you do good and not evil. |
8 ** May you find forgiveness for yourself and forgive others. | 8 ** May you find forgiveness for yourself and forgive others. |
9 ** May you share freely, never taking more than you give. | 9 ** May you share freely, never taking more than you give. |
10 ** | 10 ** |
(...skipping 23 matching lines...) Expand all Loading... |
34 */ | 34 */ |
35 #ifndef SQLITE_AMALGAMATION | 35 #ifndef SQLITE_AMALGAMATION |
36 # include "sqlite3.h" | 36 # include "sqlite3.h" |
37 # include <stdlib.h> | 37 # include <stdlib.h> |
38 # include <string.h> | 38 # include <string.h> |
39 # include <assert.h> | 39 # include <assert.h> |
40 typedef unsigned char u8; | 40 typedef unsigned char u8; |
41 #endif | 41 #endif |
42 #include <ctype.h> | 42 #include <ctype.h> |
43 | 43 |
| 44 /* Used to get the current process ID */ |
| 45 #if !defined(_WIN32) |
| 46 # include <unistd.h> |
| 47 # define GETPID getpid |
| 48 #elif !defined(_WIN32_WCE) |
| 49 # ifndef SQLITE_AMALGAMATION |
| 50 # define WIN32_LEAN_AND_MEAN |
| 51 # include <windows.h> |
| 52 # endif |
| 53 # define GETPID (int)GetCurrentProcessId |
| 54 #endif |
| 55 |
44 /* | 56 /* |
45 * Windows needs to know which symbols to export. Unix does not. | 57 * Windows needs to know which symbols to export. Unix does not. |
46 * BUILD_sqlite should be undefined for Unix. | 58 * BUILD_sqlite should be undefined for Unix. |
47 */ | 59 */ |
48 #ifdef BUILD_sqlite | 60 #ifdef BUILD_sqlite |
49 #undef TCL_STORAGE_CLASS | 61 #undef TCL_STORAGE_CLASS |
50 #define TCL_STORAGE_CLASS DLLEXPORT | 62 #define TCL_STORAGE_CLASS DLLEXPORT |
51 #endif /* BUILD_sqlite */ | 63 #endif /* BUILD_sqlite */ |
52 | 64 |
53 #define NUM_PREPARED_STMTS 10 | 65 #define NUM_PREPARED_STMTS 10 |
54 #define MAX_PREPARED_STMTS 100 | 66 #define MAX_PREPARED_STMTS 100 |
55 | 67 |
56 /* | 68 /* Forward declaration */ |
57 ** If TCL uses UTF-8 and SQLite is configured to use iso8859, then we | 69 typedef struct SqliteDb SqliteDb; |
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 | 70 |
66 /* | 71 /* |
67 ** New SQL functions can be created as TCL scripts. Each such function | 72 ** New SQL functions can be created as TCL scripts. Each such function |
68 ** is described by an instance of the following structure. | 73 ** is described by an instance of the following structure. |
69 */ | 74 */ |
70 typedef struct SqlFunc SqlFunc; | 75 typedef struct SqlFunc SqlFunc; |
71 struct SqlFunc { | 76 struct SqlFunc { |
72 Tcl_Interp *interp; /* The TCL interpret to execute the function */ | 77 Tcl_Interp *interp; /* The TCL interpret to execute the function */ |
73 Tcl_Obj *pScript; /* The Tcl_Obj representation of the script */ | 78 Tcl_Obj *pScript; /* The Tcl_Obj representation of the script */ |
| 79 SqliteDb *pDb; /* Database connection that owns this function */ |
74 int useEvalObjv; /* True if it is safe to use Tcl_EvalObjv */ | 80 int useEvalObjv; /* True if it is safe to use Tcl_EvalObjv */ |
75 char *zName; /* Name of this function */ | 81 char *zName; /* Name of this function */ |
76 SqlFunc *pNext; /* Next function on the list of them all */ | 82 SqlFunc *pNext; /* Next function on the list of them all */ |
77 }; | 83 }; |
78 | 84 |
79 /* | 85 /* |
80 ** New collation sequences function can be created as TCL scripts. Each such | 86 ** New collation sequences function can be created as TCL scripts. Each such |
81 ** function is described by an instance of the following structure. | 87 ** function is described by an instance of the following structure. |
82 */ | 88 */ |
83 typedef struct SqlCollate SqlCollate; | 89 typedef struct SqlCollate SqlCollate; |
(...skipping 16 matching lines...) Expand all Loading... |
100 const char *zSql; /* Text of the SQL statement */ | 106 const char *zSql; /* Text of the SQL statement */ |
101 int nParm; /* Size of apParm array */ | 107 int nParm; /* Size of apParm array */ |
102 Tcl_Obj **apParm; /* Array of referenced object pointers */ | 108 Tcl_Obj **apParm; /* Array of referenced object pointers */ |
103 }; | 109 }; |
104 | 110 |
105 typedef struct IncrblobChannel IncrblobChannel; | 111 typedef struct IncrblobChannel IncrblobChannel; |
106 | 112 |
107 /* | 113 /* |
108 ** There is one instance of this structure for each SQLite database | 114 ** There is one instance of this structure for each SQLite database |
109 ** that has been opened by the SQLite TCL interface. | 115 ** that has been opened by the SQLite TCL interface. |
| 116 ** |
| 117 ** If this module is built with SQLITE_TEST defined (to create the SQLite |
| 118 ** testfixture executable), then it may be configured to use either |
| 119 ** sqlite3_prepare_v2() or sqlite3_prepare() to prepare SQL statements. |
| 120 ** If SqliteDb.bLegacyPrepare is true, sqlite3_prepare() is used. |
110 */ | 121 */ |
111 typedef struct SqliteDb SqliteDb; | |
112 struct SqliteDb { | 122 struct SqliteDb { |
113 sqlite3 *db; /* The "real" database structure. MUST BE FIRST */ | 123 sqlite3 *db; /* The "real" database structure. MUST BE FIRST */ |
114 Tcl_Interp *interp; /* The interpreter used for this database */ | 124 Tcl_Interp *interp; /* The interpreter used for this database */ |
115 char *zBusy; /* The busy callback routine */ | 125 char *zBusy; /* The busy callback routine */ |
116 char *zCommit; /* The commit hook callback routine */ | 126 char *zCommit; /* The commit hook callback routine */ |
117 char *zTrace; /* The trace callback routine */ | 127 char *zTrace; /* The trace callback routine */ |
118 char *zProfile; /* The profile callback routine */ | 128 char *zProfile; /* The profile callback routine */ |
119 char *zProgress; /* The progress callback routine */ | 129 char *zProgress; /* The progress callback routine */ |
120 char *zAuth; /* The authorization callback routine */ | 130 char *zAuth; /* The authorization callback routine */ |
121 int disableAuth; /* Disable the authorizer if it exists */ | 131 int disableAuth; /* Disable the authorizer if it exists */ |
122 char *zNull; /* Text to substitute for an SQL NULL value */ | 132 char *zNull; /* Text to substitute for an SQL NULL value */ |
123 SqlFunc *pFunc; /* List of SQL functions */ | 133 SqlFunc *pFunc; /* List of SQL functions */ |
124 Tcl_Obj *pUpdateHook; /* Update hook script (if any) */ | 134 Tcl_Obj *pUpdateHook; /* Update hook script (if any) */ |
125 Tcl_Obj *pRollbackHook; /* Rollback hook script (if any) */ | 135 Tcl_Obj *pRollbackHook; /* Rollback hook script (if any) */ |
126 Tcl_Obj *pWalHook; /* WAL hook script (if any) */ | 136 Tcl_Obj *pWalHook; /* WAL hook script (if any) */ |
127 Tcl_Obj *pUnlockNotify; /* Unlock notify script (if any) */ | 137 Tcl_Obj *pUnlockNotify; /* Unlock notify script (if any) */ |
128 SqlCollate *pCollate; /* List of SQL collation functions */ | 138 SqlCollate *pCollate; /* List of SQL collation functions */ |
129 int rc; /* Return code of most recent sqlite3_exec() */ | 139 int rc; /* Return code of most recent sqlite3_exec() */ |
130 Tcl_Obj *pCollateNeeded; /* Collation needed script */ | 140 Tcl_Obj *pCollateNeeded; /* Collation needed script */ |
131 SqlPreparedStmt *stmtList; /* List of prepared statements*/ | 141 SqlPreparedStmt *stmtList; /* List of prepared statements*/ |
132 SqlPreparedStmt *stmtLast; /* Last statement in the list */ | 142 SqlPreparedStmt *stmtLast; /* Last statement in the list */ |
133 int maxStmt; /* The next maximum number of stmtList */ | 143 int maxStmt; /* The next maximum number of stmtList */ |
134 int nStmt; /* Number of statements in stmtList */ | 144 int nStmt; /* Number of statements in stmtList */ |
135 IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */ | 145 IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */ |
136 int nStep, nSort, nIndex; /* Statistics for most recent operation */ | 146 int nStep, nSort, nIndex; /* Statistics for most recent operation */ |
137 int nTransaction; /* Number of nested [transaction] methods */ | 147 int nTransaction; /* Number of nested [transaction] methods */ |
| 148 #ifdef SQLITE_TEST |
| 149 int bLegacyPrepare; /* True to use sqlite3_prepare() */ |
| 150 #endif |
138 }; | 151 }; |
139 | 152 |
140 struct IncrblobChannel { | 153 struct IncrblobChannel { |
141 sqlite3_blob *pBlob; /* sqlite3 blob handle */ | 154 sqlite3_blob *pBlob; /* sqlite3 blob handle */ |
142 SqliteDb *pDb; /* Associated database connection */ | 155 SqliteDb *pDb; /* Associated database connection */ |
143 int iSeek; /* Current seek offset */ | 156 int iSeek; /* Current seek offset */ |
144 Tcl_Channel channel; /* Channel identifier */ | 157 Tcl_Channel channel; /* Channel identifier */ |
145 IncrblobChannel *pNext; /* Linked list of all open incrblob channels */ | 158 IncrblobChannel *pNext; /* Linked list of all open incrblob channels */ |
146 IncrblobChannel *pPrev; /* Linked list of all open incrblob channels */ | 159 IncrblobChannel *pPrev; /* Linked list of all open incrblob channels */ |
147 }; | 160 }; |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
404 return 1; | 417 return 1; |
405 } | 418 } |
406 | 419 |
407 /* | 420 /* |
408 ** Find an SqlFunc structure with the given name. Or create a new | 421 ** Find an SqlFunc structure with the given name. Or create a new |
409 ** one if an existing one cannot be found. Return a pointer to the | 422 ** one if an existing one cannot be found. Return a pointer to the |
410 ** structure. | 423 ** structure. |
411 */ | 424 */ |
412 static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){ | 425 static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){ |
413 SqlFunc *p, *pNew; | 426 SqlFunc *p, *pNew; |
414 int i; | 427 int nName = strlen30(zName); |
415 pNew = (SqlFunc*)Tcl_Alloc( sizeof(*pNew) + strlen30(zName) + 1 ); | 428 pNew = (SqlFunc*)Tcl_Alloc( sizeof(*pNew) + nName + 1 ); |
416 pNew->zName = (char*)&pNew[1]; | 429 pNew->zName = (char*)&pNew[1]; |
417 for(i=0; zName[i]; i++){ pNew->zName[i] = tolower(zName[i]); } | 430 memcpy(pNew->zName, zName, nName+1); |
418 pNew->zName[i] = 0; | |
419 for(p=pDb->pFunc; p; p=p->pNext){ | 431 for(p=pDb->pFunc; p; p=p->pNext){ |
420 if( strcmp(p->zName, pNew->zName)==0 ){ | 432 if( sqlite3_stricmp(p->zName, pNew->zName)==0 ){ |
421 Tcl_Free((char*)pNew); | 433 Tcl_Free((char*)pNew); |
422 return p; | 434 return p; |
423 } | 435 } |
424 } | 436 } |
425 pNew->interp = pDb->interp; | 437 pNew->interp = pDb->interp; |
| 438 pNew->pDb = pDb; |
426 pNew->pScript = 0; | 439 pNew->pScript = 0; |
427 pNew->pNext = pDb->pFunc; | 440 pNew->pNext = pDb->pFunc; |
428 pDb->pFunc = pNew; | 441 pDb->pFunc = pNew; |
429 return pNew; | 442 return pNew; |
430 } | 443 } |
431 | 444 |
432 /* | 445 /* |
| 446 ** Free a single SqlPreparedStmt object. |
| 447 */ |
| 448 static void dbFreeStmt(SqlPreparedStmt *pStmt){ |
| 449 #ifdef SQLITE_TEST |
| 450 if( sqlite3_sql(pStmt->pStmt)==0 ){ |
| 451 Tcl_Free((char *)pStmt->zSql); |
| 452 } |
| 453 #endif |
| 454 sqlite3_finalize(pStmt->pStmt); |
| 455 Tcl_Free((char *)pStmt); |
| 456 } |
| 457 |
| 458 /* |
433 ** Finalize and free a list of prepared statements | 459 ** Finalize and free a list of prepared statements |
434 */ | 460 */ |
435 static void flushStmtCache( SqliteDb *pDb ){ | 461 static void flushStmtCache(SqliteDb *pDb){ |
436 SqlPreparedStmt *pPreStmt; | 462 SqlPreparedStmt *pPreStmt; |
| 463 SqlPreparedStmt *pNext; |
437 | 464 |
438 while( pDb->stmtList ){ | 465 for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pNext){ |
439 sqlite3_finalize( pDb->stmtList->pStmt ); | 466 pNext = pPreStmt->pNext; |
440 pPreStmt = pDb->stmtList; | 467 dbFreeStmt(pPreStmt); |
441 pDb->stmtList = pDb->stmtList->pNext; | |
442 Tcl_Free( (char*)pPreStmt ); | |
443 } | 468 } |
444 pDb->nStmt = 0; | 469 pDb->nStmt = 0; |
445 pDb->stmtLast = 0; | 470 pDb->stmtLast = 0; |
| 471 pDb->stmtList = 0; |
446 } | 472 } |
447 | 473 |
448 /* | 474 /* |
449 ** TCL calls this procedure when an sqlite3 database command is | 475 ** TCL calls this procedure when an sqlite3 database command is |
450 ** deleted. | 476 ** deleted. |
451 */ | 477 */ |
452 static void DbDeleteCmd(void *db){ | 478 static void DbDeleteCmd(void *db){ |
453 SqliteDb *pDb = (SqliteDb*)db; | 479 SqliteDb *pDb = (SqliteDb*)db; |
454 flushStmtCache(pDb); | 480 flushStmtCache(pDb); |
455 closeIncrblobChannels(pDb); | 481 closeIncrblobChannels(pDb); |
456 sqlite3_close(pDb->db); | 482 sqlite3_close(pDb->db); |
457 while( pDb->pFunc ){ | 483 while( pDb->pFunc ){ |
458 SqlFunc *pFunc = pDb->pFunc; | 484 SqlFunc *pFunc = pDb->pFunc; |
459 pDb->pFunc = pFunc->pNext; | 485 pDb->pFunc = pFunc->pNext; |
| 486 assert( pFunc->pDb==pDb ); |
460 Tcl_DecrRefCount(pFunc->pScript); | 487 Tcl_DecrRefCount(pFunc->pScript); |
461 Tcl_Free((char*)pFunc); | 488 Tcl_Free((char*)pFunc); |
462 } | 489 } |
463 while( pDb->pCollate ){ | 490 while( pDb->pCollate ){ |
464 SqlCollate *pCollate = pDb->pCollate; | 491 SqlCollate *pCollate = pDb->pCollate; |
465 pDb->pCollate = pCollate->pNext; | 492 pDb->pCollate = pCollate->pNext; |
466 Tcl_Free((char*)pCollate); | 493 Tcl_Free((char*)pCollate); |
467 } | 494 } |
468 if( pDb->zBusy ){ | 495 if( pDb->zBusy ){ |
469 Tcl_Free(pDb->zBusy); | 496 Tcl_Free(pDb->zBusy); |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
726 ** bytecode for the command on the first invocation and thus make | 753 ** bytecode for the command on the first invocation and thus make |
727 ** subsequent invocations much faster. */ | 754 ** subsequent invocations much faster. */ |
728 pCmd = p->pScript; | 755 pCmd = p->pScript; |
729 Tcl_IncrRefCount(pCmd); | 756 Tcl_IncrRefCount(pCmd); |
730 rc = Tcl_EvalObjEx(p->interp, pCmd, 0); | 757 rc = Tcl_EvalObjEx(p->interp, pCmd, 0); |
731 Tcl_DecrRefCount(pCmd); | 758 Tcl_DecrRefCount(pCmd); |
732 }else{ | 759 }else{ |
733 /* If there are arguments to the function, make a shallow copy of the | 760 /* If there are arguments to the function, make a shallow copy of the |
734 ** script object, lappend the arguments, then evaluate the copy. | 761 ** script object, lappend the arguments, then evaluate the copy. |
735 ** | 762 ** |
736 ** By "shallow" copy, we mean a only the outer list Tcl_Obj is duplicated. | 763 ** By "shallow" copy, we mean only the outer list Tcl_Obj is duplicated. |
737 ** The new Tcl_Obj contains pointers to the original list elements. | 764 ** The new Tcl_Obj contains pointers to the original list elements. |
738 ** That way, when Tcl_EvalObjv() is run and shimmers the first element | 765 ** That way, when Tcl_EvalObjv() is run and shimmers the first element |
739 ** of the list to tclCmdNameType, that alternate representation will | 766 ** of the list to tclCmdNameType, that alternate representation will |
740 ** be preserved and reused on the next invocation. | 767 ** be preserved and reused on the next invocation. |
741 */ | 768 */ |
742 Tcl_Obj **aArg; | 769 Tcl_Obj **aArg; |
743 int nArg; | 770 int nArg; |
744 if( Tcl_ListObjGetElements(p->interp, p->pScript, &nArg, &aArg) ){ | 771 if( Tcl_ListObjGetElements(p->interp, p->pScript, &nArg, &aArg) ){ |
745 sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); | 772 sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); |
746 return; | 773 return; |
747 } | 774 } |
748 pCmd = Tcl_NewListObj(nArg, aArg); | 775 pCmd = Tcl_NewListObj(nArg, aArg); |
749 Tcl_IncrRefCount(pCmd); | 776 Tcl_IncrRefCount(pCmd); |
750 for(i=0; i<argc; i++){ | 777 for(i=0; i<argc; i++){ |
751 sqlite3_value *pIn = argv[i]; | 778 sqlite3_value *pIn = argv[i]; |
752 Tcl_Obj *pVal; | 779 Tcl_Obj *pVal; |
753 | 780 |
754 /* Set pVal to contain the i'th column of this row. */ | 781 /* Set pVal to contain the i'th column of this row. */ |
755 switch( sqlite3_value_type(pIn) ){ | 782 switch( sqlite3_value_type(pIn) ){ |
756 case SQLITE_BLOB: { | 783 case SQLITE_BLOB: { |
757 int bytes = sqlite3_value_bytes(pIn); | 784 int bytes = sqlite3_value_bytes(pIn); |
758 pVal = Tcl_NewByteArrayObj(sqlite3_value_blob(pIn), bytes); | 785 pVal = Tcl_NewByteArrayObj(sqlite3_value_blob(pIn), bytes); |
759 break; | 786 break; |
760 } | 787 } |
761 case SQLITE_INTEGER: { | 788 case SQLITE_INTEGER: { |
762 sqlite_int64 v = sqlite3_value_int64(pIn); | 789 sqlite_int64 v = sqlite3_value_int64(pIn); |
763 if( v>=-2147483647 && v<=2147483647 ){ | 790 if( v>=-2147483647 && v<=2147483647 ){ |
764 pVal = Tcl_NewIntObj(v); | 791 pVal = Tcl_NewIntObj((int)v); |
765 }else{ | 792 }else{ |
766 pVal = Tcl_NewWideIntObj(v); | 793 pVal = Tcl_NewWideIntObj(v); |
767 } | 794 } |
768 break; | 795 break; |
769 } | 796 } |
770 case SQLITE_FLOAT: { | 797 case SQLITE_FLOAT: { |
771 double r = sqlite3_value_double(pIn); | 798 double r = sqlite3_value_double(pIn); |
772 pVal = Tcl_NewDoubleObj(r); | 799 pVal = Tcl_NewDoubleObj(r); |
773 break; | 800 break; |
774 } | 801 } |
775 case SQLITE_NULL: { | 802 case SQLITE_NULL: { |
776 pVal = Tcl_NewStringObj("", 0); | 803 pVal = Tcl_NewStringObj(p->pDb->zNull, -1); |
777 break; | 804 break; |
778 } | 805 } |
779 default: { | 806 default: { |
780 int bytes = sqlite3_value_bytes(pIn); | 807 int bytes = sqlite3_value_bytes(pIn); |
781 pVal = Tcl_NewStringObj((char *)sqlite3_value_text(pIn), bytes); | 808 pVal = Tcl_NewStringObj((char *)sqlite3_value_text(pIn), bytes); |
782 break; | 809 break; |
783 } | 810 } |
784 } | 811 } |
785 rc = Tcl_ListObjAppendElement(p->interp, pCmd, pVal); | 812 rc = Tcl_ListObjAppendElement(p->interp, pCmd, pVal); |
786 if( rc ){ | 813 if( rc ){ |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
838 ** on the interpreter. The reply is examined to determine if the | 865 ** on the interpreter. The reply is examined to determine if the |
839 ** authentication fails or succeeds. | 866 ** authentication fails or succeeds. |
840 */ | 867 */ |
841 static int auth_callback( | 868 static int auth_callback( |
842 void *pArg, | 869 void *pArg, |
843 int code, | 870 int code, |
844 const char *zArg1, | 871 const char *zArg1, |
845 const char *zArg2, | 872 const char *zArg2, |
846 const char *zArg3, | 873 const char *zArg3, |
847 const char *zArg4 | 874 const char *zArg4 |
| 875 #ifdef SQLITE_USER_AUTHENTICATION |
| 876 ,const char *zArg5 |
| 877 #endif |
848 ){ | 878 ){ |
849 char *zCode; | 879 const char *zCode; |
850 Tcl_DString str; | 880 Tcl_DString str; |
851 int rc; | 881 int rc; |
852 const char *zReply; | 882 const char *zReply; |
853 SqliteDb *pDb = (SqliteDb*)pArg; | 883 SqliteDb *pDb = (SqliteDb*)pArg; |
854 if( pDb->disableAuth ) return SQLITE_OK; | 884 if( pDb->disableAuth ) return SQLITE_OK; |
855 | 885 |
856 switch( code ){ | 886 switch( code ){ |
857 case SQLITE_COPY : zCode="SQLITE_COPY"; break; | 887 case SQLITE_COPY : zCode="SQLITE_COPY"; break; |
858 case SQLITE_CREATE_INDEX : zCode="SQLITE_CREATE_INDEX"; break; | 888 case SQLITE_CREATE_INDEX : zCode="SQLITE_CREATE_INDEX"; break; |
859 case SQLITE_CREATE_TABLE : zCode="SQLITE_CREATE_TABLE"; break; | 889 case SQLITE_CREATE_TABLE : zCode="SQLITE_CREATE_TABLE"; break; |
(...skipping 20 matching lines...) Expand all Loading... |
880 case SQLITE_UPDATE : zCode="SQLITE_UPDATE"; break; | 910 case SQLITE_UPDATE : zCode="SQLITE_UPDATE"; break; |
881 case SQLITE_ATTACH : zCode="SQLITE_ATTACH"; break; | 911 case SQLITE_ATTACH : zCode="SQLITE_ATTACH"; break; |
882 case SQLITE_DETACH : zCode="SQLITE_DETACH"; break; | 912 case SQLITE_DETACH : zCode="SQLITE_DETACH"; break; |
883 case SQLITE_ALTER_TABLE : zCode="SQLITE_ALTER_TABLE"; break; | 913 case SQLITE_ALTER_TABLE : zCode="SQLITE_ALTER_TABLE"; break; |
884 case SQLITE_REINDEX : zCode="SQLITE_REINDEX"; break; | 914 case SQLITE_REINDEX : zCode="SQLITE_REINDEX"; break; |
885 case SQLITE_ANALYZE : zCode="SQLITE_ANALYZE"; break; | 915 case SQLITE_ANALYZE : zCode="SQLITE_ANALYZE"; break; |
886 case SQLITE_CREATE_VTABLE : zCode="SQLITE_CREATE_VTABLE"; break; | 916 case SQLITE_CREATE_VTABLE : zCode="SQLITE_CREATE_VTABLE"; break; |
887 case SQLITE_DROP_VTABLE : zCode="SQLITE_DROP_VTABLE"; break; | 917 case SQLITE_DROP_VTABLE : zCode="SQLITE_DROP_VTABLE"; break; |
888 case SQLITE_FUNCTION : zCode="SQLITE_FUNCTION"; break; | 918 case SQLITE_FUNCTION : zCode="SQLITE_FUNCTION"; break; |
889 case SQLITE_SAVEPOINT : zCode="SQLITE_SAVEPOINT"; break; | 919 case SQLITE_SAVEPOINT : zCode="SQLITE_SAVEPOINT"; break; |
| 920 case SQLITE_RECURSIVE : zCode="SQLITE_RECURSIVE"; break; |
890 default : zCode="????"; break; | 921 default : zCode="????"; break; |
891 } | 922 } |
892 Tcl_DStringInit(&str); | 923 Tcl_DStringInit(&str); |
893 Tcl_DStringAppend(&str, pDb->zAuth, -1); | 924 Tcl_DStringAppend(&str, pDb->zAuth, -1); |
894 Tcl_DStringAppendElement(&str, zCode); | 925 Tcl_DStringAppendElement(&str, zCode); |
895 Tcl_DStringAppendElement(&str, zArg1 ? zArg1 : ""); | 926 Tcl_DStringAppendElement(&str, zArg1 ? zArg1 : ""); |
896 Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : ""); | 927 Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : ""); |
897 Tcl_DStringAppendElement(&str, zArg3 ? zArg3 : ""); | 928 Tcl_DStringAppendElement(&str, zArg3 ? zArg3 : ""); |
898 Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : ""); | 929 Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : ""); |
| 930 #ifdef SQLITE_USER_AUTHENTICATION |
| 931 Tcl_DStringAppendElement(&str, zArg5 ? zArg5 : ""); |
| 932 #endif |
899 rc = Tcl_GlobalEval(pDb->interp, Tcl_DStringValue(&str)); | 933 rc = Tcl_GlobalEval(pDb->interp, Tcl_DStringValue(&str)); |
900 Tcl_DStringFree(&str); | 934 Tcl_DStringFree(&str); |
901 zReply = Tcl_GetStringResult(pDb->interp); | 935 zReply = rc==TCL_OK ? Tcl_GetStringResult(pDb->interp) : "SQLITE_DENY"; |
902 if( strcmp(zReply,"SQLITE_OK")==0 ){ | 936 if( strcmp(zReply,"SQLITE_OK")==0 ){ |
903 rc = SQLITE_OK; | 937 rc = SQLITE_OK; |
904 }else if( strcmp(zReply,"SQLITE_DENY")==0 ){ | 938 }else if( strcmp(zReply,"SQLITE_DENY")==0 ){ |
905 rc = SQLITE_DENY; | 939 rc = SQLITE_DENY; |
906 }else if( strcmp(zReply,"SQLITE_IGNORE")==0 ){ | 940 }else if( strcmp(zReply,"SQLITE_IGNORE")==0 ){ |
907 rc = SQLITE_IGNORE; | 941 rc = SQLITE_IGNORE; |
908 }else{ | 942 }else{ |
909 rc = 999; | 943 rc = 999; |
910 } | 944 } |
911 return rc; | 945 return rc; |
912 } | 946 } |
913 #endif /* SQLITE_OMIT_AUTHORIZATION */ | 947 #endif /* SQLITE_OMIT_AUTHORIZATION */ |
914 | 948 |
915 /* | 949 /* |
916 ** zText is a pointer to text obtained via an sqlite3_result_text() | |
917 ** or similar interface. This routine returns a Tcl string object, | |
918 ** reference count set to 0, containing the text. If a translation | |
919 ** between iso8859 and UTF-8 is required, it is preformed. | |
920 */ | |
921 static Tcl_Obj *dbTextToObj(char const *zText){ | |
922 Tcl_Obj *pVal; | |
923 #ifdef UTF_TRANSLATION_NEEDED | |
924 Tcl_DString dCol; | |
925 Tcl_DStringInit(&dCol); | |
926 Tcl_ExternalToUtfDString(NULL, zText, -1, &dCol); | |
927 pVal = Tcl_NewStringObj(Tcl_DStringValue(&dCol), -1); | |
928 Tcl_DStringFree(&dCol); | |
929 #else | |
930 pVal = Tcl_NewStringObj(zText, -1); | |
931 #endif | |
932 return pVal; | |
933 } | |
934 | |
935 /* | |
936 ** This routine reads a line of text from FILE in, stores | 950 ** This routine reads a line of text from FILE in, stores |
937 ** the text in memory obtained from malloc() and returns a pointer | 951 ** the text in memory obtained from malloc() and returns a pointer |
938 ** to the text. NULL is returned at end of file, or if malloc() | 952 ** to the text. NULL is returned at end of file, or if malloc() |
939 ** fails. | 953 ** fails. |
940 ** | 954 ** |
941 ** The interface is like "readline" but no command-line editing | 955 ** The interface is like "readline" but no command-line editing |
942 ** is done. | 956 ** is done. |
943 ** | 957 ** |
944 ** copied from shell.c from '.import' command | 958 ** copied from shell.c from '.import' command |
945 */ | 959 */ |
946 static char *local_getline(char *zPrompt, FILE *in){ | 960 static char *local_getline(char *zPrompt, FILE *in){ |
947 char *zLine; | 961 char *zLine; |
948 int nLine; | 962 int nLine; |
949 int n; | 963 int n; |
950 int eol; | |
951 | 964 |
952 nLine = 100; | 965 nLine = 100; |
953 zLine = malloc( nLine ); | 966 zLine = malloc( nLine ); |
954 if( zLine==0 ) return 0; | 967 if( zLine==0 ) return 0; |
955 n = 0; | 968 n = 0; |
956 eol = 0; | 969 while( 1 ){ |
957 while( !eol ){ | |
958 if( n+100>nLine ){ | 970 if( n+100>nLine ){ |
959 nLine = nLine*2 + 100; | 971 nLine = nLine*2 + 100; |
960 zLine = realloc(zLine, nLine); | 972 zLine = realloc(zLine, nLine); |
961 if( zLine==0 ) return 0; | 973 if( zLine==0 ) return 0; |
962 } | 974 } |
963 if( fgets(&zLine[n], nLine - n, in)==0 ){ | 975 if( fgets(&zLine[n], nLine - n, in)==0 ){ |
964 if( n==0 ){ | 976 if( n==0 ){ |
965 free(zLine); | 977 free(zLine); |
966 return 0; | 978 return 0; |
967 } | 979 } |
968 zLine[n] = 0; | 980 zLine[n] = 0; |
969 eol = 1; | |
970 break; | 981 break; |
971 } | 982 } |
972 while( zLine[n] ){ n++; } | 983 while( zLine[n] ){ n++; } |
973 if( n>0 && zLine[n-1]=='\n' ){ | 984 if( n>0 && zLine[n-1]=='\n' ){ |
974 n--; | 985 n--; |
975 zLine[n] = 0; | 986 zLine[n] = 0; |
976 eol = 1; | 987 break; |
977 } | 988 } |
978 } | 989 } |
979 zLine = realloc( zLine, n+1 ); | 990 zLine = realloc( zLine, n+1 ); |
980 return zLine; | 991 return zLine; |
981 } | 992 } |
982 | 993 |
983 | 994 |
984 /* | 995 /* |
985 ** This function is part of the implementation of the command: | 996 ** This function is part of the implementation of the command: |
986 ** | 997 ** |
987 ** $db transaction [-deferred|-immediate|-exclusive] SCRIPT | 998 ** $db transaction [-deferred|-immediate|-exclusive] SCRIPT |
988 ** | 999 ** |
989 ** It is invoked after evaluating the script SCRIPT to commit or rollback | 1000 ** It is invoked after evaluating the script SCRIPT to commit or rollback |
990 ** the transaction or savepoint opened by the [transaction] command. | 1001 ** the transaction or savepoint opened by the [transaction] command. |
991 */ | 1002 */ |
992 static int DbTransPostCmd( | 1003 static int DbTransPostCmd( |
993 ClientData data[], /* data[0] is the Sqlite3Db* for $db */ | 1004 ClientData data[], /* data[0] is the Sqlite3Db* for $db */ |
994 Tcl_Interp *interp, /* Tcl interpreter */ | 1005 Tcl_Interp *interp, /* Tcl interpreter */ |
995 int result /* Result of evaluating SCRIPT */ | 1006 int result /* Result of evaluating SCRIPT */ |
996 ){ | 1007 ){ |
997 static const char *azEnd[] = { | 1008 static const char *const azEnd[] = { |
998 "RELEASE _tcl_transaction", /* rc==TCL_ERROR, nTransaction!=0 */ | 1009 "RELEASE _tcl_transaction", /* rc==TCL_ERROR, nTransaction!=0 */ |
999 "COMMIT", /* rc!=TCL_ERROR, nTransaction==0 */ | 1010 "COMMIT", /* rc!=TCL_ERROR, nTransaction==0 */ |
1000 "ROLLBACK TO _tcl_transaction ; RELEASE _tcl_transaction", | 1011 "ROLLBACK TO _tcl_transaction ; RELEASE _tcl_transaction", |
1001 "ROLLBACK" /* rc==TCL_ERROR, nTransaction==0 */ | 1012 "ROLLBACK" /* rc==TCL_ERROR, nTransaction==0 */ |
1002 }; | 1013 }; |
1003 SqliteDb *pDb = (SqliteDb*)data[0]; | 1014 SqliteDb *pDb = (SqliteDb*)data[0]; |
1004 int rc = result; | 1015 int rc = result; |
1005 const char *zEnd; | 1016 const char *zEnd; |
1006 | 1017 |
1007 pDb->nTransaction--; | 1018 pDb->nTransaction--; |
1008 zEnd = azEnd[(rc==TCL_ERROR)*2 + (pDb->nTransaction==0)]; | 1019 zEnd = azEnd[(rc==TCL_ERROR)*2 + (pDb->nTransaction==0)]; |
1009 | 1020 |
1010 pDb->disableAuth++; | 1021 pDb->disableAuth++; |
1011 if( sqlite3_exec(pDb->db, zEnd, 0, 0, 0) ){ | 1022 if( sqlite3_exec(pDb->db, zEnd, 0, 0, 0) ){ |
1012 /* This is a tricky scenario to handle. The most likely cause of an | 1023 /* This is a tricky scenario to handle. The most likely cause of an |
1013 ** error is that the exec() above was an attempt to commit the | 1024 ** error is that the exec() above was an attempt to commit the |
1014 ** top-level transaction that returned SQLITE_BUSY. Or, less likely, | 1025 ** top-level transaction that returned SQLITE_BUSY. Or, less likely, |
1015 ** that an IO-error has occured. In either case, throw a Tcl exception | 1026 ** that an IO-error has occurred. In either case, throw a Tcl exception |
1016 ** and try to rollback the transaction. | 1027 ** and try to rollback the transaction. |
1017 ** | 1028 ** |
1018 ** But it could also be that the user executed one or more BEGIN, | 1029 ** But it could also be that the user executed one or more BEGIN, |
1019 ** COMMIT, SAVEPOINT, RELEASE or ROLLBACK commands that are confusing | 1030 ** COMMIT, SAVEPOINT, RELEASE or ROLLBACK commands that are confusing |
1020 ** this method's logic. Not clear how this would be best handled. | 1031 ** this method's logic. Not clear how this would be best handled. |
1021 */ | 1032 */ |
1022 if( rc!=TCL_ERROR ){ | 1033 if( rc!=TCL_ERROR ){ |
1023 Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0); | 1034 Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0); |
1024 rc = TCL_ERROR; | 1035 rc = TCL_ERROR; |
1025 } | 1036 } |
1026 sqlite3_exec(pDb->db, "ROLLBACK", 0, 0, 0); | 1037 sqlite3_exec(pDb->db, "ROLLBACK", 0, 0, 0); |
1027 } | 1038 } |
1028 pDb->disableAuth--; | 1039 pDb->disableAuth--; |
1029 | 1040 |
1030 return rc; | 1041 return rc; |
1031 } | 1042 } |
1032 | 1043 |
1033 /* | 1044 /* |
| 1045 ** Unless SQLITE_TEST is defined, this function is a simple wrapper around |
| 1046 ** sqlite3_prepare_v2(). If SQLITE_TEST is defined, then it uses either |
| 1047 ** sqlite3_prepare_v2() or legacy interface sqlite3_prepare(), depending |
| 1048 ** on whether or not the [db_use_legacy_prepare] command has been used to |
| 1049 ** configure the connection. |
| 1050 */ |
| 1051 static int dbPrepare( |
| 1052 SqliteDb *pDb, /* Database object */ |
| 1053 const char *zSql, /* SQL to compile */ |
| 1054 sqlite3_stmt **ppStmt, /* OUT: Prepared statement */ |
| 1055 const char **pzOut /* OUT: Pointer to next SQL statement */ |
| 1056 ){ |
| 1057 #ifdef SQLITE_TEST |
| 1058 if( pDb->bLegacyPrepare ){ |
| 1059 return sqlite3_prepare(pDb->db, zSql, -1, ppStmt, pzOut); |
| 1060 } |
| 1061 #endif |
| 1062 return sqlite3_prepare_v2(pDb->db, zSql, -1, ppStmt, pzOut); |
| 1063 } |
| 1064 |
| 1065 /* |
1034 ** Search the cache for a prepared-statement object that implements the | 1066 ** Search the cache for a prepared-statement object that implements the |
1035 ** first SQL statement in the buffer pointed to by parameter zIn. If | 1067 ** first SQL statement in the buffer pointed to by parameter zIn. If |
1036 ** no such prepared-statement can be found, allocate and prepare a new | 1068 ** no such prepared-statement can be found, allocate and prepare a new |
1037 ** one. In either case, bind the current values of the relevant Tcl | 1069 ** one. In either case, bind the current values of the relevant Tcl |
1038 ** variables to any $var, :var or @var variables in the statement. Before | 1070 ** variables to any $var, :var or @var variables in the statement. Before |
1039 ** returning, set *ppPreStmt to point to the prepared-statement object. | 1071 ** returning, set *ppPreStmt to point to the prepared-statement object. |
1040 ** | 1072 ** |
1041 ** Output parameter *pzOut is set to point to the next SQL statement in | 1073 ** Output parameter *pzOut is set to point to the next SQL statement in |
1042 ** buffer zIn, or to the '\0' byte at the end of zIn if there is no | 1074 ** buffer zIn, or to the '\0' byte at the end of zIn if there is no |
1043 ** next statement. | 1075 ** next statement. |
1044 ** | 1076 ** |
1045 ** If successful, TCL_OK is returned. Otherwise, TCL_ERROR is returned | 1077 ** If successful, TCL_OK is returned. Otherwise, TCL_ERROR is returned |
1046 ** and an error message loaded into interpreter pDb->interp. | 1078 ** and an error message loaded into interpreter pDb->interp. |
1047 */ | 1079 */ |
1048 static int dbPrepareAndBind( | 1080 static int dbPrepareAndBind( |
1049 SqliteDb *pDb, /* Database object */ | 1081 SqliteDb *pDb, /* Database object */ |
1050 char const *zIn, /* SQL to compile */ | 1082 char const *zIn, /* SQL to compile */ |
1051 char const **pzOut, /* OUT: Pointer to next SQL statement */ | 1083 char const **pzOut, /* OUT: Pointer to next SQL statement */ |
1052 SqlPreparedStmt **ppPreStmt /* OUT: Object used to cache statement */ | 1084 SqlPreparedStmt **ppPreStmt /* OUT: Object used to cache statement */ |
1053 ){ | 1085 ){ |
1054 const char *zSql = zIn; /* Pointer to first SQL statement in zIn */ | 1086 const char *zSql = zIn; /* Pointer to first SQL statement in zIn */ |
1055 sqlite3_stmt *pStmt; /* Prepared statement object */ | 1087 sqlite3_stmt *pStmt; /* Prepared statement object */ |
1056 SqlPreparedStmt *pPreStmt; /* Pointer to cached statement */ | 1088 SqlPreparedStmt *pPreStmt; /* Pointer to cached statement */ |
1057 int nSql; /* Length of zSql in bytes */ | 1089 int nSql; /* Length of zSql in bytes */ |
1058 int nVar; /* Number of variables in statement */ | 1090 int nVar; /* Number of variables in statement */ |
1059 int iParm = 0; /* Next free entry in apParm */ | 1091 int iParm = 0; /* Next free entry in apParm */ |
| 1092 char c; |
1060 int i; | 1093 int i; |
1061 Tcl_Interp *interp = pDb->interp; | 1094 Tcl_Interp *interp = pDb->interp; |
1062 | 1095 |
1063 *ppPreStmt = 0; | 1096 *ppPreStmt = 0; |
1064 | 1097 |
1065 /* Trim spaces from the start of zSql and calculate the remaining length. */ | 1098 /* Trim spaces from the start of zSql and calculate the remaining length. */ |
1066 while( isspace(zSql[0]) ){ zSql++; } | 1099 while( (c = zSql[0])==' ' || c=='\t' || c=='\r' || c=='\n' ){ zSql++; } |
1067 nSql = strlen30(zSql); | 1100 nSql = strlen30(zSql); |
1068 | 1101 |
1069 for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pPreStmt->pNext){ | 1102 for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pPreStmt->pNext){ |
1070 int n = pPreStmt->nSql; | 1103 int n = pPreStmt->nSql; |
1071 if( nSql>=n | 1104 if( nSql>=n |
1072 && memcmp(pPreStmt->zSql, zSql, n)==0 | 1105 && memcmp(pPreStmt->zSql, zSql, n)==0 |
1073 && (zSql[n]==0 || zSql[n-1]==';') | 1106 && (zSql[n]==0 || zSql[n-1]==';') |
1074 ){ | 1107 ){ |
1075 pStmt = pPreStmt->pStmt; | 1108 pStmt = pPreStmt->pStmt; |
1076 *pzOut = &zSql[pPreStmt->nSql]; | 1109 *pzOut = &zSql[pPreStmt->nSql]; |
(...skipping 16 matching lines...) Expand all Loading... |
1093 nVar = sqlite3_bind_parameter_count(pStmt); | 1126 nVar = sqlite3_bind_parameter_count(pStmt); |
1094 break; | 1127 break; |
1095 } | 1128 } |
1096 } | 1129 } |
1097 | 1130 |
1098 /* If no prepared statement was found. Compile the SQL text. Also allocate | 1131 /* If no prepared statement was found. Compile the SQL text. Also allocate |
1099 ** a new SqlPreparedStmt structure. */ | 1132 ** a new SqlPreparedStmt structure. */ |
1100 if( pPreStmt==0 ){ | 1133 if( pPreStmt==0 ){ |
1101 int nByte; | 1134 int nByte; |
1102 | 1135 |
1103 if( SQLITE_OK!=sqlite3_prepare_v2(pDb->db, zSql, -1, &pStmt, pzOut) ){ | 1136 if( SQLITE_OK!=dbPrepare(pDb, zSql, &pStmt, pzOut) ){ |
1104 Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db))); | 1137 Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1)); |
1105 return TCL_ERROR; | 1138 return TCL_ERROR; |
1106 } | 1139 } |
1107 if( pStmt==0 ){ | 1140 if( pStmt==0 ){ |
1108 if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){ | 1141 if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){ |
1109 /* A compile-time error in the statement. */ | 1142 /* A compile-time error in the statement. */ |
1110 Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db))); | 1143 Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1)); |
1111 return TCL_ERROR; | 1144 return TCL_ERROR; |
1112 }else{ | 1145 }else{ |
1113 /* The statement was a no-op. Continue to the next statement | 1146 /* The statement was a no-op. Continue to the next statement |
1114 ** in the SQL string. | 1147 ** in the SQL string. |
1115 */ | 1148 */ |
1116 return TCL_OK; | 1149 return TCL_OK; |
1117 } | 1150 } |
1118 } | 1151 } |
1119 | 1152 |
1120 assert( pPreStmt==0 ); | 1153 assert( pPreStmt==0 ); |
1121 nVar = sqlite3_bind_parameter_count(pStmt); | 1154 nVar = sqlite3_bind_parameter_count(pStmt); |
1122 nByte = sizeof(SqlPreparedStmt) + nVar*sizeof(Tcl_Obj *); | 1155 nByte = sizeof(SqlPreparedStmt) + nVar*sizeof(Tcl_Obj *); |
1123 pPreStmt = (SqlPreparedStmt*)Tcl_Alloc(nByte); | 1156 pPreStmt = (SqlPreparedStmt*)Tcl_Alloc(nByte); |
1124 memset(pPreStmt, 0, nByte); | 1157 memset(pPreStmt, 0, nByte); |
1125 | 1158 |
1126 pPreStmt->pStmt = pStmt; | 1159 pPreStmt->pStmt = pStmt; |
1127 pPreStmt->nSql = (*pzOut - zSql); | 1160 pPreStmt->nSql = (int)(*pzOut - zSql); |
1128 pPreStmt->zSql = sqlite3_sql(pStmt); | 1161 pPreStmt->zSql = sqlite3_sql(pStmt); |
1129 pPreStmt->apParm = (Tcl_Obj **)&pPreStmt[1]; | 1162 pPreStmt->apParm = (Tcl_Obj **)&pPreStmt[1]; |
| 1163 #ifdef SQLITE_TEST |
| 1164 if( pPreStmt->zSql==0 ){ |
| 1165 char *zCopy = Tcl_Alloc(pPreStmt->nSql + 1); |
| 1166 memcpy(zCopy, zSql, pPreStmt->nSql); |
| 1167 zCopy[pPreStmt->nSql] = '\0'; |
| 1168 pPreStmt->zSql = zCopy; |
| 1169 } |
| 1170 #endif |
1130 } | 1171 } |
1131 assert( pPreStmt ); | 1172 assert( pPreStmt ); |
1132 assert( strlen30(pPreStmt->zSql)==pPreStmt->nSql ); | 1173 assert( strlen30(pPreStmt->zSql)==pPreStmt->nSql ); |
1133 assert( 0==memcmp(pPreStmt->zSql, zSql, pPreStmt->nSql) ); | 1174 assert( 0==memcmp(pPreStmt->zSql, zSql, pPreStmt->nSql) ); |
1134 | 1175 |
1135 /* Bind values to parameters that begin with $ or : */ | 1176 /* Bind values to parameters that begin with $ or : */ |
1136 for(i=1; i<=nVar; i++){ | 1177 for(i=1; i<=nVar; i++){ |
1137 const char *zVar = sqlite3_bind_parameter_name(pStmt, i); | 1178 const char *zVar = sqlite3_bind_parameter_name(pStmt, i); |
1138 if( zVar!=0 && (zVar[0]=='$' || zVar[0]==':' || zVar[0]=='@') ){ | 1179 if( zVar!=0 && (zVar[0]=='$' || zVar[0]==':' || zVar[0]=='@') ){ |
1139 Tcl_Obj *pVar = Tcl_GetVar2Ex(interp, &zVar[1], 0, 0); | 1180 Tcl_Obj *pVar = Tcl_GetVar2Ex(interp, &zVar[1], 0, 0); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1173 sqlite3_bind_null(pStmt, i); | 1214 sqlite3_bind_null(pStmt, i); |
1174 } | 1215 } |
1175 } | 1216 } |
1176 } | 1217 } |
1177 pPreStmt->nParm = iParm; | 1218 pPreStmt->nParm = iParm; |
1178 *ppPreStmt = pPreStmt; | 1219 *ppPreStmt = pPreStmt; |
1179 | 1220 |
1180 return TCL_OK; | 1221 return TCL_OK; |
1181 } | 1222 } |
1182 | 1223 |
1183 | |
1184 /* | 1224 /* |
1185 ** Release a statement reference obtained by calling dbPrepareAndBind(). | 1225 ** Release a statement reference obtained by calling dbPrepareAndBind(). |
1186 ** There should be exactly one call to this function for each call to | 1226 ** There should be exactly one call to this function for each call to |
1187 ** dbPrepareAndBind(). | 1227 ** dbPrepareAndBind(). |
1188 ** | 1228 ** |
1189 ** If the discard parameter is non-zero, then the statement is deleted | 1229 ** If the discard parameter is non-zero, then the statement is deleted |
1190 ** immediately. Otherwise it is added to the LRU list and may be returned | 1230 ** immediately. Otherwise it is added to the LRU list and may be returned |
1191 ** by a subsequent call to dbPrepareAndBind(). | 1231 ** by a subsequent call to dbPrepareAndBind(). |
1192 */ | 1232 */ |
1193 static void dbReleaseStmt( | 1233 static void dbReleaseStmt( |
1194 SqliteDb *pDb, /* Database handle */ | 1234 SqliteDb *pDb, /* Database handle */ |
1195 SqlPreparedStmt *pPreStmt, /* Prepared statement handle to release */ | 1235 SqlPreparedStmt *pPreStmt, /* Prepared statement handle to release */ |
1196 int discard /* True to delete (not cache) the pPreStmt */ | 1236 int discard /* True to delete (not cache) the pPreStmt */ |
1197 ){ | 1237 ){ |
1198 int i; | 1238 int i; |
1199 | 1239 |
1200 /* Free the bound string and blob parameters */ | 1240 /* Free the bound string and blob parameters */ |
1201 for(i=0; i<pPreStmt->nParm; i++){ | 1241 for(i=0; i<pPreStmt->nParm; i++){ |
1202 Tcl_DecrRefCount(pPreStmt->apParm[i]); | 1242 Tcl_DecrRefCount(pPreStmt->apParm[i]); |
1203 } | 1243 } |
1204 pPreStmt->nParm = 0; | 1244 pPreStmt->nParm = 0; |
1205 | 1245 |
1206 if( pDb->maxStmt<=0 || discard ){ | 1246 if( pDb->maxStmt<=0 || discard ){ |
1207 /* If the cache is turned off, deallocated the statement */ | 1247 /* If the cache is turned off, deallocated the statement */ |
1208 sqlite3_finalize(pPreStmt->pStmt); | 1248 dbFreeStmt(pPreStmt); |
1209 Tcl_Free((char *)pPreStmt); | |
1210 }else{ | 1249 }else{ |
1211 /* Add the prepared statement to the beginning of the cache list. */ | 1250 /* Add the prepared statement to the beginning of the cache list. */ |
1212 pPreStmt->pNext = pDb->stmtList; | 1251 pPreStmt->pNext = pDb->stmtList; |
1213 pPreStmt->pPrev = 0; | 1252 pPreStmt->pPrev = 0; |
1214 if( pDb->stmtList ){ | 1253 if( pDb->stmtList ){ |
1215 pDb->stmtList->pPrev = pPreStmt; | 1254 pDb->stmtList->pPrev = pPreStmt; |
1216 } | 1255 } |
1217 pDb->stmtList = pPreStmt; | 1256 pDb->stmtList = pPreStmt; |
1218 if( pDb->stmtLast==0 ){ | 1257 if( pDb->stmtLast==0 ){ |
1219 assert( pDb->nStmt==0 ); | 1258 assert( pDb->nStmt==0 ); |
1220 pDb->stmtLast = pPreStmt; | 1259 pDb->stmtLast = pPreStmt; |
1221 }else{ | 1260 }else{ |
1222 assert( pDb->nStmt>0 ); | 1261 assert( pDb->nStmt>0 ); |
1223 } | 1262 } |
1224 pDb->nStmt++; | 1263 pDb->nStmt++; |
1225 | 1264 |
1226 /* If we have too many statement in cache, remove the surplus from | 1265 /* If we have too many statement in cache, remove the surplus from |
1227 ** the end of the cache list. */ | 1266 ** the end of the cache list. */ |
1228 while( pDb->nStmt>pDb->maxStmt ){ | 1267 while( pDb->nStmt>pDb->maxStmt ){ |
1229 sqlite3_finalize(pDb->stmtLast->pStmt); | 1268 SqlPreparedStmt *pLast = pDb->stmtLast; |
1230 pDb->stmtLast = pDb->stmtLast->pPrev; | 1269 pDb->stmtLast = pLast->pPrev; |
1231 Tcl_Free((char*)pDb->stmtLast->pNext); | |
1232 pDb->stmtLast->pNext = 0; | 1270 pDb->stmtLast->pNext = 0; |
1233 pDb->nStmt--; | 1271 pDb->nStmt--; |
| 1272 dbFreeStmt(pLast); |
1234 } | 1273 } |
1235 } | 1274 } |
1236 } | 1275 } |
1237 | 1276 |
1238 /* | 1277 /* |
1239 ** Structure used with dbEvalXXX() functions: | 1278 ** Structure used with dbEvalXXX() functions: |
1240 ** | 1279 ** |
1241 ** dbEvalInit() | 1280 ** dbEvalInit() |
1242 ** dbEvalStep() | 1281 ** dbEvalStep() |
1243 ** dbEvalFinalize() | 1282 ** dbEvalFinalize() |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1313 if( 0==p->apColName ){ | 1352 if( 0==p->apColName ){ |
1314 sqlite3_stmt *pStmt = p->pPreStmt->pStmt; | 1353 sqlite3_stmt *pStmt = p->pPreStmt->pStmt; |
1315 int i; /* Iterator variable */ | 1354 int i; /* Iterator variable */ |
1316 int nCol; /* Number of columns returned by pStmt */ | 1355 int nCol; /* Number of columns returned by pStmt */ |
1317 Tcl_Obj **apColName = 0; /* Array of column names */ | 1356 Tcl_Obj **apColName = 0; /* Array of column names */ |
1318 | 1357 |
1319 p->nCol = nCol = sqlite3_column_count(pStmt); | 1358 p->nCol = nCol = sqlite3_column_count(pStmt); |
1320 if( nCol>0 && (papColName || p->pArray) ){ | 1359 if( nCol>0 && (papColName || p->pArray) ){ |
1321 apColName = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*)*nCol ); | 1360 apColName = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*)*nCol ); |
1322 for(i=0; i<nCol; i++){ | 1361 for(i=0; i<nCol; i++){ |
1323 apColName[i] = dbTextToObj(sqlite3_column_name(pStmt,i)); | 1362 apColName[i] = Tcl_NewStringObj(sqlite3_column_name(pStmt,i), -1); |
1324 Tcl_IncrRefCount(apColName[i]); | 1363 Tcl_IncrRefCount(apColName[i]); |
1325 } | 1364 } |
1326 p->apColName = apColName; | 1365 p->apColName = apColName; |
1327 } | 1366 } |
1328 | 1367 |
1329 /* If results are being stored in an array variable, then create | 1368 /* If results are being stored in an array variable, then create |
1330 ** the array(*) entry for that array | 1369 ** the array(*) entry for that array |
1331 */ | 1370 */ |
1332 if( p->pArray ){ | 1371 if( p->pArray ){ |
1333 Tcl_Interp *interp = p->pDb->interp; | 1372 Tcl_Interp *interp = p->pDb->interp; |
(...skipping 22 matching lines...) Expand all Loading... |
1356 ** returned, then an error message is stored in the interpreter before | 1395 ** returned, then an error message is stored in the interpreter before |
1357 ** returning. | 1396 ** returning. |
1358 ** | 1397 ** |
1359 ** A return value of TCL_OK means there is a row of data available. The | 1398 ** A return value of TCL_OK means there is a row of data available. The |
1360 ** data may be accessed using dbEvalRowInfo() and dbEvalColumnValue(). This | 1399 ** data may be accessed using dbEvalRowInfo() and dbEvalColumnValue(). This |
1361 ** is analogous to a return of SQLITE_ROW from sqlite3_step(). If TCL_BREAK | 1400 ** is analogous to a return of SQLITE_ROW from sqlite3_step(). If TCL_BREAK |
1362 ** is returned, then the SQL script has finished executing and there are | 1401 ** is returned, then the SQL script has finished executing and there are |
1363 ** no further rows available. This is similar to SQLITE_DONE. | 1402 ** no further rows available. This is similar to SQLITE_DONE. |
1364 */ | 1403 */ |
1365 static int dbEvalStep(DbEvalContext *p){ | 1404 static int dbEvalStep(DbEvalContext *p){ |
| 1405 const char *zPrevSql = 0; /* Previous value of p->zSql */ |
| 1406 |
1366 while( p->zSql[0] || p->pPreStmt ){ | 1407 while( p->zSql[0] || p->pPreStmt ){ |
1367 int rc; | 1408 int rc; |
1368 if( p->pPreStmt==0 ){ | 1409 if( p->pPreStmt==0 ){ |
| 1410 zPrevSql = (p->zSql==zPrevSql ? 0 : p->zSql); |
1369 rc = dbPrepareAndBind(p->pDb, p->zSql, &p->zSql, &p->pPreStmt); | 1411 rc = dbPrepareAndBind(p->pDb, p->zSql, &p->zSql, &p->pPreStmt); |
1370 if( rc!=TCL_OK ) return rc; | 1412 if( rc!=TCL_OK ) return rc; |
1371 }else{ | 1413 }else{ |
1372 int rcs; | 1414 int rcs; |
1373 SqliteDb *pDb = p->pDb; | 1415 SqliteDb *pDb = p->pDb; |
1374 SqlPreparedStmt *pPreStmt = p->pPreStmt; | 1416 SqlPreparedStmt *pPreStmt = p->pPreStmt; |
1375 sqlite3_stmt *pStmt = pPreStmt->pStmt; | 1417 sqlite3_stmt *pStmt = pPreStmt->pStmt; |
1376 | 1418 |
1377 rcs = sqlite3_step(pStmt); | 1419 rcs = sqlite3_step(pStmt); |
1378 if( rcs==SQLITE_ROW ){ | 1420 if( rcs==SQLITE_ROW ){ |
1379 return TCL_OK; | 1421 return TCL_OK; |
1380 } | 1422 } |
1381 if( p->pArray ){ | 1423 if( p->pArray ){ |
1382 dbEvalRowInfo(p, 0, 0); | 1424 dbEvalRowInfo(p, 0, 0); |
1383 } | 1425 } |
1384 rcs = sqlite3_reset(pStmt); | 1426 rcs = sqlite3_reset(pStmt); |
1385 | 1427 |
1386 pDb->nStep = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_FULLSCAN_STEP,1); | 1428 pDb->nStep = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_FULLSCAN_STEP,1); |
1387 pDb->nSort = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_SORT,1); | 1429 pDb->nSort = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_SORT,1); |
1388 pDb->nIndex = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_AUTOINDEX,1); | 1430 pDb->nIndex = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_AUTOINDEX,1); |
1389 dbReleaseColumnNames(p); | 1431 dbReleaseColumnNames(p); |
1390 p->pPreStmt = 0; | 1432 p->pPreStmt = 0; |
1391 | 1433 |
1392 if( rcs!=SQLITE_OK ){ | 1434 if( rcs!=SQLITE_OK ){ |
1393 /* If a run-time error occurs, report the error and stop reading | 1435 /* If a run-time error occurs, report the error and stop reading |
1394 ** the SQL. */ | 1436 ** the SQL. */ |
1395 Tcl_SetObjResult(pDb->interp, dbTextToObj(sqlite3_errmsg(pDb->db))); | |
1396 dbReleaseStmt(pDb, pPreStmt, 1); | 1437 dbReleaseStmt(pDb, pPreStmt, 1); |
| 1438 #if SQLITE_TEST |
| 1439 if( p->pDb->bLegacyPrepare && rcs==SQLITE_SCHEMA && zPrevSql ){ |
| 1440 /* If the runtime error was an SQLITE_SCHEMA, and the database |
| 1441 ** handle is configured to use the legacy sqlite3_prepare() |
| 1442 ** interface, retry prepare()/step() on the same SQL statement. |
| 1443 ** This only happens once. If there is a second SQLITE_SCHEMA |
| 1444 ** error, the error will be returned to the caller. */ |
| 1445 p->zSql = zPrevSql; |
| 1446 continue; |
| 1447 } |
| 1448 #endif |
| 1449 Tcl_SetObjResult(pDb->interp, |
| 1450 Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1)); |
1397 return TCL_ERROR; | 1451 return TCL_ERROR; |
1398 }else{ | 1452 }else{ |
1399 dbReleaseStmt(pDb, pPreStmt, 0); | 1453 dbReleaseStmt(pDb, pPreStmt, 0); |
1400 } | 1454 } |
1401 } | 1455 } |
1402 } | 1456 } |
1403 | 1457 |
1404 /* Finished */ | 1458 /* Finished */ |
1405 return TCL_BREAK; | 1459 return TCL_BREAK; |
1406 } | 1460 } |
(...skipping 27 matching lines...) Expand all Loading... |
1434 switch( sqlite3_column_type(pStmt, iCol) ){ | 1488 switch( sqlite3_column_type(pStmt, iCol) ){ |
1435 case SQLITE_BLOB: { | 1489 case SQLITE_BLOB: { |
1436 int bytes = sqlite3_column_bytes(pStmt, iCol); | 1490 int bytes = sqlite3_column_bytes(pStmt, iCol); |
1437 const char *zBlob = sqlite3_column_blob(pStmt, iCol); | 1491 const char *zBlob = sqlite3_column_blob(pStmt, iCol); |
1438 if( !zBlob ) bytes = 0; | 1492 if( !zBlob ) bytes = 0; |
1439 return Tcl_NewByteArrayObj((u8*)zBlob, bytes); | 1493 return Tcl_NewByteArrayObj((u8*)zBlob, bytes); |
1440 } | 1494 } |
1441 case SQLITE_INTEGER: { | 1495 case SQLITE_INTEGER: { |
1442 sqlite_int64 v = sqlite3_column_int64(pStmt, iCol); | 1496 sqlite_int64 v = sqlite3_column_int64(pStmt, iCol); |
1443 if( v>=-2147483647 && v<=2147483647 ){ | 1497 if( v>=-2147483647 && v<=2147483647 ){ |
1444 return Tcl_NewIntObj(v); | 1498 return Tcl_NewIntObj((int)v); |
1445 }else{ | 1499 }else{ |
1446 return Tcl_NewWideIntObj(v); | 1500 return Tcl_NewWideIntObj(v); |
1447 } | 1501 } |
1448 } | 1502 } |
1449 case SQLITE_FLOAT: { | 1503 case SQLITE_FLOAT: { |
1450 return Tcl_NewDoubleObj(sqlite3_column_double(pStmt, iCol)); | 1504 return Tcl_NewDoubleObj(sqlite3_column_double(pStmt, iCol)); |
1451 } | 1505 } |
1452 case SQLITE_NULL: { | 1506 case SQLITE_NULL: { |
1453 return dbTextToObj(p->pDb->zNull); | 1507 return Tcl_NewStringObj(p->pDb->zNull, -1); |
1454 } | 1508 } |
1455 } | 1509 } |
1456 | 1510 |
1457 return dbTextToObj((char *)sqlite3_column_text(pStmt, iCol)); | 1511 return Tcl_NewStringObj((char*)sqlite3_column_text(pStmt, iCol), -1); |
1458 } | 1512 } |
1459 | 1513 |
1460 /* | 1514 /* |
1461 ** If using Tcl version 8.6 or greater, use the NR functions to avoid | 1515 ** If using Tcl version 8.6 or greater, use the NR functions to avoid |
1462 ** recursive evalution of scripts by the [db eval] and [db trans] | 1516 ** recursive evalution of scripts by the [db eval] and [db trans] |
1463 ** commands. Even if the headers used while compiling the extension | 1517 ** commands. Even if the headers used while compiling the extension |
1464 ** are 8.6 or newer, the code still tests the Tcl version at runtime. | 1518 ** are 8.6 or newer, the code still tests the Tcl version at runtime. |
1465 ** This allows stubs-enabled builds to be used with older Tcl libraries. | 1519 ** This allows stubs-enabled builds to be used with older Tcl libraries. |
1466 */ | 1520 */ |
1467 #if TCL_MAJOR_VERSION>8 || (TCL_MAJOR_VERSION==8 && TCL_MINOR_VERSION>=6) | 1521 #if TCL_MAJOR_VERSION>8 || (TCL_MAJOR_VERSION==8 && TCL_MINOR_VERSION>=6) |
1468 # define SQLITE_TCL_NRE 1 | 1522 # define SQLITE_TCL_NRE 1 |
1469 static int DbUseNre(void){ | 1523 static int DbUseNre(void){ |
1470 int major, minor; | 1524 int major, minor; |
1471 Tcl_GetVersion(&major, &minor, 0, 0); | 1525 Tcl_GetVersion(&major, &minor, 0, 0); |
1472 return( (major==8 && minor>=6) || major>8 ); | 1526 return( (major==8 && minor>=6) || major>8 ); |
1473 } | 1527 } |
1474 #else | 1528 #else |
1475 /* | 1529 /* |
1476 ** Compiling using headers earlier than 8.6. In this case NR cannot be | 1530 ** Compiling using headers earlier than 8.6. In this case NR cannot be |
1477 ** used, so DbUseNre() to always return zero. Add #defines for the other | 1531 ** used, so DbUseNre() to always return zero. Add #defines for the other |
1478 ** Tcl_NRxxx() functions to prevent them from causing compilation errors, | 1532 ** Tcl_NRxxx() functions to prevent them from causing compilation errors, |
1479 ** even though the only invocations of them are within conditional blocks | 1533 ** even though the only invocations of them are within conditional blocks |
1480 ** of the form: | 1534 ** of the form: |
1481 ** | 1535 ** |
1482 ** if( DbUseNre() ) { ... } | 1536 ** if( DbUseNre() ) { ... } |
1483 */ | 1537 */ |
1484 # define SQLITE_TCL_NRE 0 | 1538 # define SQLITE_TCL_NRE 0 |
1485 # define DbUseNre() 0 | 1539 # define DbUseNre() 0 |
1486 # define Tcl_NRAddCallback(a,b,c,d,e,f) 0 | 1540 # define Tcl_NRAddCallback(a,b,c,d,e,f) (void)0 |
1487 # define Tcl_NREvalObj(a,b,c) 0 | 1541 # define Tcl_NREvalObj(a,b,c) 0 |
1488 # define Tcl_NRCreateCommand(a,b,c,d,e,f) 0 | 1542 # define Tcl_NRCreateCommand(a,b,c,d,e,f) (void)0 |
1489 #endif | 1543 #endif |
1490 | 1544 |
1491 /* | 1545 /* |
1492 ** This function is part of the implementation of the command: | 1546 ** This function is part of the implementation of the command: |
1493 ** | 1547 ** |
1494 ** $db eval SQL ?ARRAYNAME? SCRIPT | 1548 ** $db eval SQL ?ARRAYNAME? SCRIPT |
1495 */ | 1549 */ |
1496 static int DbEvalNextCmd( | 1550 static int DbEvalNextCmd( |
1497 ClientData data[], /* data[0] is the (DbEvalContext*) */ | 1551 ClientData data[], /* data[0] is the (DbEvalContext*) */ |
1498 Tcl_Interp *interp, /* Tcl interpreter */ | 1552 Tcl_Interp *interp, /* Tcl interpreter */ |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1620 ** (5) Name of trigger that is doing the access | 1674 ** (5) Name of trigger that is doing the access |
1621 ** | 1675 ** |
1622 ** The callback should return on of the following strings: SQLITE_OK, | 1676 ** The callback should return on of the following strings: SQLITE_OK, |
1623 ** SQLITE_IGNORE, or SQLITE_DENY. Any other return value is an error. | 1677 ** SQLITE_IGNORE, or SQLITE_DENY. Any other return value is an error. |
1624 ** | 1678 ** |
1625 ** If this method is invoked with no arguments, the current authorization | 1679 ** If this method is invoked with no arguments, the current authorization |
1626 ** callback string is returned. | 1680 ** callback string is returned. |
1627 */ | 1681 */ |
1628 case DB_AUTHORIZER: { | 1682 case DB_AUTHORIZER: { |
1629 #ifdef SQLITE_OMIT_AUTHORIZATION | 1683 #ifdef SQLITE_OMIT_AUTHORIZATION |
1630 Tcl_AppendResult(interp, "authorization not available in this build", 0); | 1684 Tcl_AppendResult(interp, "authorization not available in this build", |
| 1685 (char*)0); |
1631 return TCL_ERROR; | 1686 return TCL_ERROR; |
1632 #else | 1687 #else |
1633 if( objc>3 ){ | 1688 if( objc>3 ){ |
1634 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); | 1689 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); |
1635 return TCL_ERROR; | 1690 return TCL_ERROR; |
1636 }else if( objc==2 ){ | 1691 }else if( objc==2 ){ |
1637 if( pDb->zAuth ){ | 1692 if( pDb->zAuth ){ |
1638 Tcl_AppendResult(interp, pDb->zAuth, 0); | 1693 Tcl_AppendResult(interp, pDb->zAuth, (char*)0); |
1639 } | 1694 } |
1640 }else{ | 1695 }else{ |
1641 char *zAuth; | 1696 char *zAuth; |
1642 int len; | 1697 int len; |
1643 if( pDb->zAuth ){ | 1698 if( pDb->zAuth ){ |
1644 Tcl_Free(pDb->zAuth); | 1699 Tcl_Free(pDb->zAuth); |
1645 } | 1700 } |
1646 zAuth = Tcl_GetStringFromObj(objv[2], &len); | 1701 zAuth = Tcl_GetStringFromObj(objv[2], &len); |
1647 if( zAuth && len>0 ){ | 1702 if( zAuth && len>0 ){ |
1648 pDb->zAuth = Tcl_Alloc( len + 1 ); | 1703 pDb->zAuth = Tcl_Alloc( len + 1 ); |
1649 memcpy(pDb->zAuth, zAuth, len+1); | 1704 memcpy(pDb->zAuth, zAuth, len+1); |
1650 }else{ | 1705 }else{ |
1651 pDb->zAuth = 0; | 1706 pDb->zAuth = 0; |
1652 } | 1707 } |
1653 if( pDb->zAuth ){ | 1708 if( pDb->zAuth ){ |
| 1709 typedef int (*sqlite3_auth_cb)( |
| 1710 void*,int,const char*,const char*, |
| 1711 const char*,const char*); |
1654 pDb->interp = interp; | 1712 pDb->interp = interp; |
1655 sqlite3_set_authorizer(pDb->db, auth_callback, pDb); | 1713 sqlite3_set_authorizer(pDb->db,(sqlite3_auth_cb)auth_callback,pDb); |
1656 }else{ | 1714 }else{ |
1657 sqlite3_set_authorizer(pDb->db, 0, 0); | 1715 sqlite3_set_authorizer(pDb->db, 0, 0); |
1658 } | 1716 } |
1659 } | 1717 } |
1660 #endif | 1718 #endif |
1661 break; | 1719 break; |
1662 } | 1720 } |
1663 | 1721 |
1664 /* $db backup ?DATABASE? FILENAME | 1722 /* $db backup ?DATABASE? FILENAME |
1665 ** | 1723 ** |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1714 ** | 1772 ** |
1715 ** Invoke the given callback if an SQL statement attempts to open | 1773 ** Invoke the given callback if an SQL statement attempts to open |
1716 ** a locked database file. | 1774 ** a locked database file. |
1717 */ | 1775 */ |
1718 case DB_BUSY: { | 1776 case DB_BUSY: { |
1719 if( objc>3 ){ | 1777 if( objc>3 ){ |
1720 Tcl_WrongNumArgs(interp, 2, objv, "CALLBACK"); | 1778 Tcl_WrongNumArgs(interp, 2, objv, "CALLBACK"); |
1721 return TCL_ERROR; | 1779 return TCL_ERROR; |
1722 }else if( objc==2 ){ | 1780 }else if( objc==2 ){ |
1723 if( pDb->zBusy ){ | 1781 if( pDb->zBusy ){ |
1724 Tcl_AppendResult(interp, pDb->zBusy, 0); | 1782 Tcl_AppendResult(interp, pDb->zBusy, (char*)0); |
1725 } | 1783 } |
1726 }else{ | 1784 }else{ |
1727 char *zBusy; | 1785 char *zBusy; |
1728 int len; | 1786 int len; |
1729 if( pDb->zBusy ){ | 1787 if( pDb->zBusy ){ |
1730 Tcl_Free(pDb->zBusy); | 1788 Tcl_Free(pDb->zBusy); |
1731 } | 1789 } |
1732 zBusy = Tcl_GetStringFromObj(objv[2], &len); | 1790 zBusy = Tcl_GetStringFromObj(objv[2], &len); |
1733 if( zBusy && len>0 ){ | 1791 if( zBusy && len>0 ){ |
1734 pDb->zBusy = Tcl_Alloc( len + 1 ); | 1792 pDb->zBusy = Tcl_Alloc( len + 1 ); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1768 }else{ | 1826 }else{ |
1769 flushStmtCache( pDb ); | 1827 flushStmtCache( pDb ); |
1770 } | 1828 } |
1771 }else if( *subCmd=='s' && strcmp(subCmd,"size")==0 ){ | 1829 }else if( *subCmd=='s' && strcmp(subCmd,"size")==0 ){ |
1772 if( objc!=4 ){ | 1830 if( objc!=4 ){ |
1773 Tcl_WrongNumArgs(interp, 2, objv, "size n"); | 1831 Tcl_WrongNumArgs(interp, 2, objv, "size n"); |
1774 return TCL_ERROR; | 1832 return TCL_ERROR; |
1775 }else{ | 1833 }else{ |
1776 if( TCL_ERROR==Tcl_GetIntFromObj(interp, objv[3], &n) ){ | 1834 if( TCL_ERROR==Tcl_GetIntFromObj(interp, objv[3], &n) ){ |
1777 Tcl_AppendResult( interp, "cannot convert \"", | 1835 Tcl_AppendResult( interp, "cannot convert \"", |
1778 Tcl_GetStringFromObj(objv[3],0), "\" to integer", 0); | 1836 Tcl_GetStringFromObj(objv[3],0), "\" to integer", (char*)0); |
1779 return TCL_ERROR; | 1837 return TCL_ERROR; |
1780 }else{ | 1838 }else{ |
1781 if( n<0 ){ | 1839 if( n<0 ){ |
1782 flushStmtCache( pDb ); | 1840 flushStmtCache( pDb ); |
1783 n = 0; | 1841 n = 0; |
1784 }else if( n>MAX_PREPARED_STMTS ){ | 1842 }else if( n>MAX_PREPARED_STMTS ){ |
1785 n = MAX_PREPARED_STMTS; | 1843 n = MAX_PREPARED_STMTS; |
1786 } | 1844 } |
1787 pDb->maxStmt = n; | 1845 pDb->maxStmt = n; |
1788 } | 1846 } |
1789 } | 1847 } |
1790 }else{ | 1848 }else{ |
1791 Tcl_AppendResult( interp, "bad option \"", | 1849 Tcl_AppendResult( interp, "bad option \"", |
1792 Tcl_GetStringFromObj(objv[2],0), "\": must be flush or size", 0); | 1850 Tcl_GetStringFromObj(objv[2],0), "\": must be flush or size", |
| 1851 (char*)0); |
1793 return TCL_ERROR; | 1852 return TCL_ERROR; |
1794 } | 1853 } |
1795 break; | 1854 break; |
1796 } | 1855 } |
1797 | 1856 |
1798 /* $db changes | 1857 /* $db changes |
1799 ** | 1858 ** |
1800 ** Return the number of rows that were modified, inserted, or deleted by | 1859 ** Return the number of rows that were modified, inserted, or deleted by |
1801 ** the most recent INSERT, UPDATE or DELETE statement, not including | 1860 ** the most recent INSERT, UPDATE or DELETE statement, not including |
1802 ** any changes made by trigger programs. | 1861 ** any changes made by trigger programs. |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1879 ** If the callback throws an exception or returns non-zero, then the | 1938 ** If the callback throws an exception or returns non-zero, then the |
1880 ** transaction is aborted. If CALLBACK is an empty string, the callback | 1939 ** transaction is aborted. If CALLBACK is an empty string, the callback |
1881 ** is disabled. | 1940 ** is disabled. |
1882 */ | 1941 */ |
1883 case DB_COMMIT_HOOK: { | 1942 case DB_COMMIT_HOOK: { |
1884 if( objc>3 ){ | 1943 if( objc>3 ){ |
1885 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); | 1944 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); |
1886 return TCL_ERROR; | 1945 return TCL_ERROR; |
1887 }else if( objc==2 ){ | 1946 }else if( objc==2 ){ |
1888 if( pDb->zCommit ){ | 1947 if( pDb->zCommit ){ |
1889 Tcl_AppendResult(interp, pDb->zCommit, 0); | 1948 Tcl_AppendResult(interp, pDb->zCommit, (char*)0); |
1890 } | 1949 } |
1891 }else{ | 1950 }else{ |
1892 char *zCommit; | 1951 const char *zCommit; |
1893 int len; | 1952 int len; |
1894 if( pDb->zCommit ){ | 1953 if( pDb->zCommit ){ |
1895 Tcl_Free(pDb->zCommit); | 1954 Tcl_Free(pDb->zCommit); |
1896 } | 1955 } |
1897 zCommit = Tcl_GetStringFromObj(objv[2], &len); | 1956 zCommit = Tcl_GetStringFromObj(objv[2], &len); |
1898 if( zCommit && len>0 ){ | 1957 if( zCommit && len>0 ){ |
1899 pDb->zCommit = Tcl_Alloc( len + 1 ); | 1958 pDb->zCommit = Tcl_Alloc( len + 1 ); |
1900 memcpy(pDb->zCommit, zCommit, len+1); | 1959 memcpy(pDb->zCommit, zCommit, len+1); |
1901 }else{ | 1960 }else{ |
1902 pDb->zCommit = 0; | 1961 pDb->zCommit = 0; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1955 char *zConflict; /* The conflict algorithm to use */ | 2014 char *zConflict; /* The conflict algorithm to use */ |
1956 sqlite3_stmt *pStmt; /* A statement */ | 2015 sqlite3_stmt *pStmt; /* A statement */ |
1957 int nCol; /* Number of columns in the table */ | 2016 int nCol; /* Number of columns in the table */ |
1958 int nByte; /* Number of bytes in an SQL string */ | 2017 int nByte; /* Number of bytes in an SQL string */ |
1959 int i, j; /* Loop counters */ | 2018 int i, j; /* Loop counters */ |
1960 int nSep; /* Number of bytes in zSep[] */ | 2019 int nSep; /* Number of bytes in zSep[] */ |
1961 int nNull; /* Number of bytes in zNull[] */ | 2020 int nNull; /* Number of bytes in zNull[] */ |
1962 char *zSql; /* An SQL statement */ | 2021 char *zSql; /* An SQL statement */ |
1963 char *zLine; /* A single line of input from the file */ | 2022 char *zLine; /* A single line of input from the file */ |
1964 char **azCol; /* zLine[] broken up into columns */ | 2023 char **azCol; /* zLine[] broken up into columns */ |
1965 char *zCommit; /* How to commit changes */ | 2024 const char *zCommit; /* How to commit changes */ |
1966 FILE *in; /* The input file */ | 2025 FILE *in; /* The input file */ |
1967 int lineno = 0; /* Line number of input file */ | 2026 int lineno = 0; /* Line number of input file */ |
1968 char zLineNum[80]; /* Line number print buffer */ | 2027 char zLineNum[80]; /* Line number print buffer */ |
1969 Tcl_Obj *pResult; /* interp result */ | 2028 Tcl_Obj *pResult; /* interp result */ |
1970 | 2029 |
1971 char *zSep; | 2030 const char *zSep; |
1972 char *zNull; | 2031 const char *zNull; |
1973 if( objc<5 || objc>7 ){ | 2032 if( objc<5 || objc>7 ){ |
1974 Tcl_WrongNumArgs(interp, 2, objv, | 2033 Tcl_WrongNumArgs(interp, 2, objv, |
1975 "CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?"); | 2034 "CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?"); |
1976 return TCL_ERROR; | 2035 return TCL_ERROR; |
1977 } | 2036 } |
1978 if( objc>=6 ){ | 2037 if( objc>=6 ){ |
1979 zSep = Tcl_GetStringFromObj(objv[5], 0); | 2038 zSep = Tcl_GetStringFromObj(objv[5], 0); |
1980 }else{ | 2039 }else{ |
1981 zSep = "\t"; | 2040 zSep = "\t"; |
1982 } | 2041 } |
1983 if( objc>=7 ){ | 2042 if( objc>=7 ){ |
1984 zNull = Tcl_GetStringFromObj(objv[6], 0); | 2043 zNull = Tcl_GetStringFromObj(objv[6], 0); |
1985 }else{ | 2044 }else{ |
1986 zNull = ""; | 2045 zNull = ""; |
1987 } | 2046 } |
1988 zConflict = Tcl_GetStringFromObj(objv[2], 0); | 2047 zConflict = Tcl_GetStringFromObj(objv[2], 0); |
1989 zTable = Tcl_GetStringFromObj(objv[3], 0); | 2048 zTable = Tcl_GetStringFromObj(objv[3], 0); |
1990 zFile = Tcl_GetStringFromObj(objv[4], 0); | 2049 zFile = Tcl_GetStringFromObj(objv[4], 0); |
1991 nSep = strlen30(zSep); | 2050 nSep = strlen30(zSep); |
1992 nNull = strlen30(zNull); | 2051 nNull = strlen30(zNull); |
1993 if( nSep==0 ){ | 2052 if( nSep==0 ){ |
1994 Tcl_AppendResult(interp,"Error: non-null separator required for copy",0); | 2053 Tcl_AppendResult(interp,"Error: non-null separator required for copy", |
| 2054 (char*)0); |
1995 return TCL_ERROR; | 2055 return TCL_ERROR; |
1996 } | 2056 } |
1997 if(strcmp(zConflict, "rollback") != 0 && | 2057 if(strcmp(zConflict, "rollback") != 0 && |
1998 strcmp(zConflict, "abort" ) != 0 && | 2058 strcmp(zConflict, "abort" ) != 0 && |
1999 strcmp(zConflict, "fail" ) != 0 && | 2059 strcmp(zConflict, "fail" ) != 0 && |
2000 strcmp(zConflict, "ignore" ) != 0 && | 2060 strcmp(zConflict, "ignore" ) != 0 && |
2001 strcmp(zConflict, "replace" ) != 0 ) { | 2061 strcmp(zConflict, "replace" ) != 0 ) { |
2002 Tcl_AppendResult(interp, "Error: \"", zConflict, | 2062 Tcl_AppendResult(interp, "Error: \"", zConflict, |
2003 "\", conflict-algorithm must be one of: rollback, " | 2063 "\", conflict-algorithm must be one of: rollback, " |
2004 "abort, fail, ignore, or replace", 0); | 2064 "abort, fail, ignore, or replace", (char*)0); |
2005 return TCL_ERROR; | 2065 return TCL_ERROR; |
2006 } | 2066 } |
2007 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable); | 2067 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable); |
2008 if( zSql==0 ){ | 2068 if( zSql==0 ){ |
2009 Tcl_AppendResult(interp, "Error: no such table: ", zTable, 0); | 2069 Tcl_AppendResult(interp, "Error: no such table: ", zTable, (char*)0); |
2010 return TCL_ERROR; | 2070 return TCL_ERROR; |
2011 } | 2071 } |
2012 nByte = strlen30(zSql); | 2072 nByte = strlen30(zSql); |
2013 rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0); | 2073 rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0); |
2014 sqlite3_free(zSql); | 2074 sqlite3_free(zSql); |
2015 if( rc ){ | 2075 if( rc ){ |
2016 Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), 0); | 2076 Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), (char*)0); |
2017 nCol = 0; | 2077 nCol = 0; |
2018 }else{ | 2078 }else{ |
2019 nCol = sqlite3_column_count(pStmt); | 2079 nCol = sqlite3_column_count(pStmt); |
2020 } | 2080 } |
2021 sqlite3_finalize(pStmt); | 2081 sqlite3_finalize(pStmt); |
2022 if( nCol==0 ) { | 2082 if( nCol==0 ) { |
2023 return TCL_ERROR; | 2083 return TCL_ERROR; |
2024 } | 2084 } |
2025 zSql = malloc( nByte + 50 + nCol*2 ); | 2085 zSql = malloc( nByte + 50 + nCol*2 ); |
2026 if( zSql==0 ) { | 2086 if( zSql==0 ) { |
2027 Tcl_AppendResult(interp, "Error: can't malloc()", 0); | 2087 Tcl_AppendResult(interp, "Error: can't malloc()", (char*)0); |
2028 return TCL_ERROR; | 2088 return TCL_ERROR; |
2029 } | 2089 } |
2030 sqlite3_snprintf(nByte+50, zSql, "INSERT OR %q INTO '%q' VALUES(?", | 2090 sqlite3_snprintf(nByte+50, zSql, "INSERT OR %q INTO '%q' VALUES(?", |
2031 zConflict, zTable); | 2091 zConflict, zTable); |
2032 j = strlen30(zSql); | 2092 j = strlen30(zSql); |
2033 for(i=1; i<nCol; i++){ | 2093 for(i=1; i<nCol; i++){ |
2034 zSql[j++] = ','; | 2094 zSql[j++] = ','; |
2035 zSql[j++] = '?'; | 2095 zSql[j++] = '?'; |
2036 } | 2096 } |
2037 zSql[j++] = ')'; | 2097 zSql[j++] = ')'; |
2038 zSql[j] = 0; | 2098 zSql[j] = 0; |
2039 rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0); | 2099 rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0); |
2040 free(zSql); | 2100 free(zSql); |
2041 if( rc ){ | 2101 if( rc ){ |
2042 Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), 0); | 2102 Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), (char*)0); |
2043 sqlite3_finalize(pStmt); | 2103 sqlite3_finalize(pStmt); |
2044 return TCL_ERROR; | 2104 return TCL_ERROR; |
2045 } | 2105 } |
2046 in = fopen(zFile, "rb"); | 2106 in = fopen(zFile, "rb"); |
2047 if( in==0 ){ | 2107 if( in==0 ){ |
2048 Tcl_AppendResult(interp, "Error: cannot open file: ", zFile, NULL); | 2108 Tcl_AppendResult(interp, "Error: cannot open file: ", zFile, NULL); |
2049 sqlite3_finalize(pStmt); | 2109 sqlite3_finalize(pStmt); |
2050 return TCL_ERROR; | 2110 return TCL_ERROR; |
2051 } | 2111 } |
2052 azCol = malloc( sizeof(azCol[0])*(nCol+1) ); | 2112 azCol = malloc( sizeof(azCol[0])*(nCol+1) ); |
2053 if( azCol==0 ) { | 2113 if( azCol==0 ) { |
2054 Tcl_AppendResult(interp, "Error: can't malloc()", 0); | 2114 Tcl_AppendResult(interp, "Error: can't malloc()", (char*)0); |
2055 fclose(in); | 2115 fclose(in); |
2056 return TCL_ERROR; | 2116 return TCL_ERROR; |
2057 } | 2117 } |
2058 (void)sqlite3_exec(pDb->db, "BEGIN", 0, 0, 0); | 2118 (void)sqlite3_exec(pDb->db, "BEGIN", 0, 0, 0); |
2059 zCommit = "COMMIT"; | 2119 zCommit = "COMMIT"; |
2060 while( (zLine = local_getline(0, in))!=0 ){ | 2120 while( (zLine = local_getline(0, in))!=0 ){ |
2061 char *z; | 2121 char *z; |
2062 i = 0; | |
2063 lineno++; | 2122 lineno++; |
2064 azCol[0] = zLine; | 2123 azCol[0] = zLine; |
2065 for(i=0, z=zLine; *z; z++){ | 2124 for(i=0, z=zLine; *z; z++){ |
2066 if( *z==zSep[0] && strncmp(z, zSep, nSep)==0 ){ | 2125 if( *z==zSep[0] && strncmp(z, zSep, nSep)==0 ){ |
2067 *z = 0; | 2126 *z = 0; |
2068 i++; | 2127 i++; |
2069 if( i<nCol ){ | 2128 if( i<nCol ){ |
2070 azCol[i] = &z[nSep]; | 2129 azCol[i] = &z[nSep]; |
2071 z += nSep-1; | 2130 z += nSep-1; |
2072 } | 2131 } |
2073 } | 2132 } |
2074 } | 2133 } |
2075 if( i+1!=nCol ){ | 2134 if( i+1!=nCol ){ |
2076 char *zErr; | 2135 char *zErr; |
2077 int nErr = strlen30(zFile) + 200; | 2136 int nErr = strlen30(zFile) + 200; |
2078 zErr = malloc(nErr); | 2137 zErr = malloc(nErr); |
2079 if( zErr ){ | 2138 if( zErr ){ |
2080 sqlite3_snprintf(nErr, zErr, | 2139 sqlite3_snprintf(nErr, zErr, |
2081 "Error: %s line %d: expected %d columns of data but found %d", | 2140 "Error: %s line %d: expected %d columns of data but found %d", |
2082 zFile, lineno, nCol, i+1); | 2141 zFile, lineno, nCol, i+1); |
2083 Tcl_AppendResult(interp, zErr, 0); | 2142 Tcl_AppendResult(interp, zErr, (char*)0); |
2084 free(zErr); | 2143 free(zErr); |
2085 } | 2144 } |
2086 zCommit = "ROLLBACK"; | 2145 zCommit = "ROLLBACK"; |
2087 break; | 2146 break; |
2088 } | 2147 } |
2089 for(i=0; i<nCol; i++){ | 2148 for(i=0; i<nCol; i++){ |
2090 /* check for null data, if so, bind as null */ | 2149 /* check for null data, if so, bind as null */ |
2091 if( (nNull>0 && strcmp(azCol[i], zNull)==0) | 2150 if( (nNull>0 && strcmp(azCol[i], zNull)==0) |
2092 || strlen30(azCol[i])==0 | 2151 || strlen30(azCol[i])==0 |
2093 ){ | 2152 ){ |
2094 sqlite3_bind_null(pStmt, i+1); | 2153 sqlite3_bind_null(pStmt, i+1); |
2095 }else{ | 2154 }else{ |
2096 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC); | 2155 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC); |
2097 } | 2156 } |
2098 } | 2157 } |
2099 sqlite3_step(pStmt); | 2158 sqlite3_step(pStmt); |
2100 rc = sqlite3_reset(pStmt); | 2159 rc = sqlite3_reset(pStmt); |
2101 free(zLine); | 2160 free(zLine); |
2102 if( rc!=SQLITE_OK ){ | 2161 if( rc!=SQLITE_OK ){ |
2103 Tcl_AppendResult(interp,"Error: ", sqlite3_errmsg(pDb->db), 0); | 2162 Tcl_AppendResult(interp,"Error: ", sqlite3_errmsg(pDb->db), (char*)0); |
2104 zCommit = "ROLLBACK"; | 2163 zCommit = "ROLLBACK"; |
2105 break; | 2164 break; |
2106 } | 2165 } |
2107 } | 2166 } |
2108 free(azCol); | 2167 free(azCol); |
2109 fclose(in); | 2168 fclose(in); |
2110 sqlite3_finalize(pStmt); | 2169 sqlite3_finalize(pStmt); |
2111 (void)sqlite3_exec(pDb->db, zCommit, 0, 0, 0); | 2170 (void)sqlite3_exec(pDb->db, zCommit, 0, 0, 0); |
2112 | 2171 |
2113 if( zCommit[0] == 'C' ){ | 2172 if( zCommit[0] == 'C' ){ |
2114 /* success, set result as number of lines processed */ | 2173 /* success, set result as number of lines processed */ |
2115 pResult = Tcl_GetObjResult(interp); | 2174 pResult = Tcl_GetObjResult(interp); |
2116 Tcl_SetIntObj(pResult, lineno); | 2175 Tcl_SetIntObj(pResult, lineno); |
2117 rc = TCL_OK; | 2176 rc = TCL_OK; |
2118 }else{ | 2177 }else{ |
2119 /* failure, append lineno where failed */ | 2178 /* failure, append lineno where failed */ |
2120 sqlite3_snprintf(sizeof(zLineNum), zLineNum,"%d",lineno); | 2179 sqlite3_snprintf(sizeof(zLineNum), zLineNum,"%d",lineno); |
2121 Tcl_AppendResult(interp,", failed while processing line: ",zLineNum,0); | 2180 Tcl_AppendResult(interp,", failed while processing line: ",zLineNum, |
| 2181 (char*)0); |
2122 rc = TCL_ERROR; | 2182 rc = TCL_ERROR; |
2123 } | 2183 } |
2124 break; | 2184 break; |
2125 } | 2185 } |
2126 | 2186 |
2127 /* | 2187 /* |
2128 ** $db enable_load_extension BOOLEAN | 2188 ** $db enable_load_extension BOOLEAN |
2129 ** | 2189 ** |
2130 ** Turn the extension loading feature on or off. It if off by | 2190 ** Turn the extension loading feature on or off. It if off by |
2131 ** default. | 2191 ** default. |
2132 */ | 2192 */ |
2133 case DB_ENABLE_LOAD_EXTENSION: { | 2193 case DB_ENABLE_LOAD_EXTENSION: { |
2134 #ifndef SQLITE_OMIT_LOAD_EXTENSION | 2194 #ifndef SQLITE_OMIT_LOAD_EXTENSION |
2135 int onoff; | 2195 int onoff; |
2136 if( objc!=3 ){ | 2196 if( objc!=3 ){ |
2137 Tcl_WrongNumArgs(interp, 2, objv, "BOOLEAN"); | 2197 Tcl_WrongNumArgs(interp, 2, objv, "BOOLEAN"); |
2138 return TCL_ERROR; | 2198 return TCL_ERROR; |
2139 } | 2199 } |
2140 if( Tcl_GetBooleanFromObj(interp, objv[2], &onoff) ){ | 2200 if( Tcl_GetBooleanFromObj(interp, objv[2], &onoff) ){ |
2141 return TCL_ERROR; | 2201 return TCL_ERROR; |
2142 } | 2202 } |
2143 sqlite3_enable_load_extension(pDb->db, onoff); | 2203 sqlite3_enable_load_extension(pDb->db, onoff); |
2144 break; | 2204 break; |
2145 #else | 2205 #else |
2146 Tcl_AppendResult(interp, "extension loading is turned off at compile-time", | 2206 Tcl_AppendResult(interp, "extension loading is turned off at compile-time", |
2147 0); | 2207 (char*)0); |
2148 return TCL_ERROR; | 2208 return TCL_ERROR; |
2149 #endif | 2209 #endif |
2150 } | 2210 } |
2151 | 2211 |
2152 /* | 2212 /* |
2153 ** $db errorcode | 2213 ** $db errorcode |
2154 ** | 2214 ** |
2155 ** Return the numeric error code that was returned by the most recent | 2215 ** Return the numeric error code that was returned by the most recent |
2156 ** call to sqlite3_exec(). | 2216 ** call to sqlite3_exec(). |
2157 */ | 2217 */ |
(...skipping 15 matching lines...) Expand all Loading... |
2173 if( objc!=3 ){ | 2233 if( objc!=3 ){ |
2174 Tcl_WrongNumArgs(interp, 2, objv, "SQL"); | 2234 Tcl_WrongNumArgs(interp, 2, objv, "SQL"); |
2175 return TCL_ERROR; | 2235 return TCL_ERROR; |
2176 } | 2236 } |
2177 | 2237 |
2178 dbEvalInit(&sEval, pDb, objv[2], 0); | 2238 dbEvalInit(&sEval, pDb, objv[2], 0); |
2179 rc = dbEvalStep(&sEval); | 2239 rc = dbEvalStep(&sEval); |
2180 if( choice==DB_ONECOLUMN ){ | 2240 if( choice==DB_ONECOLUMN ){ |
2181 if( rc==TCL_OK ){ | 2241 if( rc==TCL_OK ){ |
2182 Tcl_SetObjResult(interp, dbEvalColumnValue(&sEval, 0)); | 2242 Tcl_SetObjResult(interp, dbEvalColumnValue(&sEval, 0)); |
| 2243 }else if( rc==TCL_BREAK ){ |
| 2244 Tcl_ResetResult(interp); |
2183 } | 2245 } |
2184 }else if( rc==TCL_BREAK || rc==TCL_OK ){ | 2246 }else if( rc==TCL_BREAK || rc==TCL_OK ){ |
2185 Tcl_SetObjResult(interp, Tcl_NewBooleanObj(rc==TCL_OK)); | 2247 Tcl_SetObjResult(interp, Tcl_NewBooleanObj(rc==TCL_OK)); |
2186 } | 2248 } |
2187 dbEvalFinalize(&sEval); | 2249 dbEvalFinalize(&sEval); |
2188 | 2250 |
2189 if( rc==TCL_BREAK ){ | 2251 if( rc==TCL_BREAK ){ |
2190 rc = TCL_OK; | 2252 rc = TCL_OK; |
2191 } | 2253 } |
2192 break; | 2254 break; |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2293 Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE); | 2355 Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE); |
2294 } | 2356 } |
2295 break; | 2357 break; |
2296 } | 2358 } |
2297 | 2359 |
2298 /* | 2360 /* |
2299 ** $db incrblob ?-readonly? ?DB? TABLE COLUMN ROWID | 2361 ** $db incrblob ?-readonly? ?DB? TABLE COLUMN ROWID |
2300 */ | 2362 */ |
2301 case DB_INCRBLOB: { | 2363 case DB_INCRBLOB: { |
2302 #ifdef SQLITE_OMIT_INCRBLOB | 2364 #ifdef SQLITE_OMIT_INCRBLOB |
2303 Tcl_AppendResult(interp, "incrblob not available in this build", 0); | 2365 Tcl_AppendResult(interp, "incrblob not available in this build", (char*)0); |
2304 return TCL_ERROR; | 2366 return TCL_ERROR; |
2305 #else | 2367 #else |
2306 int isReadonly = 0; | 2368 int isReadonly = 0; |
2307 const char *zDb = "main"; | 2369 const char *zDb = "main"; |
2308 const char *zTable; | 2370 const char *zTable; |
2309 const char *zColumn; | 2371 const char *zColumn; |
2310 sqlite_int64 iRow; | 2372 Tcl_WideInt iRow; |
2311 | 2373 |
2312 /* Check for the -readonly option */ | 2374 /* Check for the -readonly option */ |
2313 if( objc>3 && strcmp(Tcl_GetString(objv[2]), "-readonly")==0 ){ | 2375 if( objc>3 && strcmp(Tcl_GetString(objv[2]), "-readonly")==0 ){ |
2314 isReadonly = 1; | 2376 isReadonly = 1; |
2315 } | 2377 } |
2316 | 2378 |
2317 if( objc!=(5+isReadonly) && objc!=(6+isReadonly) ){ | 2379 if( objc!=(5+isReadonly) && objc!=(6+isReadonly) ){ |
2318 Tcl_WrongNumArgs(interp, 2, objv, "?-readonly? ?DB? TABLE COLUMN ROWID"); | 2380 Tcl_WrongNumArgs(interp, 2, objv, "?-readonly? ?DB? TABLE COLUMN ROWID"); |
2319 return TCL_ERROR; | 2381 return TCL_ERROR; |
2320 } | 2382 } |
2321 | 2383 |
2322 if( objc==(6+isReadonly) ){ | 2384 if( objc==(6+isReadonly) ){ |
2323 zDb = Tcl_GetString(objv[2]); | 2385 zDb = Tcl_GetString(objv[2]); |
2324 } | 2386 } |
2325 zTable = Tcl_GetString(objv[objc-3]); | 2387 zTable = Tcl_GetString(objv[objc-3]); |
2326 zColumn = Tcl_GetString(objv[objc-2]); | 2388 zColumn = Tcl_GetString(objv[objc-2]); |
2327 rc = Tcl_GetWideIntFromObj(interp, objv[objc-1], &iRow); | 2389 rc = Tcl_GetWideIntFromObj(interp, objv[objc-1], &iRow); |
2328 | 2390 |
2329 if( rc==TCL_OK ){ | 2391 if( rc==TCL_OK ){ |
2330 rc = createIncrblobChannel( | 2392 rc = createIncrblobChannel( |
2331 interp, pDb, zDb, zTable, zColumn, iRow, isReadonly | 2393 interp, pDb, zDb, zTable, zColumn, (sqlite3_int64)iRow, isReadonly |
2332 ); | 2394 ); |
2333 } | 2395 } |
2334 #endif | 2396 #endif |
2335 break; | 2397 break; |
2336 } | 2398 } |
2337 | 2399 |
2338 /* | 2400 /* |
2339 ** $db interrupt | 2401 ** $db interrupt |
2340 ** | 2402 ** |
2341 ** Interrupt the execution of the inner-most SQL interpreter. This | 2403 ** Interrupt the execution of the inner-most SQL interpreter. This |
(...skipping 18 matching lines...) Expand all Loading... |
2360 return TCL_ERROR; | 2422 return TCL_ERROR; |
2361 } | 2423 } |
2362 if( objc==3 ){ | 2424 if( objc==3 ){ |
2363 int len; | 2425 int len; |
2364 char *zNull = Tcl_GetStringFromObj(objv[2], &len); | 2426 char *zNull = Tcl_GetStringFromObj(objv[2], &len); |
2365 if( pDb->zNull ){ | 2427 if( pDb->zNull ){ |
2366 Tcl_Free(pDb->zNull); | 2428 Tcl_Free(pDb->zNull); |
2367 } | 2429 } |
2368 if( zNull && len>0 ){ | 2430 if( zNull && len>0 ){ |
2369 pDb->zNull = Tcl_Alloc( len + 1 ); | 2431 pDb->zNull = Tcl_Alloc( len + 1 ); |
2370 strncpy(pDb->zNull, zNull, len); | 2432 memcpy(pDb->zNull, zNull, len); |
2371 pDb->zNull[len] = '\0'; | 2433 pDb->zNull[len] = '\0'; |
2372 }else{ | 2434 }else{ |
2373 pDb->zNull = 0; | 2435 pDb->zNull = 0; |
2374 } | 2436 } |
2375 } | 2437 } |
2376 Tcl_SetObjResult(interp, dbTextToObj(pDb->zNull)); | 2438 Tcl_SetObjResult(interp, Tcl_NewStringObj(pDb->zNull, -1)); |
2377 break; | 2439 break; |
2378 } | 2440 } |
2379 | 2441 |
2380 /* | 2442 /* |
2381 ** $db last_insert_rowid | 2443 ** $db last_insert_rowid |
2382 ** | 2444 ** |
2383 ** Return an integer which is the ROWID for the most recent insert. | 2445 ** Return an integer which is the ROWID for the most recent insert. |
2384 */ | 2446 */ |
2385 case DB_LAST_INSERT_ROWID: { | 2447 case DB_LAST_INSERT_ROWID: { |
2386 Tcl_Obj *pResult; | 2448 Tcl_Obj *pResult; |
(...skipping 13 matching lines...) Expand all Loading... |
2400 */ | 2462 */ |
2401 | 2463 |
2402 /* $db progress ?N CALLBACK? | 2464 /* $db progress ?N CALLBACK? |
2403 ** | 2465 ** |
2404 ** Invoke the given callback every N virtual machine opcodes while executing | 2466 ** Invoke the given callback every N virtual machine opcodes while executing |
2405 ** queries. | 2467 ** queries. |
2406 */ | 2468 */ |
2407 case DB_PROGRESS: { | 2469 case DB_PROGRESS: { |
2408 if( objc==2 ){ | 2470 if( objc==2 ){ |
2409 if( pDb->zProgress ){ | 2471 if( pDb->zProgress ){ |
2410 Tcl_AppendResult(interp, pDb->zProgress, 0); | 2472 Tcl_AppendResult(interp, pDb->zProgress, (char*)0); |
2411 } | 2473 } |
2412 }else if( objc==4 ){ | 2474 }else if( objc==4 ){ |
2413 char *zProgress; | 2475 char *zProgress; |
2414 int len; | 2476 int len; |
2415 int N; | 2477 int N; |
2416 if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &N) ){ | 2478 if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &N) ){ |
2417 return TCL_ERROR; | 2479 return TCL_ERROR; |
2418 }; | 2480 }; |
2419 if( pDb->zProgress ){ | 2481 if( pDb->zProgress ){ |
2420 Tcl_Free(pDb->zProgress); | 2482 Tcl_Free(pDb->zProgress); |
(...skipping 25 matching lines...) Expand all Loading... |
2446 ** Make arrangements to invoke the CALLBACK routine after each SQL statement | 2508 ** Make arrangements to invoke the CALLBACK routine after each SQL statement |
2447 ** that has run. The text of the SQL and the amount of elapse time are | 2509 ** that has run. The text of the SQL and the amount of elapse time are |
2448 ** appended to CALLBACK before the script is run. | 2510 ** appended to CALLBACK before the script is run. |
2449 */ | 2511 */ |
2450 case DB_PROFILE: { | 2512 case DB_PROFILE: { |
2451 if( objc>3 ){ | 2513 if( objc>3 ){ |
2452 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); | 2514 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); |
2453 return TCL_ERROR; | 2515 return TCL_ERROR; |
2454 }else if( objc==2 ){ | 2516 }else if( objc==2 ){ |
2455 if( pDb->zProfile ){ | 2517 if( pDb->zProfile ){ |
2456 Tcl_AppendResult(interp, pDb->zProfile, 0); | 2518 Tcl_AppendResult(interp, pDb->zProfile, (char*)0); |
2457 } | 2519 } |
2458 }else{ | 2520 }else{ |
2459 char *zProfile; | 2521 char *zProfile; |
2460 int len; | 2522 int len; |
2461 if( pDb->zProfile ){ | 2523 if( pDb->zProfile ){ |
2462 Tcl_Free(pDb->zProfile); | 2524 Tcl_Free(pDb->zProfile); |
2463 } | 2525 } |
2464 zProfile = Tcl_GetStringFromObj(objv[2], &len); | 2526 zProfile = Tcl_GetStringFromObj(objv[2], &len); |
2465 if( zProfile && len>0 ){ | 2527 if( zProfile && len>0 ){ |
2466 pDb->zProfile = Tcl_Alloc( len + 1 ); | 2528 pDb->zProfile = Tcl_Alloc( len + 1 ); |
(...skipping 12 matching lines...) Expand all Loading... |
2479 } | 2541 } |
2480 break; | 2542 break; |
2481 } | 2543 } |
2482 | 2544 |
2483 /* | 2545 /* |
2484 ** $db rekey KEY | 2546 ** $db rekey KEY |
2485 ** | 2547 ** |
2486 ** Change the encryption key on the currently open database. | 2548 ** Change the encryption key on the currently open database. |
2487 */ | 2549 */ |
2488 case DB_REKEY: { | 2550 case DB_REKEY: { |
| 2551 #ifdef SQLITE_HAS_CODEC |
2489 int nKey; | 2552 int nKey; |
2490 void *pKey; | 2553 void *pKey; |
| 2554 #endif |
2491 if( objc!=3 ){ | 2555 if( objc!=3 ){ |
2492 Tcl_WrongNumArgs(interp, 2, objv, "KEY"); | 2556 Tcl_WrongNumArgs(interp, 2, objv, "KEY"); |
2493 return TCL_ERROR; | 2557 return TCL_ERROR; |
2494 } | 2558 } |
| 2559 #ifdef SQLITE_HAS_CODEC |
2495 pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey); | 2560 pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey); |
2496 #ifdef SQLITE_HAS_CODEC | |
2497 rc = sqlite3_rekey(pDb->db, pKey, nKey); | 2561 rc = sqlite3_rekey(pDb->db, pKey, nKey); |
2498 if( rc ){ | 2562 if( rc ){ |
2499 Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0); | 2563 Tcl_AppendResult(interp, sqlite3_errstr(rc), (char*)0); |
2500 rc = TCL_ERROR; | 2564 rc = TCL_ERROR; |
2501 } | 2565 } |
2502 #endif | 2566 #endif |
2503 break; | 2567 break; |
2504 } | 2568 } |
2505 | 2569 |
2506 /* $db restore ?DATABASE? FILENAME | 2570 /* $db restore ?DATABASE? FILENAME |
2507 ** | 2571 ** |
2508 ** Open a database file named FILENAME. Transfer the content | 2572 ** Open a database file named FILENAME. Transfer the content |
2509 ** of FILENAME into the local database DATABASE (default: "main"). | 2573 ** of FILENAME into the local database DATABASE (default: "main"). |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2630 ** Make arrangements to invoke the CALLBACK routine for each SQL statement | 2694 ** Make arrangements to invoke the CALLBACK routine for each SQL statement |
2631 ** that is executed. The text of the SQL is appended to CALLBACK before | 2695 ** that is executed. The text of the SQL is appended to CALLBACK before |
2632 ** it is executed. | 2696 ** it is executed. |
2633 */ | 2697 */ |
2634 case DB_TRACE: { | 2698 case DB_TRACE: { |
2635 if( objc>3 ){ | 2699 if( objc>3 ){ |
2636 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); | 2700 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); |
2637 return TCL_ERROR; | 2701 return TCL_ERROR; |
2638 }else if( objc==2 ){ | 2702 }else if( objc==2 ){ |
2639 if( pDb->zTrace ){ | 2703 if( pDb->zTrace ){ |
2640 Tcl_AppendResult(interp, pDb->zTrace, 0); | 2704 Tcl_AppendResult(interp, pDb->zTrace, (char*)0); |
2641 } | 2705 } |
2642 }else{ | 2706 }else{ |
2643 char *zTrace; | 2707 char *zTrace; |
2644 int len; | 2708 int len; |
2645 if( pDb->zTrace ){ | 2709 if( pDb->zTrace ){ |
2646 Tcl_Free(pDb->zTrace); | 2710 Tcl_Free(pDb->zTrace); |
2647 } | 2711 } |
2648 zTrace = Tcl_GetStringFromObj(objv[2], &len); | 2712 zTrace = Tcl_GetStringFromObj(objv[2], &len); |
2649 if( zTrace && len>0 ){ | 2713 if( zTrace && len>0 ){ |
2650 pDb->zTrace = Tcl_Alloc( len + 1 ); | 2714 pDb->zTrace = Tcl_Alloc( len + 1 ); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2701 case TTYPE_IMMEDIATE: zBegin = "BEGIN IMMEDIATE"; break; | 2765 case TTYPE_IMMEDIATE: zBegin = "BEGIN IMMEDIATE"; break; |
2702 } | 2766 } |
2703 } | 2767 } |
2704 pScript = objv[objc-1]; | 2768 pScript = objv[objc-1]; |
2705 | 2769 |
2706 /* Run the SQLite BEGIN command to open a transaction or savepoint. */ | 2770 /* Run the SQLite BEGIN command to open a transaction or savepoint. */ |
2707 pDb->disableAuth++; | 2771 pDb->disableAuth++; |
2708 rc = sqlite3_exec(pDb->db, zBegin, 0, 0, 0); | 2772 rc = sqlite3_exec(pDb->db, zBegin, 0, 0, 0); |
2709 pDb->disableAuth--; | 2773 pDb->disableAuth--; |
2710 if( rc!=SQLITE_OK ){ | 2774 if( rc!=SQLITE_OK ){ |
2711 Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0); | 2775 Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0); |
2712 return TCL_ERROR; | 2776 return TCL_ERROR; |
2713 } | 2777 } |
2714 pDb->nTransaction++; | 2778 pDb->nTransaction++; |
2715 | 2779 |
2716 /* If using NRE, schedule a callback to invoke the script pScript, then | 2780 /* If using NRE, schedule a callback to invoke the script pScript, then |
2717 ** a second callback to commit (or rollback) the transaction or savepoint | 2781 ** a second callback to commit (or rollback) the transaction or savepoint |
2718 ** opened above. If not using NRE, evaluate the script directly, then | 2782 ** opened above. If not using NRE, evaluate the script directly, then |
2719 ** call function DbTransPostCmd() to commit (or rollback) the transaction | 2783 ** call function DbTransPostCmd() to commit (or rollback) the transaction |
2720 ** or savepoint. */ | 2784 ** or savepoint. */ |
2721 if( DbUseNre() ){ | 2785 if( DbUseNre() ){ |
2722 Tcl_NRAddCallback(interp, DbTransPostCmd, cd, 0, 0, 0); | 2786 Tcl_NRAddCallback(interp, DbTransPostCmd, cd, 0, 0, 0); |
2723 Tcl_NREvalObj(interp, pScript, 0); | 2787 (void)Tcl_NREvalObj(interp, pScript, 0); |
2724 }else{ | 2788 }else{ |
2725 rc = DbTransPostCmd(&cd, interp, Tcl_EvalObjEx(interp, pScript, 0)); | 2789 rc = DbTransPostCmd(&cd, interp, Tcl_EvalObjEx(interp, pScript, 0)); |
2726 } | 2790 } |
2727 break; | 2791 break; |
2728 } | 2792 } |
2729 | 2793 |
2730 /* | 2794 /* |
2731 ** $db unlock_notify ?script? | 2795 ** $db unlock_notify ?script? |
2732 */ | 2796 */ |
2733 case DB_UNLOCK_NOTIFY: { | 2797 case DB_UNLOCK_NOTIFY: { |
2734 #ifndef SQLITE_ENABLE_UNLOCK_NOTIFY | 2798 #ifndef SQLITE_ENABLE_UNLOCK_NOTIFY |
2735 Tcl_AppendResult(interp, "unlock_notify not available in this build", 0); | 2799 Tcl_AppendResult(interp, "unlock_notify not available in this build", |
| 2800 (char*)0); |
2736 rc = TCL_ERROR; | 2801 rc = TCL_ERROR; |
2737 #else | 2802 #else |
2738 if( objc!=2 && objc!=3 ){ | 2803 if( objc!=2 && objc!=3 ){ |
2739 Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?"); | 2804 Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?"); |
2740 rc = TCL_ERROR; | 2805 rc = TCL_ERROR; |
2741 }else{ | 2806 }else{ |
2742 void (*xNotify)(void **, int) = 0; | 2807 void (*xNotify)(void **, int) = 0; |
2743 void *pNotifyArg = 0; | 2808 void *pNotifyArg = 0; |
2744 | 2809 |
2745 if( pDb->pUnlockNotify ){ | 2810 if( pDb->pUnlockNotify ){ |
2746 Tcl_DecrRefCount(pDb->pUnlockNotify); | 2811 Tcl_DecrRefCount(pDb->pUnlockNotify); |
2747 pDb->pUnlockNotify = 0; | 2812 pDb->pUnlockNotify = 0; |
2748 } | 2813 } |
2749 | 2814 |
2750 if( objc==3 ){ | 2815 if( objc==3 ){ |
2751 xNotify = DbUnlockNotify; | 2816 xNotify = DbUnlockNotify; |
2752 pNotifyArg = (void *)pDb; | 2817 pNotifyArg = (void *)pDb; |
2753 pDb->pUnlockNotify = objv[2]; | 2818 pDb->pUnlockNotify = objv[2]; |
2754 Tcl_IncrRefCount(pDb->pUnlockNotify); | 2819 Tcl_IncrRefCount(pDb->pUnlockNotify); |
2755 } | 2820 } |
2756 | 2821 |
2757 if( sqlite3_unlock_notify(pDb->db, xNotify, pNotifyArg) ){ | 2822 if( sqlite3_unlock_notify(pDb->db, xNotify, pNotifyArg) ){ |
2758 Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0); | 2823 Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0); |
2759 rc = TCL_ERROR; | 2824 rc = TCL_ERROR; |
2760 } | 2825 } |
2761 } | 2826 } |
2762 #endif | 2827 #endif |
2763 break; | 2828 break; |
2764 } | 2829 } |
2765 | 2830 |
2766 /* | 2831 /* |
2767 ** $db wal_hook ?script? | 2832 ** $db wal_hook ?script? |
2768 ** $db update_hook ?script? | 2833 ** $db update_hook ?script? |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2849 ** The first argument, DBNAME, is an arbitrary name for a new | 2914 ** The first argument, DBNAME, is an arbitrary name for a new |
2850 ** database connection. This command creates a new command named | 2915 ** database connection. This command creates a new command named |
2851 ** DBNAME that is used to control that connection. The database | 2916 ** DBNAME that is used to control that connection. The database |
2852 ** connection is deleted when the DBNAME command is deleted. | 2917 ** connection is deleted when the DBNAME command is deleted. |
2853 ** | 2918 ** |
2854 ** The second argument is the name of the database file. | 2919 ** The second argument is the name of the database file. |
2855 ** | 2920 ** |
2856 */ | 2921 */ |
2857 static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ | 2922 static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ |
2858 SqliteDb *p; | 2923 SqliteDb *p; |
2859 void *pKey = 0; | |
2860 int nKey = 0; | |
2861 const char *zArg; | 2924 const char *zArg; |
2862 char *zErrMsg; | 2925 char *zErrMsg; |
2863 int i; | 2926 int i; |
2864 const char *zFile; | 2927 const char *zFile; |
2865 const char *zVfs = 0; | 2928 const char *zVfs = 0; |
2866 int flags; | 2929 int flags; |
2867 Tcl_DString translatedFilename; | 2930 Tcl_DString translatedFilename; |
| 2931 #ifdef SQLITE_HAS_CODEC |
| 2932 void *pKey = 0; |
| 2933 int nKey = 0; |
| 2934 #endif |
| 2935 int rc; |
2868 | 2936 |
2869 /* In normal use, each TCL interpreter runs in a single thread. So | 2937 /* In normal use, each TCL interpreter runs in a single thread. So |
2870 ** by default, we can turn of mutexing on SQLite database connections. | 2938 ** by default, we can turn of mutexing on SQLite database connections. |
2871 ** However, for testing purposes it is useful to have mutexes turned | 2939 ** However, for testing purposes it is useful to have mutexes turned |
2872 ** on. So, by default, mutexes default off. But if compiled with | 2940 ** on. So, by default, mutexes default off. But if compiled with |
2873 ** SQLITE_TCL_DEFAULT_FULLMUTEX then mutexes default on. | 2941 ** SQLITE_TCL_DEFAULT_FULLMUTEX then mutexes default on. |
2874 */ | 2942 */ |
2875 #ifdef SQLITE_TCL_DEFAULT_FULLMUTEX | 2943 #ifdef SQLITE_TCL_DEFAULT_FULLMUTEX |
2876 flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX; | 2944 flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX; |
2877 #else | 2945 #else |
2878 flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX; | 2946 flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX; |
2879 #endif | 2947 #endif |
2880 | 2948 |
2881 if( objc==2 ){ | 2949 if( objc==2 ){ |
2882 zArg = Tcl_GetStringFromObj(objv[1], 0); | 2950 zArg = Tcl_GetStringFromObj(objv[1], 0); |
2883 if( strcmp(zArg,"-version")==0 ){ | 2951 if( strcmp(zArg,"-version")==0 ){ |
2884 Tcl_AppendResult(interp,sqlite3_version,0); | 2952 Tcl_AppendResult(interp,sqlite3_libversion(), (char*)0); |
2885 return TCL_OK; | 2953 return TCL_OK; |
2886 } | 2954 } |
2887 if( strcmp(zArg,"-has-codec")==0 ){ | 2955 if( strcmp(zArg,"-has-codec")==0 ){ |
2888 #ifdef SQLITE_HAS_CODEC | 2956 #ifdef SQLITE_HAS_CODEC |
2889 Tcl_AppendResult(interp,"1",0); | 2957 Tcl_AppendResult(interp,"1",(char*)0); |
2890 #else | 2958 #else |
2891 Tcl_AppendResult(interp,"0",0); | 2959 Tcl_AppendResult(interp,"0",(char*)0); |
2892 #endif | 2960 #endif |
2893 return TCL_OK; | 2961 return TCL_OK; |
2894 } | 2962 } |
2895 } | 2963 } |
2896 for(i=3; i+1<objc; i+=2){ | 2964 for(i=3; i+1<objc; i+=2){ |
2897 zArg = Tcl_GetString(objv[i]); | 2965 zArg = Tcl_GetString(objv[i]); |
2898 if( strcmp(zArg,"-key")==0 ){ | 2966 if( strcmp(zArg,"-key")==0 ){ |
| 2967 #ifdef SQLITE_HAS_CODEC |
2899 pKey = Tcl_GetByteArrayFromObj(objv[i+1], &nKey); | 2968 pKey = Tcl_GetByteArrayFromObj(objv[i+1], &nKey); |
| 2969 #endif |
2900 }else if( strcmp(zArg, "-vfs")==0 ){ | 2970 }else if( strcmp(zArg, "-vfs")==0 ){ |
2901 zVfs = Tcl_GetString(objv[i+1]); | 2971 zVfs = Tcl_GetString(objv[i+1]); |
2902 }else if( strcmp(zArg, "-readonly")==0 ){ | 2972 }else if( strcmp(zArg, "-readonly")==0 ){ |
2903 int b; | 2973 int b; |
2904 if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; | 2974 if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; |
2905 if( b ){ | 2975 if( b ){ |
2906 flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); | 2976 flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); |
2907 flags |= SQLITE_OPEN_READONLY; | 2977 flags |= SQLITE_OPEN_READONLY; |
2908 }else{ | 2978 }else{ |
2909 flags &= ~SQLITE_OPEN_READONLY; | 2979 flags &= ~SQLITE_OPEN_READONLY; |
2910 flags |= SQLITE_OPEN_READWRITE; | 2980 flags |= SQLITE_OPEN_READWRITE; |
2911 } | 2981 } |
2912 }else if( strcmp(zArg, "-create")==0 ){ | 2982 }else if( strcmp(zArg, "-create")==0 ){ |
2913 int b; | 2983 int b; |
2914 if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; | 2984 if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; |
2915 if( b && (flags & SQLITE_OPEN_READONLY)==0 ){ | 2985 if( b && (flags & SQLITE_OPEN_READONLY)==0 ){ |
2916 flags |= SQLITE_OPEN_CREATE; | 2986 flags |= SQLITE_OPEN_CREATE; |
2917 }else{ | 2987 }else{ |
2918 flags &= ~SQLITE_OPEN_CREATE; | 2988 flags &= ~SQLITE_OPEN_CREATE; |
2919 } | 2989 } |
2920 }else if( strcmp(zArg, "-nomutex")==0 ){ | 2990 }else if( strcmp(zArg, "-nomutex")==0 ){ |
2921 int b; | 2991 int b; |
2922 if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; | 2992 if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; |
2923 if( b ){ | 2993 if( b ){ |
2924 flags |= SQLITE_OPEN_NOMUTEX; | 2994 flags |= SQLITE_OPEN_NOMUTEX; |
2925 flags &= ~SQLITE_OPEN_FULLMUTEX; | 2995 flags &= ~SQLITE_OPEN_FULLMUTEX; |
2926 }else{ | 2996 }else{ |
2927 flags &= ~SQLITE_OPEN_NOMUTEX; | 2997 flags &= ~SQLITE_OPEN_NOMUTEX; |
2928 } | 2998 } |
2929 }else if( strcmp(zArg, "-fullmutex")==0 ){ | 2999 }else if( strcmp(zArg, "-fullmutex")==0 ){ |
2930 int b; | 3000 int b; |
2931 if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; | 3001 if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; |
2932 if( b ){ | 3002 if( b ){ |
2933 flags |= SQLITE_OPEN_FULLMUTEX; | 3003 flags |= SQLITE_OPEN_FULLMUTEX; |
2934 flags &= ~SQLITE_OPEN_NOMUTEX; | 3004 flags &= ~SQLITE_OPEN_NOMUTEX; |
2935 }else{ | 3005 }else{ |
2936 flags &= ~SQLITE_OPEN_FULLMUTEX; | 3006 flags &= ~SQLITE_OPEN_FULLMUTEX; |
2937 } | 3007 } |
| 3008 }else if( strcmp(zArg, "-uri")==0 ){ |
| 3009 int b; |
| 3010 if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; |
| 3011 if( b ){ |
| 3012 flags |= SQLITE_OPEN_URI; |
| 3013 }else{ |
| 3014 flags &= ~SQLITE_OPEN_URI; |
| 3015 } |
2938 }else{ | 3016 }else{ |
2939 Tcl_AppendResult(interp, "unknown option: ", zArg, (char*)0); | 3017 Tcl_AppendResult(interp, "unknown option: ", zArg, (char*)0); |
2940 return TCL_ERROR; | 3018 return TCL_ERROR; |
2941 } | 3019 } |
2942 } | 3020 } |
2943 if( objc<3 || (objc&1)!=1 ){ | 3021 if( objc<3 || (objc&1)!=1 ){ |
2944 Tcl_WrongNumArgs(interp, 1, objv, | 3022 Tcl_WrongNumArgs(interp, 1, objv, |
2945 "HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?" | 3023 "HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?" |
2946 " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN?" | 3024 " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?" |
2947 #ifdef SQLITE_HAS_CODEC | 3025 #ifdef SQLITE_HAS_CODEC |
2948 " ?-key CODECKEY?" | 3026 " ?-key CODECKEY?" |
2949 #endif | 3027 #endif |
2950 ); | 3028 ); |
2951 return TCL_ERROR; | 3029 return TCL_ERROR; |
2952 } | 3030 } |
2953 zErrMsg = 0; | 3031 zErrMsg = 0; |
2954 p = (SqliteDb*)Tcl_Alloc( sizeof(*p) ); | 3032 p = (SqliteDb*)Tcl_Alloc( sizeof(*p) ); |
2955 if( p==0 ){ | 3033 if( p==0 ){ |
2956 Tcl_SetResult(interp, "malloc failed", TCL_STATIC); | 3034 Tcl_SetResult(interp, (char *)"malloc failed", TCL_STATIC); |
2957 return TCL_ERROR; | 3035 return TCL_ERROR; |
2958 } | 3036 } |
2959 memset(p, 0, sizeof(*p)); | 3037 memset(p, 0, sizeof(*p)); |
2960 zFile = Tcl_GetStringFromObj(objv[2], 0); | 3038 zFile = Tcl_GetStringFromObj(objv[2], 0); |
2961 zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename); | 3039 zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename); |
2962 sqlite3_open_v2(zFile, &p->db, flags, zVfs); | 3040 rc = sqlite3_open_v2(zFile, &p->db, flags, zVfs); |
2963 Tcl_DStringFree(&translatedFilename); | 3041 Tcl_DStringFree(&translatedFilename); |
2964 if( SQLITE_OK!=sqlite3_errcode(p->db) ){ | 3042 if( p->db ){ |
2965 zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db)); | 3043 if( SQLITE_OK!=sqlite3_errcode(p->db) ){ |
2966 sqlite3_close(p->db); | 3044 zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db)); |
2967 p->db = 0; | 3045 sqlite3_close(p->db); |
| 3046 p->db = 0; |
| 3047 } |
| 3048 }else{ |
| 3049 zErrMsg = sqlite3_mprintf("%s", sqlite3_errstr(rc)); |
2968 } | 3050 } |
2969 #ifdef SQLITE_HAS_CODEC | 3051 #ifdef SQLITE_HAS_CODEC |
2970 if( p->db ){ | 3052 if( p->db ){ |
2971 sqlite3_key(p->db, pKey, nKey); | 3053 sqlite3_key(p->db, pKey, nKey); |
2972 } | 3054 } |
2973 #endif | 3055 #endif |
2974 if( p->db==0 ){ | 3056 if( p->db==0 ){ |
2975 Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE); | 3057 Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE); |
2976 Tcl_Free((char*)p); | 3058 Tcl_Free((char*)p); |
2977 sqlite3_free(zErrMsg); | 3059 sqlite3_free(zErrMsg); |
(...skipping 10 matching lines...) Expand all Loading... |
2988 } | 3070 } |
2989 return TCL_OK; | 3071 return TCL_OK; |
2990 } | 3072 } |
2991 | 3073 |
2992 /* | 3074 /* |
2993 ** Provide a dummy Tcl_InitStubs if we are using this as a static | 3075 ** Provide a dummy Tcl_InitStubs if we are using this as a static |
2994 ** library. | 3076 ** library. |
2995 */ | 3077 */ |
2996 #ifndef USE_TCL_STUBS | 3078 #ifndef USE_TCL_STUBS |
2997 # undef Tcl_InitStubs | 3079 # undef Tcl_InitStubs |
2998 # define Tcl_InitStubs(a,b,c) | 3080 # define Tcl_InitStubs(a,b,c) TCL_VERSION |
2999 #endif | 3081 #endif |
3000 | 3082 |
3001 /* | 3083 /* |
3002 ** Make sure we have a PACKAGE_VERSION macro defined. This will be | 3084 ** Make sure we have a PACKAGE_VERSION macro defined. This will be |
3003 ** defined automatically by the TEA makefile. But other makefiles | 3085 ** defined automatically by the TEA makefile. But other makefiles |
3004 ** do not define it. | 3086 ** do not define it. |
3005 */ | 3087 */ |
3006 #ifndef PACKAGE_VERSION | 3088 #ifndef PACKAGE_VERSION |
3007 # define PACKAGE_VERSION SQLITE_VERSION | 3089 # define PACKAGE_VERSION SQLITE_VERSION |
3008 #endif | 3090 #endif |
3009 | 3091 |
3010 /* | 3092 /* |
3011 ** Initialize this module. | 3093 ** Initialize this module. |
3012 ** | 3094 ** |
3013 ** This Tcl module contains only a single new Tcl command named "sqlite". | 3095 ** This Tcl module contains only a single new Tcl command named "sqlite". |
3014 ** (Hence there is no namespace. There is no point in using a namespace | 3096 ** (Hence there is no namespace. There is no point in using a namespace |
3015 ** if the extension only supplies one new name!) The "sqlite" command is | 3097 ** if the extension only supplies one new name!) The "sqlite" command is |
3016 ** used to open a new SQLite database. See the DbMain() routine above | 3098 ** used to open a new SQLite database. See the DbMain() routine above |
3017 ** for additional information. | 3099 ** for additional information. |
3018 ** | 3100 ** |
3019 ** The EXTERN macros are required by TCL in order to work on windows. | 3101 ** The EXTERN macros are required by TCL in order to work on windows. |
3020 */ | 3102 */ |
3021 EXTERN int Sqlite3_Init(Tcl_Interp *interp){ | 3103 EXTERN int Sqlite3_Init(Tcl_Interp *interp){ |
3022 Tcl_InitStubs(interp, "8.4", 0); | 3104 int rc = Tcl_InitStubs(interp, "8.4", 0)==0 ? TCL_ERROR : TCL_OK; |
3023 Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0); | 3105 if( rc==TCL_OK ){ |
3024 Tcl_PkgProvide(interp, "sqlite3", PACKAGE_VERSION); | 3106 Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0); |
3025 | |
3026 #ifndef SQLITE_3_SUFFIX_ONLY | 3107 #ifndef SQLITE_3_SUFFIX_ONLY |
3027 /* The "sqlite" alias is undocumented. It is here only to support | 3108 /* The "sqlite" alias is undocumented. It is here only to support |
3028 ** legacy scripts. All new scripts should use only the "sqlite3" | 3109 ** legacy scripts. All new scripts should use only the "sqlite3" |
3029 ** command. | 3110 ** command. */ |
3030 */ | 3111 Tcl_CreateObjCommand(interp, "sqlite", (Tcl_ObjCmdProc*)DbMain, 0, 0); |
3031 Tcl_CreateObjCommand(interp, "sqlite", (Tcl_ObjCmdProc*)DbMain, 0, 0); | |
3032 #endif | 3112 #endif |
3033 | 3113 rc = Tcl_PkgProvide(interp, "sqlite3", PACKAGE_VERSION); |
3034 return TCL_OK; | 3114 } |
| 3115 return rc; |
3035 } | 3116 } |
3036 EXTERN int Tclsqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } | 3117 EXTERN int Tclsqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } |
3037 EXTERN int Sqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; } | |
3038 EXTERN int Tclsqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; } | |
3039 EXTERN int Sqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } | 3118 EXTERN int Sqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } |
3040 EXTERN int Tclsqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } | 3119 EXTERN int Tclsqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } |
3041 EXTERN int Sqlite3_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK; } | |
3042 EXTERN int Tclsqlite3_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK;} | |
3043 | 3120 |
| 3121 /* Because it accesses the file-system and uses persistent state, SQLite |
| 3122 ** is not considered appropriate for safe interpreters. Hence, we deliberately |
| 3123 ** omit the _SafeInit() interfaces. |
| 3124 */ |
3044 | 3125 |
3045 #ifndef SQLITE_3_SUFFIX_ONLY | 3126 #ifndef SQLITE_3_SUFFIX_ONLY |
3046 int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } | 3127 int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } |
3047 int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } | 3128 int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } |
3048 int Sqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; } | |
3049 int Tclsqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; } | |
3050 int Sqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } | 3129 int Sqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } |
3051 int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } | 3130 int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } |
3052 int Sqlite_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK; } | |
3053 int Tclsqlite_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK;} | |
3054 #endif | 3131 #endif |
3055 | 3132 |
3056 #ifdef TCLSH | 3133 #ifdef TCLSH |
3057 /***************************************************************************** | 3134 /***************************************************************************** |
3058 ** All of the code that follows is used to build standalone TCL interpreters | 3135 ** All of the code that follows is used to build standalone TCL interpreters |
3059 ** that are statically linked with SQLite. Enable these by compiling | 3136 ** that are statically linked with SQLite. Enable these by compiling |
3060 ** with -DTCLSH=n where n can be 1 or 2. An n of 1 generates a standard | 3137 ** with -DTCLSH=n where n can be 1 or 2. An n of 1 generates a standard |
3061 ** tclsh but with SQLite built in. An n of 2 generates the SQLite space | 3138 ** tclsh but with SQLite built in. An n of 2 generates the SQLite space |
3062 ** analysis program. | 3139 ** analysis program. |
3063 */ | 3140 */ |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3302 | 3379 |
3303 /* Now fill the next block with 56 bytes */ | 3380 /* Now fill the next block with 56 bytes */ |
3304 memset(ctx->in, 0, 56); | 3381 memset(ctx->in, 0, 56); |
3305 } else { | 3382 } else { |
3306 /* Pad block to 56 bytes */ | 3383 /* Pad block to 56 bytes */ |
3307 memset(p, 0, count-8); | 3384 memset(p, 0, count-8); |
3308 } | 3385 } |
3309 byteReverse(ctx->in, 14); | 3386 byteReverse(ctx->in, 14); |
3310 | 3387 |
3311 /* Append length in bits and transform */ | 3388 /* Append length in bits and transform */ |
3312 ((uint32 *)ctx->in)[ 14 ] = ctx->bits[0]; | 3389 memcpy(ctx->in + 14*4, ctx->bits, 8); |
3313 ((uint32 *)ctx->in)[ 15 ] = ctx->bits[1]; | |
3314 | 3390 |
3315 MD5Transform(ctx->buf, (uint32 *)ctx->in); | 3391 MD5Transform(ctx->buf, (uint32 *)ctx->in); |
3316 byteReverse((unsigned char *)ctx->buf, 4); | 3392 byteReverse((unsigned char *)ctx->buf, 4); |
3317 memcpy(digest, ctx->buf, 16); | 3393 memcpy(digest, ctx->buf, 16); |
3318 memset(ctx, 0, sizeof(ctx)); /* In case it is sensitive */ | |
3319 } | 3394 } |
3320 | 3395 |
3321 /* | 3396 /* |
3322 ** Convert a 128-bit MD5 digest into a 32-digit base-16 number. | 3397 ** Convert a 128-bit MD5 digest into a 32-digit base-16 number. |
3323 */ | 3398 */ |
3324 static void MD5DigestToBase16(unsigned char *digest, char *zBuf){ | 3399 static void MD5DigestToBase16(unsigned char *digest, char *zBuf){ |
3325 static char const zEncode[] = "0123456789abcdef"; | 3400 static char const zEncode[] = "0123456789abcdef"; |
3326 int i, j; | 3401 int i, j; |
3327 | 3402 |
3328 for(j=i=0; i<16; i++){ | 3403 for(j=i=0; i<16; i++){ |
(...skipping 27 matching lines...) Expand all Loading... |
3356 ** Result is the hash in base64. | 3431 ** Result is the hash in base64. |
3357 */ | 3432 */ |
3358 static int md5_cmd(void*cd, Tcl_Interp *interp, int argc, const char **argv){ | 3433 static int md5_cmd(void*cd, Tcl_Interp *interp, int argc, const char **argv){ |
3359 MD5Context ctx; | 3434 MD5Context ctx; |
3360 unsigned char digest[16]; | 3435 unsigned char digest[16]; |
3361 char zBuf[50]; | 3436 char zBuf[50]; |
3362 void (*converter)(unsigned char*, char*); | 3437 void (*converter)(unsigned char*, char*); |
3363 | 3438 |
3364 if( argc!=2 ){ | 3439 if( argc!=2 ){ |
3365 Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], | 3440 Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], |
3366 " TEXT\"", 0); | 3441 " TEXT\"", (char*)0); |
3367 return TCL_ERROR; | 3442 return TCL_ERROR; |
3368 } | 3443 } |
3369 MD5Init(&ctx); | 3444 MD5Init(&ctx); |
3370 MD5Update(&ctx, (unsigned char*)argv[1], (unsigned)strlen(argv[1])); | 3445 MD5Update(&ctx, (unsigned char*)argv[1], (unsigned)strlen(argv[1])); |
3371 MD5Final(digest, &ctx); | 3446 MD5Final(digest, &ctx); |
3372 converter = (void(*)(unsigned char*,char*))cd; | 3447 converter = (void(*)(unsigned char*,char*))cd; |
3373 converter(digest, zBuf); | 3448 converter(digest, zBuf); |
3374 Tcl_AppendResult(interp, zBuf, (char*)0); | 3449 Tcl_AppendResult(interp, zBuf, (char*)0); |
3375 return TCL_OK; | 3450 return TCL_OK; |
3376 } | 3451 } |
3377 | 3452 |
3378 /* | 3453 /* |
3379 ** A TCL command to take the md5 hash of a file. The argument is the | 3454 ** A TCL command to take the md5 hash of a file. The argument is the |
3380 ** name of the file. | 3455 ** name of the file. |
3381 */ | 3456 */ |
3382 static int md5file_cmd(void*cd, Tcl_Interp*interp, int argc, const char **argv){ | 3457 static int md5file_cmd(void*cd, Tcl_Interp*interp, int argc, const char **argv){ |
3383 FILE *in; | 3458 FILE *in; |
3384 MD5Context ctx; | 3459 MD5Context ctx; |
3385 void (*converter)(unsigned char*, char*); | 3460 void (*converter)(unsigned char*, char*); |
3386 unsigned char digest[16]; | 3461 unsigned char digest[16]; |
3387 char zBuf[10240]; | 3462 char zBuf[10240]; |
3388 | 3463 |
3389 if( argc!=2 ){ | 3464 if( argc!=2 ){ |
3390 Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], | 3465 Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], |
3391 " FILENAME\"", 0); | 3466 " FILENAME\"", (char*)0); |
3392 return TCL_ERROR; | 3467 return TCL_ERROR; |
3393 } | 3468 } |
3394 in = fopen(argv[1],"rb"); | 3469 in = fopen(argv[1],"rb"); |
3395 if( in==0 ){ | 3470 if( in==0 ){ |
3396 Tcl_AppendResult(interp,"unable to open file \"", argv[1], | 3471 Tcl_AppendResult(interp,"unable to open file \"", argv[1], |
3397 "\" for reading", 0); | 3472 "\" for reading", (char*)0); |
3398 return TCL_ERROR; | 3473 return TCL_ERROR; |
3399 } | 3474 } |
3400 MD5Init(&ctx); | 3475 MD5Init(&ctx); |
3401 for(;;){ | 3476 for(;;){ |
3402 int n; | 3477 int n; |
3403 n = fread(zBuf, 1, sizeof(zBuf), in); | 3478 n = (int)fread(zBuf, 1, sizeof(zBuf), in); |
3404 if( n<=0 ) break; | 3479 if( n<=0 ) break; |
3405 MD5Update(&ctx, (unsigned char*)zBuf, (unsigned)n); | 3480 MD5Update(&ctx, (unsigned char*)zBuf, (unsigned)n); |
3406 } | 3481 } |
3407 fclose(in); | 3482 fclose(in); |
3408 MD5Final(digest, &ctx); | 3483 MD5Final(digest, &ctx); |
3409 converter = (void(*)(unsigned char*,char*))cd; | 3484 converter = (void(*)(unsigned char*,char*))cd; |
3410 converter(digest, zBuf); | 3485 converter(digest, zBuf); |
3411 Tcl_AppendResult(interp, zBuf, (char*)0); | 3486 Tcl_AppendResult(interp, zBuf, (char*)0); |
3412 return TCL_OK; | 3487 return TCL_OK; |
3413 } | 3488 } |
(...skipping 25 matching lines...) Expand all Loading... |
3439 int i; | 3514 int i; |
3440 if( argc<1 ) return; | 3515 if( argc<1 ) return; |
3441 p = sqlite3_aggregate_context(context, sizeof(*p)); | 3516 p = sqlite3_aggregate_context(context, sizeof(*p)); |
3442 if( p==0 ) return; | 3517 if( p==0 ) return; |
3443 if( !p->isInit ){ | 3518 if( !p->isInit ){ |
3444 MD5Init(p); | 3519 MD5Init(p); |
3445 } | 3520 } |
3446 for(i=0; i<argc; i++){ | 3521 for(i=0; i<argc; i++){ |
3447 const char *zData = (char*)sqlite3_value_text(argv[i]); | 3522 const char *zData = (char*)sqlite3_value_text(argv[i]); |
3448 if( zData ){ | 3523 if( zData ){ |
3449 MD5Update(p, (unsigned char*)zData, strlen(zData)); | 3524 MD5Update(p, (unsigned char*)zData, (int)strlen(zData)); |
3450 } | 3525 } |
3451 } | 3526 } |
3452 } | 3527 } |
3453 static void md5finalize(sqlite3_context *context){ | 3528 static void md5finalize(sqlite3_context *context){ |
3454 MD5Context *p; | 3529 MD5Context *p; |
3455 unsigned char digest[16]; | 3530 unsigned char digest[16]; |
3456 char zBuf[33]; | 3531 char zBuf[33]; |
3457 p = sqlite3_aggregate_context(context, sizeof(*p)); | 3532 p = sqlite3_aggregate_context(context, sizeof(*p)); |
3458 MD5Final(digest,p); | 3533 MD5Final(digest,p); |
3459 MD5DigestToBase16(digest, zBuf); | 3534 MD5DigestToBase16(digest, zBuf); |
3460 sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); | 3535 sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); |
3461 } | 3536 } |
3462 int Md5_Register(sqlite3 *db){ | 3537 int Md5_Register(sqlite3 *db){ |
3463 int rc = sqlite3_create_function(db, "md5sum", -1, SQLITE_UTF8, 0, 0, | 3538 int rc = sqlite3_create_function(db, "md5sum", -1, SQLITE_UTF8, 0, 0, |
3464 md5step, md5finalize); | 3539 md5step, md5finalize); |
3465 sqlite3_overload_function(db, "md5sum", -1); /* To exercise this API */ | 3540 sqlite3_overload_function(db, "md5sum", -1); /* To exercise this API */ |
3466 return rc; | 3541 return rc; |
3467 } | 3542 } |
3468 #endif /* defined(SQLITE_TEST) */ | 3543 #endif /* defined(SQLITE_TEST) */ |
3469 | 3544 |
3470 | 3545 |
3471 /* | 3546 /* |
3472 ** If the macro TCLSH is one, then put in code this for the | 3547 ** If the macro TCLSH is one, then put in code this for the |
3473 ** "main" routine that will initialize Tcl and take input from | 3548 ** "main" routine that will initialize Tcl and take input from |
3474 ** standard input, or if a file is named on the command line | 3549 ** standard input, or if a file is named on the command line |
3475 ** the TCL interpreter reads and evaluates that file. | 3550 ** the TCL interpreter reads and evaluates that file. |
3476 */ | 3551 */ |
3477 #if TCLSH==1 | 3552 #if TCLSH==1 |
3478 static char zMainloop[] = | 3553 static const char *tclsh_main_loop(void){ |
3479 "set line {}\n" | 3554 static const char zMainloop[] = |
3480 "while {![eof stdin]} {\n" | 3555 "set line {}\n" |
3481 "if {$line!=\"\"} {\n" | 3556 "while {![eof stdin]} {\n" |
3482 "puts -nonewline \"> \"\n" | 3557 "if {$line!=\"\"} {\n" |
3483 "} else {\n" | 3558 "puts -nonewline \"> \"\n" |
3484 "puts -nonewline \"% \"\n" | 3559 "} else {\n" |
| 3560 "puts -nonewline \"% \"\n" |
| 3561 "}\n" |
| 3562 "flush stdout\n" |
| 3563 "append line [gets stdin]\n" |
| 3564 "if {[info complete $line]} {\n" |
| 3565 "if {[catch {uplevel #0 $line} result]} {\n" |
| 3566 "puts stderr \"Error: $result\"\n" |
| 3567 "} elseif {$result!=\"\"} {\n" |
| 3568 "puts $result\n" |
| 3569 "}\n" |
| 3570 "set line {}\n" |
| 3571 "} else {\n" |
| 3572 "append line \\n\n" |
| 3573 "}\n" |
3485 "}\n" | 3574 "}\n" |
3486 "flush stdout\n" | 3575 ; |
3487 "append line [gets stdin]\n" | 3576 return zMainloop; |
3488 "if {[info complete $line]} {\n" | 3577 } |
3489 "if {[catch {uplevel #0 $line} result]} {\n" | |
3490 "puts stderr \"Error: $result\"\n" | |
3491 "} elseif {$result!=\"\"} {\n" | |
3492 "puts $result\n" | |
3493 "}\n" | |
3494 "set line {}\n" | |
3495 "} else {\n" | |
3496 "append line \\n\n" | |
3497 "}\n" | |
3498 "}\n" | |
3499 ; | |
3500 #endif | 3578 #endif |
3501 #if TCLSH==2 | 3579 #if TCLSH==2 |
3502 static char zMainloop[] = | 3580 static const char *tclsh_main_loop(void); |
3503 #include "spaceanal_tcl.h" | |
3504 ; | |
3505 #endif | 3581 #endif |
3506 | 3582 |
3507 #ifdef SQLITE_TEST | 3583 #ifdef SQLITE_TEST |
3508 static void init_all(Tcl_Interp *); | 3584 static void init_all(Tcl_Interp *); |
3509 static int init_all_cmd( | 3585 static int init_all_cmd( |
3510 ClientData cd, | 3586 ClientData cd, |
3511 Tcl_Interp *interp, | 3587 Tcl_Interp *interp, |
3512 int objc, | 3588 int objc, |
3513 Tcl_Obj *CONST objv[] | 3589 Tcl_Obj *CONST objv[] |
3514 ){ | 3590 ){ |
3515 | 3591 |
3516 Tcl_Interp *slave; | 3592 Tcl_Interp *slave; |
3517 if( objc!=2 ){ | 3593 if( objc!=2 ){ |
3518 Tcl_WrongNumArgs(interp, 1, objv, "SLAVE"); | 3594 Tcl_WrongNumArgs(interp, 1, objv, "SLAVE"); |
3519 return TCL_ERROR; | 3595 return TCL_ERROR; |
3520 } | 3596 } |
3521 | 3597 |
3522 slave = Tcl_GetSlave(interp, Tcl_GetString(objv[1])); | 3598 slave = Tcl_GetSlave(interp, Tcl_GetString(objv[1])); |
3523 if( !slave ){ | 3599 if( !slave ){ |
3524 return TCL_ERROR; | 3600 return TCL_ERROR; |
3525 } | 3601 } |
3526 | 3602 |
3527 init_all(slave); | 3603 init_all(slave); |
3528 return TCL_OK; | 3604 return TCL_OK; |
3529 } | 3605 } |
| 3606 |
| 3607 /* |
| 3608 ** Tclcmd: db_use_legacy_prepare DB BOOLEAN |
| 3609 ** |
| 3610 ** The first argument to this command must be a database command created by |
| 3611 ** [sqlite3]. If the second argument is true, then the handle is configured |
| 3612 ** to use the sqlite3_prepare_v2() function to prepare statements. If it |
| 3613 ** is false, sqlite3_prepare(). |
| 3614 */ |
| 3615 static int db_use_legacy_prepare_cmd( |
| 3616 ClientData cd, |
| 3617 Tcl_Interp *interp, |
| 3618 int objc, |
| 3619 Tcl_Obj *CONST objv[] |
| 3620 ){ |
| 3621 Tcl_CmdInfo cmdInfo; |
| 3622 SqliteDb *pDb; |
| 3623 int bPrepare; |
| 3624 |
| 3625 if( objc!=3 ){ |
| 3626 Tcl_WrongNumArgs(interp, 1, objv, "DB BOOLEAN"); |
| 3627 return TCL_ERROR; |
| 3628 } |
| 3629 |
| 3630 if( !Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){ |
| 3631 Tcl_AppendResult(interp, "no such db: ", Tcl_GetString(objv[1]), (char*)0); |
| 3632 return TCL_ERROR; |
| 3633 } |
| 3634 pDb = (SqliteDb*)cmdInfo.objClientData; |
| 3635 if( Tcl_GetBooleanFromObj(interp, objv[2], &bPrepare) ){ |
| 3636 return TCL_ERROR; |
| 3637 } |
| 3638 |
| 3639 pDb->bLegacyPrepare = bPrepare; |
| 3640 |
| 3641 Tcl_ResetResult(interp); |
| 3642 return TCL_OK; |
| 3643 } |
3530 #endif | 3644 #endif |
3531 | 3645 |
3532 /* | 3646 /* |
3533 ** Configure the interpreter passed as the first argument to have access | 3647 ** Configure the interpreter passed as the first argument to have access |
3534 ** to the commands and linked variables that make up: | 3648 ** to the commands and linked variables that make up: |
3535 ** | 3649 ** |
3536 ** * the [sqlite3] extension itself, | 3650 ** * the [sqlite3] extension itself, |
3537 ** | 3651 ** |
3538 ** * If SQLITE_TCLMD5 or SQLITE_TEST is defined, the Md5 commands, and | 3652 ** * If SQLITE_TCLMD5 or SQLITE_TEST is defined, the Md5 commands, and |
3539 ** | 3653 ** |
3540 ** * If SQLITE_TEST is set, the various test interfaces used by the Tcl | 3654 ** * If SQLITE_TEST is set, the various test interfaces used by the Tcl |
3541 ** test suite. | 3655 ** test suite. |
3542 */ | 3656 */ |
3543 static void init_all(Tcl_Interp *interp){ | 3657 static void init_all(Tcl_Interp *interp){ |
3544 Sqlite3_Init(interp); | 3658 Sqlite3_Init(interp); |
3545 | 3659 |
3546 #if defined(SQLITE_TEST) || defined(SQLITE_TCLMD5) | 3660 #if defined(SQLITE_TEST) || defined(SQLITE_TCLMD5) |
3547 Md5_Init(interp); | 3661 Md5_Init(interp); |
3548 #endif | 3662 #endif |
3549 | 3663 |
| 3664 /* Install the [register_dbstat_vtab] command to access the implementation |
| 3665 ** of virtual table dbstat (source file test_stat.c). This command is |
| 3666 ** required for testfixture and sqlite3_analyzer, but not by the production |
| 3667 ** Tcl extension. */ |
| 3668 #if defined(SQLITE_TEST) || TCLSH==2 |
| 3669 { |
| 3670 extern int SqlitetestStat_Init(Tcl_Interp*); |
| 3671 SqlitetestStat_Init(interp); |
| 3672 } |
| 3673 #endif |
| 3674 |
3550 #ifdef SQLITE_TEST | 3675 #ifdef SQLITE_TEST |
3551 { | 3676 { |
3552 extern int Sqliteconfig_Init(Tcl_Interp*); | 3677 extern int Sqliteconfig_Init(Tcl_Interp*); |
3553 extern int Sqlitetest1_Init(Tcl_Interp*); | 3678 extern int Sqlitetest1_Init(Tcl_Interp*); |
3554 extern int Sqlitetest2_Init(Tcl_Interp*); | 3679 extern int Sqlitetest2_Init(Tcl_Interp*); |
3555 extern int Sqlitetest3_Init(Tcl_Interp*); | 3680 extern int Sqlitetest3_Init(Tcl_Interp*); |
3556 extern int Sqlitetest4_Init(Tcl_Interp*); | 3681 extern int Sqlitetest4_Init(Tcl_Interp*); |
3557 extern int Sqlitetest5_Init(Tcl_Interp*); | 3682 extern int Sqlitetest5_Init(Tcl_Interp*); |
3558 extern int Sqlitetest6_Init(Tcl_Interp*); | 3683 extern int Sqlitetest6_Init(Tcl_Interp*); |
3559 extern int Sqlitetest7_Init(Tcl_Interp*); | 3684 extern int Sqlitetest7_Init(Tcl_Interp*); |
3560 extern int Sqlitetest8_Init(Tcl_Interp*); | 3685 extern int Sqlitetest8_Init(Tcl_Interp*); |
3561 extern int Sqlitetest9_Init(Tcl_Interp*); | 3686 extern int Sqlitetest9_Init(Tcl_Interp*); |
3562 extern int Sqlitetestasync_Init(Tcl_Interp*); | 3687 extern int Sqlitetestasync_Init(Tcl_Interp*); |
3563 extern int Sqlitetest_autoext_Init(Tcl_Interp*); | 3688 extern int Sqlitetest_autoext_Init(Tcl_Interp*); |
3564 extern int Sqlitetest_demovfs_Init(Tcl_Interp *); | 3689 extern int Sqlitetest_demovfs_Init(Tcl_Interp *); |
3565 extern int Sqlitetest_func_Init(Tcl_Interp*); | 3690 extern int Sqlitetest_func_Init(Tcl_Interp*); |
3566 extern int Sqlitetest_hexio_Init(Tcl_Interp*); | 3691 extern int Sqlitetest_hexio_Init(Tcl_Interp*); |
3567 extern int Sqlitetest_init_Init(Tcl_Interp*); | 3692 extern int Sqlitetest_init_Init(Tcl_Interp*); |
3568 extern int Sqlitetest_malloc_Init(Tcl_Interp*); | 3693 extern int Sqlitetest_malloc_Init(Tcl_Interp*); |
3569 extern int Sqlitetest_mutex_Init(Tcl_Interp*); | 3694 extern int Sqlitetest_mutex_Init(Tcl_Interp*); |
3570 extern int Sqlitetestschema_Init(Tcl_Interp*); | 3695 extern int Sqlitetestschema_Init(Tcl_Interp*); |
3571 extern int Sqlitetestsse_Init(Tcl_Interp*); | 3696 extern int Sqlitetestsse_Init(Tcl_Interp*); |
3572 extern int Sqlitetesttclvar_Init(Tcl_Interp*); | 3697 extern int Sqlitetesttclvar_Init(Tcl_Interp*); |
| 3698 extern int Sqlitetestfs_Init(Tcl_Interp*); |
3573 extern int SqlitetestThread_Init(Tcl_Interp*); | 3699 extern int SqlitetestThread_Init(Tcl_Interp*); |
3574 extern int SqlitetestOnefile_Init(); | 3700 extern int SqlitetestOnefile_Init(); |
3575 extern int SqlitetestOsinst_Init(Tcl_Interp*); | 3701 extern int SqlitetestOsinst_Init(Tcl_Interp*); |
3576 extern int Sqlitetestbackup_Init(Tcl_Interp*); | 3702 extern int Sqlitetestbackup_Init(Tcl_Interp*); |
3577 extern int Sqlitetestintarray_Init(Tcl_Interp*); | 3703 extern int Sqlitetestintarray_Init(Tcl_Interp*); |
3578 extern int Sqlitetestvfs_Init(Tcl_Interp *); | 3704 extern int Sqlitetestvfs_Init(Tcl_Interp *); |
3579 extern int SqlitetestStat_Init(Tcl_Interp*); | |
3580 extern int Sqlitetestrtree_Init(Tcl_Interp*); | 3705 extern int Sqlitetestrtree_Init(Tcl_Interp*); |
3581 extern int Sqlitequota_Init(Tcl_Interp*); | 3706 extern int Sqlitequota_Init(Tcl_Interp*); |
3582 extern int Sqlitemultiplex_Init(Tcl_Interp*); | 3707 extern int Sqlitemultiplex_Init(Tcl_Interp*); |
3583 extern int SqliteSuperlock_Init(Tcl_Interp*); | 3708 extern int SqliteSuperlock_Init(Tcl_Interp*); |
3584 extern int SqlitetestSyscall_Init(Tcl_Interp*); | 3709 extern int SqlitetestSyscall_Init(Tcl_Interp*); |
3585 extern int Sqlitetestfuzzer_Init(Tcl_Interp*); | 3710 |
3586 extern int Sqlitetestwholenumber_Init(Tcl_Interp*); | 3711 #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) |
| 3712 extern int Sqlitetestfts3_Init(Tcl_Interp *interp); |
| 3713 #endif |
3587 | 3714 |
3588 #ifdef SQLITE_ENABLE_ZIPVFS | 3715 #ifdef SQLITE_ENABLE_ZIPVFS |
3589 extern int Zipvfs_Init(Tcl_Interp*); | 3716 extern int Zipvfs_Init(Tcl_Interp*); |
3590 Zipvfs_Init(interp); | 3717 Zipvfs_Init(interp); |
3591 #endif | 3718 #endif |
3592 | 3719 |
3593 Sqliteconfig_Init(interp); | 3720 Sqliteconfig_Init(interp); |
3594 Sqlitetest1_Init(interp); | 3721 Sqlitetest1_Init(interp); |
3595 Sqlitetest2_Init(interp); | 3722 Sqlitetest2_Init(interp); |
3596 Sqlitetest3_Init(interp); | 3723 Sqlitetest3_Init(interp); |
3597 Sqlitetest4_Init(interp); | 3724 Sqlitetest4_Init(interp); |
3598 Sqlitetest5_Init(interp); | 3725 Sqlitetest5_Init(interp); |
3599 Sqlitetest6_Init(interp); | 3726 Sqlitetest6_Init(interp); |
3600 Sqlitetest7_Init(interp); | 3727 Sqlitetest7_Init(interp); |
3601 Sqlitetest8_Init(interp); | 3728 Sqlitetest8_Init(interp); |
3602 Sqlitetest9_Init(interp); | 3729 Sqlitetest9_Init(interp); |
3603 Sqlitetestasync_Init(interp); | 3730 Sqlitetestasync_Init(interp); |
3604 Sqlitetest_autoext_Init(interp); | 3731 Sqlitetest_autoext_Init(interp); |
3605 Sqlitetest_demovfs_Init(interp); | 3732 Sqlitetest_demovfs_Init(interp); |
3606 Sqlitetest_func_Init(interp); | 3733 Sqlitetest_func_Init(interp); |
3607 Sqlitetest_hexio_Init(interp); | 3734 Sqlitetest_hexio_Init(interp); |
3608 Sqlitetest_init_Init(interp); | 3735 Sqlitetest_init_Init(interp); |
3609 Sqlitetest_malloc_Init(interp); | 3736 Sqlitetest_malloc_Init(interp); |
3610 Sqlitetest_mutex_Init(interp); | 3737 Sqlitetest_mutex_Init(interp); |
3611 Sqlitetestschema_Init(interp); | 3738 Sqlitetestschema_Init(interp); |
3612 Sqlitetesttclvar_Init(interp); | 3739 Sqlitetesttclvar_Init(interp); |
| 3740 Sqlitetestfs_Init(interp); |
3613 SqlitetestThread_Init(interp); | 3741 SqlitetestThread_Init(interp); |
3614 SqlitetestOnefile_Init(interp); | 3742 SqlitetestOnefile_Init(interp); |
3615 SqlitetestOsinst_Init(interp); | 3743 SqlitetestOsinst_Init(interp); |
3616 Sqlitetestbackup_Init(interp); | 3744 Sqlitetestbackup_Init(interp); |
3617 Sqlitetestintarray_Init(interp); | 3745 Sqlitetestintarray_Init(interp); |
3618 Sqlitetestvfs_Init(interp); | 3746 Sqlitetestvfs_Init(interp); |
3619 SqlitetestStat_Init(interp); | |
3620 Sqlitetestrtree_Init(interp); | 3747 Sqlitetestrtree_Init(interp); |
3621 Sqlitequota_Init(interp); | 3748 Sqlitequota_Init(interp); |
3622 Sqlitemultiplex_Init(interp); | 3749 Sqlitemultiplex_Init(interp); |
3623 SqliteSuperlock_Init(interp); | 3750 SqliteSuperlock_Init(interp); |
3624 SqlitetestSyscall_Init(interp); | 3751 SqlitetestSyscall_Init(interp); |
3625 Sqlitetestfuzzer_Init(interp); | |
3626 Sqlitetestwholenumber_Init(interp); | |
3627 | 3752 |
3628 Tcl_CreateObjCommand(interp,"load_testfixture_extensions",init_all_cmd,0,0); | 3753 #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) |
| 3754 Sqlitetestfts3_Init(interp); |
| 3755 #endif |
| 3756 |
| 3757 Tcl_CreateObjCommand( |
| 3758 interp, "load_testfixture_extensions", init_all_cmd, 0, 0 |
| 3759 ); |
| 3760 Tcl_CreateObjCommand( |
| 3761 interp, "db_use_legacy_prepare", db_use_legacy_prepare_cmd, 0, 0 |
| 3762 ); |
3629 | 3763 |
3630 #ifdef SQLITE_SSE | 3764 #ifdef SQLITE_SSE |
3631 Sqlitetestsse_Init(interp); | 3765 Sqlitetestsse_Init(interp); |
3632 #endif | 3766 #endif |
3633 } | 3767 } |
3634 #endif | 3768 #endif |
3635 } | 3769 } |
3636 | 3770 |
3637 #define TCLSH_MAIN main /* Needed to fake out mktclapp */ | 3771 #define TCLSH_MAIN main /* Needed to fake out mktclapp */ |
3638 int TCLSH_MAIN(int argc, char **argv){ | 3772 int TCLSH_MAIN(int argc, char **argv){ |
3639 Tcl_Interp *interp; | 3773 Tcl_Interp *interp; |
3640 | 3774 |
| 3775 #if !defined(_WIN32_WCE) |
| 3776 if( getenv("BREAK") ){ |
| 3777 fprintf(stderr, |
| 3778 "attach debugger to process %d and press any key to continue.\n", |
| 3779 GETPID()); |
| 3780 fgetc(stdin); |
| 3781 } |
| 3782 #endif |
| 3783 |
3641 /* Call sqlite3_shutdown() once before doing anything else. This is to | 3784 /* Call sqlite3_shutdown() once before doing anything else. This is to |
3642 ** test that sqlite3_shutdown() can be safely called by a process before | 3785 ** test that sqlite3_shutdown() can be safely called by a process before |
3643 ** sqlite3_initialize() is. */ | 3786 ** sqlite3_initialize() is. */ |
3644 sqlite3_shutdown(); | 3787 sqlite3_shutdown(); |
3645 | 3788 |
| 3789 Tcl_FindExecutable(argv[0]); |
| 3790 Tcl_SetSystemEncoding(NULL, "utf-8"); |
| 3791 interp = Tcl_CreateInterp(); |
| 3792 |
3646 #if TCLSH==2 | 3793 #if TCLSH==2 |
3647 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); | 3794 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); |
3648 #endif | 3795 #endif |
3649 Tcl_FindExecutable(argv[0]); | |
3650 | 3796 |
3651 interp = Tcl_CreateInterp(); | |
3652 init_all(interp); | 3797 init_all(interp); |
3653 if( argc>=2 ){ | 3798 if( argc>=2 ){ |
3654 int i; | 3799 int i; |
3655 char zArgc[32]; | 3800 char zArgc[32]; |
3656 sqlite3_snprintf(sizeof(zArgc), zArgc, "%d", argc-(3-TCLSH)); | 3801 sqlite3_snprintf(sizeof(zArgc), zArgc, "%d", argc-(3-TCLSH)); |
3657 Tcl_SetVar(interp,"argc", zArgc, TCL_GLOBAL_ONLY); | 3802 Tcl_SetVar(interp,"argc", zArgc, TCL_GLOBAL_ONLY); |
3658 Tcl_SetVar(interp,"argv0",argv[1],TCL_GLOBAL_ONLY); | 3803 Tcl_SetVar(interp,"argv0",argv[1],TCL_GLOBAL_ONLY); |
3659 Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY); | 3804 Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY); |
3660 for(i=3-TCLSH; i<argc; i++){ | 3805 for(i=3-TCLSH; i<argc; i++){ |
3661 Tcl_SetVar(interp, "argv", argv[i], | 3806 Tcl_SetVar(interp, "argv", argv[i], |
3662 TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE); | 3807 TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE); |
3663 } | 3808 } |
3664 if( TCLSH==1 && Tcl_EvalFile(interp, argv[1])!=TCL_OK ){ | 3809 if( TCLSH==1 && Tcl_EvalFile(interp, argv[1])!=TCL_OK ){ |
3665 const char *zInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY); | 3810 const char *zInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY); |
3666 if( zInfo==0 ) zInfo = Tcl_GetStringResult(interp); | 3811 if( zInfo==0 ) zInfo = Tcl_GetStringResult(interp); |
3667 fprintf(stderr,"%s: %s\n", *argv, zInfo); | 3812 fprintf(stderr,"%s: %s\n", *argv, zInfo); |
3668 return 1; | 3813 return 1; |
3669 } | 3814 } |
3670 } | 3815 } |
3671 if( TCLSH==2 || argc<=1 ){ | 3816 if( TCLSH==2 || argc<=1 ){ |
3672 Tcl_GlobalEval(interp, zMainloop); | 3817 Tcl_GlobalEval(interp, tclsh_main_loop()); |
3673 } | 3818 } |
3674 return 0; | 3819 return 0; |
3675 } | 3820 } |
3676 #endif /* TCLSH */ | 3821 #endif /* TCLSH */ |
OLD | NEW |