1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-27 20:41:58 +03:00

Initial work on the Tcl API interface to the new sqlite3_trace_v2() function.

FossilOrigin-Name: 7b59fa40a01c89cc98414d90a798169c26e04256
This commit is contained in:
mistachkin
2016-07-14 21:26:09 +00:00
parent 0129a54a16
commit b56660f5a4
3 changed files with 223 additions and 94 deletions

View File

@ -1,5 +1,5 @@
C Fix\scopy/paste\stypo\sin\sthe\snew\ssqlite3_expanded_sql()\sfunction.
D 2016-07-14T09:22:16.664
C Initial\swork\son\sthe\sTcl\sAPI\sinterface\sto\sthe\snew\ssqlite3_trace_v2()\sfunction.
D 2016-07-14T21:26:09.090
F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a
@ -392,7 +392,7 @@ F src/sqliteInt.h 48cd97eb134665348393dfe277b4c14d1085bfc7
F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247
F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab
F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9
F src/tclsqlite.c 25fbbbb97f76dbfd113153fb63f52d7ecfac5dd0
F src/tclsqlite.c 361167055f0d0d9883b729f1db698edcd3b46065
F src/test1.c 5124aff86fba753a6994e9621696ccfdc8bbf24e
F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b
F src/test3.c c75c8af0eadb335236c9e61b51044c58a8f7dd59
@ -1505,7 +1505,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 989de2d5b5e7155654d3eebadb9651b23f422c58
R 22fe35d8085a083776873f2a488c7041
P e7d18c70d2b8f09c9f5b978fe3d69d1088e42322
R 85912bc13f3699d6087855b14808f819
U mistachkin
Z 0cf3ee8d7f2e128326cc9e0cdcd59d22
Z 312d6409632132f635d6a5f40333e628

View File

@ -1 +1 @@
e7d18c70d2b8f09c9f5b978fe3d69d1088e42322
7b59fa40a01c89cc98414d90a798169c26e04256

View File

