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