xFileControl, xDeviceCharacteristics, PSOW.

This commit is contained in:
Nuno Cruces
2023-03-17 13:24:15 +00:00
parent f789c2fb8b
commit 4cb65ccbd9
15 changed files with 193 additions and 77 deletions

View File

@@ -1,10 +0,0 @@
#include <stddef.h>
#include "main.c"
#include "os.c"
#include "qsort.c"
#include "sqlite3.c"
#include "time.c"
sqlite3_destructor_type malloc_destructor = &free;
size_t sqlite3_interrupt_offset = offsetof(sqlite3, u1.isInterrupted);

View File

@@ -1,14 +1,20 @@
#include <stdbool.h>
#include <stddef.h>
#include "sqlite3.h"
#include "sqlite3.c"
//
#include "os.c"
#include "qsort.c"
#include "time.c"
sqlite3_destructor_type malloc_destructor = &free;
size_t sqlite3_interrupt_offset = offsetof(sqlite3, u1.isInterrupted);
int sqlite3_os_init() {
return sqlite3_vfs_register(os_vfs(), /*default=*/true);
}
int main() {
int rc = sqlite3_initialize();
if (rc != SQLITE_OK) return 1;
}
sqlite3_vfs *os_vfs();
int sqlite3_os_init() {
return sqlite3_vfs_register(os_vfs(), /*default=*/true);
}

View File

@@ -18,36 +18,73 @@ int os_full_pathname(sqlite3_vfs *, const char *zName, int nOut, char *zOut);
struct os_file {
sqlite3_file base;
int id;
int lock;
char lock;
char psow;
int lockTimeout;
};
static_assert(offsetof(struct os_file, id) == 4, "Unexpected offset");
static_assert(offsetof(struct os_file, lock) == 8, "Unexpected offset");
static_assert(offsetof(struct os_file, psow) == 9, "Unexpected offset");
static_assert(offsetof(struct os_file, lockTimeout) == 12, "Unexpected offset");
int os_close(sqlite3_file *);
int os_read(sqlite3_file *, void *, int iAmt, sqlite3_int64 iOfst);
int os_write(sqlite3_file *, const void *, int iAmt, sqlite3_int64 iOfst);
int os_truncate(sqlite3_file *, sqlite3_int64 size);
int os_sync(sqlite3_file *, int flags);
int os_file_size(sqlite3_file *, sqlite3_int64 *pSize);
int os_file_control(sqlite3_file *pFile, int op, void *pArg);
int os_file_control(sqlite3_file *, int op, void *pArg);
int os_lock(sqlite3_file *pFile, int eLock);
int os_unlock(sqlite3_file *pFile, int eLock);
int os_check_reserved_lock(sqlite3_file *pFile, int *pResOut);
int os_lock(sqlite3_file *, int eLock);
int os_unlock(sqlite3_file *, int eLock);
int os_check_reserved_lock(sqlite3_file *, int *pResOut);
static int no_lock(sqlite3_file *pFile, int eLock) { return SQLITE_OK; }
static int no_unlock(sqlite3_file *pFile, int eLock) { return SQLITE_OK; }
static int no_check_reserved_lock(sqlite3_file *pFile, int *pResOut) {
*pResOut = 0;
return SQLITE_OK;
}
static int no_file_control(sqlite3_file *pFile, int op, void *pArg) {
static int os_file_control_w(sqlite3_file *file, int op, void *pArg) {
struct os_file *pFile = (struct os_file *)file;
switch (op) {
case SQLITE_FCNTL_VFSNAME: {
*(char **)pArg = sqlite3_mprintf("%s", "os");
return SQLITE_OK;
}
case SQLITE_FCNTL_LOCKSTATE: {
*(int *)pArg = pFile->lock;
return SQLITE_OK;
}
case SQLITE_FCNTL_LOCK_TIMEOUT: {
int iOld = pFile->lockTimeout;
pFile->lockTimeout = *(int *)pArg;
*(int *)pArg = iOld;
return SQLITE_OK;
}
case SQLITE_FCNTL_POWERSAFE_OVERWRITE: {
if (*(int *)pArg < 0) {
*(int *)pArg = pFile->psow;
} else {
pFile->psow = *(int *)pArg;
}
return SQLITE_OK;
}
case SQLITE_FCNTL_SIZE_HINT:
case SQLITE_FCNTL_HAS_MOVED:
return os_file_control(file, op, pArg);
}
// Consider also implementing these opcodes (in use by SQLite):
// SQLITE_FCNTL_BUSYHANDLER
// SQLITE_FCNTL_COMMIT_PHASETWO
// SQLITE_FCNTL_PDB
// SQLITE_FCNTL_PRAGMA
// SQLITE_FCNTL_SYNC
return SQLITE_NOTFOUND;
}
static int no_sector_size(sqlite3_file *pFile) { return 0; }
static int no_device_characteristics(sqlite3_file *pFile) { return 0; }
int localtime_s(struct tm *const pTm, time_t const *const pTime) {
return os_localtime((sqlite3_int64)*pTime, pTm);
static int os_sector_size(sqlite3_file *file) {
return SQLITE_DEFAULT_SECTOR_SIZE;
}
static int os_device_characteristics(sqlite3_file *file) {
struct os_file *pFile = (struct os_file *)file;
return pFile->psow ? SQLITE_IOCAP_POWERSAFE_OVERWRITE : 0;
}
static int os_open_w(sqlite3_vfs *vfs, sqlite3_filename zName,
@@ -63,12 +100,23 @@ static int os_open_w(sqlite3_vfs *vfs, sqlite3_filename zName,
.xLock = os_lock,
.xUnlock = os_unlock,
.xCheckReservedLock = os_check_reserved_lock,
.xFileControl = no_file_control,
.xDeviceCharacteristics = no_device_characteristics,
.xFileControl = os_file_control_w,
.xSectorSize = os_sector_size,
.xDeviceCharacteristics = os_device_characteristics,
};
memset(file, 0, sizeof(struct os_file));
int rc = os_open(vfs, zName, file, flags, pOutFlags);
file->pMethods = (char)rc == SQLITE_OK ? &os_io : NULL;
return rc;
if (rc) {
return rc;
}
struct os_file *pFile = (struct os_file *)file;
pFile->base.pMethods = &os_io;
if (flags & SQLITE_OPEN_MAIN_DB) {
pFile->psow =
sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE);
}
return SQLITE_OK;
}
sqlite3_vfs *os_vfs() {
@@ -90,3 +138,7 @@ sqlite3_vfs *os_vfs() {
};
return &os_vfs;
}
int localtime_s(struct tm *const pTm, time_t const *const pTime) {
return os_localtime((sqlite3_int64)*pTime, pTm);
}