MemoryVFS journal.

This commit is contained in:
Nuno Cruces
2023-05-31 03:24:21 +01:00
parent 830240c368
commit dc3dc6853d
12 changed files with 54 additions and 51 deletions

Binary file not shown.

20
sqlite3/deserialize.patch Normal file
View File

@@ -0,0 +1,20 @@
--- sqlite3.c.orig
+++ sqlite3.c
@@ -60425,7 +60425,7 @@
int rc = SQLITE_OK; /* Return code */
int tempFile = 0; /* True for temp files (incl. in-memory files) */
int memDb = 0; /* True if this is an in-memory file */
-#ifndef SQLITE_OMIT_DESERIALIZE
+#if 1
int memJM = 0; /* Memory journal mode */
#else
# define memJM 0
@@ -60628,7 +60628,7 @@
int fout = 0; /* VFS flags returned by xOpen() */
rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout);
assert( !memDb );
-#ifndef SQLITE_OMIT_DESERIALIZE
+#if 1
pPager->memVfs = memJM = (fout&SQLITE_OPEN_MEMORY)!=0;
#endif
readOnly = (fout&SQLITE_OPEN_READONLY)!=0;

View File

@@ -8,6 +8,9 @@ unzip -d . sqlite-amalgamation-*.zip
mv sqlite-amalgamation-*/sqlite3* .
rm -rf sqlite-amalgamation-*
patch < vfs_find.patch
patch < deserialize.patch
cd ext/
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.42.0/ext/misc/decimal.c"
curl -#OL "https://github.com/sqlite/sqlite/raw/version-3.42.0/ext/misc/uint.c"

View File

@@ -30,6 +30,9 @@
// Other Options
#define SQLITE_ALLOW_URI_AUTHORITY
#define SQLITE_ENABLE_BATCH_ATOMIC_WRITE
#define SQLITE_ENABLE_ATOMIC_WRITE
#define SQLITE_OMIT_DESERIALIZE
// Because WASM does not support shared memory,
// SQLite disables WAL for WASM builds.
@@ -55,16 +58,5 @@
// #define SQLITE_ENABLE_SESSION
// #define SQLITE_ENABLE_PREUPDATE_HOOK
// https://stackoverflow.com/a/50616684
#define SECOND(...) SECOND_I(__VA_ARGS__, , )
#define SECOND_I(A, B, ...) B
#define GLUE(A, B) GLUE_I(A, B)
#define GLUE_I(A, B) A##_##B
#define CREATE_REPLACER(A) SECOND(GLUE(A, __LINE__), A)
#define REPLACE_AT_LINE(A) , A
// Implemented in vfs.c.
int localtime_s(struct tm *const pTm, time_t const *const pTime);
#define sqlite3_vfs_find CREATE_REPLACER(sqlite3_vfs_find_wrapper)
#define sqlite3_vfs_find_wrapper_25397 REPLACE_AT_LINE(sqlite3_vfs_find)
int localtime_s(struct tm *const pTm, time_t const *const pTime);

View File

@@ -87,8 +87,7 @@ int localtime_s(struct tm *const pTm, time_t const *const pTime) {
return go_localtime(pTm, (sqlite3_int64)*pTime);
}
#undef sqlite3_vfs_find
sqlite3_vfs *sqlite3_vfs_find_wrapper(const char *zVfsName) {
sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName) {
if (zVfsName) {
static sqlite3_vfs *go_vfs_list;
sqlite3_vfs *found = NULL;
@@ -130,7 +129,7 @@ sqlite3_vfs *sqlite3_vfs_find_wrapper(const char *zVfsName) {
return go_vfs_list;
}
}
return sqlite3_vfs_find(zVfsName);
return sqlite3_vfs_find_orig(zVfsName);
}
static_assert(offsetof(struct go_file, handle) == 4, "Unexpected offset");

11
sqlite3/vfs_find.patch Normal file
View File

