当前位置:首页 > 技术分析 > 正文内容

SQL.js 开源:在浏览器中运行 SQLite 数据库

ruisui883周前 (04-07)技术分析17

家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发,您的支持是我不断创作的动力。

1.什么是 sql.js

sql.js is a port of SQLite to Webassembly, by compiling the SQLite C code with Emscripten. It uses a virtual database file stored in memory, and thus doesn't persist the changes made to the database. However, it allows you to import any existing sqlite file, and to export the created database as a JavaScript typed array.

sql.js 是 SQLite 到 WebAssembly 的端口,通过使用 Emscripten 编译 SQLite C 代码。

sql.js 允许开发者创建关系数据库并完全在浏览器中查询,而且使用存储在内存中的虚拟数据库文件,因此不会保留对数据库所做的更改。 但是,其允许开发者导入任何现有的 sqlite 文件,并将创建的数据库导出为 JavaScript 类型数组。

sql.js 可以像任何传统的 JavaScript 库一样使用,因此如果正在使用 JavaScript 构建本机应用程序(例如使用 Electron),或者正在使用 Node.js 则可能更喜欢使用 SQLite 到 JavaScript 的本机绑定 (Native Binding of SQLite to JavaScript)。

本机绑定不仅速度更快,而且还能够直接处理数据库文件,而不必将整个数据库加载到内存中,从而避免内存不足错误并进一步提高性能。

目前 sql.js 在 Github 通过 MIT 协议开源,有超过 12.2k 的star、1k 的fork、项目依赖量6.8k、代码贡献者 50+ ,妥妥的前端优质开源项目。

2.如何使用 sql.js

浏览器中使用

默认情况下,sql.js 使用 wasm,因此除了 javascript 库之外还需要加载 .wasm 文件。 从 npm 安装 sql.js 后,开发者可以在
./node_modules/sql.js/dist/sql-wasm.wasm 中找到此文件,并指示捆绑程序将其添加到静态资产或从 CDN 加载。

然后使用传递给 initSqlJs 的配置对象的 locateFile 属性来指示文件所在的位置。 如果使用 webpack 等构建器,则可以自动执行此操作。

const initSqlJs = require('sql.js');

const SQL = await initSqlJs({
  // 需要异步加载 wasm 二进制文件
  //  在 node 中运行时可以完全省略 locateFile
  locateFile: file => `https://sql.js.org/dist/${file}`
});

// 创建数据库
const db = new SQL.Database();
// 执行包含多个语句的单个 SQL 字符串
let sqlstr = "CREATE TABLE hello (a int, b char); \
INSERT INTO hello VALUES (0, 'hello'); \
INSERT INTO hello VALUES (1, 'world');";
db.run(sqlstr);
// 准备一条 sql 语句
const stmt = db.prepare("SELECT * FROM hello WHERE a=:aval AND b=:bval");

// 将值绑定到参数并获取查询结果
const result = stmt.getAsObject({':aval' : 1, ':bval' : 'world'});
console.log(result);
// 输出值 {a:1, b:'world'}

stmt.bind([0, 'hello']);
stmt.free();
const res = db.exec("SELECT * FROM hello");
/* 输出
[
  {columns:['a','b'], values:[[0,'hello'],[1,'world']]}
]
*/
db.create_aggregate(
  "json_agg",
  {
    init: () => [],
    step: (state, val) => [...state, val],
    finalize: (state) => JSON.stringify(state),
  }
);
db.exec("SELECT json_agg(column1) FROM (VALUES ('hello'), ('world'))");
// -> 输出值 '["hello","world"]'

// 将数据库导出到包含 SQLite 数据库文件的 Uint8Array
const binaryArray = db.export();

Node.js 环境中

sql.js 托管在 npm 上,只需运行 npm install sql.js 即可。或者,开发者可以简单地从下面的下载链接下载 sql-wasm.js 和 sql-wasm.wasm。

在 Node.js 环境中,可以通过下面代码从磁盘读取数据库:

const fs = require('fs');
const initSqlJs = require('sql-wasm.js');
const filebuffer = fs.readFileSync('test.sqlite');

initSqlJs().then(function(SQL){
  // 读取 DB
  const db = new SQL.Database(filebuffer);
});

同时,可以通过下面方法将内容写入磁盘:

const fs = require("fs");
// [...] (create the database)
const data = db.export();
const buffer = Buffer.from(data);
fs.writeFileSync("filename.sqlite", buffer);

