diff --git a/libsql-sqlite3/src/pragma.c b/libsql-sqlite3/src/pragma.c index 90076b0c26..a75c8958b4 100644 --- a/libsql-sqlite3/src/pragma.c +++ b/libsql-sqlite3/src/pragma.c @@ -2927,7 +2927,7 @@ Module *sqlite3PragmaVtabRegister(sqlite3 *db, const char *zName){ if( pName==0 ) return 0; if( (pName->mPragFlg & (PragFlg_Result0|PragFlg_Result1))==0 ) return 0; assert( sqlite3HashFind(&db->aModule, zName)==0 ); - return sqlite3VtabCreateModule(db, zName, &pragmaVtabModule, (void*)pName, 0); + return sqlite3VtabCreateModule(db, zName, &pragmaVtabModule, NULL, (void*)pName, 0); } #endif /* SQLITE_OMIT_VIRTUALTABLE */ diff --git a/libsql-sqlite3/src/sqlite.h.in b/libsql-sqlite3/src/sqlite.h.in index 36b8203471..c9162c9e10 100644 --- a/libsql-sqlite3/src/sqlite.h.in +++ b/libsql-sqlite3/src/sqlite.h.in @@ -7268,6 +7268,7 @@ typedef struct sqlite3_vtab sqlite3_vtab; typedef struct sqlite3_index_info sqlite3_index_info; typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; typedef struct sqlite3_module sqlite3_module; +typedef struct libsql_module libsql_module; /* ** CAPI3REF: Virtual Table Object @@ -7325,8 +7326,11 @@ struct sqlite3_module { ** Those below are for version 4 and greater. */ int (*xIntegrity)(sqlite3_vtab *pVTab, const char *zSchema, const char *zTabName, int mFlags, char **pzErr); - /* The methods below relate to features contributed by the community and - ** are available for version 700 and greater. */ +}; + +/* libSQL extensions for modules */ +struct libsql_module { + int iVersion; int (*xPreparedSql)(sqlite3_vtab_cursor*, const char*); }; @@ -7574,6 +7578,14 @@ int sqlite3_create_module_v2( void *pClientData, /* Client data for xCreate/xConnect */ void(*xDestroy)(void*) /* Module destructor function */ ); +int libsql_create_module( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *p, /* Methods for the module */ + const libsql_module *pLibsql, /* Methods for the module */ + void *pClientData, /* Client data for xCreate/xConnect */ + void(*xDestroy)(void*) /* Module destructor function */ +); /* ** CAPI3REF: Remove Unnecessary Virtual Table Implementations @@ -7611,9 +7623,10 @@ int sqlite3_drop_modules( ** freed by sqlite3_free() and the zErrMsg field will be zeroed. */ struct sqlite3_vtab { - const sqlite3_module *pModule; /* The module for this virtual table */ - int nRef; /* Number of open cursors */ - char *zErrMsg; /* Error message from sqlite3_mprintf() */ + const sqlite3_module *pModule; /* The module for this virtual table */ + const libsql_module *pLibsqlModule; /* The libSQL module for this virtual table */ + int nRef; /* Number of open cursors */ + char *zErrMsg; /* Error message from sqlite3_mprintf() */ /* Virtual table implementations will typically add additional fields */ }; diff --git a/libsql-sqlite3/src/sqliteInt.h b/libsql-sqlite3/src/sqliteInt.h index cd02a8ad05..2829527341 100644 --- a/libsql-sqlite3/src/sqliteInt.h +++ b/libsql-sqlite3/src/sqliteInt.h @@ -2203,6 +2203,7 @@ struct Savepoint { */ struct Module { const sqlite3_module *pModule; /* Callback pointers */ + const libsql_module *pLibsqlModule; /* Callback pointers for libSQL */ const char *zName; /* Name passed to create_module() */ int nRefModule; /* Number of pointers to this object */ void *pAux; /* pAux passed to create_module() */ @@ -5477,6 +5478,7 @@ void sqlite3AutoLoadExtensions(sqlite3*); sqlite3*, const char*, const sqlite3_module*, + const libsql_module*, void*, void(*)(void*) ); diff --git a/libsql-sqlite3/src/vdbe.c b/libsql-sqlite3/src/vdbe.c index 21a6147fbc..deba99da3a 100644 --- a/libsql-sqlite3/src/vdbe.c +++ b/libsql-sqlite3/src/vdbe.c @@ -8309,6 +8309,7 @@ case OP_VInitIn: { /* out2, ncycle */ */ case OP_VPreparedSql: { const sqlite3_module *pModule; + const libsql_module *pLibsqlModule; sqlite3_vtab_cursor *pVCur; sqlite3_vtab *pVtab; VdbeCursor *pCur; @@ -8319,11 +8320,12 @@ case OP_VPreparedSql: { pVCur = pCur->uc.pVCur; pVtab = pVCur->pVtab; pModule = pVtab->pModule; + pLibsqlModule = pVtab->pLibsqlModule; /* Invoke the xPreparedSql method */ - if( pModule->iVersion>=700 ){ - if( pModule->xPreparedSql && p->zSql ){ - rc = pModule->xPreparedSql(pVCur, p->zSql); + if (pLibsqlModule) { + if( pLibsqlModule->xPreparedSql && p->zSql ){ + rc = pLibsqlModule->xPreparedSql(pVCur, p->zSql); if( rc ) goto abort_due_to_error; } } diff --git a/libsql-sqlite3/src/vtab.c b/libsql-sqlite3/src/vtab.c index a9cfcb9d73..fa21589726 100644 --- a/libsql-sqlite3/src/vtab.c +++ b/libsql-sqlite3/src/vtab.c @@ -37,11 +37,12 @@ struct VtabCtx { ** If pModule==0, then delete the module zName if it exists. */ Module *sqlite3VtabCreateModule( - sqlite3 *db, /* Database in which module is registered */ - const char *zName, /* Name assigned to this module */ - const sqlite3_module *pModule, /* The definition of the module */ - void *pAux, /* Context pointer for xCreate/xConnect */ - void (*xDestroy)(void *) /* Module destructor function */ + sqlite3 *db, /* Database in which module is registered */ + const char *zName, /* Name assigned to this module */ + const sqlite3_module *pModule, /* The definition of the module */ + const libsql_module *pLibsqlModule, /* The definition of the libSQL module */ + void *pAux, /* Context pointer for xCreate/xConnect */ + void (*xDestroy)(void *) /* Module destructor function */ ){ Module *pMod; Module *pDel; @@ -60,6 +61,7 @@ Module *sqlite3VtabCreateModule( memcpy(zCopy, zName, nName+1); pMod->zName = zCopy; pMod->pModule = pModule; + pMod->pLibsqlModule = pLibsqlModule; pMod->pAux = pAux; pMod->xDestroy = xDestroy; pMod->pEpoTab = 0; @@ -85,16 +87,17 @@ Module *sqlite3VtabCreateModule( ** sqlite3_create_module_v2() interfaces. */ static int createModule( - sqlite3 *db, /* Database in which module is registered */ - const char *zName, /* Name assigned to this module */ - const sqlite3_module *pModule, /* The definition of the module */ - void *pAux, /* Context pointer for xCreate/xConnect */ - void (*xDestroy)(void *) /* Module destructor function */ + sqlite3 *db, /* Database in which module is registered */ + const char *zName, /* Name assigned to this module */ + const sqlite3_module *pModule, /* The definition of the module */ + const libsql_module *pLibsqlModule, /* The definition of the libSQL module */ + void *pAux, /* Context pointer for xCreate/xConnect */ + void (*xDestroy)(void *) /* Module destructor function */ ){ int rc = SQLITE_OK; sqlite3_mutex_enter(db->mutex); - (void)sqlite3VtabCreateModule(db, zName, pModule, pAux, xDestroy); + (void)sqlite3VtabCreateModule(db, zName, pModule, pLibsqlModule, pAux, xDestroy); rc = sqlite3ApiExit(db, rc); if( rc!=SQLITE_OK && xDestroy ) xDestroy(pAux); sqlite3_mutex_leave(db->mutex); @@ -114,7 +117,7 @@ int sqlite3_create_module( #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; #endif - return createModule(db, zName, pModule, pAux, 0); + return createModule(db, zName, pModule, NULL, pAux, 0); } /* @@ -123,14 +126,31 @@ int sqlite3_create_module( int sqlite3_create_module_v2( sqlite3 *db, /* Database in which module is registered */ const char *zName, /* Name assigned to this module */ - const sqlite3_module *pModule, /* The definition of the module */ + const sqlite3_module *pModule, /* The definition of the libSQL module */ void *pAux, /* Context pointer for xCreate/xConnect */ void (*xDestroy)(void *) /* Module destructor function */ ){ #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; #endif - return createModule(db, zName, pModule, pAux, xDestroy); + return createModule(db, zName, pModule, NULL, pAux, xDestroy); +} + +/* +** External API function used to create a new virtual-table module. +*/ +int libsql_create_module_v2( + sqlite3 *db, /* Database in which module is registered */ + const char *zName, /* Name assigned to this module */ + const sqlite3_module *pModule, /* The definition of the module */ + const libsql_module *pLibsqlModule, /* The definition of the module */ + void *pAux, /* Context pointer for xCreate/xConnect */ + void (*xDestroy)(void *) /* Module destructor function */ +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; +#endif + return createModule(db, zName, pModule, pLibsqlModule, pAux, xDestroy); } /* @@ -150,7 +170,7 @@ int sqlite3_drop_modules(sqlite3 *db, const char** azNames){ for(ii=0; azNames[ii]!=0 && strcmp(azNames[ii],pMod->zName)!=0; ii++){} if( azNames[ii]!=0 ) continue; } - createModule(db, pMod->zName, 0, 0, 0); + createModule(db, pMod->zName, 0, 0, 0, 0); } return SQLITE_OK; } @@ -630,6 +650,7 @@ static int vtabCallConstructor( ** the sqlite3_vtab object if successful. */ memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0])); pVTable->pVtab->pModule = pMod->pModule; + pVTable->pVtab->pLibsqlModule = pMod->pLibsqlModule; pMod->nRefModule++; pVTable->nRef = 1; if( sCtx.bDeclared==0 ){