@ -133,6 +133,7 @@ struct SqliteDb {
char *zBusy; /* The busy callback routine */
char *zCommit; /* The commit hook callback routine */
char *zTrace; /* The trace callback routine */
char *zTraceV2; /* The trace_v2 callback routine */
char *zProfile; /* The profile callback routine */
char *zProgress; /* The progress callback routine */
char *zAuth; /* The authorization callback routine */
@ -508,6 +509,9 @@ static void DbDeleteCmd(void *db){
if( pDb->zTrace ){
Tcl_Free(pDb->zTrace);
}
if( pDb->zTraceV2 ){
Tcl_Free(pDb->zTraceV2);
}
if( pDb->zProfile ){
Tcl_Free(pDb->zProfile);
}
@ -587,6 +591,82 @@ static void DbTraceHandler(void *cd, const char *zSql){
}
#endif
#ifndef SQLITE_OMIT_TRACE
/*
** This routine is called by the SQLite trace_v2 handler whenever a new
** supported event is generated. Unsupported event types are ignored.
** The TCL script in pDb->zTraceV2 is executed, with the arguments for
** the event appended to it (as list elements).
*/
static int DbTraceV2Handler(
unsigned type, /* One of the SQLITE_TRACE_* event types. */
void *cd, /* The original context data pointer. */
void *pd, /* Primary event data, depends on event type. */
void *xd /* Extra event data, depends on event type. */
){
SqliteDb *pDb = (SqliteDb*)cd;
Tcl_Obj *pCmd;
switch( type ){
case SQLITE_TRACE_STMT: {
sqlite3_stmt *pStmt = (sqlite3_stmt *)pd;
char *zSql = (char *)xd;
pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
Tcl_IncrRefCount(pCmd);
Tcl_ListObjAppendElement(pDb->interp, pCmd,
Tcl_NewWideIntObj((Tcl_WideInt)pStmt));
Tcl_ListObjAppendElement(pDb->interp, pCmd,
Tcl_NewStringObj(zSql, -1));
Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
Tcl_DecrRefCount(pCmd);
Tcl_ResetResult(pDb->interp);
break;
}
case SQLITE_TRACE_PROFILE: {
sqlite3_stmt *pStmt = (sqlite3_stmt *)pd;
sqlite3_int64 ns = (sqlite3_int64)xd;
pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
Tcl_IncrRefCount(pCmd);
Tcl_ListObjAppendElement(pDb->interp, pCmd,
Tcl_NewWideIntObj((Tcl_WideInt)pStmt));
Tcl_ListObjAppendElement(pDb->interp, pCmd,
Tcl_NewWideIntObj((Tcl_WideInt)ns));
Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
Tcl_DecrRefCount(pCmd);
Tcl_ResetResult(pDb->interp);
break;
}
case SQLITE_TRACE_ROW: {
sqlite3_stmt *pStmt = (sqlite3_stmt *)pd;
pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
Tcl_IncrRefCount(pCmd);
Tcl_ListObjAppendElement(pDb->interp, pCmd,
Tcl_NewWideIntObj((Tcl_WideInt)pStmt));
Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
Tcl_DecrRefCount(pCmd);
Tcl_ResetResult(pDb->interp);
break;
}
case SQLITE_TRACE_CLOSE: {
sqlite3 *db = (sqlite3 *)pd;
pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
Tcl_IncrRefCount(pCmd);
Tcl_ListObjAppendElement(pDb->interp, pCmd,
Tcl_NewWideIntObj((Tcl_WideInt)db));
Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
Tcl_DecrRefCount(pCmd);
Tcl_ResetResult(pDb->interp);
break;
}
}
return SQLITE_OK;
}
#endif
#ifndef SQLITE_OMIT_TRACE
/*
** This routine is called by the SQLite profile handler after a statement
@ -1726,8 +1806,9 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
"preupdate", "profile", "progress",
"rekey", "restore", "rollback_hook",
"status", "timeout", "total_changes",
"trace", "transaction", "unlock_notify",
"update_hook", "version", "wal_hook",
"trace", "trace_v2", "transaction",
"unlock_notify", "update_hook", "version",
"wal_hook",
0
};
enum DB_enum {
@ -1741,8 +1822,9 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
DB_PREUPDATE, DB_PROFILE, DB_PROGRESS,
DB_REKEY, DB_RESTORE, DB_ROLLBACK_HOOK,
DB_STATUS, DB_TIMEOUT, DB_TOTAL_CHANGES,
DB_TRACE, DB_TRANSACTION, DB_UNLOCK_NOTIFY,
DB_UPDATE_HOOK, DB_VERSION, DB_WAL_HOOK,
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 */
@ -2842,6 +2924,53 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
break;
}
/* $db trace_v2 ?CALLBACK? ?MASK?
**
** Make arrangements to invoke the CALLBACK routine for each trace event
** matching the mask that is generated. The parameters are appended to
** CALLBACK before it is executed.
*/
case DB_TRACE_V2: {
if( objc>4 ){
Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK? ?MASK?");
return TCL_ERROR;
}else if( objc==2 ){
if( pDb->zTraceV2 ){
Tcl_AppendResult(interp, pDb->zTraceV2, (char*)0);
}
}else{
Tcl_WideInt wMask;
char *zTraceV2;
int len;
if( objc==4 ){
if( TCL_OK!=Tcl_GetWideIntFromObj(interp, objv[3], &wMask) ){
return TCL_ERROR;
}
}else{
wMask = SQLITE_TRACE_STMT;
}
if( pDb->zTraceV2 ){
Tcl_Free(pDb->zTraceV2);
}
zTraceV2 = Tcl_GetStringFromObj(objv[2], &len);
if( zTraceV2 && len>0 ){
pDb->zTraceV2 = Tcl_Alloc( len + 1 );
memcpy(pDb->zTraceV2, zTraceV2, len+1);
}else{
pDb->zTraceV2 = 0;
}
#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
if( pDb->zTraceV2 ){
pDb->interp = interp;
sqlite3_trace_v2(pDb->db, (unsigned)wMask, DbTraceV2Handler, pDb);
}else{
sqlite3_trace_v2(pDb->db, 0, 0, 0);
}
#endif
}
break;
}
/* $db transaction [-deferred|-immediate|-exclusive] SCRIPT
**
** Start a new transaction (if we are not already in the midst of a