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 #ifndef SQLITE_DEFAULT_UNIX_VFS 17 # define SQLITE_DEFAULT_UNIX_VFS "unix-none" 18 #endif 19 #ifndef SQLITE_OMIT_DEPRECATED 20 # define SQLITE_OMIT_DEPRECATED 21 #endif 22 #ifndef SQLITE_OMIT_LOAD_EXTENSION 23 # define SQLITE_OMIT_LOAD_EXTENSION 24 #endif 25 #ifndef SQLITE_OMIT_SHARED_CACHE 26 # define SQLITE_OMIT_SHARED_CACHE 27 #endif 28 #ifndef SQLITE_OMIT_UTF16 29 # define SQLITE_OMIT_UTF16 30 #endif 31 #ifndef SQLITE_OS_KV_OPTIONAL 32 # define SQLITE_OS_KV_OPTIONAL 1 33 #endif 34 #ifndef SQLITE_TEMP_STORE 35 # define SQLITE_TEMP_STORE 3 36 #endif 37 #ifndef SQLITE_THREADSAFE 38 # define SQLITE_THREADSAFE 0 39 #endif 40 41 #include "sqlite3.c" /* yes, .c instead of .h. */ 42 43 /* 44 ** WASM_KEEP is identical to EMSCRIPTEN_KEEPALIVE but is not 45 ** Emscripten-specific. It explicitly marks functions for export into 46 ** the target wasm file without requiring explicit listing of those 47 ** functions in Emscripten's -sEXPORTED_FUNCTIONS=... list (or 48 ** equivalent in other build platforms). Any function with neither 49 ** this attribute nor which is listed as an explicit export will not 50 ** be exported from the wasm file (but may still be used internally 51 ** within the wasm file). 52 ** 53 ** The functions in this file (sqlite3-wasm.c) which require exporting 54 ** are marked with this flag. They may also be added to any explicit 55 ** build-time export list but need not be. All of these APIs are 56 ** intended for use only within the project's own JS/WASM code, and 57 ** not by client code, so an argument can be made for reducing their 58 ** visibility by not including them in any build-time export lists. 59 ** 60 ** 2022-09-11: it's not yet _proven_ that this approach works in 61 ** non-Emscripten builds. If not, such builds will need to export 62 ** those using the --export=... wasm-ld flag (or equivalent). As of 63 ** this writing we are tied to Emscripten for various reasons 64 ** and cannot test the library with other build environments. 65 */ 66 #define WASM_KEEP __attribute__((used,visibility("default"))) 67 // See also: 68 //__attribute__((export_name("theExportedName"), used, visibility("default"))) 69 70 /* 71 ** This function is NOT part of the sqlite3 public API. It is strictly 72 ** for use by the sqlite project's own JS/WASM bindings. 73 ** 74 ** For purposes of certain hand-crafted C/Wasm function bindings, we 75 ** need a way of reporting errors which is consistent with the rest of 76 ** the C API, as opposed to throwing JS exceptions. To that end, this 77 ** internal-use-only function is a thin proxy around 78 ** sqlite3ErrorWithMessage(). The intent is that it only be used from 79 ** Wasm bindings such as sqlite3_prepare_v2/v3(), and definitely not 80 ** from client code. 81 ** 82 ** Returns err_code. 83 */ 84 WASM_KEEP 85 int sqlite3_wasm_db_error(sqlite3*db, int err_code, const char *zMsg){ 86 if(0!=zMsg){ 87 const int nMsg = sqlite3Strlen30(zMsg); 88 sqlite3ErrorWithMsg(db, err_code, "%.*s", nMsg, zMsg); 89 }else{ 90 sqlite3ErrorWithMsg(db, err_code, NULL); 91 } 92 return err_code; 93 } 94 95 /* 96 ** This function is NOT part of the sqlite3 public API. It is strictly 97 ** for use by the sqlite project's own JS/WASM bindings. Unlike the 98 ** rest of the sqlite3 API, this part requires C99 for snprintf() and 99 ** variadic macros. 100 ** 101 ** Returns a string containing a JSON-format "enum" of C-level 102 ** constants intended to be imported into the JS environment. The JSON 103 ** is initialized the first time this function is called and that 104 ** result is reused for all future calls. 105 ** 106 ** If this function returns NULL then it means that the internal 107 ** buffer is not large enough for the generated JSON. In debug builds 108 ** that will trigger an assert(). 109 */ 110 WASM_KEEP 111 const char * sqlite3_wasm_enum_json(void){ 112 static char strBuf[1024 * 12] = {0} /* where the JSON goes */; 113 int n = 0, childCount = 0, structCount = 0 114 /* output counters for figuring out where commas go */; 115 char * pos = &strBuf[1] /* skip first byte for now to help protect 116 ** against a small race condition */; 117 char const * const zEnd = pos + sizeof(strBuf) /* one-past-the-end */; 118 if(strBuf[0]) return strBuf; 119 /* Leave strBuf[0] at 0 until the end to help guard against a tiny 120 ** race condition. If this is called twice concurrently, they might 121 ** end up both writing to strBuf, but they'll both write the same 122 ** thing, so that's okay. If we set byte 0 up front then the 2nd 123 ** instance might return and use the string before the 1st instance 124 ** is done filling it. */ 125 126 /* Core output macros... */ 127 #define lenCheck assert(pos < zEnd - 128 \ 128 && "sqlite3_wasm_enum_json() buffer is too small."); \ 129 if(pos >= zEnd - 128) return 0 130 #define outf(format,...) \ 131 pos += snprintf(pos, ((size_t)(zEnd - pos)), format, __VA_ARGS__); \ 132 lenCheck 133 #define out(TXT) outf("%s",TXT) 134 #define CloseBrace(LEVEL) \ 135 assert(LEVEL<5); memset(pos, '}', LEVEL); pos+=LEVEL; lenCheck 136 137 /* Macros for emitting maps of integer- and string-type macros to 138 ** their values. */ 139 #define DefGroup(KEY) n = 0; \ 140 outf("%s\"" #KEY "\": {",(childCount++ ? "," : "")); 141 #define DefInt(KEY) \ 142 outf("%s\"%s\": %d", (n++ ? ", " : ""), #KEY, (int)KEY) 143 #define DefStr(KEY) \ 144 outf("%s\"%s\": \"%s\"", (n++ ? ", " : ""), #KEY, KEY) 145 #define _DefGroup CloseBrace(1) 146 147 DefGroup(version) { 148 DefInt(SQLITE_VERSION_NUMBER); 149 DefStr(SQLITE_VERSION); 150 DefStr(SQLITE_SOURCE_ID); 151 } _DefGroup; 152 153 DefGroup(resultCodes) { 154 DefInt(SQLITE_OK); 155 DefInt(SQLITE_ERROR); 156 DefInt(SQLITE_INTERNAL); 157 DefInt(SQLITE_PERM); 158 DefInt(SQLITE_ABORT); 159 DefInt(SQLITE_BUSY); 160 DefInt(SQLITE_LOCKED); 161 DefInt(SQLITE_NOMEM); 162 DefInt(SQLITE_READONLY); 163 DefInt(SQLITE_INTERRUPT); 164 DefInt(SQLITE_IOERR); 165 DefInt(SQLITE_CORRUPT); 166 DefInt(SQLITE_NOTFOUND); 167 DefInt(SQLITE_FULL); 168 DefInt(SQLITE_CANTOPEN); 169 DefInt(SQLITE_PROTOCOL); 170 DefInt(SQLITE_EMPTY); 171 DefInt(SQLITE_SCHEMA); 172 DefInt(SQLITE_TOOBIG); 173 DefInt(SQLITE_CONSTRAINT); 174 DefInt(SQLITE_MISMATCH); 175 DefInt(SQLITE_MISUSE); 176 DefInt(SQLITE_NOLFS); 177 DefInt(SQLITE_AUTH); 178 DefInt(SQLITE_FORMAT); 179 DefInt(SQLITE_RANGE); 180 DefInt(SQLITE_NOTADB); 181 DefInt(SQLITE_NOTICE); 182 DefInt(SQLITE_WARNING); 183 DefInt(SQLITE_ROW); 184 DefInt(SQLITE_DONE); 185 186 // Extended Result Codes 187 DefInt(SQLITE_ERROR_MISSING_COLLSEQ); 188 DefInt(SQLITE_ERROR_RETRY); 189 DefInt(SQLITE_ERROR_SNAPSHOT); 190 DefInt(SQLITE_IOERR_READ); 191 DefInt(SQLITE_IOERR_SHORT_READ); 192 DefInt(SQLITE_IOERR_WRITE); 193 DefInt(SQLITE_IOERR_FSYNC); 194 DefInt(SQLITE_IOERR_DIR_FSYNC); 195 DefInt(SQLITE_IOERR_TRUNCATE); 196 DefInt(SQLITE_IOERR_FSTAT); 197 DefInt(SQLITE_IOERR_UNLOCK); 198 DefInt(SQLITE_IOERR_RDLOCK); 199 DefInt(SQLITE_IOERR_DELETE); 200 DefInt(SQLITE_IOERR_BLOCKED); 201 DefInt(SQLITE_IOERR_NOMEM); 202 DefInt(SQLITE_IOERR_ACCESS); 203 DefInt(SQLITE_IOERR_CHECKRESERVEDLOCK); 204 DefInt(SQLITE_IOERR_LOCK); 205 DefInt(SQLITE_IOERR_CLOSE); 206 DefInt(SQLITE_IOERR_DIR_CLOSE); 207 DefInt(SQLITE_IOERR_SHMOPEN); 208 DefInt(SQLITE_IOERR_SHMSIZE); 209 DefInt(SQLITE_IOERR_SHMLOCK); 210 DefInt(SQLITE_IOERR_SHMMAP); 211 DefInt(SQLITE_IOERR_SEEK); 212 DefInt(SQLITE_IOERR_DELETE_NOENT); 213 DefInt(SQLITE_IOERR_MMAP); 214 DefInt(SQLITE_IOERR_GETTEMPPATH); 215 DefInt(SQLITE_IOERR_CONVPATH); 216 DefInt(SQLITE_IOERR_VNODE); 217 DefInt(SQLITE_IOERR_AUTH); 218 DefInt(SQLITE_IOERR_BEGIN_ATOMIC); 219 DefInt(SQLITE_IOERR_COMMIT_ATOMIC); 220 DefInt(SQLITE_IOERR_ROLLBACK_ATOMIC); 221 DefInt(SQLITE_IOERR_DATA); 222 DefInt(SQLITE_IOERR_CORRUPTFS); 223 DefInt(SQLITE_LOCKED_SHAREDCACHE); 224 DefInt(SQLITE_LOCKED_VTAB); 225 DefInt(SQLITE_BUSY_RECOVERY); 226 DefInt(SQLITE_BUSY_SNAPSHOT); 227 DefInt(SQLITE_BUSY_TIMEOUT); 228 DefInt(SQLITE_CANTOPEN_NOTEMPDIR); 229 DefInt(SQLITE_CANTOPEN_ISDIR); 230 DefInt(SQLITE_CANTOPEN_FULLPATH); 231 DefInt(SQLITE_CANTOPEN_CONVPATH); 232 //DefInt(SQLITE_CANTOPEN_DIRTYWAL)/*docs say not used*/; 233 DefInt(SQLITE_CANTOPEN_SYMLINK); 234 DefInt(SQLITE_CORRUPT_VTAB); 235 DefInt(SQLITE_CORRUPT_SEQUENCE); 236 DefInt(SQLITE_CORRUPT_INDEX); 237 DefInt(SQLITE_READONLY_RECOVERY); 238 DefInt(SQLITE_READONLY_CANTLOCK); 239 DefInt(SQLITE_READONLY_ROLLBACK); 240 DefInt(SQLITE_READONLY_DBMOVED); 241 DefInt(SQLITE_READONLY_CANTINIT); 242 DefInt(SQLITE_READONLY_DIRECTORY); 243 DefInt(SQLITE_ABORT_ROLLBACK); 244 DefInt(SQLITE_CONSTRAINT_CHECK); 245 DefInt(SQLITE_CONSTRAINT_COMMITHOOK); 246 DefInt(SQLITE_CONSTRAINT_FOREIGNKEY); 247 DefInt(SQLITE_CONSTRAINT_FUNCTION); 248 DefInt(SQLITE_CONSTRAINT_NOTNULL); 249 DefInt(SQLITE_CONSTRAINT_PRIMARYKEY); 250 DefInt(SQLITE_CONSTRAINT_TRIGGER); 251 DefInt(SQLITE_CONSTRAINT_UNIQUE); 252 DefInt(SQLITE_CONSTRAINT_VTAB); 253 DefInt(SQLITE_CONSTRAINT_ROWID); 254 DefInt(SQLITE_CONSTRAINT_PINNED); 255 DefInt(SQLITE_CONSTRAINT_DATATYPE); 256 DefInt(SQLITE_NOTICE_RECOVER_WAL); 257 DefInt(SQLITE_NOTICE_RECOVER_ROLLBACK); 258 DefInt(SQLITE_WARNING_AUTOINDEX); 259 DefInt(SQLITE_AUTH_USER); 260 DefInt(SQLITE_OK_LOAD_PERMANENTLY); 261 //DefInt(SQLITE_OK_SYMLINK) /* internal use only */; 262 } _DefGroup; 263 264 DefGroup(dataTypes) { 265 DefInt(SQLITE_INTEGER); 266 DefInt(SQLITE_FLOAT); 267 DefInt(SQLITE_TEXT); 268 DefInt(SQLITE_BLOB); 269 DefInt(SQLITE_NULL); 270 } _DefGroup; 271 272 DefGroup(encodings) { 273 /* Noting that the wasm binding only aims to support UTF-8. */ 274 DefInt(SQLITE_UTF8); 275 DefInt(SQLITE_UTF16LE); 276 DefInt(SQLITE_UTF16BE); 277 DefInt(SQLITE_UTF16); 278 /*deprecated DefInt(SQLITE_ANY); */ 279 DefInt(SQLITE_UTF16_ALIGNED); 280 } _DefGroup; 281 282 DefGroup(blobFinalizers) { 283 /* SQLITE_STATIC/TRANSIENT need to be handled explicitly as 284 ** integers to avoid casting-related warnings. */ 285 out("\"SQLITE_STATIC\":0, \"SQLITE_TRANSIENT\":-1"); 286 } _DefGroup; 287 288 DefGroup(udfFlags) { 289 DefInt(SQLITE_DETERMINISTIC); 290 DefInt(SQLITE_DIRECTONLY); 291 DefInt(SQLITE_INNOCUOUS); 292 } _DefGroup; 293 294 DefGroup(openFlags) { 295 /* Noting that not all of these will have any effect in 296 ** WASM-space. */ 297 DefInt(SQLITE_OPEN_READONLY); 298 DefInt(SQLITE_OPEN_READWRITE); 299 DefInt(SQLITE_OPEN_CREATE); 300 DefInt(SQLITE_OPEN_URI); 301 DefInt(SQLITE_OPEN_MEMORY); 302 DefInt(SQLITE_OPEN_NOMUTEX); 303 DefInt(SQLITE_OPEN_FULLMUTEX); 304 DefInt(SQLITE_OPEN_SHAREDCACHE); 305 DefInt(SQLITE_OPEN_PRIVATECACHE); 306 DefInt(SQLITE_OPEN_EXRESCODE); 307 DefInt(SQLITE_OPEN_NOFOLLOW); 308 /* OPEN flags for use with VFSes... */ 309 DefInt(SQLITE_OPEN_MAIN_DB); 310 DefInt(SQLITE_OPEN_MAIN_JOURNAL); 311 DefInt(SQLITE_OPEN_TEMP_DB); 312 DefInt(SQLITE_OPEN_TEMP_JOURNAL); 313 DefInt(SQLITE_OPEN_TRANSIENT_DB); 314 DefInt(SQLITE_OPEN_SUBJOURNAL); 315 DefInt(SQLITE_OPEN_SUPER_JOURNAL); 316 DefInt(SQLITE_OPEN_WAL); 317 DefInt(SQLITE_OPEN_DELETEONCLOSE); 318 DefInt(SQLITE_OPEN_EXCLUSIVE); 319 } _DefGroup; 320 321 DefGroup(syncFlags) { 322 DefInt(SQLITE_SYNC_NORMAL); 323 DefInt(SQLITE_SYNC_FULL); 324 DefInt(SQLITE_SYNC_DATAONLY); 325 } _DefGroup; 326 327 DefGroup(prepareFlags) { 328 DefInt(SQLITE_PREPARE_PERSISTENT); 329 DefInt(SQLITE_PREPARE_NORMALIZE); 330 DefInt(SQLITE_PREPARE_NO_VTAB); 331 } _DefGroup; 332 333 DefGroup(flock) { 334 DefInt(SQLITE_LOCK_NONE); 335 DefInt(SQLITE_LOCK_SHARED); 336 DefInt(SQLITE_LOCK_RESERVED); 337 DefInt(SQLITE_LOCK_PENDING); 338 DefInt(SQLITE_LOCK_EXCLUSIVE); 339 } _DefGroup; 340 341 DefGroup(ioCap) { 342 DefInt(SQLITE_IOCAP_ATOMIC); 343 DefInt(SQLITE_IOCAP_ATOMIC512); 344 DefInt(SQLITE_IOCAP_ATOMIC1K); 345 DefInt(SQLITE_IOCAP_ATOMIC2K); 346 DefInt(SQLITE_IOCAP_ATOMIC4K); 347 DefInt(SQLITE_IOCAP_ATOMIC8K); 348 DefInt(SQLITE_IOCAP_ATOMIC16K); 349 DefInt(SQLITE_IOCAP_ATOMIC32K); 350 DefInt(SQLITE_IOCAP_ATOMIC64K); 351 DefInt(SQLITE_IOCAP_SAFE_APPEND); 352 DefInt(SQLITE_IOCAP_SEQUENTIAL); 353 DefInt(SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN); 354 DefInt(SQLITE_IOCAP_POWERSAFE_OVERWRITE); 355 DefInt(SQLITE_IOCAP_IMMUTABLE); 356 DefInt(SQLITE_IOCAP_BATCH_ATOMIC); 357 } _DefGroup; 358 359 DefGroup(fcntl) { 360 DefInt(SQLITE_FCNTL_LOCKSTATE); 361 DefInt(SQLITE_FCNTL_GET_LOCKPROXYFILE); 362 DefInt(SQLITE_FCNTL_SET_LOCKPROXYFILE); 363 DefInt(SQLITE_FCNTL_LAST_ERRNO); 364 DefInt(SQLITE_FCNTL_SIZE_HINT); 365 DefInt(SQLITE_FCNTL_CHUNK_SIZE); 366 DefInt(SQLITE_FCNTL_FILE_POINTER); 367 DefInt(SQLITE_FCNTL_SYNC_OMITTED); 368 DefInt(SQLITE_FCNTL_WIN32_AV_RETRY); 369 DefInt(SQLITE_FCNTL_PERSIST_WAL); 370 DefInt(SQLITE_FCNTL_OVERWRITE); 371 DefInt(SQLITE_FCNTL_VFSNAME); 372 DefInt(SQLITE_FCNTL_POWERSAFE_OVERWRITE); 373 DefInt(SQLITE_FCNTL_PRAGMA); 374 DefInt(SQLITE_FCNTL_BUSYHANDLER); 375 DefInt(SQLITE_FCNTL_TEMPFILENAME); 376 DefInt(SQLITE_FCNTL_MMAP_SIZE); 377 DefInt(SQLITE_FCNTL_TRACE); 378 DefInt(SQLITE_FCNTL_HAS_MOVED); 379 DefInt(SQLITE_FCNTL_SYNC); 380 DefInt(SQLITE_FCNTL_COMMIT_PHASETWO); 381 DefInt(SQLITE_FCNTL_WIN32_SET_HANDLE); 382 DefInt(SQLITE_FCNTL_WAL_BLOCK); 383 DefInt(SQLITE_FCNTL_ZIPVFS); 384 DefInt(SQLITE_FCNTL_RBU); 385 DefInt(SQLITE_FCNTL_VFS_POINTER); 386 DefInt(SQLITE_FCNTL_JOURNAL_POINTER); 387 DefInt(SQLITE_FCNTL_WIN32_GET_HANDLE); 388 DefInt(SQLITE_FCNTL_PDB); 389 DefInt(SQLITE_FCNTL_BEGIN_ATOMIC_WRITE); 390 DefInt(SQLITE_FCNTL_COMMIT_ATOMIC_WRITE); 391 DefInt(SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE); 392 DefInt(SQLITE_FCNTL_LOCK_TIMEOUT); 393 DefInt(SQLITE_FCNTL_DATA_VERSION); 394 DefInt(SQLITE_FCNTL_SIZE_LIMIT); 395 DefInt(SQLITE_FCNTL_CKPT_DONE); 396 DefInt(SQLITE_FCNTL_RESERVE_BYTES); 397 DefInt(SQLITE_FCNTL_CKPT_START); 398 DefInt(SQLITE_FCNTL_EXTERNAL_READER); 399 DefInt(SQLITE_FCNTL_CKSM_FILE); 400 } _DefGroup; 401 402 DefGroup(access){ 403 DefInt(SQLITE_ACCESS_EXISTS); 404 DefInt(SQLITE_ACCESS_READWRITE); 405 DefInt(SQLITE_ACCESS_READ)/*docs say this is unused*/; 406 } _DefGroup; 407 408 #undef DefGroup 409 #undef DefStr 410 #undef DefInt 411 #undef _DefGroup 412 413 /* 414 ** Emit an array of "StructBinder" struct descripions, which look 415 ** like: 416 ** 417 ** { 418 ** "name": "MyStruct", 419 ** "sizeof": 16, 420 ** "members": { 421 ** "member1": {"offset": 0,"sizeof": 4,"signature": "i"}, 422 ** "member2": {"offset": 4,"sizeof": 4,"signature": "p"}, 423 ** "member3": {"offset": 8,"sizeof": 8,"signature": "j"} 424 ** } 425 ** } 426 ** 427 ** Detailed documentation for those bits are in the docs for the 428 ** Jaccwabyt JS-side component. 429 */ 430 431 /** Macros for emitting StructBinder description. */ 432 #define StructBinder__(TYPE) \ 433 n = 0; \ 434 outf("%s{", (structCount++ ? ", " : "")); \ 435 out("\"name\": \"" # TYPE "\","); \ 436 outf("\"sizeof\": %d", (int)sizeof(TYPE)); \ 437 out(",\"members\": {"); 438 #define StructBinder_(T) StructBinder__(T) 439 /** ^^^ indirection needed to expand CurrentStruct */ 440 #define StructBinder StructBinder_(CurrentStruct) 441 #define _StructBinder CloseBrace(2) 442 #define M(MEMBER,SIG) \ 443 outf("%s\"%s\": " \ 444 "{\"offset\":%d,\"sizeof\": %d,\"signature\":\"%s\"}", \ 445 (n++ ? ", " : ""), #MEMBER, \ 446 (int)offsetof(CurrentStruct,MEMBER), \ 447 (int)sizeof(((CurrentStruct*)0)->MEMBER), \ 448 SIG) 449 450 structCount = 0; 451 out(", \"structs\": ["); { 452 453 #define CurrentStruct sqlite3_vfs 454 StructBinder { 455 M(iVersion,"i"); 456 M(szOsFile,"i"); 457 M(mxPathname,"i"); 458 M(pNext,"p"); 459 M(zName,"s"); 460 M(pAppData,"p"); 461 M(xOpen,"i(pppip)"); 462 M(xDelete,"i(ppi)"); 463 M(xAccess,"i(ppip)"); 464 M(xFullPathname,"i(ppip)"); 465 M(xDlOpen,"p(pp)"); 466 M(xDlError,"p(pip)"); 467 M(xDlSym,"p()"); 468 M(xDlClose,"v(pp)"); 469 M(xRandomness,"i(pip)"); 470 M(xSleep,"i(pi)"); 471 M(xCurrentTime,"i(pp)"); 472 M(xGetLastError,"i(pip)"); 473 M(xCurrentTimeInt64,"i(pp)"); 474 M(xSetSystemCall,"i(ppp)"); 475 M(xGetSystemCall,"p(pp)"); 476 M(xNextSystemCall,"p(pp)"); 477 } _StructBinder; 478 #undef CurrentStruct 479 480 #define CurrentStruct sqlite3_io_methods 481 StructBinder { 482 M(iVersion,"i"); 483 M(xClose,"i(p)"); 484 M(xRead,"i(ppij)"); 485 M(xWrite,"i(ppij)"); 486 M(xTruncate,"i(pj)"); 487 M(xSync,"i(pi)"); 488 M(xFileSize,"i(pp)"); 489 M(xLock,"i(pi)"); 490 M(xUnlock,"i(pi)"); 491 M(xCheckReservedLock,"i(pp)"); 492 M(xFileControl,"i(pip)"); 493 M(xSectorSize,"i(p)"); 494 M(xDeviceCharacteristics,"i(p)"); 495 M(xShmMap,"i(piiip)"); 496 M(xShmLock,"i(piii)"); 497 M(xShmBarrier,"v(p)"); 498 M(xShmUnmap,"i(pi)"); 499 M(xFetch,"i(pjip)"); 500 M(xUnfetch,"i(pjp)"); 501 } _StructBinder; 502 #undef CurrentStruct 503 504 #define CurrentStruct sqlite3_file 505 StructBinder { 506 M(pMethods,"p"); 507 } _StructBinder; 508 #undef CurrentStruct 509 510 } out( "]"/*structs*/); 511 512 out("}"/*top-level object*/); 513 *pos = 0; 514 strBuf[0] = '{'/*end of the race-condition workaround*/; 515 return strBuf; 516 #undef StructBinder 517 #undef StructBinder_ 518 #undef StructBinder__ 519 #undef M 520 #undef _StructBinder 521 #undef CloseBrace 522 #undef out 523 #undef outf 524 #undef lenCheck 525 } 526 527 /* 528 ** This function is NOT part of the sqlite3 public API. It is strictly 529 ** for use by the sqlite project's own JS/WASM bindings. 530 ** 531 ** This function invokes the xDelete method of the default VFS, 532 ** passing on the given filename. If zName is NULL, no default VFS is 533 ** found, or it has no xDelete method, SQLITE_MISUSE is returned, else 534 ** the result of the xDelete() call is returned. 535 */ 536 WASM_KEEP 537 int sqlite3_wasm_vfs_unlink(const char * zName){ 538 int rc = SQLITE_MISUSE /* ??? */; 539 sqlite3_vfs * const pVfs = sqlite3_vfs_find(0); 540 if( zName && pVfs && pVfs->xDelete ){ 541 rc = pVfs->xDelete(pVfs, zName, 1); 542 } 543 return rc; 544 } 545 546 #if defined(__EMSCRIPTEN__) && defined(SQLITE_WASM_WASMFS) 547 #include <emscripten/wasmfs.h> 548 #include <emscripten/console.h> 549 550 /* 551 ** This function is NOT part of the sqlite3 public API. It is strictly 552 ** for use by the sqlite project's own JS/WASM bindings, specifically 553 ** only when building with Emscripten's WASMFS support. 554 ** 555 ** This function should only be called if the JS side detects the 556 ** existence of the Origin-Private FileSystem (OPFS) APIs in the 557 ** client. The first time it is called, this function instantiates a 558 ** WASMFS backend impl for OPFS. On success, subsequent calls are 559 ** no-ops. 560 ** 561 ** This function may be passed a "mount point" name, which must have a 562 ** leading "/" and is currently restricted to a single path component, 563 ** e.g. "/foo" is legal but "/foo/" and "/foo/bar" are not. If it is 564 ** NULL or empty, it defaults to "/persistent". 565 ** 566 ** Returns 0 on success, SQLITE_NOMEM if instantiation of the backend 567 ** object fails, SQLITE_IOERR if mkdir() of the zMountPoint dir in 568 ** the virtual FS fails. In builds compiled without SQLITE_WASM_WASMFS 569 ** defined, SQLITE_NOTFOUND is returned without side effects. 570 */ 571 WASM_KEEP 572 int sqlite3_wasm_init_wasmfs(const char *zMountPoint){ 573 static backend_t pOpfs = 0; 574 if( !zMountPoint || !*zMountPoint ) zMountPoint = "/opfs"; 575 if( !pOpfs ){ 576 pOpfs = wasmfs_create_opfs_backend(); 577 if( pOpfs ){ 578 emscripten_console_log("Created WASMFS OPFS backend."); 579 } 580 } 581 /** It's not enough to instantiate the backend. We have to create a 582 mountpoint in the VFS and attach the backend to it. */ 583 if( pOpfs && 0!=access(zMountPoint, F_OK) ){ 584 /* mkdir() simply hangs when called from fiddle app. Cause is 585 not yet determined but the hypothesis is an init-order 586 issue. */ 587 /* Note that this check and is not robust but it will 588 hypothetically suffice for the transient wasm-based virtual 589 filesystem we're currently running in. */ 590 const int rc = wasmfs_create_directory(zMountPoint, 0777, pOpfs); 591 emscripten_console_logf("OPFS mkdir(%s) rc=%d", zMountPoint, rc); 592 if(rc) return SQLITE_IOERR; 593 } 594 return pOpfs ? 0 : SQLITE_NOMEM; 595 } 596 #else 597 WASM_KEEP 598 int sqlite3_wasm_init_wasmfs(const char *zUnused){ 599 if(zUnused){/*unused*/} 600 return SQLITE_NOTFOUND; 601 } 602 #endif /* __EMSCRIPTEN__ && SQLITE_WASM_WASMFS */ 603 604 605 #undef WASM_KEEP 606