From b5a20d3cebe7872a747b3d316403fa36fb46b1f2 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 23 Apr 2003 12:25:23 +0000 Subject: [PATCH] Remove the begin_hook and commit_hook APIs. They were a bad idea. Add a "trace" method to the TCL interface. (CVS 929) FossilOrigin-Name: 6289b863590ecc5de3d1efaaa60aa6f3f64fefb3 --- manifest | 24 +++--- manifest.uuid | 2 +- src/main.c | 38 +--------- src/sqlite.h.in | 17 +---- src/sqliteInt.h | 13 +--- src/tclsqlite.c | 180 +++++++++++++++----------------------------- src/vdbe.c | 16 +--- test/hook.test | 148 ------------------------------------ test/tclsqlite.test | 4 +- tool/mkopts.tcl | 51 +++++++++++++ 10 files changed, 131 insertions(+), 362 deletions(-) delete mode 100644 test/hook.test create mode 100755 tool/mkopts.tcl diff --git a/manifest b/manifest index 837b63fe1a..37c39bc388 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\sauthorizer\sAPI\sso\sthat\sit\sreports\sthe\sdatabase\sthat\stable\sand\nindices\sbelong\sto\sand\sso\sthat\sit\sreports\swhen\sactions\sare\staken\sin\sresponse\nto\sa\strigger.\s(CVS\s928) -D 2003-04-22T20:30:38 +C Remove\sthe\sbegin_hook\sand\scommit_hook\sAPIs.\s\sThey\swere\sa\sbad\sidea.\s\sAdd\sa\n"trace"\smethod\sto\sthe\sTCL\sinterface.\s(CVS\s929) +D 2003-04-23T12:25:24 F Makefile.in 004acec253ecdde985c8ecd5b7c9accdb210378f F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -33,7 +33,7 @@ F src/func.c 882c3ed5a02be18cd904715c7ec62947a34a3605 F src/hash.c 4fc39feb7b7711f6495ee9f2159559bedb043e1f F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8 F src/insert.c 350167db53b779a8d402d00ec5153410a8003931 -F src/main.c d6a7f78ec5269c7ced3380908a7ff04508aa2f8e +F src/main.c 5e4d4d081d82840a743c57269ca3c32640cefc06 F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565 F src/os.c 7274951ed6894f383cb889342267ded07caf339b F src/os.h aa52f0c9da321ff6134d19f2ca959e18e33615d0 @@ -46,10 +46,10 @@ F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe F src/select.c 92a66f0122f321688569e108feceaf74f5f4e63a F src/shell.c a0b7043713713ff45f666ce6b3c03a64109a8bb5 F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e -F src/sqlite.h.in 058574a5c0cc4cdd4826b2452f8088c9fb04ed85 -F src/sqliteInt.h b9bbf9d8ec7d5b3fd5a0a4173a3a41f54f1dff6e +F src/sqlite.h.in b4799af223dfc82f47d27c34b14f43b27509a49a +F src/sqliteInt.h cd2952587a8d3bff5d6cc7a0cfaf0e89c3bef0ad F src/table.c eed2098c9b577aa17f8abe89313a9c4413f57d63 -F src/tclsqlite.c 1ca3b70aaa8564f89900909c28b991b95bf3fc70 +F src/tclsqlite.c 9e25f98f1765afa0716144ef57abda75c88f688d F src/test1.c 4484806861a3099670188a09e12f858ec65aa56c F src/test2.c 5014337d8576b731cce5b5a14bec4f0daf432700 F src/test3.c 30985ebdfaf3ee1462a9b0652d3efbdc8d9798f5 @@ -59,7 +59,7 @@ F src/trigger.c 21ad1677bb0f0625348a01e92d1e0c6d794185a1 F src/update.c 3301448786205a7ec2d035c7cb7bd8ae5128c2b0 F src/util.c 87635cfdfffa056a8d3147719357aa442374f78c F src/vacuum.c e24781e38db36d1c9f578b6b3613bf0989ebd63c -F src/vdbe.c d453e8c95c9fac5a5e067c5c58243b3ae75699fc +F src/vdbe.c f0868ac926d98395d28c2a29119364ff11b77852 F src/vdbe.h 985c24f312d10f9ef8f9a8b8ea62fcdf68e82f21 F src/where.c c0709e5cf402f30026b597dce9dc3e74f1d07f8e F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242 @@ -81,7 +81,6 @@ F test/expr.test 48bc6400627532ec97e233809e33d336468bc84c F test/fkey1.test d65c824459916249bee501532d6154ddab0b5db7 F test/format3.test 64ab6c4db132b28a645996d413530f7b2a462cc2 F test/func.test 000515779001ac6899eec4b54e65c6e2501279d4 -F test/hook.test 7a4c97b886801d265c981dc4ec123c77af642a9d F test/in.test 22de8a3eb27265aab723adc513bea0e76bef70c6 F test/index.test 90ef4c426865f15937858bd433cc82b9c11af913 F test/insert.test 5697ba098e4d8a6f0151f281b7e39dec9c439e05 @@ -116,7 +115,7 @@ F test/sort.test ba07b107c16070208e6aab3cadea66ba079d85ba F test/subselect.test f0fea8cf9f386d416d64d152e3c65f9116d0f50f F test/table.test 371a1fc1c470982b2f68f9732f903a5d96f949c4 F test/tableapi.test 3c80421a889e1d106df16e5800fa787f0d2914a6 -F test/tclsqlite.test 42b8f01461a73e9921a3dfaa6d34e28e54441dcc +F test/tclsqlite.test d9bdfc0afca9ee605c50ecb39e94ae4dea8c222b F test/temptable.test 6feff1960c707e924d5462356c5303943dac4a8e F test/tester.tcl d7a5835edaf118539241145d8188f0822b673488 F test/trans.test 75e7a171b5d2d94ee56766459113e2ad0e5f809d @@ -134,6 +133,7 @@ F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b F tool/lemon.c 14fedcde9cf70aa6040b89de164cf8f56f92a4b9 F tool/lempar.c 73a991cc3017fb34804250fa901488b5147b3717 F tool/memleak.awk 16ef9493dcd36146f806e75148f4bb0201a123ec +F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c F tool/report1.txt 9eae07f26a8fc53889b45fc833a66a33daa22816 F tool/showdb.c 3559eac5a3b46e9b558d50856946b25e77633236 @@ -165,7 +165,7 @@ F www/speed.tcl cb4c10a722614aea76d2c51f32ee43400d5951be F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218 -P 393dd91c252531bb5abfe424b86a5f7eb20edcfc -R 6eac04a1271ebdc92908dc18c218ec20 +P c675a5504138f34cae6def782b5d3add2c67d2bc +R e42e1c0805bb96ad9734d493fd4b89bd U drh -Z 926b6500299b68262d64ec3146410e0c +Z 6cfe8cf5cfb533faee03d9b06ef89d27 diff --git a/manifest.uuid b/manifest.uuid index 05605c2ba3..465ce41a0b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c675a5504138f34cae6def782b5d3add2c67d2bc \ No newline at end of file +6289b863590ecc5de3d1efaaa60aa6f3f64fefb3 \ No newline at end of file diff --git a/src/main.c b/src/main.c index d2900b1016..d349647433 100644 --- a/src/main.c +++ b/src/main.c @@ -14,7 +14,7 @@ ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: main.c,v 1.126 2003/04/17 22:57:54 drh Exp $ +** $Id: main.c,v 1.127 2003/04/23 12:25:24 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -723,9 +723,7 @@ static int sqliteMain( sParse.pArg = pArg; sParse.useDb = -1; sParse.useCallback = ppVm==0; -#ifndef SQLITE_OMIT_TRACE if( db->xTrace ) db->xTrace(db->pTraceArg, zSql); -#endif sqliteRunParser(&sParse, zSql, pzErrMsg); if( sqlite_malloc_failed ){ sqliteSetString(pzErrMsg, "out of memory", 0); @@ -1023,44 +1021,10 @@ int sqlite_function_type(sqlite *db, const char *zName, int dataType){ ** sqlite_exec(). */ void *sqlite_trace(sqlite *db, void (*xTrace)(void*,const char*), void *pArg){ -#ifndef SQLITE_OMIT_TRACE void *pOld = db->pTraceArg; db->xTrace = xTrace; db->pTraceArg = pArg; return pOld; -#else - return 0; -#endif -} - -/* -** Register functions to be invoked when a transaction is started or when -** a transaction commits. If either function returns non-zero, then the -** corresponding operation aborts with a constraint error. -** -** EXPERIMENTAL. This API is under evaluation and is not yet an -** official part of the SQLite interface. This means it could change -** or be deleted in future releases. -*/ -void *sqlite_begin_hook( - sqlite *db, - int (*xCallback)(void*), - void *pArg -){ - void *pOld = db->pBeginArg; - db->xBeginCallback = xCallback; - db->pBeginArg = pArg; - return pOld; -} -void *sqlite_commit_hook( - sqlite *db, - int (*xCallback)(void*), - void *pArg -){ - void *pOld = db->pCommitArg; - db->xCommitCallback = xCallback; - db->pCommitArg = pArg; - return pOld; } /* diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 377b9f5424..cae7814dd2 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -12,7 +12,7 @@ ** This header file defines the interface that the SQLite library ** presents to client programs. ** -** @(#) $Id: sqlite.h.in,v 1.45 2003/04/22 20:30:39 drh Exp $ +** @(#) $Id: sqlite.h.in,v 1.46 2003/04/23 12:25:24 drh Exp $ */ #ifndef _SQLITE_H_ #define _SQLITE_H_ @@ -679,21 +679,6 @@ int sqlite_step( */ int sqlite_finalize(sqlite_vm*, char **pzErrMsg); -/*** EXPERIMENTAL *** -** -** Register a callback function to be invoked whenever a new transaction -** is started or committed. The pArg argument is passed through to the -** callback. If the callback function returns non-zero, then the operation -** is aborted with a constraint error. -** -** If another function was previously registered, its pArg value is returned. -** Otherwise NULL is returned. -** -** Registering a NULL function disables the callback. -*/ -void *sqlite_begin_hook(sqlite*, int(*)(void*), void*); -void *sqlite_commit_hook(sqlite*, int(*)(void*), void*); - #ifdef __cplusplus } /* End of the 'extern "C"' block */ #endif diff --git a/src/sqliteInt.h b/src/sqliteInt.h index c95a56710e..09209c2c8b 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.178 2003/04/22 20:30:39 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.179 2003/04/23 12:25:24 drh Exp $ */ #include "config.h" #include "sqlite.h" @@ -86,7 +86,6 @@ */ /* #define SQLITE_OMIT_AUTHORIZATION 1 */ /* #define SQLITE_OMIT_INMEMORYDB 1 */ -/* #define SQLITE_OMIT_TRACE 1 */ /* #define SQLITE_OMIT_VACUUM 1 */ /* @@ -105,9 +104,6 @@ #ifndef UINT8_TYPE # define UINT8_TYPE unsigned char #endif -#ifndef INT8_TYPE -# define INT8_TYPE signed char -#endif #ifndef INTPTR_TYPE # if SQLITE_PTR_SZ==4 # define INTPTR_TYPE int @@ -118,7 +114,6 @@ typedef UINT32_TYPE u32; /* 4-byte unsigned integer */ typedef UINT16_TYPE u16; /* 2-byte unsigned integer */ typedef UINT8_TYPE u8; /* 1-byte unsigned integer */ -typedef INT8_TYPE i8; /* 1-byte signed integer */ typedef INTPTR_TYPE ptr; /* Big enough to hold a pointer */ typedef unsigned INTPTR_TYPE uptr; /* Big enough to hold a pointer */ @@ -278,10 +273,6 @@ struct sqlite { int nTable; /* Number of tables in the database */ void *pBusyArg; /* 1st Argument to the busy callback */ int (*xBusyCallback)(void *,const char*,int); /* The busy callback */ - void *pBeginArg; /* Argument to the xBeginCallback() */ - int (*xBeginCallback)(void*); /* Invoked at every transaction start */ - void *pCommitArg; /* Argument to xCommitCallback() */ - int (*xCommitCallback)(void*);/* Invoked at every commit. */ Hash aFunc; /* All functions that can be in SQL exprs */ int lastRowid; /* ROWID of most recent insert */ int priorNewRowid; /* Last randomly generated ROWID */ @@ -585,7 +576,7 @@ struct Token { struct Expr { u8 op; /* Operation performed by this node */ u8 dataType; /* Either SQLITE_SO_TEXT or SQLITE_SO_NUM */ - i8 iDb; /* Database referenced by this expression */ + u8 iDb; /* Database referenced by this expression */ u8 flags; /* Various flags. See below */ Expr *pLeft, *pRight; /* Left and right subnodes */ ExprList *pList; /* A list of expressions used as function arguments diff --git a/src/tclsqlite.c b/src/tclsqlite.c index b1b446f987..ed4eb6c475 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -11,7 +11,7 @@ ************************************************************************* ** A TCL Interface to SQLite ** -** $Id: tclsqlite.c,v 1.47 2003/04/22 20:30:39 drh Exp $ +** $Id: tclsqlite.c,v 1.48 2003/04/23 12:25:24 drh Exp $ */ #ifndef NO_TCL /* Omit this whole file if TCL is unavailable */ @@ -51,8 +51,7 @@ struct SqliteDb { sqlite *db; /* The "real" database structure */ Tcl_Interp *interp; /* The interpreter used for this database */ char *zBusy; /* The busy callback routine */ - char *zBegin; /* The begin-transaction callback routine */ - char *zCommit; /* The commit-transaction callback routine */ + char *zTrace; /* The trace callback routine */ char *zAuth; /* The authorization callback routine */ SqlFunc *pFunc; /* List of SQL functions */ int rc; /* Return code of most recent sqlite_exec() */ @@ -263,11 +262,8 @@ static void DbDeleteCmd(void *db){ if( pDb->zBusy ){ Tcl_Free(pDb->zBusy); } - if( pDb->zBegin ){ - Tcl_Free(pDb->zBegin); - } - if( pDb->zCommit ){ - Tcl_Free(pDb->zCommit); + if( pDb->zTrace ){ + Tcl_Free(pDb->zTrace); } if( pDb->zAuth ){ Tcl_Free(pDb->zAuth); @@ -301,36 +297,19 @@ static int DbBusyHandler(void *cd, const char *zTable, int nTries){ } /* -** This routine is called when a new transaction is started. The -** TCL script in pDb->zBegin is executed. If it returns non-zero or -** if it throws an exception, the transaction is aborted. +** This routine is called by the SQLite trace handler whenever a new +** block of SQL is executed. The TCL script in pDb->zTrace is executed. */ -static int DbBeginHandler(void *cd){ +static void DbTraceHandler(void *cd, const char *zSql){ SqliteDb *pDb = (SqliteDb*)cd; - int rc; + Tcl_DString str; - rc = Tcl_Eval(pDb->interp, pDb->zBegin); - if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){ - return 1; - } - return 0; -} - -/* -** This routine is called when a transaction is committed. The -** TCL script in pDb->zCommit is executed. If it returns non-zero or -** if it throws an exception, the transaction is rolled back instead -** of being committed. -*/ -static int DbCommitHandler(void *cd){ - SqliteDb *pDb = (SqliteDb*)cd; - int rc; - - rc = Tcl_Eval(pDb->interp, pDb->zCommit); - if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){ - return 1; - } - return 0; + Tcl_DStringInit(&str); + Tcl_DStringAppend(&str, pDb->zTrace, -1); + Tcl_DStringAppendElement(&str, zSql); + Tcl_Eval(pDb->interp, Tcl_DStringValue(&str)); + Tcl_DStringFree(&str); + Tcl_ResetResult(pDb->interp); } /* @@ -443,17 +422,16 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ SqliteDb *pDb = (SqliteDb*)cd; int choice; static const char *DB_strs[] = { - "authorizer", "begin_hook", "busy", - "changes", "close", "commit_hook", - "complete", "errorcode", "eval", - "function", "last_insert_rowid", "timeout", - 0 + "authorizer", "busy", "changes", + "close", "complete", "errorcode", + "eval", "function", "last_insert_rowid", + "timeout", "trace", 0 }; enum DB_enum { - DB_AUTHORIZER, DB_BEGIN_HOOK, DB_BUSY, - DB_CHANGES, DB_CLOSE, DB_COMMIT_HOOK, - DB_COMPLETE, DB_ERRORCODE, DB_EVAL, - DB_FUNCTION, DB_LAST_INSERT_ROWID,DB_TIMEOUT, + DB_AUTHORIZER, DB_BUSY, DB_CHANGES, + DB_CLOSE, DB_COMPLETE, DB_ERRORCODE, + DB_EVAL, DB_FUNCTION, DB_LAST_INSERT_ROWID, + DB_TIMEOUT, DB_TRACE, }; if( objc<2 ){ @@ -488,7 +466,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ if( objc>3 ){ Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); }else if( objc==2 ){ - if( pDb->zBegin ){ + if( pDb->zAuth ){ Tcl_AppendResult(interp, pDb->zAuth, 0); } }else{ @@ -516,44 +494,6 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ break; } - - /* $db begin_callback ?CALLBACK? - ** - ** Invoke the given callback at the beginning of every SQL transaction. - ** If the callback throws an exception or returns non-zero, then the - ** transaction is aborted. If CALLBACK is an empty string, the callback - ** is disabled. - */ - case DB_BEGIN_HOOK: { - if( objc>3 ){ - Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); - }else if( objc==2 ){ - if( pDb->zBegin ){ - Tcl_AppendResult(interp, pDb->zBegin, 0); - } - }else{ - char *zBegin; - int len; - if( pDb->zBegin ){ - Tcl_Free(pDb->zBegin); - } - zBegin = Tcl_GetStringFromObj(objv[2], &len); - if( zBegin && len>0 ){ - pDb->zBegin = Tcl_Alloc( len + 1 ); - strcpy(pDb->zBegin, zBegin); - }else{ - pDb->zBegin = 0; - } - if( pDb->zBegin ){ - pDb->interp = interp; - sqlite_begin_hook(pDb->db, DbBeginHandler, pDb); - }else{ - sqlite_begin_hook(pDb->db, 0, 0); - } - } - break; - } - /* $db busy ?CALLBACK? ** ** Invoke the given callback if an SQL statement attempts to open @@ -618,43 +558,6 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ break; } - /* $db commit_hook ?CALLBACK? - ** - ** Invoke the given callback just before committing every SQL transaction. - ** If the callback throws an exception or returns non-zero, then the - ** transaction is aborted. If CALLBACK is an empty string, the callback - ** is disabled. - */ - case DB_COMMIT_HOOK: { - if( objc>3 ){ - Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); - }else if( objc==2 ){ - if( pDb->zCommit ){ - Tcl_AppendResult(interp, pDb->zCommit, 0); - } - }else{ - char *zCommit; - int len; - if( pDb->zCommit ){ - Tcl_Free(pDb->zCommit); - } - zCommit = Tcl_GetStringFromObj(objv[2], &len); - if( zCommit && len>0 ){ - pDb->zCommit = Tcl_Alloc( len + 1 ); - strcpy(pDb->zCommit, zCommit); - }else{ - pDb->zCommit = 0; - } - if( pDb->zCommit ){ - pDb->interp = interp; - sqlite_commit_hook(pDb->db, DbCommitHandler, pDb); - }else{ - sqlite_commit_hook(pDb->db, 0, 0); - } - } - break; - } - /* $db complete SQL ** ** Return TRUE if SQL is a complete SQL statement. Return FALSE if @@ -825,6 +728,43 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ sqlite_busy_timeout(pDb->db, ms); break; } + + /* $db trace ?CALLBACK? + ** + ** Make arrangements to invoke the CALLBACK routine for each SQL statement + ** that is executed. The text of the SQL is appended to CALLBACK before + ** it is executed. + */ + case DB_TRACE: { + if( objc>3 ){ + Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); + }else if( objc==2 ){ + if( pDb->zTrace ){ + Tcl_AppendResult(interp, pDb->zTrace, 0); + } + }else{ + char *zTrace; + int len; + if( pDb->zTrace ){ + Tcl_Free(pDb->zTrace); + } + zTrace = Tcl_GetStringFromObj(objv[2], &len); + if( zTrace && len>0 ){ + pDb->zTrace = Tcl_Alloc( len + 1 ); + strcpy(pDb->zTrace, zTrace); + }else{ + pDb->zTrace = 0; + } + if( pDb->zTrace ){ + pDb->interp = interp; + sqlite_trace(pDb->db, DbTraceHandler, pDb); + }else{ + sqlite_trace(pDb->db, 0, 0); + } + } + break; + } + } /* End of the SWITCH statement */ return TCL_OK; } diff --git a/src/vdbe.c b/src/vdbe.c index 127a6fae2e..8c1ee6bda3 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -36,7 +36,7 @@ ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.218 2003/04/17 12:44:25 drh Exp $ +** $Id: vdbe.c,v 1.219 2003/04/23 12:25:25 drh Exp $ */ #include "sqliteInt.h" #include @@ -3224,13 +3224,6 @@ case OP_Transaction: { } db->aDb[i].inTrans = 1; p->undoTransOnError = 1; - if( db->xBeginCallback!=0 && i==1 && rc==SQLITE_OK ){ - if( sqliteSafetyOff(db) ) goto abort_due_to_misuse; - if( db->xBeginCallback(db->pBeginArg)!=0 ){ - rc = SQLITE_CONSTRAINT; - } - if( sqliteSafetyOn(db) ) goto abort_due_to_misuse; - } break; } @@ -3244,13 +3237,6 @@ case OP_Transaction: { */ case OP_Commit: { int i; - if( db->xCommitCallback!=0 ){ - if( sqliteSafetyOff(db) ) goto abort_due_to_misuse; - if( db->xCommitCallback(db->pCommitArg)!=0 ){ - rc = SQLITE_CONSTRAINT; - } - if( sqliteSafetyOn(db) ) goto abort_due_to_misuse; - } for(i=0; rc==SQLITE_OK && inDb; i++){ if( db->aDb[i].inTrans ){ rc = sqliteBtreeCommit(db->aDb[i].pBt); diff --git a/test/hook.test b/test/hook.test deleted file mode 100644 index 78682b75bb..0000000000 --- a/test/hook.test +++ /dev/null @@ -1,148 +0,0 @@ -# 2003 April 3 -# -# 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. -# -#*********************************************************************** -# This file implements regression tests for TCL interface to the -# SQLite library. -# -# The focus of the tests in this file is the following interface: -# -# sqlite_begin_hook -# sqlite_commit_hook -# -# $Id: hook.test,v 1.1 2003/04/03 15:46:05 drh Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -do_test hook-1.1 { - db begin_hook -} {} -do_test hook-1.2 { - db commit_hook -} {} - -do_test hook-2.1 { - set begin_cnt 0 - proc begin_hook {} { - incr ::begin_cnt - return 0 - } - db begin_hook begin_hook - db begin_hook -} {begin_hook} -do_test hook-2.2 { - set begin_cnt -} {0} -do_test hook-2.3 { - execsql { - CREATE TABLE t1(a,b); - } - set begin_cnt -} {1} -do_test hook-2.4 { - execsql { - INSERT INTO t1 VALUES(1,2); - INSERT INTO t1 SELECT a+1, b+1 FROM t1; - INSERT INTO t1 SELECT a+2, b+2 FROM t1; - } - set begin_cnt -} {4} -do_test hook-2.5 { - execsql { - SELECT * FROM t1 - } -} {1 2 2 3 3 4 4 5} -do_test hook-2.6 { - set begin_cnt -} {4} -do_test hook-2.7 { - proc begin_hook {} { - incr ::begin_cnt - return 1 - } - catchsql { - INSERT INTO t1 VALUES(9,10); - } -} {1 {constraint failed}} -do_test hook-2.8 { - set begin_cnt -} {5} -do_test hook-2.9 { - execsql { - SELECT * FROM t1; - } -} {1 2 2 3 3 4 4 5} -do_test hook-2.10 { - db begin_hook {} - db begin_hook -} {} -do_test hook-2.11 { - execsql { - INSERT INTO t1 VALUES(9,10); - SELECT * FROM t1 - } -} {1 2 2 3 3 4 4 5 9 10} - -do_test hook-3.1 { - set commit_cnt 0 - proc commit_hook {} { - incr ::commit_cnt - return 0 - } - db commit_hook ::commit_hook - db commit_hook -} {::commit_hook} -do_test hook-3.2 { - set commit_cnt -} {0} -do_test hook-3.3 { - execsql { - CREATE TABLE t2(a,b); - } - set commit_cnt -} {1} -do_test hook-3.4 { - execsql { - INSERT INTO t2 VALUES(1,2); - INSERT INTO t2 SELECT a+1, b+1 FROM t2; - INSERT INTO t2 SELECT a+2, b+2 FROM t2; - } - set commit_cnt -} {4} -do_test hook-3.5 { - set commit_cnt {} - proc commit_hook {} { - set ::commit_cnt [execsql {SELECT * FROM t2}] - return 0 - } - execsql { - INSERT INTO t2 VALUES(5,6); - } - set commit_cnt -} {1 2 2 3 3 4 4 5 5 6} -do_test hook-3.6 { - set commit_cnt {} - proc commit_hook {} { - set ::commit_cnt [execsql {SELECT * FROM t2}] - return 1 - } - catchsql { - INSERT INTO t2 VALUES(6,7); - } -} {1 {constraint failed}} -do_test hook-3.7 { - set commit_cnt -} {1 2 2 3 3 4 4 5 5 6 6 7} -do_test hook-3.8 { - execsql {SELECT * FROM t2} -} {1 2 2 3 3 4 4 5 5 6} - - -finish_test diff --git a/test/tclsqlite.test b/test/tclsqlite.test index 987eda6bcb..5ab2331e37 100644 --- a/test/tclsqlite.test +++ b/test/tclsqlite.test @@ -15,7 +15,7 @@ # interface is pretty well tested. This file contains some addition # tests for fringe issues that the main test suite does not cover. # -# $Id: tclsqlite.test,v 1.12 2003/04/22 20:30:40 drh Exp $ +# $Id: tclsqlite.test,v 1.13 2003/04/23 12:25:25 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -29,7 +29,7 @@ do_test tcl-1.1 { do_test tcl-1.2 { set v [catch {db bogus} msg] lappend v $msg -} {1 {bad option "bogus": must be authorizer, begin_hook, busy, changes, close, commit_hook, complete, errorcode, eval, function, last_insert_rowid, or timeout}} +} {1 {bad option "bogus": must be authorizer, busy, changes, close, complete, errorcode, eval, function, last_insert_rowid, timeout, or trace}} do_test tcl-1.3 { execsql {CREATE TABLE t1(a int, b int)} execsql {INSERT INTO t1 VALUES(10,20)} diff --git a/tool/mkopts.tcl b/tool/mkopts.tcl new file mode 100755 index 0000000000..e3ddcb9eeb --- /dev/null +++ b/tool/mkopts.tcl @@ -0,0 +1,51 @@ +#!/usr/bin/tclsh +# +# This script is used to generate the array of strings and the enum +# that appear at the beginning of the C code implementation of a +# a TCL command and that define the available subcommands for that +# TCL command. + +set prefix {} +while {![eof stdin]} { + set line [gets stdin] + if {$line==""} continue + regsub -all "\[ \t\n,\]+" [string trim $line] { } line + foreach token [split $line { }] { + if {![regexp {(([a-zA-Z]+)_)?([_a-zA-Z]+)} $token all px p2 name]} continue + lappend namelist [string tolower $name] + if {$px!=""} {set prefix $p2} + } +} + +puts " static const char *${prefix}_strs\[\] = \173" +set col 0 +proc put_item x { + global col + if {$col==0} {puts -nonewline " "} + if {$col<2} { + puts -nonewline [format " %-21s" $x] + incr col + } else { + puts $x + set col 0 + } +} +proc finalize {} { + global col + if {$col>0} {puts {}} + set col 0 +} + +foreach name [lsort $namelist] { + put_item \"$name\", +} +put_item 0 +finalize +puts " \175;" +puts " enum ${prefix}_enum \173" +foreach name [lsort $namelist] { + regsub -all {@} $name {} name + put_item ${prefix}_[string toupper $name], +} +finalize +puts " \175;"