diff --git a/BUILD.gn b/BUILD.gn index af76d78736be2abc958fafcaf784a292a6e4629c..667a2f26d9e6b62f5c64ae121383af91fbc8e214 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 a6afc6ef09030fd1ef8e29f2ee1adac57a5ed4e3..020b3ad8be94f01e465fd5fa8022dfef9aa75b8c 100644 --- a/include/sqlite3.h +++ b/include/sqlite3.h @@ -3113,6 +3113,13 @@ 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 fa1356209165a84c818a852591bc018f8021dbb0..7c1373fe85f080143a6ddc39f664d88cecf78bc9 100644 --- a/include/sqlite3ext.h +++ b/include/sqlite3ext.h @@ -344,6 +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 }; /* @@ -659,6 +662,10 @@ 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 + +#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 5aec28f6b5b4bbebd022b4d0f74613f61fb3819b..67d6dce7aee0c2c8434cdf1fbd28b11d7cb00c15 100644 --- a/src/sqlite3.c +++ b/src/sqlite3.c @@ -5125,6 +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 @@ -16531,6 +16534,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 +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 *mDropSchemaName; + sqlite3_xDropTableHandle xDropTableHandle; /* User drop table callback */ +#endif }; /* @@ -85464,6 +85475,15 @@ 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 ** sqlite3Step() to do most of the work. If a schema error occurs, @@ -85525,6 +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; + db->xDropTableHandle(db, db->mDropTableName, db->mDropSchemaName); + if( db->mDropTableName!=NULL ){ + sqlite3_free(db->mDropTableName); + } + if( db->mDropSchemaName!=NULL ){ + sqlite3_free(db->mDropSchemaName); + } + } +#endif sqlite3_mutex_leave(db->mutex); return rc; } @@ -114374,8 +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->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 } /* @@ -128115,6 +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 }; /* @@ -128426,6 +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) @@ -128442,7 +128498,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 +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 @@ -170725,6 +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->mDropSchemaName = NULL; + db->xDropTableHandle = NULL; +#endif *ppDb = db; #ifdef SQLITE_ENABLE_SQLLOG if( sqlite3GlobalConfig.xSqllog ){