mirror of
https://github.com/ncruces/go-sqlite3.git
synced 2026-01-12 22:19:14 +00:00
xFileControl, xDeviceCharacteristics, PSOW.
This commit is contained in:
@@ -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);
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
94
sqlite3/os.c
94
sqlite3/os.c
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user