sqlite3_js_create_file() now accepts an ArrayBuffer data source. Add test for OPFS-based export/re-import. The (sqlite3*) argument converter now optionally accepts sqlite3.oo1.DB instances.

FossilOrigin-Name: 14a84b67fb17e16a5691ea4bf7f374123ac73a361a5d3d0efca53788d2001e3a
This commit is contained in:
stephan 2022-12-01 15:22:03 +00:00
parent 9ec1a7a7a0
commit 919dbc846a
5 changed files with 74 additions and 27 deletions

View File

@ -68,12 +68,15 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
`sqlite3_vfs*` via capi.sqlite3_vfs.pointer.
*/
const aPtr = wasm.xWrap.argAdapter('*');
wasm.xWrap.argAdapter('sqlite3*', aPtr)
('sqlite3_filename', aPtr)
wasm.xWrap.argAdapter('sqlite3_filename', aPtr)
('sqlite3_stmt*', aPtr)
('sqlite3_context*', aPtr)
('sqlite3_value*', aPtr)
('void*', aPtr)
('sqlite3*', (v)=>{
if(sqlite3.oo1 && v instanceof sqlite3.oo1.DB) v = v.pointer;
return aPtr(v);
})
/**
`sqlite3_vfs*`:

View File

@ -1258,7 +1258,8 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
/**
A convenience wrapper around sqlite3_serialize() which serializes
the given `sqlite3*` pointer to a Uint8Array.
the given `sqlite3*` pointer to a Uint8Array. The first argument
may be either an `sqlite3*` or an sqlite3.oo1.DB instance.
On success it returns a Uint8Array. If the schema is empty, an
empty array is returned.
@ -1269,6 +1270,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
On error it throws with a description of the problem.
*/
capi.sqlite3_js_db_export = function(pDb, schema=0){
pDb = wasm.xWrap.testConvertArg('sqlite3*', pDb);
if(!pDb) toss3('Invalid sqlite3* argument.');
if(!wasm.bigIntEnabled) toss3('BigInt64 support is not enabled.');
const scope = wasm.scopedAllocPush();
@ -1340,11 +1342,11 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
The second argument, the filename, must be a JS or WASM C-string.
The 3rd may either be falsy, a valid WASM memory pointer, or a
Uint8Array. The 4th must be the length, in bytes, of the data
array to copy. If the 3rd argument is a Uint8Array and the 4th is
not a positive integer then the 4th defaults to the array's
byteLength value.
The 3rd may either be falsy, a valid WASM memory pointer, an
ArrayBuffer, or a Uint8Array. The 4th must be the length, in
bytes, of the data array to copy. If the 3rd argument is an
ArrayBuffer or Uint8Array and the 4th is not a positive integer
then the 4th defaults to the array's byteLength value.
If data is falsy then a file is created with dataLen bytes filled
with uninitialized data (whatever truncate() leaves there). If
@ -1364,7 +1366,9 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
VFS-specific notes:
- "memdb" and "kvvfs": results are undefined.
- "memdb": results are undefined.
- "kvvfs": results are undefined.
- "unix" and related: will use the WASM build's equivalent of the
POSIX I/O APIs.
@ -1374,16 +1378,22 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
*/
capi.sqlite3_js_vfs_create_file = function(vfs, filename, data, dataLen){
let pData;
if(!data) pData = 0;
else if(wasm.isPtr(data)){
pData = data;
}else if(data instanceof Uint8Array){
pData = wasm.allocFromTypedArray(data);
if(arguments.length<4 || !util.isInt32(dataLen) || dataLen<0){
dataLen = data.byteLength;
if(data){
if(wasm.isPtr(data)){
pData = data;
}else if(data instanceof ArrayBuffer){
data = new Uint8Array(data);
}
if(data instanceof Uint8Array){
pData = wasm.allocFromTypedArray(data);
if(arguments.length<4 || !util.isInt32(dataLen) || dataLen<0){
dataLen = data.byteLength;
}
}else{
SQLite3Error.toss("Invalid 3rd argument type for sqlite3_js_vfs_create_file().");
}
}else{
SQLite3Error.toss("Invalid 3rd argument type for sqlite3_js_vfs_create_file().");
pData = 0;
}
if(!util.isInt32(dataLen) || dataLen<0){
wasm.dealloc(pData);

View File

@ -1160,7 +1160,8 @@ self.sqlite3InitModule = sqlite3InitModule;
.mustThrowMatching(()=>db.pointer=1, /read-only/)
.assert(0===sqlite3.capi.sqlite3_extended_result_codes(db.pointer,1))
.assert('main'===db.dbName(0))
.assert('string' === typeof db.dbVfsName());
.assert('string' === typeof db.dbVfsName())
.assert(db.pointer === wasm.xWrap.testConvertArg('sqlite3*',db));
// Custom db error message handling via sqlite3_prepare_v2/v3()
let rc = capi.sqlite3_prepare_v3(db.pointer, {/*invalid*/}, -1, 0, null, null);
T.assert(capi.SQLITE_MISUSE === rc)
@ -1782,6 +1783,17 @@ self.sqlite3InitModule = sqlite3InitModule;
db = new JDb(filename);
db.exec('insert into kvvfs(a) values(4),(5),(6)');
T.assert(6 === db.selectValue('select count(*) from kvvfs'));
// Check import/export of db...
if(0){
// does not yet work with kvvfs for unknown reasons...
const exp = capi.sqlite3_js_db_export(db);
db.close();
unlink();
capi.sqlite3_js_vfs_create_file("kvvfs", filename, exp);
db = new JDb(filename);
T.assert(6 === db.selectValue('select count(*) from kvvfs'));
}
}finally{
db.close();
unlink();
@ -1812,12 +1824,31 @@ self.sqlite3InitModule = sqlite3InitModule;
db = new sqlite3.oo1.OpfsDb(filename);
db.exec('insert into p(a) values(4),(5),(6)');
T.assert(6 === db.selectValue('select count(*) from p'));
this.opfsDbExport = capi.sqlite3_js_db_export(db);
T.assert(this.opfsDbExport instanceof Uint8Array)
.assert(this.opfsDbExport.byteLength>0
&& 0===this.opfsDbExport.byteLength % 512);
}finally{
db.close();
unlink();
}
}
}/*OPFS db sanity checks*/)
.t({
name: 'OPFS export/import',
test: async function(sqlite3){
let db;
try {
const exp = this.opfsDbExport;
delete this.opfsDbExport;
capi.sqlite3_js_vfs_create_file("opfs", this.opfsDbFile, exp);
const db = new sqlite3.oo1.OpfsDb(this.opfsDbFile);
T.assert(6 === db.selectValue('select count(*) from p'));
}finally{
if(db) db.close();
}
}
}/*OPFS export/import*/)
.t({
name: 'OPFS utility APIs and sqlite3_js_vfs_create_file()',
test: async function(sqlite3){
@ -1825,6 +1856,9 @@ self.sqlite3InitModule = sqlite3InitModule;
const pVfs = this.opfsVfs;
const unlink = this.opfsUnlink;
T.assert(filename && pVfs && !!unlink);
delete this.opfsDbFile;
delete this.opfsVfs;
delete this.opfsUnlink;
unlink();
// Sanity-test sqlite3_js_vfs_create_file()...
/**************************************************************

View File

@ -1,5 +1,5 @@
C Reformulate\sand\ssimplify\ssome\sJS\stests\srelated\sto\sthe\sprevious\scheckin.
D 2022-12-01T04:45:51.580
C sqlite3_js_create_file()\snow\saccepts\san\sArrayBuffer\sdata\ssource.\sAdd\stest\sfor\sOPFS-based\sexport/re-import.\sThe\s(sqlite3*)\sargument\sconverter\snow\soptionally\saccepts\ssqlite3.oo1.DB\sinstances.
D 2022-12-01T15:22:03.961
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@ -503,9 +503,9 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08
F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62
F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f
F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4
F ext/wasm/api/sqlite3-api-glue.js 5468ba750e081c55ff3c572e3ae47dd415be73907ce40117fb121f37f4d0649e
F ext/wasm/api/sqlite3-api-glue.js b528207ba43f7740d1ade623f3f6b08a49f44ce7e9126915b78e1818c2466d8e
F ext/wasm/api/sqlite3-api-oo1.js 06ad2079368e16cb9f182c18cd37bdc3932536856dff4f60582d0ca5f6c491a8
F ext/wasm/api/sqlite3-api-prologue.js 603d074cf7824ebfe4014a475fe59d88134b03ca75f3e00c42b8ddc8a474d57b
F ext/wasm/api/sqlite3-api-prologue.js f8330a837cf008cae65083c356ebddb6a00054e94a2d2927f2828ad83d3112ce
F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f
F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3
F ext/wasm/api/sqlite3-opfs-async-proxy.js 9963c78bf6e5ccb5ba28e8597851bd9d980e86803b6d341cc985e586aef10c82
@ -555,7 +555,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555
F ext/wasm/test-opfs-vfs.js 44363db07b2a20e73b0eb1808de4400ca71b703af718d0fa6d962f15e73bf2ac
F ext/wasm/tester1-worker.html 5ef353348c37cf2e4fd0b23da562d3275523e036260b510734e9a3239ba8c987
F ext/wasm/tester1.c-pp.html 74aa9b31c75f12490653f814b53c3dd39f40cd3f70d6a53a716f4e8587107399
F ext/wasm/tester1.c-pp.js b6cad0c527efedd373698fccb1c56fe187c008afc08be955616b099588b5505c
F ext/wasm/tester1.c-pp.js 9ae36e9b6055975348d7893f2d89ba7119f54e7e78f3d1c7007522d12c444165
F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70
F ext/wasm/tests/opfs/concurrency/test.js bfc3d7e27b207f0827f12568986b8d516a744529550b449314f5c21c9e9faf4a
F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
@ -2065,8 +2065,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P e1009b16d351b23676ad7bffab0c91b373a92132eb855c9af61991b50cd237ed
R 635926f8422902f122ea2d3b331c7a8f
P 9ea2d3dcf798393a7fd231e199c0e2c6302949fe2a7f2573178fb0e50c78a2f4
R 03a40b38b5a233d1d5761f06f6f34dbb
U stephan
Z ff69e84e8c5af74f8df80a8186f78bea
Z 343e90b1bb6c198c8661d1f234560b23
# Remove this line to create a well-formed Fossil manifest.

View File

@ -1 +1 @@
9ea2d3dcf798393a7fd231e199c0e2c6302949fe2a7f2573178fb0e50c78a2f4
14a84b67fb17e16a5691ea4bf7f374123ac73a361a5d3d0efca53788d2001e3a