@@ -0,0 +1,11 @@
--- sqlite3.c.orig
+++ sqlite3.c
@@ -25394,7 +25394,7 @@
** Locate a VFS by name. If no name is given, simply return the
** first VFS on the list.
*/
-SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){
+SQLITE_API sqlite3_vfs *sqlite3_vfs_find_orig(const char *zVfs){
sqlite3_vfs *pVfs = 0;
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex;

View File

@@ -22,7 +22,7 @@ func ExampleMemoryVFS_embed() {
"test.db": sqlite3vfs.NewMemoryDB(testDB),
})
db, err := sql.Open("sqlite3", "file:test.db?vfs=memory&_pragma=journal_mode(memory)")
db, err := sql.Open("sqlite3", "file:test.db?vfs=memory")
if err != nil {
log.Fatal(err)
}

View File

@@ -21,7 +21,7 @@ func (vfs MemoryVFS) Open(name string, flags OpenFlag) (File, OpenFlag, error) {
return &memoryFile{
MemoryDB: db,
readOnly: flags&OPEN_READONLY != 0,
}, flags, nil
}, flags | OPEN_MEMORY, nil
}
return nil, flags, _CANTOPEN
}
@@ -45,8 +45,7 @@ const memSectorSize = 65536
// A MemoryDB is a [MemoryVFS] database.
//
// A MemoryDB is safe to access concurrently from multiple SQLite connections.
// It requires journal mode MEMORY or OFF.
// A MemoryDB is safe to access concurrently through multiple SQLite connections.
type MemoryDB struct {
MaxSize int64
@@ -60,16 +59,16 @@ type MemoryDB struct {
shared int
}
// NewMemoryDB creates a new MemoryDB using buf as its initial contents.
// The new MemoryDB takes ownership of buf, and the caller should not use buf after this call.
func NewMemoryDB(buf []byte) *MemoryDB {
// NewMemoryDB creates a new MemoryDB using mem as its initial contents.
// The new MemoryDB takes ownership of mem, and the caller should not use mem after this call.
func NewMemoryDB(mem []byte) *MemoryDB {
m := new(MemoryDB)
m.size = int64(len(buf))
m.size = int64(len(mem))
sectors := divRoundUp(m.size, memSectorSize)
m.data = make([]*[memSectorSize]byte, sectors)
for i := range m.data {
sector := buf[i*memSectorSize:]
sector := mem[i*memSectorSize:]
if len(sector) >= memSectorSize {
m.data[i] = (*[memSectorSize]byte)(sector)
} else {

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:aafb873c26d32dbf7498e4c4dd243eb6411c056432818121463d8cb49bc15f70
size 1479293
oid sha256:fab92aa470cc311d0cda364e21594ac57f25efce679920f65dd681f027ec9629
size 1477051

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2638f5458f93b60f97006456f60e3e294cffb9ac22b20dba748fbd12e34f056d
size 1515841
oid sha256:61adff257e8f6035c3fc7fd6371f4ac14c66ae5622202f6567244d18757375b2
size 1513558

View File

@@ -24,7 +24,7 @@ func TestDB_VFS(t *testing.T) {
"test.db": &sqlite3vfs.MemoryDB{},
})
defer sqlite3vfs.Unregister("memvfs")
testDB(t, "file:test.db?vfs=memvfs&_pragma=journal_mode(memory)")
testDB(t, "file:test.db?vfs=memvfs")
}
func testDB(t *testing.T, name string) {

View File

@@ -31,34 +31,13 @@ func TestMemoryVFS_Open_notfound(t *testing.T) {
}
}
func TestMemoryVFS_Open_journal(t *testing.T) {
sqlite3vfs.Register("memory", sqlite3vfs.MemoryVFS{
"test.db": &sqlite3vfs.MemoryDB{},
})
defer sqlite3vfs.Unregister("memory")
db, err := sqlite3.Open("file:test.db?vfs=memory")
if err != nil {
t.Fatal(err)
}
defer db.Close()
err = db.Exec(`CREATE TABLE IF NOT EXISTS test (col)`)
if err == nil {
t.Error("want error")
}
if !errors.Is(err, sqlite3.CANTOPEN) {
t.Errorf("got %v, want sqlite3.CANTOPEN", err)
}
}
func TestMemoryVFS_Open_errors(t *testing.T) {
sqlite3vfs.Register("memory", sqlite3vfs.MemoryVFS{
"test.db": &sqlite3vfs.MemoryDB{MaxSize: 65536},
})
defer sqlite3vfs.Unregister("memory")
db, err := sqlite3.Open("file:test.db?vfs=memory&_pragma=journal_mode(memory)")
db, err := sqlite3.Open("file:test.db?vfs=memory")
if err != nil {
t.Fatal(err)
}