sqlite3-api-prologue.js 85 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196
  1. /*
  2. 2022-05-22
  3. The author disclaims copyright to this source code. In place of a
  4. legal notice, here is a blessing:
  5. * May you do good and not evil.
  6. * May you find forgiveness for yourself and forgive others.
  7. * May you share freely, never taking more than you give.
  8. ***********************************************************************
  9. This file is intended to be combined at build-time with other
  10. related code, most notably a header and footer which wraps this
  11. whole file into an Emscripten Module.postRun() handler. The sqlite3
  12. JS API has no hard requirements on Emscripten and does not expose
  13. any Emscripten APIs to clients. It is structured such that its build
  14. can be tweaked to include it in arbitrary WASM environments which
  15. can supply the necessary underlying features (e.g. a POSIX file I/O
  16. layer).
  17. Main project home page: https://sqlite.org
  18. Documentation home page: https://sqlite.org/wasm
  19. */
  20. /**
  21. sqlite3ApiBootstrap() is the only global symbol persistently
  22. exposed by this API. It is intended to be called one time at the
  23. end of the API amalgamation process, passed configuration details
  24. for the current environment, and then optionally be removed from
  25. the global object using `delete globalThis.sqlite3ApiBootstrap`.
  26. This function is not intended for client-level use. It is intended
  27. for use in creating bundles configured for specific WASM
  28. environments.
  29. This function expects a configuration object, intended to abstract
  30. away details specific to any given WASM environment, primarily so
  31. that it can be used without any direct dependency on
  32. Emscripten. (Note the default values for the config object!) The
  33. config object is only honored the first time this is
  34. called. Subsequent calls ignore the argument and return the same
  35. (configured) object which gets initialized by the first call. This
  36. function will throw if any of the required config options are
  37. missing.
  38. The config object properties include:
  39. - `exports`[^1]: the "exports" object for the current WASM
  40. environment. In an Emscripten-based build, this should be set to
  41. `Module['asm']`.
  42. - `memory`[^1]: optional WebAssembly.Memory object, defaulting to
  43. `exports.memory`. In Emscripten environments this should be set
  44. to `Module.wasmMemory` if the build uses `-sIMPORTED_MEMORY`, or be
  45. left undefined/falsy to default to `exports.memory` when using
  46. WASM-exported memory.
  47. - `bigIntEnabled`: true if BigInt support is enabled. Defaults to
  48. true if `globalThis.BigInt64Array` is available, else false. Some APIs
  49. will throw exceptions if called without BigInt support, as BigInt
  50. is required for marshalling C-side int64 into and out of JS.
  51. (Sidebar: it is technically possible to add int64 support via
  52. marshalling of int32 pairs, but doing so is unduly invasive.)
  53. - `allocExportName`: the name of the function, in `exports`, of the
  54. `malloc(3)`-compatible routine for the WASM environment. Defaults
  55. to `"sqlite3_malloc"`. Beware that using any allocator other than
  56. sqlite3_malloc() may require care in certain client-side code
  57. regarding which allocator is uses. Notably, sqlite3_deserialize()
  58. and sqlite3_serialize() can only safely use memory from different
  59. allocators under very specific conditions. The canonical builds
  60. of this API guaranty that `sqlite3_malloc()` is the JS-side
  61. allocator implementation.
  62. - `deallocExportName`: the name of the function, in `exports`, of
  63. the `free(3)`-compatible routine for the WASM
  64. environment. Defaults to `"sqlite3_free"`.
  65. - `reallocExportName`: the name of the function, in `exports`, of
  66. the `realloc(3)`-compatible routine for the WASM
  67. environment. Defaults to `"sqlite3_realloc"`.
  68. - `debug`, `log`, `warn`, and `error` may be functions equivalent
  69. to the like-named methods of the global `console` object. By
  70. default, these map directly to their `console` counterparts, but
  71. can be replaced with (e.g.) empty functions to squelch all such
  72. output.
  73. - `wasmfsOpfsDir`[^1]: Specifies the "mount point" of the OPFS-backed
  74. filesystem in WASMFS-capable builds.
  75. [^1] = This property may optionally be a function, in which case
  76. this function calls that function to fetch the value,
  77. enabling delayed evaluation.
  78. The returned object is the top-level sqlite3 namespace object.
  79. Client code may optionally assign sqlite3ApiBootstrap.defaultConfig
  80. an object-type value before calling sqlite3ApiBootstrap() (without
  81. arguments) in order to tell that call to use this object as its
  82. default config value. The intention of this is to provide
  83. downstream clients with a reasonably flexible approach for plugging
  84. in an environment-suitable configuration without having to define a
  85. new global-scope symbol.
  86. However, because clients who access this library via an
  87. Emscripten-hosted module will not have an opportunity to call
  88. sqlite3ApiBootstrap() themselves, nor to access it before it is
  89. called, an alternative option for setting the configuration is to
  90. define globalThis.sqlite3ApiConfig to an object. If it is set, it
  91. is used instead of sqlite3ApiBootstrap.defaultConfig if
  92. sqlite3ApiBootstrap() is called without arguments.
  93. Both sqlite3ApiBootstrap.defaultConfig and
  94. globalThis.sqlite3ApiConfig get deleted by sqlite3ApiBootstrap()
  95. because any changes to them made after that point would have no
  96. useful effect.
  97. */
  98. 'use strict';
  99. globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
  100. apiConfig = (globalThis.sqlite3ApiConfig || sqlite3ApiBootstrap.defaultConfig)
  101. ){
  102. if(sqlite3ApiBootstrap.sqlite3){ /* already initalized */
  103. (sqlite3ApiBootstrap.sqlite3.config || console).warn(
  104. "sqlite3ApiBootstrap() called multiple times.",
  105. "Config and external initializers are ignored on calls after the first."
  106. );
  107. return sqlite3ApiBootstrap.sqlite3;
  108. }
  109. const config = Object.assign(Object.create(null),{
  110. exports: undefined,
  111. memory: undefined,
  112. bigIntEnabled: (()=>{
  113. if('undefined'!==typeof Module){
  114. /* Emscripten module will contain HEAPU64 when built with
  115. -sWASM_BIGINT=1, else it will not.
  116. As of emsdk 3.1.55, when building in strict mode, HEAPxyz
  117. are only available if _explicitly_ included in the exports,
  118. else they are not. We do not (as of 2024-03-04) use -sSTRICT
  119. for the canonical builds.
  120. */
  121. if( !!Module.HEAPU64 ) return true;
  122. /* Else fall through and hope for the best. Nobody _really_
  123. builds this without BigInt support, do they? */
  124. }
  125. return !!globalThis.BigInt64Array;
  126. })(),
  127. debug: console.debug.bind(console),
  128. warn: console.warn.bind(console),
  129. error: console.error.bind(console),
  130. log: console.log.bind(console),
  131. wasmfsOpfsDir: '/opfs',
  132. /**
  133. useStdAlloc is just for testing allocator discrepancies. The
  134. docs guarantee that this is false in the canonical builds. For
  135. 99% of purposes it doesn't matter which allocators we use, but
  136. it becomes significant with, e.g., sqlite3_deserialize() and
  137. certain wasm.xWrap.resultAdapter()s.
  138. */
  139. useStdAlloc: false
  140. }, apiConfig || {});
  141. Object.assign(config, {
  142. allocExportName: config.useStdAlloc ? 'malloc' : 'sqlite3_malloc',
  143. deallocExportName: config.useStdAlloc ? 'free' : 'sqlite3_free',
  144. reallocExportName: config.useStdAlloc ? 'realloc' : 'sqlite3_realloc'
  145. }, config);
  146. [
  147. // If any of these config options are functions, replace them with
  148. // the result of calling that function...
  149. 'exports', 'memory', 'wasmfsOpfsDir'
  150. ].forEach((k)=>{
  151. if('function' === typeof config[k]){
  152. config[k] = config[k]();
  153. }
  154. });
  155. /**
  156. Eliminate any confusion about whether these config objects may
  157. be used after library initialization by eliminating the outward-facing
  158. objects...
  159. */
  160. delete globalThis.sqlite3ApiConfig;
  161. delete sqlite3ApiBootstrap.defaultConfig;
  162. /**
  163. The main sqlite3 binding API gets installed into this object,
  164. mimicking the C API as closely as we can. The numerous members
  165. names with prefixes 'sqlite3_' and 'SQLITE_' behave, insofar as
  166. possible, identically to the C-native counterparts, as documented at:
  167. https://www.sqlite.org/c3ref/intro.html
  168. A very few exceptions require an additional level of proxy
  169. function or may otherwise require special attention in the WASM
  170. environment, and all such cases are documented somewhere below
  171. in this file or in sqlite3-api-glue.js. capi members which are
  172. not documented are installed as 1-to-1 proxies for their
  173. C-side counterparts.
  174. */
  175. const capi = Object.create(null);
  176. /**
  177. Holds state which are specific to the WASM-related
  178. infrastructure and glue code.
  179. Note that a number of members of this object are injected
  180. dynamically after the api object is fully constructed, so
  181. not all are documented in this file.
  182. */
  183. const wasm = Object.create(null);
  184. /** Internal helper for SQLite3Error ctor. */
  185. const __rcStr = (rc)=>{
  186. return (capi.sqlite3_js_rc_str && capi.sqlite3_js_rc_str(rc))
  187. || ("Unknown result code #"+rc);
  188. };
  189. /** Internal helper for SQLite3Error ctor. */
  190. const __isInt = (n)=>'number'===typeof n && n===(n | 0);
  191. /**
  192. An Error subclass specifically for reporting DB-level errors and
  193. enabling clients to unambiguously identify such exceptions.
  194. The C-level APIs never throw, but some of the higher-level
  195. C-style APIs do and the object-oriented APIs use exceptions
  196. exclusively to report errors.
  197. */
  198. class SQLite3Error extends Error {
  199. /**
  200. Constructs this object with a message depending on its arguments:
  201. If its first argument is an integer, it is assumed to be
  202. an SQLITE_... result code and it is passed to
  203. sqlite3.capi.sqlite3_js_rc_str() to stringify it.
  204. If called with exactly 2 arguments and the 2nd is an object,
  205. that object is treated as the 2nd argument to the parent
  206. constructor.
  207. The exception's message is created by concatenating its
  208. arguments with a space between each, except for the
  209. two-args-with-an-object form and that the first argument will
  210. get coerced to a string, as described above, if it's an
  211. integer.
  212. If passed an integer first argument, the error object's
  213. `resultCode` member will be set to the given integer value,
  214. else it will be set to capi.SQLITE_ERROR.
  215. */
  216. constructor(...args){
  217. let rc;
  218. if(args.length){
  219. if(__isInt(args[0])){
  220. rc = args[0];
  221. if(1===args.length){
  222. super(__rcStr(args[0]));
  223. }else{
  224. const rcStr = __rcStr(rc);
  225. if('object'===typeof args[1]){
  226. super(rcStr,args[1]);
  227. }else{
  228. args[0] = rcStr+':';
  229. super(args.join(' '));
  230. }
  231. }
  232. }else{
  233. if(2===args.length && 'object'===typeof args[1]){
  234. super(...args);
  235. }else{
  236. super(args.join(' '));
  237. }
  238. }
  239. }
  240. this.resultCode = rc || capi.SQLITE_ERROR;
  241. this.name = 'SQLite3Error';
  242. }
  243. };
  244. /**
  245. Functionally equivalent to the SQLite3Error constructor but may
  246. be used as part of an expression, e.g.:
  247. ```
  248. return someFunction(x) || SQLite3Error.toss(...);
  249. ```
  250. */
  251. SQLite3Error.toss = (...args)=>{
  252. throw new SQLite3Error(...args);
  253. };
  254. const toss3 = SQLite3Error.toss;
  255. if(config.wasmfsOpfsDir && !/^\/[^/]+$/.test(config.wasmfsOpfsDir)){
  256. toss3("config.wasmfsOpfsDir must be falsy or in the form '/dir-name'.");
  257. }
  258. /**
  259. Returns true if n is a 32-bit (signed) integer, else
  260. false. This is used for determining when we need to switch to
  261. double-type DB operations for integer values in order to keep
  262. more precision.
  263. */
  264. const isInt32 = (n)=>{
  265. return ('bigint'!==typeof n /*TypeError: can't convert BigInt to number*/)
  266. && !!(n===(n|0) && n<=2147483647 && n>=-2147483648);
  267. };
  268. /**
  269. Returns true if the given BigInt value is small enough to fit
  270. into an int64 value, else false.
  271. */
  272. const bigIntFits64 = function f(b){
  273. if(!f._max){
  274. f._max = BigInt("0x7fffffffffffffff");
  275. f._min = ~f._max;
  276. }
  277. return b >= f._min && b <= f._max;
  278. };
  279. /**
  280. Returns true if the given BigInt value is small enough to fit
  281. into an int32, else false.
  282. */
  283. const bigIntFits32 = (b)=>(b >= (-0x7fffffffn - 1n) && b <= 0x7fffffffn);
  284. /**
  285. Returns true if the given BigInt value is small enough to fit
  286. into a double value without loss of precision, else false.
  287. */
  288. const bigIntFitsDouble = function f(b){
  289. if(!f._min){
  290. f._min = Number.MIN_SAFE_INTEGER;
  291. f._max = Number.MAX_SAFE_INTEGER;
  292. }
  293. return b >= f._min && b <= f._max;
  294. };
  295. /** Returns v if v appears to be a TypedArray, else false. */
  296. const isTypedArray = (v)=>{
  297. return (v && v.constructor && isInt32(v.constructor.BYTES_PER_ELEMENT)) ? v : false;
  298. };
  299. /** Internal helper to use in operations which need to distinguish
  300. between TypedArrays which are backed by a SharedArrayBuffer
  301. from those which are not. */
  302. const __SAB = ('undefined'===typeof SharedArrayBuffer)
  303. ? function(){} : SharedArrayBuffer;
  304. /** Returns true if the given TypedArray object is backed by a
  305. SharedArrayBuffer, else false. */
  306. const isSharedTypedArray = (aTypedArray)=>(aTypedArray.buffer instanceof __SAB);
  307. /**
  308. Returns either aTypedArray.slice(begin,end) (if
  309. aTypedArray.buffer is a SharedArrayBuffer) or
  310. aTypedArray.subarray(begin,end) (if it's not).
  311. This distinction is important for APIs which don't like to
  312. work on SABs, e.g. TextDecoder, and possibly for our
  313. own APIs which work on memory ranges which "might" be
  314. modified by other threads while they're working.
  315. */
  316. const typedArrayPart = (aTypedArray, begin, end)=>{
  317. return isSharedTypedArray(aTypedArray)
  318. ? aTypedArray.slice(begin, end)
  319. : aTypedArray.subarray(begin, end);
  320. };
  321. /**
  322. Returns true if v appears to be one of our bind()-able TypedArray
  323. types: Uint8Array or Int8Array or ArrayBuffer. Support for
  324. TypedArrays with element sizes >1 is a potential TODO just
  325. waiting on a use case to justify them. Until then, their `buffer`
  326. property can be used to pass them as an ArrayBuffer. If it's not
  327. a bindable array type, a falsy value is returned.
  328. */
  329. const isBindableTypedArray = (v)=>{
  330. return v && (v instanceof Uint8Array
  331. || v instanceof Int8Array
  332. || v instanceof ArrayBuffer);
  333. };
  334. /**
  335. Returns true if v appears to be one of the TypedArray types
  336. which is legal for holding SQL code (as opposed to binary blobs).
  337. Currently this is the same as isBindableTypedArray() but it
  338. seems likely that we'll eventually want to add Uint32Array
  339. and friends to the isBindableTypedArray() list but not to the
  340. isSQLableTypedArray() list.
  341. */
  342. const isSQLableTypedArray = (v)=>{
  343. return v && (v instanceof Uint8Array
  344. || v instanceof Int8Array
  345. || v instanceof ArrayBuffer);
  346. };
  347. /** Returns true if isBindableTypedArray(v) does, else throws with a message
  348. that v is not a supported TypedArray value. */
  349. const affirmBindableTypedArray = (v)=>{
  350. return isBindableTypedArray(v)
  351. || toss3("Value is not of a supported TypedArray type.");
  352. };
  353. const utf8Decoder = new TextDecoder('utf-8');
  354. /**
  355. Uses TextDecoder to decode the given half-open range of the
  356. given TypedArray to a string. This differs from a simple
  357. call to TextDecoder in that it accounts for whether the
  358. first argument is backed by a SharedArrayBuffer or not,
  359. and can work more efficiently if it's not (TextDecoder
  360. refuses to act upon an SAB).
  361. */
  362. const typedArrayToString = function(typedArray, begin, end){
  363. return utf8Decoder.decode(typedArrayPart(typedArray, begin,end));
  364. };
  365. /**
  366. If v is-a Array, its join("") result is returned. If
  367. isSQLableTypedArray(v) is true then typedArrayToString(v) is
  368. returned. If it looks like a WASM pointer, wasm.cstrToJs(v) is
  369. returned. Else v is returned as-is.
  370. */
  371. const flexibleString = function(v){
  372. if(isSQLableTypedArray(v)){
  373. return typedArrayToString(
  374. (v instanceof ArrayBuffer) ? new Uint8Array(v) : v
  375. );
  376. }
  377. else if(Array.isArray(v)) return v.join("");
  378. else if(wasm.isPtr(v)) v = wasm.cstrToJs(v);
  379. return v;
  380. };
  381. /**
  382. An Error subclass specifically for reporting Wasm-level malloc()
  383. failure and enabling clients to unambiguously identify such
  384. exceptions.
  385. */
  386. class WasmAllocError extends Error {
  387. /**
  388. If called with 2 arguments and the 2nd one is an object, it
  389. behaves like the Error constructor, else it concatenates all
  390. arguments together with a single space between each to
  391. construct an error message string. As a special case, if
  392. called with no arguments then it uses a default error
  393. message.
  394. */
  395. constructor(...args){
  396. if(2===args.length && 'object'===typeof args[1]){
  397. super(...args);
  398. }else if(args.length){
  399. super(args.join(' '));
  400. }else{
  401. super("Allocation failed.");
  402. }
  403. this.resultCode = capi.SQLITE_NOMEM;
  404. this.name = 'WasmAllocError';
  405. }
  406. };
  407. /**
  408. Functionally equivalent to the WasmAllocError constructor but may
  409. be used as part of an expression, e.g.:
  410. ```
  411. return someAllocatingFunction(x) || WasmAllocError.toss(...);
  412. ```
  413. */
  414. WasmAllocError.toss = (...args)=>{
  415. throw new WasmAllocError(...args);
  416. };
  417. Object.assign(capi, {
  418. /**
  419. sqlite3_bind_blob() works exactly like its C counterpart unless
  420. its 3rd argument is one of:
  421. - JS string: the 3rd argument is converted to a C string, the
  422. 4th argument is ignored, and the C-string's length is used
  423. in its place.
  424. - Array: converted to a string as defined for "flexible
  425. strings" and then it's treated as a JS string.
  426. - Int8Array or Uint8Array: wasm.allocFromTypedArray() is used to
  427. conver the memory to the WASM heap. If the 4th argument is
  428. 0 or greater, it is used as-is, otherwise the array's byteLength
  429. value is used. This is an exception to the C API's undefined
  430. behavior for a negative 4th argument, but results are undefined
  431. if the given 4th argument value is greater than the byteLength
  432. of the input array.
  433. - If it's an ArrayBuffer, it gets wrapped in a Uint8Array and
  434. treated as that type.
  435. In all of those cases, the final argument (destructor) is
  436. ignored and capi.SQLITE_WASM_DEALLOC is assumed.
  437. A 3rd argument of `null` is treated as if it were a WASM pointer
  438. of 0.
  439. If the 3rd argument is neither a WASM pointer nor one of the
  440. above-described types, capi.SQLITE_MISUSE is returned.
  441. The first argument may be either an `sqlite3_stmt*` WASM
  442. pointer or an sqlite3.oo1.Stmt instance.
  443. For consistency with the C API, it requires the same number of
  444. arguments. It returns capi.SQLITE_MISUSE if passed any other
  445. argument count.
  446. */
  447. sqlite3_bind_blob: undefined/*installed later*/,
  448. /**
  449. sqlite3_bind_text() works exactly like its C counterpart unless
  450. its 3rd argument is one of:
  451. - JS string: the 3rd argument is converted to a C string, the
  452. 4th argument is ignored, and the C-string's length is used
  453. in its place.
  454. - Array: converted to a string as defined for "flexible
  455. strings". The 4th argument is ignored and a value of -1
  456. is assumed.
  457. - Int8Array or Uint8Array: is assumed to contain UTF-8 text, is
  458. converted to a string. The 4th argument is ignored, replaced
  459. by the array's byteLength value.
  460. - If it's an ArrayBuffer, it gets wrapped in a Uint8Array and
  461. treated as that type.
  462. In each of those cases, the final argument (text destructor) is
  463. ignored and capi.SQLITE_WASM_DEALLOC is assumed.
  464. A 3rd argument of `null` is treated as if it were a WASM pointer
  465. of 0.
  466. If the 3rd argument is neither a WASM pointer nor one of the
  467. above-described types, capi.SQLITE_MISUSE is returned.
  468. The first argument may be either an `sqlite3_stmt*` WASM
  469. pointer or an sqlite3.oo1.Stmt instance.
  470. For consistency with the C API, it requires the same number of
  471. arguments. It returns capi.SQLITE_MISUSE if passed any other
  472. argument count.
  473. If client code needs to bind partial strings, it needs to
  474. either parcel the string up before passing it in here or it
  475. must pass in a WASM pointer for the 3rd argument and a valid
  476. 4th-argument value, taking care not to pass a value which
  477. truncates a multi-byte UTF-8 character. When passing
  478. WASM-format strings, it is important that the final argument be
  479. valid or unexpected content can result can result, or even a
  480. crash if the application reads past the WASM heap bounds.
  481. */
  482. sqlite3_bind_text: undefined/*installed later*/,
  483. /**
  484. sqlite3_create_function_v2() differs from its native
  485. counterpart only in the following ways:
  486. 1) The fourth argument (`eTextRep`) argument must not specify
  487. any encoding other than sqlite3.SQLITE_UTF8. The JS API does not
  488. currently support any other encoding and likely never
  489. will. This function does not replace that argument on its own
  490. because it may contain other flags. As a special case, if
  491. the bottom 4 bits of that argument are 0, SQLITE_UTF8 is
  492. assumed.
  493. 2) Any of the four final arguments may be either WASM pointers
  494. (assumed to be function pointers) or JS Functions. In the
  495. latter case, each gets bound to WASM using
  496. sqlite3.capi.wasm.installFunction() and that wrapper is passed
  497. on to the native implementation.
  498. For consistency with the C API, it requires the same number of
  499. arguments. It returns capi.SQLITE_MISUSE if passed any other
  500. argument count.
  501. The semantics of JS functions are:
  502. xFunc: is passed `(pCtx, ...values)`. Its return value becomes
  503. the new SQL function's result.
  504. xStep: is passed `(pCtx, ...values)`. Its return value is
  505. ignored.
  506. xFinal: is passed `(pCtx)`. Its return value becomes the new
  507. aggregate SQL function's result.
  508. xDestroy: is passed `(void*)`. Its return value is ignored. The
  509. pointer passed to it is the one from the 5th argument to
  510. sqlite3_create_function_v2().
  511. Note that:
  512. - `pCtx` in the above descriptions is a `sqlite3_context*`. At
  513. least 99 times out of a hundred, that initial argument will
  514. be irrelevant for JS UDF bindings, but it needs to be there
  515. so that the cases where it _is_ relevant, in particular with
  516. window and aggregate functions, have full access to the
  517. lower-level sqlite3 APIs.
  518. - When wrapping JS functions, the remaining arguments are passd
  519. to them as positional arguments, not as an array of
  520. arguments, because that allows callback definitions to be
  521. more JS-idiomatic than C-like. For example `(pCtx,a,b)=>a+b`
  522. is more intuitive and legible than
  523. `(pCtx,args)=>args[0]+args[1]`. For cases where an array of
  524. arguments would be more convenient, the callbacks simply need
  525. to be declared like `(pCtx,...args)=>{...}`, in which case
  526. `args` will be an array.
  527. - If a JS wrapper throws, it gets translated to
  528. sqlite3_result_error() or sqlite3_result_error_nomem(),
  529. depending on whether the exception is an
  530. sqlite3.WasmAllocError object or not.
  531. - When passing on WASM function pointers, arguments are _not_
  532. converted or reformulated. They are passed on as-is in raw
  533. pointer form using their native C signatures. Only JS
  534. functions passed in to this routine, and thus wrapped by this
  535. routine, get automatic conversions of arguments and result
  536. values. The routines which perform those conversions are
  537. exposed for client-side use as
  538. sqlite3_create_function_v2.convertUdfArgs() and
  539. sqlite3_create_function_v2.setUdfResult(). sqlite3_create_function()
  540. and sqlite3_create_window_function() have those same methods.
  541. For xFunc(), xStep(), and xFinal():
  542. - When called from SQL, arguments to the UDF, and its result,
  543. will be converted between JS and SQL with as much fidelity as
  544. is feasible, triggering an exception if a type conversion
  545. cannot be determined. Some freedom is afforded to numeric
  546. conversions due to friction between the JS and C worlds:
  547. integers which are larger than 32 bits may be treated as
  548. doubles or BigInts.
  549. If any JS-side bound functions throw, those exceptions are
  550. intercepted and converted to database-side errors with the
  551. exception of xDestroy(): any exception from it is ignored,
  552. possibly generating a console.error() message. Destructors
  553. must not throw.
  554. Once installed, there is currently no way to uninstall the
  555. automatically-converted WASM-bound JS functions from WASM. They
  556. can be uninstalled from the database as documented in the C
  557. API, but this wrapper currently has no infrastructure in place
  558. to also free the WASM-bound JS wrappers, effectively resulting
  559. in a memory leak if the client uninstalls the UDF. Improving that
  560. is a potential TODO, but removing client-installed UDFs is rare
  561. in practice. If this factor is relevant for a given client,
  562. they can create WASM-bound JS functions themselves, hold on to their
  563. pointers, and pass the pointers in to here. Later on, they can
  564. free those pointers (using `wasm.uninstallFunction()` or
  565. equivalent).
  566. C reference: https://www.sqlite.org/c3ref/create_function.html
  567. Maintenance reminder: the ability to add new
  568. WASM-accessible functions to the runtime requires that the
  569. WASM build is compiled with emcc's `-sALLOW_TABLE_GROWTH`
  570. flag.
  571. */
  572. sqlite3_create_function_v2: (
  573. pDb, funcName, nArg, eTextRep, pApp,
  574. xFunc, xStep, xFinal, xDestroy
  575. )=>{/*installed later*/},
  576. /**
  577. Equivalent to passing the same arguments to
  578. sqlite3_create_function_v2(), with 0 as the final argument.
  579. */
  580. sqlite3_create_function: (
  581. pDb, funcName, nArg, eTextRep, pApp,
  582. xFunc, xStep, xFinal
  583. )=>{/*installed later*/},
  584. /**
  585. The sqlite3_create_window_function() JS wrapper differs from
  586. its native implementation in the exact same way that
  587. sqlite3_create_function_v2() does. The additional function,
  588. xInverse(), is treated identically to xStep() by the wrapping
  589. layer.
  590. */
  591. sqlite3_create_window_function: (
  592. pDb, funcName, nArg, eTextRep, pApp,
  593. xStep, xFinal, xValue, xInverse, xDestroy
  594. )=>{/*installed later*/},
  595. /**
  596. The sqlite3_prepare_v3() binding handles two different uses
  597. with differing JS/WASM semantics:
  598. 1) sqlite3_prepare_v3(pDb, sqlString, -1, prepFlags, ppStmt , null)
  599. 2) sqlite3_prepare_v3(pDb, sqlPointer, sqlByteLen, prepFlags, ppStmt, sqlPointerToPointer)
  600. Note that the SQL length argument (the 3rd argument) must, for
  601. usage (1), always be negative because it must be a byte length
  602. and that value is expensive to calculate from JS (where only
  603. the character length of strings is readily available). It is
  604. retained in this API's interface for code/documentation
  605. compatibility reasons but is currently _always_ ignored. With
  606. usage (2), the 3rd argument is used as-is but is is still
  607. critical that the C-style input string (2nd argument) be
  608. terminated with a 0 byte.
  609. In usage (1), the 2nd argument must be of type string,
  610. Uint8Array, Int8Array, or ArrayBuffer (all of which are assumed
  611. to hold SQL). If it is, this function assumes case (1) and
  612. calls the underyling C function with the equivalent of:
  613. (pDb, sqlAsString, -1, prepFlags, ppStmt, null)
  614. The `pzTail` argument is ignored in this case because its
  615. result is meaningless when a string-type value is passed
  616. through: the string goes through another level of internal
  617. conversion for WASM's sake and the result pointer would refer
  618. to that transient conversion's memory, not the passed-in
  619. string.
  620. If the sql argument is not a string, it must be a _pointer_ to
  621. a NUL-terminated string which was allocated in the WASM memory
  622. (e.g. using capi.wasm.alloc() or equivalent). In that case,
  623. the final argument may be 0/null/undefined or must be a pointer
  624. to which the "tail" of the compiled SQL is written, as
  625. documented for the C-side sqlite3_prepare_v3(). In case (2),
  626. the underlying C function is called with the equivalent of:
  627. (pDb, sqlAsPointer, sqlByteLen, prepFlags, ppStmt, pzTail)
  628. It returns its result and compiled statement as documented in
  629. the C API. Fetching the output pointers (5th and 6th
  630. parameters) requires using `capi.wasm.peek()` (or
  631. equivalent) and the `pzTail` will point to an address relative to
  632. the `sqlAsPointer` value.
  633. If passed an invalid 2nd argument type, this function will
  634. return SQLITE_MISUSE and sqlite3_errmsg() will contain a string
  635. describing the problem.
  636. Side-note: if given an empty string, or one which contains only
  637. comments or an empty SQL expression, 0 is returned but the result
  638. output pointer will be NULL.
  639. */
  640. sqlite3_prepare_v3: (dbPtr, sql, sqlByteLen, prepFlags,
  641. stmtPtrPtr, strPtrPtr)=>{}/*installed later*/,
  642. /**
  643. Equivalent to calling sqlite3_prapare_v3() with 0 as its 4th argument.
  644. */
  645. sqlite3_prepare_v2: (dbPtr, sql, sqlByteLen,
  646. stmtPtrPtr,strPtrPtr)=>{}/*installed later*/,
  647. /**
  648. This binding enables the callback argument to be a JavaScript.
  649. If the callback is a function, then for the duration of the
  650. sqlite3_exec() call, it installs a WASM-bound function which
  651. acts as a proxy for the given callback. That proxy will also
  652. perform a conversion of the callback's arguments from
  653. `(char**)` to JS arrays of strings. However, for API
  654. consistency's sake it will still honor the C-level callback
  655. parameter order and will call it like:
  656. `callback(pVoid, colCount, listOfValues, listOfColNames)`
  657. If the callback is not a JS function then this binding performs
  658. no translation of the callback, but the sql argument is still
  659. converted to a WASM string for the call using the
  660. "string:flexible" argument converter.
  661. */
  662. sqlite3_exec: (pDb, sql, callback, pVoid, pErrMsg)=>{}/*installed later*/,
  663. /**
  664. If passed a single argument which appears to be a byte-oriented
  665. TypedArray (Int8Array or Uint8Array), this function treats that
  666. TypedArray as an output target, fetches `theArray.byteLength`
  667. bytes of randomness, and populates the whole array with it. As
  668. a special case, if the array's length is 0, this function
  669. behaves as if it were passed (0,0). When called this way, it
  670. returns its argument, else it returns the `undefined` value.
  671. If called with any other arguments, they are passed on as-is
  672. to the C API. Results are undefined if passed any incompatible
  673. values.
  674. */
  675. sqlite3_randomness: (n, outPtr)=>{/*installed later*/},
  676. }/*capi*/);
  677. /**
  678. Various internal-use utilities are added here as needed. They
  679. are bound to an object only so that we have access to them in
  680. the differently-scoped steps of the API bootstrapping
  681. process. At the end of the API setup process, this object gets
  682. removed. These are NOT part of the public API.
  683. */
  684. const util = {
  685. affirmBindableTypedArray, flexibleString,
  686. bigIntFits32, bigIntFits64, bigIntFitsDouble,
  687. isBindableTypedArray,
  688. isInt32, isSQLableTypedArray, isTypedArray,
  689. typedArrayToString,
  690. isUIThread: ()=>(globalThis.window===globalThis && !!globalThis.document),
  691. // is this true for ESM?: 'undefined'===typeof WorkerGlobalScope
  692. isSharedTypedArray,
  693. toss: function(...args){throw new Error(args.join(' '))},
  694. toss3,
  695. typedArrayPart,
  696. /**
  697. Given a byte array or ArrayBuffer, this function throws if the
  698. lead bytes of that buffer do not hold a SQLite3 database header,
  699. else it returns without side effects.
  700. Added in 3.44.
  701. */
  702. affirmDbHeader: function(bytes){
  703. if(bytes instanceof ArrayBuffer) bytes = new Uint8Array(bytes);
  704. const header = "SQLite format 3";
  705. if( header.length > bytes.byteLength ){
  706. toss3("Input does not contain an SQLite3 database header.");
  707. }
  708. for(let i = 0; i < header.length; ++i){
  709. if( header.charCodeAt(i) !== bytes[i] ){
  710. toss3("Input does not contain an SQLite3 database header.");
  711. }
  712. }
  713. },
  714. /**
  715. Given a byte array or ArrayBuffer, this function throws if the
  716. database does not, at a cursory glance, appear to be an SQLite3
  717. database. It only examines the size and header, but further
  718. checks may be added in the future.
  719. Added in 3.44.
  720. */
  721. affirmIsDb: function(bytes){
  722. if(bytes instanceof ArrayBuffer) bytes = new Uint8Array(bytes);
  723. const n = bytes.byteLength;
  724. if(n<512 || n%512!==0) {
  725. toss3("Byte array size",n,"is invalid for an SQLite3 db.");
  726. }
  727. util.affirmDbHeader(bytes);
  728. }
  729. }/*util*/;
  730. Object.assign(wasm, {
  731. /**
  732. Emscripten APIs have a deep-seated assumption that all pointers
  733. are 32 bits. We'll remain optimistic that that won't always be
  734. the case and will use this constant in places where we might
  735. otherwise use a hard-coded 4.
  736. */
  737. ptrSizeof: config.wasmPtrSizeof || 4,
  738. /**
  739. The WASM IR (Intermediate Representation) value for
  740. pointer-type values. It MUST refer to a value type of the
  741. size described by this.ptrSizeof.
  742. */
  743. ptrIR: config.wasmPtrIR || "i32",
  744. /**
  745. True if BigInt support was enabled via (e.g.) the
  746. Emscripten -sWASM_BIGINT flag, else false. When
  747. enabled, certain 64-bit sqlite3 APIs are enabled which
  748. are not otherwise enabled due to JS/WASM int64
  749. impedence mismatches.
  750. */
  751. bigIntEnabled: !!config.bigIntEnabled,
  752. /**
  753. The symbols exported by the WASM environment.
  754. */
  755. exports: config.exports
  756. || toss3("Missing API config.exports (WASM module exports)."),
  757. /**
  758. When Emscripten compiles with `-sIMPORTED_MEMORY`, it
  759. initalizes the heap and imports it into wasm, as opposed to
  760. the other way around. In this case, the memory is not
  761. available via this.exports.memory.
  762. */
  763. memory: config.memory || config.exports['memory']
  764. || toss3("API config object requires a WebAssembly.Memory object",
  765. "in either config.exports.memory (exported)",
  766. "or config.memory (imported)."),
  767. /**
  768. The API's primary point of access to the WASM-side memory
  769. allocator. Works like sqlite3_malloc() but throws a
  770. WasmAllocError if allocation fails. It is important that any
  771. code which might pass through the sqlite3 C API NOT throw and
  772. must instead return SQLITE_NOMEM (or equivalent, depending on
  773. the context).
  774. Very few cases in the sqlite3 JS APIs can result in
  775. client-defined functions propagating exceptions via the C-style
  776. API. Most notably, this applies to WASM-bound JS functions
  777. which are created directly by clients and passed on _as WASM
  778. function pointers_ to functions such as
  779. sqlite3_create_function_v2(). Such bindings created
  780. transparently by this API will automatically use wrappers which
  781. catch exceptions and convert them to appropriate error codes.
  782. For cases where non-throwing allocation is required, use
  783. this.alloc.impl(), which is direct binding of the
  784. underlying C-level allocator.
  785. Design note: this function is not named "malloc" primarily
  786. because Emscripten uses that name and we wanted to avoid any
  787. confusion early on in this code's development, when it still
  788. had close ties to Emscripten's glue code.
  789. */
  790. alloc: undefined/*installed later*/,
  791. /**
  792. Rarely necessary in JS code, this routine works like
  793. sqlite3_realloc(M,N), where M is either NULL or a pointer
  794. obtained from this function or this.alloc() and N is the number
  795. of bytes to reallocate the block to. Returns a pointer to the
  796. reallocated block or 0 if allocation fails.
  797. If M is NULL and N is positive, this behaves like
  798. this.alloc(N). If N is 0, it behaves like this.dealloc().
  799. Results are undefined if N is negative (sqlite3_realloc()
  800. treats that as 0, but if this code is built with a different
  801. allocator it may misbehave with negative values).
  802. Like this.alloc.impl(), this.realloc.impl() is a direct binding
  803. to the underlying realloc() implementation which does not throw
  804. exceptions, instead returning 0 on allocation error.
  805. */
  806. realloc: undefined/*installed later*/,
  807. /**
  808. The API's primary point of access to the WASM-side memory
  809. deallocator. Works like sqlite3_free().
  810. Design note: this function is not named "free" for the same
  811. reason that this.alloc() is not called this.malloc().
  812. */
  813. dealloc: undefined/*installed later*/
  814. /* Many more wasm-related APIs get installed later on. */
  815. }/*wasm*/);
  816. /**
  817. wasm.alloc()'s srcTypedArray.byteLength bytes,
  818. populates them with the values from the source
  819. TypedArray, and returns the pointer to that memory. The
  820. returned pointer must eventually be passed to
  821. wasm.dealloc() to clean it up.
  822. The argument may be a Uint8Array, Int8Array, or ArrayBuffer,
  823. and it throws if passed any other type.
  824. As a special case, to avoid further special cases where
  825. this is used, if srcTypedArray.byteLength is 0, it
  826. allocates a single byte and sets it to the value
  827. 0. Even in such cases, calls must behave as if the
  828. allocated memory has exactly srcTypedArray.byteLength
  829. bytes.
  830. */
  831. wasm.allocFromTypedArray = function(srcTypedArray){
  832. if(srcTypedArray instanceof ArrayBuffer){
  833. srcTypedArray = new Uint8Array(srcTypedArray);
  834. }
  835. affirmBindableTypedArray(srcTypedArray);
  836. const pRet = wasm.alloc(srcTypedArray.byteLength || 1);
  837. wasm.heapForSize(srcTypedArray.constructor).set(
  838. srcTypedArray.byteLength ? srcTypedArray : [0], pRet
  839. );
  840. return pRet;
  841. };
  842. {
  843. // Set up allocators...
  844. const keyAlloc = config.allocExportName,
  845. keyDealloc = config.deallocExportName,
  846. keyRealloc = config.reallocExportName;
  847. for(const key of [keyAlloc, keyDealloc, keyRealloc]){
  848. const f = wasm.exports[key];
  849. if(!(f instanceof Function)) toss3("Missing required exports[",key,"] function.");
  850. }
  851. wasm.alloc = function f(n){
  852. return f.impl(n) || WasmAllocError.toss("Failed to allocate",n," bytes.");
  853. };
  854. wasm.alloc.impl = wasm.exports[keyAlloc];
  855. wasm.realloc = function f(m,n){
  856. const m2 = f.impl(m,n);
  857. return n ? (m2 || WasmAllocError.toss("Failed to reallocate",n," bytes.")) : 0;
  858. };
  859. wasm.realloc.impl = wasm.exports[keyRealloc];
  860. wasm.dealloc = wasm.exports[keyDealloc];
  861. }
  862. /**
  863. Reports info about compile-time options using
  864. sqlite3_compileoption_get() and sqlite3_compileoption_used(). It
  865. has several distinct uses:
  866. If optName is an array then it is expected to be a list of
  867. compilation options and this function returns an object
  868. which maps each such option to true or false, indicating
  869. whether or not the given option was included in this
  870. build. That object is returned.
  871. If optName is an object, its keys are expected to be compilation
  872. options and this function sets each entry to true or false,
  873. indicating whether the compilation option was used or not. That
  874. object is returned.
  875. If passed no arguments then it returns an object mapping
  876. all known compilation options to their compile-time values,
  877. or boolean true if they are defined with no value. This
  878. result, which is relatively expensive to compute, is cached
  879. and returned for future no-argument calls.
  880. In all other cases it returns true if the given option was
  881. active when when compiling the sqlite3 module, else false.
  882. Compile-time option names may optionally include their
  883. "SQLITE_" prefix. When it returns an object of all options,
  884. the prefix is elided.
  885. */
  886. wasm.compileOptionUsed = function f(optName){
  887. if(!arguments.length){
  888. if(f._result) return f._result;
  889. else if(!f._opt){
  890. f._rx = /^([^=]+)=(.+)/;
  891. f._rxInt = /^-?\d+$/;
  892. f._opt = function(opt, rv){
  893. const m = f._rx.exec(opt);
  894. rv[0] = (m ? m[1] : opt);
  895. rv[1] = m ? (f._rxInt.test(m[2]) ? +m[2] : m[2]) : true;
  896. };
  897. }
  898. const rc = {}, ov = [0,0];
  899. let i = 0, k;
  900. while((k = capi.sqlite3_compileoption_get(i++))){
  901. f._opt(k,ov);
  902. rc[ov[0]] = ov[1];
  903. }
  904. return f._result = rc;
  905. }else if(Array.isArray(optName)){
  906. const rc = {};
  907. optName.forEach((v)=>{
  908. rc[v] = capi.sqlite3_compileoption_used(v);
  909. });
  910. return rc;
  911. }else if('object' === typeof optName){
  912. Object.keys(optName).forEach((k)=> {
  913. optName[k] = capi.sqlite3_compileoption_used(k);
  914. });
  915. return optName;
  916. }
  917. return (
  918. 'string'===typeof optName
  919. ) ? !!capi.sqlite3_compileoption_used(optName) : false;
  920. }/*compileOptionUsed()*/;
  921. /**
  922. sqlite3.wasm.pstack (pseudo-stack) holds a special-case
  923. stack-style allocator intended only for use with _small_ data of
  924. not more than (in total) a few kb in size, managed as if it were
  925. stack-based.
  926. It has only a single intended usage:
  927. ```
  928. const stackPos = pstack.pointer;
  929. try{
  930. const ptr = pstack.alloc(8);
  931. // ==> pstack.pointer === ptr
  932. const otherPtr = pstack.alloc(8);
  933. // ==> pstack.pointer === otherPtr
  934. ...
  935. }finally{
  936. pstack.restore(stackPos);
  937. // ==> pstack.pointer === stackPos
  938. }
  939. ```
  940. This allocator is much faster than a general-purpose one but is
  941. limited to usage patterns like the one shown above.
  942. It operates from a static range of memory which lives outside of
  943. space managed by Emscripten's stack-management, so does not
  944. collide with Emscripten-provided stack allocation APIs. The
  945. memory lives in the WASM heap and can be used with routines such
  946. as wasm.poke() and wasm.heap8u().slice().
  947. */
  948. wasm.pstack = Object.assign(Object.create(null),{
  949. /**
  950. Sets the current pstack position to the given pointer. Results
  951. are undefined if the passed-in value did not come from
  952. this.pointer.
  953. */
  954. restore: wasm.exports.sqlite3__wasm_pstack_restore,
  955. /**
  956. Attempts to allocate the given number of bytes from the
  957. pstack. On success, it zeroes out a block of memory of the
  958. given size, adjusts the pstack pointer, and returns a pointer
  959. to the memory. On error, throws a WasmAllocError. The
  960. memory must eventually be released using restore().
  961. If n is a string, it must be a WASM "IR" value in the set
  962. accepted by wasm.sizeofIR(), which is mapped to the size of
  963. that data type. If passed a string not in that set, it throws a
  964. WasmAllocError.
  965. This method always adjusts the given value to be a multiple
  966. of 8 bytes because failing to do so can lead to incorrect
  967. results when reading and writing 64-bit values from/to the WASM
  968. heap. Similarly, the returned address is always 8-byte aligned.
  969. */
  970. alloc: function(n){
  971. if('string'===typeof n && !(n = wasm.sizeofIR(n))){
  972. WasmAllocError.toss("Invalid value for pstack.alloc(",arguments[0],")");
  973. }
  974. return wasm.exports.sqlite3__wasm_pstack_alloc(n)
  975. || WasmAllocError.toss("Could not allocate",n,
  976. "bytes from the pstack.");
  977. },
  978. /**
  979. alloc()'s n chunks, each sz bytes, as a single memory block and
  980. returns the addresses as an array of n element, each holding
  981. the address of one chunk.
  982. sz may optionally be an IR string accepted by wasm.sizeofIR().
  983. Throws a WasmAllocError if allocation fails.
  984. Example:
  985. ```
  986. const [p1, p2, p3] = wasm.pstack.allocChunks(3,4);
  987. ```
  988. */
  989. allocChunks: function(n,sz){
  990. if('string'===typeof sz && !(sz = wasm.sizeofIR(sz))){
  991. WasmAllocError.toss("Invalid size value for allocChunks(",arguments[1],")");
  992. }
  993. const mem = wasm.pstack.alloc(n * sz);
  994. const rc = [];
  995. let i = 0, offset = 0;
  996. for(; i < n; ++i, offset += sz) rc.push(mem + offset);
  997. return rc;
  998. },
  999. /**
  1000. A convenience wrapper for allocChunks() which sizes each chunk
  1001. as either 8 bytes (safePtrSize is truthy) or wasm.ptrSizeof (if
  1002. safePtrSize is falsy).
  1003. How it returns its result differs depending on its first
  1004. argument: if it's 1, it returns a single pointer value. If it's
  1005. more than 1, it returns the same as allocChunks().
  1006. When a returned pointers will refer to a 64-bit value, e.g. a
  1007. double or int64, and that value must be written or fetched,
  1008. e.g. using wasm.poke() or wasm.peek(), it is
  1009. important that the pointer in question be aligned to an 8-byte
  1010. boundary or else it will not be fetched or written properly and
  1011. will corrupt or read neighboring memory.
  1012. However, when all pointers involved point to "small" data, it
  1013. is safe to pass a falsy value to save a tiny bit of memory.
  1014. */
  1015. allocPtr: (n=1,safePtrSize=true)=>{
  1016. return 1===n
  1017. ? wasm.pstack.alloc(safePtrSize ? 8 : wasm.ptrSizeof)
  1018. : wasm.pstack.allocChunks(n, safePtrSize ? 8 : wasm.ptrSizeof);
  1019. },
  1020. /**
  1021. Records the current pstack position, calls the given function,
  1022. passing it the sqlite3 object, then restores the pstack
  1023. regardless of whether the function throws. Returns the result
  1024. of the call or propagates an exception on error.
  1025. Added in 3.44.
  1026. */
  1027. call: function(f){
  1028. const stackPos = wasm.pstack.pointer;
  1029. try{ return f(sqlite3) } finally{
  1030. wasm.pstack.restore(stackPos);
  1031. }
  1032. }
  1033. })/*wasm.pstack*/;
  1034. Object.defineProperties(wasm.pstack, {
  1035. /**
  1036. sqlite3.wasm.pstack.pointer resolves to the current pstack
  1037. position pointer. This value is intended _only_ to be saved
  1038. for passing to restore(). Writing to this memory, without
  1039. first reserving it via wasm.pstack.alloc() and friends, leads
  1040. to undefined results.
  1041. */
  1042. pointer: {
  1043. configurable: false, iterable: true, writeable: false,
  1044. get: wasm.exports.sqlite3__wasm_pstack_ptr
  1045. //Whether or not a setter as an alternative to restore() is
  1046. //clearer or would just lead to confusion is unclear.
  1047. //set: wasm.exports.sqlite3__wasm_pstack_restore
  1048. },
  1049. /**
  1050. sqlite3.wasm.pstack.quota to the total number of bytes
  1051. available in the pstack, including any space which is currently
  1052. allocated. This value is a compile-time constant.
  1053. */
  1054. quota: {
  1055. configurable: false, iterable: true, writeable: false,
  1056. get: wasm.exports.sqlite3__wasm_pstack_quota
  1057. },
  1058. /**
  1059. sqlite3.wasm.pstack.remaining resolves to the amount of space
  1060. remaining in the pstack.
  1061. */
  1062. remaining: {
  1063. configurable: false, iterable: true, writeable: false,
  1064. get: wasm.exports.sqlite3__wasm_pstack_remaining
  1065. }
  1066. })/*wasm.pstack properties*/;
  1067. capi.sqlite3_randomness = (...args)=>{
  1068. if(1===args.length && util.isTypedArray(args[0])
  1069. && 1===args[0].BYTES_PER_ELEMENT){
  1070. const ta = args[0];
  1071. if(0===ta.byteLength){
  1072. wasm.exports.sqlite3_randomness(0,0);
  1073. return ta;
  1074. }
  1075. const stack = wasm.pstack.pointer;
  1076. try {
  1077. let n = ta.byteLength, offset = 0;
  1078. const r = wasm.exports.sqlite3_randomness;
  1079. const heap = wasm.heap8u();
  1080. const nAlloc = n < 512 ? n : 512;
  1081. const ptr = wasm.pstack.alloc(nAlloc);
  1082. do{
  1083. const j = (n>nAlloc ? nAlloc : n);
  1084. r(j, ptr);
  1085. ta.set(typedArrayPart(heap, ptr, ptr+j), offset);
  1086. n -= j;
  1087. offset += j;
  1088. } while(n > 0);
  1089. }catch(e){
  1090. console.error("Highly unexpected (and ignored!) "+
  1091. "exception in sqlite3_randomness():",e);
  1092. }finally{
  1093. wasm.pstack.restore(stack);
  1094. }
  1095. return ta;
  1096. }
  1097. wasm.exports.sqlite3_randomness(...args);
  1098. };
  1099. /** State for sqlite3_wasmfs_opfs_dir(). */
  1100. let __wasmfsOpfsDir = undefined;
  1101. /**
  1102. If the wasm environment has a WASMFS/OPFS-backed persistent
  1103. storage directory, its path is returned by this function. If it
  1104. does not then it returns "" (noting that "" is a falsy value).
  1105. The first time this is called, this function inspects the current
  1106. environment to determine whether persistence support is available
  1107. and, if it is, enables it (if needed). After the first call it
  1108. always returns the cached result.
  1109. If the returned string is not empty, any files stored under the
  1110. given path (recursively) are housed in OPFS storage. If the
  1111. returned string is empty, this particular persistent storage
  1112. option is not available on the client.
  1113. Though the mount point name returned by this function is intended
  1114. to remain stable, clients should not hard-coded it
  1115. anywhere. Always call this function to get the path.
  1116. Note that this function is a no-op in most builds of this
  1117. library, as the WASMFS capability requires a custom
  1118. build.
  1119. */
  1120. capi.sqlite3_wasmfs_opfs_dir = function(){
  1121. if(undefined !== __wasmfsOpfsDir) return __wasmfsOpfsDir;
  1122. // If we have no OPFS, there is no persistent dir
  1123. const pdir = config.wasmfsOpfsDir;
  1124. if(!pdir
  1125. || !globalThis.FileSystemHandle
  1126. || !globalThis.FileSystemDirectoryHandle
  1127. || !globalThis.FileSystemFileHandle){
  1128. return __wasmfsOpfsDir = "";
  1129. }
  1130. try{
  1131. if(pdir && 0===wasm.xCallWrapped(
  1132. 'sqlite3__wasm_init_wasmfs', 'i32', ['string'], pdir
  1133. )){
  1134. return __wasmfsOpfsDir = pdir;
  1135. }else{
  1136. return __wasmfsOpfsDir = "";
  1137. }
  1138. }catch(e){
  1139. // sqlite3__wasm_init_wasmfs() is not available
  1140. return __wasmfsOpfsDir = "";
  1141. }
  1142. };
  1143. /**
  1144. Returns true if sqlite3.capi.sqlite3_wasmfs_opfs_dir() is a
  1145. non-empty string and the given name starts with (that string +
  1146. '/'), else returns false.
  1147. */
  1148. capi.sqlite3_wasmfs_filename_is_persistent = function(name){
  1149. const p = capi.sqlite3_wasmfs_opfs_dir();
  1150. return (p && name) ? name.startsWith(p+'/') : false;
  1151. };
  1152. /**
  1153. Given an `sqlite3*`, an sqlite3_vfs name, and an optional db name
  1154. (defaulting to "main"), returns a truthy value (see below) if
  1155. that db uses that VFS, else returns false. If pDb is falsy then
  1156. the 3rd argument is ignored and this function returns a truthy
  1157. value if the default VFS name matches that of the 2nd
  1158. argument. Results are undefined if pDb is truthy but refers to an
  1159. invalid pointer. The 3rd argument specifies the database name of
  1160. the given database connection to check, defaulting to the main
  1161. db.
  1162. The 2nd and 3rd arguments may either be a JS string or a WASM
  1163. C-string. If the 2nd argument is a NULL WASM pointer, the default
  1164. VFS is assumed. If the 3rd is a NULL WASM pointer, "main" is
  1165. assumed.
  1166. The truthy value it returns is a pointer to the `sqlite3_vfs`
  1167. object.
  1168. To permit safe use of this function from APIs which may be called
  1169. via the C stack (like SQL UDFs), this function does not throw: if
  1170. bad arguments cause a conversion error when passing into
  1171. wasm-space, false is returned.
  1172. */
  1173. capi.sqlite3_js_db_uses_vfs = function(pDb,vfsName,dbName=0){
  1174. try{
  1175. const pK = capi.sqlite3_vfs_find(vfsName);
  1176. if(!pK) return false;
  1177. else if(!pDb){
  1178. return pK===capi.sqlite3_vfs_find(0) ? pK : false;
  1179. }else{
  1180. return pK===capi.sqlite3_js_db_vfs(pDb,dbName) ? pK : false;
  1181. }
  1182. }catch(e){
  1183. /* Ignore - probably bad args to a wasm-bound function. */
  1184. return false;
  1185. }
  1186. };
  1187. /**
  1188. Returns an array of the names of all currently-registered sqlite3
  1189. VFSes.
  1190. */
  1191. capi.sqlite3_js_vfs_list = function(){
  1192. const rc = [];
  1193. let pVfs = capi.sqlite3_vfs_find(0);
  1194. while(pVfs){
  1195. const oVfs = new capi.sqlite3_vfs(pVfs);
  1196. rc.push(wasm.cstrToJs(oVfs.$zName));
  1197. pVfs = oVfs.$pNext;
  1198. oVfs.dispose();
  1199. }
  1200. return rc;
  1201. };
  1202. /**
  1203. A convenience wrapper around sqlite3_serialize() which serializes
  1204. the given `sqlite3*` pointer to a Uint8Array. The first argument
  1205. may be either an `sqlite3*` or an sqlite3.oo1.DB instance.
  1206. On success it returns a Uint8Array. If the schema is empty, an
  1207. empty array is returned.
  1208. `schema` is the schema to serialize. It may be a WASM C-string
  1209. pointer or a JS string. If it is falsy, it defaults to `"main"`.
  1210. On error it throws with a description of the problem.
  1211. */
  1212. capi.sqlite3_js_db_export = function(pDb, schema=0){
  1213. pDb = wasm.xWrap.testConvertArg('sqlite3*', pDb);
  1214. if(!pDb) toss3('Invalid sqlite3* argument.');
  1215. if(!wasm.bigIntEnabled) toss3('BigInt64 support is not enabled.');
  1216. const scope = wasm.scopedAllocPush();
  1217. let pOut;
  1218. try{
  1219. const pSize = wasm.scopedAlloc(8/*i64*/ + wasm.ptrSizeof);
  1220. const ppOut = pSize + 8;
  1221. /**
  1222. Maintenance reminder, since this cost a full hour of grief
  1223. and confusion: if the order of pSize/ppOut are reversed in
  1224. that memory block, fetching the value of pSize after the
  1225. export reads a garbage size because it's not on an 8-byte
  1226. memory boundary!
  1227. */
  1228. const zSchema = schema
  1229. ? (wasm.isPtr(schema) ? schema : wasm.scopedAllocCString(''+schema))
  1230. : 0;
  1231. let rc = wasm.exports.sqlite3__wasm_db_serialize(
  1232. pDb, zSchema, ppOut, pSize, 0
  1233. );
  1234. if(rc){
  1235. toss3("Database serialization failed with code",
  1236. sqlite3.capi.sqlite3_js_rc_str(rc));
  1237. }
  1238. pOut = wasm.peekPtr(ppOut);
  1239. const nOut = wasm.peek(pSize, 'i64');
  1240. rc = nOut
  1241. ? wasm.heap8u().slice(pOut, pOut + Number(nOut))
  1242. : new Uint8Array();
  1243. return rc;
  1244. }finally{
  1245. if(pOut) wasm.exports.sqlite3_free(pOut);
  1246. wasm.scopedAllocPop(scope);
  1247. }
  1248. };
  1249. /**
  1250. Given a `sqlite3*` and a database name (JS string or WASM
  1251. C-string pointer, which may be 0), returns a pointer to the
  1252. sqlite3_vfs responsible for it. If the given db name is null/0,
  1253. or not provided, then "main" is assumed.
  1254. */
  1255. capi.sqlite3_js_db_vfs =
  1256. (dbPointer, dbName=0)=>util.sqlite3__wasm_db_vfs(dbPointer, dbName);
  1257. /**
  1258. A thin wrapper around capi.sqlite3_aggregate_context() which
  1259. behaves the same except that it throws a WasmAllocError if that
  1260. function returns 0. As a special case, if n is falsy it does
  1261. _not_ throw if that function returns 0. That special case is
  1262. intended for use with xFinal() implementations.
  1263. */
  1264. capi.sqlite3_js_aggregate_context = (pCtx, n)=>{
  1265. return capi.sqlite3_aggregate_context(pCtx, n)
  1266. || (n ? WasmAllocError.toss("Cannot allocate",n,
  1267. "bytes for sqlite3_aggregate_context()")
  1268. : 0);
  1269. };
  1270. /**
  1271. If the current environment supports the POSIX file APIs, this routine
  1272. creates (or overwrites) the given file using those APIs. This is
  1273. primarily intended for use in Emscripten-based builds where the POSIX
  1274. APIs are transparently proxied by an in-memory virtual filesystem.
  1275. It may behave diffrently in other environments.
  1276. The first argument must be either a JS string or WASM C-string
  1277. holding the filename. Note that this routine does _not_ create
  1278. intermediary directories if the filename has a directory part.
  1279. The 2nd argument may either a valid WASM memory pointer, an
  1280. ArrayBuffer, or a Uint8Array. The 3rd must be the length, in
  1281. bytes, of the data array to copy. If the 2nd argument is an
  1282. ArrayBuffer or Uint8Array and the 3rd is not a positive integer
  1283. then the 3rd defaults to the array's byteLength value.
  1284. Results are undefined if data is a WASM pointer and dataLen is
  1285. exceeds data's bounds.
  1286. Throws if any arguments are invalid or if creating or writing to
  1287. the file fails.
  1288. Added in 3.43 as an alternative for the deprecated
  1289. sqlite3_js_vfs_create_file().
  1290. */
  1291. capi.sqlite3_js_posix_create_file = function(filename, data, dataLen){
  1292. let pData;
  1293. if(data && wasm.isPtr(data)){
  1294. pData = data;
  1295. }else if(data instanceof ArrayBuffer || data instanceof Uint8Array){
  1296. pData = wasm.allocFromTypedArray(data);
  1297. if(arguments.length<3 || !util.isInt32(dataLen) || dataLen<0){
  1298. dataLen = data.byteLength;
  1299. }
  1300. }else{
  1301. SQLite3Error.toss("Invalid 2nd argument for sqlite3_js_posix_create_file().");
  1302. }
  1303. try{
  1304. if(!util.isInt32(dataLen) || dataLen<0){
  1305. SQLite3Error.toss("Invalid 3rd argument for sqlite3_js_posix_create_file().");
  1306. }
  1307. const rc = util.sqlite3__wasm_posix_create_file(filename, pData, dataLen);
  1308. if(rc) SQLite3Error.toss("Creation of file failed with sqlite3 result code",
  1309. capi.sqlite3_js_rc_str(rc));
  1310. }finally{
  1311. wasm.dealloc(pData);
  1312. }
  1313. };
  1314. /**
  1315. Deprecation warning: this function does not work properly in
  1316. debug builds of sqlite3 because its out-of-scope use of the
  1317. sqlite3_vfs API triggers assertions in the core library. That
  1318. was unfortunately not discovered until 2023-08-11. This function
  1319. is now deprecated and should not be used in new code.
  1320. Alternative options:
  1321. - "unix" VFS and its variants can get equivalent functionality
  1322. with sqlite3_js_posix_create_file().
  1323. - OPFS: use either sqlite3.oo1.OpfsDb.importDb(), for the "opfs"
  1324. VFS, or the importDb() method of the PoolUtil object provided
  1325. by the "opfs-sahpool" OPFS (noting that its VFS name may differ
  1326. depending on client-side configuration). We cannot proxy those
  1327. from here because the former is necessarily asynchronous and
  1328. the latter requires information not available to this function.
  1329. Creates a file using the storage appropriate for the given
  1330. sqlite3_vfs. The first argument may be a VFS name (JS string
  1331. only, NOT a WASM C-string), WASM-managed `sqlite3_vfs*`, or
  1332. a capi.sqlite3_vfs instance. Pass 0 (a NULL pointer) to use the
  1333. default VFS. If passed a string which does not resolve using
  1334. sqlite3_vfs_find(), an exception is thrown. (Note that a WASM
  1335. C-string is not accepted because it is impossible to
  1336. distinguish from a C-level `sqlite3_vfs*`.)
  1337. The second argument, the filename, must be a JS or WASM C-string.
  1338. The 3rd may either be falsy, a valid WASM memory pointer, an
  1339. ArrayBuffer, or a Uint8Array. The 4th must be the length, in
  1340. bytes, of the data array to copy. If the 3rd argument is an
  1341. ArrayBuffer or Uint8Array and the 4th is not a positive integer
  1342. then the 4th defaults to the array's byteLength value.
  1343. If data is falsy then a file is created with dataLen bytes filled
  1344. with uninitialized data (whatever truncate() leaves there). If
  1345. data is not falsy then a file is created or truncated and it is
  1346. filled with the first dataLen bytes of the data source.
  1347. Throws if any arguments are invalid or if creating or writing to
  1348. the file fails.
  1349. Note that most VFSes do _not_ automatically create directory
  1350. parts of filenames, nor do all VFSes have a concept of
  1351. directories. If the given filename is not valid for the given
  1352. VFS, an exception will be thrown. This function exists primarily
  1353. to assist in implementing file-upload capability, with the caveat
  1354. that clients must have some idea of the VFS into which they want
  1355. to upload and that VFS must support the operation.
  1356. VFS-specific notes:
  1357. - "memdb": results are undefined.
  1358. - "kvvfs": will fail with an I/O error due to strict internal
  1359. requirments of that VFS's xTruncate().
  1360. - "unix" and related: will use the WASM build's equivalent of the
  1361. POSIX I/O APIs. This will work so long as neither a specific
  1362. VFS nor the WASM environment imposes requirements which break it.
  1363. - "opfs": uses OPFS storage and creates directory parts of the
  1364. filename. It can only be used to import an SQLite3 database
  1365. file and will fail if given anything else.
  1366. */
  1367. capi.sqlite3_js_vfs_create_file = function(vfs, filename, data, dataLen){
  1368. config.warn("sqlite3_js_vfs_create_file() is deprecated and",
  1369. "should be avoided because it can lead to C-level crashes.",
  1370. "See its documentation for alternative options.");
  1371. let pData;
  1372. if(data){
  1373. if(wasm.isPtr(data)){
  1374. pData = data;
  1375. }else if(data instanceof ArrayBuffer){
  1376. data = new Uint8Array(data);
  1377. }
  1378. if(data instanceof Uint8Array){
  1379. pData = wasm.allocFromTypedArray(data);
  1380. if(arguments.length<4 || !util.isInt32(dataLen) || dataLen<0){
  1381. dataLen = data.byteLength;
  1382. }
  1383. }else{
  1384. SQLite3Error.toss("Invalid 3rd argument type for sqlite3_js_vfs_create_file().");
  1385. }
  1386. }else{
  1387. pData = 0;
  1388. }
  1389. if(!util.isInt32(dataLen) || dataLen<0){
  1390. wasm.dealloc(pData);
  1391. SQLite3Error.toss("Invalid 4th argument for sqlite3_js_vfs_create_file().");
  1392. }
  1393. try{
  1394. const rc = util.sqlite3__wasm_vfs_create_file(vfs, filename, pData, dataLen);
  1395. if(rc) SQLite3Error.toss("Creation of file failed with sqlite3 result code",
  1396. capi.sqlite3_js_rc_str(rc));
  1397. }finally{
  1398. wasm.dealloc(pData);
  1399. }
  1400. };
  1401. /**
  1402. Converts SQL input from a variety of convenient formats
  1403. to plain strings.
  1404. If v is a string, it is returned as-is. If it is-a Array, its
  1405. join("") result is returned. If is is a Uint8Array, Int8Array,
  1406. or ArrayBuffer, it is assumed to hold UTF-8-encoded text and is
  1407. decoded to a string. If it looks like a WASM pointer,
  1408. wasm.cstrToJs(sql) is returned. Else undefined is returned.
  1409. Added in 3.44
  1410. */
  1411. capi.sqlite3_js_sql_to_string = (sql)=>{
  1412. if('string' === typeof sql){
  1413. return sql;
  1414. }
  1415. const x = flexibleString(v);
  1416. return x===v ? undefined : x;
  1417. }
  1418. if( util.isUIThread() ){
  1419. /* Features specific to the main window thread... */
  1420. /**
  1421. Internal helper for sqlite3_js_kvvfs_clear() and friends.
  1422. Its argument should be one of ('local','session',"").
  1423. */
  1424. const __kvvfsInfo = function(which){
  1425. const rc = Object.create(null);
  1426. rc.prefix = 'kvvfs-'+which;
  1427. rc.stores = [];
  1428. if('session'===which || ""===which) rc.stores.push(globalThis.sessionStorage);
  1429. if('local'===which || ""===which) rc.stores.push(globalThis.localStorage);
  1430. return rc;
  1431. };
  1432. /**
  1433. Clears all storage used by the kvvfs DB backend, deleting any
  1434. DB(s) stored there. Its argument must be either 'session',
  1435. 'local', or "". In the first two cases, only sessionStorage
  1436. resp. localStorage is cleared. If it's an empty string (the
  1437. default) then both are cleared. Only storage keys which match
  1438. the pattern used by kvvfs are cleared: any other client-side
  1439. data are retained.
  1440. This function is only available in the main window thread.
  1441. Returns the number of entries cleared.
  1442. */
  1443. capi.sqlite3_js_kvvfs_clear = function(which=""){
  1444. let rc = 0;
  1445. const kvinfo = __kvvfsInfo(which);
  1446. kvinfo.stores.forEach((s)=>{
  1447. const toRm = [] /* keys to remove */;
  1448. let i;
  1449. for( i = 0; i < s.length; ++i ){
  1450. const k = s.key(i);
  1451. if(k.startsWith(kvinfo.prefix)) toRm.push(k);
  1452. }
  1453. toRm.forEach((kk)=>s.removeItem(kk));
  1454. rc += toRm.length;
  1455. });
  1456. return rc;
  1457. };
  1458. /**
  1459. This routine guesses the approximate amount of
  1460. window.localStorage and/or window.sessionStorage in use by the
  1461. kvvfs database backend. Its argument must be one of
  1462. ('session', 'local', ""). In the first two cases, only
  1463. sessionStorage resp. localStorage is counted. If it's an empty
  1464. string (the default) then both are counted. Only storage keys
  1465. which match the pattern used by kvvfs are counted. The returned
  1466. value is the "length" value of every matching key and value,
  1467. noting that JavaScript stores each character in 2 bytes.
  1468. Note that the returned size is not authoritative from the
  1469. perspective of how much data can fit into localStorage and
  1470. sessionStorage, as the precise algorithms for determining
  1471. those limits are unspecified and may include per-entry
  1472. overhead invisible to clients.
  1473. */
  1474. capi.sqlite3_js_kvvfs_size = function(which=""){
  1475. let sz = 0;
  1476. const kvinfo = __kvvfsInfo(which);
  1477. kvinfo.stores.forEach((s)=>{
  1478. let i;
  1479. for(i = 0; i < s.length; ++i){
  1480. const k = s.key(i);
  1481. if(k.startsWith(kvinfo.prefix)){
  1482. sz += k.length;
  1483. sz += s.getItem(k).length;
  1484. }
  1485. }
  1486. });
  1487. return sz * 2 /* because JS uses 2-byte char encoding */;
  1488. };
  1489. }/* main-window-only bits */
  1490. /**
  1491. Wraps all known variants of the C-side variadic
  1492. sqlite3_db_config().
  1493. Full docs: https://sqlite.org/c3ref/db_config.html
  1494. Returns capi.SQLITE_MISUSE if op is not a valid operation ID.
  1495. The variants which take `(int, int*)` arguments treat a
  1496. missing or falsy pointer argument as 0.
  1497. */
  1498. capi.sqlite3_db_config = function(pDb, op, ...args){
  1499. if(!this.s){
  1500. this.s = wasm.xWrap('sqlite3__wasm_db_config_s','int',
  1501. ['sqlite3*', 'int', 'string:static']
  1502. /* MAINDBNAME requires a static string */);
  1503. this.pii = wasm.xWrap('sqlite3__wasm_db_config_pii', 'int',
  1504. ['sqlite3*', 'int', '*','int', 'int']);
  1505. this.ip = wasm.xWrap('sqlite3__wasm_db_config_ip','int',
  1506. ['sqlite3*', 'int', 'int','*']);
  1507. }
  1508. switch(op){
  1509. case capi.SQLITE_DBCONFIG_ENABLE_FKEY:
  1510. case capi.SQLITE_DBCONFIG_ENABLE_TRIGGER:
  1511. case capi.SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER:
  1512. case capi.SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION:
  1513. case capi.SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE:
  1514. case capi.SQLITE_DBCONFIG_ENABLE_QPSG:
  1515. case capi.SQLITE_DBCONFIG_TRIGGER_EQP:
  1516. case capi.SQLITE_DBCONFIG_RESET_DATABASE:
  1517. case capi.SQLITE_DBCONFIG_DEFENSIVE:
  1518. case capi.SQLITE_DBCONFIG_WRITABLE_SCHEMA:
  1519. case capi.SQLITE_DBCONFIG_LEGACY_ALTER_TABLE:
  1520. case capi.SQLITE_DBCONFIG_DQS_DML:
  1521. case capi.SQLITE_DBCONFIG_DQS_DDL:
  1522. case capi.SQLITE_DBCONFIG_ENABLE_VIEW:
  1523. case capi.SQLITE_DBCONFIG_LEGACY_FILE_FORMAT:
  1524. case capi.SQLITE_DBCONFIG_TRUSTED_SCHEMA:
  1525. case capi.SQLITE_DBCONFIG_STMT_SCANSTATUS:
  1526. case capi.SQLITE_DBCONFIG_REVERSE_SCANORDER:
  1527. return this.ip(pDb, op, args[0], args[1] || 0);
  1528. case capi.SQLITE_DBCONFIG_LOOKASIDE:
  1529. return this.pii(pDb, op, args[0], args[1], args[2]);
  1530. case capi.SQLITE_DBCONFIG_MAINDBNAME:
  1531. return this.s(pDb, op, args[0]);
  1532. default:
  1533. return capi.SQLITE_MISUSE;
  1534. }
  1535. }.bind(Object.create(null));
  1536. /**
  1537. Given a (sqlite3_value*), this function attempts to convert it
  1538. to an equivalent JS value with as much fidelity as feasible and
  1539. return it.
  1540. By default it throws if it cannot determine any sensible
  1541. conversion. If passed a falsy second argument, it instead returns
  1542. `undefined` if no suitable conversion is found. Note that there
  1543. is no conversion from SQL to JS which results in the `undefined`
  1544. value, so `undefined` has an unambiguous meaning here. It will
  1545. always throw a WasmAllocError if allocating memory for a
  1546. conversion fails.
  1547. Caveats:
  1548. - It does not support sqlite3_value_to_pointer() conversions
  1549. because those require a type name string which this function
  1550. does not have and cannot sensibly be given at the level of the
  1551. API where this is used (e.g. automatically converting UDF
  1552. arguments). Clients using sqlite3_value_to_pointer(), and its
  1553. related APIs, will need to manage those themselves.
  1554. */
  1555. capi.sqlite3_value_to_js = function(pVal,throwIfCannotConvert=true){
  1556. let arg;
  1557. const valType = capi.sqlite3_value_type(pVal);
  1558. switch(valType){
  1559. case capi.SQLITE_INTEGER:
  1560. if(wasm.bigIntEnabled){
  1561. arg = capi.sqlite3_value_int64(pVal);
  1562. if(util.bigIntFitsDouble(arg)) arg = Number(arg);
  1563. }
  1564. else arg = capi.sqlite3_value_double(pVal)/*yes, double, for larger integers*/;
  1565. break;
  1566. case capi.SQLITE_FLOAT:
  1567. arg = capi.sqlite3_value_double(pVal);
  1568. break;
  1569. case capi.SQLITE_TEXT:
  1570. arg = capi.sqlite3_value_text(pVal);
  1571. break;
  1572. case capi.SQLITE_BLOB:{
  1573. const n = capi.sqlite3_value_bytes(pVal);
  1574. const pBlob = capi.sqlite3_value_blob(pVal);
  1575. if(n && !pBlob) sqlite3.WasmAllocError.toss(
  1576. "Cannot allocate memory for blob argument of",n,"byte(s)"
  1577. );
  1578. arg = n ? wasm.heap8u().slice(pBlob, pBlob + Number(n)) : null;
  1579. break;
  1580. }
  1581. case capi.SQLITE_NULL:
  1582. arg = null; break;
  1583. default:
  1584. if(throwIfCannotConvert){
  1585. toss3(capi.SQLITE_MISMATCH,
  1586. "Unhandled sqlite3_value_type():",valType);
  1587. }
  1588. arg = undefined;
  1589. }
  1590. return arg;
  1591. };
  1592. /**
  1593. Requires a C-style array of `sqlite3_value*` objects and the
  1594. number of entries in that array. Returns a JS array containing
  1595. the results of passing each C array entry to
  1596. sqlite3_value_to_js(). The 3rd argument to this function is
  1597. passed on as the 2nd argument to that one.
  1598. */
  1599. capi.sqlite3_values_to_js = function(argc,pArgv,throwIfCannotConvert=true){
  1600. let i;
  1601. const tgt = [];
  1602. for(i = 0; i < argc; ++i){
  1603. /**
  1604. Curiously: despite ostensibly requiring 8-byte
  1605. alignment, the pArgv array is parcelled into chunks of
  1606. 4 bytes (1 pointer each). The values those point to
  1607. have 8-byte alignment but the individual argv entries
  1608. do not.
  1609. */
  1610. tgt.push(capi.sqlite3_value_to_js(
  1611. wasm.peekPtr(pArgv + (wasm.ptrSizeof * i)),
  1612. throwIfCannotConvert
  1613. ));
  1614. }
  1615. return tgt;
  1616. };
  1617. /**
  1618. Calls either sqlite3_result_error_nomem(), if e is-a
  1619. WasmAllocError, or sqlite3_result_error(). In the latter case,
  1620. the second argument is coerced to a string to create the error
  1621. message.
  1622. The first argument is a (sqlite3_context*). Returns void.
  1623. Does not throw.
  1624. */
  1625. capi.sqlite3_result_error_js = function(pCtx,e){
  1626. if(e instanceof WasmAllocError){
  1627. capi.sqlite3_result_error_nomem(pCtx);
  1628. }else{
  1629. /* Maintenance reminder: ''+e, rather than e.message,
  1630. will prefix e.message with e.name, so it includes
  1631. the exception's type name in the result. */;
  1632. capi.sqlite3_result_error(pCtx, ''+e, -1);
  1633. }
  1634. };
  1635. /**
  1636. This function passes its 2nd argument to one of the
  1637. sqlite3_result_xyz() routines, depending on the type of that
  1638. argument:
  1639. - If (val instanceof Error), this function passes it to
  1640. sqlite3_result_error_js().
  1641. - `null`: `sqlite3_result_null()`
  1642. - `boolean`: `sqlite3_result_int()` with a value of 0 or 1.
  1643. - `number`: `sqlite3_result_int()`, `sqlite3_result_int64()`, or
  1644. `sqlite3_result_double()`, depending on the range of the number
  1645. and whether or not int64 support is enabled.
  1646. - `bigint`: similar to `number` but will trigger an error if the
  1647. value is too big to store in an int64.
  1648. - `string`: `sqlite3_result_text()`
  1649. - Uint8Array or Int8Array or ArrayBuffer: `sqlite3_result_blob()`
  1650. - `undefined`: is a no-op provided to simplify certain use cases.
  1651. Anything else triggers `sqlite3_result_error()` with a
  1652. description of the problem.
  1653. The first argument to this function is a `(sqlite3_context*)`.
  1654. Returns void. Does not throw.
  1655. */
  1656. capi.sqlite3_result_js = function(pCtx,val){
  1657. if(val instanceof Error){
  1658. capi.sqlite3_result_error_js(pCtx, val);
  1659. return;
  1660. }
  1661. try{
  1662. switch(typeof val) {
  1663. case 'undefined':
  1664. /* This is a no-op. This routine originated in the create_function()
  1665. family of APIs and in that context, passing in undefined indicated
  1666. that the caller was responsible for calling sqlite3_result_xxx()
  1667. (if needed). */
  1668. break;
  1669. case 'boolean':
  1670. capi.sqlite3_result_int(pCtx, val ? 1 : 0);
  1671. break;
  1672. case 'bigint':
  1673. if(util.bigIntFits32(val)){
  1674. capi.sqlite3_result_int(pCtx, Number(val));
  1675. }else if(util.bigIntFitsDouble(val)){
  1676. capi.sqlite3_result_double(pCtx, Number(val));
  1677. }else if(wasm.bigIntEnabled){
  1678. if(util.bigIntFits64(val)) capi.sqlite3_result_int64(pCtx, val);
  1679. else toss3("BigInt value",val.toString(),"is too BigInt for int64.");
  1680. }else{
  1681. toss3("BigInt value",val.toString(),"is too BigInt.");
  1682. }
  1683. break;
  1684. case 'number': {
  1685. let f;
  1686. if(util.isInt32(val)){
  1687. f = capi.sqlite3_result_int;
  1688. }else if(wasm.bigIntEnabled
  1689. && Number.isInteger(val)
  1690. && util.bigIntFits64(BigInt(val))){
  1691. f = capi.sqlite3_result_int64;
  1692. }else{
  1693. f = capi.sqlite3_result_double;
  1694. }
  1695. f(pCtx, val);
  1696. break;
  1697. }
  1698. case 'string': {
  1699. const [p, n] = wasm.allocCString(val,true);
  1700. capi.sqlite3_result_text(pCtx, p, n, capi.SQLITE_WASM_DEALLOC);
  1701. break;
  1702. }
  1703. case 'object':
  1704. if(null===val/*yes, typeof null === 'object'*/) {
  1705. capi.sqlite3_result_null(pCtx);
  1706. break;
  1707. }else if(util.isBindableTypedArray(val)){
  1708. const pBlob = wasm.allocFromTypedArray(val);
  1709. capi.sqlite3_result_blob(
  1710. pCtx, pBlob, val.byteLength,
  1711. capi.SQLITE_WASM_DEALLOC
  1712. );
  1713. break;
  1714. }
  1715. // else fall through
  1716. default:
  1717. toss3("Don't not how to handle this UDF result value:",(typeof val), val);
  1718. }
  1719. }catch(e){
  1720. capi.sqlite3_result_error_js(pCtx, e);
  1721. }
  1722. };
  1723. /**
  1724. Returns the result sqlite3_column_value(pStmt,iCol) passed to
  1725. sqlite3_value_to_js(). The 3rd argument of this function is
  1726. ignored by this function except to pass it on as the second
  1727. argument of sqlite3_value_to_js(). If the sqlite3_column_value()
  1728. returns NULL (e.g. because the column index is out of range),
  1729. this function returns `undefined`, regardless of the 3rd
  1730. argument. If the 3rd argument is falsy and conversion fails,
  1731. `undefined` will be returned.
  1732. Note that sqlite3_column_value() returns an "unprotected" value
  1733. object, but in a single-threaded environment (like this one)
  1734. there is no distinction between protected and unprotected values.
  1735. */
  1736. capi.sqlite3_column_js = function(pStmt, iCol, throwIfCannotConvert=true){
  1737. const v = capi.sqlite3_column_value(pStmt, iCol);
  1738. return (0===v) ? undefined : capi.sqlite3_value_to_js(v, throwIfCannotConvert);
  1739. };
  1740. /**
  1741. Internal impl of sqlite3_preupdate_new/old_js() and
  1742. sqlite3changeset_new/old_js().
  1743. */
  1744. const __newOldValue = function(pObj, iCol, impl){
  1745. impl = capi[impl];
  1746. if(!this.ptr) this.ptr = wasm.allocPtr();
  1747. else wasm.pokePtr(this.ptr, 0);
  1748. const rc = impl(pObj, iCol, this.ptr);
  1749. if(rc) return SQLite3Error.toss(rc,arguments[2]+"() failed with code "+rc);
  1750. const pv = wasm.peekPtr(this.ptr);
  1751. return pv ? capi.sqlite3_value_to_js( pv, true ) : undefined;
  1752. }.bind(Object.create(null));
  1753. /**
  1754. A wrapper around sqlite3_preupdate_new() which fetches the
  1755. sqlite3_value at the given index and returns the result of
  1756. passing it to sqlite3_value_to_js(). Throws on error.
  1757. */
  1758. capi.sqlite3_preupdate_new_js =
  1759. (pDb, iCol)=>__newOldValue(pDb, iCol, 'sqlite3_preupdate_new');
  1760. /**
  1761. The sqlite3_preupdate_old() counterpart of
  1762. sqlite3_preupdate_new_js(), with an identical interface.
  1763. */
  1764. capi.sqlite3_preupdate_old_js =
  1765. (pDb, iCol)=>__newOldValue(pDb, iCol, 'sqlite3_preupdate_old');
  1766. /**
  1767. A wrapper around sqlite3changeset_new() which fetches the
  1768. sqlite3_value at the given index and returns the result of
  1769. passing it to sqlite3_value_to_js(). Throws on error.
  1770. If sqlite3changeset_new() succeeds but has no value to report,
  1771. this function returns the undefined value, noting that undefined
  1772. is a valid conversion from an `sqlite3_value`, so is unambiguous.
  1773. */
  1774. capi.sqlite3changeset_new_js =
  1775. (pChangesetIter, iCol) => __newOldValue(pChangesetIter, iCol,
  1776. 'sqlite3changeset_new');
  1777. /**
  1778. The sqlite3changeset_old() counterpart of
  1779. sqlite3changeset_new_js(), with an identical interface.
  1780. */
  1781. capi.sqlite3changeset_old_js =
  1782. (pChangesetIter, iCol)=>__newOldValue(pChangesetIter, iCol,
  1783. 'sqlite3changeset_old');
  1784. /* The remainder of the API will be set up in later steps. */
  1785. const sqlite3 = {
  1786. WasmAllocError: WasmAllocError,
  1787. SQLite3Error: SQLite3Error,
  1788. capi,
  1789. util,
  1790. wasm,
  1791. config,
  1792. /**
  1793. Holds the version info of the sqlite3 source tree from which
  1794. the generated sqlite3-api.js gets built. Note that its version
  1795. may well differ from that reported by sqlite3_libversion(), but
  1796. that should be considered a source file mismatch, as the JS and
  1797. WASM files are intended to be built and distributed together.
  1798. This object is initially a placeholder which gets replaced by a
  1799. build-generated object.
  1800. */
  1801. version: Object.create(null),
  1802. /**
  1803. The library reserves the 'client' property for client-side use
  1804. and promises to never define a property with this name nor to
  1805. ever rely on specific contents of it. It makes no such guarantees
  1806. for other properties.
  1807. */
  1808. client: undefined,
  1809. /**
  1810. This function is not part of the public interface, but a
  1811. piece of internal bootstrapping infrastructure.
  1812. Performs any optional asynchronous library-level initialization
  1813. which might be required. This function returns a Promise which
  1814. resolves to the sqlite3 namespace object. Any error in the
  1815. async init will be fatal to the init as a whole, but init
  1816. routines are themselves welcome to install dummy catch()
  1817. handlers which are not fatal if their failure should be
  1818. considered non-fatal. If called more than once, the second and
  1819. subsequent calls are no-ops which return a pre-resolved
  1820. Promise.
  1821. Ideally this function is called as part of the Promise chain
  1822. which handles the loading and bootstrapping of the API. If not
  1823. then it must be called by client-level code, which must not use
  1824. the library until the returned promise resolves.
  1825. If called multiple times it will return the same promise on
  1826. subsequent calls. The current build setup precludes that
  1827. possibility, so it's only a hypothetical problem if/when this
  1828. function ever needs to be invoked by clients.
  1829. In Emscripten-based builds, this function is called
  1830. automatically and deleted from this object.
  1831. */
  1832. asyncPostInit: async function ff(){
  1833. if(ff.isReady instanceof Promise) return ff.isReady;
  1834. let lia = sqlite3ApiBootstrap.initializersAsync;
  1835. delete sqlite3ApiBootstrap.initializersAsync;
  1836. const postInit = async ()=>{
  1837. if(!sqlite3.__isUnderTest){
  1838. /* Delete references to internal-only APIs which are used by
  1839. some initializers. Retain them when running in test mode
  1840. so that we can add tests for them. */
  1841. delete sqlite3.util;
  1842. /* It's conceivable that we might want to expose
  1843. StructBinder to client-side code, but it's only useful if
  1844. clients build their own sqlite3.wasm which contains their
  1845. own C struct types. */
  1846. delete sqlite3.StructBinder;
  1847. }
  1848. return sqlite3;
  1849. };
  1850. const catcher = (e)=>{
  1851. config.error("an async sqlite3 initializer failed:",e);
  1852. throw e;
  1853. };
  1854. if(!lia || !lia.length){
  1855. return ff.isReady = postInit().catch(catcher);
  1856. }
  1857. lia = lia.map((f)=>{
  1858. return (f instanceof Function) ? async x=>f(sqlite3) : f;
  1859. });
  1860. lia.push(postInit);
  1861. let p = Promise.resolve(sqlite3);
  1862. while(lia.length) p = p.then(lia.shift());
  1863. return ff.isReady = p.catch(catcher);
  1864. },
  1865. /**
  1866. scriptInfo ideally gets injected into this object by the
  1867. infrastructure which assembles the JS/WASM module. It contains
  1868. state which must be collected before sqlite3ApiBootstrap() can
  1869. be declared. It is not necessarily available to any
  1870. sqlite3ApiBootstrap.initializers but "should" be in place (if
  1871. it's added at all) by the time that
  1872. sqlite3ApiBootstrap.initializersAsync is processed.
  1873. This state is not part of the public API, only intended for use
  1874. with the sqlite3 API bootstrapping and wasm-loading process.
  1875. */
  1876. scriptInfo: undefined
  1877. };
  1878. try{
  1879. sqlite3ApiBootstrap.initializers.forEach((f)=>{
  1880. f(sqlite3);
  1881. });
  1882. }catch(e){
  1883. /* If we don't report this here, it can get completely swallowed
  1884. up and disappear into the abyss of Promises and Workers. */
  1885. console.error("sqlite3 bootstrap initializer threw:",e);
  1886. throw e;
  1887. }
  1888. delete sqlite3ApiBootstrap.initializers;
  1889. sqlite3ApiBootstrap.sqlite3 = sqlite3;
  1890. return sqlite3;
  1891. }/*sqlite3ApiBootstrap()*/;
  1892. /**
  1893. globalThis.sqlite3ApiBootstrap.initializers is an internal detail used by
  1894. the various pieces of the sqlite3 API's amalgamation process. It
  1895. must not be modified by client code except when plugging such code
  1896. into the amalgamation process.
  1897. Each component of the amalgamation is expected to append a function
  1898. to this array. When sqlite3ApiBootstrap() is called for the first
  1899. time, each such function will be called (in their appended order)
  1900. and passed the sqlite3 namespace object, into which they can install
  1901. their features (noting that most will also require that certain
  1902. features alread have been installed). At the end of that process,
  1903. this array is deleted.
  1904. Note that the order of insertion into this array is significant for
  1905. some pieces. e.g. sqlite3.capi and sqlite3.wasm cannot be fully
  1906. utilized until the whwasmutil.js part is plugged in via
  1907. sqlite3-api-glue.js.
  1908. */
  1909. globalThis.sqlite3ApiBootstrap.initializers = [];
  1910. /**
  1911. globalThis.sqlite3ApiBootstrap.initializersAsync is an internal detail
  1912. used by the sqlite3 API's amalgamation process. It must not be
  1913. modified by client code except when plugging such code into the
  1914. amalgamation process.
  1915. The counterpart of globalThis.sqlite3ApiBootstrap.initializers,
  1916. specifically for initializers which are asynchronous. All entries in
  1917. this list must be either async functions, non-async functions which
  1918. return a Promise, or a Promise. Each function in the list is called
  1919. with the sqlite3 object as its only argument.
  1920. The resolved value of any Promise is ignored and rejection will kill
  1921. the asyncPostInit() process (at an indeterminate point because all
  1922. of them are run asynchronously in parallel).
  1923. This list is not processed until the client calls
  1924. sqlite3.asyncPostInit(). This means, for example, that intializers
  1925. added to globalThis.sqlite3ApiBootstrap.initializers may push entries to
  1926. this list.
  1927. */
  1928. globalThis.sqlite3ApiBootstrap.initializersAsync = [];
  1929. /**
  1930. Client code may assign sqlite3ApiBootstrap.defaultConfig an
  1931. object-type value before calling sqlite3ApiBootstrap() (without
  1932. arguments) in order to tell that call to use this object as its
  1933. default config value. The intention of this is to provide
  1934. downstream clients with a reasonably flexible approach for plugging in
  1935. an environment-suitable configuration without having to define a new
  1936. global-scope symbol.
  1937. */
  1938. globalThis.sqlite3ApiBootstrap.defaultConfig = Object.create(null);
  1939. /**
  1940. Placeholder: gets installed by the first call to
  1941. globalThis.sqlite3ApiBootstrap(). However, it is recommended that the
  1942. caller of sqlite3ApiBootstrap() capture its return value and delete
  1943. globalThis.sqlite3ApiBootstrap after calling it. It returns the same
  1944. value which will be stored here.
  1945. */
  1946. globalThis.sqlite3ApiBootstrap.sqlite3 = undefined;