Skip to content

Commit

Permalink
sqlite virtual wal API v2
Browse files Browse the repository at this point in the history
This is an iteration on the sqlite3 virtual WAL API, that gets rid of
global state, and completely decouples the sqlite3 WAL from the abtract
wal. This in turns makes the WAL interface compasable straighforwardly.
  • Loading branch information
MarinPostma committed Oct 30, 2023
1 parent d08eeee commit dbf9519
Show file tree
Hide file tree
Showing 17 changed files with 376 additions and 500 deletions.
8 changes: 3 additions & 5 deletions libsql-sqlite3/src/attach.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ static void attachFunc(
Db *pNew = 0; /* Db object for the newly attached database */
char *zErrDyn = 0;
sqlite3_vfs *pVfs;
libsql_wal_methods *pWal;

UNUSED_PARAMETER(NotUsed);
zFile = (const char *)sqlite3_value_text(argv[0]);
Expand All @@ -109,9 +108,8 @@ static void attachFunc(
** reopen it as a MemDB */
Btree *pNewBt = 0;
pVfs = sqlite3_vfs_find("memdb");
pWal = libsql_wal_methods_find(NULL);
if( pVfs==0 ) return;
rc = sqlite3BtreeOpen(pVfs, pWal, "x\0", db, &pNewBt, 0, SQLITE_OPEN_MAIN_DB);
rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNewBt, 0, SQLITE_OPEN_MAIN_DB);
if( rc==SQLITE_OK ){
Schema *pNewSchema = sqlite3SchemaGet(db, pNewBt);
if( pNewSchema ){
Expand Down Expand Up @@ -171,7 +169,7 @@ static void attachFunc(
** or may not be initialized.
*/
flags = db->openFlags;
rc = sqlite3ParseUri(db->pVfs->zName, db->pWalMethods->zName, zFile, &flags, &pVfs, &pWal, &zPath, &zErr);
rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr);
if( rc!=SQLITE_OK ){
if( rc==SQLITE_NOMEM ) sqlite3OomFault(db);
sqlite3_result_error(context, zErr, -1);
Expand All @@ -180,7 +178,7 @@ static void attachFunc(
}
assert( pVfs );
flags |= SQLITE_OPEN_MAIN_DB;
rc = sqlite3BtreeOpen(pVfs, pWal, zPath, db, &pNew->pBt, 0, flags);
rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags);
db->nDb++;
pNew->zDbSName = sqlite3DbStrDup(db, zName);
}
Expand Down
5 changes: 1 addition & 4 deletions libsql-sqlite3/src/btree.c
Original file line number Diff line number Diff line change
Expand Up @@ -2474,7 +2474,6 @@ static int btreeInvokeBusyHandler(void *pArg){
*/
int sqlite3BtreeOpen(
sqlite3_vfs *pVfs, /* VFS to use for this b-tree */
libsql_wal_methods *pWal,/* WAL methods to use for this b-tree */
const char *zFilename, /* Name of the file containing the BTree database */
sqlite3 *db, /* Associated database handle */
Btree **ppBtree, /* Pointer to new Btree object written here */
Expand Down Expand Up @@ -2623,9 +2622,7 @@ int sqlite3BtreeOpen(
rc = SQLITE_NOMEM_BKPT;
goto btree_open_out;
}
void* pWalMethodsData = NULL;
if (db) pWalMethodsData= db->pWalMethodsData;
rc = sqlite3PagerOpen(pVfs, pWal, pWalMethodsData, &pBt->pPager, zFilename,
rc = sqlite3PagerOpen(pVfs, db->create_wal ,&pBt->pPager, zFilename,
sizeof(MemPage), flags, vfsFlags, pageReinit);
if( rc==SQLITE_OK ){
sqlite3PagerSetMmapLimit(pBt->pPager, db->szMmap);
Expand Down
1 change: 0 additions & 1 deletion libsql-sqlite3/src/btree.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ typedef struct libsql_wal_methods libsql_wal_methods;

int sqlite3BtreeOpen(
sqlite3_vfs *pVfs, /* VFS to use with this b-tree */
libsql_wal_methods *pWal,/* WAL methods to use with this b-tree */
const char *zFilename, /* Name of database file to open */
sqlite3 *db, /* Associated database connection */
Btree **ppBtree, /* Return open Btree* here */
Expand Down
4 changes: 2 additions & 2 deletions libsql-sqlite3/src/build.c
Original file line number Diff line number Diff line change
Expand Up @@ -5222,7 +5222,7 @@ int sqlite3OpenTempDatabase(Parse *pParse){
SQLITE_OPEN_DELETEONCLOSE |
SQLITE_OPEN_TEMP_DB;

rc = sqlite3BtreeOpen(db->pVfs, db->pWalMethods, 0, db, &pBt, 0, flags);
rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pBt, 0, flags);
if( rc!=SQLITE_OK ){
sqlite3ErrorMsg(pParse, "unable to open a temporary database "
"file for storing temporary tables");
Expand Down Expand Up @@ -5835,4 +5835,4 @@ void libsql_drop_function(
sqlite3ErrorMsg(pParse, "Support for user-defined functions is not compiled-in. Try ./configure --enable-wasm-runtime");
}

#endif
#endif
7 changes: 1 addition & 6 deletions libsql-sqlite3/src/loadext.c
Original file line number Diff line number Diff line change
Expand Up @@ -517,12 +517,7 @@ static const sqlite3_api_routines sqlite3Apis = {
sqlite3_stmt_explain
};

static const libsql_api_routines libsqlApis = {
/* libSQL 0.1.1 */
libsql_wal_methods_find,
libsql_wal_methods_register,
libsql_wal_methods_unregister
};
static const libsql_api_routines libsqlApis = { };
/* True if x is the directory separator character
*/
#if SQLITE_OS_WIN
Expand Down
47 changes: 15 additions & 32 deletions libsql-sqlite3/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1238,6 +1238,9 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){
*/
sqlite3VtabRollback(db);

/* Destroy the create wal */
/* (db->create_wal.xDestroy)(db->create_wal.self); */

/* Legacy behavior (sqlite3_close() behavior) is to return
** SQLITE_BUSY if the connection can not be closed immediately.
*/
Expand Down Expand Up @@ -2932,12 +2935,6 @@ int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
return oldLimit; /* IMP: R-53341-35419 */
}

#ifdef SQLITE_OMIT_WAL
libsql_wal_methods* libsql_wal_methods_find(const char *zName) {
return NULL;
}
#endif

/*
** This function is used to parse both URIs and non-URI filenames passed by the
** user to API functions sqlite3_open() or sqlite3_open_v2(), and for database
Expand Down Expand Up @@ -2968,18 +2965,15 @@ libsql_wal_methods* libsql_wal_methods_find(const char *zName) {
*/
int sqlite3ParseUri(
const char *zDefaultVfs, /* VFS to use if no "vfs=xxx" query option */
const char *zDefaultWal, /* WAL module to use if no "wal=xxx" query option */
const char *zUri, /* Nul-terminated URI to parse */
unsigned int *pFlags, /* IN/OUT: SQLITE_OPEN_XXX flags */
sqlite3_vfs **ppVfs, /* OUT: VFS to use */
libsql_wal_methods **ppWal, /* OUT: WAL module to use */
char **pzFile, /* OUT: Filename component of URI */
char **pzErrMsg /* OUT: Error message (if rc!=SQLITE_OK) */
){
int rc = SQLITE_OK;
unsigned int flags = *pFlags;
const char *zVfs = zDefaultVfs;
const char *zWal = zDefaultWal;
char *zFile;
char c;
int nUri = sqlite3Strlen30(zUri);
Expand Down Expand Up @@ -3110,9 +3104,7 @@ int sqlite3ParseUri(

if( nOpt==3 && memcmp("vfs", zOpt, 3)==0 ){
zVfs = zVal;
}else if( nOpt==3 && memcmp("wal", zOpt, 3)==0 ){
zWal = zVal;
}else{
} else {
struct OpenMode {
const char *z;
int mode;
Expand Down Expand Up @@ -3194,11 +3186,6 @@ int sqlite3ParseUri(
*pzErrMsg = sqlite3_mprintf("no such vfs: %s", zVfs);
rc = SQLITE_ERROR;
}
*ppWal = libsql_wal_methods_find(zWal);
if( *ppWal==NULL ){
*pzErrMsg = sqlite3_mprintf("no such WAL module: %s", zWal);
rc = SQLITE_ERROR;
}
parse_uri_out:
if( rc!=SQLITE_OK ){
sqlite3_free_filename(zFile);
Expand Down Expand Up @@ -3232,12 +3219,12 @@ static const char *uriParameter(const char *zFilename, const char *zParam){
** is UTF-8 encoded.
*/
static int openDatabase(
const char *zFilename, /* Database filename UTF-8 encoded */
sqlite3 **ppDb, /* OUT: Returned database handle */
unsigned int flags, /* Operational flags */
const char *zVfs, /* Name of the VFS to use */
const char *zWal, /* Name of WAL module to use */
void* pWalMethodsData /* Pointer to the user data*/
const char *zFilename, /* Database filename UTF-8 encoded */
sqlite3 **ppDb, /* OUT: Returned database handle */
unsigned int flags, /* Operational flags */
const char *zVfs, /* Name of the VFS to use */
const char *zWal, /* Name of WAL module to use */
libsql_create_wal *create_wal /* Pointer to the user data*/
){
sqlite3 *db; /* Store allocated handle here */
int rc; /* Return code */
Expand Down Expand Up @@ -3297,7 +3284,7 @@ static int openDatabase(
/* Allocate the sqlite data structure */
db = sqlite3MallocZero( sizeof(sqlite3) );
if( db==0 ) goto opendb_out;
db->pWalMethodsData = pWalMethodsData;
db->create_wal = create_wal;
if( isThreadsafe
#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS
|| sqlite3GlobalConfig.bCoreMutex
Expand Down Expand Up @@ -3465,7 +3452,7 @@ static int openDatabase(
if( ((1<<(flags&7)) & 0x46)==0 ){
rc = SQLITE_MISUSE_BKPT; /* IMP: R-18321-05872 */
}else{
rc = sqlite3ParseUri(zVfs, zWal, zFilename, &flags, &db->pVfs, &db->pWalMethods, &zOpen, &zErrMsg);
rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg);
}
if( rc!=SQLITE_OK ){
if( rc==SQLITE_NOMEM ) sqlite3OomFault(db);
Expand All @@ -3481,7 +3468,7 @@ static int openDatabase(
#endif

/* Open the backend database driver */
rc = sqlite3BtreeOpen(db->pVfs, db->pWalMethods, zOpen, db, &db->aDb[0].pBt, 0,
rc = sqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, 0,
flags | SQLITE_OPEN_MAIN_DB);
if( rc!=SQLITE_OK ){
if( rc==SQLITE_IOERR_NOMEM ){
Expand Down Expand Up @@ -3559,10 +3546,6 @@ static int openDatabase(
setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside,
sqlite3GlobalConfig.nLookaside);

if (strcmp("default", libsql_wal_methods_name(db->pWalMethods)) != 0) {
sqlite3_exec(db, "pragma journal_mode=wal", NULL, NULL, NULL);
}

sqlite3_wal_autocheckpoint(db, SQLITE_DEFAULT_WAL_AUTOCHECKPOINT);

opendb_out:
Expand Down Expand Up @@ -3627,9 +3610,9 @@ int libsql_open_v2(
int flags, /* Flags */
const char *zVfs, /* Name of VFS module to use, NULL for default */
const char *zWal, /* Name of WAL module to use */
void* pWalMethodsData /* User data, passed to the libsql_wal struct*/
libsql_create_wal create_wal /* User data, passed to the libsql_wal struct*/
) {
return openDatabase(filename, ppDb, (unsigned int)flags, zVfs, zWal, pWalMethodsData);
return openDatabase(filename, ppDb, (unsigned int)flags, zVfs, zWal, NULL);
}

#ifndef SQLITE_OMIT_UTF16
Expand Down
Loading

0 comments on commit dbf9519

Please sign in to comment.