12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958 |
- /*
- ** 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
- */
- #define SQLITE_WASM
- #ifdef SQLITE_WASM_ENABLE_C_TESTS
- # undef SQLITE_WASM_ENABLE_C_TESTS
- # define SQLITE_WASM_ENABLE_C_TESTS 1
- /*
- ** 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.
- */
- #else
- # define SQLITE_WASM_ENABLE_C_TESTS 0
- #endif
- /*
- ** 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.
- */
- #undef SQLITE_OMIT_DESERIALIZE
- #undef SQLITE_OMIT_MEMORYDB
- /*
- ** Define any SQLITE_... config defaults we want if they aren't
- ** overridden by the builder. Please keep these alphabetized.
- */
- /**********************************************************************/
- /* SQLITE_D... */
- #ifndef SQLITE_DEFAULT_CACHE_SIZE
- /*
- ** 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.
- */
- # define SQLITE_DEFAULT_CACHE_SIZE -16384
- #endif
- #if !defined(SQLITE_DEFAULT_PAGE_SIZE)
- /*
- ** 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.
- */
- # define SQLITE_DEFAULT_PAGE_SIZE 8192
- #endif
- #ifndef SQLITE_DEFAULT_UNIX_VFS
- # define SQLITE_DEFAULT_UNIX_VFS "unix-none"
- #endif
- #undef SQLITE_DQS
- #define SQLITE_DQS 0
- /**********************************************************************/
- /* 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.
- */
- #undef SQLITE_ENABLE_API_ARMOR
- #define SQLITE_ENABLE_API_ARMOR 1
- /**********************************************************************/
- /* SQLITE_O... */
- #undef SQLITE_OMIT_DEPRECATED
- #define SQLITE_OMIT_DEPRECATED 1
- #undef SQLITE_OMIT_LOAD_EXTENSION
- #define SQLITE_OMIT_LOAD_EXTENSION 1
- #undef SQLITE_OMIT_SHARED_CACHE
- #define SQLITE_OMIT_SHARED_CACHE 1
- #undef SQLITE_OMIT_UTF16
- #define SQLITE_OMIT_UTF16 1
- #undef SQLITE_OS_KV_OPTIONAL
- #define SQLITE_OS_KV_OPTIONAL 1
- /**********************************************************************/
- /* SQLITE_S... */
- #ifndef SQLITE_STRICT_SUBTYPE
- # define SQLITE_STRICT_SUBTYPE 1
- #endif
- /**********************************************************************/
- /* SQLITE_T... */
- #ifndef SQLITE_TEMP_STORE
- # define SQLITE_TEMP_STORE 2
- #endif
- #ifndef SQLITE_THREADSAFE
- # define SQLITE_THREADSAFE 0
- #endif
- /**********************************************************************/
- /* SQLITE_USE_... */
- #ifndef SQLITE_USE_URI
- # define SQLITE_USE_URI 1
- #endif
- #ifdef SQLITE_WASM_EXTRA_INIT
- /* SQLITE_EXTRA_INIT vs SQLITE_EXTRA_INIT_MUTEXED:
- ** see https://sqlite.org/forum/forumpost/14183b98fc0b1dea */
- # define SQLITE_EXTRA_INIT_MUTEXED sqlite3_wasm_extra_init
- #endif
- /*
- ** If SQLITE_WASM_BARE_BONES is defined, undefine most of the ENABLE
- ** macros.
- */
- #ifdef SQLITE_WASM_BARE_BONES
- # undef SQLITE_ENABLE_DBPAGE_VTAB
- # undef SQLITE_ENABLE_DBSTAT_VTAB
- # undef SQLITE_ENABLE_EXPLAIN_COMMENTS
- # undef SQLITE_ENABLE_FTS5
- # undef SQLITE_ENABLE_OFFSET_SQL_FUNC
- # undef SQLITE_ENABLE_PREUPDATE_HOOK
- # undef SQLITE_ENABLE_RTREE
- # undef SQLITE_ENABLE_SESSION
- # undef SQLITE_ENABLE_STMTVTAB
- # undef SQLITE_OMIT_AUTHORIZATION
- # define SQLITE_OMIT_AUTHORIZATION
- # undef SQLITE_OMIT_GET_TABLE
- # define SQLITE_OMIT_GET_TABLE
- # undef SQLITE_OMIT_INCRBLOB
- # define SQLITE_OMIT_INCRBLOB
- # undef SQLITE_OMIT_INTROSPECTION_PRAGMAS
- # define SQLITE_OMIT_INTROSPECTION_PRAGMAS
- # undef SQLITE_OMIT_JSON
- # define SQLITE_OMIT_JSON
- # undef SQLITE_OMIT_PROGRESS_CALLBACK
- # define SQLITE_OMIT_PROGRESS_CALLBACK
- # undef SQLITE_OMIT_WAL
- # define SQLITE_OMIT_WAL
- /*
- 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.
- */
- #endif
- #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_WASM_BARE_BONES)
- # define SQLITE_WASM_HAS_VTAB 1
- #else
- # define SQLITE_WASM_HAS_VTAB 0
- #endif
- #include <assert.h>
- /*
- ** 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.
- **
- ** 2022-09-11: it's not yet _proven_ that this approach works in
- ** non-Emscripten builds. If not, such builds will need to export
- ** those using the --export=... wasm-ld flag (or equivalent). As of
- ** this writing we are tied to Emscripten for various reasons
- ** and cannot test the library with other build environments.
- */
- #define SQLITE_WASM_EXPORT __attribute__((used,visibility("default")))
- // See also:
- //__attribute__((export_name("theExportedName"), used, visibility("default")))
- /*
- ** Which sqlite3.c we're using needs to be configurable to enable
- ** building against a custom copy, e.g. the SEE variant. Note that we
- ** #include the .c file, rather than the header, so that the WASM
- ** extensions have access to private API internals.
- **
- ** 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.
- */
- #ifndef SQLITE_C
- # define SQLITE_C sqlite3.c /* yes, .c instead of .h. */
- #endif
- #define INC__STRINGIFY_(f) #f
- #define INC__STRINGIFY(f) INC__STRINGIFY_(f)
- #include INC__STRINGIFY(SQLITE_C)
- #undef INC__STRINGIFY_
- #undef INC__STRINGIFY
- #undef SQLITE_C
- #if 0
- /*
- ** An EXPERIMENT in implementing a stack-based allocator analog to
- ** Emscripten's stackSave(), stackAlloc(), stackRestore().
- ** Unfortunately, this cannot work together with Emscripten because
- ** Emscripten defines its own native one and we'd stomp on each
- ** other's memory. Other than that complication, basic tests show it
- ** to work just fine.
- **
- ** Another option is to malloc() a chunk of our own and call that our
- ** "stack".
- */
- SQLITE_WASM_EXPORT void * sqlite3__wasm_stack_end(void){
- extern void __heap_base
- /* see https://stackoverflow.com/questions/10038964 */;
- return &__heap_base;
- }
- SQLITE_WASM_EXPORT void * sqlite3__wasm_stack_begin(void){
- extern void __data_end;
- return &__data_end;
- }
- static void * pWasmStackPtr = 0;
- SQLITE_WASM_EXPORT void * sqlite3__wasm_stack_ptr(void){
- if(!pWasmStackPtr) pWasmStackPtr = sqlite3__wasm_stack_end();
- return pWasmStackPtr;
- }
- SQLITE_WASM_EXPORT void sqlite3__wasm_stack_restore(void * p){
- pWasmStackPtr = p;
- }
- SQLITE_WASM_EXPORT void * sqlite3__wasm_stack_alloc(int n){
- if(n<=0) return 0;
- n = (n + 7) & ~7 /* align to 8-byte boundary */;
- unsigned char * const p = (unsigned char *)sqlite3__wasm_stack_ptr();
- unsigned const char * const b = (unsigned const char *)sqlite3__wasm_stack_begin();
- if(b + n >= p || b + n < b/*overflow*/) return 0;
- return pWasmStackPtr = p - n;
- }
- #endif /* stack allocator experiment */
- /*
- ** 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[512 * 8] = {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));
- 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 will
- ** call for doing so).
- */
- SQLITE_WASM_EXPORT 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_EXPORT 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_EXPORT int sqlite3__wasm_pstack_quota(void){
- return (int)(PStack.pEnd - PStack.pBegin);
- }
- /*
- ** This function is NOT part of the sqlite3 public API. It is strictly
- ** for use by the sqlite project's own JS/WASM bindings.
- **
- ** For purposes of certain hand-crafted C/Wasm function bindings, we
- ** need a way of reporting errors which is consistent with the rest of
- ** the C API, as opposed to throwing JS exceptions. To that end, this
- ** internal-use-only function is a thin proxy around
- ** sqlite3ErrorWithMessage(). The intent is that it only be used from
- ** Wasm bindings such as sqlite3_prepare_v2/v3(), and definitely not
- ** from client code.
- **
- ** Returns err_code.
- */
- SQLITE_WASM_EXPORT
- int sqlite3__wasm_db_error(sqlite3*db, int err_code, const char *zMsg){
- if( db!=0 ){
- if( 0!=zMsg ){
- const int nMsg = sqlite3Strlen30(zMsg);
- sqlite3_mutex_enter(sqlite3_db_mutex(db));
- sqlite3ErrorWithMsg(db, err_code, "%.*s", nMsg, zMsg);
- sqlite3_mutex_leave(sqlite3_db_mutex(db));
- }else{
- sqlite3ErrorWithMsg(db, err_code, NULL);
- }
- }
- return err_code;
- }
- #if SQLITE_WASM_ENABLE_C_TESTS
- struct WasmTestStruct {
- int v4;
- void * ppV;
- const char * cstr;
- int64_t v8;
- void (*xFunc)(void*);
- };
- typedef struct WasmTestStruct WasmTestStruct;
- SQLITE_WASM_EXPORT
- void sqlite3__wasm_test_struct(WasmTestStruct * s){
- if(s){
- s->v4 *= 2;
- s->v8 = s->v4 * 2;
- s->ppV = s;
- s->cstr = __FILE__;
- if(s->xFunc) s->xFunc(s);
- }
- return;
- }
- #endif /* SQLITE_WASM_ENABLE_C_TESTS */
- /*
- ** 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().
- */
- SQLITE_WASM_EXPORT
- const char * sqlite3__wasm_enum_json(void){
- static char aBuffer[1024 * 20] = {0} /* where the JSON goes */;
- 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... */
- #define lenCheck assert(zPos < zEnd - 128 \
- && "sqlite3__wasm_enum_json() buffer is too small."); \
- if( zPos >= zEnd - 128 ) return 0
- #define outf(format,...) \
- zPos += snprintf(zPos, ((size_t)(zEnd - zPos)), format, __VA_ARGS__); \
- lenCheck
- #define out(TXT) outf("%s",TXT)
- #define CloseBrace(LEVEL) \
- assert(LEVEL<5); memset(zPos, '}', LEVEL); zPos+=LEVEL; lenCheck
- /* Macros for emitting maps of integer- and string-type macros to
- ** their values. */
- #define DefGroup(KEY) n = 0; \
- outf("%s\"" #KEY "\": {",(nChildren++ ? "," : ""));
- #define DefInt(KEY) \
- outf("%s\"%s\": %d", (n++ ? ", " : ""), #KEY, (int)KEY)
- #define DefStr(KEY) \
- outf("%s\"%s\": \"%s\"", (n++ ? ", " : ""), #KEY, KEY)
- #define _DefGroup CloseBrace(1)
- /* 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){
- #ifdef SQLITE_CHANGESETSTART_INVERT
- 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);
- #endif
- } _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_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){
- #ifdef SQLITE_SESSION_CONFIG_STRMSIZE
- DefInt(SQLITE_SESSION_CONFIG_STRMSIZE);
- DefInt(SQLITE_SESSION_OBJCONFIG_SIZE);
- #endif
- } _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);
- } _DefGroup;
- DefGroup(version) {
- DefInt(SQLITE_VERSION_NUMBER);
- DefStr(SQLITE_VERSION);
- DefStr(SQLITE_SOURCE_ID);
- } _DefGroup;
- DefGroup(vtab) {
- #if SQLITE_WASM_HAS_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);
- #endif /*SQLITE_WASM_HAS_VTAB*/
- } _DefGroup;
- #undef DefGroup
- #undef DefStr
- #undef DefInt
- #undef _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 docs for the
- ** Jaccwabyt JS-side component.
- */
- /** Macros for emitting StructBinder description. */
- #define StructBinder__(TYPE) \
- n = 0; \
- outf("%s{", (nStruct++ ? ", " : "")); \
- out("\"name\": \"" # TYPE "\","); \
- outf("\"sizeof\": %d", (int)sizeof(TYPE)); \
- out(",\"members\": {");
- #define StructBinder_(T) StructBinder__(T)
- /** ^^^ indirection needed to expand CurrentStruct */
- #define StructBinder StructBinder_(CurrentStruct)
- #define _StructBinder CloseBrace(2)
- #define M(MEMBER,SIG) \
- outf("%s\"%s\": " \
- "{\"offset\":%d,\"sizeof\": %d,\"signature\":\"%s\"}", \
- (n++ ? ", " : ""), #MEMBER, \
- (int)offsetof(CurrentStruct,MEMBER), \
- (int)sizeof(((CurrentStruct*)0)->MEMBER), \
- SIG)
- nStruct = 0;
- out(", \"structs\": ["); {
- #define CurrentStruct sqlite3_vfs
- 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, "p(pp)");
- M(xDlError, "p(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;
- #undef CurrentStruct
- #define CurrentStruct sqlite3_io_methods
- 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;
- #undef CurrentStruct
- #define CurrentStruct sqlite3_file
- StructBinder {
- M(pMethods, "p");
- } _StructBinder;
- #undef CurrentStruct
- #define CurrentStruct sqlite3_kvvfs_methods
- StructBinder {
- M(xRead, "i(sspi)");
- M(xWrite, "i(sss)");
- M(xDelete, "i(ss)");
- M(nKeySize, "i");
- } _StructBinder;
- #undef CurrentStruct
- #if SQLITE_WASM_HAS_VTAB
- #define CurrentStruct sqlite3_vtab
- StructBinder {
- M(pModule, "p");
- M(nRef, "i");
- M(zErrMsg, "p");
- } _StructBinder;
- #undef CurrentStruct
- #define CurrentStruct sqlite3_vtab_cursor
- StructBinder {
- M(pVtab, "p");
- } _StructBinder;
- #undef CurrentStruct
- #define CurrentStruct sqlite3_module
- 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)");
- } _StructBinder;
- #undef CurrentStruct
- /**
- ** 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.
- */
- 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;
- #define IndexSzCheck(T,M) \
- (sizeof(T) == sizeof(*siiCheck.M))
- 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;
- }
- #undef IndexSzCheck
- }
- #define CurrentStruct sqlite3_index_constraint
- StructBinder {
- M(iColumn, "i");
- M(op, "C");
- M(usable, "C");
- M(iTermOffset, "i");
- } _StructBinder;
- #undef CurrentStruct
- #define CurrentStruct sqlite3_index_orderby
- StructBinder {
- M(iColumn, "i");
- M(desc, "C");
- } _StructBinder;
- #undef CurrentStruct
- #define CurrentStruct sqlite3_index_constraint_usage
- StructBinder {
- M(argvIndex, "i");
- M(omit, "C");
- } _StructBinder;
- #undef CurrentStruct
- #define CurrentStruct sqlite3_index_info
- 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;
- #undef CurrentStruct
- #endif /*SQLITE_WASM_HAS_VTAB*/
- #if SQLITE_WASM_ENABLE_C_TESTS
- #define CurrentStruct WasmTestStruct
- StructBinder {
- M(v4, "i");
- M(cstr, "s");
- M(ppV, "p");
- M(v8, "j");
- M(xFunc, "v(p)");
- } _StructBinder;
- #undef CurrentStruct
- #endif /*SQLITE_WASM_ENABLE_C_TESTS*/
- } out( "]"/*structs*/);
- out("}"/*top-level object*/);
- *zPos = 0;
- aBuffer[0] = '{'/*end of the race-condition workaround*/;
- return aBuffer;
- #undef StructBinder
- #undef StructBinder_
- #undef StructBinder__
- #undef M
- #undef _StructBinder
- #undef CloseBrace
- #undef out
- #undef outf
- #undef lenCheck
- }
- /*
- ** 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_EXPORT
- 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_EXPORT
- 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_EXPORT
- 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_EXPORT
- 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_EXPORT
- 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
- #if 0 && defined(SQLITE_DEBUG)
- | 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. */
- #endif
- ;
- 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);
- #if 0
- # define RC fprintf(stderr,"create_file(%s,%s) @%d rc=%d\n", \
- pVfs->zName, zFilename, __LINE__, rc);
- #else
- # define RC
- #endif
- 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;
- #undef 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_EXPORT
- 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.
- **
- ** Allocates sqlite3KvvfsMethods.nKeySize bytes from
- ** sqlite3__wasm_pstack_alloc() and returns 0 if that allocation fails,
- ** else it passes that string to kvstorageMakeKey() and returns a
- ** NUL-terminated pointer to that string. It is up to the caller to
- ** use sqlite3__wasm_pstack_restore() to free the returned pointer.
- */
- SQLITE_WASM_EXPORT
- char * sqlite3__wasm_kvvfsMakeKeyOnPstack(const char *zClass,
- const char *zKeyIn){
- assert(sqlite3KvvfsMethods.nKeySize>24);
- char *zKeyOut =
- (char *)sqlite3__wasm_pstack_alloc(sqlite3KvvfsMethods.nKeySize);
- if(zKeyOut){
- kvstorageMakeKey(zClass, zKeyIn, zKeyOut);
- }
- return zKeyOut;
- }
- /*
- ** 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_EXPORT
- sqlite3_kvvfs_methods * sqlite3__wasm_kvvfs_methods(void){
- return &sqlite3KvvfsMethods;
- }
- #if SQLITE_WASM_HAS_VTAB
- /*
- ** 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_EXPORT
- 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;
- }
- }
- #endif /*SQLITE_WASM_HAS_VTAB*/
- /*
- ** 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_EXPORT
- 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_EXPORT
- 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_EXPORT
- 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_EXPORT
- 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_EXPORT
- 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_EXPORT
- 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_EXPORT
- 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;
- }
- #if defined(__EMSCRIPTEN__) && defined(SQLITE_ENABLE_WASMFS)
- #include <emscripten/console.h>
- #include <emscripten/wasmfs.h>
- /*
- ** 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_EXPORT
- 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;
- }
- #else
- SQLITE_WASM_EXPORT
- int sqlite3__wasm_init_wasmfs(const char *zUnused){
- //emscripten_console_warn("WASMFS OPFS is not compiled in.");
- if(zUnused){/*unused*/}
- return SQLITE_NOTFOUND;
- }
- #endif /* __EMSCRIPTEN__ && SQLITE_ENABLE_WASMFS */
- #if SQLITE_WASM_ENABLE_C_TESTS
- SQLITE_WASM_EXPORT
- int sqlite3__wasm_test_intptr(int * p){
- return *p = *p * 2;
- }
- SQLITE_WASM_EXPORT
- void * sqlite3__wasm_test_voidptr(void * p){
- return p;
- }
- SQLITE_WASM_EXPORT
- int64_t sqlite3__wasm_test_int64_max(void){
- return (int64_t)0x7fffffffffffffff;
- }
- SQLITE_WASM_EXPORT
- int64_t sqlite3__wasm_test_int64_min(void){
- return ~sqlite3__wasm_test_int64_max();
- }
- SQLITE_WASM_EXPORT
- int64_t sqlite3__wasm_test_int64_times2(int64_t x){
- return x * 2;
- }
- SQLITE_WASM_EXPORT
- 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_EXPORT
- 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_EXPORT
- 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_EXPORT
- 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_EXPORT
- int sqlite3__wasm_SQLTester_strglob(const char *zGlob, const char *z){
- return !sqlite3__wasm_SQLTester_strnotglob(zGlob, z);
- }
- #endif /* SQLITE_WASM_ENABLE_C_TESTS */
- #undef SQLITE_WASM_EXPORT
- #undef SQLITE_WASM_HAS_VTAB
- #undef SQLITE_WASM_BARE_BONES
- #undef SQLITE_WASM_ENABLE_C_TESTS
|