Download ext/wasm/api/sqlite3-wasm.c from AryaWu/sqlite: direct link, hf CLI and curl.
- Browser
- Download file 66.2 kB
-
https://huggingface.co/AryaWu/sqlite/resolve/main/ext/wasm/api/sqlite3-wasm.c
- Command line
-
hf download hf://AryaWu/sqlite/ext/wasm/api/sqlite3-wasm.c
-
curl -L -o sqlite3-wasm.c https://huggingface.co/AryaWu/sqlite/resolve/main/ext/wasm/api/sqlite3-wasm.c
66.2 kB
| /* | |
| ** This file requires access to sqlite3.c static state in order to | |
| ** implement certain WASM-specific features, and thus directly | |
| ** includes that file. Unlike the rest of sqlite3.c, this file | |
| ** requires compiling with -std=c99 (or equivalent, or a later C | |
| ** version) because it makes use of features not available in C89. | |
| ** | |
| ** At its simplest, to build sqlite3.wasm either place this file | |
| ** in the same directory as sqlite3.c/h before compilation or use the | |
| ** -I/path flag to tell the compiler where to find both of those | |
| ** files, then compile this file. For example: | |
| ** | |
| ** emcc -o sqlite3.wasm ... -I/path/to/sqlite3-c-and-h sqlite3-wasm.c | |
| */ | |
| /* | |
| ** Code blocked off by SQLITE_WASM_ENABLE_C_TESTS is intended solely | |
| ** for use in unit/regression testing. They may be safely omitted from | |
| ** client-side builds. The main unit test script, tester1.js, will | |
| ** skip related tests if it doesn't find the corresponding functions | |
| ** in the WASM exports. | |
| */ | |
| /* | |
| ** Threading and file locking: JS is single-threaded. Each Worker | |
| ** thread is a separate instance of the JS engine so can never access | |
| ** the same db handle as another thread, thus multi-threading support | |
| ** is unnecessary in the library. Because the filesystems are virtual | |
| ** and local to a given wasm runtime instance, two Workers can never | |
| ** access the same db file at once, with the exception of OPFS. | |
| ** | |
| ** Summary: except for the case of OPFS, which supports locking using | |
| ** its own API, threading and file locking support are unnecessary in | |
| ** the wasm build. | |
| */ | |
| /* | |
| ** Undefine any SQLITE_... config flags which we specifically do not | |
| ** want defined. Please keep these alphabetized. | |
| */ | |
| /* | |
| ** Define any SQLITE_... config defaults we want if they aren't | |
| ** overridden by the builder. Please keep these alphabetized. | |
| */ | |
| /**********************************************************************/ | |
| /* SQLITE_D... */ | |
| /* | |
| ** The OPFS impls benefit tremendously from an increased cache size | |
| ** when working on large workloads, e.g. speedtest1 --size 50 or | |
| ** higher. On smaller workloads, e.g. speedtest1 --size 25, they | |
| ** clearly benefit from having 4mb of cache, but not as much as a | |
| ** larger cache benefits the larger workloads. Speed differences | |
| ** between 2x and nearly 3x have been measured with ample page cache. | |
| */ | |
| /* | |
| ** OPFS performance is improved by approx. 12% with a page size of 8kb | |
| ** instead of 4kb. Performance with 16kb is equivalent to 8kb. | |
| ** | |
| ** Performance difference of kvvfs with a page size of 8kb compared to | |
| ** 4kb, as measured by speedtest1 --size 4, is indeterminate: | |
| ** measurements are all over the place either way and not | |
| ** significantly different. | |
| */ | |
| /**********************************************************************/ | |
| /* SQLITE_ENABLE_... */ | |
| /* | |
| ** Unconditionally enable API_ARMOR in the WASM build. It ensures that | |
| ** public APIs behave predictable in the face of passing illegal NULLs | |
| ** or ranges which might otherwise invoke undefined behavior. | |
| */ | |
| /**********************************************************************/ | |
| /* SQLITE_EXPERIMENTAL_PRAGMA_20251114 */ | |
| /* | |
| ** See: | |
| ** https://sqlite.org/src/info/e2b3f1a9480a9be3 | |
| ** https://github.com/rhashimoto/wa-sqlite/discussions/301 | |
| ** | |
| ** It is enabled here for the sake of VFS experimentors. | |
| */ | |
| /**********************************************************************/ | |
| /* SQLITE_O... */ | |
| /**********************************************************************/ | |
| /* SQLITE_S... */ | |
| /**********************************************************************/ | |
| /* SQLITE_T... */ | |
| /**********************************************************************/ | |
| /* SQLITE_USE_... */ | |
| /* SQLITE_EXTRA_INIT vs SQLITE_EXTRA_INIT_MUTEXED: | |
| ** see https://sqlite.org/forum/forumpost/14183b98fc0b1dea */ | |
| /* | |
| ** If SQLITE_WASM_BARE_BONES is defined, undefine most of the ENABLE | |
| ** macros. This will, when using the canonical makefile, also elide | |
| ** any C functions from the WASM exports: see | |
| ** ./EXPORTED_FUNCTIONS.c-pp. | |
| */ | |
| /* | |
| The following OMITs do not work with the standard amalgamation, so | |
| require a custom build: | |
| fossil clean -x | |
| ./configure | |
| OPTS='...' make -e sqlite3 | |
| where ... has a -D... for each of the following OMIT flags: | |
| # undef SQLITE_OMIT_EXPLAIN | |
| # define SQLITE_OMIT_EXPLAIN | |
| # undef SQLITE_OMIT_TRIGGER | |
| # define SQLITE_OMIT_TRIGGER | |
| # undef SQLITE_OMIT_VIRTUALTABLE | |
| # define SQLITE_OMIT_VIRTUALTABLE | |
| # undef SQLITE_OMIT_WINDOWFUNC | |
| # define SQLITE_OMIT_WINDOWFUNC | |
| As of this writing (2024-07-25), such a build fails in various ways | |
| for as-yet-unknown reasons. | |
| */ | |
| /* | |
| ** SQLITE_WASM_EXPORT is functionally identical to EMSCRIPTEN_KEEPALIVE | |
| ** but is not Emscripten-specific. It explicitly marks functions for | |
| ** export into the target wasm file without requiring explicit listing | |
| ** of those functions in Emscripten's -sEXPORTED_FUNCTIONS=... list | |
| ** (or equivalent in other build platforms). Any function with neither | |
| ** this attribute nor which is listed as an explicit export will not | |
| ** be exported from the wasm file (but may still be used internally | |
| ** within the wasm file). | |
| ** | |
| ** The functions in this file (sqlite3-wasm.c) which require exporting | |
| ** are marked with this flag. They may also be added to any explicit | |
| ** build-time export list but need not be. All of these APIs are | |
| ** intended for use only within the project's own JS/WASM code, and | |
| ** not by client code, so an argument can be made for reducing their | |
| ** visibility by not including them in any build-time export lists. | |
| ** | |
| ** 2025-12-01: for use in non-Emscripten builds, we need a more | |
| ** invasive macro which explicitly names the export: | |
| ** SQLITE_WASM_EXPORT2. | |
| */ | |
| /** Increase the kvvfs key size limit from 32. */ | |
| /* | |
| ** Which sqlite3.c we're using needs to be configurable to enable | |
| ** building against a custom copy, e.g. the SEE variant. We #include | |
| ** the .c file, rather than the header, so that the WASM extensions | |
| ** have access to private API internals (namely for kvvfs and | |
| ** SQLTester pieces). | |
| ** | |
| ** The caveat here is that custom variants need to account for | |
| ** exporting any necessary symbols (e.g. sqlite3_activate_see()). We | |
| ** cannot export them from here using SQLITE_WASM_EXPORT because that | |
| ** attribute (apparently) has to be part of the function definition. | |
| */ | |
| /* | |
| ** State for the "pseudo-stack" allocator implemented in | |
| ** sqlite3__wasm_pstack_xyz(). In order to avoid colliding with | |
| ** Emscripten-controlled stack space, it carves out a bit of stack | |
| ** memory to use for that purpose. This memory ends up in the | |
| ** WASM-managed memory, such that routines which manipulate the wasm | |
| ** heap can also be used to manipulate this memory. | |
| ** | |
| ** This particular allocator is intended for small allocations such as | |
| ** storage for output pointers. We cannot reasonably size it large | |
| ** enough for general-purpose string conversions because some of our | |
| ** tests use input files (strings) of 16MB+. | |
| */ | |
| static unsigned char PStack_mem[ | |
| 1024 * 4 /* API docs guaranty at least 2kb and it's been set at 4kb | |
| since it was introduced. */ | |
| ] = {0}; | |
| static struct { | |
| unsigned const char * const pBegin;/* Start (inclusive) of memory */ | |
| unsigned const char * const pEnd; /* One-after-the-end of memory */ | |
| unsigned char * pPos; /* Current stack pointer */ | |
| } PStack = { | |
| &PStack_mem[0], | |
| &PStack_mem[0] + sizeof(PStack_mem), | |
| &PStack_mem[0] + sizeof(PStack_mem) | |
| }; | |
| /* | |
| ** Returns the current pstack position. | |
| */ | |
| SQLITE_WASM_EXPORT void * sqlite3__wasm_pstack_ptr(void){ | |
| return PStack.pPos; | |
| } | |
| /* | |
| ** Sets the pstack position pointer to p. Results are undefined if the | |
| ** given value did not come from sqlite3__wasm_pstack_ptr(). | |
| */ | |
| SQLITE_WASM_EXPORT void sqlite3__wasm_pstack_restore(unsigned char * p){ | |
| assert(p>=PStack.pBegin && p<=PStack.pEnd && p>=PStack.pPos); | |
| assert(0==((unsigned long long)p & 0x7) /* 8-byte aligned */); | |
| if(p>=PStack.pBegin && p<=PStack.pEnd /*&& p>=PStack.pPos*/){ | |
| PStack.pPos = p; | |
| } | |
| } | |
| /* | |
| ** Allocate and zero out n bytes from the pstack. Returns a pointer to | |
| ** the memory on success, 0 on error (including a negative n value). n | |
| ** is always adjusted to be a multiple of 8 and returned memory is | |
| ** always zeroed out before returning (because this keeps the client | |
| ** JS code from having to do so, and most uses of the pstack call for | |
| ** doing so). | |
| */ | |
| SQLITE_WASM_EXPORT2(void *,sqlite3__wasm_pstack_alloc,(int n)){ | |
| if( n<=0 ) return 0; | |
| n = (n + 7) & ~7 /* align to 8-byte boundary */; | |
| if( PStack.pBegin + n > PStack.pPos /*not enough space left*/ | |
| || PStack.pBegin + n <= PStack.pBegin /*overflow*/ ) return 0; | |
| memset((PStack.pPos = PStack.pPos - n), 0, (unsigned int)n); | |
| return PStack.pPos; | |
| } | |
| /* | |
| ** Return the number of bytes left which can be | |
| ** sqlite3__wasm_pstack_alloc()'d. | |
| */ | |
| SQLITE_WASM_EXPORT2(int,sqlite3__wasm_pstack_remaining,(void)){ | |
| assert(PStack.pPos >= PStack.pBegin); | |
| assert(PStack.pPos <= PStack.pEnd); | |
| return (int)(PStack.pPos - PStack.pBegin); | |
| } | |
| /* | |
| ** Return the total number of bytes available in the pstack, including | |
| ** any space which is currently allocated. This value is a | |
| ** compile-time constant. | |
| */ | |
| SQLITE_WASM_EXPORT2(int,sqlite3__wasm_pstack_quota,(void)){ | |
| return (int)(PStack.pEnd - PStack.pBegin); | |
| } | |
| struct WasmTestStruct { | |
| int v4; | |
| void * ppV; | |
| const char * cstr; | |
| int64_t v8; | |
| void (*xFunc)(void*); | |
| }; | |
| typedef struct WasmTestStruct WasmTestStruct; | |
| SQLITE_WASM_EXPORT2(void,sqlite3__wasm_test_struct,(WasmTestStruct * s)){ | |
| if(s){ | |
| if( 0 ){ | |
| /* Do not be alarmed by the small (and odd) pointer values. | |
| Function pointers in WASM are their index into the | |
| indirect function table, not their address. */ | |
| fprintf(stderr,"%s:%s()@%p s=@%p xFunc=@%p\n", | |
| __FILE__, __func__, | |
| (void*)sqlite3__wasm_test_struct, | |
| s, (void*)s->xFunc); | |
| } | |
| s->v4 *= 2; | |
| s->v8 = s->v4 * 2; | |
| s->ppV = s; | |
| s->cstr = __FILE__; | |
| if(s->xFunc) s->xFunc(s); | |
| } | |
| } | |
| /* | |
| ** This function is NOT part of the sqlite3 public API. It is strictly | |
| ** for use by the sqlite project's own JS/WASM bindings. Unlike the | |
| ** rest of the sqlite3 API, this part requires C99 for snprintf() and | |
| ** variadic macros. | |
| ** | |
| ** Returns a string containing a JSON-format "enum" of C-level | |
| ** constants and struct-related metadata intended to be imported into | |
| ** the JS environment. The JSON is initialized the first time this | |
| ** function is called and that result is reused for all future calls. | |
| ** | |
| ** If this function returns NULL then it means that the internal | |
| ** buffer is not large enough for the generated JSON and needs to be | |
| ** increased. In debug builds that will trigger an assert(). | |
| ** | |
| ** 2025-09-19: for reasons entirely not understood, building with emcc | |
| ** -sMEMORY64=2 causes this function to fail (return 0). -sMEMORY64=1 | |
| ** fails to compile with "tables may not be 64-bit" but does not tell | |
| ** us where it's happening. | |
| */ | |
| SQLITE_WASM_EXPORT2(const char *,sqlite3__wasm_enum_json,(void)){ | |
| static char aBuffer[1024 * 20] = | |
| {0} /* where the JSON goes. 2025-09-19: output size=19295, but | |
| that can vary slightly from build to build, so a little | |
| leeway is needed here. */; | |
| int n = 0, nChildren = 0, nStruct = 0 | |
| /* output counters for figuring out where commas go */; | |
| char * zPos = &aBuffer[1] /* skip first byte for now to help protect | |
| ** against a small race condition */; | |
| char const * const zEnd = &aBuffer[0] + sizeof(aBuffer) /* one-past-the-end */; | |
| if(aBuffer[0]) return aBuffer; | |
| /* Leave aBuffer[0] at 0 until the end to help guard against a tiny | |
| ** race condition. If this is called twice concurrently, they might | |
| ** end up both writing to aBuffer, but they'll both write the same | |
| ** thing, so that's okay. If we set byte 0 up front then the 2nd | |
| ** instance might return and use the string before the 1st instance | |
| ** is done filling it. */ | |
| /* Core output macros... */ | |
| /* Macros for emitting maps of integer- and string-type macros to | |
| ** their values. */ | |
| /* The following groups are sorted alphabetic by group name. */ | |
| DefGroup(access){ | |
| DefInt(SQLITE_ACCESS_EXISTS); | |
| DefInt(SQLITE_ACCESS_READWRITE); | |
| DefInt(SQLITE_ACCESS_READ)/*docs say this is unused*/; | |
| } _DefGroup; | |
| DefGroup(authorizer){ | |
| DefInt(SQLITE_DENY); | |
| DefInt(SQLITE_IGNORE); | |
| DefInt(SQLITE_CREATE_INDEX); | |
| DefInt(SQLITE_CREATE_TABLE); | |
| DefInt(SQLITE_CREATE_TEMP_INDEX); | |
| DefInt(SQLITE_CREATE_TEMP_TABLE); | |
| DefInt(SQLITE_CREATE_TEMP_TRIGGER); | |
| DefInt(SQLITE_CREATE_TEMP_VIEW); | |
| DefInt(SQLITE_CREATE_TRIGGER); | |
| DefInt(SQLITE_CREATE_VIEW); | |
| DefInt(SQLITE_DELETE); | |
| DefInt(SQLITE_DROP_INDEX); | |
| DefInt(SQLITE_DROP_TABLE); | |
| DefInt(SQLITE_DROP_TEMP_INDEX); | |
| DefInt(SQLITE_DROP_TEMP_TABLE); | |
| DefInt(SQLITE_DROP_TEMP_TRIGGER); | |
| DefInt(SQLITE_DROP_TEMP_VIEW); | |
| DefInt(SQLITE_DROP_TRIGGER); | |
| DefInt(SQLITE_DROP_VIEW); | |
| DefInt(SQLITE_INSERT); | |
| DefInt(SQLITE_PRAGMA); | |
| DefInt(SQLITE_READ); | |
| DefInt(SQLITE_SELECT); | |
| DefInt(SQLITE_TRANSACTION); | |
| DefInt(SQLITE_UPDATE); | |
| DefInt(SQLITE_ATTACH); | |
| DefInt(SQLITE_DETACH); | |
| DefInt(SQLITE_ALTER_TABLE); | |
| DefInt(SQLITE_REINDEX); | |
| DefInt(SQLITE_ANALYZE); | |
| DefInt(SQLITE_CREATE_VTABLE); | |
| DefInt(SQLITE_DROP_VTABLE); | |
| DefInt(SQLITE_FUNCTION); | |
| DefInt(SQLITE_SAVEPOINT); | |
| //DefInt(SQLITE_COPY) /* No longer used */; | |
| DefInt(SQLITE_RECURSIVE); | |
| } _DefGroup; | |
| DefGroup(blobFinalizers) { | |
| /* SQLITE_STATIC/TRANSIENT need to be handled explicitly as | |
| ** integers to avoid casting-related warnings. */ | |
| out("\"SQLITE_STATIC\":0, \"SQLITE_TRANSIENT\":-1"); | |
| outf(",\"SQLITE_WASM_DEALLOC\": %lld", | |
| (sqlite3_int64)(sqlite3_free)); | |
| } _DefGroup; | |
| DefGroup(changeset){ | |
| DefInt(SQLITE_CHANGESETSTART_INVERT); | |
| DefInt(SQLITE_CHANGESETAPPLY_NOSAVEPOINT); | |
| DefInt(SQLITE_CHANGESETAPPLY_INVERT); | |
| DefInt(SQLITE_CHANGESETAPPLY_IGNORENOOP); | |
| DefInt(SQLITE_CHANGESET_DATA); | |
| DefInt(SQLITE_CHANGESET_NOTFOUND); | |
| DefInt(SQLITE_CHANGESET_CONFLICT); | |
| DefInt(SQLITE_CHANGESET_CONSTRAINT); | |
| DefInt(SQLITE_CHANGESET_FOREIGN_KEY); | |
| DefInt(SQLITE_CHANGESET_OMIT); | |
| DefInt(SQLITE_CHANGESET_REPLACE); | |
| DefInt(SQLITE_CHANGESET_ABORT); | |
| } _DefGroup; | |
| DefGroup(config){ | |
| DefInt(SQLITE_CONFIG_SINGLETHREAD); | |
| DefInt(SQLITE_CONFIG_MULTITHREAD); | |
| DefInt(SQLITE_CONFIG_SERIALIZED); | |
| DefInt(SQLITE_CONFIG_MALLOC); | |
| DefInt(SQLITE_CONFIG_GETMALLOC); | |
| DefInt(SQLITE_CONFIG_SCRATCH); | |
| DefInt(SQLITE_CONFIG_PAGECACHE); | |
| DefInt(SQLITE_CONFIG_HEAP); | |
| DefInt(SQLITE_CONFIG_MEMSTATUS); | |
| DefInt(SQLITE_CONFIG_MUTEX); | |
| DefInt(SQLITE_CONFIG_GETMUTEX); | |
| /* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ | |
| DefInt(SQLITE_CONFIG_LOOKASIDE); | |
| DefInt(SQLITE_CONFIG_PCACHE); | |
| DefInt(SQLITE_CONFIG_GETPCACHE); | |
| DefInt(SQLITE_CONFIG_LOG); | |
| DefInt(SQLITE_CONFIG_URI); | |
| DefInt(SQLITE_CONFIG_PCACHE2); | |
| DefInt(SQLITE_CONFIG_GETPCACHE2); | |
| DefInt(SQLITE_CONFIG_COVERING_INDEX_SCAN); | |
| DefInt(SQLITE_CONFIG_SQLLOG); | |
| DefInt(SQLITE_CONFIG_MMAP_SIZE); | |
| DefInt(SQLITE_CONFIG_WIN32_HEAPSIZE); | |
| DefInt(SQLITE_CONFIG_PCACHE_HDRSZ); | |
| DefInt(SQLITE_CONFIG_PMASZ); | |
| DefInt(SQLITE_CONFIG_STMTJRNL_SPILL); | |
| DefInt(SQLITE_CONFIG_SMALL_MALLOC); | |
| DefInt(SQLITE_CONFIG_SORTERREF_SIZE); | |
| DefInt(SQLITE_CONFIG_MEMDB_MAXSIZE); | |
| /* maintenance note: we specifically do not include | |
| SQLITE_CONFIG_ROWID_IN_VIEW here, on the grounds that | |
| it's only for legacy support and no apps written with | |
| this API require that. */ | |
| } _DefGroup; | |
| DefGroup(dataTypes) { | |
| DefInt(SQLITE_INTEGER); | |
| DefInt(SQLITE_FLOAT); | |
| DefInt(SQLITE_TEXT); | |
| DefInt(SQLITE_BLOB); | |
| DefInt(SQLITE_NULL); | |
| } _DefGroup; | |
| DefGroup(dbConfig){ | |
| DefInt(SQLITE_DBCONFIG_MAINDBNAME); | |
| DefInt(SQLITE_DBCONFIG_LOOKASIDE); | |
| DefInt(SQLITE_DBCONFIG_ENABLE_FKEY); | |
| DefInt(SQLITE_DBCONFIG_ENABLE_TRIGGER); | |
| DefInt(SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION); | |
| DefInt(SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE); | |
| DefInt(SQLITE_DBCONFIG_ENABLE_QPSG); | |
| DefInt(SQLITE_DBCONFIG_TRIGGER_EQP); | |
| DefInt(SQLITE_DBCONFIG_RESET_DATABASE); | |
| DefInt(SQLITE_DBCONFIG_DEFENSIVE); | |
| DefInt(SQLITE_DBCONFIG_WRITABLE_SCHEMA); | |
| DefInt(SQLITE_DBCONFIG_LEGACY_ALTER_TABLE); | |
| DefInt(SQLITE_DBCONFIG_DQS_DML); | |
| DefInt(SQLITE_DBCONFIG_DQS_DDL); | |
| DefInt(SQLITE_DBCONFIG_ENABLE_VIEW); | |
| DefInt(SQLITE_DBCONFIG_LEGACY_FILE_FORMAT); | |
| DefInt(SQLITE_DBCONFIG_TRUSTED_SCHEMA); | |
| DefInt(SQLITE_DBCONFIG_STMT_SCANSTATUS); | |
| DefInt(SQLITE_DBCONFIG_REVERSE_SCANORDER); | |
| DefInt(SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE); | |
| DefInt(SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE); | |
| DefInt(SQLITE_DBCONFIG_ENABLE_COMMENTS); | |
| DefInt(SQLITE_DBCONFIG_MAX); | |
| } _DefGroup; | |
| DefGroup(dbStatus){ | |
| DefInt(SQLITE_DBSTATUS_LOOKASIDE_USED); | |
| DefInt(SQLITE_DBSTATUS_CACHE_USED); | |
| DefInt(SQLITE_DBSTATUS_SCHEMA_USED); | |
| DefInt(SQLITE_DBSTATUS_STMT_USED); | |
| DefInt(SQLITE_DBSTATUS_LOOKASIDE_HIT); | |
| DefInt(SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE); | |
| DefInt(SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL); | |
| DefInt(SQLITE_DBSTATUS_CACHE_HIT); | |
| DefInt(SQLITE_DBSTATUS_CACHE_MISS); | |
| DefInt(SQLITE_DBSTATUS_CACHE_WRITE); | |
| DefInt(SQLITE_DBSTATUS_DEFERRED_FKS); | |
| DefInt(SQLITE_DBSTATUS_CACHE_USED_SHARED); | |
| DefInt(SQLITE_DBSTATUS_CACHE_SPILL); | |
| DefInt(SQLITE_DBSTATUS_TEMPBUF_SPILL); | |
| DefInt(SQLITE_DBSTATUS_MAX); | |
| } _DefGroup; | |
| DefGroup(encodings) { | |
| /* Noting that the wasm binding only aims to support UTF-8. */ | |
| DefInt(SQLITE_UTF8); | |
| DefInt(SQLITE_UTF16LE); | |
| DefInt(SQLITE_UTF16BE); | |
| DefInt(SQLITE_UTF16); | |
| /*deprecated DefInt(SQLITE_ANY); */ | |
| DefInt(SQLITE_UTF16_ALIGNED); | |
| } _DefGroup; | |
| DefGroup(fcntl) { | |
| DefInt(SQLITE_FCNTL_LOCKSTATE); | |
| DefInt(SQLITE_FCNTL_GET_LOCKPROXYFILE); | |
| DefInt(SQLITE_FCNTL_SET_LOCKPROXYFILE); | |
| DefInt(SQLITE_FCNTL_LAST_ERRNO); | |
| DefInt(SQLITE_FCNTL_SIZE_HINT); | |
| DefInt(SQLITE_FCNTL_CHUNK_SIZE); | |
| DefInt(SQLITE_FCNTL_FILE_POINTER); | |
| DefInt(SQLITE_FCNTL_SYNC_OMITTED); | |
| DefInt(SQLITE_FCNTL_WIN32_AV_RETRY); | |
| DefInt(SQLITE_FCNTL_PERSIST_WAL); | |
| DefInt(SQLITE_FCNTL_OVERWRITE); | |
| DefInt(SQLITE_FCNTL_VFSNAME); | |
| DefInt(SQLITE_FCNTL_POWERSAFE_OVERWRITE); | |
| DefInt(SQLITE_FCNTL_PRAGMA); | |
| DefInt(SQLITE_FCNTL_BUSYHANDLER); | |
| DefInt(SQLITE_FCNTL_TEMPFILENAME); | |
| DefInt(SQLITE_FCNTL_MMAP_SIZE); | |
| DefInt(SQLITE_FCNTL_TRACE); | |
| DefInt(SQLITE_FCNTL_HAS_MOVED); | |
| DefInt(SQLITE_FCNTL_SYNC); | |
| DefInt(SQLITE_FCNTL_COMMIT_PHASETWO); | |
| DefInt(SQLITE_FCNTL_WIN32_SET_HANDLE); | |
| DefInt(SQLITE_FCNTL_WAL_BLOCK); | |
| DefInt(SQLITE_FCNTL_ZIPVFS); | |
| DefInt(SQLITE_FCNTL_RBU); | |
| DefInt(SQLITE_FCNTL_VFS_POINTER); | |
| DefInt(SQLITE_FCNTL_JOURNAL_POINTER); | |
| DefInt(SQLITE_FCNTL_WIN32_GET_HANDLE); | |
| DefInt(SQLITE_FCNTL_PDB); | |
| DefInt(SQLITE_FCNTL_BEGIN_ATOMIC_WRITE); | |
| DefInt(SQLITE_FCNTL_COMMIT_ATOMIC_WRITE); | |
| DefInt(SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE); | |
| DefInt(SQLITE_FCNTL_LOCK_TIMEOUT); | |
| DefInt(SQLITE_FCNTL_DATA_VERSION); | |
| DefInt(SQLITE_FCNTL_SIZE_LIMIT); | |
| DefInt(SQLITE_FCNTL_CKPT_DONE); | |
| DefInt(SQLITE_FCNTL_RESERVE_BYTES); | |
| DefInt(SQLITE_FCNTL_CKPT_START); | |
| DefInt(SQLITE_FCNTL_EXTERNAL_READER); | |
| DefInt(SQLITE_FCNTL_CKSM_FILE); | |
| DefInt(SQLITE_FCNTL_RESET_CACHE); | |
| } _DefGroup; | |
| DefGroup(flock) { | |
| DefInt(SQLITE_LOCK_NONE); | |
| DefInt(SQLITE_LOCK_SHARED); | |
| DefInt(SQLITE_LOCK_RESERVED); | |
| DefInt(SQLITE_LOCK_PENDING); | |
| DefInt(SQLITE_LOCK_EXCLUSIVE); | |
| } _DefGroup; | |
| DefGroup(ioCap) { | |
| DefInt(SQLITE_IOCAP_ATOMIC); | |
| DefInt(SQLITE_IOCAP_ATOMIC512); | |
| DefInt(SQLITE_IOCAP_ATOMIC1K); | |
| DefInt(SQLITE_IOCAP_ATOMIC2K); | |
| DefInt(SQLITE_IOCAP_ATOMIC4K); | |
| DefInt(SQLITE_IOCAP_ATOMIC8K); | |
| DefInt(SQLITE_IOCAP_ATOMIC16K); | |
| DefInt(SQLITE_IOCAP_ATOMIC32K); | |
| DefInt(SQLITE_IOCAP_ATOMIC64K); | |
| DefInt(SQLITE_IOCAP_SAFE_APPEND); | |
| DefInt(SQLITE_IOCAP_SEQUENTIAL); | |
| DefInt(SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN); | |
| DefInt(SQLITE_IOCAP_POWERSAFE_OVERWRITE); | |
| DefInt(SQLITE_IOCAP_IMMUTABLE); | |
| DefInt(SQLITE_IOCAP_BATCH_ATOMIC); | |
| } _DefGroup; | |
| DefGroup(limits) { | |
| DefInt(SQLITE_MAX_ALLOCATION_SIZE); | |
| DefInt(SQLITE_LIMIT_LENGTH); | |
| DefInt(SQLITE_MAX_LENGTH); | |
| DefInt(SQLITE_LIMIT_SQL_LENGTH); | |
| DefInt(SQLITE_MAX_SQL_LENGTH); | |
| DefInt(SQLITE_LIMIT_COLUMN); | |
| DefInt(SQLITE_MAX_COLUMN); | |
| DefInt(SQLITE_LIMIT_EXPR_DEPTH); | |
| DefInt(SQLITE_MAX_EXPR_DEPTH); | |
| DefInt(SQLITE_LIMIT_COMPOUND_SELECT); | |
| DefInt(SQLITE_MAX_COMPOUND_SELECT); | |
| DefInt(SQLITE_LIMIT_VDBE_OP); | |
| DefInt(SQLITE_MAX_VDBE_OP); | |
| DefInt(SQLITE_LIMIT_FUNCTION_ARG); | |
| DefInt(SQLITE_MAX_FUNCTION_ARG); | |
| DefInt(SQLITE_LIMIT_ATTACHED); | |
| DefInt(SQLITE_MAX_ATTACHED); | |
| DefInt(SQLITE_LIMIT_LIKE_PATTERN_LENGTH); | |
| DefInt(SQLITE_MAX_LIKE_PATTERN_LENGTH); | |
| DefInt(SQLITE_LIMIT_VARIABLE_NUMBER); | |
| DefInt(SQLITE_MAX_VARIABLE_NUMBER); | |
| DefInt(SQLITE_LIMIT_TRIGGER_DEPTH); | |
| DefInt(SQLITE_MAX_TRIGGER_DEPTH); | |
| DefInt(SQLITE_LIMIT_WORKER_THREADS); | |
| DefInt(SQLITE_MAX_WORKER_THREADS); | |
| } _DefGroup; | |
| DefGroup(openFlags) { | |
| /* Noting that not all of these will have any effect in | |
| ** WASM-space. */ | |
| DefInt(SQLITE_OPEN_READONLY); | |
| DefInt(SQLITE_OPEN_READWRITE); | |
| DefInt(SQLITE_OPEN_CREATE); | |
| DefInt(SQLITE_OPEN_URI); | |
| DefInt(SQLITE_OPEN_MEMORY); | |
| DefInt(SQLITE_OPEN_NOMUTEX); | |
| DefInt(SQLITE_OPEN_FULLMUTEX); | |
| DefInt(SQLITE_OPEN_SHAREDCACHE); | |
| DefInt(SQLITE_OPEN_PRIVATECACHE); | |
| DefInt(SQLITE_OPEN_EXRESCODE); | |
| DefInt(SQLITE_OPEN_NOFOLLOW); | |
| /* OPEN flags for use with VFSes... */ | |
| DefInt(SQLITE_OPEN_MAIN_DB); | |
| DefInt(SQLITE_OPEN_MAIN_JOURNAL); | |
| DefInt(SQLITE_OPEN_TEMP_DB); | |
| DefInt(SQLITE_OPEN_TEMP_JOURNAL); | |
| DefInt(SQLITE_OPEN_TRANSIENT_DB); | |
| DefInt(SQLITE_OPEN_SUBJOURNAL); | |
| DefInt(SQLITE_OPEN_SUPER_JOURNAL); | |
| DefInt(SQLITE_OPEN_WAL); | |
| DefInt(SQLITE_OPEN_DELETEONCLOSE); | |
| DefInt(SQLITE_OPEN_EXCLUSIVE); | |
| } _DefGroup; | |
| DefGroup(prepareFlags) { | |
| DefInt(SQLITE_PREPARE_PERSISTENT); | |
| DefInt(SQLITE_PREPARE_NORMALIZE); | |
| DefInt(SQLITE_PREPARE_NO_VTAB); | |
| } _DefGroup; | |
| DefGroup(resultCodes) { | |
| DefInt(SQLITE_OK); | |
| DefInt(SQLITE_ERROR); | |
| DefInt(SQLITE_INTERNAL); | |
| DefInt(SQLITE_PERM); | |
| DefInt(SQLITE_ABORT); | |
| DefInt(SQLITE_BUSY); | |
| DefInt(SQLITE_LOCKED); | |
| DefInt(SQLITE_NOMEM); | |
| DefInt(SQLITE_READONLY); | |
| DefInt(SQLITE_INTERRUPT); | |
| DefInt(SQLITE_IOERR); | |
| DefInt(SQLITE_CORRUPT); | |
| DefInt(SQLITE_NOTFOUND); | |
| DefInt(SQLITE_FULL); | |
| DefInt(SQLITE_CANTOPEN); | |
| DefInt(SQLITE_PROTOCOL); | |
| DefInt(SQLITE_EMPTY); | |
| DefInt(SQLITE_SCHEMA); | |
| DefInt(SQLITE_TOOBIG); | |
| DefInt(SQLITE_CONSTRAINT); | |
| DefInt(SQLITE_MISMATCH); | |
| DefInt(SQLITE_MISUSE); | |
| DefInt(SQLITE_NOLFS); | |
| DefInt(SQLITE_AUTH); | |
| DefInt(SQLITE_FORMAT); | |
| DefInt(SQLITE_RANGE); | |
| DefInt(SQLITE_NOTADB); | |
| DefInt(SQLITE_NOTICE); | |
| DefInt(SQLITE_WARNING); | |
| DefInt(SQLITE_ROW); | |
| DefInt(SQLITE_DONE); | |
| // Extended Result Codes | |
| DefInt(SQLITE_ERROR_MISSING_COLLSEQ); | |
| DefInt(SQLITE_ERROR_RETRY); | |
| DefInt(SQLITE_ERROR_SNAPSHOT); | |
| DefInt(SQLITE_IOERR_READ); | |
| DefInt(SQLITE_IOERR_SHORT_READ); | |
| DefInt(SQLITE_IOERR_WRITE); | |
| DefInt(SQLITE_IOERR_FSYNC); | |
| DefInt(SQLITE_IOERR_DIR_FSYNC); | |
| DefInt(SQLITE_IOERR_TRUNCATE); | |
| DefInt(SQLITE_IOERR_FSTAT); | |
| DefInt(SQLITE_IOERR_UNLOCK); | |
| DefInt(SQLITE_IOERR_RDLOCK); | |
| DefInt(SQLITE_IOERR_DELETE); | |
| DefInt(SQLITE_IOERR_BLOCKED); | |
| DefInt(SQLITE_IOERR_NOMEM); | |
| DefInt(SQLITE_IOERR_ACCESS); | |
| DefInt(SQLITE_IOERR_CHECKRESERVEDLOCK); | |
| DefInt(SQLITE_IOERR_LOCK); | |
| DefInt(SQLITE_IOERR_CLOSE); | |
| DefInt(SQLITE_IOERR_DIR_CLOSE); | |
| DefInt(SQLITE_IOERR_SHMOPEN); | |
| DefInt(SQLITE_IOERR_SHMSIZE); | |
| DefInt(SQLITE_IOERR_SHMLOCK); | |
| DefInt(SQLITE_IOERR_SHMMAP); | |
| DefInt(SQLITE_IOERR_SEEK); | |
| DefInt(SQLITE_IOERR_DELETE_NOENT); | |
| DefInt(SQLITE_IOERR_MMAP); | |
| DefInt(SQLITE_IOERR_GETTEMPPATH); | |
| DefInt(SQLITE_IOERR_CONVPATH); | |
| DefInt(SQLITE_IOERR_VNODE); | |
| DefInt(SQLITE_IOERR_AUTH); | |
| DefInt(SQLITE_IOERR_BEGIN_ATOMIC); | |
| DefInt(SQLITE_IOERR_COMMIT_ATOMIC); | |
| DefInt(SQLITE_IOERR_ROLLBACK_ATOMIC); | |
| DefInt(SQLITE_IOERR_DATA); | |
| DefInt(SQLITE_IOERR_CORRUPTFS); | |
| DefInt(SQLITE_LOCKED_SHAREDCACHE); | |
| DefInt(SQLITE_LOCKED_VTAB); | |
| DefInt(SQLITE_BUSY_RECOVERY); | |
| DefInt(SQLITE_BUSY_SNAPSHOT); | |
| DefInt(SQLITE_BUSY_TIMEOUT); | |
| DefInt(SQLITE_CANTOPEN_NOTEMPDIR); | |
| DefInt(SQLITE_CANTOPEN_ISDIR); | |
| DefInt(SQLITE_CANTOPEN_FULLPATH); | |
| DefInt(SQLITE_CANTOPEN_CONVPATH); | |
| //DefInt(SQLITE_CANTOPEN_DIRTYWAL)/*docs say not used*/; | |
| DefInt(SQLITE_CANTOPEN_SYMLINK); | |
| DefInt(SQLITE_CORRUPT_VTAB); | |
| DefInt(SQLITE_CORRUPT_SEQUENCE); | |
| DefInt(SQLITE_CORRUPT_INDEX); | |
| DefInt(SQLITE_READONLY_RECOVERY); | |
| DefInt(SQLITE_READONLY_CANTLOCK); | |
| DefInt(SQLITE_READONLY_ROLLBACK); | |
| DefInt(SQLITE_READONLY_DBMOVED); | |
| DefInt(SQLITE_READONLY_CANTINIT); | |
| DefInt(SQLITE_READONLY_DIRECTORY); | |
| DefInt(SQLITE_ABORT_ROLLBACK); | |
| DefInt(SQLITE_CONSTRAINT_CHECK); | |
| DefInt(SQLITE_CONSTRAINT_COMMITHOOK); | |
| DefInt(SQLITE_CONSTRAINT_FOREIGNKEY); | |
| DefInt(SQLITE_CONSTRAINT_FUNCTION); | |
| DefInt(SQLITE_CONSTRAINT_NOTNULL); | |
| DefInt(SQLITE_CONSTRAINT_PRIMARYKEY); | |
| DefInt(SQLITE_CONSTRAINT_TRIGGER); | |
| DefInt(SQLITE_CONSTRAINT_UNIQUE); | |
| DefInt(SQLITE_CONSTRAINT_VTAB); | |
| DefInt(SQLITE_CONSTRAINT_ROWID); | |
| DefInt(SQLITE_CONSTRAINT_PINNED); | |
| DefInt(SQLITE_CONSTRAINT_DATATYPE); | |
| DefInt(SQLITE_NOTICE_RECOVER_WAL); | |
| DefInt(SQLITE_NOTICE_RECOVER_ROLLBACK); | |
| DefInt(SQLITE_WARNING_AUTOINDEX); | |
| DefInt(SQLITE_AUTH_USER); | |
| DefInt(SQLITE_OK_LOAD_PERMANENTLY); | |
| //DefInt(SQLITE_OK_SYMLINK) /* internal use only */; | |
| } _DefGroup; | |
| DefGroup(serialize){ | |
| DefInt(SQLITE_SERIALIZE_NOCOPY); | |
| DefInt(SQLITE_DESERIALIZE_FREEONCLOSE); | |
| DefInt(SQLITE_DESERIALIZE_READONLY); | |
| DefInt(SQLITE_DESERIALIZE_RESIZEABLE); | |
| } _DefGroup; | |
| DefGroup(session){ | |
| DefInt(SQLITE_SESSION_CONFIG_STRMSIZE); | |
| DefInt(SQLITE_SESSION_OBJCONFIG_SIZE); | |
| } _DefGroup; | |
| DefGroup(sqlite3Status){ | |
| DefInt(SQLITE_STATUS_MEMORY_USED); | |
| DefInt(SQLITE_STATUS_PAGECACHE_USED); | |
| DefInt(SQLITE_STATUS_PAGECACHE_OVERFLOW); | |
| //DefInt(SQLITE_STATUS_SCRATCH_USED) /* NOT USED */; | |
| //DefInt(SQLITE_STATUS_SCRATCH_OVERFLOW) /* NOT USED */; | |
| DefInt(SQLITE_STATUS_MALLOC_SIZE); | |
| DefInt(SQLITE_STATUS_PARSER_STACK); | |
| DefInt(SQLITE_STATUS_PAGECACHE_SIZE); | |
| //DefInt(SQLITE_STATUS_SCRATCH_SIZE) /* NOT USED */; | |
| DefInt(SQLITE_STATUS_MALLOC_COUNT); | |
| } _DefGroup; | |
| DefGroup(stmtStatus){ | |
| DefInt(SQLITE_STMTSTATUS_FULLSCAN_STEP); | |
| DefInt(SQLITE_STMTSTATUS_SORT); | |
| DefInt(SQLITE_STMTSTATUS_AUTOINDEX); | |
| DefInt(SQLITE_STMTSTATUS_VM_STEP); | |
| DefInt(SQLITE_STMTSTATUS_REPREPARE); | |
| DefInt(SQLITE_STMTSTATUS_RUN); | |
| DefInt(SQLITE_STMTSTATUS_FILTER_MISS); | |
| DefInt(SQLITE_STMTSTATUS_FILTER_HIT); | |
| DefInt(SQLITE_STMTSTATUS_MEMUSED); | |
| } _DefGroup; | |
| DefGroup(syncFlags) { | |
| DefInt(SQLITE_SYNC_NORMAL); | |
| DefInt(SQLITE_SYNC_FULL); | |
| DefInt(SQLITE_SYNC_DATAONLY); | |
| } _DefGroup; | |
| DefGroup(trace) { | |
| DefInt(SQLITE_TRACE_STMT); | |
| DefInt(SQLITE_TRACE_PROFILE); | |
| DefInt(SQLITE_TRACE_ROW); | |
| DefInt(SQLITE_TRACE_CLOSE); | |
| } _DefGroup; | |
| DefGroup(txnState){ | |
| DefInt(SQLITE_TXN_NONE); | |
| DefInt(SQLITE_TXN_READ); | |
| DefInt(SQLITE_TXN_WRITE); | |
| } _DefGroup; | |
| DefGroup(udfFlags) { | |
| DefInt(SQLITE_DETERMINISTIC); | |
| DefInt(SQLITE_DIRECTONLY); | |
| DefInt(SQLITE_INNOCUOUS); | |
| DefInt(SQLITE_SUBTYPE); | |
| DefInt(SQLITE_RESULT_SUBTYPE); | |
| DefInt(SQLITE_SELFORDER1); | |
| } _DefGroup; | |
| DefGroup(version) { | |
| DefInt(SQLITE_VERSION_NUMBER); | |
| DefStr(SQLITE_VERSION); | |
| DefStr(SQLITE_SOURCE_ID); | |
| } _DefGroup; | |
| DefGroup(vtab) { | |
| DefInt(SQLITE_INDEX_SCAN_UNIQUE); | |
| DefInt(SQLITE_INDEX_CONSTRAINT_EQ); | |
| DefInt(SQLITE_INDEX_CONSTRAINT_GT); | |
| DefInt(SQLITE_INDEX_CONSTRAINT_LE); | |
| DefInt(SQLITE_INDEX_CONSTRAINT_LT); | |
| DefInt(SQLITE_INDEX_CONSTRAINT_GE); | |
| DefInt(SQLITE_INDEX_CONSTRAINT_MATCH); | |
| DefInt(SQLITE_INDEX_CONSTRAINT_LIKE); | |
| DefInt(SQLITE_INDEX_CONSTRAINT_GLOB); | |
| DefInt(SQLITE_INDEX_CONSTRAINT_REGEXP); | |
| DefInt(SQLITE_INDEX_CONSTRAINT_NE); | |
| DefInt(SQLITE_INDEX_CONSTRAINT_ISNOT); | |
| DefInt(SQLITE_INDEX_CONSTRAINT_ISNOTNULL); | |
| DefInt(SQLITE_INDEX_CONSTRAINT_ISNULL); | |
| DefInt(SQLITE_INDEX_CONSTRAINT_IS); | |
| DefInt(SQLITE_INDEX_CONSTRAINT_LIMIT); | |
| DefInt(SQLITE_INDEX_CONSTRAINT_OFFSET); | |
| DefInt(SQLITE_INDEX_CONSTRAINT_FUNCTION); | |
| DefInt(SQLITE_VTAB_CONSTRAINT_SUPPORT); | |
| DefInt(SQLITE_VTAB_INNOCUOUS); | |
| DefInt(SQLITE_VTAB_DIRECTONLY); | |
| DefInt(SQLITE_VTAB_USES_ALL_SCHEMAS); | |
| DefInt(SQLITE_ROLLBACK); | |
| //DefInt(SQLITE_IGNORE); // Also used by sqlite3_authorizer() callback | |
| DefInt(SQLITE_FAIL); | |
| //DefInt(SQLITE_ABORT); // Also an error code | |
| DefInt(SQLITE_REPLACE); | |
| } _DefGroup; | |
| /* | |
| ** Emit an array of "StructBinder" struct descriptions, which look | |
| ** like: | |
| ** | |
| ** { | |
| ** "name": "MyStruct", | |
| ** "sizeof": 16, | |
| ** "members": { | |
| ** "member1": {"offset": 0,"sizeof": 4,"signature": "i"}, | |
| ** "member2": {"offset": 4,"sizeof": 4,"signature": "p"}, | |
| ** "member3": {"offset": 8,"sizeof": 8,"signature": "j"} | |
| ** } | |
| ** } | |
| ** | |
| ** Detailed documentation for those bits are in the Jaccwabyt | |
| ** JS-side component. | |
| */ | |
| /** Macros for emitting StructBinder description. */ | |
| /** ^^^ indirection needed to expand CurrentStruct */ | |
| nStruct = 0; | |
| out(", \"structs\": ["); { | |
| StructBinder { | |
| M(iVersion, "i"); | |
| M(szOsFile, "i"); | |
| M(mxPathname, "i"); | |
| M(pNext, "p"); | |
| M(zName, "s"); | |
| M(pAppData, "p"); | |
| M(xOpen, "i(pppip)"); | |
| M(xDelete, "i(ppi)"); | |
| M(xAccess, "i(ppip)"); | |
| M(xFullPathname, "i(ppip)"); | |
| M(xDlOpen, "v(pp)"); | |
| M(xDlError, "v(pip)"); | |
| M(xDlSym, "p()"); | |
| M(xDlClose, "v(pp)"); | |
| M(xRandomness, "i(pip)"); | |
| M(xSleep, "i(pi)"); | |
| M(xCurrentTime, "i(pp)"); | |
| M(xGetLastError, "i(pip)"); | |
| M(xCurrentTimeInt64, "i(pp)"); | |
| M(xSetSystemCall, "i(ppp)"); | |
| M(xGetSystemCall, "p(pp)"); | |
| M(xNextSystemCall, "p(pp)"); | |
| } _StructBinder; | |
| StructBinder { | |
| M(iVersion, "i"); | |
| M(xClose, "i(p)"); | |
| M(xRead, "i(ppij)"); | |
| M(xWrite, "i(ppij)"); | |
| M(xTruncate, "i(pj)"); | |
| M(xSync, "i(pi)"); | |
| M(xFileSize, "i(pp)"); | |
| M(xLock, "i(pi)"); | |
| M(xUnlock, "i(pi)"); | |
| M(xCheckReservedLock, "i(pp)"); | |
| M(xFileControl, "i(pip)"); | |
| M(xSectorSize, "i(p)"); | |
| M(xDeviceCharacteristics, "i(p)"); | |
| M(xShmMap, "i(piiip)"); | |
| M(xShmLock, "i(piii)"); | |
| M(xShmBarrier, "v(p)"); | |
| M(xShmUnmap, "i(pi)"); | |
| M(xFetch, "i(pjip)"); | |
| M(xUnfetch, "i(pjp)"); | |
| } _StructBinder; | |
| StructBinder { | |
| M(pMethods, "p"); | |
| } _StructBinder; | |
| /* From os_kv.c */ | |
| StructBinder { | |
| M(xRcrdRead, "i(sspi)"); | |
| M(xRcrdWrite, "i(sss)"); | |
| M(xRcrdDelete, "i(ss)"); | |
| MRO(nKeySize, "i"); | |
| MRO(nBufferSize, "i"); | |
| M(pVfs, "p"); | |
| M(pIoDb, "p"); | |
| M(pIoJrnl, "p"); | |
| } _StructBinder; | |
| /* From os_kv.c */ | |
| StructBinder { | |
| M(base, "p")/*sqlite3_file base*/; | |
| M(zClass, "s"); | |
| M(isJournal, "i"); | |
| M(nJrnl, "i")/*actually unsigned!*/; | |
| M(aJrnl, "p"); | |
| M(szPage, "i"); | |
| M(szDb, "j"); | |
| M(aData, "p"); | |
| } _StructBinder; | |
| StructBinder { | |
| M(pModule, "p"); | |
| M(nRef, "i"); | |
| M(zErrMsg, "p"); | |
| } _StructBinder; | |
| StructBinder { | |
| M(pVtab, "p"); | |
| } _StructBinder; | |
| StructBinder { | |
| M(iVersion, "i"); | |
| M(xCreate, "i(ppippp)"); | |
| M(xConnect, "i(ppippp)"); | |
| M(xBestIndex, "i(pp)"); | |
| M(xDisconnect, "i(p)"); | |
| M(xDestroy, "i(p)"); | |
| M(xOpen, "i(pp)"); | |
| M(xClose, "i(p)"); | |
| M(xFilter, "i(pisip)"); | |
| M(xNext, "i(p)"); | |
| M(xEof, "i(p)"); | |
| M(xColumn, "i(ppi)"); | |
| M(xRowid, "i(pp)"); | |
| M(xUpdate, "i(pipp)"); | |
| M(xBegin, "i(p)"); | |
| M(xSync, "i(p)"); | |
| M(xCommit, "i(p)"); | |
| M(xRollback, "i(p)"); | |
| M(xFindFunction, "i(pispp)"); | |
| M(xRename, "i(ps)"); | |
| // ^^^ v1. v2+ follows... | |
| M(xSavepoint, "i(pi)"); | |
| M(xRelease, "i(pi)"); | |
| M(xRollbackTo, "i(pi)"); | |
| // ^^^ v2. v3+ follows... | |
| M(xShadowName, "i(s)"); | |
| // ^^^ v3. v4+ follows... | |
| M(xIntegrity, "i(pppip)"); | |
| } _StructBinder; | |
| /** | |
| ** Workaround: in order to map the various inner structs from | |
| ** sqlite3_index_info, we have to uplift those into constructs we | |
| ** can access by type name. These structs _must_ match their | |
| ** in-sqlite3_index_info counterparts byte for byte. | |
| ** | |
| ** 2025-11-21: this uplifing is no longer necessary, as Jaccwabyt | |
| ** can now handle nested structs, but "it ain't broke" so there's | |
| ** no pressing need to rewire this. Also, it's conceivable that | |
| ** rewiring it might break downstream vtab impls, so it shouldn't | |
| ** be rewired. | |
| */ | |
| typedef struct { | |
| int iColumn; | |
| unsigned char op; | |
| unsigned char usable; | |
| int iTermOffset; | |
| } sqlite3_index_constraint; | |
| typedef struct { | |
| int iColumn; | |
| unsigned char desc; | |
| } sqlite3_index_orderby; | |
| typedef struct { | |
| int argvIndex; | |
| unsigned char omit; | |
| } sqlite3_index_constraint_usage; | |
| { /* Validate that the above struct sizeof()s match | |
| ** expectations. We could improve upon this by | |
| ** checking the offsetof() for each member. */ | |
| const sqlite3_index_info siiCheck = {0}; | |
| if(!IndexSzCheck(sqlite3_index_constraint,aConstraint) | |
| || !IndexSzCheck(sqlite3_index_orderby,aOrderBy) | |
| || !IndexSzCheck(sqlite3_index_constraint_usage,aConstraintUsage)){ | |
| assert(!"sizeof mismatch in sqlite3_index_... struct(s)"); | |
| return 0; | |
| } | |
| } | |
| StructBinder { | |
| M(iColumn, "i"); | |
| M(op, "C"); | |
| M(usable, "C"); | |
| M(iTermOffset, "i"); | |
| } _StructBinder; | |
| StructBinder { | |
| M(iColumn, "i"); | |
| M(desc, "C"); | |
| } _StructBinder; | |
| StructBinder { | |
| M(argvIndex, "i"); | |
| M(omit, "C"); | |
| } _StructBinder; | |
| StructBinder { | |
| M(nConstraint, "i"); | |
| M(aConstraint, "p"); | |
| M(nOrderBy, "i"); | |
| M(aOrderBy, "p"); | |
| M(aConstraintUsage, "p"); | |
| M(idxNum, "i"); | |
| M(idxStr, "p"); | |
| M(needToFreeIdxStr, "i"); | |
| M(orderByConsumed, "i"); | |
| M(estimatedCost, "d"); | |
| M(estimatedRows, "j"); | |
| M(idxFlags, "i"); | |
| M(colUsed, "j"); | |
| } _StructBinder; | |
| StructBinder { | |
| M(v4, "i"); | |
| M(cstr, "s"); | |
| M(ppV, "p"); | |
| M(v8, "j"); | |
| M(xFunc, "v(p)"); | |
| } _StructBinder; | |
| } out( "]"/*structs*/); | |
| out("}"/*top-level object*/); | |
| *zPos = 0; | |
| aBuffer[0] = '{'/*end of the race-condition workaround*/; | |
| return aBuffer; | |
| } | |
| /* | |
| ** This function is NOT part of the sqlite3 public API. It is strictly | |
| ** for use by the sqlite project's own JS/WASM bindings. | |
| ** | |
| ** This function invokes the xDelete method of the given VFS (or the | |
| ** default VFS if pVfs is NULL), passing on the given filename. If | |
| ** zName is NULL, no default VFS is found, or it has no xDelete | |
| ** method, SQLITE_MISUSE is returned, else the result of the xDelete() | |
| ** call is returned. | |
| */ | |
| SQLITE_WASM_EXPORT2(int,sqlite3__wasm_vfs_unlink,(sqlite3_vfs *pVfs, const char *zName)){ | |
| int rc = SQLITE_MISUSE /* ??? */; | |
| if( 0==pVfs && 0!=zName ) pVfs = sqlite3_vfs_find(0); | |
| if( zName && pVfs && pVfs->xDelete ){ | |
| rc = pVfs->xDelete(pVfs, zName, 1); | |
| } | |
| return rc; | |
| } | |
| /* | |
| ** This function is NOT part of the sqlite3 public API. It is strictly | |
| ** for use by the sqlite project's own JS/WASM bindings. | |
| ** | |
| ** Returns a pointer to the given DB's VFS for the given DB name, | |
| ** defaulting to "main" if zDbName is 0. Returns 0 if no db with the | |
| ** given name is open. | |
| */ | |
| SQLITE_WASM_EXPORT2(sqlite3_vfs *,sqlite3__wasm_db_vfs,(sqlite3 *pDb, const char *zDbName)){ | |
| sqlite3_vfs * pVfs = 0; | |
| sqlite3_file_control(pDb, zDbName ? zDbName : "main", | |
| SQLITE_FCNTL_VFS_POINTER, &pVfs); | |
| return pVfs; | |
| } | |
| /* | |
| ** This function is NOT part of the sqlite3 public API. It is strictly | |
| ** for use by the sqlite project's own JS/WASM bindings. | |
| ** | |
| ** This function resets the given db pointer's database as described at | |
| ** | |
| ** https://sqlite.org/c3ref/c_dbconfig_defensive.html#sqlitedbconfigresetdatabase | |
| ** | |
| ** But beware: virtual tables destroyed that way do not have their | |
| ** xDestroy() called, so will leak if they require that function for | |
| ** proper cleanup. | |
| ** | |
| ** Returns 0 on success, an SQLITE_xxx code on error. Returns | |
| ** SQLITE_MISUSE if pDb is NULL. | |
| */ | |
| SQLITE_WASM_EXPORT2(int,sqlite3__wasm_db_reset,(sqlite3 *pDb)){ | |
| int rc = SQLITE_MISUSE; | |
| if( pDb ){ | |
| sqlite3_table_column_metadata(pDb, "main", 0, 0, 0, 0, 0, 0, 0); | |
| rc = sqlite3_db_config(pDb, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0); | |
| if( 0==rc ){ | |
| rc = sqlite3_exec(pDb, "VACUUM", 0, 0, 0); | |
| sqlite3_db_config(pDb, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0); | |
| } | |
| } | |
| return rc; | |
| } | |
| /* | |
| ** This function is NOT part of the sqlite3 public API. It is strictly | |
| ** for use by the sqlite project's own JS/WASM bindings. | |
| ** | |
| ** Uses the given database's VFS xRead to stream the db file's | |
| ** contents out to the given callback. The callback gets a single | |
| ** chunk of size n (its 2nd argument) on each call and must return 0 | |
| ** on success, non-0 on error. This function returns 0 on success, | |
| ** SQLITE_NOTFOUND if no db is open, or propagates any other non-0 | |
| ** code from the callback. Note that this is not thread-friendly: it | |
| ** expects that it will be the only thread reading the db file and | |
| ** takes no measures to ensure that is the case. | |
| ** | |
| ** This implementation appears to work fine, but | |
| ** sqlite3__wasm_db_serialize() is arguably the better way to achieve | |
| ** this. | |
| */ | |
| SQLITE_WASM_EXPORT | |
| int sqlite3__wasm_db_export_chunked( sqlite3* pDb, | |
| int (*xCallback)(unsigned const char *zOut, int n) ){ | |
| sqlite3_int64 nSize = 0; | |
| sqlite3_int64 nPos = 0; | |
| sqlite3_file * pFile = 0; | |
| unsigned char buf[1024 * 8]; | |
| int nBuf = (int)sizeof(buf); | |
| int rc = pDb | |
| ? sqlite3_file_control(pDb, "main", | |
| SQLITE_FCNTL_FILE_POINTER, &pFile) | |
| : SQLITE_NOTFOUND; | |
| if( rc ) return rc; | |
| rc = pFile->pMethods->xFileSize(pFile, &nSize); | |
| if( rc ) return rc; | |
| if(nSize % nBuf){ | |
| /* DB size is not an even multiple of the buffer size. Reduce | |
| ** buffer size so that we do not unduly inflate the db size | |
| ** with zero-padding when exporting. */ | |
| if(0 == nSize % 4096) nBuf = 4096; | |
| else if(0 == nSize % 2048) nBuf = 2048; | |
| else if(0 == nSize % 1024) nBuf = 1024; | |
| else nBuf = 512; | |
| } | |
| for( ; 0==rc && nPos<nSize; nPos += nBuf ){ | |
| rc = pFile->pMethods->xRead(pFile, buf, nBuf, nPos); | |
| if( SQLITE_IOERR_SHORT_READ == rc ){ | |
| rc = (nPos + nBuf) < nSize ? rc : 0/*assume EOF*/; | |
| } | |
| if( 0==rc ) rc = xCallback(buf, nBuf); | |
| } | |
| return rc; | |
| } | |
| /* | |
| ** This function is NOT part of the sqlite3 public API. It is strictly | |
| ** for use by the sqlite project's own JS/WASM bindings. | |
| ** | |
| ** A proxy for sqlite3_serialize() which serializes the schema zSchema | |
| ** of pDb, placing the serialized output in pOut and nOut. nOut may be | |
| ** NULL. If zSchema is NULL then "main" is assumed. If pDb or pOut are | |
| ** NULL then SQLITE_MISUSE is returned. If allocation of the | |
| ** serialized copy fails, SQLITE_NOMEM is returned. On success, 0 is | |
| ** returned and `*pOut` will contain a pointer to the memory unless | |
| ** mFlags includes SQLITE_SERIALIZE_NOCOPY and the database has no | |
| ** contiguous memory representation, in which case `*pOut` will be | |
| ** NULL but 0 will be returned. | |
| ** | |
| ** If `*pOut` is not NULL, the caller is responsible for passing it to | |
| ** sqlite3_free() to free it. | |
| */ | |
| SQLITE_WASM_EXPORT2(int,sqlite3__wasm_db_serialize, | |
| (sqlite3 *pDb, const char *zSchema, | |
| unsigned char **pOut, | |
| sqlite3_int64 *nOut, unsigned int mFlags)){ | |
| unsigned char * z; | |
| if( !pDb || !pOut ) return SQLITE_MISUSE; | |
| if( nOut ) *nOut = 0; | |
| z = sqlite3_serialize(pDb, zSchema ? zSchema : "main", nOut, mFlags); | |
| if( z || (SQLITE_SERIALIZE_NOCOPY & mFlags) ){ | |
| *pOut = z; | |
| return 0; | |
| }else{ | |
| return SQLITE_NOMEM; | |
| } | |
| } | |
| /* | |
| ** This function is NOT part of the sqlite3 public API. It is strictly | |
| ** for use by the sqlite project's own JS/WASM bindings. | |
| ** | |
| ** ACHTUNG: it was discovered on 2023-08-11 that, with SQLITE_DEBUG, | |
| ** this function's out-of-scope use of the sqlite3_vfs/file/io_methods | |
| ** APIs leads to triggering of assertions in the core library. Its use | |
| ** is now deprecated and VFS-specific APIs for importing files need to | |
| ** be found to replace it. sqlite3__wasm_posix_create_file() is | |
| ** suitable for the "unix" family of VFSes. | |
| ** | |
| ** Creates a new file using the I/O API of the given VFS, containing | |
| ** the given number of bytes of the given data. If the file exists, it | |
| ** is truncated to the given length and populated with the given | |
| ** data. | |
| ** | |
| ** This function exists so that we can implement the equivalent of | |
| ** Emscripten's FS.createDataFile() in a VFS-agnostic way. This | |
| ** functionality is intended for use in uploading database files. | |
| ** | |
| ** Not all VFSes support this functionality, e.g. the "kvvfs" does | |
| ** not. | |
| ** | |
| ** If pVfs is NULL, sqlite3_vfs_find(0) is used. | |
| ** | |
| ** If zFile is NULL, pVfs is NULL (and sqlite3_vfs_find(0) returns | |
| ** NULL), or nData is negative, SQLITE_MISUSE are returned. | |
| ** | |
| ** On success, it creates a new file with the given name, populated | |
| ** with the first nData bytes of pData. If pData is NULL, the file is | |
| ** created and/or truncated to nData bytes. | |
| ** | |
| ** Whether or not directory components of zFilename are created | |
| ** automatically or not is unspecified: that detail is left to the | |
| ** VFS. The "opfs" VFS, for example, creates them. | |
| ** | |
| ** If an error happens while populating or truncating the file, the | |
| ** target file will be deleted (if needed) if this function created | |
| ** it. If this function did not create it, it is not deleted but may | |
| ** be left in an undefined state. | |
| ** | |
| ** Returns 0 on success. On error, it returns a code described above | |
| ** or propagates a code from one of the I/O methods. | |
| ** | |
| ** Design note: nData is an integer, instead of int64, for WASM | |
| ** portability, so that the API can still work in builds where BigInt | |
| ** support is disabled or unavailable. | |
| */ | |
| SQLITE_WASM_EXPORT2(int,sqlite3__wasm_vfs_create_file, | |
| (sqlite3_vfs *pVfs, const char *zFilename, | |
| const unsigned char * pData, int nData)){ | |
| int rc; | |
| sqlite3_file *pFile = 0; | |
| sqlite3_io_methods const *pIo; | |
| const int openFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | |
| | SQLITE_OPEN_MAIN_JOURNAL | |
| /* ^^^^ This is for testing a horrible workaround to avoid | |
| triggering a specific assert() in os_unix.c:unixOpen(). Please | |
| do not enable this in real builds. */ | |
| ; | |
| int flagsOut = 0; | |
| int fileExisted = 0; | |
| int doUnlock = 0; | |
| const unsigned char *pPos = pData; | |
| const int blockSize = 512 | |
| /* Because we are using pFile->pMethods->xWrite() for writing, and | |
| ** it may have a buffer limit related to sqlite3's pager size, we | |
| ** conservatively write in 512-byte blocks (smallest page | |
| ** size). */; | |
| //fprintf(stderr, "pVfs=%p, zFilename=%s, nData=%d\n", pVfs, zFilename, nData); | |
| if( !pVfs ) pVfs = sqlite3_vfs_find(0); | |
| if( !pVfs || !zFilename || nData<0 ) return SQLITE_MISUSE; | |
| pVfs->xAccess(pVfs, zFilename, SQLITE_ACCESS_EXISTS, &fileExisted); | |
| rc = sqlite3OsOpenMalloc(pVfs, zFilename, &pFile, openFlags, &flagsOut); | |
| RC; | |
| if(rc) return rc; | |
| pIo = pFile->pMethods; | |
| if( pIo->xLock ) { | |
| /* We need xLock() in order to accommodate the OPFS VFS, as it | |
| ** obtains a writeable handle via the lock operation and releases | |
| ** it in xUnlock(). If we don't do those here, we have to add code | |
| ** to the VFS to account check whether it was locked before | |
| ** xFileSize(), xTruncate(), and the like, and release the lock | |
| ** only if it was unlocked when the op was started. */ | |
| rc = pIo->xLock(pFile, SQLITE_LOCK_EXCLUSIVE); | |
| RC; | |
| doUnlock = 0==rc; | |
| } | |
| if( 0==rc ){ | |
| rc = pIo->xTruncate(pFile, nData); | |
| RC; | |
| } | |
| if( 0==rc && 0!=pData && nData>0 ){ | |
| while( 0==rc && nData>0 ){ | |
| const int n = nData>=blockSize ? blockSize : nData; | |
| rc = pIo->xWrite(pFile, pPos, n, (sqlite3_int64)(pPos - pData)); | |
| RC; | |
| nData -= n; | |
| pPos += n; | |
| } | |
| if( 0==rc && nData>0 ){ | |
| assert( nData<blockSize ); | |
| rc = pIo->xWrite(pFile, pPos, nData, | |
| (sqlite3_int64)(pPos - pData)); | |
| RC; | |
| } | |
| } | |
| if( pIo->xUnlock && doUnlock!=0 ){ | |
| pIo->xUnlock(pFile, SQLITE_LOCK_NONE); | |
| } | |
| pIo->xClose(pFile); | |
| if( rc!=0 && 0==fileExisted ){ | |
| pVfs->xDelete(pVfs, zFilename, 1); | |
| } | |
| RC; | |
| return rc; | |
| } | |
| /** | |
| ** This function is NOT part of the sqlite3 public API. It is strictly | |
| ** for use by the sqlite project's own JS/WASM bindings. | |
| ** | |
| ** Creates or overwrites a file using the POSIX file API, | |
| ** i.e. Emscripten's virtual filesystem. Creates or truncates | |
| ** zFilename, appends pData bytes to it, and returns 0 on success or | |
| ** SQLITE_IOERR on error. | |
| */ | |
| SQLITE_WASM_EXPORT2(int,sqlite3__wasm_posix_create_file, | |
| (const char *zFilename, const unsigned char * pData, | |
| int nData)){ | |
| int rc; | |
| FILE * pFile = 0; | |
| int fileExisted = 0; | |
| size_t nWrote = 1; | |
| if( !zFilename || nData<0 || (pData==0 && nData>0) ) return SQLITE_MISUSE; | |
| pFile = fopen(zFilename, "w"); | |
| if( 0==pFile ) return SQLITE_IOERR; | |
| if( nData>0 ){ | |
| nWrote = fwrite(pData, (size_t)nData, 1, pFile); | |
| } | |
| fclose(pFile); | |
| return 1==nWrote ? 0 : SQLITE_IOERR; | |
| } | |
| /* | |
| ** This function is NOT part of the sqlite3 public API. It is strictly | |
| ** for use by the sqlite project's own JS/WASM bindings. | |
| ** | |
| ** This returns either a pointer to a static buffer or zKeyIn directly | |
| ** (if zClass is NULL or empty). | |
| */ | |
| SQLITE_WASM_EXPORT2(const char *,sqlite3__wasm_kvvfsMakeKey, | |
| (const char *zClass, const char *zKeyIn)){ | |
| static char buf[SQLITE_KVOS_SZ+1] = {0}; | |
| assert(sqlite3KvvfsMethods.nKeySize>24); | |
| if( zClass && *zClass ){ | |
| kvrecordMakeKey(zClass, zKeyIn, buf); | |
| return buf; | |
| }else{ | |
| /* We can return zKeyIn here only because the JS API takes special | |
| ** care with its lifetime.*/ | |
| return zKeyIn; | |
| /* It would be nice to be able to return zKeyIn directly here, but | |
| ** it may have been allocated as part of the automated JS-to-WASM | |
| ** conversions, in which case it will be freed before reaching the | |
| ** caller. */ | |
| sqlite3_snprintf(KVRECORD_KEY_SZ, buf, "%s", zKeyIn); | |
| return buf; | |
| } | |
| } | |
| /* | |
| ** This function is NOT part of the sqlite3 public API. It is strictly | |
| ** for use by the sqlite project's own JS/WASM bindings. | |
| ** | |
| ** Returns the pointer to the singleton object which holds the kvvfs | |
| ** I/O methods and associated state. | |
| */ | |
| SQLITE_WASM_EXPORT2(sqlite3_kvvfs_methods *,sqlite3__wasm_kvvfs_methods,(void)){ | |
| return &sqlite3KvvfsMethods; | |
| } | |
| /* | |
| ** This function is NOT part of the sqlite3 public API. It is strictly | |
| ** for use by the sqlite project's own JS/WASM bindings. | |
| ** | |
| ** This is a proxy for the variadic sqlite3_vtab_config() which passes | |
| ** its argument on, or not, to sqlite3_vtab_config(), depending on the | |
| ** value of its 2nd argument. Returns the result of | |
| ** sqlite3_vtab_config(), or SQLITE_MISUSE if the 2nd arg is not a | |
| ** valid value. | |
| */ | |
| SQLITE_WASM_EXPORT2(int,sqlite3__wasm_vtab_config, | |
| (sqlite3 *pDb, int op, int arg)){ | |
| switch(op){ | |
| case SQLITE_VTAB_DIRECTONLY: | |
| case SQLITE_VTAB_INNOCUOUS: | |
| return sqlite3_vtab_config(pDb, op); | |
| case SQLITE_VTAB_CONSTRAINT_SUPPORT: | |
| return sqlite3_vtab_config(pDb, op, arg); | |
| default: | |
| return SQLITE_MISUSE; | |
| } | |
| } | |
| /* | |
| ** This function is NOT part of the sqlite3 public API. It is strictly | |
| ** for use by the sqlite project's own JS/WASM bindings. | |
| ** | |
| ** Wrapper for the variants of sqlite3_db_config() which take | |
| ** (int,int*) variadic args. | |
| */ | |
| SQLITE_WASM_EXPORT2(int,sqlite3__wasm_db_config_ip, | |
| (sqlite3 *pDb, int op, int arg1, int* pArg2)){ | |
| switch(op){ | |
| case SQLITE_DBCONFIG_ENABLE_FKEY: | |
| case SQLITE_DBCONFIG_ENABLE_TRIGGER: | |
| case SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER: | |
| case SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION: | |
| case SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE: | |
| case SQLITE_DBCONFIG_ENABLE_QPSG: | |
| case SQLITE_DBCONFIG_TRIGGER_EQP: | |
| case SQLITE_DBCONFIG_RESET_DATABASE: | |
| case SQLITE_DBCONFIG_DEFENSIVE: | |
| case SQLITE_DBCONFIG_WRITABLE_SCHEMA: | |
| case SQLITE_DBCONFIG_LEGACY_ALTER_TABLE: | |
| case SQLITE_DBCONFIG_DQS_DML: | |
| case SQLITE_DBCONFIG_DQS_DDL: | |
| case SQLITE_DBCONFIG_ENABLE_VIEW: | |
| case SQLITE_DBCONFIG_LEGACY_FILE_FORMAT: | |
| case SQLITE_DBCONFIG_TRUSTED_SCHEMA: | |
| case SQLITE_DBCONFIG_STMT_SCANSTATUS: | |
| case SQLITE_DBCONFIG_REVERSE_SCANORDER: | |
| case SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE: | |
| case SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE: | |
| case SQLITE_DBCONFIG_ENABLE_COMMENTS: | |
| return sqlite3_db_config(pDb, op, arg1, pArg2); | |
| default: return SQLITE_MISUSE; | |
| } | |
| } | |
| /* | |
| ** This function is NOT part of the sqlite3 public API. It is strictly | |
| ** for use by the sqlite project's own JS/WASM bindings. | |
| ** | |
| ** Wrapper for the variants of sqlite3_db_config() which take | |
| ** (void*,int,int) variadic args. | |
| */ | |
| SQLITE_WASM_EXPORT2(int,sqlite3__wasm_db_config_pii, | |
| (sqlite3 *pDb, int op, void * pArg1, int arg2, | |
| int arg3)){ | |
| switch(op){ | |
| case SQLITE_DBCONFIG_LOOKASIDE: | |
| return sqlite3_db_config(pDb, op, pArg1, arg2, arg3); | |
| default: return SQLITE_MISUSE; | |
| } | |
| } | |
| /* | |
| ** This function is NOT part of the sqlite3 public API. It is strictly | |
| ** for use by the sqlite project's own JS/WASM bindings. | |
| ** | |
| ** Wrapper for the variants of sqlite3_db_config() which take | |
| ** (const char *) variadic args. | |
| */ | |
| SQLITE_WASM_EXPORT2(int,sqlite3__wasm_db_config_s,(sqlite3 *pDb, int op, | |
| const char *zArg)){ | |
| switch(op){ | |
| case SQLITE_DBCONFIG_MAINDBNAME: | |
| return sqlite3_db_config(pDb, op, zArg); | |
| default: return SQLITE_MISUSE; | |
| } | |
| } | |
| /* | |
| ** This function is NOT part of the sqlite3 public API. It is strictly | |
| ** for use by the sqlite project's own JS/WASM bindings. | |
| ** | |
| ** Binding for combinations of sqlite3_config() arguments which take | |
| ** a single integer argument. | |
| */ | |
| SQLITE_WASM_EXPORT2(int,sqlite3__wasm_config_i,(int op, int arg)){ | |
| return sqlite3_config(op, arg); | |
| } | |
| /* | |
| ** This function is NOT part of the sqlite3 public API. It is strictly | |
| ** for use by the sqlite project's own JS/WASM bindings. | |
| ** | |
| ** Binding for combinations of sqlite3_config() arguments which take | |
| ** two int arguments. | |
| */ | |
| SQLITE_WASM_EXPORT2(int,sqlite3__wasm_config_ii,(int op, int arg1, int arg2)){ | |
| return sqlite3_config(op, arg1, arg2); | |
| } | |
| /* | |
| ** This function is NOT part of the sqlite3 public API. It is strictly | |
| ** for use by the sqlite project's own JS/WASM bindings. | |
| ** | |
| ** Binding for combinations of sqlite3_config() arguments which take | |
| ** a single i64 argument. | |
| */ | |
| SQLITE_WASM_EXPORT2(int,sqlite3__wasm_config_j,(int op, sqlite3_int64 arg)){ | |
| return sqlite3_config(op, arg); | |
| } | |
| /* | |
| ** This function is NOT part of the sqlite3 public API. It is strictly | |
| ** for use by the sqlite project's own JS/WASM bindings. | |
| ** | |
| ** If z is not NULL, returns the result of passing z to | |
| ** sqlite3_mprintf()'s %Q modifier (if addQuotes is true) or %q (if | |
| ** addQuotes is 0). Returns NULL if z is NULL or on OOM. | |
| */ | |
| SQLITE_WASM_EXPORT2(char *,sqlite3__wasm_qfmt_token,(char *z, int addQuotes)){ | |
| char * rc = 0; | |
| if( z ){ | |
| rc = addQuotes | |
| ? sqlite3_mprintf("%Q", z) | |
| : sqlite3_mprintf("%q", z); | |
| } | |
| return rc; | |
| } | |
| /* | |
| ** This function is NOT part of the sqlite3 public API. It is strictly | |
| ** for use by the sqlite project's own JS/WASM bindings. | |
| ** | |
| ** A WASM wrapper for the interal os_kv.c:kvvfsDecode() for internal | |
| ** use by the kvvfs v2 API. | |
| */ | |
| SQLITE_WASM_EXPORT2(int,sqlite3__wasm_kvvfs_decode,(const char *a, char *aOut, int nOut)){ | |
| return kvvfsDecode(a, aOut, nOut); | |
| } | |
| SQLITE_WASM_EXPORT2(int,sqlite3__wasm_kvvfs_encode,(const char *a, int nA, char *aOut)){ | |
| return kvvfsEncode(a, nA, aOut); | |
| } | |
| /* | |
| ** This function is NOT part of the sqlite3 public API. It is strictly | |
| ** for use by the sqlite project's own JS/WASM bindings, specifically | |
| ** only when building with Emscripten's WASMFS support. | |
| ** | |
| ** This function should only be called if the JS side detects the | |
| ** existence of the Origin-Private FileSystem (OPFS) APIs in the | |
| ** client. The first time it is called, this function instantiates a | |
| ** WASMFS backend impl for OPFS. On success, subsequent calls are | |
| ** no-ops. | |
| ** | |
| ** This function may be passed a "mount point" name, which must have a | |
| ** leading "/" and is currently restricted to a single path component, | |
| ** e.g. "/foo" is legal but "/foo/" and "/foo/bar" are not. If it is | |
| ** NULL or empty, it defaults to "/opfs". | |
| ** | |
| ** Returns 0 on success, SQLITE_NOMEM if instantiation of the backend | |
| ** object fails, SQLITE_IOERR if mkdir() of the zMountPoint dir in | |
| ** the virtual FS fails. In builds compiled without SQLITE_ENABLE_WASMFS | |
| ** defined, SQLITE_NOTFOUND is returned without side effects. | |
| */ | |
| SQLITE_WASM_EXPORT2(int,sqlite3__wasm_init_wasmfs,(const char *zMountPoint)){ | |
| static backend_t pOpfs = 0; | |
| if( !zMountPoint || !*zMountPoint ) zMountPoint = "/opfs"; | |
| if( !pOpfs ){ | |
| pOpfs = wasmfs_create_opfs_backend(); | |
| } | |
| /** It's not enough to instantiate the backend. We have to create a | |
| mountpoint in the VFS and attach the backend to it. */ | |
| if( pOpfs && 0!=access(zMountPoint, F_OK) ){ | |
| /* Note that this check and is not robust but it will | |
| hypothetically suffice for the transient wasm-based virtual | |
| filesystem we're currently running in. */ | |
| const int rc = wasmfs_create_directory(zMountPoint, 0777, pOpfs); | |
| /*emscripten_console_logf("OPFS mkdir(%s) rc=%d", zMountPoint, rc);*/ | |
| if(rc) return SQLITE_IOERR; | |
| } | |
| return pOpfs ? 0 : SQLITE_NOMEM; | |
| } | |
| SQLITE_WASM_EXPORT2(int,sqlite3__wasm_init_wasmfs,(const char *zUnused)){ | |
| //emscripten_console_warn("WASMFS OPFS is not compiled in."); | |
| (void)zUnused; | |
| return SQLITE_NOTFOUND; | |
| } | |
| SQLITE_WASM_EXPORT2(int,sqlite3__wasm_test_intptr,(int * p)){ | |
| return *p = *p * 2; | |
| } | |
| SQLITE_WASM_EXPORT2(void *,sqlite3__wasm_test_voidptr,(void * p)){ | |
| return p; | |
| } | |
| SQLITE_WASM_EXPORT2(int64_t,sqlite3__wasm_test_int64_max,(void)){ | |
| return (int64_t)0x7fffffffffffffff; | |
| } | |
| SQLITE_WASM_EXPORT2(int64_t,sqlite3__wasm_test_int64_min,(void)){ | |
| return ~sqlite3__wasm_test_int64_max(); | |
| } | |
| SQLITE_WASM_EXPORT2(int64_t,sqlite3__wasm_test_int64_times2,(int64_t x)){ | |
| return x * 2; | |
| } | |
| SQLITE_WASM_EXPORT2(void,sqlite3__wasm_test_int64_minmax,(int64_t * min, int64_t *max)){ | |
| *max = sqlite3__wasm_test_int64_max(); | |
| *min = sqlite3__wasm_test_int64_min(); | |
| /*printf("minmax: min=%lld, max=%lld\n", *min, *max);*/ | |
| } | |
| SQLITE_WASM_EXPORT2(int64_t,sqlite3__wasm_test_int64ptr,(int64_t * p)){ | |
| /*printf("sqlite3__wasm_test_int64ptr( @%lld = 0x%llx )\n", (int64_t)p, *p);*/ | |
| return *p = *p * 2; | |
| } | |
| SQLITE_WASM_EXPORT2(void,sqlite3__wasm_test_stack_overflow,(int recurse)){ | |
| if(recurse) sqlite3__wasm_test_stack_overflow(recurse); | |
| } | |
| /* For testing the 'string:dealloc' whwasmutil.xWrap() conversion. */ | |
| SQLITE_WASM_EXPORT2(char *,sqlite3__wasm_test_str_hello,(int fail)){ | |
| char * s = fail ? 0 : (char *)sqlite3_malloc(6); | |
| if(s){ | |
| memcpy(s, "hello", 5); | |
| s[5] = 0; | |
| } | |
| return s; | |
| } | |
| /* | |
| ** For testing using SQLTester scripts. | |
| ** | |
| ** Return non-zero if string z matches glob pattern zGlob and zero if the | |
| ** pattern does not match. | |
| ** | |
| ** To repeat: | |
| ** | |
| ** zero == no match | |
| ** non-zero == match | |
| ** | |
| ** Globbing rules: | |
| ** | |
| ** '*' Matches any sequence of zero or more characters. | |
| ** | |
| ** '?' Matches exactly one character. | |
| ** | |
| ** [...] Matches one character from the enclosed list of | |
| ** characters. | |
| ** | |
| ** [^...] Matches one character not in the enclosed list. | |
| ** | |
| ** '#' Matches any sequence of one or more digits with an | |
| ** optional + or - sign in front, or a hexadecimal | |
| ** literal of the form 0x... | |
| */ | |
| static int sqlite3__wasm_SQLTester_strnotglob(const char *zGlob, const char *z){ | |
| int c, c2; | |
| int invert; | |
| int seen; | |
| typedef int (*recurse_f)(const char *,const char *); | |
| static const recurse_f recurse = sqlite3__wasm_SQLTester_strnotglob; | |
| while( (c = (*(zGlob++)))!=0 ){ | |
| if( c=='*' ){ | |
| while( (c=(*(zGlob++))) == '*' || c=='?' ){ | |
| if( c=='?' && (*(z++))==0 ) return 0; | |
| } | |
| if( c==0 ){ | |
| return 1; | |
| }else if( c=='[' ){ | |
| while( *z && recurse(zGlob-1,z)==0 ){ | |
| z++; | |
| } | |
| return (*z)!=0; | |
| } | |
| while( (c2 = (*(z++)))!=0 ){ | |
| while( c2!=c ){ | |
| c2 = *(z++); | |
| if( c2==0 ) return 0; | |
| } | |
| if( recurse(zGlob,z) ) return 1; | |
| } | |
| return 0; | |
| }else if( c=='?' ){ | |
| if( (*(z++))==0 ) return 0; | |
| }else if( c=='[' ){ | |
| int prior_c = 0; | |
| seen = 0; | |
| invert = 0; | |
| c = *(z++); | |
| if( c==0 ) return 0; | |
| c2 = *(zGlob++); | |
| if( c2=='^' ){ | |
| invert = 1; | |
| c2 = *(zGlob++); | |
| } | |
| if( c2==']' ){ | |
| if( c==']' ) seen = 1; | |
| c2 = *(zGlob++); | |
| } | |
| while( c2 && c2!=']' ){ | |
| if( c2=='-' && zGlob[0]!=']' && zGlob[0]!=0 && prior_c>0 ){ | |
| c2 = *(zGlob++); | |
| if( c>=prior_c && c<=c2 ) seen = 1; | |
| prior_c = 0; | |
| }else{ | |
| if( c==c2 ){ | |
| seen = 1; | |
| } | |
| prior_c = c2; | |
| } | |
| c2 = *(zGlob++); | |
| } | |
| if( c2==0 || (seen ^ invert)==0 ) return 0; | |
| }else if( c=='#' ){ | |
| if( z[0]=='0' | |
| && (z[1]=='x' || z[1]=='X') | |
| && sqlite3Isxdigit(z[2]) | |
| ){ | |
| z += 3; | |
| while( sqlite3Isxdigit(z[0]) ){ z++; } | |
| }else{ | |
| if( (z[0]=='-' || z[0]=='+') && sqlite3Isdigit(z[1]) ) z++; | |
| if( !sqlite3Isdigit(z[0]) ) return 0; | |
| z++; | |
| while( sqlite3Isdigit(z[0]) ){ z++; } | |
| } | |
| }else{ | |
| if( c!=(*(z++)) ) return 0; | |
| } | |
| } | |
| return *z==0; | |
| } | |
| SQLITE_WASM_EXPORT2(int,sqlite3__wasm_SQLTester_strglob, | |
| (const char *zGlob, const char *z)){ | |
| return !sqlite3__wasm_SQLTester_strnotglob(zGlob, z); | |
| } | |