mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Database must be named either "local" or "session". Each has a distinct
namespace. FossilOrigin-Name: c8e41279294ea7c2f041c7d4cbbd85fce47d55f2f56180ca837316f7dfd75237
This commit is contained in:
257
ext/misc/vfskv.c
257
ext/misc/vfskv.c
@ -47,40 +47,23 @@ SQLITE_EXTENSION_INIT1
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
** The low-level storage engine
|
** The low-level storage engine
|
||||||
*/
|
*/
|
||||||
typedef struct KVStorage KVStorage;
|
#define KVSTORAGE_KEY_SZ 24
|
||||||
struct KVStorage {
|
static int kvstorageWrite(const char*, const char *zKey, const char *zData);
|
||||||
char *zDir;
|
static int kvstorageDelete(const char*, const char *zKey);
|
||||||
char zKey[50];
|
static int kvstorageRead(const char*, const char *zKey, char *zBuf, int nBuf);
|
||||||
};
|
|
||||||
|
|
||||||
static KVStorage *kvstorageOpen(void);
|
|
||||||
static void kvstorageClose(KVStorage*);
|
|
||||||
static int kvstorageWrite(KVStorage*, const char *zKey, const char *zData);
|
|
||||||
static int kvstorageDelete(KVStorage*, const char *zKey);
|
|
||||||
static int kvstorageRead(KVStorage*, const char *zKey, char *zBuf, int nBuf);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Forward declaration of objects used by this utility
|
** Forward declaration of objects used by this VFS implementation
|
||||||
*/
|
*/
|
||||||
typedef struct KVVfsVfs KVVfsVfs;
|
|
||||||
typedef struct KVVfsFile KVVfsFile;
|
typedef struct KVVfsFile KVVfsFile;
|
||||||
|
|
||||||
|
|
||||||
/* All information about the database */
|
|
||||||
struct KVVfsVfs {
|
|
||||||
sqlite3_vfs base; /* VFS methods */
|
|
||||||
KVStorage *pStore; /* Single command KV storage object */
|
|
||||||
KVVfsFile *pFiles; /* List of open KVVfsFile objects */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* A single open file. There are only two files represented by this
|
/* A single open file. There are only two files represented by this
|
||||||
** VFS - the database and the rollback journal.
|
** VFS - the database and the rollback journal.
|
||||||
*/
|
*/
|
||||||
struct KVVfsFile {
|
struct KVVfsFile {
|
||||||
sqlite3_file base; /* IO methods */
|
sqlite3_file base; /* IO methods */
|
||||||
KVVfsVfs *pVfs; /* The VFS to which this file belongs */
|
const char *zClass; /* Storage class */
|
||||||
KVVfsFile *pNext; /* Next in list of all files */
|
|
||||||
int isJournal; /* True if this is a journal file */
|
int isJournal; /* True if this is a journal file */
|
||||||
unsigned int nJrnl; /* Space allocated for aJrnl[] */
|
unsigned int nJrnl; /* Space allocated for aJrnl[] */
|
||||||
char *aJrnl; /* Journal content */
|
char *aJrnl; /* Journal content */
|
||||||
@ -110,7 +93,7 @@ static int kvvfsSectorSize(sqlite3_file*);
|
|||||||
static int kvvfsDeviceCharacteristics(sqlite3_file*);
|
static int kvvfsDeviceCharacteristics(sqlite3_file*);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Methods for KVVfsVfs
|
** Methods for sqlite3_vfs
|
||||||
*/
|
*/
|
||||||
static int kvvfsOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
|
static int kvvfsOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
|
||||||
static int kvvfsDelete(sqlite3_vfs*, const char *zName, int syncDir);
|
static int kvvfsDelete(sqlite3_vfs*, const char *zName, int syncDir);
|
||||||
@ -122,30 +105,26 @@ static int kvvfsSleep(sqlite3_vfs*, int microseconds);
|
|||||||
static int kvvfsCurrentTime(sqlite3_vfs*, double*);
|
static int kvvfsCurrentTime(sqlite3_vfs*, double*);
|
||||||
static int kvvfsCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
|
static int kvvfsCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
|
||||||
|
|
||||||
static KVVfsVfs kvvfs_vfs = {
|
static sqlite3_vfs kvvfs_vfs = {
|
||||||
{
|
1, /* iVersion */
|
||||||
1, /* iVersion */
|
sizeof(KVVfsFile), /* szOsFile */
|
||||||
sizeof(KVVfsFile), /* szOsFile */
|
1024, /* mxPathname */
|
||||||
1024, /* mxPathname */
|
0, /* pNext */
|
||||||
0, /* pNext */
|
"kvvfs", /* zName */
|
||||||
"kvvfs", /* zName */
|
0, /* pAppData */
|
||||||
0, /* pAppData */
|
kvvfsOpen, /* xOpen */
|
||||||
kvvfsOpen, /* xOpen */
|
kvvfsDelete, /* xDelete */
|
||||||
kvvfsDelete, /* xDelete */
|
kvvfsAccess, /* xAccess */
|
||||||
kvvfsAccess, /* xAccess */
|
kvvfsFullPathname, /* xFullPathname */
|
||||||
kvvfsFullPathname, /* xFullPathname */
|
kvvfsDlOpen, /* xDlOpen */
|
||||||
kvvfsDlOpen, /* xDlOpen */
|
0, /* xDlError */
|
||||||
0, /* xDlError */
|
0, /* xDlSym */
|
||||||
0, /* xDlSym */
|
0, /* xDlClose */
|
||||||
0, /* xDlClose */
|
kvvfsRandomness, /* xRandomness */
|
||||||
kvvfsRandomness, /* xRandomness */
|
kvvfsSleep, /* xSleep */
|
||||||
kvvfsSleep, /* xSleep */
|
kvvfsCurrentTime, /* xCurrentTime */
|
||||||
kvvfsCurrentTime, /* xCurrentTime */
|
0, /* xGetLastError */
|
||||||
0, /* xGetLastError */
|
kvvfsCurrentTimeInt64 /* xCurrentTimeInt64 */
|
||||||
kvvfsCurrentTimeInt64 /* xCurrentTimeInt64 */
|
|
||||||
},
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Methods for sqlite3_file objects referencing a database file
|
/* Methods for sqlite3_file objects referencing a database file
|
||||||
@ -198,27 +177,16 @@ static sqlite3_io_methods kvvfs_jrnl_io_methods = {
|
|||||||
|
|
||||||
/****** Storage subsystem **************************************************/
|
/****** Storage subsystem **************************************************/
|
||||||
|
|
||||||
/* Allocate a new storage subsystem.
|
|
||||||
** Return NULL if OOM
|
|
||||||
*/
|
|
||||||
static KVStorage *kvstorageOpen(void){
|
|
||||||
KVStorage *pStore;
|
|
||||||
pStore = sqlite3_malloc64( sizeof(*pStore) );
|
|
||||||
if( pStore==0 ) return 0;
|
|
||||||
memset(pStore, 0, sizeof(*pStore));
|
|
||||||
return pStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free all resources associated with the storage subsystem */
|
|
||||||
static void kvstorageClose(KVStorage *pStore){
|
|
||||||
sqlite3_free(pStore);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Expand the key name with an appropriate prefix and put the result
|
/* Expand the key name with an appropriate prefix and put the result
|
||||||
** in pStore->zKey[]
|
** in pStore->zKey[]
|
||||||
*/
|
*/
|
||||||
static void kvstorageMakeKey(KVStorage *pStore, const char *zKey){
|
static void kvstorageMakeKey(
|
||||||
sqlite3_snprintf(sizeof(pStore->zKey), pStore->zKey, "kvvfs-%s", zKey);
|
const char *zClass,
|
||||||
|
const char *zKeyIn,
|
||||||
|
char *zKeyOut
|
||||||
|
){
|
||||||
|
sqlite3_snprintf(KVSTORAGE_KEY_SZ, zKeyOut, "%s-%s", zClass, zKeyIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write content into a key. zKey is of limited size. zData should be
|
/* Write content into a key. zKey is of limited size. zData should be
|
||||||
@ -227,15 +195,16 @@ static void kvstorageMakeKey(KVStorage *pStore, const char *zKey){
|
|||||||
** Return the number of errors.
|
** Return the number of errors.
|
||||||
*/
|
*/
|
||||||
static int kvstorageWrite(
|
static int kvstorageWrite(
|
||||||
KVStorage *pStore,
|
const char *zClass,
|
||||||
const char *zKey,
|
const char *zKey,
|
||||||
const char *zData
|
const char *zData
|
||||||
){
|
){
|
||||||
FILE *fd;
|
FILE *fd;
|
||||||
kvstorageMakeKey(pStore, zKey);
|
char zXKey[KVSTORAGE_KEY_SZ];
|
||||||
fd = fopen(pStore->zKey, "wb");
|
kvstorageMakeKey(zClass, zKey, zXKey);
|
||||||
|
fd = fopen(zXKey, "wb");
|
||||||
if( fd ){
|
if( fd ){
|
||||||
KVVFS_TRACE(("KVVFS-WRITE %-10s (%d) %.50s%s\n", pStore->zKey,
|
KVVFS_TRACE(("KVVFS-WRITE %-15s (%d) %.50s%s\n", zXKey,
|
||||||
(int)strlen(zData), zData,
|
(int)strlen(zData), zData,
|
||||||
strlen(zData)>50 ? "..." : ""));
|
strlen(zData)>50 ? "..." : ""));
|
||||||
fputs(zData, fd);
|
fputs(zData, fd);
|
||||||
@ -248,10 +217,11 @@ static int kvstorageWrite(
|
|||||||
|
|
||||||
/* Delete a key
|
/* Delete a key
|
||||||
*/
|
*/
|
||||||
static int kvstorageDelete(KVStorage *pStore, const char *zKey){
|
static int kvstorageDelete(const char *zClass, const char *zKey){
|
||||||
kvstorageMakeKey(pStore, zKey);
|
char zXKey[KVSTORAGE_KEY_SZ];
|
||||||
unlink(pStore->zKey);
|
kvstorageMakeKey(zClass, zKey, zXKey);
|
||||||
KVVFS_TRACE(("KVVFS-DELETE %-10s\n", pStore->zKey));
|
unlink(zXKey);
|
||||||
|
KVVFS_TRACE(("KVVFS-DELETE %-15s\n", zXKey));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,41 +238,42 @@ static int kvstorageDelete(KVStorage *pStore, const char *zKey){
|
|||||||
** actually reading it.
|
** actually reading it.
|
||||||
*/
|
*/
|
||||||
static int kvstorageRead(
|
static int kvstorageRead(
|
||||||
KVStorage *pStore,
|
const char *zClass,
|
||||||
const char *zKey,
|
const char *zKey,
|
||||||
char *zBuf,
|
char *zBuf,
|
||||||
int nBuf
|
int nBuf
|
||||||
){
|
){
|
||||||
FILE *fd;
|
FILE *fd;
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
kvstorageMakeKey(pStore, zKey);
|
char zXKey[KVSTORAGE_KEY_SZ];
|
||||||
if( access(pStore->zKey, R_OK)!=0
|
kvstorageMakeKey(zClass, zKey, zXKey);
|
||||||
|| stat(pStore->zKey, &buf)!=0
|
if( access(zXKey, R_OK)!=0
|
||||||
|
|| stat(zXKey, &buf)!=0
|
||||||
|| !S_ISREG(buf.st_mode)
|
|| !S_ISREG(buf.st_mode)
|
||||||
){
|
){
|
||||||
KVVFS_TRACE(("KVVFS-READ %-10s (-1)\n", pStore->zKey));
|
KVVFS_TRACE(("KVVFS-READ %-15s (-1)\n", zXKey));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if( nBuf<0 ){
|
if( nBuf<0 ){
|
||||||
return (int)buf.st_size;
|
return (int)buf.st_size;
|
||||||
}else if( nBuf==1 ){
|
}else if( nBuf==1 ){
|
||||||
zBuf[0] = 0;
|
zBuf[0] = 0;
|
||||||
KVVFS_TRACE(("KVVFS-READ %-10s (%d)\n", pStore->zKey,
|
KVVFS_TRACE(("KVVFS-READ %-15s (%d)\n", zXKey,
|
||||||
(int)buf.st_size));
|
(int)buf.st_size));
|
||||||
return (int)buf.st_size;
|
return (int)buf.st_size;
|
||||||
}
|
}
|
||||||
if( nBuf-1 > buf.st_size ){
|
if( nBuf > buf.st_size + 1 ){
|
||||||
nBuf = buf.st_size + 1;
|
nBuf = buf.st_size + 1;
|
||||||
}
|
}
|
||||||
fd = fopen(pStore->zKey, "rb");
|
fd = fopen(zXKey, "rb");
|
||||||
if( fd==0 ){
|
if( fd==0 ){
|
||||||
KVVFS_TRACE(("KVVFS-READ %-10s (-1)\n", pStore->zKey));
|
KVVFS_TRACE(("KVVFS-READ %-15s (-1)\n", zXKey));
|
||||||
return -1;
|
return -1;
|
||||||
}else{
|
}else{
|
||||||
sqlite3_int64 n = fread(zBuf, 1, nBuf-1, fd);
|
sqlite3_int64 n = fread(zBuf, 1, nBuf-1, fd);
|
||||||
fclose(fd);
|
fclose(fd);
|
||||||
zBuf[n] = 0;
|
zBuf[n] = 0;
|
||||||
KVVFS_TRACE(("KVVFS-READ %-10s (%lld) %.50s%s\n", pStore->zKey,
|
KVVFS_TRACE(("KVVFS-READ %-15s (%lld) %.50s%s\n", zXKey,
|
||||||
n, zBuf, n>50 ? "..." : ""));
|
n, zBuf, n>50 ? "..." : ""));
|
||||||
return (int)n;
|
return (int)n;
|
||||||
}
|
}
|
||||||
@ -445,42 +416,25 @@ static void kvvfsDecodeJournal(
|
|||||||
static sqlite3_int64 kvvfsReadFileSize(KVVfsFile *pFile){
|
static sqlite3_int64 kvvfsReadFileSize(KVVfsFile *pFile){
|
||||||
char zData[50];
|
char zData[50];
|
||||||
zData[0] = 0;
|
zData[0] = 0;
|
||||||
kvstorageRead(pFile->pVfs->pStore, "sz", zData, sizeof(zData)-1);
|
kvstorageRead(pFile->zClass, "sz", zData, sizeof(zData)-1);
|
||||||
return strtoll(zData, 0, 0);
|
return strtoll(zData, 0, 0);
|
||||||
}
|
}
|
||||||
static void kvvfsWriteFileSize(KVVfsFile *pFile, sqlite3_int64 sz){
|
static void kvvfsWriteFileSize(KVVfsFile *pFile, sqlite3_int64 sz){
|
||||||
char zData[50];
|
char zData[50];
|
||||||
sqlite3_snprintf(sizeof(zData), zData, "%lld", sz);
|
sqlite3_snprintf(sizeof(zData), zData, "%lld", sz);
|
||||||
kvstorageWrite(pFile->pVfs->pStore, "sz", zData);
|
kvstorageWrite(pFile->zClass, "sz", zData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****** VFS methods ********************************************************/
|
/****** sqlite3_io_methods methods ******************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Close an kvvfs-file.
|
** Close an kvvfs-file.
|
||||||
*/
|
*/
|
||||||
static int kvvfsClose(sqlite3_file *pProtoFile){
|
static int kvvfsClose(sqlite3_file *pProtoFile){
|
||||||
KVVfsFile *pFile = (KVVfsFile *)pProtoFile;
|
KVVfsFile *pFile = (KVVfsFile *)pProtoFile;
|
||||||
KVVfsVfs *pVfs = pFile->pVfs;
|
|
||||||
|
|
||||||
KVVFS_LOG(("xClose %s\n", pFile->isJournal ? "journal" : "db"));
|
KVVFS_LOG(("xClose %s %s\n", pFile->zClass,
|
||||||
if( pVfs->pFiles==pFile ){
|
pFile->isJournal ? "journal" : "db"));
|
||||||
pVfs->pFiles = pFile->pNext;
|
|
||||||
if( pVfs->pFiles==0 ){
|
|
||||||
kvstorageClose(pVfs->pStore);
|
|
||||||
pVfs->pStore = 0;
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
KVVfsFile *pX = pVfs->pFiles;
|
|
||||||
while( 1 ){
|
|
||||||
assert( pX );
|
|
||||||
if( pX->pNext==pFile ){
|
|
||||||
pX->pNext = pFile->pNext;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pX = pX->pNext;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sqlite3_free(pFile->aJrnl);
|
sqlite3_free(pFile->aJrnl);
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
@ -496,16 +450,16 @@ static int kvvfsReadJrnl(
|
|||||||
){
|
){
|
||||||
KVVfsFile *pFile = (KVVfsFile*)pProtoFile;
|
KVVfsFile *pFile = (KVVfsFile*)pProtoFile;
|
||||||
assert( pFile->isJournal );
|
assert( pFile->isJournal );
|
||||||
KVVFS_LOG(("xRead('journal',%d,%lld)\n", iAmt, iOfst));
|
KVVFS_LOG(("xRead('%s-journal',%d,%lld)\n", pFile->zClass, iAmt, iOfst));
|
||||||
if( pFile->aJrnl==0 ){
|
if( pFile->aJrnl==0 ){
|
||||||
int szTxt = kvstorageRead(pFile->pVfs->pStore, "jrnl", 0, 0);
|
int szTxt = kvstorageRead(pFile->zClass, "jrnl", 0, -1);
|
||||||
char *aTxt;
|
char *aTxt;
|
||||||
if( szTxt<=4 ){
|
if( szTxt<=4 ){
|
||||||
return SQLITE_IOERR;
|
return SQLITE_IOERR;
|
||||||
}
|
}
|
||||||
aTxt = sqlite3_malloc64( szTxt+1 );
|
aTxt = sqlite3_malloc64( szTxt+1 );
|
||||||
if( aTxt==0 ) return SQLITE_NOMEM;
|
if( aTxt==0 ) return SQLITE_NOMEM;
|
||||||
kvstorageRead(pFile->pVfs->pStore, "jrnl", aTxt, szTxt+1);
|
kvstorageRead(pFile->zClass, "jrnl", aTxt, szTxt+1);
|
||||||
kvvfsDecodeJournal(pFile, aTxt, szTxt);
|
kvvfsDecodeJournal(pFile, aTxt, szTxt);
|
||||||
sqlite3_free(aTxt);
|
sqlite3_free(aTxt);
|
||||||
if( pFile->aJrnl==0 ) return SQLITE_IOERR;
|
if( pFile->aJrnl==0 ) return SQLITE_IOERR;
|
||||||
@ -533,7 +487,7 @@ static int kvvfsReadDb(
|
|||||||
char aData[131073];
|
char aData[131073];
|
||||||
assert( iOfst>=0 );
|
assert( iOfst>=0 );
|
||||||
assert( iAmt>=0 );
|
assert( iAmt>=0 );
|
||||||
KVVFS_LOG(("xRead('db',%d,%lld)\n", iAmt, iOfst));
|
KVVFS_LOG(("xRead('%s-db',%d,%lld)\n", pFile->zClass, iAmt, iOfst));
|
||||||
if( iOfst+iAmt>=512 ){
|
if( iOfst+iAmt>=512 ){
|
||||||
if( (iOfst % iAmt)!=0 ){
|
if( (iOfst % iAmt)!=0 ){
|
||||||
return SQLITE_IOERR_READ;
|
return SQLITE_IOERR_READ;
|
||||||
@ -547,7 +501,7 @@ static int kvvfsReadDb(
|
|||||||
pgno = 1;
|
pgno = 1;
|
||||||
}
|
}
|
||||||
sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno);
|
sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno);
|
||||||
got = kvstorageRead(pFile->pVfs->pStore, zKey, aData, sizeof(aData)-1);
|
got = kvstorageRead(pFile->zClass, zKey, aData, sizeof(aData)-1);
|
||||||
if( got<0 ){
|
if( got<0 ){
|
||||||
n = 0;
|
n = 0;
|
||||||
}else{
|
}else{
|
||||||
@ -583,7 +537,7 @@ static int kvvfsWriteJrnl(
|
|||||||
){
|
){
|
||||||
KVVfsFile *pFile = (KVVfsFile*)pProtoFile;
|
KVVfsFile *pFile = (KVVfsFile*)pProtoFile;
|
||||||
sqlite3_int64 iEnd = iOfst+iAmt;
|
sqlite3_int64 iEnd = iOfst+iAmt;
|
||||||
KVVFS_LOG(("xWrite('journal',%d,%lld)\n", iAmt, iOfst));
|
KVVFS_LOG(("xWrite('%s-journal',%d,%lld)\n", pFile->zClass, iAmt, iOfst));
|
||||||
if( iEnd>=0x10000000 ) return SQLITE_FULL;
|
if( iEnd>=0x10000000 ) return SQLITE_FULL;
|
||||||
if( pFile->aJrnl==0 || pFile->nJrnl<iEnd ){
|
if( pFile->aJrnl==0 || pFile->nJrnl<iEnd ){
|
||||||
char *aNew = sqlite3_realloc(pFile->aJrnl, iEnd);
|
char *aNew = sqlite3_realloc(pFile->aJrnl, iEnd);
|
||||||
@ -613,13 +567,13 @@ static int kvvfsWriteDb(
|
|||||||
unsigned int pgno;
|
unsigned int pgno;
|
||||||
char zKey[30];
|
char zKey[30];
|
||||||
char aData[131073];
|
char aData[131073];
|
||||||
KVVFS_LOG(("xWrite('db',%d,%lld)\n", iAmt, iOfst));
|
KVVFS_LOG(("xWrite('%s-db',%d,%lld)\n", pFile->zClass, iAmt, iOfst));
|
||||||
assert( iAmt>=512 && iAmt<=65536 );
|
assert( iAmt>=512 && iAmt<=65536 );
|
||||||
assert( (iAmt & (iAmt-1))==0 );
|
assert( (iAmt & (iAmt-1))==0 );
|
||||||
pgno = 1 + iOfst/iAmt;
|
pgno = 1 + iOfst/iAmt;
|
||||||
sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno);
|
sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno);
|
||||||
kvvfsEncode(zBuf, iAmt, aData);
|
kvvfsEncode(zBuf, iAmt, aData);
|
||||||
kvstorageWrite(pFile->pVfs->pStore, zKey, aData);
|
kvstorageWrite(pFile->zClass, zKey, aData);
|
||||||
if( iOfst+iAmt > pFile->szDb ){
|
if( iOfst+iAmt > pFile->szDb ){
|
||||||
pFile->szDb = iOfst + iAmt;
|
pFile->szDb = iOfst + iAmt;
|
||||||
}
|
}
|
||||||
@ -631,9 +585,9 @@ static int kvvfsWriteDb(
|
|||||||
*/
|
*/
|
||||||
static int kvvfsTruncateJrnl(sqlite3_file *pProtoFile, sqlite_int64 size){
|
static int kvvfsTruncateJrnl(sqlite3_file *pProtoFile, sqlite_int64 size){
|
||||||
KVVfsFile *pFile = (KVVfsFile *)pProtoFile;
|
KVVfsFile *pFile = (KVVfsFile *)pProtoFile;
|
||||||
KVVFS_LOG(("xTruncate('journal',%lld)\n", size));
|
KVVFS_LOG(("xTruncate('%s-journal',%lld)\n", pFile->zClass, size));
|
||||||
assert( size==0 );
|
assert( size==0 );
|
||||||
kvstorageDelete(pFile->pVfs->pStore, "jrnl");
|
kvstorageDelete(pFile->zClass, "jrnl");
|
||||||
sqlite3_free(pFile->aJrnl);
|
sqlite3_free(pFile->aJrnl);
|
||||||
pFile->aJrnl = 0;
|
pFile->aJrnl = 0;
|
||||||
pFile->nJrnl = 0;
|
pFile->nJrnl = 0;
|
||||||
@ -647,12 +601,12 @@ static int kvvfsTruncateDb(sqlite3_file *pProtoFile, sqlite_int64 size){
|
|||||||
){
|
){
|
||||||
char zKey[50];
|
char zKey[50];
|
||||||
unsigned int pgno, pgnoMax;
|
unsigned int pgno, pgnoMax;
|
||||||
KVVFS_LOG(("xTruncate('db',%lld)\n", size));
|
KVVFS_LOG(("xTruncate('%s-db',%lld)\n", pFile->zClass, size));
|
||||||
pgno = 1 + size/pFile->szPage;
|
pgno = 1 + size/pFile->szPage;
|
||||||
pgnoMax = 2 + pFile->szDb/pFile->szPage;
|
pgnoMax = 2 + pFile->szDb/pFile->szPage;
|
||||||
while( pgno<=pgnoMax ){
|
while( pgno<=pgnoMax ){
|
||||||
sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno);
|
sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno);
|
||||||
kvstorageDelete(pFile->pVfs->pStore, zKey);
|
kvstorageDelete(pFile->zClass, zKey);
|
||||||
pgno++;
|
pgno++;
|
||||||
}
|
}
|
||||||
pFile->szDb = size;
|
pFile->szDb = size;
|
||||||
@ -669,7 +623,7 @@ static int kvvfsSyncJrnl(sqlite3_file *pProtoFile, int flags){
|
|||||||
int i, n;
|
int i, n;
|
||||||
KVVfsFile *pFile = (KVVfsFile *)pProtoFile;
|
KVVfsFile *pFile = (KVVfsFile *)pProtoFile;
|
||||||
char *zOut;
|
char *zOut;
|
||||||
KVVFS_LOG(("xSync('journal')\n"));
|
KVVFS_LOG(("xSync('%s-journal')\n", pFile->zClass));
|
||||||
if( pFile->nJrnl<=0 ){
|
if( pFile->nJrnl<=0 ){
|
||||||
return kvvfsTruncateJrnl(pProtoFile, 0);
|
return kvvfsTruncateJrnl(pProtoFile, 0);
|
||||||
}
|
}
|
||||||
@ -685,13 +639,13 @@ static int kvvfsSyncJrnl(sqlite3_file *pProtoFile, int flags){
|
|||||||
}while( n>0 );
|
}while( n>0 );
|
||||||
zOut[i++] = ' ';
|
zOut[i++] = ' ';
|
||||||
kvvfsEncode(pFile->aJrnl, pFile->nJrnl, &zOut[i]);
|
kvvfsEncode(pFile->aJrnl, pFile->nJrnl, &zOut[i]);
|
||||||
kvstorageWrite(pFile->pVfs->pStore, "jrnl", zOut);
|
kvstorageWrite(pFile->zClass, "jrnl", zOut);
|
||||||
sqlite3_free(zOut);
|
sqlite3_free(zOut);
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
static int kvvfsSyncDb(sqlite3_file *pProtoFile, int flags){
|
static int kvvfsSyncDb(sqlite3_file *pProtoFile, int flags){
|
||||||
KVVfsFile *pFile = (KVVfsFile *)pProtoFile;
|
KVVfsFile *pFile = (KVVfsFile *)pProtoFile;
|
||||||
KVVFS_LOG(("xSync('db')\n"));
|
KVVFS_LOG(("xSync('%s-db')\n", pFile->zClass));
|
||||||
if( pFile->szDb>0 ){
|
if( pFile->szDb>0 ){
|
||||||
kvvfsWriteFileSize(pFile, pFile->szDb);
|
kvvfsWriteFileSize(pFile, pFile->szDb);
|
||||||
}
|
}
|
||||||
@ -703,13 +657,13 @@ static int kvvfsSyncDb(sqlite3_file *pProtoFile, int flags){
|
|||||||
*/
|
*/
|
||||||
static int kvvfsFileSizeJrnl(sqlite3_file *pProtoFile, sqlite_int64 *pSize){
|
static int kvvfsFileSizeJrnl(sqlite3_file *pProtoFile, sqlite_int64 *pSize){
|
||||||
KVVfsFile *pFile = (KVVfsFile *)pProtoFile;
|
KVVfsFile *pFile = (KVVfsFile *)pProtoFile;
|
||||||
KVVFS_LOG(("xFileSize('journal')\n"));
|
KVVFS_LOG(("xFileSize('%s-journal')\n", pFile->zClass));
|
||||||
*pSize = pFile->nJrnl;
|
*pSize = pFile->nJrnl;
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
static int kvvfsFileSizeDb(sqlite3_file *pProtoFile, sqlite_int64 *pSize){
|
static int kvvfsFileSizeDb(sqlite3_file *pProtoFile, sqlite_int64 *pSize){
|
||||||
KVVfsFile *pFile = (KVVfsFile *)pProtoFile;
|
KVVfsFile *pFile = (KVVfsFile *)pProtoFile;
|
||||||
KVVFS_LOG(("xFileSize('db')\n"));
|
KVVFS_LOG(("xFileSize('%s-db')\n", pFile->zClass));
|
||||||
if( pFile->szDb>=0 ){
|
if( pFile->szDb>=0 ){
|
||||||
*pSize = pFile->szDb;
|
*pSize = pFile->szDb;
|
||||||
}else{
|
}else{
|
||||||
@ -724,7 +678,7 @@ static int kvvfsFileSizeDb(sqlite3_file *pProtoFile, sqlite_int64 *pSize){
|
|||||||
static int kvvfsLock(sqlite3_file *pProtoFile, int eLock){
|
static int kvvfsLock(sqlite3_file *pProtoFile, int eLock){
|
||||||
KVVfsFile *pFile = (KVVfsFile *)pProtoFile;
|
KVVfsFile *pFile = (KVVfsFile *)pProtoFile;
|
||||||
assert( !pFile->isJournal );
|
assert( !pFile->isJournal );
|
||||||
KVVFS_LOG(("xLock(%d)\n", eLock));
|
KVVFS_LOG(("xLock(%s,%d)\n", pFile->zClass, eLock));
|
||||||
|
|
||||||
if( eLock!=SQLITE_LOCK_NONE ){
|
if( eLock!=SQLITE_LOCK_NONE ){
|
||||||
pFile->szDb = kvvfsReadFileSize(pFile);
|
pFile->szDb = kvvfsReadFileSize(pFile);
|
||||||
@ -738,7 +692,7 @@ static int kvvfsLock(sqlite3_file *pProtoFile, int eLock){
|
|||||||
static int kvvfsUnlock(sqlite3_file *pProtoFile, int eLock){
|
static int kvvfsUnlock(sqlite3_file *pProtoFile, int eLock){
|
||||||
KVVfsFile *pFile = (KVVfsFile *)pProtoFile;
|
KVVfsFile *pFile = (KVVfsFile *)pProtoFile;
|
||||||
assert( !pFile->isJournal );
|
assert( !pFile->isJournal );
|
||||||
KVVFS_LOG(("xUnlock(%d)\n", eLock));
|
KVVFS_LOG(("xUnlock(%s,%d)\n", pFile->zClass, eLock));
|
||||||
if( eLock==SQLITE_LOCK_NONE ){
|
if( eLock==SQLITE_LOCK_NONE ){
|
||||||
pFile->szDb = -1;
|
pFile->szDb = -1;
|
||||||
}
|
}
|
||||||
@ -775,6 +729,7 @@ static int kvvfsDeviceCharacteristics(sqlite3_file *pProtoFile){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****** sqlite3_vfs methods *************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Open an kvvfs file handle.
|
** Open an kvvfs file handle.
|
||||||
@ -787,25 +742,26 @@ static int kvvfsOpen(
|
|||||||
int *pOutFlags
|
int *pOutFlags
|
||||||
){
|
){
|
||||||
KVVfsFile *pFile = (KVVfsFile*)pProtoFile;
|
KVVfsFile *pFile = (KVVfsFile*)pProtoFile;
|
||||||
KVVfsVfs *pVfs = (KVVfsVfs*)pProtoVfs;
|
|
||||||
KVVFS_LOG(("xOpen(\"%s\")\n", zName));
|
KVVFS_LOG(("xOpen(\"%s\")\n", zName));
|
||||||
pFile->aJrnl = 0;
|
if( strcmp(zName, "local")==0
|
||||||
pFile->nJrnl = 0;
|
|| strcmp(zName, "session")==0
|
||||||
if( sqlite3_strglob("*-journal", zName)==0 ){
|
){
|
||||||
|
pFile->isJournal = 0;
|
||||||
|
pFile->base.pMethods = &kvvfs_db_io_methods;
|
||||||
|
}else
|
||||||
|
if( strcmp(zName, "local-journal")==0
|
||||||
|
|| strcmp(zName, "session-journal")==0
|
||||||
|
){
|
||||||
pFile->isJournal = 1;
|
pFile->isJournal = 1;
|
||||||
pFile->base.pMethods = &kvvfs_jrnl_io_methods;
|
pFile->base.pMethods = &kvvfs_jrnl_io_methods;
|
||||||
}else{
|
}else{
|
||||||
pFile->isJournal = 0;
|
return SQLITE_CANTOPEN;
|
||||||
pFile->base.pMethods = &kvvfs_db_io_methods;
|
|
||||||
}
|
}
|
||||||
|
pFile->zClass = zName[0]=='s' ? "kvvfs-ses" : "kvvfs-loc";
|
||||||
|
pFile->aJrnl = 0;
|
||||||
|
pFile->nJrnl = 0;
|
||||||
pFile->szPage = -1;
|
pFile->szPage = -1;
|
||||||
pFile->szDb = -1;
|
pFile->szDb = -1;
|
||||||
pFile->pVfs = pVfs;
|
|
||||||
if( pVfs->pFiles==0 ){
|
|
||||||
pVfs->pStore = kvstorageOpen();
|
|
||||||
}
|
|
||||||
pFile->pNext = pVfs->pFiles;
|
|
||||||
pVfs->pFiles = pFile;
|
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -815,9 +771,11 @@ static int kvvfsOpen(
|
|||||||
** returning.
|
** returning.
|
||||||
*/
|
*/
|
||||||
static int kvvfsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
|
static int kvvfsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
|
||||||
KVVfsVfs *p = (KVVfsVfs*)pVfs;
|
if( strcmp(zPath, "local-journal")==0 ){
|
||||||
if( sqlite3_strglob("*-journal",zPath)==0 ){
|
kvstorageDelete("kvvfs-loc", "jrnl");
|
||||||
kvstorageDelete(p->pStore, "jrnl");
|
}else
|
||||||
|
if( strcmp(zPath, "session-journal")==0 ){
|
||||||
|
kvstorageDelete("kvvfs-ses", "jrnl");
|
||||||
}
|
}
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
@ -832,14 +790,21 @@ static int kvvfsAccess(
|
|||||||
int flags,
|
int flags,
|
||||||
int *pResOut
|
int *pResOut
|
||||||
){
|
){
|
||||||
KVVfsVfs *pVfs = (KVVfsVfs*)pProtoVfs;
|
|
||||||
KVVFS_LOG(("xAccess(\"%s\")\n", zPath));
|
KVVFS_LOG(("xAccess(\"%s\")\n", zPath));
|
||||||
if( sqlite3_strglob("*-journal", zPath)==0 ){
|
if( strcmp(zPath, "local-journal")==0 ){
|
||||||
*pResOut = kvstorageRead(pVfs->pStore, "jrnl", 0, 0)>0;
|
*pResOut = kvstorageRead("kvvfs-loc", "jrnl", 0, -1)>0;
|
||||||
}else if( sqlite3_strglob("*-wal", zPath)==0 ){
|
}else
|
||||||
|
if( strcmp(zPath, "session-journal")==0 ){
|
||||||
|
*pResOut = kvstorageRead("kvvfs-ses", "jrnl", 0, -1)>0;
|
||||||
|
}else
|
||||||
|
if( strcmp(zPath, "local")==0 ){
|
||||||
|
*pResOut = kvstorageRead("kvvfs-loc", "sz", 0, -1)>0;
|
||||||
|
}else
|
||||||
|
if( strcmp(zPath, "session")==0 ){
|
||||||
|
*pResOut = kvstorageRead("kvvfs-ses", "sz", 0, -1)>0;
|
||||||
|
}else
|
||||||
|
{
|
||||||
*pResOut = 0;
|
*pResOut = 0;
|
||||||
}else{
|
|
||||||
*pResOut = 1;
|
|
||||||
}
|
}
|
||||||
KVVFS_LOG(("xAccess returns %d\n",*pResOut));
|
KVVFS_LOG(("xAccess returns %d\n",*pResOut));
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
@ -915,6 +880,6 @@ int sqlite3_vfskv_init(
|
|||||||
const sqlite3_api_routines *pApi
|
const sqlite3_api_routines *pApi
|
||||||
){
|
){
|
||||||
SQLITE_EXTENSION_INIT2(pApi);
|
SQLITE_EXTENSION_INIT2(pApi);
|
||||||
sqlite3_vfs_register(&kvvfs_vfs.base, 1);
|
sqlite3_vfs_register(&kvvfs_vfs, 1);
|
||||||
return SQLITE_OK_LOAD_PERMANENTLY;
|
return SQLITE_OK_LOAD_PERMANENTLY;
|
||||||
}
|
}
|
||||||
|
12
manifest
12
manifest
@ -1,5 +1,5 @@
|
|||||||
C Separate\ssqlite3_io_methods\sobjects\sfor\sdatabase\sfiles\sand\sjournals.
|
C Database\smust\sbe\snamed\seither\s"local"\sor\s"session".\s\sEach\shas\sa\sdistinct\nnamespace.
|
||||||
D 2022-09-09T14:22:41.989
|
D 2022-09-09T16:16:33.749
|
||||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||||
@ -335,7 +335,7 @@ F ext/misc/uint.c 053fed3bce2e89583afcd4bf804d75d659879bbcedac74d0fa9ed548839a03
|
|||||||
F ext/misc/unionvtab.c 36237f0607ca954ac13a4a0e2d2ac40c33bc6e032a5f55f431713061ef1625f9
|
F ext/misc/unionvtab.c 36237f0607ca954ac13a4a0e2d2ac40c33bc6e032a5f55f431713061ef1625f9
|
||||||
F ext/misc/urifuncs.c f71360d14fa9e7626b563f1f781c6148109462741c5235ac63ae0f8917b9c751
|
F ext/misc/urifuncs.c f71360d14fa9e7626b563f1f781c6148109462741c5235ac63ae0f8917b9c751
|
||||||
F ext/misc/uuid.c 5bb2264c1b64d163efa46509544fd7500cb8769cb7c16dd52052da8d961505cf
|
F ext/misc/uuid.c 5bb2264c1b64d163efa46509544fd7500cb8769cb7c16dd52052da8d961505cf
|
||||||
F ext/misc/vfskv.c 7b2fa888cd33f41a7a3821eec10ed258fe029af41ad788a43856958c4d216432
|
F ext/misc/vfskv.c f154254c7585a0434d50d1b0fa0bb27b03ae4231a9045961e58a046dc5ea40ab
|
||||||
F ext/misc/vfslog.c 3932ab932eeb2601dbc4447cb14d445aaa9fbe43b863ef5f014401c3420afd20
|
F ext/misc/vfslog.c 3932ab932eeb2601dbc4447cb14d445aaa9fbe43b863ef5f014401c3420afd20
|
||||||
F ext/misc/vfsstat.c 474d08efc697b8eba300082cb1eb74a5f0f3df31ed257db1cb07e72ab0e53dfb
|
F ext/misc/vfsstat.c 474d08efc697b8eba300082cb1eb74a5f0f3df31ed257db1cb07e72ab0e53dfb
|
||||||
F ext/misc/vtablog.c 5538acd0c8ddaae372331bee11608d76973436b77d6a91e8635cfc9432fba5ae
|
F ext/misc/vtablog.c 5538acd0c8ddaae372331bee11608d76973436b77d6a91e8635cfc9432fba5ae
|
||||||
@ -2001,8 +2001,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P 00845ac9ef2616e90f5f6a20da3dd040fa8bdcfe73f72fe9c06039561150a82d
|
P 74fbf6c2a97729e481d5562344e960d0c237aeb1f07240262d32a24fb1f4b5a3
|
||||||
R 460848ff6f3cd63ef5eccab59824c77b
|
R ef722c3c17f5bd16a7c59b26dec45e05
|
||||||
U drh
|
U drh
|
||||||
Z 26961af5f4b759d7a43ac0a5cf8d117b
|
Z c4e335313d89d964aa7abb0331378ddc
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@ -1 +1 @@
|
|||||||
74fbf6c2a97729e481d5562344e960d0c237aeb1f07240262d32a24fb1f4b5a3
|
c8e41279294ea7c2f041c7d4cbbd85fce47d55f2f56180ca837316f7dfd75237
|
Reference in New Issue
Block a user