sql.js:JS专用的内存型数据库[github项目精选0x01]
翻译:疯狂的技术宅
项目链接:https://github.com/kripken/sql.js
对于没有耐心的人,请在这里处尝试 Demo:http://kripken.github.io/sql.js/examples/GUI
sql.js 是 SQLite【http://sqlite.org/about.html】 到 Webassembly 的端口,是用 Emscripten【http://kripken.github.io/emscripten-site/docs/introducing_emscripten/about_emscripten.html】 编译的 SQLite C 代码。它使用存储在内存中的虚拟数据库文件【https://kripken.github.io/emscripten-site/docs/porting/files/file_systems_overview.html】,因此不会保留所做的更改到数据库。但是,它允许你导入任何现有的 sqlite 文件,并将创建的数据库导出为 JavaScript 类型数组【https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Typed_arrays】。
没有 C 绑定或 node-gyp 编译,sql.js 是一个简单的JavaScript 文件,可以像传统的 JavaScript 库一样使用。如果你在 JavaScript 中创建本机应用程序(例如 Electron),或者在 node.js 中工作,那么你可能更喜欢使用 SQLite 与 JavaScript 的本机绑定【https://www.npmjs.com/package/sqlite3】。
SQLite是 Public Domain,sql.js 是 MIT license。
Sql.js 的开发早于 WebAssembly,因此是作为 asm.js【https://en.wikipedia.org/wiki/Asm.js】 项目启动的。现在它仍然保持对 asm.js 的向后兼容。
二进制版本
Sql.js 的最后构建日期:
Emscripten 版本 1.38.30(2019-04-16)发布历史【https://emscripten.org/docs/introducing_emscripten/release_notes.html】
SqlLite 版本:3.28.0(2019-4-16)发布历史【https://www.sqlite.org/changes.html】
文档
完整文档【http://kripken.github.io/sql.js/documentation/#http://kripken.github.io/sql.js/documentation/class/Database.html】 根据源代码生成,可用。
用法
1var initSqlJs = require('sql.js'); 2// or if you are in a browser: 3// var initSqlJs = window.initSqlJs; 4 5initSqlJs().then(SQL => { 6 7 // Create a database 8 var db = new SQL.Database(); 9 // NOTE: You can also use new SQL.Database(data) where 10 // data is an Uint8Array representing an SQLite database file 11 12 // Execute some sql 13 sqlstr = "CREATE TABLE hello (a int, b char);"; 14 sqlstr += "INSERT INTO hello VALUES (0, 'hello');" 15 sqlstr += "INSERT INTO hello VALUES (1, 'world');" 16 db.run(sqlstr); // Run the query without returning anything 17 18 var res = db.exec("SELECT * FROM hello"); 19 /* 20 [ 21 {columns:['a','b'], values:[[0,'hello'],[1,'world']]} 22 ] 23 */ 24 25 // Prepare an sql statement 26 var stmt = db.prepare("SELECT * FROM hello WHERE a=:aval AND b=:bval"); 27 28 // Bind values to the parameters and fetch the results of the query 29 var result = stmt.getAsObject({':aval' : 1, ':bval' : 'world'}); 30 console.log(result); // Will print {a:1, b:'world'} 31 32 // Bind other values 33 stmt.bind([0, 'hello']); 34 while (stmt.step()) console.log(stmt.get()); // Will print [0, 'hello'] 35 36 // You can also use JavaScript functions inside your SQL code 37 // Create the js function you need 38 function add(a, b) {return a+b;} 39 // Specifies the SQL function's name, the number of it's arguments, and the js function to use 40 db.create_function("add_js", add); 41 // Run a query in which the function is used 42 db.run("INSERT INTO hello VALUES (add_js(7, 3), add_js('Hello ', 'world'));"); // Inserts 10 and 'Hello world' 43 44 // free the memory used by the statement 45 stmt.free(); 46 // You can not use your statement anymore once it has been freed. 47 // But not freeing your statements causes memory leaks. You don't want that. 48 49 // Export the database to an Uint8Array containing the SQLite database file 50 var binaryArray = db.export(); 51});
演示
有一些示例可在这里得到【https://kripken.github.io/sql.js/index.html】。功能最全的是 Sqlite 解释器【https://kripken.github.io/sql.js/examples/GUI/index.html】。
例子
测试文件提供了关于 api 使用的最新示例。
在浏览器中
HTML 示例文件:
1<meta charset="utf8" /> 2<html> 3 <script src='/dist/sql-wasm.js'></script> 4 <script> 5 config = { 6 locateFile: filename => `/dist/${filename}` 7 } 8 // The `initSqlJs` function is globally provided by all of the main dist files if loaded in the browser. 9 // We must specify this locateFile function if we are loading a wasm file from anywhere other than the current html page's folder. 10 initSqlJs(config).then(function(SQL){ 11 //Create the database 12 var db = new SQL.Database(); 13 // Run a query without reading the results 14 db.run("CREATE TABLE test (col1, col2);"); 15 // Insert two rows: (1,111) and (2,222) 16 db.run("INSERT INTO test VALUES (?,?), (?,?)", [1,111,2,222]); 17 18 // Prepare a statement 19 var stmt = db.prepare("SELECT * FROM test WHERE col1 BETWEEN $start AND $end"); 20 stmt.getAsObject({$start:1, $end:1}); // {col1:1, col2:111} 21 22 // Bind new values 23 stmt.bind({$start:1, $end:2}); 24 while(stmt.step()) { // 25 var row = stmt.getAsObject(); 26 console.log('Here is a row: ' + JSON.stringify(row)); 27 } 28 }); 29 </script> 30 <body> 31 Output is in Javascript console 32 </body> 33</html>
从用户选择的文件创建数据库
构造函数 SQL.Database 把表示数据库文件的整数数组作为可选参数。
以下代码用 HTML input 作为加载数据库的来源:
1dbFileElm.onchange = () => { 2 var f = dbFileElm.files[0]; 3 var r = new FileReader(); 4 r.onload = function() { 5 var Uints = new Uint8Array(r.result); 6 db = new SQL.Database(Uints); 7 } 8 r.readAsArrayBuffer(f); 9}
参见:http://kripken.github.io/sql.js/examples/GUI/gui.js
从服务器加载数据库
1var xhr = new XMLHttpRequest(); 2// For example: https://github.com/lerocha/chinook-database/raw/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite 3xhr.open('GET', '/path/to/database.sqlite', true); 4xhr.responseType = 'arraybuffer'; 5 6xhr.onload = e => { 7 var uInt8Array = new Uint8Array(this.response); 8 var db = new SQL.Database(uInt8Array); 9 var contents = db.exec("SELECT * FROM my_table"); 10 // contents is now [{columns:['col1','col2',...], values:[[first row], [second row], ...]}] 11}; 12xhr.send();
参见:https://github.com/kripken/sql.js/wiki/Load-a-database-from-the-server
在 node.js 中使用
sql.js 托管在 npm 上【https://www.npmjs.org/package/sql.js】。你只需运行 npm install sql.js 就能安装。
另外,你也可以从下面的下载链接中简单地下载 sql-wasm.js 和 sql-wasm.wasm。
从磁盘读取数据库:
1var fs = require('fs'); 2var initSqlJs = require('sql-wasm.js'); 3var filebuffer = fs.readFileSync('test.sqlite'); 4 5initSqlJs().then(function(SQL){ 6 // Load the db 7 var db = new SQL.Database(filebuffer); 8});
将数据库写入磁盘
你需要将 db.export 的结果转换为 buffer
1var fs = require("fs"); 2// [...] (create the database) 3var data = db.export(); 4var buffer = new Buffer(data); 5fs.writeFileSync("filename.sqlite", buffer);
参见:https://github.com/kripken/sql.js/blob/master/test/test_node_file.js
用作 web worker
如果你不想在程序的主线程中运行 CPU 密集型 SQL 查询,可以使用更有限的 WebWorker API。
你将需要下载 dist/worker.sql-wasm.js【dist/worker.sql-wasm.js】 和 dist/worker.sql-wasm.wasm【dist/worker.sql-wasm.wasm】.。
例:
1<script> 2 var worker = new Worker("/dist/worker.sql-wasm.js"); 3 worker.onmessage = () => { 4 console.log("Database opened"); 5 worker.onmessage = event => { 6 console.log(event.data); // The result of the query 7 }; 8 9 worker.postMessage({ 10 id: 2, 11 action: 'exec', 12 sql: 'SELECT * FROM test' 13 }); 14 }; 15 16 worker.onerror = e => console.log("Worker error: ", e); 17 worker.postMessage({ 18 id:1, 19 action:'open', 20 buffer:buf, /*Optional. An ArrayBuffer representing an SQLite Database file*/ 21 }); 22</script>
有关完整的例子,请参见 examples/GUI/gui.js【examples/GUI/gui.js】 。
Flavors/versions Targets/Downloads
该库包含 Sqlite 的 WebAssembly 和 asm.js 两个版本。(WebAssembly 是较新的,也是首选的编译为 JavaScript 的方法,它已经取代了 asm.js。它会生成更小、更快的代码。)包含 Asm.js 版本是为了兼容性的考虑。
从 0.x 升级到 1.x
sql.js 的 1.0 版必须异步加载,而 asm.js 则可以同步加载。
所以在过去,你应该:
1<script src='js/sql.js'></script> 2<script> 3 var db = new SQL.Database(); 4 //... 5</script>
或者
1var SQL = require('sql.js'); 2var db = new SQL.Database(); 3//...
在版本1.x 中:
1<script src='dist/sql-wasm.js'></script> 2<script> 3 initSqlJs({ locateFile: filename => `/dist/${filename}` }).then(function(SQL){ 4 var db = new SQL.Database(); 5 //... 6 }); 7</script>
或者:
1var initSqlJs = require('sql-wasm.js'); 2initSqlJs().then(function(SQL){ 3 var db = new SQL.Database(); 4 //... 5});
现在,NOTHING 是 SQLite 中的保留字,而以前不是。这可能会导致类似 Error: near "nothing": syntax error 的错误。
下载与使用:
尽管 asm.js 文件是作为单个 Javascript 文件分发的,但 WebAssembly 库却能够最有效地对 .js 加载器和 .wasm 文件进行分发,例如 dist/sql-wasm.js 和 dist/sql-wasm.wasm。.js 文件负责包装与加载 .wasm 文件。
包含在 distributed artifacts 中的sql.js版本
对于每个 relase【https://github.com/kripken/sql.js/releases/】,你都会在 release assets 中找到一个名为 sqljs.zip 的文件。它包含:
-
sql-wasm.js:WebAssembly 版本的Sql.js。适合生产环境。如果选择它,则还需要包含 sql-wasm.wasm。
-
sql-wasm-debug.js:Sql.js 的 WebAssembly 调试版本。更大,打开了断言,这对本地开发很有用。如果使用它,则需要包含 sql-wasm-debug.wasm。
-
sql-asm.js:Sql.js 的 asm.js 旧版本。较慢且更大。出于兼容性的原因提供。
-
sql-asm-memory-growth.js:默认情况下,Asm.js 不允许内存增长,因为它速度较慢且会进行优化。如果你正在使用 sql-asm.js 并看到这个错误:Cannot enlarge memory arrays ,请使用此文件。
-
sql-asm-debug.js:Sql.js 的 Debug asm.js 版本。用它进行本地开发。
- worker.* :以上库的 Web Worker 版本。API 更加有限。有关它的示例,请参见 examples/GUI/gui.js【examples/GUI/gui.js】。
编译
-
安装 EMSDK,这里有详细描述【https://kripken.github.io/emscripten-site/docs/getting_started/downloads.html】
- 运行 npm run rebuild
- (github精选)优秀的web摄像头调用项目webcamjs
- 使用LitePal操作数据库(CRUD增删改查) 项目已上传GitHub
- 利用HTML+WEBSQL(sqlite)完成创建数据库,完成对数据的增删改查(使用原生JS编写)
- 项目队列利用Travis CI 让你的github项目持续构建(Node.js为例)
- IT咨询顾问:一次吐血的项目救火 java或判断优化小技巧 asp.net core Session的测试使用心得 【.NET架构】BIM软件架构02:Web管控平台后台架构 NetCore入门篇:(十一)NetCore项目读取配置文件appsettings.json 使用LINQ生成Where的SQL语句 js_jquery_创建cookie有效期问题_时区问题
- 2013.9.29 数据库SQL:mysql 时间函数在项目中的使用
- 【 js 工具 】如何使用Git上传本地项目到github?(mac版)
- 如何在Vue项目中使用websql数据库
- 利用Travis CI 让你的github项目持续构建(Node.js为例)
- node.js项目中基于mysql利用sequelize-auto对照数据库自动生成相应的models
- web项目中不适用于java.sql.DriverManager描述的JDBC 4.0 Drivers及以后版本连接数据库是不需要用forName()?
- 使用ssm(spring+springmvc+mybatis)框架+maven构建项目不到数据库bean的id的问题:Error creating bean with name 'sqlSe
- GitHub项目精选(持续更新)
- Android stuido在线获取项目SQL数据库
- 从15000个Python开源项目中精选的Top30,Github平均star为3707,赶紧收藏!
- VS2003和VS2005的Web项目访问局域网中的MS SQL Server2000数据库都报这个错误,安装上SP4以后还是不能解决?(已解决)
- GitHub 项目精选
- 同一个web项目,hibernate的mysql和sqlservice的两个不同数据库配置
- 利用Travis CI 让你的github项目持续构建(Node.js为例)
- Node.js爬虫实验项目(二)数据库的建立与储存