1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-27 20:41:58 +03:00

Merge kv-vfs branch into fiddle-opfs branch to add kvvfs-based wasm build and demo.

FossilOrigin-Name: a7d8b26acd3c1ae344369e4d70804c0cab45272c0983cfd32d616a0a7b28acb9
This commit is contained in:
stephan
2022-09-12 16:09:50 +00:00
19 changed files with 1494 additions and 319 deletions

View File

@ -184,7 +184,7 @@ LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \
main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \
memdb.lo memjournal.lo \
mutex.lo mutex_noop.lo mutex_unix.lo mutex_w32.lo \
notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \
notify.lo opcodes.lo os.lo os_kv.lo os_unix.lo os_win.lo \
pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
random.lo resolve.lo rowset.lo rtree.lo \
sqlite3session.lo select.lo sqlite3rbu.lo status.lo stmt.lo \
@ -257,6 +257,7 @@ SRC = \
$(TOP)/src/os.h \
$(TOP)/src/os_common.h \
$(TOP)/src/os_setup.h \
$(TOP)/src/os_kv.c \
$(TOP)/src/os_unix.c \
$(TOP)/src/os_win.c \
$(TOP)/src/os_win.h \
@ -492,6 +493,7 @@ TESTSRC2 = \
$(TOP)/src/main.c \
$(TOP)/src/mem5.c \
$(TOP)/src/os.c \
$(TOP)/src/os_kv.c \
$(TOP)/src/os_unix.c \
$(TOP)/src/os_win.c \
$(TOP)/src/pager.c \
@ -938,6 +940,9 @@ pcache1.lo: $(TOP)/src/pcache1.c $(HDR) $(TOP)/src/pcache.h
os.lo: $(TOP)/src/os.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os.c
os_kv.lo: $(TOP)/src/os_kv.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_kv.c
os_unix.lo: $(TOP)/src/os_unix.c $(HDR)
$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/os_unix.c

View File

@ -380,6 +380,8 @@ speedtest1: $(speedtest1.js)
all: $(speedtest1.js)
CLEAN_FILES += $(speedtest1.js) $(speedtest1.wasm)
# end speedtest1.js
########################################################################
########################################################################
# fiddle_remote is the remote destination for the fiddle app. It
# must be a [user@]HOST:/path for rsync.
@ -402,3 +404,5 @@ push-fiddle: $(fiddle_files)
rsync -va fiddle/ $(fiddle_remote)
# end fiddle remote push
########################################################################
include kvvfs.make

View File

