1 /* 2 ** This file requires access to sqlite3.c static state in order to 3 ** implement certain WASM-specific features, and thus directly 4 ** includes that file. Unlike the rest of sqlite3.c, this file 5 ** requires compiling with -std=c99 (or equivalent, or a later C 6 ** version) because it makes use of features not available in C89. 7 ** 8 ** At it's simplest, to build sqlite3.wasm either place this file 9 ** in the same directory as sqlite3.c/h before compilation or use the 10 ** -I/path flag to tell the compiler where to find both of those 11 ** files, then compile this file. For example: 12 ** 13 ** emcc -o sqlite3.wasm ... -I/path/to/sqlite3-c-and-h sqlite3-wasm.c 14 */ 15 16 /* 17 ** Threading and file locking: JS is single-threaded. Each Worker 18 ** thread is a separate instance of the JS engine so can never access 19 ** the same db handle as another thread, thus multi-threading support 20 ** is unnecessary in the library. Because the filesystems are virtual 21 ** and local to a given wasm runtime instance, two Workers can never 22 ** access the same db file at once, with the exception of OPFS. As of 23 ** this writing (2022-09-30), OPFS exclusively locks a file when 24 ** opening it, so two Workers can never open the same OPFS-backed file 25 ** at once. That situation will change if and when lower-level locking 26 ** features are added to OPFS (as is currently planned, per folks 27 ** involved with its development). 28 ** 29 ** Summary: except for the case of future OPFS, which supports 30 ** locking, and any similar future filesystems, threading and file 31 ** locking support are unnecessary in the wasm build. 32 */ 33 #undef SQLITE_OMIT_DESERIALIZE 34 #ifndef SQLITE_DEFAULT_UNIX_VFS 35 # define SQLITE_DEFAULT_UNIX_VFS "unix-none" 36 #endif 37 #ifndef SQLITE_OMIT_DEPRECATED 38 # define SQLITE_OMIT_DEPRECATED 39 #endif 40 #ifndef SQLITE_OMIT_LOAD_EXTENSION 41 # define SQLITE_OMIT_LOAD_EXTENSION 42 #endif 43 #ifndef SQLITE_OMIT_SHARED_CACHE 44 # define SQLITE_OMIT_SHARED_CACHE 45 #endif 46 #ifndef SQLITE_OMIT_UTF16 47 # define SQLITE_OMIT_UTF16 48 #endif 49 #ifndef SQLITE_OS_KV_OPTIONAL 50 # define SQLITE_OS_KV_OPTIONAL 1 51 #endif 52 #ifndef SQLITE_TEMP_STORE 53 # define SQLITE_TEMP_STORE 3 54 #endif 55 #ifndef SQLITE_THREADSAFE 56 # define SQLITE_THREADSAFE 0 57 #endif 58 59 #include <assert.h> 60 #include "sqlite3.c" /* yes, .c instead of .h. */ 61 62 #if defined(__EMSCRIPTEN__) 63 # include <emscripten/console.h> 64 #endif 65 66 /* 67 ** WASM_KEEP is identical to EMSCRIPTEN_KEEPALIVE but is not 68 ** Emscripten-specific. It explicitly marks functions for export into 69 ** the target wasm file without requiring explicit listing of those 70 ** functions in Emscripten's -sEXPORTED_FUNCTIONS=... list (or 71 ** equivalent in other build platforms). Any function with neither 72 ** this attribute nor which is listed as an explicit export will not 73 ** be exported from the wasm file (but may still be used internally 74 ** within the wasm file). 75 ** 76 ** The functions in this file (sqlite3-wasm.c) which require exporting 77 ** are marked with this flag. They may also be added to any explicit 78 ** build-time export list but need not be. All of these APIs are 79 ** intended for use only within the project's own JS/WASM code, and 80 ** not by client code, so an argument can be made for reducing their 81 ** visibility by not including them in any build-time export lists. 82 ** 83 ** 2022-09-11: it's not yet _proven_ that this approach works in 84 ** non-Emscripten builds. If not, such builds will need to export 85 ** those using the --export=... wasm-ld flag (or equivalent). As of 86 ** this writing we are tied to Emscripten for various reasons 87 ** and cannot test the library with other build environments. 88 */ 89 #define WASM_KEEP __attribute__((used,visibility("default"))) 90 // See also: 91 //__attribute__((export_name("theExportedName"), used, visibility("default"))) 92 93 94 #if 0 95 /* 96 ** An EXPERIMENT in implementing a stack-based allocator analog to 97 ** Emscripten's stackSave(), stackAlloc(), stackRestore(). 98 ** Unfortunately, this cannot work together with Emscripten because 99 ** Emscripten defines its own native one and we'd stomp on each 100 ** other's memory. Other than that complication, basic tests show it 101 ** to work just fine. 102 ** 103 ** Another option is to malloc() a chunk of our own and call that our 104 ** "stack". 105 */ 106 WASM_KEEP void * sqlite3_wasm_stack_end(void){ 107 extern void __heap_base 108 /* see https://stackoverflow.com/questions/10038964 */; 109 return &__heap_base; 110 } 111 WASM_KEEP void * sqlite3_wasm_stack_begin(void){ 112 extern void __data_end; 113 return &__data_end; 114 } 115 static void * sq3StackPtr = 0; 116 WASM_KEEP void * sqlite3_wasm_stack_ptr(void){ 117 if(!sq3StackPtr) sq3StackPtr = sqlite3_wasm_stack_end(); 118 return sq3StackPtr; 119 } 120 WASM_KEEP void sqlite3_wasm_stack_restore(void * p){ 121 sq3StackPtr = p; 122 } 123 WASM_KEEP void * sqlite3_wasm_stack_alloc(int n){ 124 if(n<=0) return 0; 125 n = (n + 7) & ~7 /* align to 8-byte boundary */; 126 unsigned char * const p = (unsigned char *)sqlite3_wasm_stack_ptr(); 127 unsigned const char * const b = (unsigned const char *)sqlite3_wasm_stack_begin(); 128 if(b + n >= p || b + n < b/*overflow*/) return 0; 129 return sq3StackPtr = p - n; 130 } 131 #endif /* stack allocator experiment */ 132 133 /* 134 ** State for the "pseudo-stack" allocator implemented in 135 ** sqlite3_wasm_pstack_xyz(). In order to avoid colliding with 136 ** Emscripten-controled stack space, it carves out a bit of stack 137 ** memory to use for that purpose. This memory ends up in the 138 ** WASM-managed memory, such that routines which manipulate the wasm 139 ** heap can also be used to manipulate this memory. 140 */ 141 static unsigned char PStack_mem[512 * 8] = {0}; 142 static struct { 143 unsigned const char * const pBegin;/* Start (inclusive) of memory */ 144 unsigned const char * const pEnd; /* One-after-the-end of memory */ 145 unsigned char * pPos; /* Current stack pointer */ 146 } PStack = { 147 &PStack_mem[0], 148 &PStack_mem[0] + sizeof(PStack_mem), 149 &PStack_mem[0] + sizeof(PStack_mem) 150 }; 151 /* 152 ** Returns the current pstack position. 153 */ 154 WASM_KEEP void * sqlite3_wasm_pstack_ptr(void){ 155 return PStack.pPos; 156 } 157 /* 158 ** Sets the pstack position poitner to p. Results are undefined if the 159 ** given value did not come from sqlite3_wasm_pstack_ptr(). 160 */ 161 WASM_KEEP void sqlite3_wasm_pstack_restore(unsigned char * p){ 162 assert(p>=PStack.pBegin && p<=PStack.pEnd && p>=PStack.pPos); 163 assert(0==(p & 0x7)); 164 if(p>=PStack.pBegin && p<=PStack.pEnd /*&& p>=PStack.pPos*/){ 165 PStack.pPos = p; 166 } 167 } 168 /* 169 ** Allocate and zero out n bytes from the pstack. Returns a pointer to 170 ** the memory on success, 0 on error (including a negative n value). n 171 ** is always adjusted to be a multiple of 8 and returned memory is 172 ** always zeroed out before returning (because this keeps the client 173 ** JS code from having to do so, and most uses of the pstack will 174 ** call for doing so). 175 */ 176 WASM_KEEP void * sqlite3_wasm_pstack_alloc(int n){ 177 if( n<=0 ) return 0; 178 //if( n & 0x7 ) n += 8 - (n & 0x7) /* align to 8-byte boundary */; 179 n = (n + 7) & ~7 /* align to 8-byte boundary */; 180 unsigned char * const p = PStack.pPos; 181 unsigned const char * const b = PStack.pBegin; 182 if( b + n > p || b + n <= b/*overflow*/ ) return 0; 183 memset((PStack.pPos = p - n), 0, (unsigned int)n); 184 return PStack.pPos; 185 } 186 /* 187 ** Return the number of bytes left which can be 188 ** sqlite3_wasm_pstack_alloc()'d. 189 */ 190 WASM_KEEP int sqlite3_wasm_pstack_remaining(void){ 191 assert(PStack.pPos >= PStack.pBegin); 192 assert(PStack.pPos <= PStack.pEnd); 193 return (int)(PStack.pPos - PStack.pBegin); 194 } 195 196 197 /* 198 ** This function is NOT part of the sqlite3 public API. It is strictly 199 ** for use by the sqlite project's own JS/WASM bindings. 200 ** 201 ** For purposes of certain hand-crafted C/Wasm function bindings, we 202 ** need a way of reporting errors which is consistent with the rest of 203 ** the C API, as opposed to throwing JS exceptions. To that end, this 204 ** internal-use-only function is a thin proxy around 205 ** sqlite3ErrorWithMessage(). The intent is that it only be used from 206 ** Wasm bindings such as sqlite3_prepare_v2/v3(), and definitely not 207 ** from client code. 208 ** 209 ** Returns err_code. 210 */ 211 WASM_KEEP 212 int sqlite3_wasm_db_error(sqlite3*db, int err_code, const char *zMsg){ 213 if(0!=zMsg){ 214 const int nMsg = sqlite3Strlen30(zMsg); 215 sqlite3ErrorWithMsg(db, err_code, "%.*s", nMsg, zMsg); 216 }else{ 217 sqlite3ErrorWithMsg(db, err_code, NULL); 218 } 219 return err_code; 220 } 221 222 /* 223 ** This function is NOT part of the sqlite3 public API. It is strictly 224 ** for use by the sqlite project's own JS/WASM bindings. Unlike the 225 ** rest of the sqlite3 API, this part requires C99 for snprintf() and 226 ** variadic macros. 227 ** 228 ** Returns a string containing a JSON-format "enum" of C-level 229 ** constants intended to be imported into the JS environment. The JSON 230 ** is initialized the first time this function is called and that 231 ** result is reused for all future calls. 232 ** 233 ** If this function returns NULL then it means that the internal 234 ** buffer is not large enough for the generated JSON. In debug builds 235 ** that will trigger an assert(). 236 */ 237 WASM_KEEP 238 const char * sqlite3_wasm_enum_json(void){ 239 static char strBuf[1024 * 12] = {0} /* where the JSON goes */; 240 int n = 0, childCount = 0, structCount = 0 241 /* output counters for figuring out where commas go */; 242 char * pos = &strBuf[1] /* skip first byte for now to help protect 243 ** against a small race condition */; 244 char const * const zEnd = pos + sizeof(strBuf) /* one-past-the-end */; 245 if(strBuf[0]) return strBuf; 246 /* Leave strBuf[0] at 0 until the end to help guard against a tiny 247 ** race condition. If this is called twice concurrently, they might 248 ** end up both writing to strBuf, but they'll both write the same 249 ** thing, so that's okay. If we set byte 0 up front then the 2nd 250 ** instance might return and use the string before the 1st instance 251 ** is done filling it. */ 252 253 /* Core output macros... */ 254 #define lenCheck assert(pos < zEnd - 128 \ 255 && "sqlite3_wasm_enum_json() buffer is too small."); \ 256 if(pos >= zEnd - 128) return 0 257 #define outf(format,...) \ 258 pos += snprintf(pos, ((size_t)(zEnd - pos)), format, __VA_ARGS__); \ 259 lenCheck 260 #define out(TXT) outf("%s",TXT) 261 #define CloseBrace(LEVEL) \ 262 assert(LEVEL<5); memset(pos, '}', LEVEL); pos+=LEVEL; lenCheck 263 264 /* Macros for emitting maps of integer- and string-type macros to 265 ** their values. */ 266 #define DefGroup(KEY) n = 0; \ 267 outf("%s\"" #KEY "\": {",(childCount++ ? "," : "")); 268 #define DefInt(KEY) \ 269 outf("%s\"%s\": %d", (n++ ? ", " : ""), #KEY, (int)KEY) 270 #define DefStr(KEY) \ 271 outf("%s\"%s\": \"%s\"", (n++ ? ", " : ""), #KEY, KEY) 272 #define _DefGroup CloseBrace(1) 273 274 /* The following groups are sorted alphabetic by group name. */ 275 DefGroup(access){ 276 DefInt(SQLITE_ACCESS_EXISTS); 277 DefInt(SQLITE_ACCESS_READWRITE); 278 DefInt(SQLITE_ACCESS_READ)/*docs say this is unused*/; 279 } _DefGroup; 280 281 DefGroup(blobFinalizers) { 282 /* SQLITE_STATIC/TRANSIENT need to be handled explicitly as 283 ** integers to avoid casting-related warnings. */ 284 out("\"SQLITE_STATIC\":0, \"SQLITE_TRANSIENT\":-1"); 285 } _DefGroup; 286 287 DefGroup(dataTypes) { 288 DefInt(SQLITE_INTEGER); 289 DefInt(SQLITE_FLOAT); 290 DefInt(SQLITE_TEXT); 291 DefInt(SQLITE_BLOB); 292 DefInt(SQLITE_NULL); 293 } _DefGroup; 294 295 DefGroup(encodings) { 296 /* Noting that the wasm binding only aims to support UTF-8. */ 297 DefInt(SQLITE_UTF8); 298 DefInt(SQLITE_UTF16LE); 299 DefInt(SQLITE_UTF16BE); 300 DefInt(SQLITE_UTF16); 301 /*deprecated DefInt(SQLITE_ANY); */ 302 DefInt(SQLITE_UTF16_ALIGNED); 303 } _DefGroup; 304 305 DefGroup(fcntl) { 306 DefInt(SQLITE_FCNTL_LOCKSTATE); 307 DefInt(SQLITE_FCNTL_GET_LOCKPROXYFILE); 308 DefInt(SQLITE_FCNTL_SET_LOCKPROXYFILE); 309 DefInt(SQLITE_FCNTL_LAST_ERRNO); 310 DefInt(SQLITE_FCNTL_SIZE_HINT); 311 DefInt(SQLITE_FCNTL_CHUNK_SIZE); 312 DefInt(SQLITE_FCNTL_FILE_POINTER); 313 DefInt(SQLITE_FCNTL_SYNC_OMITTED); 314 DefInt(SQLITE_FCNTL_WIN32_AV_RETRY); 315 DefInt(SQLITE_FCNTL_PERSIST_WAL); 316 DefInt(SQLITE_FCNTL_OVERWRITE); 317 DefInt(SQLITE_FCNTL_VFSNAME); 318 DefInt(SQLITE_FCNTL_POWERSAFE_OVERWRITE); 319 DefInt(SQLITE_FCNTL_PRAGMA); 320 DefInt(SQLITE_FCNTL_BUSYHANDLER); 321 DefInt(SQLITE_FCNTL_TEMPFILENAME); 322 DefInt(SQLITE_FCNTL_MMAP_SIZE); 323 DefInt(SQLITE_FCNTL_TRACE); 324 DefInt(SQLITE_FCNTL_HAS_MOVED); 325 DefInt(SQLITE_FCNTL_SYNC); 326 DefInt(SQLITE_FCNTL_COMMIT_PHASETWO); 327 DefInt(SQLITE_FCNTL_WIN32_SET_HANDLE); 328 DefInt(SQLITE_FCNTL_WAL_BLOCK); 329 DefInt(SQLITE_FCNTL_ZIPVFS); 330 DefInt(SQLITE_FCNTL_RBU); 331 DefInt(SQLITE_FCNTL_VFS_POINTER); 332 DefInt(SQLITE_FCNTL_JOURNAL_POINTER); 333 DefInt(SQLITE_FCNTL_WIN32_GET_HANDLE); 334 DefInt(SQLITE_FCNTL_PDB); 335 DefInt(SQLITE_FCNTL_BEGIN_ATOMIC_WRITE); 336 DefInt(SQLITE_FCNTL_COMMIT_ATOMIC_WRITE); 337 DefInt(SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE); 338 DefInt(SQLITE_FCNTL_LOCK_TIMEOUT); 339 DefInt(SQLITE_FCNTL_DATA_VERSION); 340 DefInt(SQLITE_FCNTL_SIZE_LIMIT); 341 DefInt(SQLITE_FCNTL_CKPT_DONE); 342 DefInt(SQLITE_FCNTL_RESERVE_BYTES); 343 DefInt(SQLITE_FCNTL_CKPT_START); 344 DefInt(SQLITE_FCNTL_EXTERNAL_READER); 345 DefInt(SQLITE_FCNTL_CKSM_FILE); 346 } _DefGroup; 347 348 DefGroup(flock) { 349 DefInt(SQLITE_LOCK_NONE); 350 DefInt(SQLITE_LOCK_SHARED); 351 DefInt(SQLITE_LOCK_RESERVED); 352 DefInt(SQLITE_LOCK_PENDING); 353 DefInt(SQLITE_LOCK_EXCLUSIVE); 354 } _DefGroup; 355 356 DefGroup(ioCap) { 357 DefInt(SQLITE_IOCAP_ATOMIC); 358 DefInt(SQLITE_IOCAP_ATOMIC512); 359 DefInt(SQLITE_IOCAP_ATOMIC1K); 360 DefInt(SQLITE_IOCAP_ATOMIC2K); 361 DefInt(SQLITE_IOCAP_ATOMIC4K); 362 DefInt(SQLITE_IOCAP_ATOMIC8K); 363 DefInt(SQLITE_IOCAP_ATOMIC16K); 364 DefInt(SQLITE_IOCAP_ATOMIC32K); 365 DefInt(SQLITE_IOCAP_ATOMIC64K); 366 DefInt(SQLITE_IOCAP_SAFE_APPEND); 367 DefInt(SQLITE_IOCAP_SEQUENTIAL); 368 DefInt(SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN); 369 DefInt(SQLITE_IOCAP_POWERSAFE_OVERWRITE); 370 DefInt(SQLITE_IOCAP_IMMUTABLE); 371 DefInt(SQLITE_IOCAP_BATCH_ATOMIC); 372 } _DefGroup; 373 374 DefGroup(openFlags) { 375 /* Noting that not all of these will have any effect in 376 ** WASM-space. */ 377 DefInt(SQLITE_OPEN_READONLY); 378 DefInt(SQLITE_OPEN_READWRITE); 379 DefInt(SQLITE_OPEN_CREATE); 380 DefInt(SQLITE_OPEN_URI); 381 DefInt(SQLITE_OPEN_MEMORY); 382 DefInt(SQLITE_OPEN_NOMUTEX); 383 DefInt(SQLITE_OPEN_FULLMUTEX); 384 DefInt(SQLITE_OPEN_SHAREDCACHE); 385 DefInt(SQLITE_OPEN_PRIVATECACHE); 386 DefInt(SQLITE_OPEN_EXRESCODE); 387 DefInt(SQLITE_OPEN_NOFOLLOW); 388 /* OPEN flags for use with VFSes... */ 389 DefInt(SQLITE_OPEN_MAIN_DB); 390 DefInt(SQLITE_OPEN_MAIN_JOURNAL); 391 DefInt(SQLITE_OPEN_TEMP_DB); 392 DefInt(SQLITE_OPEN_TEMP_JOURNAL); 393 DefInt(SQLITE_OPEN_TRANSIENT_DB); 394 DefInt(SQLITE_OPEN_SUBJOURNAL); 395 DefInt(SQLITE_OPEN_SUPER_JOURNAL); 396 DefInt(SQLITE_OPEN_WAL); 397 DefInt(SQLITE_OPEN_DELETEONCLOSE); 398 DefInt(SQLITE_OPEN_EXCLUSIVE); 399 } _DefGroup; 400 401 DefGroup(prepareFlags) { 402 DefInt(SQLITE_PREPARE_PERSISTENT); 403 DefInt(SQLITE_PREPARE_NORMALIZE); 404 DefInt(SQLITE_PREPARE_NO_VTAB); 405 } _DefGroup; 406 407 DefGroup(resultCodes) { 408 DefInt(SQLITE_OK); 409 DefInt(SQLITE_ERROR); 410 DefInt(SQLITE_INTERNAL); 411 DefInt(SQLITE_PERM); 412 DefInt(SQLITE_ABORT); 413 DefInt(SQLITE_BUSY); 414 DefInt(SQLITE_LOCKED); 415 DefInt(SQLITE_NOMEM); 416 DefInt(SQLITE_READONLY); 417 DefInt(SQLITE_INTERRUPT); 418 DefInt(SQLITE_IOERR); 419 DefInt(SQLITE_CORRUPT); 420 DefInt(SQLITE_NOTFOUND); 421 DefInt(SQLITE_FULL); 422 DefInt(SQLITE_CANTOPEN); 423 DefInt(SQLITE_PROTOCOL); 424 DefInt(SQLITE_EMPTY); 425 DefInt(SQLITE_SCHEMA); 426 DefInt(SQLITE_TOOBIG); 427 DefInt(SQLITE_CONSTRAINT); 428 DefInt(SQLITE_MISMATCH); 429 DefInt(SQLITE_MISUSE); 430 DefInt(SQLITE_NOLFS); 431 DefInt(SQLITE_AUTH); 432 DefInt(SQLITE_FORMAT); 433 DefInt(SQLITE_RANGE); 434 DefInt(SQLITE_NOTADB); 435 DefInt(SQLITE_NOTICE); 436 DefInt(SQLITE_WARNING); 437 DefInt(SQLITE_ROW); 438 DefInt(SQLITE_DONE); 439 // Extended Result Codes 440 DefInt(SQLITE_ERROR_MISSING_COLLSEQ); 441 DefInt(SQLITE_ERROR_RETRY); 442 DefInt(SQLITE_ERROR_SNAPSHOT); 443 DefInt(SQLITE_IOERR_READ); 444 DefInt(SQLITE_IOERR_SHORT_READ); 445 DefInt(SQLITE_IOERR_WRITE); 446 DefInt(SQLITE_IOERR_FSYNC); 447 DefInt(SQLITE_IOERR_DIR_FSYNC); 448 DefInt(SQLITE_IOERR_TRUNCATE); 449 DefInt(SQLITE_IOERR_FSTAT); 450 DefInt(SQLITE_IOERR_UNLOCK); 451 DefInt(SQLITE_IOERR_RDLOCK); 452 DefInt(SQLITE_IOERR_DELETE); 453 DefInt(SQLITE_IOERR_BLOCKED); 454 DefInt(SQLITE_IOERR_NOMEM); 455 DefInt(SQLITE_IOERR_ACCESS); 456 DefInt(SQLITE_IOERR_CHECKRESERVEDLOCK); 457 DefInt(SQLITE_IOERR_LOCK); 458 DefInt(SQLITE_IOERR_CLOSE); 459 DefInt(SQLITE_IOERR_DIR_CLOSE); 460 DefInt(SQLITE_IOERR_SHMOPEN); 461 DefInt(SQLITE_IOERR_SHMSIZE); 462 DefInt(SQLITE_IOERR_SHMLOCK); 463 DefInt(SQLITE_IOERR_SHMMAP); 464 DefInt(SQLITE_IOERR_SEEK); 465 DefInt(SQLITE_IOERR_DELETE_NOENT); 466 DefInt(SQLITE_IOERR_MMAP); 467 DefInt(SQLITE_IOERR_GETTEMPPATH); 468 DefInt(SQLITE_IOERR_CONVPATH); 469 DefInt(SQLITE_IOERR_VNODE); 470 DefInt(SQLITE_IOERR_AUTH); 471 DefInt(SQLITE_IOERR_BEGIN_ATOMIC); 472 DefInt(SQLITE_IOERR_COMMIT_ATOMIC); 473 DefInt(SQLITE_IOERR_ROLLBACK_ATOMIC); 474 DefInt(SQLITE_IOERR_DATA); 475 DefInt(SQLITE_IOERR_CORRUPTFS); 476 DefInt(SQLITE_LOCKED_SHAREDCACHE); 477 DefInt(SQLITE_LOCKED_VTAB); 478 DefInt(SQLITE_BUSY_RECOVERY); 479 DefInt(SQLITE_BUSY_SNAPSHOT); 480 DefInt(SQLITE_BUSY_TIMEOUT); 481 DefInt(SQLITE_CANTOPEN_NOTEMPDIR); 482 DefInt(SQLITE_CANTOPEN_ISDIR); 483 DefInt(SQLITE_CANTOPEN_FULLPATH); 484 DefInt(SQLITE_CANTOPEN_CONVPATH); 485 //DefInt(SQLITE_CANTOPEN_DIRTYWAL)/*docs say not used*/; 486 DefInt(SQLITE_CANTOPEN_SYMLINK); 487 DefInt(SQLITE_CORRUPT_VTAB); 488 DefInt(SQLITE_CORRUPT_SEQUENCE); 489 DefInt(SQLITE_CORRUPT_INDEX); 490 DefInt(SQLITE_READONLY_RECOVERY); 491 DefInt(SQLITE_READONLY_CANTLOCK); 492 DefInt(SQLITE_READONLY_ROLLBACK); 493 DefInt(SQLITE_READONLY_DBMOVED); 494 DefInt(SQLITE_READONLY_CANTINIT); 495 DefInt(SQLITE_READONLY_DIRECTORY); 496 DefInt(SQLITE_ABORT_ROLLBACK); 497 DefInt(SQLITE_CONSTRAINT_CHECK); 498 DefInt(SQLITE_CONSTRAINT_COMMITHOOK); 499 DefInt(SQLITE_CONSTRAINT_FOREIGNKEY); 500 DefInt(SQLITE_CONSTRAINT_FUNCTION); 501 DefInt(SQLITE_CONSTRAINT_NOTNULL); 502 DefInt(SQLITE_CONSTRAINT_PRIMARYKEY); 503 DefInt(SQLITE_CONSTRAINT_TRIGGER); 504 DefInt(SQLITE_CONSTRAINT_UNIQUE); 505 DefInt(SQLITE_CONSTRAINT_VTAB); 506 DefInt(SQLITE_CONSTRAINT_ROWID); 507 DefInt(SQLITE_CONSTRAINT_PINNED); 508 DefInt(SQLITE_CONSTRAINT_DATATYPE); 509 DefInt(SQLITE_NOTICE_RECOVER_WAL); 510 DefInt(SQLITE_NOTICE_RECOVER_ROLLBACK); 511 DefInt(SQLITE_WARNING_AUTOINDEX); 512 DefInt(SQLITE_AUTH_USER); 513 DefInt(SQLITE_OK_LOAD_PERMANENTLY); 514 //DefInt(SQLITE_OK_SYMLINK) /* internal use only */; 515 } _DefGroup; 516 517 DefGroup(serialize){ 518 DefInt(SQLITE_SERIALIZE_NOCOPY); 519 DefInt(SQLITE_DESERIALIZE_FREEONCLOSE); 520 DefInt(SQLITE_DESERIALIZE_READONLY); 521 DefInt(SQLITE_DESERIALIZE_RESIZEABLE); 522 } _DefGroup; 523 524 DefGroup(syncFlags) { 525 DefInt(SQLITE_SYNC_NORMAL); 526 DefInt(SQLITE_SYNC_FULL); 527 DefInt(SQLITE_SYNC_DATAONLY); 528 } _DefGroup; 529 530 DefGroup(udfFlags) { 531 DefInt(SQLITE_DETERMINISTIC); 532 DefInt(SQLITE_DIRECTONLY); 533 DefInt(SQLITE_INNOCUOUS); 534 } _DefGroup; 535 536 DefGroup(version) { 537 DefInt(SQLITE_VERSION_NUMBER); 538 DefStr(SQLITE_VERSION); 539 DefStr(SQLITE_SOURCE_ID); 540 } _DefGroup; 541 542 #undef DefGroup 543 #undef DefStr 544 #undef DefInt 545 #undef _DefGroup 546 547 /* 548 ** Emit an array of "StructBinder" struct descripions, which look 549 ** like: 550 ** 551 ** { 552 ** "name": "MyStruct", 553 ** "sizeof": 16, 554 ** "members": { 555 ** "member1": {"offset": 0,"sizeof": 4,"signature": "i"}, 556 ** "member2": {"offset": 4,"sizeof": 4,"signature": "p"}, 557 ** "member3": {"offset": 8,"sizeof": 8,"signature": "j"} 558 ** } 559 ** } 560 ** 561 ** Detailed documentation for those bits are in the docs for the 562 ** Jaccwabyt JS-side component. 563 */ 564 565 /** Macros for emitting StructBinder description. */ 566 #define StructBinder__(TYPE) \ 567 n = 0; \ 568 outf("%s{", (structCount++ ? ", " : "")); \ 569 out("\"name\": \"" # TYPE "\","); \ 570 outf("\"sizeof\": %d", (int)sizeof(TYPE)); \ 571 out(",\"members\": {"); 572 #define StructBinder_(T) StructBinder__(T) 573 /** ^^^ indirection needed to expand CurrentStruct */ 574 #define StructBinder StructBinder_(CurrentStruct) 575 #define _StructBinder CloseBrace(2) 576 #define M(MEMBER,SIG) \ 577 outf("%s\"%s\": " \ 578 "{\"offset\":%d,\"sizeof\": %d,\"signature\":\"%s\"}", \ 579 (n++ ? ", " : ""), #MEMBER, \ 580 (int)offsetof(CurrentStruct,MEMBER), \ 581 (int)sizeof(((CurrentStruct*)0)->MEMBER), \ 582 SIG) 583 584 structCount = 0; 585 out(", \"structs\": ["); { 586 587 #define CurrentStruct sqlite3_vfs 588 StructBinder { 589 M(iVersion,"i"); 590 M(szOsFile,"i"); 591 M(mxPathname,"i"); 592 M(pNext,"p"); 593 M(zName,"s"); 594 M(pAppData,"p"); 595 M(xOpen,"i(pppip)"); 596 M(xDelete,"i(ppi)"); 597 M(xAccess,"i(ppip)"); 598 M(xFullPathname,"i(ppip)"); 599 M(xDlOpen,"p(pp)"); 600 M(xDlError,"p(pip)"); 601 M(xDlSym,"p()"); 602 M(xDlClose,"v(pp)"); 603 M(xRandomness,"i(pip)"); 604 M(xSleep,"i(pi)"); 605 M(xCurrentTime,"i(pp)"); 606 M(xGetLastError,"i(pip)"); 607 M(xCurrentTimeInt64,"i(pp)"); 608 M(xSetSystemCall,"i(ppp)"); 609 M(xGetSystemCall,"p(pp)"); 610 M(xNextSystemCall,"p(pp)"); 611 } _StructBinder; 612 #undef CurrentStruct 613 614 #define CurrentStruct sqlite3_io_methods 615 StructBinder { 616 M(iVersion,"i"); 617 M(xClose,"i(p)"); 618 M(xRead,"i(ppij)"); 619 M(xWrite,"i(ppij)"); 620 M(xTruncate,"i(pj)"); 621 M(xSync,"i(pi)"); 622 M(xFileSize,"i(pp)"); 623 M(xLock,"i(pi)"); 624 M(xUnlock,"i(pi)"); 625 M(xCheckReservedLock,"i(pp)"); 626 M(xFileControl,"i(pip)"); 627 M(xSectorSize,"i(p)"); 628 M(xDeviceCharacteristics,"i(p)"); 629 M(xShmMap,"i(piiip)"); 630 M(xShmLock,"i(piii)"); 631 M(xShmBarrier,"v(p)"); 632 M(xShmUnmap,"i(pi)"); 633 M(xFetch,"i(pjip)"); 634 M(xUnfetch,"i(pjp)"); 635 } _StructBinder; 636 #undef CurrentStruct 637 638 #define CurrentStruct sqlite3_file 639 StructBinder { 640 M(pMethods,"p"); 641 } _StructBinder; 642 #undef CurrentStruct 643 644 } out( "]"/*structs*/); 645 646 out("}"/*top-level object*/); 647 *pos = 0; 648 strBuf[0] = '{'/*end of the race-condition workaround*/; 649 return strBuf; 650 #undef StructBinder 651 #undef StructBinder_ 652 #undef StructBinder__ 653 #undef M 654 #undef _StructBinder 655 #undef CloseBrace 656 #undef out 657 #undef outf 658 #undef lenCheck 659 } 660 661 /* 662 ** This function is NOT part of the sqlite3 public API. It is strictly 663 ** for use by the sqlite project's own JS/WASM bindings. 664 ** 665 ** This function invokes the xDelete method of the default VFS, 666 ** passing on the given filename. If zName is NULL, no default VFS is 667 ** found, or it has no xDelete method, SQLITE_MISUSE is returned, else 668 ** the result of the xDelete() call is returned. 669 */ 670 WASM_KEEP 671 int sqlite3_wasm_vfs_unlink(const char * zName){ 672 int rc = SQLITE_MISUSE /* ??? */; 673 sqlite3_vfs * const pVfs = sqlite3_vfs_find(0); 674 #if defined(__EMSCRIPTEN__) 675 emscripten_console_warn("sqlite3_wasm_vfs_unlink() will be removed."); 676 #endif 677 if( zName && pVfs && pVfs->xDelete ){ 678 rc = pVfs->xDelete(pVfs, zName, 1); 679 } 680 return rc; 681 } 682 683 /* 684 ** Uses the current database's VFS xRead to stream the db file's 685 ** contents out to the given callback. The callback gets a single 686 ** chunk of size n (its 2nd argument) on each call and must return 0 687 ** on success, non-0 on error. This function returns 0 on success, 688 ** SQLITE_NOTFOUND if no db is open, or propagates any other non-0 689 ** code from the callback. Note that this is not thread-friendly: it 690 ** expects that it will be the only thread reading the db file and 691 ** takes no measures to ensure that is the case. 692 ** 693 ** This implementation appears to work fine, but 694 ** sqlite3_wasm_db_serialize() is arguably the better way to achieve 695 ** this. 696 */ 697 WASM_KEEP 698 int sqlite3_wasm_db_export_chunked( sqlite3* pDb, 699 int (*xCallback)(unsigned const char *zOut, int n) ){ 700 sqlite3_int64 nSize = 0; 701 sqlite3_int64 nPos = 0; 702 sqlite3_file * pFile = 0; 703 unsigned char buf[1024 * 8]; 704 int nBuf = (int)sizeof(buf); 705 int rc = pDb 706 ? sqlite3_file_control(pDb, "main", 707 SQLITE_FCNTL_FILE_POINTER, &pFile) 708 : SQLITE_NOTFOUND; 709 if( rc ) return rc; 710 rc = pFile->pMethods->xFileSize(pFile, &nSize); 711 if( rc ) return rc; 712 if(nSize % nBuf){ 713 /* DB size is not an even multiple of the buffer size. Reduce 714 ** buffer size so that we do not unduly inflate the db size 715 ** with zero-padding when exporting. */ 716 if(0 == nSize % 4096) nBuf = 4096; 717 else if(0 == nSize % 2048) nBuf = 2048; 718 else if(0 == nSize % 1024) nBuf = 1024; 719 else nBuf = 512; 720 } 721 for( ; 0==rc && nPos<nSize; nPos += nBuf ){ 722 rc = pFile->pMethods->xRead(pFile, buf, nBuf, nPos); 723 if(SQLITE_IOERR_SHORT_READ == rc){ 724 rc = (nPos + nBuf) < nSize ? rc : 0/*assume EOF*/; 725 } 726 if( 0==rc ) rc = xCallback(buf, nBuf); 727 } 728 return rc; 729 } 730 731 /* 732 ** A proxy for sqlite3_serialize() which serializes the "main" schema 733 ** of pDb, placing the serialized output in pOut and nOut. nOut may be 734 ** NULL. If pDb or pOut are NULL then SQLITE_MISUSE is returned. If 735 ** allocation of the serialized copy fails, SQLITE_NOMEM is returned. 736 ** On success, 0 is returned and `*pOut` will contain a pointer to the 737 ** memory unless mFlags includes SQLITE_SERIALIZE_NOCOPY and the 738 ** database has no contiguous memory representation, in which case 739 ** `*pOut` will be NULL but 0 will be returned. 740 ** 741 ** If `*pOut` is not NULL, the caller is responsible for passing it to 742 ** sqlite3_free() to free it. 743 */ 744 WASM_KEEP 745 int sqlite3_wasm_db_serialize( sqlite3* pDb, unsigned char **pOut, sqlite3_int64 * nOut, 746 unsigned int mFlags ){ 747 unsigned char * z; 748 if( !pDb || !pOut ) return SQLITE_MISUSE; 749 if(nOut) *nOut = 0; 750 z = sqlite3_serialize(pDb, "main", nOut, mFlags); 751 if( z || (SQLITE_SERIALIZE_NOCOPY & mFlags) ){ 752 *pOut = z; 753 return 0; 754 }else{ 755 return SQLITE_NOMEM; 756 } 757 } 758 759 760 #if defined(__EMSCRIPTEN__) && defined(SQLITE_WASM_WASMFS) 761 #include <emscripten/wasmfs.h> 762 763 /* 764 ** This function is NOT part of the sqlite3 public API. It is strictly 765 ** for use by the sqlite project's own JS/WASM bindings, specifically 766 ** only when building with Emscripten's WASMFS support. 767 ** 768 ** This function should only be called if the JS side detects the 769 ** existence of the Origin-Private FileSystem (OPFS) APIs in the 770 ** client. The first time it is called, this function instantiates a 771 ** WASMFS backend impl for OPFS. On success, subsequent calls are 772 ** no-ops. 773 ** 774 ** This function may be passed a "mount point" name, which must have a 775 ** leading "/" and is currently restricted to a single path component, 776 ** e.g. "/foo" is legal but "/foo/" and "/foo/bar" are not. If it is 777 ** NULL or empty, it defaults to "/persistent". 778 ** 779 ** Returns 0 on success, SQLITE_NOMEM if instantiation of the backend 780 ** object fails, SQLITE_IOERR if mkdir() of the zMountPoint dir in 781 ** the virtual FS fails. In builds compiled without SQLITE_WASM_WASMFS 782 ** defined, SQLITE_NOTFOUND is returned without side effects. 783 */ 784 WASM_KEEP 785 int sqlite3_wasm_init_wasmfs(const char *zMountPoint){ 786 static backend_t pOpfs = 0; 787 if( !zMountPoint || !*zMountPoint ) zMountPoint = "/opfs"; 788 if( !pOpfs ){ 789 pOpfs = wasmfs_create_opfs_backend(); 790 if( pOpfs ){ 791 emscripten_console_log("Created WASMFS OPFS backend."); 792 } 793 } 794 /** It's not enough to instantiate the backend. We have to create a 795 mountpoint in the VFS and attach the backend to it. */ 796 if( pOpfs && 0!=access(zMountPoint, F_OK) ){ 797 /* mkdir() simply hangs when called from fiddle app. Cause is 798 not yet determined but the hypothesis is an init-order 799 issue. */ 800 /* Note that this check and is not robust but it will 801 hypothetically suffice for the transient wasm-based virtual 802 filesystem we're currently running in. */ 803 const int rc = wasmfs_create_directory(zMountPoint, 0777, pOpfs); 804 emscripten_console_logf("OPFS mkdir(%s) rc=%d", zMountPoint, rc); 805 if(rc) return SQLITE_IOERR; 806 } 807 return pOpfs ? 0 : SQLITE_NOMEM; 808 } 809 #else 810 WASM_KEEP 811 int sqlite3_wasm_init_wasmfs(const char *zUnused){ 812 emscripten_console_warn("WASMFS OPFS is not compiled in."); 813 if(zUnused){/*unused*/} 814 return SQLITE_NOTFOUND; 815 } 816 #endif /* __EMSCRIPTEN__ && SQLITE_WASM_WASMFS */ 817 818 #undef WASM_KEEP 819