From 34b087a82030e21183afcb1bb5052d67a7185db2 Mon Sep 17 00:00:00 2001 From: zwtmichael Date: Tue, 18 Oct 2022 11:36:48 +0800 Subject: [PATCH 1/2] add drop table callback Signed-off-by: zwtmichael --- include/sqlite3.h | 5 +++++ include/sqlite3ext.h | 3 +++ src/sqlite3.c | 45 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/include/sqlite3.h b/include/sqlite3.h index a6afc6e..2ec806e 100644 --- a/include/sqlite3.h +++ b/include/sqlite3.h @@ -3113,6 +3113,11 @@ SQLITE_API int sqlite3_set_authorizer( void *pUserData ); +SQLITE_API int sqlite3_set_droptable_handle( + sqlite3 *db, + void (*xFunc)(sqlite3*,const char*,const char*) +); + /* ** CAPI3REF: Authorizer Return Codes ** diff --git a/include/sqlite3ext.h b/include/sqlite3ext.h index fa13562..d9bf770 100644 --- a/include/sqlite3ext.h +++ b/include/sqlite3ext.h @@ -344,6 +344,7 @@ struct sqlite3_api_routines { int (*autovacuum_pages)(sqlite3*, unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int), void*, void(*)(void*)); + int (*set_droptable_handle)(sqlite3*,void(*)(sqlite3*,const char*,const char*)); }; /* @@ -659,6 +660,8 @@ extern const sqlite3_api_routines *sqlite3_export_symbols; #define sqlite3_total_changes64 sqlite3_api->total_changes64 /* Version 3.37.0 and later */ #define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages + +#define sqlite3_set_droptable_handle sqlite3_api->set_droptable_handle #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) diff --git a/src/sqlite3.c b/src/sqlite3.c index 5aec28f..1dc8ab0 100644 --- a/src/sqlite3.c +++ b/src/sqlite3.c @@ -5125,6 +5125,7 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); */ SQLITE_API int sqlite3_step(sqlite3_stmt*); +SQLITE_API int sqlite3_set_droptable_handle(sqlite3*, void (*xFunc)(sqlite3*,const char*,const char*)); /* ** CAPI3REF: Number of columns in a result set ** METHOD: sqlite3_stmt @@ -16531,6 +16532,8 @@ SQLITE_PRIVATE void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**); */ #define SQLITE_MAX_DB (SQLITE_MAX_ATTACHED+2) +typedef void (*sqlite3_xDropTableHandle)(sqlite3*, const char*, const char*); + /* ** Each database connection is an instance of the following structure. */ @@ -16673,6 +16676,10 @@ struct sqlite3 { #ifdef SQLITE_USER_AUTHENTICATION sqlite3_userauth auth; /* User authentication information */ #endif + unsigned int isDropTable; + char *mDropTableName; + char *mDropTableDbName; + sqlite3_xDropTableHandle xDropTableHandle; /* User drop table callback */ }; /* @@ -85464,6 +85471,12 @@ end_of_step: return (rc&db->errMask); } +SQLITE_API int sqlite3_set_droptable_handle(sqlite3 *db, void (*xFunc)(sqlite3*, const char*, const char*)){ + db->xDropTableHandle = xFunc; + return 0; +} + + /* ** This is the top-level implementation of sqlite3_step(). Call ** sqlite3Step() to do most of the work. If a schema error occurs, @@ -85525,6 +85538,18 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){ if( savedPc>=0 ) v->doingRerun = 1; assert( v->expired==0 ); } + if( rc==SQLITE_DONE && db->xDropTableHandle!=NULL && db->isDropTable==1 ){ + db->isDropTable = 0; + const char *tableName = db->mDropTableName; + const char *zDbName = db->mDropTableDbName; + db->xDropTableHandle(db, tableName, zDbName); + if ( db->mDropTableName!=NULL ){ + sqlite3_free(db->mDropTableName); + } + if ( db->mDropTableDbName!=NULL ){ + sqlite3_free(db->mDropTableDbName); + } + } sqlite3_mutex_leave(db->mutex); return rc; } @@ -114374,8 +114399,20 @@ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char testcase( zTabName[0]==0 ); /* Zero-length table names are allowed */ pDb = &db->aDb[iDb]; p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName, 0); + u8 tableType = p->eTabType; sqlite3DeleteTable(db, p); db->mDbFlags |= DBFLAG_SchemaChange; + if( tableType!=TABTYP_VIEW ){ + db->isDropTable = 1; + db->mDropTableName = sqlite3_malloc(strlen(zTabName) + 1); + if( db->mDropTableName!=NULL ){ + memcpy(db->mDropTableName, zTabName, strlen(zTabName) + 1); + } + db->mDropTableDbName = sqlite3_malloc(strlen(db->aDb[iDb].zDbSName) + 1); + if( db->mDropTableDbName!=NULL ){ + memcpy(db->mDropTableDbName, db->aDb[iDb].zDbSName, strlen(db->aDb[iDb].zDbSName) + 1); + } + } } /* @@ -128115,6 +128152,7 @@ struct sqlite3_api_routines { int (*autovacuum_pages)(sqlite3*, unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int), void*, void(*)(void*)); + int (*set_droptable_handle)(sqlite3*,void(*)(sqlite3*,const char*,const char*)); }; /* @@ -128426,6 +128464,7 @@ typedef int (*sqlite3_loadext_entry)( #define sqlite3_total_changes64 sqlite3_api->total_changes64 /* Version 3.37.0 and later */ #define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages +#define sqlite3_set_droptable_handle sqlite3_api->set_droptable_handle #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) @@ -128442,7 +128481,6 @@ typedef int (*sqlite3_loadext_entry)( # define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */ # define SQLITE_EXTENSION_INIT3 /*no-op*/ #endif - #endif /* SQLITE3EXT_H */ /************** End of sqlite3ext.h ******************************************/ @@ -128922,6 +128960,7 @@ static const sqlite3_api_routines sqlite3Apis = { sqlite3_total_changes64, /* Version 3.37.0 and later */ sqlite3_autovacuum_pages, + sqlite3_set_droptable_handle, }; /* True if x is the directory separator character @@ -170725,6 +170764,10 @@ opendb_out: }else if( rc!=SQLITE_OK ){ db->eOpenState = SQLITE_STATE_SICK; } + db->isDropTable = 0; + db->mDropTableName = NULL; + db->mDropTableDbName = NULL; + db->xDropTableHandle = NULL; *ppDb = db; #ifdef SQLITE_ENABLE_SQLLOG if( sqlite3GlobalConfig.xSqllog ){ -- Gitee From 5e8bdac7389aef41cdb4f8433aace3dd04d54845 Mon Sep 17 00:00:00 2001 From: zwtmichael Date: Fri, 21 Oct 2022 15:37:14 +0800 Subject: [PATCH 2/2] modify review commitment Signed-off-by: zwtmichael --- BUILD.gn | 1 + include/sqlite3.h | 2 ++ include/sqlite3ext.h | 4 ++++ src/sqlite3.c | 45 ++++++++++++++++++++++++++++++++------------ 4 files changed, 40 insertions(+), 12 deletions(-) diff --git a/BUILD.gn b/BUILD.gn index af76d78..667a2f2 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -76,6 +76,7 @@ ohos_shared_library("sqlite") { "SQLITE_EXPORT_SYMBOLS", "SQLITE_SHARED_BLOCK_OPTIMIZATION", "SQLITE_CODEC_ATTACH_CHANGED", + "SQLITE_ENABLE_DROPTABLE_CALLBACK", ] cflags_c = [ "-fvisibility=hidden", diff --git a/include/sqlite3.h b/include/sqlite3.h index 2ec806e..020b3ad 100644 --- a/include/sqlite3.h +++ b/include/sqlite3.h @@ -3113,10 +3113,12 @@ SQLITE_API int sqlite3_set_authorizer( void *pUserData ); +#ifdef SQLITE_ENABLE_DROPTABLE_CALLBACK SQLITE_API int sqlite3_set_droptable_handle( sqlite3 *db, void (*xFunc)(sqlite3*,const char*,const char*) ); +#endif /* ** CAPI3REF: Authorizer Return Codes diff --git a/include/sqlite3ext.h b/include/sqlite3ext.h index d9bf770..7c1373f 100644 --- a/include/sqlite3ext.h +++ b/include/sqlite3ext.h @@ -344,7 +344,9 @@ struct sqlite3_api_routines { int (*autovacuum_pages)(sqlite3*, unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int), void*, void(*)(void*)); +#ifdef SQLITE_ENABLE_DROPTABLE_CALLBACK int (*set_droptable_handle)(sqlite3*,void(*)(sqlite3*,const char*,const char*)); +#endif }; /* @@ -661,7 +663,9 @@ extern const sqlite3_api_routines *sqlite3_export_symbols; /* Version 3.37.0 and later */ #define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages +#ifdef SQLITE_ENABLE_DROPTABLE_CALLBACK #define sqlite3_set_droptable_handle sqlite3_api->set_droptable_handle +#endif #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) diff --git a/src/sqlite3.c b/src/sqlite3.c index 1dc8ab0..67d6dce 100644 --- a/src/sqlite3.c +++ b/src/sqlite3.c @@ -5125,7 +5125,9 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); */ SQLITE_API int sqlite3_step(sqlite3_stmt*); +#ifdef SQLITE_ENABLE_DROPTABLE_CALLBACK SQLITE_API int sqlite3_set_droptable_handle(sqlite3*, void (*xFunc)(sqlite3*,const char*,const char*)); +#endif /* ** CAPI3REF: Number of columns in a result set ** METHOD: sqlite3_stmt @@ -16676,10 +16678,12 @@ struct sqlite3 { #ifdef SQLITE_USER_AUTHENTICATION sqlite3_userauth auth; /* User authentication information */ #endif +#ifdef SQLITE_ENABLE_DROPTABLE_CALLBACK unsigned int isDropTable; char *mDropTableName; - char *mDropTableDbName; + char *mDropSchemaName; sqlite3_xDropTableHandle xDropTableHandle; /* User drop table callback */ +#endif }; /* @@ -85471,11 +85475,14 @@ end_of_step: return (rc&db->errMask); } +#ifdef SQLITE_ENABLE_DROPTABLE_CALLBACK SQLITE_API int sqlite3_set_droptable_handle(sqlite3 *db, void (*xFunc)(sqlite3*, const char*, const char*)){ + sqlite3_mutex_enter(db->mutex); db->xDropTableHandle = xFunc; + sqlite3_mutex_leave(db->mutex); return 0; } - +#endif /* ** This is the top-level implementation of sqlite3_step(). Call @@ -85538,18 +85545,18 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){ if( savedPc>=0 ) v->doingRerun = 1; assert( v->expired==0 ); } +#ifdef SQLITE_ENABLE_DROPTABLE_CALLBACK if( rc==SQLITE_DONE && db->xDropTableHandle!=NULL && db->isDropTable==1 ){ db->isDropTable = 0; - const char *tableName = db->mDropTableName; - const char *zDbName = db->mDropTableDbName; - db->xDropTableHandle(db, tableName, zDbName); - if ( db->mDropTableName!=NULL ){ + db->xDropTableHandle(db, db->mDropTableName, db->mDropSchemaName); + if( db->mDropTableName!=NULL ){ sqlite3_free(db->mDropTableName); } - if ( db->mDropTableDbName!=NULL ){ - sqlite3_free(db->mDropTableDbName); + if( db->mDropSchemaName!=NULL ){ + sqlite3_free(db->mDropSchemaName); } } +#endif sqlite3_mutex_leave(db->mutex); return rc; } @@ -114399,20 +114406,24 @@ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char testcase( zTabName[0]==0 ); /* Zero-length table names are allowed */ pDb = &db->aDb[iDb]; p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName, 0); +#ifdef SQLITE_ENABLE_DROPTABLE_CALLBACK u8 tableType = p->eTabType; +#endif sqlite3DeleteTable(db, p); db->mDbFlags |= DBFLAG_SchemaChange; +#ifdef SQLITE_ENABLE_DROPTABLE_CALLBACK if( tableType!=TABTYP_VIEW ){ db->isDropTable = 1; db->mDropTableName = sqlite3_malloc(strlen(zTabName) + 1); if( db->mDropTableName!=NULL ){ memcpy(db->mDropTableName, zTabName, strlen(zTabName) + 1); } - db->mDropTableDbName = sqlite3_malloc(strlen(db->aDb[iDb].zDbSName) + 1); - if( db->mDropTableDbName!=NULL ){ - memcpy(db->mDropTableDbName, db->aDb[iDb].zDbSName, strlen(db->aDb[iDb].zDbSName) + 1); + db->mDropSchemaName = sqlite3_malloc(strlen(db->aDb[iDb].zDbSName) + 1); + if( db->mDropSchemaName!=NULL ){ + memcpy(db->mDropSchemaName, db->aDb[iDb].zDbSName, strlen(db->aDb[iDb].zDbSName) + 1); } } +#endif } /* @@ -128152,7 +128163,9 @@ struct sqlite3_api_routines { int (*autovacuum_pages)(sqlite3*, unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int), void*, void(*)(void*)); +#ifdef SQLITE_ENABLE_DROPTABLE_CALLBACK int (*set_droptable_handle)(sqlite3*,void(*)(sqlite3*,const char*,const char*)); +#endif }; /* @@ -128464,7 +128477,11 @@ typedef int (*sqlite3_loadext_entry)( #define sqlite3_total_changes64 sqlite3_api->total_changes64 /* Version 3.37.0 and later */ #define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages + +#ifdef SQLITE_ENABLE_DROPTABLE_CALLBACK #define sqlite3_set_droptable_handle sqlite3_api->set_droptable_handle +#endif + #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) @@ -128960,7 +128977,9 @@ static const sqlite3_api_routines sqlite3Apis = { sqlite3_total_changes64, /* Version 3.37.0 and later */ sqlite3_autovacuum_pages, +#ifdef SQLITE_ENABLE_DROPTABLE_CALLBACK sqlite3_set_droptable_handle, +#endif }; /* True if x is the directory separator character @@ -170764,10 +170783,12 @@ opendb_out: }else if( rc!=SQLITE_OK ){ db->eOpenState = SQLITE_STATE_SICK; } +#ifdef SQLITE_ENABLE_DROPTABLE_CALLBACK db->isDropTable = 0; db->mDropTableName = NULL; - db->mDropTableDbName = NULL; + db->mDropSchemaName = NULL; db->xDropTableHandle = NULL; +#endif *ppDb = db; #ifdef SQLITE_ENABLE_SQLLOG if( sqlite3GlobalConfig.xSqllog ){ -- Gitee