此页面收集了实现常见应用程序级功能(例如……)的“食谱”和技巧。
导入和导出数据库
一个常用的功能是上传和下载数据库。
将浏览器内的数据库导出到本地文件系统
只要有一个打开的数据库句柄,下载就非常简单易于实现。获取数据库的原始字节是第一步(也是最简单的一步)
const byteArray = sqlite3.capi.sqlite3_js_db_export(myDb);
然后我们需要更多代码才能将该字节数组导出到浏览器之外。这是一种方法
const blob = new Blob([byteArray.buffer],
{type:"application/x-sqlite3"});
const a = document.createElement('a');
document.body.appendChild(a);
a.href = window.URL.createObjectURL(blob);
a.download = (myDb.filename.split('/').pop() || "my.sqlite3");
a.addEventListener('click',function(){
setTimeout(function(){
console.log("Exported (possibly auto-downloaded) database");
window.URL.revokeObjectURL(a.href);
a.remove();
},500);
});
a.click();
将数据库导入浏览器
预警:这对于 WAL 模式数据库无效。WASM 环境缺少 WASM 所需的共享内存 API,因此 WASM 构建无法读取 WAL 模式数据库。
将数据库导入浏览器比导出更棘手,因为客户端必须能够将数据库存储在某个位置,并且这种存储依赖于sqlite3_vfs
。第一步,获取数据库字节,是相当通用的,下面演示了两种方法。
首先,我们将展示如何将本地数据库文件上传到浏览器。为此,我们需要一个用于获取数据库的 UI 元素
<input type='file' id='load-db'/>
然后我们需要监听事件,这些事件将上传的文件传输到我们的 JS 代码中。忽略诸如加载进度指示器之类的细节,看起来像这样……
const eUploadDb = document.querySelector('#load-db');
eUploadDb.addEventListener('change',function(){
const f = this.files[0];
if(!f) return;
const r = new FileReader();
r.addEventListener('load', function(){
// this.result is an ArrayBuffer with the file's contents
});
r.readAsArrayBuffer(f);
});
类似地,可以使用fetch()
加载数据库,无论是来自本地 Web 服务器还是远程服务器
fetch( '...url to the db...' )
.then(res=>res.arrayBuffer)
.then(function(arrayBuffer){
// the database's bytes are in arrayBuffer
});
加载该 ArrayBuffer 后,我们需要决定如何处理它。我们至少有两个选项。最简单的是,我们可以将其加载到内存数据库中
// assuming arrayBuffer contains the result of the above operation...
const p = sqlite3.wasm.allocFromTypedArray(arrayBuffer);
const db = new sqlite3.oo1.DB();
const rc = sqlite3.capi.sqlite3_deserialize(
db.pointer, 'main', p, arrayBuffer.byteLength, arrayBuffer.byteLength,
sqlite3.capi.SQLITE_DESERIALIZE_FREEONCLOSE
// Optionally:
// | sqlite3.capi.SQLITE_DESERIALIZE_RESIZEABLE
);
db.checkRc(rc);
sqlite3_deserialize()
的最后一个参数在这里很重要,原因在sqlite3_deserialize()
的文档中讨论。
可以将获取的数据库写入浏览器端存储,但具体操作方式取决于 VFS
- 对于“opfs” VFS,请参阅OpfsDb 文档。
- 对于“opfs-sahpool” VFS,请参阅该 VFS 的文档。
- 对于默认 VFS(“unix”及其变体),请参阅
sqlite3_js_posix_create_file()
。 "kvvfs"
VFS 文档演示了如何使用VACUUM INTO
将另一个数据库导入 kvvfs。
替换库的日志记录例程
为了帮助库的支持人员从报告问题的用户那里收集详细信息,它可能会将少量信息记录到 JS 开发人员控制台。可以通过用与console.log()
函数系列兼容的例程替换日志记录例程来使其完全静默。在加载库之前安装它们,请执行以下操作
globalThis.sqlite3ApiConfig = {
// define any or all of these:
warn: ()=>{},
error: ()=>{},
debug: ()=>{},
log: ()=>{}
};
// Then load the library using your preferred approach, then
// delete the temporary config object:
delete globalThis.sqlite3ApiConfig /* automatically done as of 3.46.0 */;
这些例程必须与console.log()
接口兼容,但库不依赖于它们如何实际处理其参数,因此省略它们或将它们发送到备用日志通道都是合法选项。它们不得抛出任何异常,否则库可能会出现故障。
它们也可以在加载库后修改,但它们可能已在库初始化阶段发出输出,例如,如果OPFS不可用,则发出警告,因此这将为时已晚,无法抑制所有可能的输出
sqlite3.config.log =
sqlite3.config.error =
sqlite3.config.warn =
sqlite3.config.debug = ()=>{};
请注意,不需要覆盖所有这些例程。在撰写本文时,库在某些罕见情况下会发出警告,在少数情况下会发出错误,但除了在其自身开发期间外,绝不会发出log()
或debug()
消息。