Skip to content

Commit 45544bd

Browse files
committed
libsql-sqlite3: Add libsql_wal_get_frame() API
This patch adds a libsql_wal_get_frame() API to read the raw WAL frame from a database. You can use the API as follows (omitting error handling) to obtain all the WAL frames in a database: ```c static int sync_db(sqlite3 *db_primary, sqlite3 *db_backup){ unsigned int max_frame; libsql_wal_frame_count(db_primary, &max_frame); for(int i=1; i<=max_frame; i++){ char frame[4096+24]; libsql_wal_get_frame(db_primary, i, frame, sizeof(frame)); } } ```
1 parent 61558b2 commit 45544bd

File tree

4 files changed

+56
-0
lines changed

4 files changed

+56
-0
lines changed

libsql-sqlite3/src/main.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2475,6 +2475,35 @@ int libsql_wal_frame_count(
24752475
#endif
24762476
}
24772477

2478+
int libsql_wal_get_frame(
2479+
sqlite3* db,
2480+
unsigned int iFrame,
2481+
void *pBuf,
2482+
unsigned int nBuf
2483+
){
2484+
int rc = SQLITE_OK;
2485+
Pager *pPager;
2486+
2487+
#ifdef SQLITE_OMIT_WAL
2488+
UNUSED_PARAMETER(iFrame);
2489+
UNUSED_PARAMETER(nBuf);
2490+
UNUSED_PARAMETER(pBuf);
2491+
return SQLITE_OK;
2492+
#else
2493+
2494+
#ifdef SQLITE_ENABLE_API_ARMOR
2495+
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
2496+
#endif
2497+
2498+
sqlite3_mutex_enter(db->mutex);
2499+
pPager = sqlite3BtreePager(db->aDb[0].pBt);
2500+
rc = sqlite3PagerWalReadFrameRaw(pPager, iFrame, pBuf, nBuf);
2501+
sqlite3_mutex_leave(db->mutex);
2502+
2503+
return rc;
2504+
#endif
2505+
}
2506+
24782507
/*
24792508
** Register a function to be invoked prior to each autovacuum that
24802509
** determines the number of pages to vacuum.

libsql-sqlite3/src/pager.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7784,6 +7784,21 @@ int sqlite3PagerWalFrameCount(Pager *pPager, unsigned int *pnFrames){
77847784
}
77857785
}
77867786

7787+
int sqlite3PagerWalReadFrameRaw(
7788+
Pager *pPager,
7789+
unsigned int iFrame,
7790+
void *pFrameOut,
7791+
unsigned int nFrameOutLen
7792+
){
7793+
if( pagerUseWal(pPager) ){
7794+
unsigned int nFrameLen = 24+pPager->pageSize;
7795+
if( nFrameOutLen!=nFrameLen ) return SQLITE_MISUSE;
7796+
return pPager->wal->methods.xReadFrameRaw(pPager->wal->pData, iFrame, nFrameOutLen, pFrameOut);
7797+
}else{
7798+
return SQLITE_ERROR;
7799+
}
7800+
}
7801+
77877802
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
77887803
/*
77897804
** If pager pPager is a wal-mode database not in exclusive locking mode,

libsql-sqlite3/src/pager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ void sqlite3PagerSetBusyHandler(Pager*, int(*)(void *), void *);
134134
int sqlite3PagerSetPagesize(Pager*, u32*, int);
135135
Pgno sqlite3PagerMaxPageCount(Pager*, Pgno);
136136
int sqlite3PagerWalFrameCount(Pager *, unsigned int *);
137+
int sqlite3PagerWalReadFrame(Pager *, unsigned int, void *, unsigned int);
137138

138139
void sqlite3PagerSetCachesize(Pager*, int);
139140
int sqlite3PagerSetSpillsize(Pager*, int);

libsql-sqlite3/src/sqlite.h.in

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10573,6 +10573,17 @@ int libsql_wal_disable_checkpoint(sqlite3 *db);
1057310573
*/
1057410574
int libsql_wal_frame_count(sqlite3*, unsigned int*);
1057510575

10576+
/*
10577+
** CAPI3REF: Get a frame from the WAL file
10578+
** METHOD: sqlite3
10579+
**
10580+
** ^The [libsql_wal_get_frame(D,I,P,S)] interface extracts frame I from
10581+
** the WAL file for [database connection] D into memory obtained from
10582+
** [sqlite3_malloc64()] and returns a pointer to that memory. The size of
10583+
** the memory allocated is given by S.
10584+
*/
10585+
int libsql_wal_get_frame(sqlite3*, unsigned int, void*, unsigned int);
10586+
1057610587
/*
1057710588
** CAPI3REF: Low-level system error code
1057810589
** METHOD: sqlite3

0 commit comments

Comments
 (0)