From: drh Date: Wed, 22 Apr 2015 14:41:19 +0000 (+0000) Subject: Prototype for an sqlite3_db_log() interface. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fheads%2Fsqlite3_db_log;p=thirdparty%2Fsqlite.git Prototype for an sqlite3_db_log() interface. FossilOrigin-Name: 658e20f55467a90bcebe5e01cf9f252dbe8bd690 --- diff --git a/manifest b/manifest index bd800e86c1..da6e84407a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\sfiltering\sof\sinput\sfor\sfuzzershell\sfor\smodes\sother\sthan\sgeneric. -D 2015-04-22T13:16:46.644 +C Prototype\sfor\san\ssqlite3_db_log()\sinterface. +D 2015-04-22T14:41:19.758 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in faaf75b89840659d74501bea269c7e33414761c1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -185,7 +185,7 @@ F src/delete.c 37964e6c1d73ff49cbea9ff690c9605fb15f600e F src/expr.c 5555f768c05d7d4a7840c6c2e72ad7aecbe0fe54 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c c9b63a217d86582c22121699a47f22f524608869 -F src/func.c 1414c24c873c48796ad45942257a179a423ba42f +F src/func.c e6b4680d0b6c901365e1ea5a6e75710e9479b70d F src/global.c 4f77cadbc5427d00139ba43d0f3979804cbb700e F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 @@ -195,7 +195,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770 F src/loadext.c 86bd4e2fccd520b748cba52492ab60c4a770f660 -F src/main.c 40e333960d53f7d50ee8ce09d40431c87ea653f2 +F src/main.c 453ae1a35c044cb5baa6b11697d722766d3f1569 F src/malloc.c 6a370b83d54e4bbf6f94021221c2a311cff26a18 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c abe6ee469b6c5a35c7f22bfeb9c9bac664a1c987 @@ -226,21 +226,21 @@ F src/pcache1.c 69d137620a305f814398bd29a0c998038c0695e9 F src/pragma.c c1f4d012ea9f6b1ce52d341b2cd0ad72d560afd7 F src/pragma.h 09c89bca58e9a44de2116cc8272b8d454657129f F src/prepare.c 1fffbdcd6f8a0173a8f70d71f22528f4c0e1e3d3 -F src/printf.c 08fa675c200aac29e561c6153f91f909ed17612f +F src/printf.c 9753790eed39d7863a3e33567199f382d980fc28 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 53486a98c17b7ae09b8c2b398013e973ce4c1aae F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c 35433ea8894ac42594ddc31eb0165a6d6401cfe5 F src/shell.c 78eabce4c16c45e36fea2368f95118116399ba8a -F src/sqlite.h.in ca27603a36fcacdaac5a19d8ee35aaff8ce8516f +F src/sqlite.h.in 3fb08b501d0155b4ba3ae8ef99c6f08491135dcb F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d -F src/sqliteInt.h 8abcea1295138f10ef8f7ed38db5f1b573b93ece +F src/sqliteInt.h 823549bbcb0131e09c4a324080309d049a80e258 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179 F src/table.c e7a09215315a978057fb42c640f890160dbcc45e F src/tclsqlite.c 14f1992dd6100bfeb1a3dec7e7f449e1c814b8ee -F src/test1.c 90fbedce75330d48d99eadb7d5f4223e86969585 +F src/test1.c 94efc685eb2e3dda4eb476670eeffaeaf05bead9 F src/test2.c 577961fe48961b2f2e5c8b56ee50c3f459d3359d F src/test3.c 64d2afdd68feac1bb5e2ffb8226c8c639f798622 F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e @@ -287,17 +287,17 @@ F src/test_vfs.c 3b65d42e18b262805716bd96178c81da8f2d9283 F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 6bbcc9fe50c917864d48287b4792d46d6e873481 -F src/tokenize.c b7fb584c2be5ec39b6fdf04b185e7c6f33f8dc15 +F src/tokenize.c 8fa8a62632f6f3916bfb6f7b10e1ffbd36de71f0 F src/trigger.c 322f23aad694e8f31d384dcfa386d52a48d3c52f F src/update.c 3c4ecc282accf12d39edb8d524cf089645e55a13 F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/util.c a6431c92803b975b7322724a7b433e538d243539 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c f0cf3cf527d5a40b8d5d2324fdbb31da6c90cd8b +F src/vdbe.c 4f4af7239261189393ca2752a3bf9977c14cb024 F src/vdbe.h 7e538ecf47dccb307ea2d087c3ddc2dd8d70e79d F src/vdbeInt.h 9cbaa84f53ddd2d09a0cf61a94337a3a035d08a0 -F src/vdbeapi.c 583d56b129dd27f12bed518270de9ebe521e6a75 -F src/vdbeaux.c 03591cca98ec50e1493043f0ff7abbece0b9c83d +F src/vdbeapi.c d4c9945b2a53b0b71d2a16843bb8d054ce513276 +F src/vdbeaux.c aa9b179cc9e6e3e75f8f28e366bb0aafab9d710e F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90 F src/vdbemem.c b5256445b318b0f2b3bc429028469cfbb08f19a5 F src/vdbesort.c 2e7f683464fd5db3be4beaa1ff2d39e24fcb64b8 @@ -307,7 +307,7 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 753995db83247f20361a8e8a874990b21a75abd9 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 -F src/where.c 32fe265e3dc74ef3b27deb9e6eb5fc3c71409612 +F src/where.c ba0839e75f989dba622809716daabeb9c7fbd3c5 F src/whereInt.h cbe4aa57326998d89e7698ca65bb7c28541d483c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -493,6 +493,7 @@ F test/enc2.test 83437a79ba1545a55fb549309175c683fb334473 F test/enc3.test 90683ad0e6ea587b9d5542ca93568af9a9858c40 F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020 F test/eqp.test 85873fa5816c48915c82c4e74cb5c35a5b48160f +F test/errlog01.test 112ea4cd0f2974a63d60fe96d322af0f383045d4 F test/errmsg.test f31592a594b44ee121371d25ddd5d63497bb3401 F test/eval.test a64c9105d6ff163df7cf09d6ac29cdad5922078c F test/exclusive.test c7ebbc756eacf544c108b15eed64d7d4e5f86b75 @@ -1252,7 +1253,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 1cceefa7c6585bca786fe9f7118f7beb829ad709 -R cbbdf393d38b0307d153eda6dc2aba63 +P 025e8370dde2918b66683f8d7fa9c7d23d03c9b4 +R 065b478bd5e153421f77ec0bbb390aae +T *branch * sqlite3_db_log +T *sym-sqlite3_db_log * +T -sym-trunk * U drh -Z 11145234dd05700bee32abe646d63f11 +Z cb2dffa7a83d63dde4f8c28d3e4ea48d diff --git a/manifest.uuid b/manifest.uuid index 7dd9717246..e3e27d6c98 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -025e8370dde2918b66683f8d7fa9c7d23d03c9b4 \ No newline at end of file +658e20f55467a90bcebe5e01cf9f252dbe8bd690 \ No newline at end of file diff --git a/src/func.c b/src/func.c index 782a240884..c34e7af9b1 100644 --- a/src/func.c +++ b/src/func.c @@ -886,8 +886,8 @@ static void sourceidFunc( /* ** Implementation of the sqlite_log() function. This is a wrapper around -** sqlite3_log(). The return value is NULL. The function exists purely for -** its side-effects. +** sqlite3_db_log(). The return value is NULL. The function exists purely +** for its side-effects. */ static void errlogFunc( sqlite3_context *context, @@ -896,7 +896,9 @@ static void errlogFunc( ){ UNUSED_PARAMETER(argc); UNUSED_PARAMETER(context); - sqlite3_log(sqlite3_value_int(argv[0]), "%s", sqlite3_value_text(argv[1])); + sqlite3_db_log(sqlite3_context_db_handle(context), + sqlite3_value_int(argv[0]), + "%s", sqlite3_value_text(argv[1])); } /* diff --git a/src/main.c b/src/main.c index d9ee77fab2..840cea2065 100644 --- a/src/main.c +++ b/src/main.c @@ -735,6 +735,14 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){ rc = setupLookaside(db, pBuf, sz, cnt); break; } + case SQLITE_DBCONFIG_LOG: { + /* MSVC is picky about pulling func ptrs from va lists. + ** http://support.microsoft.com/kb/47961 */ + typedef void(*LOGFUNC_t)(void*,int,const char*); + db->xLog = va_arg(ap, LOGFUNC_t); + db->pLogArg = va_arg(ap, void*); + break; + } default: { static const struct { int op; /* The opcode */ diff --git a/src/printf.c b/src/printf.c index 1a978dc5ca..1d8992c59d 100644 --- a/src/printf.c +++ b/src/printf.c @@ -1036,15 +1036,20 @@ char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ ** allocate memory because it might be called while the memory allocator ** mutex is held. */ -static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){ +static void renderLogMsg( + void (*xLog)(void*,int,const char*), /* Logging function */ + void *pArg, /* First argument to xLog */ + int iErrCode, /* Error code */ + const char *zFormat, /* Format string for error message */ + va_list ap /* Arguments to format string */ +){ StrAccum acc; /* String accumulator */ char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */ sqlite3StrAccumInit(&acc, zMsg, sizeof(zMsg), 0); acc.useMalloc = 0; sqlite3VXPrintf(&acc, 0, zFormat, ap); - sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode, - sqlite3StrAccumFinish(&acc)); + xLog(pArg, iErrCode, sqlite3StrAccumFinish(&acc)); } /* @@ -1054,7 +1059,21 @@ void sqlite3_log(int iErrCode, const char *zFormat, ...){ va_list ap; /* Vararg list */ if( sqlite3GlobalConfig.xLog ){ va_start(ap, zFormat); - renderLogMsg(iErrCode, zFormat, ap); + renderLogMsg(sqlite3GlobalConfig.xLog, sqlite3GlobalConfig.pLogArg, + iErrCode, zFormat, ap); + va_end(ap); + } +} +void sqlite3_db_log(sqlite3 *db, int iErrCode, const char *zFormat, ...){ + va_list ap; /* Vararg list */ + if( db && db->xLog ){ + va_start(ap, zFormat); + renderLogMsg(db->xLog, db->pLogArg, iErrCode, zFormat, ap); + va_end(ap); + }else if( sqlite3GlobalConfig.xLog ){ + va_start(ap, zFormat); + renderLogMsg(sqlite3GlobalConfig.xLog, sqlite3GlobalConfig.pLogArg, + iErrCode, zFormat, ap); va_end(ap); } } diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 163bc69fe7..6b55da1d42 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -1869,11 +1869,36 @@ struct sqlite3_mem_methods { ** following this call. The second parameter may be a NULL pointer, in ** which case the trigger setting is not reported back. ** +** [[SQLITE_DBCONFIG_LOG]]
SQLITE_DBCONFIG_LOG
+**
The SQLITE_DBCONFIG_LOG option is used to configure the SQLite +** [error log] for a specific database connection. See also the +** [SQLITE_CONFIG_LOG] option to [sqlite3_config()] for the global log +** callback. +** (^The SQLITE_DBCONFIG_LOG option takes two arguments: a pointer to a +** function with a call signature of void(*)(void*,int,const char*), +** and a pointer to void. ^If the function pointer is not NULL, it is +** invoked by [sqlite3_db_log()] to process each logging event. ^If the +** function pointer is NULL, then calls to [sqlite3_db_log()] interface try +** to use the [SQLITE_CONFIG_LOG|global error log]. If both the connection +** and global error log callbacks are NULL then [sqlite3_db_log()] is a +** harmless no-op. +** ^The void pointer that is the second argument to SQLITE_DBCONFIG_LOG is +** passed through as the first parameter to the application-defined logger +** function whenever that function is invoked. ^The second parameter to +** the logger function is a copy of the second parameter to the corresponding +** [sqlite3_db_log()] call and is intended to be a [result code] or an +** [extended result code]. ^The third parameter passed to the logger is +** log message after formatting via [sqlite3_snprintf()]. +** The SQLite logging interface is not reentrant; the logger function +** supplied by the application must not invoke any SQLite interface. +**
+** ** */ #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ #define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ +#define SQLITE_DBCONFIG_LOG 1004 /* xFunc, void* */ /* @@ -7285,10 +7310,19 @@ int sqlite3_strglob(const char *zGlob, const char *zStr); ** ** ^The [sqlite3_log()] interface writes a message into the [error log] ** established by the [SQLITE_CONFIG_LOG] option to [sqlite3_config()]. +** ^The [sqlite3_db_log()] interface writes a message into the [error log] +** established by the [SQLITE_DBCONFIG_LOG] option to [sqlite3_db_config()]. ** ^If logging is enabled, the zFormat string and subsequent arguments are ** used with [sqlite3_snprintf()] to generate the final output string. ** -** The sqlite3_log() interface is intended for use by extensions such as +** ^The [sqlite3_db_log()] interface writes error and warning information +** to the callback identified by the [SQLITE_DBCONFIG_LOG] option if that +** callback is not NULL, falling back to the [SQLITE_CONFIG_LOG] callback +** if the first parameter to [sqlite3_db_log()] is NULL or if the +** [SQLITE_DBCONFIG_LOG] callback is NULL. +** +** The sqlite3_log() and sqlite3_db_log() interfaces are intended for +** use by extensions such as ** virtual tables, collating functions, and SQL functions. While there is ** nothing to prevent an application from calling sqlite3_log(), doing so ** is considered bad form. @@ -7302,6 +7336,7 @@ int sqlite3_strglob(const char *zGlob, const char *zStr); ** buffer. */ void sqlite3_log(int iErrCode, const char *zFormat, ...); +void sqlite3_db_log(sqlite3*, int iErrCode, const char *zFormat, ...); /* ** CAPI3REF: Write-Ahead Log Commit Hook diff --git a/src/sqliteInt.h b/src/sqliteInt.h index f34645fa8d..7560f41a48 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1138,6 +1138,8 @@ struct sqlite3 { double notUsed1; /* Spacer */ } u1; Lookaside lookaside; /* Lookaside malloc configuration */ + void (*xLog)(void*,int,const char*); /* Function for logging */ + void *pLogArg; /* First argument to xLog() */ #ifndef SQLITE_OMIT_AUTHORIZATION sqlite3_xauth xAuth; /* Access authorization function */ void *pAuthArg; /* 1st argument to the access auth function */ diff --git a/src/test1.c b/src/test1.c index a87fcd859d..3ae7aad226 100644 --- a/src/test1.c +++ b/src/test1.c @@ -5797,7 +5797,7 @@ static int test_sqlite3_log( logcallback.pInterp = 0; sqlite3_config(SQLITE_CONFIG_LOG, 0, 0); } - if( objc>1 ){ + if( objc==2 ){ logcallback.pObj = objv[1]; Tcl_IncrRefCount(logcallback.pObj); logcallback.pInterp = interp; @@ -5805,6 +5805,32 @@ static int test_sqlite3_log( } return TCL_OK; } +static int test_sqlite3_db_log( + ClientData clientData, + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int objc, /* Number of arguments */ + Tcl_Obj *CONST objv[] /* Command arguments */ +){ + sqlite3 *db; + if( objc<1 || objc>3 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB SCRIPT"); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; + if( logcallback.pObj ){ + Tcl_DecrRefCount(logcallback.pObj); + logcallback.pObj = 0; + logcallback.pInterp = 0; + sqlite3_db_config(db, SQLITE_DBCONFIG_LOG, 0, 0); + } + if( objc==3 ){ + logcallback.pObj = objv[2]; + Tcl_IncrRefCount(logcallback.pObj); + logcallback.pInterp = interp; + sqlite3_db_config(db, SQLITE_DBCONFIG_LOG, xLogcallback, 0); + } + return TCL_OK; +} /* ** tcl_objproc COMMANDNAME ARGS... @@ -6906,6 +6932,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "sqlite3_wal_checkpoint_v2",test_wal_checkpoint_v2, 0 }, { "sqlite3_wal_autocheckpoint",test_wal_autocheckpoint, 0 }, { "test_sqlite3_log", test_sqlite3_log, 0 }, + { "test_sqlite3_db_log", test_sqlite3_db_log, 0 }, #ifndef SQLITE_OMIT_EXPLAIN { "print_explain_query_plan", test_print_eqp, 0 }, #endif diff --git a/src/tokenize.c b/src/tokenize.c index 076acb0209..b1d48ad94b 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -475,7 +475,7 @@ abort_parse: assert( pzErrMsg!=0 ); if( pParse->zErrMsg ){ *pzErrMsg = pParse->zErrMsg; - sqlite3_log(pParse->rc, "%s", *pzErrMsg); + sqlite3_db_log(db, pParse->rc, "%s", *pzErrMsg); pParse->zErrMsg = 0; nErr++; } diff --git a/src/vdbe.c b/src/vdbe.c index 52b4830577..abe2b7bf5d 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -974,7 +974,7 @@ case OP_Halt: { }else{ sqlite3SetString(&p->zErrMsg, db, "%s constraint failed", zType); } - sqlite3_log(pOp->p1, zLogFmt, pcx, p->zSql, p->zErrMsg); + sqlite3_db_log(db, pOp->p1, zLogFmt, pcx, p->zSql, p->zErrMsg); } rc = sqlite3VdbeHalt(p); assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR ); @@ -6529,7 +6529,7 @@ vdbe_error_halt: assert( rc ); p->rc = rc; testcase( sqlite3GlobalConfig.xLog!=0 ); - sqlite3_log(rc, "statement aborts at %d: [%s] %s", + sqlite3_db_log(db, rc, "statement aborts at %d: [%s] %s", (int)(pOp - aOp), p->zSql, p->zErrMsg); sqlite3VdbeHalt(p); if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1; diff --git a/src/vdbeapi.c b/src/vdbeapi.c index e03640dfbd..ea9fd707a7 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1145,9 +1145,9 @@ static int vdbeUnbind(Vdbe *p, int i){ sqlite3_mutex_enter(p->db->mutex); if( p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){ sqlite3Error(p->db, SQLITE_MISUSE); - sqlite3_mutex_leave(p->db->mutex); - sqlite3_log(SQLITE_MISUSE, + sqlite3_db_log(p->db, SQLITE_MISUSE, "bind on a busy prepared statement: [%s]", p->zSql); + sqlite3_mutex_leave(p->db->mutex); return SQLITE_MISUSE_BKPT; } if( i<1 || i>p->nVar ){ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 2c32038564..9cf9848f04 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2053,11 +2053,11 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ u32 iRandom; if( retryCount ){ if( retryCount>100 ){ - sqlite3_log(SQLITE_FULL, "MJ delete: %s", zMaster); + sqlite3_db_log(db, SQLITE_FULL, "MJ delete: %s", zMaster); sqlite3OsDelete(pVfs, zMaster, 0); break; }else if( retryCount==1 ){ - sqlite3_log(SQLITE_FULL, "MJ collide: %s", zMaster); + sqlite3_db_log(db, SQLITE_FULL, "MJ collide: %s", zMaster); } } retryCount++; diff --git a/src/where.c b/src/where.c index 25d20c8808..a1d09048fd 100644 --- a/src/where.c +++ b/src/where.c @@ -1750,7 +1750,7 @@ static void constructAutomaticIndex( testcase( iCol==BMS ); testcase( iCol==BMS-1 ); if( !sentWarning ){ - sqlite3_log(SQLITE_WARNING_AUTOINDEX, + sqlite3_db_log(pParse->db, SQLITE_WARNING_AUTOINDEX, "automatic index on %s(%s)", pTable->zName, pTable->aCol[iCol].zName); sentWarning = 1; diff --git a/test/errlog01.test b/test/errlog01.test new file mode 100644 index 0000000000..690faf598d --- /dev/null +++ b/test/errlog01.test @@ -0,0 +1,37 @@ +# 2015-04-22 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#************************************************************************* +# Test cases for the sqlite3_log() and sqlite3_db_log() interfaces. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +unset -nocomplain log +set log {} +do_test errlog01-1.0 { + test_sqlite3_db_log db [list lappend ::log] + db eval {SELECT sqlite_log(7,'simulated error')} +} {{}} +do_test errlog01-1.1 { + set ::log +} {SQLITE_NOMEM {simulated error}} +do_test errlog01-1.2 { + sqlite3 db2 :memory: + set ::log {} + db2 eval {SELECT sqlite_log(7,'simulated error')} +} {{}} +do_test errlog01-1.3 { + set ::log +} {} + + + +finish_test