aboutsummaryrefslogtreecommitdiff
path: root/ext/wasm/api/sqlite3-wasm.c
diff options
context:
space:
mode:
authorstephan <stephan@noemail.net>2022-10-01 16:01:41 +0000
committerstephan <stephan@noemail.net>2022-10-01 16:01:41 +0000
commit32781427d7496d713f9f81e70021a7e20f7586b1 (patch)
tree9550ae644a93f857d823d7bd885bd95b31e33033 /ext/wasm/api/sqlite3-wasm.c
parentbe9d203665f470a4603966a34d35cbdc71d0a786 (diff)
downloadsqlite-32781427d7496d713f9f81e70021a7e20f7586b1.tar.gz
sqlite-32781427d7496d713f9f81e70021a7e20f7586b1.zip
Fiddle: fix makefile dependency issue and duplicate inclusion of post-js.js. Reimplement db export using sqlite3_serialize().
FossilOrigin-Name: 29db7de79232c21d19b91bb0fc253114e02e21dd9bf90619453dbe72a4c8bf7f
Diffstat (limited to 'ext/wasm/api/sqlite3-wasm.c')
-rw-r--r--ext/wasm/api/sqlite3-wasm.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/ext/wasm/api/sqlite3-wasm.c b/ext/wasm/api/sqlite3-wasm.c
index da8f5c32e..a66b51a8f 100644
--- a/ext/wasm/api/sqlite3-wasm.c
+++ b/ext/wasm/api/sqlite3-wasm.c
@@ -406,6 +406,7 @@ const char * sqlite3_wasm_enum_json(void){
} _DefGroup;
DefGroup(serialize){
+ DefInt(SQLITE_SERIALIZE_NOCOPY);
DefInt(SQLITE_DESERIALIZE_FREEONCLOSE);
DefInt(SQLITE_DESERIALIZE_READONLY);
DefInt(SQLITE_DESERIALIZE_RESIZEABLE);
@@ -567,6 +568,83 @@ int sqlite3_wasm_vfs_unlink(const char * zName){
return rc;
}
+/*
+** Uses the current database's VFS xRead to stream the db file's
+** contents out to the given callback. The callback gets a single
+** chunk of size n (its 2nd argument) on each call and must return 0
+** on success, non-0 on error. This function returns 0 on success,
+** SQLITE_NOTFOUND if no db is open, or propagates any other non-0
+** code from the callback. Note that this is not thread-friendly: it
+** expects that it will be the only thread reading the db file and
+** takes no measures to ensure that is the case.
+**
+** This implementation appears to work fine, but
+** sqlite3_wasm_db_serialize() is arguably the better way to achieve
+** this.
+*/
+WASM_KEEP
+int sqlite3_wasm_db_export_chunked( sqlite3* pDb,
+ int (*xCallback)(unsigned const char *zOut, int n) ){
+ sqlite3_int64 nSize = 0;
+ sqlite3_int64 nPos = 0;
+ sqlite3_file * pFile = 0;
+ unsigned char buf[1024 * 8];
+ int nBuf = (int)sizeof(buf);
+ int rc = pDb
+ ? sqlite3_file_control(pDb, "main",
+ SQLITE_FCNTL_FILE_POINTER, &pFile)
+ : SQLITE_NOTFOUND;
+ if( rc ) return rc;
+ rc = pFile->pMethods->xFileSize(pFile, &nSize);
+ if( rc ) return rc;
+ if(nSize % nBuf){
+ /* DB size is not an even multiple of the buffer size. Reduce
+ ** buffer size so that we do not unduly inflate the db size
+ ** with zero-padding when exporting. */
+ if(0 == nSize % 4096) nBuf = 4096;
+ else if(0 == nSize % 2048) nBuf = 2048;
+ else if(0 == nSize % 1024) nBuf = 1024;
+ else nBuf = 512;
+ }
+ for( ; 0==rc && nPos<nSize; nPos += nBuf ){
+ rc = pFile->pMethods->xRead(pFile, buf, nBuf, nPos);
+ if(SQLITE_IOERR_SHORT_READ == rc){
+ rc = (nPos + nBuf) < nSize ? rc : 0/*assume EOF*/;
+ }
+ if( 0==rc ) rc = xCallback(buf, nBuf);
+ }
+ return rc;
+}
+
+/*
+** A proxy for sqlite3_serialize() which serializes the "main" schema
+** of pDb, placing the serialized output in pOut and nOut. nOut may be
+** NULL. If pDb or pOut are NULL then SQLITE_MISUSE is returned. If
+** allocation of the serialized copy fails, SQLITE_NOMEM is returned.
+** On success, 0 is returned and `*pOut` will contain a pointer to the
+** memory unless mFlags includes SQLITE_SERIALIZE_NOCOPY and the
+** database has no contiguous memory representation, in which case
+** `*pOut` will be NULL but 0 will be returned.
+**
+** If `*pOut` is not NULL, the caller is responsible for passing it to
+** sqlite3_free() to free it.
+*/
+WASM_KEEP
+int sqlite3_wasm_db_serialize( sqlite3* pDb, unsigned char **pOut, sqlite3_int64 * nOut,
+ unsigned int mFlags ){
+ unsigned char * z;
+ if( !pDb || !pOut ) return SQLITE_MISUSE;
+ if(nOut) *nOut = 0;
+ z = sqlite3_serialize(pDb, "main", nOut, mFlags);
+ if( z || (SQLITE_SERIALIZE_NOCOPY & mFlags) ){
+ *pOut = z;
+ return 0;
+ }else{
+ return SQLITE_NOMEM;
+ }
+}
+
+
#if defined(__EMSCRIPTEN__)
#include <emscripten/console.h>
#if defined(SQLITE_WASM_WASMFS)