Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(34)

Unified Diff: third_party/sqlite/src/src/tclsqlite.c

Issue 949043002: Add //third_party/sqlite to dirs_to_snapshot, remove net_sql.patch (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/sqlite/src/src/table.c ('k') | third_party/sqlite/src/src/test1.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/sqlite/src/src/tclsqlite.c
diff --git a/third_party/sqlite/src/src/tclsqlite.c b/third_party/sqlite/src/src/tclsqlite.c
index 575651d7e561d11c8e54280377b72ff6bddd75ec..756d0daa5a914287f55b0faeb431caf6d0a40b03 100644
--- a/third_party/sqlite/src/src/tclsqlite.c
+++ b/third_party/sqlite/src/src/tclsqlite.c
@@ -41,6 +41,18 @@
#endif
#include <ctype.h>
+/* Used to get the current process ID */
+#if !defined(_WIN32)
+# include <unistd.h>
+# define GETPID getpid
+#elif !defined(_WIN32_WCE)
+# ifndef SQLITE_AMALGAMATION
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# endif
+# define GETPID (int)GetCurrentProcessId
+#endif
+
/*
* Windows needs to know which symbols to export. Unix does not.
* BUILD_sqlite should be undefined for Unix.
@@ -53,15 +65,8 @@
#define NUM_PREPARED_STMTS 10
#define MAX_PREPARED_STMTS 100
-/*
-** If TCL uses UTF-8 and SQLite is configured to use iso8859, then we
-** have to do a translation when going between the two. Set the
-** UTF_TRANSLATION_NEEDED macro to indicate that we need to do
-** this translation.
-*/
-#if defined(TCL_UTF_MAX) && !defined(SQLITE_UTF8)
-# define UTF_TRANSLATION_NEEDED 1
-#endif
+/* Forward declaration */
+typedef struct SqliteDb SqliteDb;
/*
** New SQL functions can be created as TCL scripts. Each such function
@@ -71,6 +76,7 @@ typedef struct SqlFunc SqlFunc;
struct SqlFunc {
Tcl_Interp *interp; /* The TCL interpret to execute the function */
Tcl_Obj *pScript; /* The Tcl_Obj representation of the script */
+ SqliteDb *pDb; /* Database connection that owns this function */
int useEvalObjv; /* True if it is safe to use Tcl_EvalObjv */
char *zName; /* Name of this function */
SqlFunc *pNext; /* Next function on the list of them all */
@@ -107,8 +113,12 @@ typedef struct IncrblobChannel IncrblobChannel;
/*
** There is one instance of this structure for each SQLite database
** that has been opened by the SQLite TCL interface.
+**
+** If this module is built with SQLITE_TEST defined (to create the SQLite
+** testfixture executable), then it may be configured to use either
+** sqlite3_prepare_v2() or sqlite3_prepare() to prepare SQL statements.
+** If SqliteDb.bLegacyPrepare is true, sqlite3_prepare() is used.
*/
-typedef struct SqliteDb SqliteDb;
struct SqliteDb {
sqlite3 *db; /* The "real" database structure. MUST BE FIRST */
Tcl_Interp *interp; /* The interpreter used for this database */
@@ -135,6 +145,9 @@ struct SqliteDb {
IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */
int nStep, nSort, nIndex; /* Statistics for most recent operation */
int nTransaction; /* Number of nested [transaction] methods */
+#ifdef SQLITE_TEST
+ int bLegacyPrepare; /* True to use sqlite3_prepare() */
+#endif
};
struct IncrblobChannel {
@@ -411,18 +424,18 @@ static int safeToUseEvalObjv(Tcl_Interp *interp, Tcl_Obj *pCmd){
*/
static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){
SqlFunc *p, *pNew;
- int i;
- pNew = (SqlFunc*)Tcl_Alloc( sizeof(*pNew) + strlen30(zName) + 1 );
+ int nName = strlen30(zName);
+ pNew = (SqlFunc*)Tcl_Alloc( sizeof(*pNew) + nName + 1 );
pNew->zName = (char*)&pNew[1];
- for(i=0; zName[i]; i++){ pNew->zName[i] = tolower(zName[i]); }
- pNew->zName[i] = 0;
+ memcpy(pNew->zName, zName, nName+1);
for(p=pDb->pFunc; p; p=p->pNext){
- if( strcmp(p->zName, pNew->zName)==0 ){
+ if( sqlite3_stricmp(p->zName, pNew->zName)==0 ){
Tcl_Free((char*)pNew);
return p;
}
}
pNew->interp = pDb->interp;
+ pNew->pDb = pDb;
pNew->pScript = 0;
pNew->pNext = pDb->pFunc;
pDb->pFunc = pNew;
@@ -430,19 +443,32 @@ static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){
}
/*
+** Free a single SqlPreparedStmt object.
+*/
+static void dbFreeStmt(SqlPreparedStmt *pStmt){
+#ifdef SQLITE_TEST
+ if( sqlite3_sql(pStmt->pStmt)==0 ){
+ Tcl_Free((char *)pStmt->zSql);
+ }
+#endif
+ sqlite3_finalize(pStmt->pStmt);
+ Tcl_Free((char *)pStmt);
+}
+
+/*
** Finalize and free a list of prepared statements
*/
-static void flushStmtCache( SqliteDb *pDb ){
+static void flushStmtCache(SqliteDb *pDb){
SqlPreparedStmt *pPreStmt;
+ SqlPreparedStmt *pNext;
- while( pDb->stmtList ){
- sqlite3_finalize( pDb->stmtList->pStmt );
- pPreStmt = pDb->stmtList;
- pDb->stmtList = pDb->stmtList->pNext;
- Tcl_Free( (char*)pPreStmt );
+ for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pNext){
+ pNext = pPreStmt->pNext;
+ dbFreeStmt(pPreStmt);
}
pDb->nStmt = 0;
pDb->stmtLast = 0;
+ pDb->stmtList = 0;
}
/*
@@ -457,6 +483,7 @@ static void DbDeleteCmd(void *db){
while( pDb->pFunc ){
SqlFunc *pFunc = pDb->pFunc;
pDb->pFunc = pFunc->pNext;
+ assert( pFunc->pDb==pDb );
Tcl_DecrRefCount(pFunc->pScript);
Tcl_Free((char*)pFunc);
}
@@ -733,7 +760,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
/* If there are arguments to the function, make a shallow copy of the
** script object, lappend the arguments, then evaluate the copy.
**
- ** By "shallow" copy, we mean a only the outer list Tcl_Obj is duplicated.
+ ** By "shallow" copy, we mean only the outer list Tcl_Obj is duplicated.
** The new Tcl_Obj contains pointers to the original list elements.
** That way, when Tcl_EvalObjv() is run and shimmers the first element
** of the list to tclCmdNameType, that alternate representation will
@@ -761,7 +788,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
case SQLITE_INTEGER: {
sqlite_int64 v = sqlite3_value_int64(pIn);
if( v>=-2147483647 && v<=2147483647 ){
- pVal = Tcl_NewIntObj(v);
+ pVal = Tcl_NewIntObj((int)v);
}else{
pVal = Tcl_NewWideIntObj(v);
}
@@ -773,7 +800,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
break;
}
case SQLITE_NULL: {
- pVal = Tcl_NewStringObj("", 0);
+ pVal = Tcl_NewStringObj(p->pDb->zNull, -1);
break;
}
default: {
@@ -845,8 +872,11 @@ static int auth_callback(
const char *zArg2,
const char *zArg3,
const char *zArg4
+#ifdef SQLITE_USER_AUTHENTICATION
+ ,const char *zArg5
+#endif
){
- char *zCode;
+ const char *zCode;
Tcl_DString str;
int rc;
const char *zReply;
@@ -887,6 +917,7 @@ static int auth_callback(
case SQLITE_DROP_VTABLE : zCode="SQLITE_DROP_VTABLE"; break;
case SQLITE_FUNCTION : zCode="SQLITE_FUNCTION"; break;
case SQLITE_SAVEPOINT : zCode="SQLITE_SAVEPOINT"; break;
+ case SQLITE_RECURSIVE : zCode="SQLITE_RECURSIVE"; break;
default : zCode="????"; break;
}
Tcl_DStringInit(&str);
@@ -896,9 +927,12 @@ static int auth_callback(
Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : "");
Tcl_DStringAppendElement(&str, zArg3 ? zArg3 : "");
Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : "");
+#ifdef SQLITE_USER_AUTHENTICATION
+ Tcl_DStringAppendElement(&str, zArg5 ? zArg5 : "");
+#endif
rc = Tcl_GlobalEval(pDb->interp, Tcl_DStringValue(&str));
Tcl_DStringFree(&str);
- zReply = Tcl_GetStringResult(pDb->interp);
+ zReply = rc==TCL_OK ? Tcl_GetStringResult(pDb->interp) : "SQLITE_DENY";
if( strcmp(zReply,"SQLITE_OK")==0 ){
rc = SQLITE_OK;
}else if( strcmp(zReply,"SQLITE_DENY")==0 ){
@@ -913,26 +947,6 @@ static int auth_callback(
#endif /* SQLITE_OMIT_AUTHORIZATION */
/*
-** zText is a pointer to text obtained via an sqlite3_result_text()
-** or similar interface. This routine returns a Tcl string object,
-** reference count set to 0, containing the text. If a translation
-** between iso8859 and UTF-8 is required, it is preformed.
-*/
-static Tcl_Obj *dbTextToObj(char const *zText){
- Tcl_Obj *pVal;
-#ifdef UTF_TRANSLATION_NEEDED
- Tcl_DString dCol;
- Tcl_DStringInit(&dCol);
- Tcl_ExternalToUtfDString(NULL, zText, -1, &dCol);
- pVal = Tcl_NewStringObj(Tcl_DStringValue(&dCol), -1);
- Tcl_DStringFree(&dCol);
-#else
- pVal = Tcl_NewStringObj(zText, -1);
-#endif
- return pVal;
-}
-
-/*
** This routine reads a line of text from FILE in, stores
** the text in memory obtained from malloc() and returns a pointer
** to the text. NULL is returned at end of file, or if malloc()
@@ -947,14 +961,12 @@ static char *local_getline(char *zPrompt, FILE *in){
char *zLine;
int nLine;
int n;
- int eol;
nLine = 100;
zLine = malloc( nLine );
if( zLine==0 ) return 0;
n = 0;
- eol = 0;
- while( !eol ){
+ while( 1 ){
if( n+100>nLine ){
nLine = nLine*2 + 100;
zLine = realloc(zLine, nLine);
@@ -966,14 +978,13 @@ static char *local_getline(char *zPrompt, FILE *in){
return 0;
}
zLine[n] = 0;
- eol = 1;
break;
}
while( zLine[n] ){ n++; }
if( n>0 && zLine[n-1]=='\n' ){
n--;
zLine[n] = 0;
- eol = 1;
+ break;
}
}
zLine = realloc( zLine, n+1 );
@@ -994,7 +1005,7 @@ static int DbTransPostCmd(
Tcl_Interp *interp, /* Tcl interpreter */
int result /* Result of evaluating SCRIPT */
){
- static const char *azEnd[] = {
+ static const char *const azEnd[] = {
"RELEASE _tcl_transaction", /* rc==TCL_ERROR, nTransaction!=0 */
"COMMIT", /* rc!=TCL_ERROR, nTransaction==0 */
"ROLLBACK TO _tcl_transaction ; RELEASE _tcl_transaction",
@@ -1012,7 +1023,7 @@ static int DbTransPostCmd(
/* This is a tricky scenario to handle. The most likely cause of an
** error is that the exec() above was an attempt to commit the
** top-level transaction that returned SQLITE_BUSY. Or, less likely,
- ** that an IO-error has occured. In either case, throw a Tcl exception
+ ** that an IO-error has occurred. In either case, throw a Tcl exception
** and try to rollback the transaction.
**
** But it could also be that the user executed one or more BEGIN,
@@ -1020,7 +1031,7 @@ static int DbTransPostCmd(
** this method's logic. Not clear how this would be best handled.
*/
if( rc!=TCL_ERROR ){
- Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0);
+ Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
rc = TCL_ERROR;
}
sqlite3_exec(pDb->db, "ROLLBACK", 0, 0, 0);
@@ -1031,6 +1042,27 @@ static int DbTransPostCmd(
}
/*
+** Unless SQLITE_TEST is defined, this function is a simple wrapper around
+** sqlite3_prepare_v2(). If SQLITE_TEST is defined, then it uses either
+** sqlite3_prepare_v2() or legacy interface sqlite3_prepare(), depending
+** on whether or not the [db_use_legacy_prepare] command has been used to
+** configure the connection.
+*/
+static int dbPrepare(
+ SqliteDb *pDb, /* Database object */
+ const char *zSql, /* SQL to compile */
+ sqlite3_stmt **ppStmt, /* OUT: Prepared statement */
+ const char **pzOut /* OUT: Pointer to next SQL statement */
+){
+#ifdef SQLITE_TEST
+ if( pDb->bLegacyPrepare ){
+ return sqlite3_prepare(pDb->db, zSql, -1, ppStmt, pzOut);
+ }
+#endif
+ return sqlite3_prepare_v2(pDb->db, zSql, -1, ppStmt, pzOut);
+}
+
+/*
** Search the cache for a prepared-statement object that implements the
** first SQL statement in the buffer pointed to by parameter zIn. If
** no such prepared-statement can be found, allocate and prepare a new
@@ -1057,13 +1089,14 @@ static int dbPrepareAndBind(
int nSql; /* Length of zSql in bytes */
int nVar; /* Number of variables in statement */
int iParm = 0; /* Next free entry in apParm */
+ char c;
int i;
Tcl_Interp *interp = pDb->interp;
*ppPreStmt = 0;
/* Trim spaces from the start of zSql and calculate the remaining length. */
- while( isspace(zSql[0]) ){ zSql++; }
+ while( (c = zSql[0])==' ' || c=='\t' || c=='\r' || c=='\n' ){ zSql++; }
nSql = strlen30(zSql);
for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pPreStmt->pNext){
@@ -1100,14 +1133,14 @@ static int dbPrepareAndBind(
if( pPreStmt==0 ){
int nByte;
- if( SQLITE_OK!=sqlite3_prepare_v2(pDb->db, zSql, -1, &pStmt, pzOut) ){
- Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
+ if( SQLITE_OK!=dbPrepare(pDb, zSql, &pStmt, pzOut) ){
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
return TCL_ERROR;
}
if( pStmt==0 ){
if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){
/* A compile-time error in the statement. */
- Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
return TCL_ERROR;
}else{
/* The statement was a no-op. Continue to the next statement
@@ -1124,9 +1157,17 @@ static int dbPrepareAndBind(
memset(pPreStmt, 0, nByte);
pPreStmt->pStmt = pStmt;
- pPreStmt->nSql = (*pzOut - zSql);
+ pPreStmt->nSql = (int)(*pzOut - zSql);
pPreStmt->zSql = sqlite3_sql(pStmt);
pPreStmt->apParm = (Tcl_Obj **)&pPreStmt[1];
+#ifdef SQLITE_TEST
+ if( pPreStmt->zSql==0 ){
+ char *zCopy = Tcl_Alloc(pPreStmt->nSql + 1);
+ memcpy(zCopy, zSql, pPreStmt->nSql);
+ zCopy[pPreStmt->nSql] = '\0';
+ pPreStmt->zSql = zCopy;
+ }
+#endif
}
assert( pPreStmt );
assert( strlen30(pPreStmt->zSql)==pPreStmt->nSql );
@@ -1180,7 +1221,6 @@ static int dbPrepareAndBind(
return TCL_OK;
}
-
/*
** Release a statement reference obtained by calling dbPrepareAndBind().
** There should be exactly one call to this function for each call to
@@ -1205,8 +1245,7 @@ static void dbReleaseStmt(
if( pDb->maxStmt<=0 || discard ){
/* If the cache is turned off, deallocated the statement */
- sqlite3_finalize(pPreStmt->pStmt);
- Tcl_Free((char *)pPreStmt);
+ dbFreeStmt(pPreStmt);
}else{
/* Add the prepared statement to the beginning of the cache list. */
pPreStmt->pNext = pDb->stmtList;
@@ -1226,11 +1265,11 @@ static void dbReleaseStmt(
/* If we have too many statement in cache, remove the surplus from
** the end of the cache list. */
while( pDb->nStmt>pDb->maxStmt ){
- sqlite3_finalize(pDb->stmtLast->pStmt);
- pDb->stmtLast = pDb->stmtLast->pPrev;
- Tcl_Free((char*)pDb->stmtLast->pNext);
+ SqlPreparedStmt *pLast = pDb->stmtLast;
+ pDb->stmtLast = pLast->pPrev;
pDb->stmtLast->pNext = 0;
pDb->nStmt--;
+ dbFreeStmt(pLast);
}
}
}
@@ -1320,7 +1359,7 @@ static void dbEvalRowInfo(
if( nCol>0 && (papColName || p->pArray) ){
apColName = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*)*nCol );
for(i=0; i<nCol; i++){
- apColName[i] = dbTextToObj(sqlite3_column_name(pStmt,i));
+ apColName[i] = Tcl_NewStringObj(sqlite3_column_name(pStmt,i), -1);
Tcl_IncrRefCount(apColName[i]);
}
p->apColName = apColName;
@@ -1363,9 +1402,12 @@ static void dbEvalRowInfo(
** no further rows available. This is similar to SQLITE_DONE.
*/
static int dbEvalStep(DbEvalContext *p){
+ const char *zPrevSql = 0; /* Previous value of p->zSql */
+
while( p->zSql[0] || p->pPreStmt ){
int rc;
if( p->pPreStmt==0 ){
+ zPrevSql = (p->zSql==zPrevSql ? 0 : p->zSql);
rc = dbPrepareAndBind(p->pDb, p->zSql, &p->zSql, &p->pPreStmt);
if( rc!=TCL_OK ) return rc;
}else{
@@ -1392,8 +1434,20 @@ static int dbEvalStep(DbEvalContext *p){
if( rcs!=SQLITE_OK ){
/* If a run-time error occurs, report the error and stop reading
** the SQL. */
- Tcl_SetObjResult(pDb->interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
dbReleaseStmt(pDb, pPreStmt, 1);
+#if SQLITE_TEST
+ if( p->pDb->bLegacyPrepare && rcs==SQLITE_SCHEMA && zPrevSql ){
+ /* If the runtime error was an SQLITE_SCHEMA, and the database
+ ** handle is configured to use the legacy sqlite3_prepare()
+ ** interface, retry prepare()/step() on the same SQL statement.
+ ** This only happens once. If there is a second SQLITE_SCHEMA
+ ** error, the error will be returned to the caller. */
+ p->zSql = zPrevSql;
+ continue;
+ }
+#endif
+ Tcl_SetObjResult(pDb->interp,
+ Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
return TCL_ERROR;
}else{
dbReleaseStmt(pDb, pPreStmt, 0);
@@ -1441,7 +1495,7 @@ static Tcl_Obj *dbEvalColumnValue(DbEvalContext *p, int iCol){
case SQLITE_INTEGER: {
sqlite_int64 v = sqlite3_column_int64(pStmt, iCol);
if( v>=-2147483647 && v<=2147483647 ){
- return Tcl_NewIntObj(v);
+ return Tcl_NewIntObj((int)v);
}else{
return Tcl_NewWideIntObj(v);
}
@@ -1450,11 +1504,11 @@ static Tcl_Obj *dbEvalColumnValue(DbEvalContext *p, int iCol){
return Tcl_NewDoubleObj(sqlite3_column_double(pStmt, iCol));
}
case SQLITE_NULL: {
- return dbTextToObj(p->pDb->zNull);
+ return Tcl_NewStringObj(p->pDb->zNull, -1);
}
}
- return dbTextToObj((char *)sqlite3_column_text(pStmt, iCol));
+ return Tcl_NewStringObj((char*)sqlite3_column_text(pStmt, iCol), -1);
}
/*
@@ -1483,9 +1537,9 @@ static int DbUseNre(void){
*/
# define SQLITE_TCL_NRE 0
# define DbUseNre() 0
-# define Tcl_NRAddCallback(a,b,c,d,e,f) 0
+# define Tcl_NRAddCallback(a,b,c,d,e,f) (void)0
# define Tcl_NREvalObj(a,b,c) 0
-# define Tcl_NRCreateCommand(a,b,c,d,e,f) 0
+# define Tcl_NRCreateCommand(a,b,c,d,e,f) (void)0
#endif
/*
@@ -1627,7 +1681,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
*/
case DB_AUTHORIZER: {
#ifdef SQLITE_OMIT_AUTHORIZATION
- Tcl_AppendResult(interp, "authorization not available in this build", 0);
+ Tcl_AppendResult(interp, "authorization not available in this build",
+ (char*)0);
return TCL_ERROR;
#else
if( objc>3 ){
@@ -1635,7 +1690,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
return TCL_ERROR;
}else if( objc==2 ){
if( pDb->zAuth ){
- Tcl_AppendResult(interp, pDb->zAuth, 0);
+ Tcl_AppendResult(interp, pDb->zAuth, (char*)0);
}
}else{
char *zAuth;
@@ -1651,8 +1706,11 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
pDb->zAuth = 0;
}
if( pDb->zAuth ){
+ typedef int (*sqlite3_auth_cb)(
+ void*,int,const char*,const char*,
+ const char*,const char*);
pDb->interp = interp;
- sqlite3_set_authorizer(pDb->db, auth_callback, pDb);
+ sqlite3_set_authorizer(pDb->db,(sqlite3_auth_cb)auth_callback,pDb);
}else{
sqlite3_set_authorizer(pDb->db, 0, 0);
}
@@ -1721,7 +1779,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
return TCL_ERROR;
}else if( objc==2 ){
if( pDb->zBusy ){
- Tcl_AppendResult(interp, pDb->zBusy, 0);
+ Tcl_AppendResult(interp, pDb->zBusy, (char*)0);
}
}else{
char *zBusy;
@@ -1775,7 +1833,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
}else{
if( TCL_ERROR==Tcl_GetIntFromObj(interp, objv[3], &n) ){
Tcl_AppendResult( interp, "cannot convert \"",
- Tcl_GetStringFromObj(objv[3],0), "\" to integer", 0);
+ Tcl_GetStringFromObj(objv[3],0), "\" to integer", (char*)0);
return TCL_ERROR;
}else{
if( n<0 ){
@@ -1789,7 +1847,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
}
}else{
Tcl_AppendResult( interp, "bad option \"",
- Tcl_GetStringFromObj(objv[2],0), "\": must be flush or size", 0);
+ Tcl_GetStringFromObj(objv[2],0), "\": must be flush or size",
+ (char*)0);
return TCL_ERROR;
}
break;
@@ -1886,10 +1945,10 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
return TCL_ERROR;
}else if( objc==2 ){
if( pDb->zCommit ){
- Tcl_AppendResult(interp, pDb->zCommit, 0);
+ Tcl_AppendResult(interp, pDb->zCommit, (char*)0);
}
}else{
- char *zCommit;
+ const char *zCommit;
int len;
if( pDb->zCommit ){
Tcl_Free(pDb->zCommit);
@@ -1962,14 +2021,14 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
char *zSql; /* An SQL statement */
char *zLine; /* A single line of input from the file */
char **azCol; /* zLine[] broken up into columns */
- char *zCommit; /* How to commit changes */
+ const char *zCommit; /* How to commit changes */
FILE *in; /* The input file */
int lineno = 0; /* Line number of input file */
char zLineNum[80]; /* Line number print buffer */
Tcl_Obj *pResult; /* interp result */
- char *zSep;
- char *zNull;
+ const char *zSep;
+ const char *zNull;
if( objc<5 || objc>7 ){
Tcl_WrongNumArgs(interp, 2, objv,
"CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?");
@@ -1991,7 +2050,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
nSep = strlen30(zSep);
nNull = strlen30(zNull);
if( nSep==0 ){
- Tcl_AppendResult(interp,"Error: non-null separator required for copy",0);
+ Tcl_AppendResult(interp,"Error: non-null separator required for copy",
+ (char*)0);
return TCL_ERROR;
}
if(strcmp(zConflict, "rollback") != 0 &&
@@ -2001,19 +2061,19 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
strcmp(zConflict, "replace" ) != 0 ) {
Tcl_AppendResult(interp, "Error: \"", zConflict,
"\", conflict-algorithm must be one of: rollback, "
- "abort, fail, ignore, or replace", 0);
+ "abort, fail, ignore, or replace", (char*)0);
return TCL_ERROR;
}
zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
if( zSql==0 ){
- Tcl_AppendResult(interp, "Error: no such table: ", zTable, 0);
+ Tcl_AppendResult(interp, "Error: no such table: ", zTable, (char*)0);
return TCL_ERROR;
}
nByte = strlen30(zSql);
rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0);
sqlite3_free(zSql);
if( rc ){
- Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), 0);
+ Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), (char*)0);
nCol = 0;
}else{
nCol = sqlite3_column_count(pStmt);
@@ -2024,7 +2084,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
}
zSql = malloc( nByte + 50 + nCol*2 );
if( zSql==0 ) {
- Tcl_AppendResult(interp, "Error: can't malloc()", 0);
+ Tcl_AppendResult(interp, "Error: can't malloc()", (char*)0);
return TCL_ERROR;
}
sqlite3_snprintf(nByte+50, zSql, "INSERT OR %q INTO '%q' VALUES(?",
@@ -2039,7 +2099,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0);
free(zSql);
if( rc ){
- Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), 0);
+ Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), (char*)0);
sqlite3_finalize(pStmt);
return TCL_ERROR;
}
@@ -2051,7 +2111,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
}
azCol = malloc( sizeof(azCol[0])*(nCol+1) );
if( azCol==0 ) {
- Tcl_AppendResult(interp, "Error: can't malloc()", 0);
+ Tcl_AppendResult(interp, "Error: can't malloc()", (char*)0);
fclose(in);
return TCL_ERROR;
}
@@ -2059,7 +2119,6 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
zCommit = "COMMIT";
while( (zLine = local_getline(0, in))!=0 ){
char *z;
- i = 0;
lineno++;
azCol[0] = zLine;
for(i=0, z=zLine; *z; z++){
@@ -2080,7 +2139,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
sqlite3_snprintf(nErr, zErr,
"Error: %s line %d: expected %d columns of data but found %d",
zFile, lineno, nCol, i+1);
- Tcl_AppendResult(interp, zErr, 0);
+ Tcl_AppendResult(interp, zErr, (char*)0);
free(zErr);
}
zCommit = "ROLLBACK";
@@ -2100,7 +2159,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
rc = sqlite3_reset(pStmt);
free(zLine);
if( rc!=SQLITE_OK ){
- Tcl_AppendResult(interp,"Error: ", sqlite3_errmsg(pDb->db), 0);
+ Tcl_AppendResult(interp,"Error: ", sqlite3_errmsg(pDb->db), (char*)0);
zCommit = "ROLLBACK";
break;
}
@@ -2118,7 +2177,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
}else{
/* failure, append lineno where failed */
sqlite3_snprintf(sizeof(zLineNum), zLineNum,"%d",lineno);
- Tcl_AppendResult(interp,", failed while processing line: ",zLineNum,0);
+ Tcl_AppendResult(interp,", failed while processing line: ",zLineNum,
+ (char*)0);
rc = TCL_ERROR;
}
break;
@@ -2144,7 +2204,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
break;
#else
Tcl_AppendResult(interp, "extension loading is turned off at compile-time",
- 0);
+ (char*)0);
return TCL_ERROR;
#endif
}
@@ -2180,6 +2240,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
if( choice==DB_ONECOLUMN ){
if( rc==TCL_OK ){
Tcl_SetObjResult(interp, dbEvalColumnValue(&sEval, 0));
+ }else if( rc==TCL_BREAK ){
+ Tcl_ResetResult(interp);
}
}else if( rc==TCL_BREAK || rc==TCL_OK ){
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(rc==TCL_OK));
@@ -2300,14 +2362,14 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
*/
case DB_INCRBLOB: {
#ifdef SQLITE_OMIT_INCRBLOB
- Tcl_AppendResult(interp, "incrblob not available in this build", 0);
+ Tcl_AppendResult(interp, "incrblob not available in this build", (char*)0);
return TCL_ERROR;
#else
int isReadonly = 0;
const char *zDb = "main";
const char *zTable;
const char *zColumn;
- sqlite_int64 iRow;
+ Tcl_WideInt iRow;
/* Check for the -readonly option */
if( objc>3 && strcmp(Tcl_GetString(objv[2]), "-readonly")==0 ){
@@ -2328,7 +2390,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
if( rc==TCL_OK ){
rc = createIncrblobChannel(
- interp, pDb, zDb, zTable, zColumn, iRow, isReadonly
+ interp, pDb, zDb, zTable, zColumn, (sqlite3_int64)iRow, isReadonly
);
}
#endif
@@ -2367,13 +2429,13 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
}
if( zNull && len>0 ){
pDb->zNull = Tcl_Alloc( len + 1 );
- strncpy(pDb->zNull, zNull, len);
+ memcpy(pDb->zNull, zNull, len);
pDb->zNull[len] = '\0';
}else{
pDb->zNull = 0;
}
}
- Tcl_SetObjResult(interp, dbTextToObj(pDb->zNull));
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(pDb->zNull, -1));
break;
}
@@ -2407,7 +2469,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
case DB_PROGRESS: {
if( objc==2 ){
if( pDb->zProgress ){
- Tcl_AppendResult(interp, pDb->zProgress, 0);
+ Tcl_AppendResult(interp, pDb->zProgress, (char*)0);
}
}else if( objc==4 ){
char *zProgress;
@@ -2453,7 +2515,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
return TCL_ERROR;
}else if( objc==2 ){
if( pDb->zProfile ){
- Tcl_AppendResult(interp, pDb->zProfile, 0);
+ Tcl_AppendResult(interp, pDb->zProfile, (char*)0);
}
}else{
char *zProfile;
@@ -2486,17 +2548,19 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
** Change the encryption key on the currently open database.
*/
case DB_REKEY: {
+#ifdef SQLITE_HAS_CODEC
int nKey;
void *pKey;
+#endif
if( objc!=3 ){
Tcl_WrongNumArgs(interp, 2, objv, "KEY");
return TCL_ERROR;
}
- pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey);
#ifdef SQLITE_HAS_CODEC
+ pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey);
rc = sqlite3_rekey(pDb->db, pKey, nKey);
if( rc ){
- Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0);
+ Tcl_AppendResult(interp, sqlite3_errstr(rc), (char*)0);
rc = TCL_ERROR;
}
#endif
@@ -2637,7 +2701,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
return TCL_ERROR;
}else if( objc==2 ){
if( pDb->zTrace ){
- Tcl_AppendResult(interp, pDb->zTrace, 0);
+ Tcl_AppendResult(interp, pDb->zTrace, (char*)0);
}
}else{
char *zTrace;
@@ -2708,7 +2772,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
rc = sqlite3_exec(pDb->db, zBegin, 0, 0, 0);
pDb->disableAuth--;
if( rc!=SQLITE_OK ){
- Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0);
+ Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
return TCL_ERROR;
}
pDb->nTransaction++;
@@ -2720,7 +2784,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
** or savepoint. */
if( DbUseNre() ){
Tcl_NRAddCallback(interp, DbTransPostCmd, cd, 0, 0, 0);
- Tcl_NREvalObj(interp, pScript, 0);
+ (void)Tcl_NREvalObj(interp, pScript, 0);
}else{
rc = DbTransPostCmd(&cd, interp, Tcl_EvalObjEx(interp, pScript, 0));
}
@@ -2732,7 +2796,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
*/
case DB_UNLOCK_NOTIFY: {
#ifndef SQLITE_ENABLE_UNLOCK_NOTIFY
- Tcl_AppendResult(interp, "unlock_notify not available in this build", 0);
+ Tcl_AppendResult(interp, "unlock_notify not available in this build",
+ (char*)0);
rc = TCL_ERROR;
#else
if( objc!=2 && objc!=3 ){
@@ -2755,7 +2820,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
}
if( sqlite3_unlock_notify(pDb->db, xNotify, pNotifyArg) ){
- Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0);
+ Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
rc = TCL_ERROR;
}
}
@@ -2856,8 +2921,6 @@ static int DbObjCmdAdaptor(
*/
static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
SqliteDb *p;
- void *pKey = 0;
- int nKey = 0;
const char *zArg;
char *zErrMsg;
int i;
@@ -2865,6 +2928,11 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
const char *zVfs = 0;
int flags;
Tcl_DString translatedFilename;
+#ifdef SQLITE_HAS_CODEC
+ void *pKey = 0;
+ int nKey = 0;
+#endif
+ int rc;
/* In normal use, each TCL interpreter runs in a single thread. So
** by default, we can turn of mutexing on SQLite database connections.
@@ -2881,14 +2949,14 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
if( objc==2 ){
zArg = Tcl_GetStringFromObj(objv[1], 0);
if( strcmp(zArg,"-version")==0 ){
- Tcl_AppendResult(interp,sqlite3_version,0);
+ Tcl_AppendResult(interp,sqlite3_libversion(), (char*)0);
return TCL_OK;
}
if( strcmp(zArg,"-has-codec")==0 ){
#ifdef SQLITE_HAS_CODEC
- Tcl_AppendResult(interp,"1",0);
+ Tcl_AppendResult(interp,"1",(char*)0);
#else
- Tcl_AppendResult(interp,"0",0);
+ Tcl_AppendResult(interp,"0",(char*)0);
#endif
return TCL_OK;
}
@@ -2896,7 +2964,9 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
for(i=3; i+1<objc; i+=2){
zArg = Tcl_GetString(objv[i]);
if( strcmp(zArg,"-key")==0 ){
+#ifdef SQLITE_HAS_CODEC
pKey = Tcl_GetByteArrayFromObj(objv[i+1], &nKey);
+#endif
}else if( strcmp(zArg, "-vfs")==0 ){
zVfs = Tcl_GetString(objv[i+1]);
}else if( strcmp(zArg, "-readonly")==0 ){
@@ -2926,7 +2996,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
}else{
flags &= ~SQLITE_OPEN_NOMUTEX;
}
- }else if( strcmp(zArg, "-fullmutex")==0 ){
+ }else if( strcmp(zArg, "-fullmutex")==0 ){
int b;
if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
if( b ){
@@ -2935,6 +3005,14 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
}else{
flags &= ~SQLITE_OPEN_FULLMUTEX;
}
+ }else if( strcmp(zArg, "-uri")==0 ){
+ int b;
+ if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
+ if( b ){
+ flags |= SQLITE_OPEN_URI;
+ }else{
+ flags &= ~SQLITE_OPEN_URI;
+ }
}else{
Tcl_AppendResult(interp, "unknown option: ", zArg, (char*)0);
return TCL_ERROR;
@@ -2943,7 +3021,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
if( objc<3 || (objc&1)!=1 ){
Tcl_WrongNumArgs(interp, 1, objv,
"HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?"
- " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN?"
+ " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
#ifdef SQLITE_HAS_CODEC
" ?-key CODECKEY?"
#endif
@@ -2953,18 +3031,22 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
zErrMsg = 0;
p = (SqliteDb*)Tcl_Alloc( sizeof(*p) );
if( p==0 ){
- Tcl_SetResult(interp, "malloc failed", TCL_STATIC);
+ Tcl_SetResult(interp, (char *)"malloc failed", TCL_STATIC);
return TCL_ERROR;
}
memset(p, 0, sizeof(*p));
zFile = Tcl_GetStringFromObj(objv[2], 0);
zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename);
- sqlite3_open_v2(zFile, &p->db, flags, zVfs);
+ rc = sqlite3_open_v2(zFile, &p->db, flags, zVfs);
Tcl_DStringFree(&translatedFilename);
- if( SQLITE_OK!=sqlite3_errcode(p->db) ){
- zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db));
- sqlite3_close(p->db);
- p->db = 0;
+ if( p->db ){
+ if( SQLITE_OK!=sqlite3_errcode(p->db) ){
+ zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db));
+ sqlite3_close(p->db);
+ p->db = 0;
+ }
+ }else{
+ zErrMsg = sqlite3_mprintf("%s", sqlite3_errstr(rc));
}
#ifdef SQLITE_HAS_CODEC
if( p->db ){
@@ -2995,7 +3077,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
*/
#ifndef USE_TCL_STUBS
# undef Tcl_InitStubs
-# define Tcl_InitStubs(a,b,c)
+# define Tcl_InitStubs(a,b,c) TCL_VERSION
#endif
/*
@@ -3019,38 +3101,33 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
** The EXTERN macros are required by TCL in order to work on windows.
*/
EXTERN int Sqlite3_Init(Tcl_Interp *interp){
- Tcl_InitStubs(interp, "8.4", 0);
- Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0);
- Tcl_PkgProvide(interp, "sqlite3", PACKAGE_VERSION);
-
+ int rc = Tcl_InitStubs(interp, "8.4", 0)==0 ? TCL_ERROR : TCL_OK;
+ if( rc==TCL_OK ){
+ Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0);
#ifndef SQLITE_3_SUFFIX_ONLY
- /* The "sqlite" alias is undocumented. It is here only to support
- ** legacy scripts. All new scripts should use only the "sqlite3"
- ** command.
- */
- Tcl_CreateObjCommand(interp, "sqlite", (Tcl_ObjCmdProc*)DbMain, 0, 0);
+ /* The "sqlite" alias is undocumented. It is here only to support
+ ** legacy scripts. All new scripts should use only the "sqlite3"
+ ** command. */
+ Tcl_CreateObjCommand(interp, "sqlite", (Tcl_ObjCmdProc*)DbMain, 0, 0);
#endif
-
- return TCL_OK;
+ rc = Tcl_PkgProvide(interp, "sqlite3", PACKAGE_VERSION);
+ }
+ return rc;
}
EXTERN int Tclsqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
-EXTERN int Sqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
-EXTERN int Tclsqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
EXTERN int Sqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
EXTERN int Tclsqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
-EXTERN int Sqlite3_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK; }
-EXTERN int Tclsqlite3_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK;}
+/* Because it accesses the file-system and uses persistent state, SQLite
+** is not considered appropriate for safe interpreters. Hence, we deliberately
+** omit the _SafeInit() interfaces.
+*/
#ifndef SQLITE_3_SUFFIX_ONLY
int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
-int Sqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
-int Tclsqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
int Sqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
-int Sqlite_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK; }
-int Tclsqlite_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK;}
#endif
#ifdef TCLSH
@@ -3309,13 +3386,11 @@ static void MD5Final(unsigned char digest[16], MD5Context *ctx){
byteReverse(ctx->in, 14);
/* Append length in bits and transform */
- ((uint32 *)ctx->in)[ 14 ] = ctx->bits[0];
- ((uint32 *)ctx->in)[ 15 ] = ctx->bits[1];
+ memcpy(ctx->in + 14*4, ctx->bits, 8);
MD5Transform(ctx->buf, (uint32 *)ctx->in);
byteReverse((unsigned char *)ctx->buf, 4);
memcpy(digest, ctx->buf, 16);
- memset(ctx, 0, sizeof(ctx)); /* In case it is sensitive */
}
/*
@@ -3363,7 +3438,7 @@ static int md5_cmd(void*cd, Tcl_Interp *interp, int argc, const char **argv){
if( argc!=2 ){
Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
- " TEXT\"", 0);
+ " TEXT\"", (char*)0);
return TCL_ERROR;
}
MD5Init(&ctx);
@@ -3388,19 +3463,19 @@ static int md5file_cmd(void*cd, Tcl_Interp*interp, int argc, const char **argv){
if( argc!=2 ){
Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
- " FILENAME\"", 0);
+ " FILENAME\"", (char*)0);
return TCL_ERROR;
}
in = fopen(argv[1],"rb");
if( in==0 ){
Tcl_AppendResult(interp,"unable to open file \"", argv[1],
- "\" for reading", 0);
+ "\" for reading", (char*)0);
return TCL_ERROR;
}
MD5Init(&ctx);
for(;;){
int n;
- n = fread(zBuf, 1, sizeof(zBuf), in);
+ n = (int)fread(zBuf, 1, sizeof(zBuf), in);
if( n<=0 ) break;
MD5Update(&ctx, (unsigned char*)zBuf, (unsigned)n);
}
@@ -3446,7 +3521,7 @@ static void md5step(sqlite3_context *context, int argc, sqlite3_value **argv){
for(i=0; i<argc; i++){
const char *zData = (char*)sqlite3_value_text(argv[i]);
if( zData ){
- MD5Update(p, (unsigned char*)zData, strlen(zData));
+ MD5Update(p, (unsigned char*)zData, (int)strlen(zData));
}
}
}
@@ -3475,33 +3550,34 @@ int Md5_Register(sqlite3 *db){
** the TCL interpreter reads and evaluates that file.
*/
#if TCLSH==1
-static char zMainloop[] =
- "set line {}\n"
- "while {![eof stdin]} {\n"
- "if {$line!=\"\"} {\n"
- "puts -nonewline \"> \"\n"
- "} else {\n"
- "puts -nonewline \"% \"\n"
- "}\n"
- "flush stdout\n"
- "append line [gets stdin]\n"
- "if {[info complete $line]} {\n"
- "if {[catch {uplevel #0 $line} result]} {\n"
- "puts stderr \"Error: $result\"\n"
- "} elseif {$result!=\"\"} {\n"
- "puts $result\n"
+static const char *tclsh_main_loop(void){
+ static const char zMainloop[] =
+ "set line {}\n"
+ "while {![eof stdin]} {\n"
+ "if {$line!=\"\"} {\n"
+ "puts -nonewline \"> \"\n"
+ "} else {\n"
+ "puts -nonewline \"% \"\n"
+ "}\n"
+ "flush stdout\n"
+ "append line [gets stdin]\n"
+ "if {[info complete $line]} {\n"
+ "if {[catch {uplevel #0 $line} result]} {\n"
+ "puts stderr \"Error: $result\"\n"
+ "} elseif {$result!=\"\"} {\n"
+ "puts $result\n"
+ "}\n"
+ "set line {}\n"
+ "} else {\n"
+ "append line \\n\n"
"}\n"
- "set line {}\n"
- "} else {\n"
- "append line \\n\n"
"}\n"
- "}\n"
-;
+ ;
+ return zMainloop;
+}
#endif
#if TCLSH==2
-static char zMainloop[] =
-#include "spaceanal_tcl.h"
-;
+static const char *tclsh_main_loop(void);
#endif
#ifdef SQLITE_TEST
@@ -3527,6 +3603,44 @@ static int init_all_cmd(
init_all(slave);
return TCL_OK;
}
+
+/*
+** Tclcmd: db_use_legacy_prepare DB BOOLEAN
+**
+** The first argument to this command must be a database command created by
+** [sqlite3]. If the second argument is true, then the handle is configured
+** to use the sqlite3_prepare_v2() function to prepare statements. If it
+** is false, sqlite3_prepare().
+*/
+static int db_use_legacy_prepare_cmd(
+ ClientData cd,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *CONST objv[]
+){
+ Tcl_CmdInfo cmdInfo;
+ SqliteDb *pDb;
+ int bPrepare;
+
+ if( objc!=3 ){
+ Tcl_WrongNumArgs(interp, 1, objv, "DB BOOLEAN");
+ return TCL_ERROR;
+ }
+
+ if( !Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){
+ Tcl_AppendResult(interp, "no such db: ", Tcl_GetString(objv[1]), (char*)0);
+ return TCL_ERROR;
+ }
+ pDb = (SqliteDb*)cmdInfo.objClientData;
+ if( Tcl_GetBooleanFromObj(interp, objv[2], &bPrepare) ){
+ return TCL_ERROR;
+ }
+
+ pDb->bLegacyPrepare = bPrepare;
+
+ Tcl_ResetResult(interp);
+ return TCL_OK;
+}
#endif
/*
@@ -3547,6 +3661,17 @@ static void init_all(Tcl_Interp *interp){
Md5_Init(interp);
#endif
+ /* Install the [register_dbstat_vtab] command to access the implementation
+ ** of virtual table dbstat (source file test_stat.c). This command is
+ ** required for testfixture and sqlite3_analyzer, but not by the production
+ ** Tcl extension. */
+#if defined(SQLITE_TEST) || TCLSH==2
+ {
+ extern int SqlitetestStat_Init(Tcl_Interp*);
+ SqlitetestStat_Init(interp);
+ }
+#endif
+
#ifdef SQLITE_TEST
{
extern int Sqliteconfig_Init(Tcl_Interp*);
@@ -3570,20 +3695,22 @@ static void init_all(Tcl_Interp *interp){
extern int Sqlitetestschema_Init(Tcl_Interp*);
extern int Sqlitetestsse_Init(Tcl_Interp*);
extern int Sqlitetesttclvar_Init(Tcl_Interp*);
+ extern int Sqlitetestfs_Init(Tcl_Interp*);
extern int SqlitetestThread_Init(Tcl_Interp*);
extern int SqlitetestOnefile_Init();
extern int SqlitetestOsinst_Init(Tcl_Interp*);
extern int Sqlitetestbackup_Init(Tcl_Interp*);
extern int Sqlitetestintarray_Init(Tcl_Interp*);
extern int Sqlitetestvfs_Init(Tcl_Interp *);
- extern int SqlitetestStat_Init(Tcl_Interp*);
extern int Sqlitetestrtree_Init(Tcl_Interp*);
extern int Sqlitequota_Init(Tcl_Interp*);
extern int Sqlitemultiplex_Init(Tcl_Interp*);
extern int SqliteSuperlock_Init(Tcl_Interp*);
extern int SqlitetestSyscall_Init(Tcl_Interp*);
- extern int Sqlitetestfuzzer_Init(Tcl_Interp*);
- extern int Sqlitetestwholenumber_Init(Tcl_Interp*);
+
+#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
+ extern int Sqlitetestfts3_Init(Tcl_Interp *interp);
+#endif
#ifdef SQLITE_ENABLE_ZIPVFS
extern int Zipvfs_Init(Tcl_Interp*);
@@ -3610,22 +3737,29 @@ static void init_all(Tcl_Interp *interp){
Sqlitetest_mutex_Init(interp);
Sqlitetestschema_Init(interp);
Sqlitetesttclvar_Init(interp);
+ Sqlitetestfs_Init(interp);
SqlitetestThread_Init(interp);
SqlitetestOnefile_Init(interp);
SqlitetestOsinst_Init(interp);
Sqlitetestbackup_Init(interp);
Sqlitetestintarray_Init(interp);
Sqlitetestvfs_Init(interp);
- SqlitetestStat_Init(interp);
Sqlitetestrtree_Init(interp);
Sqlitequota_Init(interp);
Sqlitemultiplex_Init(interp);
SqliteSuperlock_Init(interp);
SqlitetestSyscall_Init(interp);
- Sqlitetestfuzzer_Init(interp);
- Sqlitetestwholenumber_Init(interp);
- Tcl_CreateObjCommand(interp,"load_testfixture_extensions",init_all_cmd,0,0);
+#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
+ Sqlitetestfts3_Init(interp);
+#endif
+
+ Tcl_CreateObjCommand(
+ interp, "load_testfixture_extensions", init_all_cmd, 0, 0
+ );
+ Tcl_CreateObjCommand(
+ interp, "db_use_legacy_prepare", db_use_legacy_prepare_cmd, 0, 0
+ );
#ifdef SQLITE_SSE
Sqlitetestsse_Init(interp);
@@ -3637,18 +3771,29 @@ static void init_all(Tcl_Interp *interp){
#define TCLSH_MAIN main /* Needed to fake out mktclapp */
int TCLSH_MAIN(int argc, char **argv){
Tcl_Interp *interp;
-
+
+#if !defined(_WIN32_WCE)
+ if( getenv("BREAK") ){
+ fprintf(stderr,
+ "attach debugger to process %d and press any key to continue.\n",
+ GETPID());
+ fgetc(stdin);
+ }
+#endif
+
/* Call sqlite3_shutdown() once before doing anything else. This is to
** test that sqlite3_shutdown() can be safely called by a process before
** sqlite3_initialize() is. */
sqlite3_shutdown();
+ Tcl_FindExecutable(argv[0]);
+ Tcl_SetSystemEncoding(NULL, "utf-8");
+ interp = Tcl_CreateInterp();
+
#if TCLSH==2
sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
#endif
- Tcl_FindExecutable(argv[0]);
- interp = Tcl_CreateInterp();
init_all(interp);
if( argc>=2 ){
int i;
@@ -3669,7 +3814,7 @@ int TCLSH_MAIN(int argc, char **argv){
}
}
if( TCLSH==2 || argc<=1 ){
- Tcl_GlobalEval(interp, zMainloop);
+ Tcl_GlobalEval(interp, tclsh_main_loop());
}
return 0;
}
« no previous file with comments | « third_party/sqlite/src/src/table.c ('k') | third_party/sqlite/src/src/test1.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698