From ee398fb5539afa74875cb5fcf08428e18059a426 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Mon, 23 Jan 2023 20:06:01 +0300 Subject: Upgrade to 3.39.4 --- upstream/tea/generic/tclsqlite3.c | 196 +++++++++++++++++++++++--------------- 1 file changed, 119 insertions(+), 77 deletions(-) (limited to 'upstream/tea/generic/tclsqlite3.c') diff --git a/upstream/tea/generic/tclsqlite3.c b/upstream/tea/generic/tclsqlite3.c index 4d722eb..d9792f9 100644 --- a/upstream/tea/generic/tclsqlite3.c +++ b/upstream/tea/generic/tclsqlite3.c @@ -186,6 +186,7 @@ struct SqliteDb { int nVMStep; /* Another statistic for most recent operation */ int nTransaction; /* Number of nested [transaction] methods */ int openFlags; /* Flags used to open. (SQLITE_OPEN_URI) */ + int nRef; /* Delete object when this reaches 0 */ #ifdef SQLITE_TEST int bLegacyPrepare; /* True to use sqlite3_prepare() */ #endif @@ -523,63 +524,83 @@ static void flushStmtCache(SqliteDb *pDb){ } /* +** Increment the reference counter on the SqliteDb object. The reference +** should be released by calling delDatabaseRef(). +*/ +static void addDatabaseRef(SqliteDb *pDb){ + pDb->nRef++; +} + +/* +** Decrement the reference counter associated with the SqliteDb object. +** If it reaches zero, delete the object. +*/ +static void delDatabaseRef(SqliteDb *pDb){ + assert( pDb->nRef>0 ); + pDb->nRef--; + if( pDb->nRef==0 ){ + flushStmtCache(pDb); + closeIncrblobChannels(pDb); + sqlite3_close(pDb->db); + while( pDb->pFunc ){ + SqlFunc *pFunc = pDb->pFunc; + pDb->pFunc = pFunc->pNext; + assert( pFunc->pDb==pDb ); + Tcl_DecrRefCount(pFunc->pScript); + Tcl_Free((char*)pFunc); + } + while( pDb->pCollate ){ + SqlCollate *pCollate = pDb->pCollate; + pDb->pCollate = pCollate->pNext; + Tcl_Free((char*)pCollate); + } + if( pDb->zBusy ){ + Tcl_Free(pDb->zBusy); + } + if( pDb->zTrace ){ + Tcl_Free(pDb->zTrace); + } + if( pDb->zTraceV2 ){ + Tcl_Free(pDb->zTraceV2); + } + if( pDb->zProfile ){ + Tcl_Free(pDb->zProfile); + } + if( pDb->zBindFallback ){ + Tcl_Free(pDb->zBindFallback); + } + if( pDb->zAuth ){ + Tcl_Free(pDb->zAuth); + } + if( pDb->zNull ){ + Tcl_Free(pDb->zNull); + } + if( pDb->pUpdateHook ){ + Tcl_DecrRefCount(pDb->pUpdateHook); + } + if( pDb->pPreUpdateHook ){ + Tcl_DecrRefCount(pDb->pPreUpdateHook); + } + if( pDb->pRollbackHook ){ + Tcl_DecrRefCount(pDb->pRollbackHook); + } + if( pDb->pWalHook ){ + Tcl_DecrRefCount(pDb->pWalHook); + } + if( pDb->pCollateNeeded ){ + Tcl_DecrRefCount(pDb->pCollateNeeded); + } + Tcl_Free((char*)pDb); + } +} + +/* ** TCL calls this procedure when an sqlite3 database command is ** deleted. */ static void SQLITE_TCLAPI DbDeleteCmd(void *db){ SqliteDb *pDb = (SqliteDb*)db; - flushStmtCache(pDb); - closeIncrblobChannels(pDb); - sqlite3_close(pDb->db); - while( pDb->pFunc ){ - SqlFunc *pFunc = pDb->pFunc; - pDb->pFunc = pFunc->pNext; - assert( pFunc->pDb==pDb ); - Tcl_DecrRefCount(pFunc->pScript); - Tcl_Free((char*)pFunc); - } - while( pDb->pCollate ){ - SqlCollate *pCollate = pDb->pCollate; - pDb->pCollate = pCollate->pNext; - Tcl_Free((char*)pCollate); - } - if( pDb->zBusy ){ - Tcl_Free(pDb->zBusy); - } - if( pDb->zTrace ){ - Tcl_Free(pDb->zTrace); - } - if( pDb->zTraceV2 ){ - Tcl_Free(pDb->zTraceV2); - } - if( pDb->zProfile ){ - Tcl_Free(pDb->zProfile); - } - if( pDb->zBindFallback ){ - Tcl_Free(pDb->zBindFallback); - } - if( pDb->zAuth ){ - Tcl_Free(pDb->zAuth); - } - if( pDb->zNull ){ - Tcl_Free(pDb->zNull); - } - if( pDb->pUpdateHook ){ - Tcl_DecrRefCount(pDb->pUpdateHook); - } - if( pDb->pPreUpdateHook ){ - Tcl_DecrRefCount(pDb->pPreUpdateHook); - } - if( pDb->pRollbackHook ){ - Tcl_DecrRefCount(pDb->pRollbackHook); - } - if( pDb->pWalHook ){ - Tcl_DecrRefCount(pDb->pWalHook); - } - if( pDb->pCollateNeeded ){ - Tcl_DecrRefCount(pDb->pCollateNeeded); - } - Tcl_Free((char*)pDb); + delDatabaseRef(pDb); } /* @@ -1251,6 +1272,7 @@ static int SQLITE_TCLAPI DbTransPostCmd( } pDb->disableAuth--; + delDatabaseRef(pDb); return rc; } @@ -1584,6 +1606,7 @@ static void dbEvalInit( Tcl_IncrRefCount(pArray); } p->evalFlags = evalFlags; + addDatabaseRef(p->pDb); } /* @@ -1724,6 +1747,7 @@ static void dbEvalFinalize(DbEvalContext *p){ } Tcl_DecrRefCount(p->pSql); dbReleaseColumnNames(p); + delDatabaseRef(p->pDb); } /* @@ -1924,15 +1948,16 @@ static int SQLITE_TCLAPI DbObjCmd( "close", "collate", "collation_needed", "commit_hook", "complete", "config", "copy", "deserialize", "enable_load_extension", - "errorcode", "eval", "exists", - "function", "incrblob", "interrupt", - "last_insert_rowid", "nullvalue", "onecolumn", - "preupdate", "profile", "progress", - "rekey", "restore", "rollback_hook", - "serialize", "status", "timeout", - "total_changes", "trace", "trace_v2", - "transaction", "unlock_notify", "update_hook", - "version", "wal_hook", 0 + "errorcode", "erroroffset", "eval", + "exists", "function", "incrblob", + "interrupt", "last_insert_rowid", "nullvalue", + "onecolumn", "preupdate", "profile", + "progress", "rekey", "restore", + "rollback_hook", "serialize", "status", + "timeout", "total_changes", "trace", + "trace_v2", "transaction", "unlock_notify", + "update_hook", "version", "wal_hook", + 0 }; enum DB_enum { DB_AUTHORIZER, DB_BACKUP, DB_BIND_FALLBACK, @@ -1940,15 +1965,15 @@ static int SQLITE_TCLAPI DbObjCmd( DB_CLOSE, DB_COLLATE, DB_COLLATION_NEEDED, DB_COMMIT_HOOK, DB_COMPLETE, DB_CONFIG, DB_COPY, DB_DESERIALIZE, DB_ENABLE_LOAD_EXTENSION, - DB_ERRORCODE, DB_EVAL, DB_EXISTS, - DB_FUNCTION, DB_INCRBLOB, DB_INTERRUPT, - DB_LAST_INSERT_ROWID, DB_NULLVALUE, DB_ONECOLUMN, - DB_PREUPDATE, DB_PROFILE, DB_PROGRESS, - DB_REKEY, DB_RESTORE, DB_ROLLBACK_HOOK, - DB_SERIALIZE, DB_STATUS, DB_TIMEOUT, - DB_TOTAL_CHANGES, DB_TRACE, DB_TRACE_V2, - DB_TRANSACTION, DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK, - DB_VERSION, DB_WAL_HOOK + DB_ERRORCODE, DB_ERROROFFSET, DB_EVAL, + DB_EXISTS, DB_FUNCTION, DB_INCRBLOB, + DB_INTERRUPT, DB_LAST_INSERT_ROWID, DB_NULLVALUE, + DB_ONECOLUMN, DB_PREUPDATE, DB_PROFILE, + DB_PROGRESS, DB_REKEY, DB_RESTORE, + DB_ROLLBACK_HOOK, DB_SERIALIZE, DB_STATUS, + DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE, + DB_TRACE_V2, DB_TRANSACTION, DB_UNLOCK_NOTIFY, + DB_UPDATE_HOOK, DB_VERSION, DB_WAL_HOOK, }; /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */ @@ -2212,7 +2237,7 @@ static int SQLITE_TCLAPI DbObjCmd( return TCL_ERROR; } pResult = Tcl_GetObjResult(interp); - Tcl_SetIntObj(pResult, sqlite3_changes(pDb->db)); + Tcl_SetWideIntObj(pResult, sqlite3_changes64(pDb->db)); break; } @@ -2605,7 +2630,7 @@ static int SQLITE_TCLAPI DbObjCmd( ** Reopen DATABASE (default "main") using the content in $VALUE */ case DB_DESERIALIZE: { -#ifndef SQLITE_ENABLE_DESERIALIZE +#ifdef SQLITE_OMIT_DESERIALIZE Tcl_AppendResult(interp, "MEMDB not available in this build", (char*)0); rc = TCL_ERROR; @@ -2628,8 +2653,10 @@ static int SQLITE_TCLAPI DbObjCmd( for(i=2; idb))); + break; + } + + /* ** $db exists $sql ** $db onecolumn $sql ** @@ -2932,7 +2970,7 @@ deserialize_error: } if( objc==(6+isReadonly) ){ - zDb = Tcl_GetString(objv[2]); + zDb = Tcl_GetString(objv[2+isReadonly]); } zTable = Tcl_GetString(objv[objc-3]); zColumn = Tcl_GetString(objv[objc-2]); @@ -3172,7 +3210,7 @@ deserialize_error: ** Return a serialization of a database. */ case DB_SERIALIZE: { -#ifndef SQLITE_ENABLE_DESERIALIZE +#ifdef SQLITE_OMIT_DESERIALIZE Tcl_AppendResult(interp, "MEMDB not available in this build", (char*)0); rc = TCL_ERROR; @@ -3260,7 +3298,7 @@ deserialize_error: return TCL_ERROR; } pResult = Tcl_GetObjResult(interp); - Tcl_SetIntObj(pResult, sqlite3_total_changes(pDb->db)); + Tcl_SetWideIntObj(pResult, sqlite3_total_changes64(pDb->db)); break; } @@ -3440,6 +3478,7 @@ deserialize_error: ** opened above. If not using NRE, evaluate the script directly, then ** call function DbTransPostCmd() to commit (or rollback) the transaction ** or savepoint. */ + addDatabaseRef(pDb); /* DbTransPostCmd() calls delDatabaseRef() */ if( DbUseNre() ){ Tcl_NRAddCallback(interp, DbTransPostCmd, cd, 0, 0, 0); (void)Tcl_NREvalObj(interp, pScript, 0); @@ -3847,6 +3886,7 @@ static int SQLITE_TCLAPI DbMain( }else{ Tcl_CreateObjCommand(interp, zArg, DbObjCmd, (char*)p, DbDeleteCmd); } + p->nRef = 1; return TCL_OK; } @@ -3954,7 +3994,9 @@ static const char *tclsh_main_loop(void){ return zMainloop; } -#define TCLSH_MAIN main /* Needed to fake out mktclapp */ +#ifndef TCLSH_MAIN +# define TCLSH_MAIN main +#endif int SQLITE_CDECL TCLSH_MAIN(int argc, char **argv){ Tcl_Interp *interp; int i; -- cgit v1.1