@@ -16436,7 +16436,8 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
1643616436 int,
1643716437 int,
1643816438 int,
16439- void(*)(DbPage*)
16439+ void(*)(DbPage*),
16440+ int /* hasCodec from connection-level cache */
1644016441);
1644116442SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager, sqlite3*);
1644216443SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager*, int, unsigned char*);
@@ -16625,7 +16626,8 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
1662516626 sqlite3 *db, /* Associated database connection */
1662616627 Btree **ppBtree, /* Return open Btree* here */
1662716628 int flags, /* Flags */
16628- int vfsFlags /* Flags passed through to VFS open */
16629+ int vfsFlags, /* Flags passed through to VFS open */
16630+ int hasCodec /* True if this database has encryption codec */
1662916631);
1663016632
1663116633/* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the
@@ -17993,6 +17995,7 @@ struct Db {
1799317995 Btree *pBt; /* The B*Tree structure for this database file */
1799417996 u8 safety_level; /* How aggressive at syncing data to disk */
1799517997 u8 bSyncSet; /* True if "PRAGMA synchronous=N" has been run */
17998+ u8 hasCodec; /* True if this database has encryption codec */
1799617999 Schema *pSchema; /* Pointer to database schema (possibly shared) */
1799718000};
1799818001
@@ -58232,27 +58235,18 @@ struct Pager {
5823258235/* libSQL extension: pager codec */
5823358236
5823458237#ifdef LIBSQL_CUSTOM_PAGER_CODEC
58235- int libsql_pager_has_codec_impl(struct Pager *_p);
5823658238int libsql_pager_codec_impl(libsql_pghdr *hdr, void **ret);
58239+ int libsql_db_has_codec(sqlite3_vfs* pVfs, const char* zFilename);
5823758240#endif
5823858241
5823958242int libsql_pager_has_codec(struct Pager *_p) {
5824058243#ifdef LIBSQL_CUSTOM_PAGER_CODEC
58241- return libsql_pager_has_codec_impl (_p);
58244+ return libsql_db_has_codec (_p->pVfs, _p->zFilename );
5824258245#else
5824358246 return 0;
5824458247#endif
5824558248}
5824658249
58247- /*
58248- ** Update the cached codec status.
58249- ** This should be called after encryption is added, removed, or changed
58250- ** via sqlite3_rekey_v2() to ensure the cached hasCodec value is correct.
58251- */
58252- void libsql_pager_update_codec_cache(struct Pager *pPager) {
58253- pPager->hasCodec = libsql_pager_has_codec(pPager);
58254- }
58255-
5825658250int libsql_pager_codec(libsql_pghdr *hdr, void **ret) {
5825758251 if (!ret) {
5825858252 return SQLITE_MISUSE_BKPT;
@@ -62295,7 +62289,8 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
6229562289 int nExtra, /* Extra bytes append to each in-memory page */
6229662290 int flags, /* flags controlling this file */
6229762291 int vfsFlags, /* flags passed through to sqlite3_vfs.xOpen() */
62298- void (*xReinit)(DbPage*) /* Function to reinitialize pages */
62292+ void (*xReinit)(DbPage*),/* Function to reinitialize pages */
62293+ int dbHasCodec /* hasCodec from connection-level cache */
6229962294){
6230062295 u8 *pPtr;
6230162296 Pager *pPager = 0; /* Pager object to allocate and return */
@@ -62635,8 +62630,9 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
6263562630 /* pPager->xBusyHandler = 0; */
6263662631 /* pPager->pBusyHandlerArg = 0; */
6263762632 pPager->xReiniter = xReinit;
62638- /* Cache the codec check result to avoid expensive VFS stack traversal on every page read */
62639- pPager->hasCodec = libsql_pager_has_codec(pPager);
62633+ /* Use cached codec status from connection level to avoid expensive VFS stack traversal
62634+ ** and file lookup on every pager initialization */
62635+ pPager->hasCodec = dbHasCodec;
6264062636 setGetterMethod(pPager);
6264162637 /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
6264262638 /* pPager->szMmap = SQLITE_DEFAULT_MMAP_SIZE // will be set by btree.c */
@@ -73757,7 +73753,8 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
7375773753 sqlite3 *db, /* Associated database handle */
7375873754 Btree **ppBtree, /* Pointer to new Btree object written here */
7375973755 int flags, /* Options */
73760- int vfsFlags /* Flags passed through to sqlite3_vfs.xOpen() */
73756+ int vfsFlags, /* Flags passed through to sqlite3_vfs.xOpen() */
73757+ int hasCodec /* True if this database has encryption codec */
7376173758){
7376273759 BtShared *pBt = 0; /* Shared part of btree structure */
7376373760 Btree *p; /* Handle to return */
@@ -73902,7 +73899,7 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
7390273899 goto btree_open_out;
7390373900 }
7390473901 rc = sqlite3PagerOpen(pVfs, db->wal_manager ,&pBt->pPager, zFilename,
73905- sizeof(MemPage), flags, vfsFlags, pageReinit);
73902+ sizeof(MemPage), flags, vfsFlags, pageReinit, hasCodec );
7390673903 if( rc==SQLITE_OK ){
7390773904 sqlite3PagerSetMmapLimit(pBt->pPager, db->szMmap);
7390873905 rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader);
@@ -98769,7 +98766,8 @@ case OP_OpenEphemeral: { /* ncycle */
9876998766 pCx->isEphemeral = 1;
9877098767 rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->ub.pBtx,
9877198768 BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5,
98772- vfsFlags);
98769+ vfsFlags,
98770+ 0); /* Ephemeral tables are never encrypted */
9877398771 if( rc==SQLITE_OK ){
9877498772 rc = sqlite3BtreeBeginTrans(pCx->ub.pBtx, 1, 0);
9877598773 if( rc==SQLITE_OK ){
@@ -121888,6 +121886,10 @@ int libsql_handle_extra_attach_params(sqlite3* db, const char* zName, const char
121888121886SQLITE_PRIVATE int sqlite3mcHandleAttachKey(sqlite3*, const char*, const char*, sqlite3_value*, char**);
121889121887#endif
121890121888
121889+ #ifdef LIBSQL_CUSTOM_PAGER_CODEC
121890+ int libsql_db_has_codec(sqlite3_vfs* pVfs, const char* zFilename);
121891+ #endif
121892+
121891121893/*
121892121894** An SQL user-function registered to do the work of an ATTACH statement. The
121893121895** three arguments to the function come directly from an attach statement:
@@ -121940,7 +121942,8 @@ static void attachFunc(
121940121942 Btree *pNewBt = 0;
121941121943 pVfs = sqlite3_vfs_find("memdb");
121942121944 if( pVfs==0 ) return;
121943- rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNewBt, 0, SQLITE_OPEN_MAIN_DB);
121945+ rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNewBt, 0, SQLITE_OPEN_MAIN_DB,
121946+ 0); /* Memdb databases are never encrypted */
121944121947 if( rc==SQLITE_OK ){
121945121948 Schema *pNewSchema = sqlite3SchemaGet(db, pNewBt);
121946121949 if( pNewSchema ){
@@ -122009,7 +122012,13 @@ static void attachFunc(
122009122012 }
122010122013 assert( pVfs );
122011122014 flags |= SQLITE_OPEN_MAIN_DB;
122012- rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags);
122015+ /* Check encryption status for this database file */
122016+ #ifdef LIBSQL_CUSTOM_PAGER_CODEC
122017+ pNew->hasCodec = libsql_db_has_codec(pVfs, zPath);
122018+ #else
122019+ pNew->hasCodec = 0;
122020+ #endif
122021+ rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags, pNew->hasCodec);
122013122022 db->nDb++;
122014122023 pNew->zDbSName = sqlite3DbStrDup(db, zName);
122015122024 }
@@ -128047,7 +128056,8 @@ SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *pParse){
128047128056 SQLITE_OPEN_DELETEONCLOSE |
128048128057 SQLITE_OPEN_TEMP_DB;
128049128058
128050- rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pBt, 0, flags);
128059+ db->aDb[1].hasCodec = 0; /* Temp databases are never encrypted */
128060+ rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pBt, 0, flags, db->aDb[1].hasCodec);
128051128061 if( rc!=SQLITE_OK ){
128052128062 sqlite3ErrorMsg(pParse, "unable to open a temporary database "
128053128063 "file for storing temporary tables");
@@ -184304,6 +184314,10 @@ static const char *uriParameter(const char *zFilename, const char *zParam){
184304184314int libsql_handle_extra_uri_params(sqlite3 *db, const char *zOpen);
184305184315#endif
184306184316
184317+ #ifdef LIBSQL_CUSTOM_PAGER_CODEC
184318+ int libsql_db_has_codec(sqlite3_vfs* pVfs, const char* zFilename);
184319+ #endif
184320+
184307184321/*
184308184322** This routine does the work of opening a database on behalf of
184309184323** sqlite3_open() and sqlite3_open16(). The database filename "zFilename"
@@ -184559,9 +184573,17 @@ static int openDatabase(
184559184573 }
184560184574#endif
184561184575
184576+ /* Cache encryption status at database open time to avoid expensive
184577+ ** VFS stack traversal and file lookup on every pager initialization */
184578+ #ifdef LIBSQL_CUSTOM_PAGER_CODEC
184579+ db->aDb[0].hasCodec = libsql_db_has_codec(db->pVfs, zOpen);
184580+ #else
184581+ db->aDb[0].hasCodec = 0;
184582+ #endif
184583+
184562184584 /* Open the backend database driver */
184563184585 rc = sqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, 0,
184564- flags | SQLITE_OPEN_MAIN_DB);
184586+ flags | SQLITE_OPEN_MAIN_DB, db->aDb[0].hasCodec );
184565184587 if( rc!=SQLITE_OK ){
184566184588 if( rc==SQLITE_IOERR_NOMEM ){
184567184589 rc = SQLITE_NOMEM_BKPT;
0 commit comments