Skip to content

Commit 3ac4aa1

Browse files
committed
libsql-{sqlite3,ffi}: Add xFrameCount() to the virtual WAL API
1 parent abf339d commit 3ac4aa1

17 files changed

Lines changed: 151 additions & 1 deletion

File tree

libsql-ffi/bundled/bindings/bindgen.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3316,6 +3316,13 @@ pub struct libsql_wal_methods {
33163316
aWalData: *mut ::std::os::raw::c_uint,
33173317
) -> ::std::os::raw::c_int,
33183318
>,
3319+
pub xFrameCount: ::std::option::Option<
3320+
unsafe extern "C" fn(
3321+
pWal: *mut wal_impl,
3322+
arg1: ::std::os::raw::c_int,
3323+
arg2: *mut ::std::os::raw::c_uint,
3324+
) -> ::std::os::raw::c_int,
3325+
>,
33193326
pub xFrames: ::std::option::Option<
33203327
unsafe extern "C" fn(
33213328
pWal: *mut wal_impl,

libsql-ffi/bundled/bindings/session_bindgen.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3822,6 +3822,13 @@ pub struct libsql_wal_methods {
38223822
aWalData: *mut ::std::os::raw::c_uint,
38233823
) -> ::std::os::raw::c_int,
38243824
>,
3825+
pub xFrameCount: ::std::option::Option<
3826+
unsafe extern "C" fn(
3827+
pWal: *mut wal_impl,
3828+
arg1: ::std::os::raw::c_int,
3829+
arg2: *mut ::std::os::raw::c_uint,
3830+
) -> ::std::os::raw::c_int,
3831+
>,
38253832
pub xFrames: ::std::option::Option<
38263833
unsafe extern "C" fn(
38273834
pWal: *mut wal_impl,

libsql-replication/src/injector/sqlite_injector/injector_wal.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,10 @@ impl Wal for InjectorWal {
134134
self.inner.savepoint_undo(rollback_data)
135135
}
136136

137+
fn frame_count(&self, locked: i32) -> Result<u32> {
138+
self.inner.frame_count(locked)
139+
}
140+
137141
fn insert_frames(
138142
&mut self,
139143
page_size: c_int,

libsql-sqlite3/src/main.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2449,6 +2449,32 @@ int libsql_wal_disable_checkpoint(sqlite3 *db) {
24492449
return SQLITE_OK;
24502450
}
24512451

2452+
/*
2453+
** Return the number of frames in the WAL of the given database.
2454+
*/
2455+
int libsql_wal_frame_count(
2456+
sqlite3* db,
2457+
unsigned int *pnFrame
2458+
){
2459+
int rc = SQLITE_OK;
2460+
Pager *pPager;
2461+
2462+
#ifdef SQLITE_OMIT_WAL
2463+
*pnFrame = 0;
2464+
return SQLITE_OK;
2465+
#else
2466+
#ifdef SQLITE_ENABLE_API_ARMOR
2467+
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
2468+
#endif
2469+
2470+
sqlite3_mutex_enter(db->mutex);
2471+
pPager = sqlite3BtreePager(db->aDb[0].pBt);
2472+
rc = sqlite3PagerWalFrameCount(pPager, pnFrame);
2473+
sqlite3_mutex_leave(db->mutex);
2474+
return rc;
2475+
#endif
2476+
}
2477+
24522478
/*
24532479
** Register a function to be invoked prior to each autovacuum that
24542480
** determines the number of pages to vacuum.

libsql-sqlite3/src/pager.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7771,6 +7771,19 @@ int sqlite3PagerCloseWal(Pager *pPager, sqlite3 *db){
77717771
return rc;
77727772
}
77737773

7774+
/**
7775+
** Return the number of frames in the WAL file.
7776+
**
7777+
** If the pager is not in WAL mode or we failed to obtain an exclusive write lock, returns -1.
7778+
**/
7779+
int sqlite3PagerWalFrameCount(Pager *pPager, unsigned int *pnFrames){
7780+
if( pagerUseWal(pPager) ){
7781+
return pPager->wal->methods.xFrameCount(pPager->wal->pData, 0, pnFrames);
7782+
}else{
7783+
return SQLITE_ERROR;
7784+
}
7785+
}
7786+
77747787
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
77757788
/*
77767789
** If pager pPager is a wal-mode database not in exclusive locking mode,

libsql-sqlite3/src/pager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ int sqlite3PagerReadFileheader(Pager*, int, unsigned char*);
133133
void sqlite3PagerSetBusyHandler(Pager*, int(*)(void *), void *);
134134
int sqlite3PagerSetPagesize(Pager*, u32*, int);
135135
Pgno sqlite3PagerMaxPageCount(Pager*, Pgno);
136+
int sqlite3PagerWalFrameCount(Pager *, unsigned int *);
137+
136138
void sqlite3PagerSetCachesize(Pager*, int);
137139
int sqlite3PagerSetSpillsize(Pager*, int);
138140
void sqlite3PagerSetMmapLimit(Pager *, sqlite3_int64);

libsql-sqlite3/src/sqlite.h.in

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10564,6 +10564,15 @@ void *libsql_close_hook(sqlite3 *db, void (*xClose)(void *pCtx, sqlite3 *db), vo
1056410564
*/
1056510565
int libsql_wal_disable_checkpoint(sqlite3 *db);
1056610566

10567+
/*
10568+
** CAPI3REF: Get the number of frames in the WAL file
10569+
** METHOD: sqlite3
10570+
**
10571+
** ^The [libsql_wal_frame_count(D,P)] interface returns the number of frames
10572+
** in the WAL file for [database connection] D into *P.
10573+
*/
10574+
int libsql_wal_frame_count(sqlite3*, unsigned int*);
10575+
1056710576
/*
1056810577
** CAPI3REF: Low-level system error code
1056910578
** METHOD: sqlite3

libsql-sqlite3/src/wal.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4001,6 +4001,19 @@ static int walFrames(
40014001
return rc;
40024002
}
40034003

4004+
int sqlite3WalFrameCount(Wal *pWal, int locked, unsigned int *pnFrames){
4005+
int rc = SQLITE_OK;
4006+
if( locked==0 ) {
4007+
rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
4008+
if (rc != SQLITE_OK) return rc;
4009+
}
4010+
*pnFrames = pWal->hdr.mxFrame;
4011+
if( locked==0 ) {
4012+
walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
4013+
}
4014+
return SQLITE_OK;
4015+
}
4016+
40044017
/*
40054018
** Write a set of frames to the log. The caller must hold the write-lock
40064019
** on the log file (obtained using sqlite3WalBeginWriteTransaction()).
@@ -4506,6 +4519,7 @@ static int sqlite3WalOpen(
45064519
out->methods.xUndo = (int (*)(wal_impl *, int (*)(void *, unsigned int), void *))sqlite3WalUndo;
45074520
out->methods.xSavepoint = (void (*)(wal_impl *, unsigned int *))sqlite3WalSavepoint;
45084521
out->methods.xSavepointUndo = (int (*)(wal_impl *, unsigned int *))sqlite3WalSavepointUndo;
4522+
out->methods.xFrameCount = (int (*)(wal_impl *, int, unsigned int *))sqlite3WalFrameCount;
45094523
out->methods.xFrames = (int (*)(wal_impl *, int, libsql_pghdr *, unsigned int, int, int, int *))sqlite3WalFrames;
45104524
out->methods.xCheckpoint = (int (*)(wal_impl *, sqlite3 *, int, int (*)(void *), void *, int, int, unsigned char *, int *, int *, int (*)(void*, int, const unsigned char*, int, int, int), void*))sqlite3WalCheckpoint;
45114525
out->methods.xCallback = (int (*)(wal_impl *))sqlite3WalCallback;

libsql-sqlite3/src/wal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ typedef struct libsql_wal_methods {
7575
** response to a ROLLBACK TO command. */
7676
int (*xSavepointUndo)(wal_impl* pWal, unsigned int *aWalData);
7777

78+
/* Return the number of frames in the WAL */
79+
int (*xFrameCount)(wal_impl* pWal, int, unsigned int *);
80+
7881
/* Write a frame or frames to the log. */
7982
int (*xFrames)(wal_impl* pWal, int, libsql_pghdr *, unsigned int, int, int, int*);
8083

libsql-sqlite3/test/rust_suite/src/virtual_wal.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ mod tests {
9898
self.0.read_frame(frame_no, buffer)
9999
}
100100

101+
fn frame_count(&self, locked: i32) -> libsql_sys::wal::Result<u32> {
102+
self.0.frame_count(locked)
103+
}
104+
101105
fn db_size(&self) -> u32 {
102106
self.0.db_size()
103107
}

0 commit comments

Comments
 (0)