From 41e0838cb6e8eb9a7ac9edf2baab80def15c9fb8 Mon Sep 17 00:00:00 2001
From: SheetJS <dev@sheetjs.com>
Date: Sat, 23 Jul 2022 05:06:31 -0400
Subject: [PATCH] sqlite

---
 .../03-demos/10-database.md                   | 118 ++++++++++++++++++
 .../docs/04-getting-started/03-demos/index.md |   1 +
 docz/docs/06-solutions/05-output.md           |  14 +++
 docz/docs/07-csf/07-features/01-formulae.md   |  24 ++++
 docz/docs/08-api/07-write-options.md          |  24 ++++
 docz/docs/09-miscellany/04-testing.md         |   6 +
 docz/docs/09-miscellany/05-contributing.md    |   6 +
 7 files changed, 193 insertions(+)
 create mode 100644 docz/docs/04-getting-started/03-demos/10-database.md

diff --git a/docz/docs/04-getting-started/03-demos/10-database.md b/docz/docs/04-getting-started/03-demos/10-database.md
new file mode 100644
index 0000000..59afa8d
--- /dev/null
+++ b/docz/docs/04-getting-started/03-demos/10-database.md
@@ -0,0 +1,118 @@
+---
+sidebar_position: 9
+title: Databases
+---
+
+import current from '/version.js';
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+## SQLite
+
+Most platforms offer a simple way to query `.sqlite` databases.
+
+The following example shows how to query for each table in an SQLite database,
+query for the data for each table, add each non-empty table to a workbook, and
+export as XLSX.
+
+[The Northwind database is available in SQLite form](https://github.com/jpwhite3/northwind-SQLite3/raw/master/Northwind_large.sqlite.zip).
+Download and expand the zip archive to reveal `Northwind_large.sqlite`
+
+<Tabs>
+  <TabItem value="nodejs" label="NodeJS">
+
+1) Install the dependencies:
+
+```bash
+$ npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz better-sqlite3
+```
+
+2) Save the following to `node.mjs`:
+
+```js title="node.mjs"
+/* Load SQLite3 connector library */
+import Database from "better-sqlite3";
+
+/* Load SheetJS library */
+import * as XLSX from 'xlsx/xlsx.mjs';
+import * as fs from 'fs';
+XLSX.set_fs(fs);
+
+/* Initialize database */
+var db = Database("Northwind_large.sqlite");
+
+/* Create new workbook */
+var wb = XLSX.utils.book_new();
+
+/* Get list of table names */
+var sql = db.prepare("SELECT name FROM sqlite_master WHERE type='table'");
+var result = sql.all();
+
+/* Loop across each name */
+result.forEach(function(row) {
+  /* Get first 100K rows */
+	var aoo = db.prepare("SELECT * FROM '" + row.name + "' LIMIT 100000").all();
+	if(aoo.length > 0) {
+    /* Create Worksheet from the row objects */
+    var ws = XLSX.utils.json_to_sheet(aoo, {dense: true});
+    /* Add to Workbook */
+    XLSX.utils.book_append_sheet(wb, ws, row.name);
+  }
+});
+
+/* Write File */
+XLSX.writeFile(wb, "node.xlsx");
+```
+
+3) Run `node node.mjs` and open `node.xlsx`
+
+  </TabItem>
+  <TabItem value="bun" label="Bun">
+
+1) Install the dependencies:
+
+```bash
+$ npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz
+```
+
+2) Save the following to `bun.mjs`:
+
+```js title="bun.mjs"
+/* Load SQLite3 connector library */
+import { Database } from "bun:sqlite";
+
+/* Load SheetJS library */
+import * as XLSX from 'xlsx/xlsx.mjs';
+import * as fs from 'fs';
+XLSX.set_fs(fs);
+
+/* Initialize database */
+var db = Database.open("Northwind_large.sqlite");
+
+/* Create new workbook */
+var wb = XLSX.utils.book_new();
+
+/* Get list of table names */
+var sql = db.prepare("SELECT name FROM sqlite_master WHERE type='table'");
+var result = sql.all();
+
+/* Loop across each name */
+result.forEach(function(row) {
+  /* Get first 100K rows */
+	var aoo = db.prepare("SELECT * FROM '" + row.name + "' LIMIT 100000").all();
+	if(aoo.length > 0) {
+    /* Create Worksheet from the row objects */
+    var ws = XLSX.utils.json_to_sheet(aoo, {dense: true});
+    /* Add to Workbook */
+    XLSX.utils.book_append_sheet(wb, ws, row.name);
+  }
+});
+
+/* Write File */
+XLSX.writeFile(wb, "bun.xlsx");
+```
+
+3) Run `bun bun.mjs` and open `bun.xlsx`
+
+  </TabItem>
+</Tabs>
\ No newline at end of file
diff --git a/docz/docs/04-getting-started/03-demos/index.md b/docz/docs/04-getting-started/03-demos/index.md
index c4c3909..08aea0f 100644
--- a/docz/docs/04-getting-started/03-demos/index.md
+++ b/docz/docs/04-getting-started/03-demos/index.md
@@ -44,6 +44,7 @@ The demo projects include small runnable examples and short explainers.
 - [`Headless Automation`](./headless)
 - [`Other JavaScript Engines`](https://github.com/SheetJS/SheetJS/tree/master/demos/altjs/)
 - [`"serverless" functions`](https://github.com/SheetJS/SheetJS/tree/master/demos/function/)
+- [`sqlite3`](./database#sqlite)
 - [`Databases and Key/Value Stores`](https://github.com/SheetJS/SheetJS/tree/master/demos/database/)
 - [`Legacy Internet Explorer`](https://github.com/SheetJS/SheetJS/tree/master/demos/oldie/)
 
diff --git a/docz/docs/06-solutions/05-output.md b/docz/docs/06-solutions/05-output.md
index dcb7d7c..a45b35a 100644
--- a/docz/docs/06-solutions/05-output.md
+++ b/docz/docs/06-solutions/05-output.md
@@ -188,6 +188,20 @@ import * as fs from "fs";
 import { writeFile, set_fs } from "xlsx/xlsx.mjs";
 set_fs(fs);
 
+/* output format determined by filename */
+writeFile(workbook, "out.xlsb");
+```
+
+  </TabItem>
+  <TabItem value="bun" label="Bun">
+
+As with Node ESM, `fs` must be loaded manually:
+
+```js
+import * as fs from "fs";
+import { writeFile, set_fs } from "xlsx/xlsx.mjs";
+set_fs(fs);
+
 /* output format determined by filename */
 writeFile(workbook, "out.xlsb");
 ```
diff --git a/docz/docs/07-csf/07-features/01-formulae.md b/docz/docs/07-csf/07-features/01-formulae.md
index 460424e..bf32c68 100644
--- a/docz/docs/07-csf/07-features/01-formulae.md
+++ b/docz/docs/07-csf/07-features/01-formulae.md
@@ -65,6 +65,30 @@ const workbook = XLSX.read(ab, { cellFormula: true });
 
 **`XLSX.readFile`**
 
+```js
+/* using readFile in NodeJS, add `cellFormula` to the second argument */
+const workbook = XLSX.readFile("test.xlsx", { cellFormula: true });
+// -------------------------------------------^^^^^^^^^^^^^^^^^
+```
+
+  </TabItem>
+  <TabItem value="bun" label="Bun">
+
+Typically file data will be available as a `Buffer` from a network request / API
+or stored in the filesystem.  `cellFormula: true` should be added to the second
+options argument to `read` or `readFile`:
+
+**`XLSX.read`**
+
+```js
+/* using read in NodeJS, `cellFormula` is in the second argument */
+const ab = await (await fetch("test.xlsx")).arrayBuffer();
+const workbook = XLSX.read(ab, { cellFormula: true });
+// ------------------------------^^^^^^^^^^^^^^^^^
+```
+
+**`XLSX.readFile`**
+
 ```js
 /* using readFile in NodeJS, add `cellFormula` to the second argument */
 const workbook = XLSX.readFile("test.xlsx", { cellFormula: true });
diff --git a/docz/docs/08-api/07-write-options.md b/docz/docs/08-api/07-write-options.md
index 9ff3570..5ff256f 100644
--- a/docz/docs/08-api/07-write-options.md
+++ b/docz/docs/08-api/07-write-options.md
@@ -105,6 +105,30 @@ var wb = XLSX.utils.book_new(); var ws = XLSX.utils.aoa_to_sheet([
   [true,false,],
 ]); XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
 XLSX.writeFile(wb, "textport.numbers", {numbers: XLSX_ZAHL_PAYLOAD, compression: true});
+```
+
+  </TabItem>
+  <TabItem value="bun" label="Bun">
+
+After installing the package:
+
+<pre><code parentName="pre" {...{"className": "language-bash"}}>{`\
+$ npm install --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
+</code></pre>
+
+The scripts will be available at `xlsx/dist/xlsx.zahl` (CommonJS) and
+`xlsx/dist/xlsx.zahl.mjs` (ESM).
+
+```js
+import * as XLSX from "xlsx";
+import XLSX_ZAHL_PAYLOAD from "xlsx/dist/xlsx.zahl";
+var wb = XLSX.utils.book_new(); var ws = XLSX.utils.aoa_to_sheet([
+  ["SheetJS", "<3","விரிதாள்"],
+  [72,,"Arbeitsblätter"],
+  [,62,"数据"],
+  [true,false,],
+]); XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
+XLSX.writeFile(wb, "textport.numbers", {numbers: XLSX_ZAHL_PAYLOAD, compression: true});
 ```
 
   </TabItem>
diff --git a/docz/docs/09-miscellany/04-testing.md b/docz/docs/09-miscellany/04-testing.md
index 848c6dd..00ecf7a 100644
--- a/docz/docs/09-miscellany/04-testing.md
+++ b/docz/docs/09-miscellany/04-testing.md
@@ -44,6 +44,12 @@ Start a local server and navigate to that directory to run the tests.
 `make ctest` will generate the browser fixtures.  To add more files, edit the
 `tests/fixtures.lst` file and add the paths.
 
+  </TabItem>
+  <TabItem value="bun" label="Bun">
+
+`make test-bun` will run the full Bun test suite and `make test-bun_misc`
+will run the smaller feature-specific tests.
+
   </TabItem>
   <TabItem value="deno" label="Deno">
 
diff --git a/docz/docs/09-miscellany/05-contributing.md b/docz/docs/09-miscellany/05-contributing.md
index ec70267..9ee4992 100644
--- a/docz/docs/09-miscellany/05-contributing.md
+++ b/docz/docs/09-miscellany/05-contributing.md
@@ -132,6 +132,12 @@ make dist
 
 ```bash
 curl -fsSL https://deno.land/install.sh | sh
+```
+
+5) (For Bun testing) Install Bun:
+
+```bash
+curl https://bun.sh/install | bash
 ```
 
   </TabItem>