diff options
author | drh <drh@noemail.net> | 2016-07-13 22:55:01 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2016-07-13 22:55:01 +0000 |
commit | 3d2a529df6ce9cc3e9a11e5a2214eabfb35e0b77 (patch) | |
tree | 165c74f465692f09861bb4900041949dad8c125b /src | |
parent | ed916ba02514b2714e61e91eb478e4d2d6f243df (diff) | |
download | sqlite-3d2a529df6ce9cc3e9a11e5a2214eabfb35e0b77.tar.gz sqlite-3d2a529df6ce9cc3e9a11e5a2214eabfb35e0b77.zip |
First cut at implementing the new sqlite3_trace_v2() interface.
FossilOrigin-Name: cb0062feb018f52689938a58cb76886d431c33f0
Diffstat (limited to 'src')
-rw-r--r-- | src/main.c | 31 | ||||
-rw-r--r-- | src/sqlite.h.in | 6 | ||||
-rw-r--r-- | src/sqlite3ext.h | 5 | ||||
-rw-r--r-- | src/sqliteInt.h | 12 | ||||
-rw-r--r-- | src/vacuum.c | 6 | ||||
-rw-r--r-- | src/vdbe.c | 26 | ||||
-rw-r--r-- | src/vdbeapi.c | 14 |
7 files changed, 85 insertions, 15 deletions
diff --git a/src/main.c b/src/main.c index 30370f8ca..d2f8bf799 100644 --- a/src/main.c +++ b/src/main.c @@ -1033,6 +1033,9 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){ return SQLITE_MISUSE_BKPT; } sqlite3_mutex_enter(db->mutex); + if( db->mTrace & SQLITE_TRACE_CLOSE ){ + db->xTrace(SQLITE_TRACE_CLOSE, db->pTraceArg, db, 0); + } /* Force xDisconnect calls on all virtual tables */ disconnectAllVtab(db); @@ -1801,6 +1804,7 @@ int sqlite3_overload_function( ** trace is a pointer to a function that is invoked at the start of each ** SQL statement. */ +#ifndef SQLITE_OMIT_DEPRECATED void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){ void *pOld; @@ -1812,11 +1816,36 @@ void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){ #endif sqlite3_mutex_enter(db->mutex); pOld = db->pTraceArg; - db->xTrace = xTrace; + db->mTrace = SQLITE_TRACE_LEGACY; + db->xTrace = (int(*)(u32,void*,void*,i64))xTrace; db->pTraceArg = pArg; sqlite3_mutex_leave(db->mutex); return pOld; } +#endif /* SQLITE_OMIT_DEPRECATED */ + +/* Register a trace callback using the version-2 interface. +*/ +int sqlite3_trace_v2( + sqlite3 *db, /* Trace this connection */ + int(*xTrace)(unsigned,void*,void*,sqlite3_int64), /* Callback to invoke */ + unsigned mTrace, /* OPs to be traced */ + void *pArg /* Context */ +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return 0; + } +#endif + sqlite3_mutex_enter(db->mutex); + db->mTrace = mTrace; + db->xTrace = xTrace; + db->pTraceArg = pArg; + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + /* ** Register a profile function. The pArg from the previously registered ** profile function is returned. diff --git a/src/sqlite.h.in b/src/sqlite.h.in index a3b8f31f0..07d85b254 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2805,7 +2805,7 @@ SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, ** The C argument is a copy of the context pointer passed in as the ** fourth argument to [sqlite3_trace_v2()]. ** The P argument is a pointer whose meaning depends on T. -** The X argument is an unsigned 64-bit integer whose meaning also +** The X argument is an 64-bit integer whose meaning also ** depends on T. ** ** <dl> @@ -2874,7 +2874,7 @@ SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, ** The T argument is one of the [SQLITE_TRACE] ** constants to indicate why the callback was invoked. ** The C argument is a copy of the context pointer. -** The P and X arguments are a pointer and an unsigned 64-bit integer +** The P and X arguments are a pointer and a 64-bit integer ** whose meanings depend on T. ** ** The sqlite3_trace_v2() interface is intended to replace the legacy @@ -2883,7 +2883,7 @@ SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, */ int sqlite3_trace_v2( sqlite3*, - int(*xCallback)(unsigned,void*,void*,sqlite3_uint64), + int(*xCallback)(unsigned,void*,void*,sqlite3_int64), unsigned uMask, void *pCtx ); diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h index 2d38e87ae..8bcfc6852 100644 --- a/src/sqlite3ext.h +++ b/src/sqlite3ext.h @@ -281,6 +281,9 @@ struct sqlite3_api_routines { int (*db_cacheflush)(sqlite3*); /* Version 3.12.0 and later */ int (*system_errno)(sqlite3*); + /* Version 3.14.0 and later */ + int (*trace_v2)(sqlite3*,int(*)(unsigned,void*,void*,sqlite3_uint64), + unsigned,void*); }; /* @@ -526,6 +529,8 @@ struct sqlite3_api_routines { #define sqlite3_db_cacheflush sqlite3_api->db_cacheflush /* Version 3.12.0 and later */ #define sqlite3_system_errno sqlite3_api->system_errno +/* Version 3.14.0 and later */ +#define sqlite3_trace_v2 sqlite3_api->trace_v2 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 998a17dac..225d7b287 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1241,6 +1241,15 @@ void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**); const char*); #endif +#ifndef SQLITE_OMIT_DEPRECATED +/* This is an extra SQLITE_TRACE macro that indicates "legacy" tracing +** in the style of sqlite3_trace() +*/ +#define SQLITE_TRACE_LEGACY 0x80 +#else +#define SQLITE_TRACE_LEGACY 0 +#endif /* SQLITE_OMIT_DEPRECATED */ + /* ** Each database connection is an instance of the following structure. @@ -1270,6 +1279,7 @@ struct sqlite3 { u8 suppressErr; /* Do not issue error messages if true */ u8 vtabOnConflict; /* Value to return for s3_vtab_on_conflict() */ u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */ + u8 mTrace; /* zero or more SQLITE_TRACE flags */ int nextPagesize; /* Pagesize after VACUUM if >0 */ u32 magic; /* Magic number for detect library misuse */ int nChange; /* Value returned by sqlite3_changes() */ @@ -1290,7 +1300,7 @@ struct sqlite3 { int nVDestroy; /* Number of active OP_VDestroy operations */ int nExtension; /* Number of loaded extensions */ void **aExtension; /* Array of shared library handles */ - void (*xTrace)(void*,const char*); /* Trace function */ + int (*xTrace)(u32,void*,void*,i64); /* Trace function */ void *pTraceArg; /* Argument to the trace function */ void (*xProfile)(void*,const char*,u64); /* Profiling function */ void *pProfileArg; /* Argument to profile function */ diff --git a/src/vacuum.c b/src/vacuum.c index bc7b5831b..93b438fb1 100644 --- a/src/vacuum.c +++ b/src/vacuum.c @@ -121,7 +121,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ int saved_flags; /* Saved value of the db->flags */ int saved_nChange; /* Saved value of db->nChange */ int saved_nTotalChange; /* Saved value of db->nTotalChange */ - void (*saved_xTrace)(void*,const char*); /* Saved db->xTrace */ + u8 saved_mTrace; /* Saved trace settings */ Db *pDb = 0; /* Database to detach at end of vacuum */ int isMemDb; /* True if vacuuming a :memory: database */ int nRes; /* Bytes of reserved space at the end of each page */ @@ -142,7 +142,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ saved_flags = db->flags; saved_nChange = db->nChange; saved_nTotalChange = db->nTotalChange; - saved_xTrace = db->xTrace; + saved_mTrace = db->mTrace; db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_PreferBuiltin; db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder); db->xTrace = 0; @@ -345,7 +345,7 @@ end_of_vacuum: db->flags = saved_flags; db->nChange = saved_nChange; db->nTotalChange = saved_nTotalChange; - db->xTrace = saved_xTrace; + db->mTrace = saved_mTrace; sqlite3BtreeSetPageSize(pMain, -1, -1, 1); /* Currently there is an SQL level transaction open on the vacuum diff --git a/src/vdbe.c b/src/vdbe.c index 6adbcbbec..788353602 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1383,6 +1383,10 @@ case OP_ResultRow: { } if( db->mallocFailed ) goto no_mem; + if( db->mTrace & SQLITE_TRACE_ROW ){ + db->xTrace(SQLITE_TRACE_ROW, db->pTraceArg, p, 0); + } + /* Return SQLITE_ROW */ p->pc = (int)(pOp - aOp) + 1; @@ -6781,13 +6785,27 @@ case OP_Init: { /* jump */ char *z; #ifndef SQLITE_OMIT_TRACE - if( db->xTrace + if( (db->mTrace & (SQLITE_TRACE_SQL|SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0 && !p->doingRerun && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 ){ - z = sqlite3VdbeExpandSql(p, zTrace); - db->xTrace(db->pTraceArg, z); - sqlite3DbFree(db, z); + if( db->mTrace & (SQLITE_TRACE_SQL|SQLITE_TRACE_LEGACY) ){ + z = sqlite3VdbeExpandSql(p, zTrace); +#ifndef SQLITE_OMIT_DEPRECATED + if( SQLITE_TRACE_LEGACY ){ + void (*x)(void*,const char*); + x = (void(*)(void*,const char*))db->xTrace; + x(db->pTraceArg, z); + }else +#endif + { + db->xTrace(SQLITE_TRACE_SQL,db->pTraceArg,z,0); + } + sqlite3DbFree(db, z); + } + if( db->mTrace & SQLITE_TRACE_STMT ){ + (void)db->xTrace(SQLITE_TRACE_STMT,db->pTraceArg,p,0); + } } #ifdef SQLITE_USE_FCNTL_TRACE zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 83718eae3..a602fad38 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -60,12 +60,19 @@ static int vdbeSafetyNotNull(Vdbe *p){ */ static SQLITE_NOINLINE void invokeProfileCallback(sqlite3 *db, Vdbe *p){ sqlite3_int64 iNow; + sqlite3_int64 iElapse; assert( p->startTime>0 ); - assert( db->xProfile!=0 ); + assert( db->xProfile!=0 || (db->mTrace & SQLITE_TRACE_PROFILE)!=0 ); assert( db->init.busy==0 ); assert( p->zSql!=0 ); sqlite3OsCurrentTimeInt64(db->pVfs, &iNow); - db->xProfile(db->pProfileArg, p->zSql, (iNow - p->startTime)*1000000); + iElapse = (iNow - p->startTime)*1000000; + if( db->xProfile ){ + db->xProfile(db->pProfileArg, p->zSql, iElapse); + } + if( db->mTrace & SQLITE_TRACE_PROFILE ){ + db->xTrace(SQLITE_TRACE_PROFILE, db->pTraceArg, p, iElapse); + } p->startTime = 0; } /* @@ -569,7 +576,8 @@ static int sqlite3Step(Vdbe *p){ ); #ifndef SQLITE_OMIT_TRACE - if( db->xProfile && !db->init.busy && p->zSql ){ + if( (db->xProfile || (db->mTrace & SQLITE_TRACE_PROFILE)!=0) + && !db->init.busy && p->zSql ){ sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime); }else{ assert( p->startTime==0 ); |