@ -39,7 +39,7 @@ if('undefined' !== typeof Module){ // presumably an Emscripten build
delete self.sqlite3ApiBootstrap;
if(self.location && +self.location.port > 1024){
console.warn("Installing sqlite3 bits as global S for dev-testing purposes.");
console.warn("Installing sqlite3 bits as global S for local dev/test purposes.");
self.S = sqlite3;
}

View File

@ -70,6 +70,74 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
const toss3 = (...args)=>{throw new SQLite3Error(...args)};
sqlite3.SQLite3Error = SQLite3Error;
// Documented in DB.checkRc()
const checkSqlite3Rc = function(dbPtr, sqliteResultCode){
if(sqliteResultCode){
if(dbPtr instanceof DB) dbPtr = dbPtr.pointer;
throw new SQLite3Error(
"sqlite result code",sqliteResultCode+":",
(dbPtr
? capi.sqlite3_errmsg(dbPtr)
: capi.sqlite3_errstr(sqliteResultCode))
);
}
};
/**
A proxy for DB class constructors. It must be called with the
being-construct DB object as its "this".
*/
const dbCtorHelper = function ctor(fn=':memory:', flags='c', vfsName){
if(!ctor._name2vfs){
// Map special filenames which we handle here (instead of in C)
// to some helpful metadata...
ctor._name2vfs = Object.create(null);
const isWorkerThread = (self.window===self /*===running in main window*/)
? false
: (n)=>toss3("The VFS for",n,"is only available in the main window thread.")
ctor._name2vfs[':localStorage:'] = {
vfs: 'kvvfs',
filename: isWorkerThread || (()=>'local')
};
ctor._name2vfs[':sessionStorage:'] = {
vfs: 'kvvfs',
filename: isWorkerThread || (()=>'session')
};
}
if('string'!==typeof fn){
toss3("Invalid filename for DB constructor.");
}
const vfsCheck = ctor._name2vfs[fn];
if(vfsCheck){
vfsName = vfsCheck.vfs;
fn = vfsCheck.filename(fn);
}
let ptr, oflags = 0;
if( flags.indexOf('c')>=0 ){
oflags |= capi.SQLITE_OPEN_CREATE | capi.SQLITE_OPEN_READWRITE;
}
if( flags.indexOf('w')>=0 ) oflags |= capi.SQLITE_OPEN_READWRITE;
if( 0===oflags ) oflags |= capi.SQLITE_OPEN_READONLY;
oflags |= capi.SQLITE_OPEN_EXRESCODE;
const stack = capi.wasm.scopedAllocPush();
try {
const ppDb = capi.wasm.scopedAllocPtr() /* output (sqlite3**) arg */;
const pVfsName = vfsName ? capi.wasm.scopedAllocCString(vfsName) : 0;
const rc = capi.sqlite3_open_v2(fn, ppDb, oflags, pVfsName);
ptr = capi.wasm.getPtrValue(ppDb);
checkSqlite3Rc(ptr, rc);
}catch( e ){
if( ptr ) capi.sqlite3_close_v2(ptr);
throw e;
}finally{
capi.wasm.scopedAllocPop(stack);
}
this.filename = fn;
__ptrMap.set(this, ptr);
__stmtMap.set(this, Object.create(null));
__udfMap.set(this, Object.create(null));
};
/**
The DB class provides a high-level OO wrapper around an sqlite3
db handle.
@ -102,42 +170,29 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
"c". These modes are ignored for the special ":memory:" and ""
names.
The final argument is currently unimplemented but will eventually
be used to specify an optional sqlite3 VFS implementation name,
as for the final argument to sqlite3_open_v2().
The final argument is analogous to the final argument of
sqlite3_open_v2(): the name of an sqlite3 VFS. Pass a falsy value,
or not at all, to use the default. If passed a value, it must
be the string name of a VFS
For purposes of passing a DB instance to C-style sqlite3
functions, the DB object's read-only `pointer` property holds its
`sqlite3*` pointer value. That property can also be used to check
whether this DB instance is still open.
EXPERIMENTAL: in the main window thread, the filenames
":localStorage:" and ":sessionStorage:" are special: they cause
the db to use either localStorage or sessionStorage for storing
the database. In this mode, only a single database is permitted
in each storage object. This feature is experimental and subject
to any number of changes (including outright removal). This
support requires a specific build of sqlite3, the existence of
which can be determined at runtime by checking for a non-0 return
value from sqlite3.capi.sqlite3_vfs_find("kvvfs").
*/
const DB = function ctor(fn=':memory:', flags='c', vtab="not yet implemented"){
if('string'!==typeof fn){
toss3("Invalid filename for DB constructor.");
}
let ptr, oflags = 0;
if( flags.indexOf('c')>=0 ){
oflags |= capi.SQLITE_OPEN_CREATE | capi.SQLITE_OPEN_READWRITE;
}
if( flags.indexOf('w')>=0 ) oflags |= capi.SQLITE_OPEN_READWRITE;
if( 0===oflags ) oflags |= capi.SQLITE_OPEN_READONLY;
oflags |= capi.SQLITE_OPEN_EXRESCODE;
const stack = capi.wasm.scopedAllocPush();
try {
const ppDb = capi.wasm.scopedAllocPtr() /* output (sqlite3**) arg */;
const rc = capi.sqlite3_open_v2(fn, ppDb, oflags, null);
ptr = capi.wasm.getPtrValue(ppDb);
ctor.checkRc(ptr, rc);
}catch( e ){
if( ptr ) capi.sqlite3_close_v2(ptr);
throw e;
}finally{
capi.wasm.scopedAllocPop(stack);
}
this.filename = fn;
__ptrMap.set(this, ptr);
__stmtMap.set(this, Object.create(null));
__udfMap.set(this, Object.create(null));
const DB = function ctor(fn=':memory:', flags='c', vfsName){
dbCtorHelper.apply(this, Array.prototype.slice.call(arguments));
};
/**
@ -232,6 +287,8 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}else if(args[0] && 'object'===typeof args[0]){
out.opt = args[0];
out.sql = out.opt.sql;
}else if(Array.isArray(args[0])){
out.sql = args[0];
}
break;
case 2:
@ -295,17 +352,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
non-0 non-error codes need to be checked for in
client code where they are expected.
*/
DB.checkRc = function(dbPtr, sqliteResultCode){
if(sqliteResultCode){
if(dbPtr instanceof DB) dbPtr = dbPtr.pointer;
throw new SQLite3Error(
"sqlite result code",sqliteResultCode+":",
(dbPtr
? capi.sqlite3_errmsg(dbPtr)
: capi.sqlite3_errstr(sqliteResultCode))
);
}
};
DB.checkRc = checkSqlite3Rc;
DB.prototype = {
/**
@ -1532,5 +1579,19 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
DB,
Stmt
}/*oo1 object*/;
if( self.window===self && 0!==capi.sqlite3_vfs_find('kvvfs') ){
/* In the main window thread, add a couple of convenience proxies
for localStorage and sessionStorage DBs... */
let klass = sqlite3.oo1.LocalStorageDb = function(){
dbCtorHelper.call(this, 'local', 'c', 'kvvfs');
};
klass.prototype = DB.prototype;
klass = sqlite3.oo1.SessionStorageDb = function(){
dbCtorHelper.call(this, 'session', 'c', 'kvvfs');
};
klass.prototype = DB.prototype;
}
});

View File

@ -713,7 +713,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
return __persistentDir = "";
}
try{
if(pdir && 0===this.wasm.xCallWrapped(
if(pdir && 0===capi.wasm.xCallWrapped(
'sqlite3_wasm_init_opfs', 'i32', ['string'], pdir
)){
/** OPFS does not support locking and will trigger errors if
@ -736,7 +736,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
// sqlite3_wasm_init_opfs() is not available
return __persistentDir = "";
}
}.bind(capi);
};
/**
Returns true if sqlite3.capi.sqlite3_web_persistent_dir() is a
@ -744,9 +744,15 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
prefix, else returns false.
*/
capi.sqlite3_web_filename_is_persistent = function(name){
const p = this.sqlite3_web_persistent_dir();
const p = capi.sqlite3_web_persistent_dir();
return (p && name) ? name.startsWith(p) : false;
}.bind(capi);
};
if(0===capi.wasm.exports.sqlite3_vfs_find(0)){
/* Assume that sqlite3_initialize() has not yet been called.
This will be the case in an SQLITE_OS_KV build. */
capi.wasm.exports.sqlite3_initialize();
}
/* The remainder of the API will be set up in later steps. */
const sqlite3 = {

View File

@ -523,226 +523,5 @@ int sqlite3_wasm_init_opfs(void){
}
#endif /* __EMSCRIPTEN__ && SQLITE_WASM_OPFS */
#if defined(__EMSCRIPTEN__) // && defined(SQLITE_OS_KV)
#include <emscripten.h>
#include <emscripten/console.h>
#ifndef KVSTORAGE_KEY_SZ
/* We can remove this once kvvfs and this bit is merged. */
# define KVSTORAGE_KEY_SZ 32
static void kvstorageMakeKey(
const char *zClass,
const char *zKeyIn,
char *zKeyOut
){
sqlite3_snprintf(KVSTORAGE_KEY_SZ, zKeyOut, "kvvfs-%s-%s", zClass, zKeyIn);
}
#endif
/*
** An internal level of indirection for accessing the static
** kvstorageMakeKey() from EM_JS()-generated functions. This must be
** made available for export via Emscripten but is not intended to be
** used from client code. If called with a NULL zKeyOut it is a no-op.
** It returns KVSTORAGE_KEY_SZ, so JS code (which cannot see that
** constant) may call it with NULL arguments to get the size of the
** allocation they'll need for a kvvfs key.
**
** Maintenance reminder: Emscripten will install this in the Module
** init scope and will prefix its name with "_".
*/
WASM_KEEP
int sqlite3_wasm__kvvfsMakeKey(const char *zClass,
const char *zKeyIn,
char *zKeyOut){
if(zKeyOut) kvstorageMakeKey(zClass, zKeyIn, zKeyOut);
return KVSTORAGE_KEY_SZ;
}
#if 0
/*
** Alternately, we can implement kvstorageMakeKey() in JS in such a
** way that it's visible to kvstorageWrite/Delete/Read() but not the
** rest of the world. This impl is considerably more verbose than the
** C impl because writing directly to memory requires more code in
** JS. Though more verbose, this approach enables removal of
** sqlite3_wasm__kvvfsMakeKey(). The only catch is that the
** KVSTORAGE_KEY_SZ constant has to be hard-coded into this function.
*/
EM_JS(void, kvstorageMakeKeyJS,
(const char *zClass, const char *zKeyIn, char *zKeyOut),{
const max = 32;
if(!arguments.length) return max;
let n = 0, i = 0, ch = 0;
// Write key prefix to dest...
if(0){
const prefix = "kvvfs-";
for(i in prefix) setValue(zKeyOut+(n++), prefix.charCodeAt(i));
}else{
// slightly optimized but less readable...
setValue(zKeyOut + (n++), 107/*'k'*/);
setValue(zKeyOut + (n++), 118/*'v'*/);
setValue(zKeyOut + (n++), 118/*'v'*/);
setValue(zKeyOut + (n++), 102/*'f'*/);
setValue(zKeyOut + (n++), 115/*'s'*/);
setValue(zKeyOut + (n++), 45/*'-'*/);
}
// Write zClass to dest...
for(i = 0; n < max && (ch = getValue(zClass+i)); ++n, ++i){
setValue(zKeyOut + n, ch);
}
// Write "-" separator to dest...
if(n<max) setValue(zKeyOut + (n++), 45/* == '-'*/);
// Write zKeyIn to dest...
for(i = 0; n < max && (ch = getValue(zKeyIn+i)); ++n, ++i){
setValue(zKeyOut + n, ch);
}
// NUL terminate...
if(n<max) setValue(zKeyOut + n, 0);
});
#endif
/*
** Internal helper for kvstorageWrite/Read/Delete() which creates a
** storage key for the given zClass/zKeyIn combination. Returns a
** pointer to the key: a C string allocated on the WASM stack, or 0 if
** allocation fails. It is up to the caller to save/restore the stack
** before/after this operation.
*/
EM_JS(const char *, kvstorageMakeKeyOnJSStack,
(const char *zClass, const char *zKeyIn),{
if( 0==zClass || 0==zKeyIn) return 0;
const zXKey = stackAlloc(_sqlite3_wasm__kvvfsMakeKey(0,0,0));
if(zXKey) _sqlite3_wasm__kvvfsMakeKey(zClass, zKeyIn, zXKey);
return zXKey;
});
/*
** JS impl of kvstorageWrite(). Main docs are in the C impl. This impl
** writes zData to the global sessionStorage (if zClass starts with
** 's') or localStorage, using a storage key derived from zClass and
** zKey.
*/
EM_JS(int, kvstorageWrite,
(const char *zClass, const char *zKey, const char *zData),{
const stack = stackSave();
try {
const zXKey = kvstorageMakeKeyOnJSStack(zClass,zKey);
if(!zXKey) return 1/*OOM*/;
const jKey = UTF8ToString(zXKey);
/**
We could simplify this function and eliminate the
kvstorageMakeKey() symbol acrobatics if we'd simply hard-code
the key algo into the 3 functions which need it:
const jKey = "kvvfs-"+UTF8ToString(zClass)+"-"+UTF8ToString(zKey);
*/
((115/*=='s'*/===getValue(zClass))
? sessionStorage : localStorage).setItem(jKey, UTF8ToString(zData));
}catch(e){
console.error("kvstorageWrite()",e);
return 1; // Can't access SQLITE_xxx from here
}finally{
stackRestore(stack);
}
return 0;
});
/*
** JS impl of kvstorageDelete(). Main docs are in the C impl. This
** impl generates a key derived from zClass and zKey, and removes the
** matching entry (if any) from global sessionStorage (if zClass
** starts with 's') or localStorage.
*/
EM_JS(int, kvstorageDelete,
(const char *zClass, const char *zKey),{
const stack = stackSave();
try {
const zXKey = kvstorageMakeKeyOnJSStack(zClass,zKey);
if(!zXKey) return 1/*OOM*/;
_sqlite3_wasm__kvvfsMakeKey(zClass, zKey, zXKey);
const jKey = UTF8ToString(zXKey);
((115/*=='s'*/===getValue(zClass))
? sessionStorage : localStorage).removeItem(jKey);
}catch(e){
console.error("kvstorageDelete()",e);
return 1;
}finally{
stackRestore(stack);
}
return 0;
});
/*
** JS impl of kvstorageRead(). Main docs are in the C impl. This impl
** reads its data from the global sessionStorage (if zClass starts
** with 's') or localStorage, using a storage key derived from zClass
** and zKey.
*/
EM_JS(int, kvstorageRead,
(const char *zClass, const char *zKey, char *zBuf, int nBuf),{
const stack = stackSave();
try {
const zXKey = kvstorageMakeKeyOnJSStack(zClass,zKey);
if(!zXKey) return -3/*OOM*/;
const jKey = UTF8ToString(zXKey);
const jV = ((115/*=='s'*/===getValue(zClass))
? sessionStorage : localStorage).getItem(jKey);
if(!jV) return -1;
const nV = jV.length /* Note that we are relying 100% on v being
ASCII so that jV.length is equal to the
C-string's byte length. */;
if(nBuf<=0) return nV;
else if(1===nBuf){
setValue(zBuf, 0);
return nV;
}
const zV = allocateUTF8OnStack(jV);
if(nBuf > nV + 1) nBuf = nV + 1;
HEAPU8.copyWithin(zBuf, zV, zV + nBuf - 1);
setValue( zBuf + nBuf - 1, 0 );
return nBuf - 1;
}catch(e){
console.error("kvstorageRead()",e);
return -2;
}finally{
stackRestore(stack);
}
});
/*
** This function exists for (1) WASM testing purposes and (2) as a
** hook to get Emscripten to export several EM_JS()-generated
** functions. It is not part of the public API and its signature
** and semantics may change at any time.
*/
WASM_KEEP
int sqlite3_wasm__emjs_keep(int whichOp){
int rc = 0;
const char * zClass = "session";
const char * zKey = "hello";
switch( whichOp ){
case 0: break;
case 1:
kvstorageWrite(zClass, zKey, "world");
break;
case 2: {
char buffer[128] = {0};
char * zBuf = &buffer[0];
rc = kvstorageRead(zClass, zKey, zBuf, (int)sizeof(buffer));
emscripten_console_logf("kvstorageRead()=%d %s\n", rc, zBuf);
break;
}
case 3:
kvstorageDelete(zClass, zKey);
break;
case 4:
kvstorageMakeKeyOnJSStack(0,0) /* force Emscripten to include this */;
break;
default: break;
}
return rc;
}
#endif /* ifdef __EMSCRIPTEN__ (kvvfs method impls) */
#undef WASM_KEEP

View File

@ -39,6 +39,8 @@
<li><a href='speedtest1.html'>speedtest1</a>: a main-thread WASM build of speedtest1.</li>
<li><a href='speedtest1-worker.html'>speedtest1-worker</a>: an interactive Worker-thread variant of speedtest1.</li>
<li><a href='demo-oo1.html'>demo-oo1</a>: demonstration of the OO API #1.</li>
<li><a href='kvvfs1.html'>kvvfs1</a>: very basic demo of using the key-value vfs for storing
a persistent db in JS localStorage or sessionStorage.</li>
<!--li><a href='x.html'></a></li-->
</ul>
</div>

84
ext/wasm/kvvfs.make Normal file
View File

@ -0,0 +1,84 @@
#!/usr/bin/make
#^^^^ help emacs select makefile mode
#
# This is a sub-make for building a standalone kvvfs-based
# sqlite3.wasm. It is intended to be "include"d from the main
# GNUMakefile.
#
# Notable potential TODOs:
#
# - Trim down a custom sqlite3-api.js for this build. We can elimate
# the jaccwabyt dependency, for example, because this build won't
# make use of the VFS bits. Similarly, we can eliminate or replace
# parts of the OO1 API, or provide a related API which manages
# singletons of the localStorage/sessionStorage instances.
#
########################################################################
MAKEFILE.kvvfs := $(lastword $(MAKEFILE_LIST))
kvvfs.js := sqlite3-kvvfs.js
kvvfs.wasm := sqlite3-kvvfs.wasm
kvvfs.wasm.c := $(dir.api)/sqlite3-wasm.c
CLEAN_FILES += $(kvvfs.js) $(kvvfs.wasm)
########################################################################
# emcc flags for .c/.o/.wasm.
kvvfs.flags =
#kvvfs.flags += -v # _very_ loud but also informative about what it's doing
########################################################################
# emcc flags for .c/.o.
kvvfs.cflags :=
kvvfs.cflags += -std=c99 -fPIC -g
kvvfs.cflags += -I. -I$(dir.top)
kvvfs.cflags += -DSQLITE_OS_KV=1 $(SQLITE_OPT)
########################################################################
# emcc flags specific to building the final .js/.wasm file...
kvvfs.jsflags := -fPIC
kvvfs.jsflags += --no-entry
kvvfs.jsflags += --minify 0
kvvfs.jsflags += -sENVIRONMENT=web
kvvfs.jsflags += -sMODULARIZE
kvvfs.jsflags += -sSTRICT_JS
kvvfs.jsflags += -sDYNAMIC_EXECUTION=0
kvvfs.jsflags += -sNO_POLYFILL
kvvfs.jsflags += -sEXPORTED_FUNCTIONS=@$(dir.api)/EXPORTED_FUNCTIONS.sqlite3-api
kvvfs.jsflags += -sEXPORTED_RUNTIME_METHODS=FS,wasmMemory,allocateUTF8OnStack
# wasmMemory ==> for -sIMPORTED_MEMORY
# allocateUTF8OnStack ==> kvvfs internals
kvvfs.jsflags += -sUSE_CLOSURE_COMPILER=0
kvvfs.jsflags += -sIMPORTED_MEMORY
#kvvfs.jsflags += -sINITIAL_MEMORY=13107200
#kvvfs.jsflags += -sTOTAL_STACK=4194304
kvvfs.jsflags += -sEXPORT_NAME=sqlite3InitModule
kvvfs.jsflags += -sGLOBAL_BASE=4096 # HYPOTHETICALLY keep func table indexes from overlapping w/ heap addr.
kvvfs.jsflags += --post-js=$(post-js.js)
#kvvfs.jsflags += -sFILESYSTEM=0 # only for experimentation. sqlite3 needs the FS API
# Perhaps the kvvfs build doesn't?
#kvvfs.jsflags += -sABORTING_MALLOC
kvvfs.jsflags += -sALLOW_MEMORY_GROWTH
kvvfs.jsflags += -sALLOW_TABLE_GROWTH
kvvfs.jsflags += -Wno-limited-postlink-optimizations
# ^^^^^ it likes to warn when we have "limited optimizations" via the -g3 flag.
kvvfs.jsflags += -sERROR_ON_UNDEFINED_SYMBOLS=0
kvvfs.jsflags += -sLLD_REPORT_UNDEFINED
#kvvfs.jsflags += --import-undefined
kvvfs.jsflags += -sMEMORY64=0
ifneq (0,$(enable_bigint))
kvvfs.jsflags += -sWASM_BIGINT
endif
$(kvvfs.js): $(MAKEFILE) $(MAKEFILE.kvvfs) $(kvvfs.wasm.c) \
EXPORTED_FUNCTIONS.api \
$(post-js.js)
$(emcc.bin) -o $@ $(emcc_opt) $(emcc.flags) $(kvvfs.cflags) $(kvvfs.jsflags) $(kvvfs.wasm.c)
chmod -x $(kvvfs.wasm)
ifneq (,$(wasm-strip))
$(wasm-strip) $(kvvfs.wasm)
endif
@ls -la $@ $(kvvfs.wasm)
kvvfs: $(kvvfs.js)
all: kvvfs

43
ext/wasm/kvvfs1.html Normal file
View File

@ -0,0 +1,43 @@
<!doctype html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon">
<link rel="stylesheet" href="common/emscripten.css"/>
<link rel="stylesheet" href="common/testing.css"/>
<title>sqlite3-kvvfs.js tests</title>
</head>
<body>
<header id='titlebar'><span>sqlite3-kvvfs.js tests</span></header>
<!-- emscripten bits -->
<figure id="module-spinner">
<div class="spinner"></div>
<div class='center'><strong>Initializing app...</strong></div>
<div class='center'>
On a slow internet connection this may take a moment. If this
message displays for "a long time", intialization may have
failed and the JavaScript console may contain clues as to why.
</div>
</figure>
<div class="emscripten" id="module-status">Downloading...</div>
<div class="emscripten">
<progress value="0" max="100" id="module-progress" hidden='1'></progress>
</div><!-- /emscripten bits -->
<div>Everything on this page happens in the dev console. TODOs for this demo include,
but are not necessarily limited to:
<ul>
<li>UI controls to switch between localStorage and sessionStorage</li>
<li>Button to clear storage.</li>
<li>Button to dump the current db contents.</li>
<!--li></li-->
</ul>
</div>
<hr>
<div id='test-output'></div>
<script src="sqlite3-kvvfs.js"></script>
<script src="common/SqliteTestUtil.js"></script>
<script src="kvvfs1.js"></script>
</body>
</html>

73
ext/wasm/kvvfs1.js Normal file
View File

@ -0,0 +1,73 @@
/*
2022-09-12
The author disclaims copyright to this source code. In place of a
legal notice, here is a blessing:
* May you do good and not evil.
* May you find forgiveness for yourself and forgive others.
* May you share freely, never taking more than you give.
***********************************************************************
A basic test script for sqlite3-kvvfs.wasm. This file must be run in
main JS thread and sqlite3-kvvfs.js must have been loaded before it.
*/
'use strict';
(function(){
const T = self.SqliteTestUtil;
const toss = function(...args){throw new Error(args.join(' '))};
const debug = console.debug.bind(console);
const eOutput = document.querySelector('#test-output');
const log = console.log.bind(console)
const logHtml = function(...args){
log.apply(this, args);
const ln = document.createElement('div');
ln.append(document.createTextNode(args.join(' ')));
eOutput.append(ln);
};
const runTests = function(Module){
//log("Module",Module);
const sqlite3 = Module.sqlite3,
capi = sqlite3.capi,
oo = sqlite3.oo1,
wasm = capi.wasm;
log("Loaded module:",capi.sqlite3_libversion(), capi.sqlite3_sourceid());
log("Build options:",wasm.compileOptionUsed());
T.assert( 0 !== capi.sqlite3_vfs_find(null) );
const dbStorage = 1 ? ':sessionStorage:' : ':localStorage:';
/**
The names ':sessionStorage:' and ':localStorage:' are handled
via the DB class constructor, not the C level. In the C API,
the names "local" and "session" are the current (2022-09-12)
names for those keys, but that is subject to change.
*/
const db = new oo.DB( dbStorage );
log("Storage backend:",db.filename /* note that the name was internally translated */);
try {
db.exec("create table if not exists t(a)");
if(undefined===db.selectValue("select a from t limit 1")){
log("New db. Populating. This DB will persist across page reloads.");
db.exec("insert into t(a) values(1),(2),(3)");
}else{
log("Found existing table data:");
db.exec({
sql: "select * from t order by a",
rowMode: 0,
callback: function(v){log(v)}
});
}
}finally{
db.close();
}
log("End of demo.");
};
sqlite3InitModule(self.sqlite3TestModule).then(function(theModule){
console.warn("Installing Emscripten module as global EM for dev console access.");
self.EM = theModule;
runTests(theModule);
});
})();

View File

@ -68,7 +68,7 @@ LIBOBJ+= vdbe.o parse.o \
main.o malloc.o mem0.o mem1.o mem2.o mem3.o mem5.o \
memdb.o memjournal.o \
mutex.o mutex_noop.o mutex_unix.o mutex_w32.o \
notify.o opcodes.o os.o os_unix.o os_win.o \
notify.o opcodes.o os.o os_kv.o os_unix.o os_win.o \
pager.o pcache.o pcache1.o pragma.o prepare.o printf.o \
random.o resolve.o rowset.o rtree.o \
select.o sqlite3rbu.o status.o stmt.o \
@ -134,6 +134,7 @@ SRC = \
$(TOP)/src/os.h \
$(TOP)/src/os_common.h \
$(TOP)/src/os_setup.h \
$(TOP)/src/os_kv.c \
$(TOP)/src/os_unix.c \
$(TOP)/src/os_win.c \
$(TOP)/src/os_win.h \
@ -411,6 +412,7 @@ TESTSRC2 = \
$(TOP)/src/main.c \
$(TOP)/src/mem5.c \
$(TOP)/src/os.c \
$(TOP)/src/os_kv.c \
$(TOP)/src/os_unix.c \
$(TOP)/src/os_win.c \
$(TOP)/src/pager.c \

View File

@ -1,9 +1,9 @@
C Minor\scleanups\sand\sdocumentation\sin\sthe\swasm\spieces.
D 2022-09-11T16:59:40.674
C Merge\skv-vfs\sbranch\sinto\sfiddle-opfs\sbranch\sto\sadd\skvvfs-based\swasm\sbuild\sand\sdemo.
D 2022-09-12T16:09:50.625
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F Makefile.in 918d18842ba16dac5ebd5f7913aa8fb4f39879c881deced83362ed44a14ab4c6
F Makefile.in 50e421194df031f669667fdb238c54959ecbea5a0b97dd3ed776cffbeea926d5
F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241
F Makefile.msc d547a2fdba38a1c6cd1954977d0b0cc017f5f8fbfbc65287bf8d335808938016
F README.md 8b8df9ca852aeac4864eb1e400002633ee6db84065bd01b78c33817f97d31f5e
@ -474,21 +474,21 @@ F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb
F ext/wasm/EXPORTED_FUNCTIONS.fiddle db7a4602f043cf4a5e4135be3609a487f9f1c83f05778bfbdf93766be4541b96
F ext/wasm/EXPORTED_RUNTIME_METHODS.fiddle a004bd5eeeda6d3b28d16779b7f1a80305bfe009dfc7f0721b042967f0d39d02
F ext/wasm/GNUmakefile 18b80a063c684b0ca44b96221fc2c23647d0196f757c83c7a572b853562d8ac9
F ext/wasm/GNUmakefile 6e642a0dc7ac43d9287e8f31c80ead469ddc7475a6d4ab7ac3b1feefcd4f7279
F ext/wasm/README.md e1ee1e7c321c6a250bf78a84ca6f5882890a237a450ba5a0649c7a8399194c52
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api 1dfd067b3cbd9a49cb204097367cf2f8fe71b5a3b245d9d82a24779fd4ac2394
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
F ext/wasm/api/README.md d876597edd2b9542b6ea031adaaff1c042076fde7b670b1dc6d8a87b28a6631b
F ext/wasm/api/post-js-footer.js b64319261d920211b8700004d08b956a6c285f3b0bba81456260a713ed04900c
F ext/wasm/api/post-js-header.js 0e853b78db83cb1c06b01663549e0e8b4f377f12f5a2d9a4a06cb776c003880b
F ext/wasm/api/sqlite3-api-cleanup.js 1a12e64060c2cb0defd34656a76a9b1d7ed58459c290249bb31567c806fd44de
F ext/wasm/api/sqlite3-api-cleanup.js 101919ec261644e2f6f0a59952fd9612127b69ea99b493277b2789ea478f9b6b
F ext/wasm/api/sqlite3-api-glue.js 2bf536a38cde324cf352bc2c575f8e22c6d204d667c0eda5a254ba45318914bc
F ext/wasm/api/sqlite3-api-oo1.js b06a1ac982c7d433396b8304550ce1493a63671a3bf653c3b5646a9075e0ca41
F ext/wasm/api/sqlite3-api-oo1.js a9d8892be246548a9978ace506d108954aa13eb5ce25332975c8377953804ff3
F ext/wasm/api/sqlite3-api-opfs.js 011799db398157cbd254264b6ebae00d7234b93d0e9e810345f213a5774993c0
F ext/wasm/api/sqlite3-api-prologue.js afd753be49ecba4b5bfc3e54929826a01eaf96ac2d8cec575d683e3c5bcc8464
F ext/wasm/api/sqlite3-api-prologue.js 9e37ce4dfd74926d0df80dd7e72e33085db4bcee48e2c21236039be416a7dff2
F ext/wasm/api/sqlite3-api-worker1.js d33062afa045fd4be01ba4abc266801807472558b862b30056211b00c9c347b4
F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
F ext/wasm/api/sqlite3-wasm.c ab8abf26708238a17840cad224bec1511efde6e5b182068f3abf079ba1d83ef6
F ext/wasm/api/sqlite3-wasm.c bf4637cf28463cada4b25f09651943c7ece004b253ef39b7ab68eaa60662aa09
F ext/wasm/batch-runner.html 23209ade7981acce7ecd79d6eff9f4c5a4e8b14ae867ac27cd89b230be640fa6
F ext/wasm/batch-runner.js 2abd146d3e3a66128ac0a2cc39bfd01e9811c9511fa10ec927d6649795f1ee50
F ext/wasm/common/SqliteTestUtil.js 529161a624265ba84271a52db58da022649832fa1c71309fb1e02cc037327a2b
@ -501,11 +501,14 @@ F ext/wasm/fiddle/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d695
F ext/wasm/fiddle/fiddle-worker.js bccf46045be8824752876f3eec01c223be0616ccac184bffd0024cfe7a3262b8
F ext/wasm/fiddle/fiddle.html 550c5aafce40bd218de9bf26192749f69f9b10bc379423ecd2e162bcef885c08
F ext/wasm/fiddle/fiddle.js 4ffcfc9a235beebaddec689a549e9e0dfad6dca5c1f0b41f03468d7e76480686
F ext/wasm/index.html 4f635f986dbc7518280abe0ef537ba41682e35f160fac35a0745cf6c4d223b62
F ext/wasm/index.html 5876ae0442bef5b37fec9a45ee0722798e47ef727723ada742d33554845afa6a
F ext/wasm/jaccwabyt/jaccwabyt.js 0d7f32817456a0f3937fcfd934afeb32154ca33580ab264dab6c285e6dbbd215
F ext/wasm/jaccwabyt/jaccwabyt.md 447cc02b598f7792edaa8ae6853a7847b8178a18ed356afacbdbf312b2588106
F ext/wasm/jaccwabyt/jaccwabyt_test.c 39e4b865a33548f943e2eb9dd0dc8d619a80de05d5300668e9960fff30d0d36f
F ext/wasm/jaccwabyt/jaccwabyt_test.exports 5ff001ef975c426ffe88d7d8a6e96ec725e568d2c2307c416902059339c06f19
F ext/wasm/kvvfs.make dba616578bf91a76370a46494dd68a09c6dff5beb6d5561e2db65a27216e9630
F ext/wasm/kvvfs1.html b8304cd5c7e7ec32c3b15521a95c322d6efdb8d22b3c4156123545dc54e07583
F ext/wasm/kvvfs1.js a5075f98ffecd7d32348697db991fc61342d89aa20651034d1572af61890fb8b
F ext/wasm/scratchpad-opfs-main.html 4565cf194e66188190d35f70e82553e2e2d72b9809b73c94ab67b8cfd14d2e0c
F ext/wasm/scratchpad-opfs-main.js 69e960e9161f6412fd0c30f355d4112f1894d6609eb431e2d16d207d1380518e
F ext/wasm/scratchpad-opfs-worker.html 66c1d15d678f3bd306373d76b61c6c8aef988f61f4a8dd40185d452f9c6d2bf5
@ -528,7 +531,7 @@ F ext/wasm/testing2.js 25584bcc30f19673ce13a6f301f89f8820a59dfe044e0c4f2913941f4
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
F main.mk 20801eed419dc58936ff9449b04041edbbbc0488a9fc683e72471dded050e0bb
F main.mk b1b02927b2e0b73d025f93e388f2f7fba07614e972453983bddc65cd2bf33bb1
F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
@ -571,7 +574,7 @@ F src/insert.c aea5361767817f917b0f0f647a1f0b1621bd858938ae6ae545c3b6b9814b798f
F src/json.c 7749b98c62f691697c7ee536b570c744c0583cab4a89200fdd0fc2aa8cc8cbd6
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 853385cc7a604157e137585097949252d5d0c731768e16b044608e5c95c3614b
F src/main.c 8983b4a316d7e09946dd731913aa41712f02e2b55cb5c6c92126ccfe2473244a
F src/main.c e11267cdd380be68d95d4292666636a7f1dff5f17a395f3d55be910d7e9350fb
F src/malloc.c b7a3430cbe91d3e8e04fc10c2041b3a19794e63556ad2441a13d8dadd9b2bafc
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
@ -590,8 +593,9 @@ F src/notify.c 89a97dc854c3aa62ad5f384ef50c5a4a11d70fcc69f86de3e991573421130ed6
F src/os.c 0eb831ba3575af5277e47f4edd14fdfc90025c67eb25ce5cda634518d308d4e9
F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
F src/os_unix.c 102f7e5c5b59c18ea3dbc929dc3be8acb3afc0e0b6ad572e032335c9c27f44f1
F src/os_kv.c a188e92dac693b1c1b512d93b0c4dc85c1baad11e322b01121f87057996e4d11
F src/os_setup.h 0711dbc4678f3ac52d7fe736951b6384a0615387c4ba5135a4764e4e31f4b6a6
F src/os_unix.c d6322b78130d995160bb9cfb7850678ad6838b08c1d13915461b33326a406c04
F src/os_win.c e9454cb141908e8eef2102180bad353a36480612d5b736e4c2bd5777d9b25a34
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c 6176d9752eb580419e8fef4592dc417a6b00ddfd43ee22f818819bf8840ceee8
@ -612,7 +616,7 @@ F src/shell.c.in e7e7c2c69ae86c5ee9e8ad66227203d46ff6dce8700a1b1dababff01c71d33d
F src/sqlite.h.in b9b7fd73239d94db20332bb6e504688001e5564b655e1318a4427a1caef4b99e
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h a988810c9b21c0dc36dc7a62735012339dc76fc7ab448fb0792721d30eacb69d
F src/sqliteInt.h 94e7fc2a5f0fa5d1f0af84513fd2d1c70a9f6e772556b9dfef16feee63291eae
F src/sqliteInt.h 44eb45c25d379361ee1bd7fc49205471c6cb8a3727aed42372cf4716f653ebf2
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@ -1956,7 +1960,7 @@ F tool/mkshellc.tcl df5d249617f9cc94d5c48eb0401673eb3f31f383ecbc54e8a13ca3dd97e8
F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f
F tool/mksqlite3c.tcl eee7e9d9c58abb1045f6ed74ad95ad26e8d22be29fdc431deea5267fb3fa049c
F tool/mksqlite3c.tcl 4fc26a9bfa0c4505b203d7ca0cf086e75ebcd4d63eb719c82f37e3fecdf23d37
F tool/mksqlite3h.tcl 1f5e4a1dbbbc43c83cc6e74fe32c6c620502240b66c7c0f33a51378e78fc4edf
F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b
F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5
@ -2019,8 +2023,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P cdbf09fa1b0c93aeb3222a157de33a4688ae629c2b829ffff0f1f62364c5ae1c
R 9d278bdeb3b04c59e81ef94ad61886ea
P 4e6ce329872eb733ba2f7f7879747c52761ae97790fd8ed169a25a79854cc3d9 e49682c5eac91958f143e639c5656ca54560d14f5805d514bf4aa0c206e63844
R f15733833cf5e73dce86b4365f218581
U stephan
Z 1e71f5bdda12caaeb1881e6b3d2fda00
Z f2a01bf4c99986993a2e00b39e93be73
# Remove this line to create a well-formed Fossil manifest.

View File

@ -1 +1 @@
4e6ce329872eb733ba2f7f7879747c52761ae97790fd8ed169a25a79854cc3d9
a7d8b26acd3c1ae344369e4d70804c0cab45272c0983cfd32d616a0a7b28acb9

View File

@ -4781,8 +4781,8 @@ int sqlite3_snapshot_open(
*/
int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb){
int rc = SQLITE_ERROR;
int iDb;
#ifndef SQLITE_OMIT_WAL
int iDb;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){

1077
src/os_kv.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -20,38 +20,72 @@
** Figure out if we are dealing with Unix, Windows, or some other operating
** system.
**
** After the following block of preprocess macros, all of SQLITE_OS_UNIX,
** SQLITE_OS_WIN, and SQLITE_OS_OTHER will defined to either 1 or 0. One of
** the three will be 1. The other two will be 0.
** After the following block of preprocess macros, all of
**
** SQLITE_OS_KV
** SQLITE_OS_OTHER
** SQLITE_OS_UNIX
** SQLITE_OS_WIN
**
** will defined to either 1 or 0. One of them will be 1. The others will be 0.
** If none of the macros are initially defined, then select either
** SQLITE_OS_UNIX or SQLITE_OS_WIN depending on the target platform.
**
** If SQLITE_OS_OTHER=1 is specified at compile-time, then the application
** must provide its own VFS implementation together with sqlite3_os_init()
** and sqlite3_os_end() routines.
*/
#if defined(SQLITE_OS_OTHER)
# if SQLITE_OS_OTHER==1
# undef SQLITE_OS_UNIX
#if !defined(SQLITE_OS_KV) && !defined(SQLITE_OS_OTHER) && \
!defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_WIN)
# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || \
defined(__MINGW32__) || defined(__BORLANDC__)
# define SQLITE_OS_WIN 1
# define SQLITE_OS_UNIX 0
# undef SQLITE_OS_WIN
# define SQLITE_OS_WIN 0
# else
# undef SQLITE_OS_OTHER
# define SQLITE_OS_WIN 0
# define SQLITE_OS_UNIX 1
# endif
#endif
#if !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_OTHER)
#if SQLITE_OS_OTHER+1>1
# undef SQLITE_OS_KV
# define SQLITE_OS_KV 0
# undef SQLITE_OS_UNIX
# define SQLITE_OS_UNIX 0
# undef SQLITE_OS_WIN
# define SQLITE_OS_WIN 0
#endif
#if SQLITE_OS_KV+1>1
# undef SQLITE_OS_OTHER
# define SQLITE_OS_OTHER 0
# ifndef SQLITE_OS_WIN
# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || \
defined(__MINGW32__) || defined(__BORLANDC__)
# define SQLITE_OS_WIN 1
# define SQLITE_OS_UNIX 0
# else
# define SQLITE_OS_WIN 0
# define SQLITE_OS_UNIX 1
# endif
# else
# define SQLITE_OS_UNIX 0
# endif
#else
# ifndef SQLITE_OS_WIN
# define SQLITE_OS_WIN 0
# endif
# undef SQLITE_OS_UNIX
# define SQLITE_OS_UNIX 0
# undef SQLITE_OS_WIN
# define SQLITE_OS_WIN 0
# define SQLITE_OMIT_LOAD_EXTENSION 1
# define SQLITE_OMIT_WAL 1
# define SQLITE_OMIT DEPRECATED 1
# undef SQLITE_TEMP_STORE
# define SQLITE_TEMP_STORE 3 /* Always use memory for temporary storage */
# define SQLITE_DQS 0
# define SQLITE_OMIT_SHARED_CACHE 1
# define SQLITE_OMIT_AUTOINIT 1
#endif
#if SQLITE_OS_UNIX+1>1
# undef SQLITE_OS_KV
# define SQLITE_OS_KV 0
# undef SQLITE_OS_OTHER
# define SQLITE_OS_OTHER 0
# undef SQLITE_OS_WIN
# define SQLITE_OS_WIN 0
#endif
#if SQLITE_OS_WIN+1>1
# undef SQLITE_OS_KV
# define SQLITE_OS_KV 0
# undef SQLITE_OS_OTHER
# define SQLITE_OS_OTHER 0
# undef SQLITE_OS_UNIX
# define SQLITE_OS_UNIX 0
#endif
#endif /* SQLITE_OS_SETUP_H */

View File

@ -87,11 +87,11 @@
/*
** standard include files.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/types.h> /* amalgamator: keep */
#include <sys/stat.h> /* amalgamator: keep */
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <unistd.h> /* amalgamator: keep */
#include <time.h>
#include <sys/time.h>
#include <errno.h>

View File

@ -1268,11 +1268,11 @@ typedef int VList;
** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque
** pointer types (i.e. FuncDef) defined above.
*/
#include "os.h"
#include "pager.h"
#include "btree.h"
#include "vdbe.h"
#include "pcache.h"
#include "os.h"
#include "mutex.h"
/* The SQLITE_EXTRA_DURABLE compile-time option used to set the default

View File

@ -355,6 +355,7 @@ foreach file {
hash.c
opcodes.c
os_kv.c
os_unix.c
os_win.c
memdb.c