Skip to content

Commit 092fd3c

Browse files
committed
libsql-sqlite3: Add libsql_wal_insert_frame() API
```c static void sync_db(sqlite3 *db_primary, sqlite3 *db_backup){ unsigned int max_frame; libsql_wal_frame_count(db_primary, &max_frame); libsql_wal_begin_commit(db_backup); for(int i=1; i<=max_frame; i++){ char frame[4096+24]; libsql_wal_get_frame(db_primary, i, frame, sizeof(frame)); libsql_wal_insert_frame(db_backup, i, frame, sizeof(frame)); } libsql_wal_end_commit(db_backup); } ```
1 parent 45544bd commit 092fd3c

File tree

4 files changed

+156
-0
lines changed

4 files changed

+156
-0
lines changed

libsql-sqlite3/src/main.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2504,6 +2504,81 @@ int libsql_wal_get_frame(
25042504
#endif
25052505
}
25062506

2507+
/*
2508+
** Begin a WAL commit.
2509+
*/
2510+
int libsql_wal_insert_begin(sqlite3 *db) {
2511+
Pager *pPager;
2512+
int rc;
2513+
2514+
sqlite3_mutex_enter(db->mutex);
2515+
pPager = sqlite3BtreePager(db->aDb[0].pBt);
2516+
rc = sqlite3PagerSharedLock(pPager);
2517+
if (rc != SQLITE_OK) {
2518+
goto out_unlock;
2519+
}
2520+
int isOpen = 0;
2521+
rc = sqlite3PagerOpenWal(pPager, &isOpen);
2522+
if (rc != SQLITE_OK) {
2523+
goto out_unlock;
2524+
}
2525+
rc = sqlite3PagerWalBeginCommit(pPager);
2526+
if (rc != SQLITE_OK) {
2527+
goto out_unlock;
2528+
}
2529+
out_unlock:
2530+
sqlite3_mutex_leave(db->mutex);
2531+
return rc;
2532+
}
2533+
2534+
int libsql_wal_insert_end(sqlite3 *db) {
2535+
Pager *pPager;
2536+
int rc;
2537+
2538+
sqlite3_mutex_enter(db->mutex);
2539+
pPager = sqlite3BtreePager(db->aDb[0].pBt);
2540+
rc = sqlite3PagerWalEndCommit(pPager);
2541+
if (rc != SQLITE_OK) {
2542+
goto out_unlock;
2543+
}
2544+
out_unlock:
2545+
sqlite3_mutex_leave(db->mutex);
2546+
return rc;
2547+
}
2548+
2549+
/*
2550+
** Insert a frame into the WAL.
2551+
*/
2552+
int libsql_wal_insert_frame(
2553+
sqlite3* db,
2554+
unsigned int iFrame,
2555+
void *pBuf,
2556+
unsigned int nBuf
2557+
){
2558+
int rc = SQLITE_OK;
2559+
Pager *pPager;
2560+
2561+
#ifdef SQLITE_OMIT_WAL
2562+
*pnFrame = 0;
2563+
return SQLITE_OK;
2564+
#else
2565+
#ifdef SQLITE_ENABLE_API_ARMOR
2566+
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
2567+
#endif
2568+
2569+
sqlite3_mutex_enter(db->mutex);
2570+
pPager = sqlite3BtreePager(db->aDb[0].pBt);
2571+
rc = sqlite3PagerWalInsert(pPager, iFrame, pBuf, nBuf);
2572+
if (rc != SQLITE_OK) {
2573+
goto out_unlock;
2574+
}
2575+
out_unlock:
2576+
sqlite3_mutex_leave(db->mutex);
2577+
2578+
return rc;
2579+
#endif
2580+
}
2581+
25072582
/*
25082583
** Register a function to be invoked prior to each autovacuum that
25092584
** determines the number of pages to vacuum.

libsql-sqlite3/src/pager.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7799,6 +7799,66 @@ int sqlite3PagerWalReadFrameRaw(
77997799
}
78007800
}
78017801

7802+
int sqlite3PagerWalBeginCommit(Pager *pPager) {
7803+
int rc;
7804+
if (!pagerUseWal(pPager)) {
7805+
return SQLITE_ERROR;
7806+
}
7807+
rc = pagerBeginReadTransaction(pPager);
7808+
if (rc != SQLITE_OK) {
7809+
return rc;
7810+
}
7811+
return pPager->wal->methods.xBeginWriteTransaction(pPager->wal->pData);
7812+
}
7813+
7814+
int sqlite3PagerWalEndCommit(Pager *pPager) {
7815+
if (!pagerUseWal(pPager)) {
7816+
return SQLITE_ERROR;
7817+
}
7818+
return pPager->wal->methods.xEndWriteTransaction(pPager->wal->pData);
7819+
}
7820+
7821+
int sqlite3PagerWalInsert(Pager *pPager, unsigned int iFrame, void *pBuf, unsigned int nBuf) {
7822+
int rc = SQLITE_OK;
7823+
7824+
if (!pagerUseWal(pPager)) {
7825+
return SQLITE_ERROR;
7826+
}
7827+
unsigned int mxFrame;
7828+
rc = pPager->wal->methods.xFrameCount(pPager->wal->pData, 1, &mxFrame);
7829+
if (rc != SQLITE_OK) {
7830+
return rc;
7831+
}
7832+
if (iFrame <= mxFrame) {
7833+
return SQLITE_OK;
7834+
}
7835+
u8 *aFrame = (u8*)pBuf;
7836+
u32 pgno = sqlite3Get4byte(&aFrame[0]);
7837+
u32 nTruncate = sqlite3Get4byte(&aFrame[4]);
7838+
u8 *pData = aFrame + 24;
7839+
7840+
PgHdr pghdr;
7841+
memset(&pghdr, 0, sizeof(PgHdr));
7842+
pghdr.pPage = NULL;
7843+
pghdr.pData = pData;
7844+
pghdr.pExtra = NULL;
7845+
pghdr.pgno = pgno;
7846+
pghdr.flags = 0;
7847+
7848+
int isCommit = (nTruncate != 0);
7849+
7850+
int nFrames = 0;
7851+
rc = pPager->wal->methods.xFrames(pPager->wal->pData,
7852+
pPager->pageSize,
7853+
&pghdr,
7854+
nTruncate,
7855+
isCommit,
7856+
pPager->walSyncFlags,
7857+
&nFrames);
7858+
assert( nFrames == 1 );
7859+
return rc;
7860+
}
7861+
78027862
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
78037863
/*
78047864
** If pager pPager is a wal-mode database not in exclusive locking mode,

libsql-sqlite3/src/pager.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,9 @@ int sqlite3PagerSetPagesize(Pager*, u32*, int);
135135
Pgno sqlite3PagerMaxPageCount(Pager*, Pgno);
136136
int sqlite3PagerWalFrameCount(Pager *, unsigned int *);
137137
int sqlite3PagerWalReadFrame(Pager *, unsigned int, void *, unsigned int);
138+
int sqlite3PagerWalBeginCommit(Pager*);
139+
int sqlite3PagerWalEndCommit(Pager*);
140+
int sqlite3PagerWalInsert(Pager*, unsigned int, void *, unsigned int);
138141

139142
void sqlite3PagerSetCachesize(Pager*, int);
140143
int sqlite3PagerSetSpillsize(Pager*, int);

libsql-sqlite3/src/sqlite.h.in

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10584,6 +10584,24 @@ int libsql_wal_frame_count(sqlite3*, unsigned int*);
1058410584
*/
1058510585
int libsql_wal_get_frame(sqlite3*, unsigned int, void*, unsigned int);
1058610586

10587+
/*
10588+
** CAPI3REF: Begin frame insertion into the WAL
10589+
** METHOD: sqlite3
10590+
*/
10591+
int libsql_wal_insert_begin(sqlite3*);
10592+
10593+
/*
10594+
** CAPI3REF: End frame insertion into the WAL
10595+
** METHOD: sqlite3
10596+
*/
10597+
int libsql_wal_insert_end(sqlite3*);
10598+
10599+
/*
10600+
** CAPI3REF: Insert a frame into the WAL
10601+
** METHOD: sqlite3
10602+
*/
10603+
int libsql_wal_insert_frame(sqlite3*, unsigned int, void *, unsigned int);
10604+
1058710605
/*
1058810606
** CAPI3REF: Low-level system error code
1058910607
** METHOD: sqlite3

0 commit comments

Comments
 (0)