同时,如果开发者不想在主应用程序线程中运行 CPU 密集型 SQL 查询,则可以使用更受限制的 WebWorker API。

  const worker = new Worker("/dist/worker.sql-wasm.js");
  worker.onmessage = () => {
    console.log("Database opened");
    worker.onmessage = event => {
      console.log(event.data);
      // 查询结果
    };

    worker.postMessage({
      id: 2,
      action: "exec",
      sql: "SELECT age,name FROM test WHERE id=$id",
      params: {"$id": 1}
    });
  };

  worker.onerror = e => console.log("Worker error:", e);
  worker.postMessage({
    id:1,
    action:"open",
    buffer:buf,
     /* 可选,代表 SQLite 数据库文件的 ArrayBuffer*/
  });

sql.js 还支持与 XMLHttpRequest 一起使用,比如下面的示例:

const xhr = new XMLHttpRequest();
// For example: https://github.com/lerocha/chinook-database/raw/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite
xhr.open('GET', '/path/to/database.sqlite', true);
xhr.responseType = 'arraybuffer';

xhr.onload = e => {
  const uInt8Array = new Uint8Array(xhr.response);
  const db = new SQL.Database(uInt8Array);
  const contents = db.exec("SELECT * FROM my_table");
  // contents is now [{columns:['col1','col2',...], values:[[first row], [second row], ...]}]
};
xhr.send();

更多关于 Sql.js 的知识和用法可以参考文末资料,本文不再过多展开。

参考资料

https://madewithwebassembly.com/showcase/sqlite/

https://github.com/sql-js/sql.js

https://www.youtube.com/watch?app=desktop&v=0DZ472GiVNw

https://blog.logrocket.com/detailed-look-basic-sqljs-features/

扫描二维码推送至手机访问。

版权声明:本文由ruisui88发布,如需转载请注明出处。

本文链接:http://www.ruisui88.com/post/3335.html

标签: readfilesync
分享给朋友:

“SQL.js 开源:在浏览器中运行 SQLite 数据库” 的相关文章

基于Ubuntu的Linux Lite 6.0发行版正式发布

开发者 Jerry Bezencon 今天宣布,基于 Ubuntu 的 Linux Lite 6.0 发行版正式发布。本次更新代号为“Fluorite”,基于 Ubuntu 22.04 LTS (Jammy Jellyfish) 系统,它由长期支持的 Linux 5.15 LTS 内核系列驱动。下载...

总结了Vue3的七种组件通信方式,别再说不会组件通信了

写在前面本篇文章是全部采用的<script setup>这种组合式API写法,相对于选项式来说,组合式API这种写法更加自由,具体可以参考Vue文档对两种方式的描述。本篇文章将介绍如下七种组件通信方式:propsemitv-modelrefsprovide/injecteventBusv...

Git 分支管理策略汇总

最近,团队新入职了一些小伙伴,在开发过程中,他们问我 Git 分支是如何管理的,以及应该怎么提交代码?我大概说了一些规则,但仔细想来,好像也并没有形成一个清晰规范的流程。所以查了一些资料,总结出下面这篇文章,一共包含四种常见的分支管理策略,分享给大家。Git flow在这种模式下,主要维护了两类分支...

HTML5学习笔记三:HTML5语法规则

1.标签要小写2.属性值可加可不加””或”3.可以省略某些标签 html body head tbody4.可以省略某些结束标签 tr td li例:显示效果:5.单标签不用加结束标签img input6.废除的标签font center big7.新添加的标签将在下一HTML5学习笔记中重点阐述。...

HTML5最新版本介绍

HTML5是HTML4.01和XHTML1.0之后超文本标记语言的最新版本,由一群自由思想者设计,最终实现了多媒体支持、交互性、更智能的表单和更好的语义标注。 HTML 5不只是 HTML规范的最新版本,它是用于生成现代 Web内容的一系列相关技术的总称,其中最重要的三个技术是:HTML5核心规范...

《暗黑破坏神 2:重制版》PC 版 2.3 版本发布,支持英伟达 DLSS

IT之家 12 月 3 日消息,暴雪为《暗黑破坏神 2:重制版》PC 版发布了更新 2.3 版本,添加了“离线难度缩放”滑块(玩家可以在单人游戏时增加挑战和奖励的级别)、多项辅助功能和用户界面改进,以及英伟达 DLSS 支持。玩法改进:玩家现在可以在离线游戏的选项菜单中使用“游戏难度等级”,它提供与...