forked from sheetjs/docs.sheetjs.com
		
	websqlite
This commit is contained in:
		
							parent
							
								
									45d0ed0e13
								
							
						
					
					
						commit
						009d4e0a21
					
				@ -129,7 +129,7 @@ site.use(sheets({
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
 | 
			
		||||
This demo was last tested against `lume v1.17.5` on 2023 June 25.
 | 
			
		||||
This demo was last tested against `lume v1.19.1` on 2023 October 14.
 | 
			
		||||
 | 
			
		||||
This example uses the Nunjucks template format. Lume plugins support additional
 | 
			
		||||
template formats, including Markdown and JSX.
 | 
			
		||||
@ -195,7 +195,7 @@ page will show the contents of the spreadsheet.
 | 
			
		||||
5) While the server is still running, open `_data/pres.xlsx` in a spreadsheet
 | 
			
		||||
editor and add a new row at the bottom of the sheet.
 | 
			
		||||
 | 
			
		||||
The page will refresh and show the new contents.
 | 
			
		||||
After saving the spreadsheet, the page will refresh and show the new contents.
 | 
			
		||||
 | 
			
		||||
### Static Site
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -47,7 +47,7 @@ This demo was tested in the following environments:
 | 
			
		||||
| OS and Version | Arch | RN Platform | Date       |
 | 
			
		||||
|:---------------|:-----|:------------|:-----------|
 | 
			
		||||
| Windows 10     | x64  | `v0.71.25`  | 2023-07-24 |
 | 
			
		||||
| Windows 11     | x64  | `v0.71.11`  | 2023-05-11 |
 | 
			
		||||
| Windows 11     | x64  | `v0.72.12`  | 2023-10-14 |
 | 
			
		||||
| Windows 11     | ARM  | `v0.72.9`   | 2023-09-18 |
 | 
			
		||||
| MacOS 12.6     | x64  | `v0.71.26`  | 2023-07-23 |
 | 
			
		||||
| MacOS 13.5.2   | ARM  | `v0.72.4`   | 2023-09-18 |
 | 
			
		||||
@ -394,16 +394,30 @@ been tested against both application types.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
0) Follow the ["Getting Started" guide](https://microsoft.github.io/react-native-windows/docs/getting-started)
 | 
			
		||||
0) Install the [development dependencies](https://microsoft.github.io/react-native-windows/docs/rnw-dependencies).
 | 
			
		||||
 | 
			
		||||
:::caution pass
 | 
			
		||||
 | 
			
		||||
At the time of testing, NodeJS `v16` was required. A tool like
 | 
			
		||||
In earlier versions of React Native, NodeJS `v16` was required. A tool like
 | 
			
		||||
[`nvm-windows`](https://github.com/coreybutler/nvm-windows/releases) should be
 | 
			
		||||
used to switch the NodeJS version.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
<details><summary><b>Installation Notes</b> (click to show)</summary>
 | 
			
		||||
 | 
			
		||||
When the demo was last tested, a PowerShell script installed dependencies:
 | 
			
		||||
 | 
			
		||||
```powershell
 | 
			
		||||
Set-ExecutionPolicy Unrestricted -Scope Process -Force;
 | 
			
		||||
iex (New-Object System.Net.WebClient).DownloadString('https://aka.ms/rnw-vs2022-deps.ps1');
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
If any step fails to install, open the dependencies page and expand "Manual
 | 
			
		||||
setup instructions" to find instructions for manual installation.
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
 | 
			
		||||
### Project Setup
 | 
			
		||||
 | 
			
		||||
1) Create a new project using React Native `0.72`:
 | 
			
		||||
@ -578,7 +592,7 @@ curl -LO https://docs.sheetjs.com/reactnative/rnw/App.tsx
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
8) Test the app again:
 | 
			
		||||
8) Launch the app again:
 | 
			
		||||
 | 
			
		||||
<Tabs groupId="arch">
 | 
			
		||||
  <TabItem value="x64" label="x64 (64-bit Windows)">
 | 
			
		||||
@ -611,10 +625,10 @@ When this demo was last tested on Windows 11 ARM, the build failed.
 | 
			
		||||
  </TabItem>
 | 
			
		||||
</Tabs>
 | 
			
		||||
 | 
			
		||||
Download <https://sheetjs.com/pres.xlsx>.
 | 
			
		||||
9) Download <https://sheetjs.com/pres.xlsx>.
 | 
			
		||||
 | 
			
		||||
Click "Click here to Open File!" and use the file picker to select `pres.xlsx` .
 | 
			
		||||
The app will refresh and display the data from the file.
 | 
			
		||||
10) In the app, click "Click here to Open File!" and use the file picker to
 | 
			
		||||
select `pres.xlsx` . The app will refresh and display the data from the file.
 | 
			
		||||
 | 
			
		||||
## macOS Demo
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -242,7 +242,7 @@ This demo was last tested in the following deployments:
 | 
			
		||||
| `darwin-x64` | `11.8.172.13` | `0.79.2` | 2023-10-12 |
 | 
			
		||||
| `darwin-arm` | `11.4.183.2`  | `0.71.2` | 2023-05-22 |
 | 
			
		||||
| `win10-x64`  | `11.8.172.13` | `0.79.2` | 2023-10-09 |
 | 
			
		||||
| `win11-x64`  | `11.7.439.6`  | `0.75.1` | 2023-08-31 |
 | 
			
		||||
| `win11-x64`  | `11.8.172.13` | `0.79.2` | 2023-10-14 |
 | 
			
		||||
| `linux-x64`  | `11.8.172.13` | `0.79.2` | 2023-10-11 |
 | 
			
		||||
| `linux-arm`  | `11.7.439.6`  | `0.75.1` | 2023-08-30 |
 | 
			
		||||
 | 
			
		||||
@ -353,6 +353,7 @@ This demo was last tested in the following deployments:
 | 
			
		||||
| `darwin-x64` | `1.37.1` | 2023-10-12 |
 | 
			
		||||
| `darwin-arm` | `1.34.1` | 2023-06-05 |
 | 
			
		||||
| `win10-x64`  | `1.37.1` | 2023-10-09 |
 | 
			
		||||
| `win11-x64`  | `1.37.2` | 2023-10-14 |
 | 
			
		||||
| `win11-arm`  | `1.37.0` | 2023-09-26 |
 | 
			
		||||
| `linux-x64`  | `1.37.1` | 2023-10-11 |
 | 
			
		||||
| `linux-arm`  | `1.36.3` | 2023-08-30 |
 | 
			
		||||
 | 
			
		||||
@ -1,258 +0,0 @@
 | 
			
		||||
---
 | 
			
		||||
title: WebSQL and SQLite
 | 
			
		||||
pagination_prev: demos/desktop/index
 | 
			
		||||
pagination_next: demos/local/index
 | 
			
		||||
sidebar_custom_props:
 | 
			
		||||
  type: web
 | 
			
		||||
  sql: true
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
import current from '/version.js';
 | 
			
		||||
import CodeBlock from '@theme/CodeBlock';
 | 
			
		||||
 | 
			
		||||
WebSQL is a popular SQL-based in-browser database available on Chrome.  In
 | 
			
		||||
practice, it is powered by SQLite, and most simple SQLite-compatible queries
 | 
			
		||||
work as-is in WebSQL.
 | 
			
		||||
 | 
			
		||||
The public demo <https://sheetjs.com/sql> generates a database from workbook.
 | 
			
		||||
 | 
			
		||||
:::caution pass
 | 
			
		||||
 | 
			
		||||
WebSQL is only supported in Chromium-based browsers including Chrome.
 | 
			
		||||
 | 
			
		||||
Safari historically supported WebSQL but Safari 13 dropped support.  Legacy
 | 
			
		||||
browsers including Internet Explorer and Firefox never added support.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
## WebSQL Details
 | 
			
		||||
 | 
			
		||||
Importing data from spreadsheets is straightforward using the `generate_sql`
 | 
			
		||||
helper function from ["Generating Tables"](/docs/demos/data/sql#generating-tables).
 | 
			
		||||
 | 
			
		||||
The Web SQL Database API is callback-based.  The following snippet wraps
 | 
			
		||||
transactions in Promise objects:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const db = openDatabase('sheetql', '1.0', 'SheetJS WebSQL Test', 2097152);
 | 
			
		||||
const stmts = generate_sql(ws, wsname);
 | 
			
		||||
 | 
			
		||||
// NOTE: tx.executeSql and db.transaction use callbacks. This wraps in Promises
 | 
			
		||||
for(var stmt of stmts) await new Promise((res, rej) => {
 | 
			
		||||
  db.transaction(tx =>
 | 
			
		||||
    tx.executeSql(stmt, [],
 | 
			
		||||
      (tx, data) => res(data), // if the query is successful, return the data
 | 
			
		||||
      (tx, err) => rej(err) // if the query fails, reject with the error
 | 
			
		||||
  ));
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The result of a SQL SELECT statement is a `SQLResultSet`.  The `rows` property
 | 
			
		||||
is a `SQLResultSetRowList`.  It is an "array-like" structure that has `length`
 | 
			
		||||
and properties like `0`, `1`, etc.  However, this is not a real Array object!
 | 
			
		||||
 | 
			
		||||
A real Array can be created using `Array.from`:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
db.readTransaction(tx =>
 | 
			
		||||
  tx.executeSQL("SELECT * FROM DatabaseTable", [], (tx, data) => {
 | 
			
		||||
    // data.rows is "array-like", so `Array.from` can make it a real array
 | 
			
		||||
    const aoo = Array.from(data.rows);
 | 
			
		||||
    const ws = XLSX.utils.json_to_sheet(aoo);
 | 
			
		||||
    // ... perform an export here OR wrap in a Promise
 | 
			
		||||
  })
 | 
			
		||||
);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Live Demo
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
 | 
			
		||||
This browser demo was tested in the following environments:
 | 
			
		||||
 | 
			
		||||
| Browser     | Date       |
 | 
			
		||||
|:------------|:-----------|
 | 
			
		||||
| Chrome 117  | 2023-10-11 |
 | 
			
		||||
 | 
			
		||||
Some lesser-used browsers do not support WebSQL:
 | 
			
		||||
 | 
			
		||||
| Browser     | Date       | Support                             |
 | 
			
		||||
|:------------|:-----------|:------------------------------------|
 | 
			
		||||
| Safari 17.0 | 2023-10-11 | Error `Web SQL is deprecated`       |
 | 
			
		||||
| Firefox 118 | 2023-10-11 | Error `openDatabase is not defined` |
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
The following demo generates a database with 5 fixed SQL statements. Queries
 | 
			
		||||
can be changed in the Live Editor.  The WebSQL database can be inspected in the
 | 
			
		||||
"WebSQL" section of the "Application" Tab of Developer Tools:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
```jsx live
 | 
			
		||||
function SheetQL() {
 | 
			
		||||
  const [out, setOut] = React.useState("");
 | 
			
		||||
  const queries = [
 | 
			
		||||
    'DROP TABLE IF EXISTS Presidents',
 | 
			
		||||
    'CREATE TABLE Presidents (Name TEXT, Idx REAL)',
 | 
			
		||||
    'INSERT INTO Presidents  (Name, Idx) VALUES ("Barack Obama", 44)',
 | 
			
		||||
    'INSERT INTO Presidents  (Name, Idx) VALUES ("Donald Trump", 45)',
 | 
			
		||||
    'INSERT INTO Presidents  (Name, Idx) VALUES ("Joseph Biden", 46)'
 | 
			
		||||
  ];
 | 
			
		||||
  const xport = React.useCallback(async() => {
 | 
			
		||||
    /* prep database */
 | 
			
		||||
    const db = openDatabase('sheetql', '1.0', 'SheetJS WebSQL Test', 2097152);
 | 
			
		||||
 | 
			
		||||
    for(var q of queries) await new Promise((res, rej) => {
 | 
			
		||||
      db.transaction((tx) => {
 | 
			
		||||
        tx.executeSql(q, [], (tx, data) => res(data), (tx, err) => rej(err));
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    /* pull data and generate rows */
 | 
			
		||||
    db.readTransaction(tx => {
 | 
			
		||||
      tx.executeSql("SELECT * FROM Presidents", [], (tx, data) => {
 | 
			
		||||
        const aoo = Array.from(data.rows);
 | 
			
		||||
        setOut("QUERY RESULT:\n" + aoo.map(r => JSON.stringify(r)).join("\n") + "\n")
 | 
			
		||||
        const ws = XLSX.utils.json_to_sheet(aoo);
 | 
			
		||||
        const wb = XLSX.utils.book_new();
 | 
			
		||||
        XLSX.utils.book_append_sheet(wb, ws, "Presidents");
 | 
			
		||||
        XLSX.writeFile(wb, "SheetQL.xlsx");
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
  return ( <pre>{out}<button onClick={xport}><b>Fetch!</b></button></pre> );
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Server-Side SQLite
 | 
			
		||||
 | 
			
		||||
Most platforms offer a simple way to query SQLite database files.
 | 
			
		||||
 | 
			
		||||
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 Chinook database is a MIT-licensed sample database. The original source code
 | 
			
		||||
repository `http://chinookdatabase.codeplex.com` is no longer available, so the
 | 
			
		||||
[raw SQL queries are mirrored here](pathname:///sqlite/chinook.sql).
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
 | 
			
		||||
This demo was last tested on 2023 May 28
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
### NodeJS
 | 
			
		||||
 | 
			
		||||
The `better-sqlite3` module provides an API for working with SQLite databases.
 | 
			
		||||
`Statement#all` runs a prepared statement and returns an array of objects:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
import Database from "better-sqlite3";
 | 
			
		||||
import * as XLSX from "xlsx";
 | 
			
		||||
 | 
			
		||||
/* open database */
 | 
			
		||||
var db = Database("chinook.db");
 | 
			
		||||
 | 
			
		||||
/* get data from the `Invoice` table */
 | 
			
		||||
var aoo = db.prepare("SELECT * FROM 'Invoice' LIMIT 100000").all();
 | 
			
		||||
 | 
			
		||||
/* create worksheet from the row objects */
 | 
			
		||||
var ws = XLSX.utils.json_to_sheet(aoo, {dense: true});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
0) Build `chinook.db` from [the SQL statements](pathname:///sqlite/chinook.sql):
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
curl -LO https://docs.sheetjs.com/sqlite/chinook.sql
 | 
			
		||||
sqlite3 chinook.db ".read chinook.sql"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
1) Install the dependencies:
 | 
			
		||||
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz better-sqlite3@8.1.0`}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
 | 
			
		||||
2) Download [`SheetJSQLiteNode.mjs`](pathname:///sqlite/SheetJSQLiteNode.mjs):
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
curl -LO https://docs.sheetjs.com/sqlite/SheetJSQLiteNode.mjs
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
3) Run `node SheetJSQLiteNode.mjs` and open `SheetJSQLiteNode.xlsx`
 | 
			
		||||
 | 
			
		||||
### Bun
 | 
			
		||||
 | 
			
		||||
Bun ships with a built-in high-performance module `bun:sqlite`:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
import { Database } from "bun:sqlite";
 | 
			
		||||
import * as XLSX from "xlsx";
 | 
			
		||||
 | 
			
		||||
/* open database */
 | 
			
		||||
var db = Database.open("chinook.db");
 | 
			
		||||
 | 
			
		||||
/* get data from the `Invoice` table */
 | 
			
		||||
var aoo = db.prepare("SELECT * FROM 'Invoice' LIMIT 100000").all();
 | 
			
		||||
 | 
			
		||||
/* create worksheet from the row objects */
 | 
			
		||||
var ws = XLSX.utils.json_to_sheet(aoo, {dense: true});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
0) Build `chinook.db` from [the SQL statements](pathname:///sqlite/chinook.sql):
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
curl -LO https://docs.sheetjs.com/sqlite/chinook.sql
 | 
			
		||||
sqlite3 chinook.db ".read chinook.sql"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
1) Install the dependencies:
 | 
			
		||||
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
 | 
			
		||||
2) Download [`SheetJSQLiteBun.mjs`](pathname:///sqlite/SheetJSQLiteBun.mjs):
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
curl -LO https://docs.sheetjs.com/sqlite/SheetJSQLiteBun.mjs
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
3) Run `bun run SheetJSQLiteBun.mjs` and open `SheetJSQLiteBun.xlsx`
 | 
			
		||||
 | 
			
		||||
### Deno
 | 
			
		||||
 | 
			
		||||
Deno `sqlite` library returns raw arrays of arrays:
 | 
			
		||||
 | 
			
		||||
<CodeBlock language="ts">{`\
 | 
			
		||||
import { DB } from "https://deno.land/x/sqlite/mod.ts";
 | 
			
		||||
// @deno-types="https://cdn.sheetjs.com/xlsx-${current}/package/types/index.d.ts"
 | 
			
		||||
import * as XLSX from "https://cdn.sheetjs.com/xlsx-${current}/package/xlsx.mjs";
 | 
			
		||||
\n\
 | 
			
		||||
/* open database */
 | 
			
		||||
var db = new DB("chinook.db");
 | 
			
		||||
\n\
 | 
			
		||||
/* get data from the \`Invoice\` table */
 | 
			
		||||
var aoa = db.prepareQuery("SELECT * FROM 'Invoice' LIMIT 100000").all();
 | 
			
		||||
\n\
 | 
			
		||||
/* create worksheet from the row objects */
 | 
			
		||||
var data = [query.columns().map(x => x.name)].concat(aoa);
 | 
			
		||||
var ws = XLSX.utils.aoa_to_sheet(data, {dense: true});`}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
 | 
			
		||||
0) Build `chinook.db` from [the SQL statements](pathname:///sqlite/chinook.sql):
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
curl -LO https://docs.sheetjs.com/sqlite/chinook.sql
 | 
			
		||||
sqlite3 chinook.db ".read chinook.sql"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
1) Download [`SheetJSQLiteDeno.ts`](pathname:///sqlite/SheetJSQLiteDeno.ts):
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
curl -LO https://docs.sheetjs.com/sqlite/SheetJSQLiteDeno.ts
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
2) Run `deno run --allow-read --allow-write SheetJSQLiteDeno.ts` and open `SheetJSQLiteDeno.xlsx`
 | 
			
		||||
							
								
								
									
										314
									
								
								docz/docs/03-demos/07-data/11-sqlite.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										314
									
								
								docz/docs/03-demos/07-data/11-sqlite.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,314 @@
 | 
			
		||||
---
 | 
			
		||||
title: Sheets with SQLite
 | 
			
		||||
sidebar_label: SQLite
 | 
			
		||||
pagination_prev: demos/desktop/index
 | 
			
		||||
pagination_next: demos/local/index
 | 
			
		||||
sidebar_custom_props:
 | 
			
		||||
  sql: true
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
<head>
 | 
			
		||||
  <script src="https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.8.0/sql-wasm.js"></script>
 | 
			
		||||
</head>
 | 
			
		||||
 | 
			
		||||
import current from '/version.js';
 | 
			
		||||
import CodeBlock from '@theme/CodeBlock';
 | 
			
		||||
 | 
			
		||||
[SQLite](https://sqlite.org/) is a lightweight embeddable SQL database engine.
 | 
			
		||||
There are connector libraries for many popular JavaScript server-side platforms.
 | 
			
		||||
 | 
			
		||||
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
 | 
			
		||||
data from spreadsheets.
 | 
			
		||||
 | 
			
		||||
This demo uses SQLite and SheetJS to exchange data between spreadsheets and SQL
 | 
			
		||||
servers. We'll explore how to use save tables from a database to spreadsheets
 | 
			
		||||
and how to add data from spreadsheets into a database.
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
 | 
			
		||||
This demo was last tested on 2023 October 13
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
:::info pass
 | 
			
		||||
 | 
			
		||||
This demo covers SQLite `.db` file processing.
 | 
			
		||||
 | 
			
		||||
The [WebSQL demo](/docs/demos/local/websql) covers the Web SQL Database API, a
 | 
			
		||||
SQLite-compatible database built into Chromium and Google Chrome.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
## Demo
 | 
			
		||||
 | 
			
		||||
The following examples show 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.
 | 
			
		||||
 | 
			
		||||
#### Sample Database
 | 
			
		||||
 | 
			
		||||
The Chinook database is a MIT-licensed sample database. The original source code
 | 
			
		||||
repository `http://chinookdatabase.codeplex.com` is no longer available, so the
 | 
			
		||||
[raw SQL queries are mirrored here](pathname:///sqlite/chinook.sql).
 | 
			
		||||
 | 
			
		||||
### Exporting Data
 | 
			
		||||
 | 
			
		||||
Connector libraries typically provide a way to generate an array of objects from
 | 
			
		||||
the result of a `SELECT` query. For example, using `better-sqlite3` in NodeJS:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
import Database from "better-sqlite3";
 | 
			
		||||
 | 
			
		||||
/* open database */
 | 
			
		||||
var db = Database("chinook.db");
 | 
			
		||||
 | 
			
		||||
/* get data from the `Invoice` table */
 | 
			
		||||
var aoo = db.prepare("SELECT * FROM 'Invoice' LIMIT 100000").all();
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The SheetJS `json_to_sheet` method[^1] can take the result and generate a
 | 
			
		||||
worksheet object[^2]. The `book_new` and `book_append_sheet` methods[^3] help
 | 
			
		||||
build a workbook object[^4]. The `writeFile` method[^5] generates a file:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
import * as XLSX from "xlsx";
 | 
			
		||||
 | 
			
		||||
/* 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, "Sheet1");
 | 
			
		||||
 | 
			
		||||
/* Write File */
 | 
			
		||||
XLSX.writeFile(wb, "SheetJSQLiteNode.xlsx");
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Importing Data
 | 
			
		||||
 | 
			
		||||
The ["Generating Tables"](/docs/demos/data/sql#generating-tables) section
 | 
			
		||||
includes a code snippet for generating SQLite-compatible SQL queries from a
 | 
			
		||||
SheetJS worksheet object. Each query can be run sequentially.
 | 
			
		||||
 | 
			
		||||
## Browser
 | 
			
		||||
 | 
			
		||||
`sql.js`[^6] is a compiled version of SQLite into WebAssembly, making it usable
 | 
			
		||||
in web browsers.
 | 
			
		||||
 | 
			
		||||
SQLite database files can be `fetch`ed and loaded:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
/* Load sql.js library */
 | 
			
		||||
const SQL = await initSqlJs(config);
 | 
			
		||||
/* fetch sqlite database */
 | 
			
		||||
const ab = await (await fetch("/sqlite/chinook.db")).arrayBuffer();
 | 
			
		||||
/* connect to DB */
 | 
			
		||||
const db = new SQL.Database(new Uint8Array(ab));
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The `sql.js` connector library uses an iterator-like interface. After preparing
 | 
			
		||||
a statement, `Statement#step` loops over the result and `Statement#getAsObject`
 | 
			
		||||
pulls each row as a row object:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
/* perform query and get iterator */
 | 
			
		||||
const sql = db.prepare("SELECT * FROM 'Invoice' LIMIT 100000").all();
 | 
			
		||||
 | 
			
		||||
/* create worksheet from the row objects */
 | 
			
		||||
let ws;
 | 
			
		||||
 | 
			
		||||
while(sql.step()) {
 | 
			
		||||
  const row = sql.getAsObject();
 | 
			
		||||
 | 
			
		||||
  if(!ws) ws = XLSX.utils.json_to_sheet([row], {dense: true, header});
 | 
			
		||||
  else XLSX.utils.sheet_add_json(ws, [row], { header, origin: -1, skipHeader: true});
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Demo
 | 
			
		||||
 | 
			
		||||
This demo fetches [`chinook.db`](pathname:///sqlite/chinook.db), loads into the
 | 
			
		||||
SQLite engine and performs a series of queries to extract the data. Worksheets
 | 
			
		||||
are created from the data. A workbook is created from the worksheets and
 | 
			
		||||
exported to a XLSX file.
 | 
			
		||||
 | 
			
		||||
```jsx live
 | 
			
		||||
function SheetJSQLJS() { return (<button onClick={async() => {
 | 
			
		||||
  /* Load sql.js library */
 | 
			
		||||
  const config = {
 | 
			
		||||
    locateFile: filename => `https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.8.0/${filename}`
 | 
			
		||||
  }
 | 
			
		||||
  const SQL = await initSqlJs(config);
 | 
			
		||||
 | 
			
		||||
  /* Initialize database */
 | 
			
		||||
  const ab = await (await fetch("/sqlite/chinook.db")).arrayBuffer();
 | 
			
		||||
  const db = new SQL.Database(new Uint8Array(ab));
 | 
			
		||||
 | 
			
		||||
  /* Create new workbook */
 | 
			
		||||
  const wb = XLSX.utils.book_new();
 | 
			
		||||
 | 
			
		||||
  /* Get all table names */
 | 
			
		||||
  const sql = db.prepare("SELECT name FROM sqlite_master WHERE type='table'");
 | 
			
		||||
  while(sql.step()) {
 | 
			
		||||
    const row = sql.getAsObject();
 | 
			
		||||
 | 
			
		||||
    /* Get first 100K rows */
 | 
			
		||||
    const stmt = db.prepare("SELECT * FROM '" + row.name + "' LIMIT 100000");
 | 
			
		||||
    let header = [];
 | 
			
		||||
    let ws;
 | 
			
		||||
    while(stmt.step()) {
 | 
			
		||||
      /* create worksheet from headers */
 | 
			
		||||
      if(!ws) ws = XLSX.utils.aoa_to_sheet([header = stmt.getColumnNames()])
 | 
			
		||||
 | 
			
		||||
      const rowobj = stmt.getAsObject();
 | 
			
		||||
      /* add to sheet */
 | 
			
		||||
      XLSX.utils.sheet_add_json(ws, [rowobj], { header, origin: -1, skipHeader: true});
 | 
			
		||||
    }
 | 
			
		||||
    if(ws) XLSX.utils.book_append_sheet(wb, ws, row.name);
 | 
			
		||||
  }
 | 
			
		||||
  XLSX.writeFile(wb, "SheetJSQLJS.xlsx");
 | 
			
		||||
}}><b>Click here to start</b></button>) }
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Server-Side Platforms
 | 
			
		||||
 | 
			
		||||
### NodeJS
 | 
			
		||||
 | 
			
		||||
The `better-sqlite3`[^7] native module embeds the SQLite C library.
 | 
			
		||||
`Statement#all` runs a prepared statement and returns an array of objects:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
import Database from "better-sqlite3";
 | 
			
		||||
import * as XLSX from "xlsx";
 | 
			
		||||
 | 
			
		||||
/* open database */
 | 
			
		||||
var db = Database("chinook.db");
 | 
			
		||||
 | 
			
		||||
/* get data from the `Invoice` table */
 | 
			
		||||
var aoo = db.prepare("SELECT * FROM 'Invoice' LIMIT 100000").all();
 | 
			
		||||
 | 
			
		||||
/* create worksheet from the row objects */
 | 
			
		||||
var ws = XLSX.utils.json_to_sheet(aoo, {dense: true});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
0) Build `chinook.db` from [the SQL statements](pathname:///sqlite/chinook.sql):
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
curl -LO https://docs.sheetjs.com/sqlite/chinook.sql
 | 
			
		||||
sqlite3 chinook.db ".read chinook.sql"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
1) Install the dependencies:
 | 
			
		||||
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz better-sqlite3@9.0.0`}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
 | 
			
		||||
2) Download [`SheetJSQLiteNode.mjs`](pathname:///sqlite/SheetJSQLiteNode.mjs):
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
curl -LO https://docs.sheetjs.com/sqlite/SheetJSQLiteNode.mjs
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
3) Run the script:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
node SheetJSQLiteNode.mjs
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Open `SheetJSQLiteNode.xlsx` with a spreadsheet editor.
 | 
			
		||||
 | 
			
		||||
### Bun
 | 
			
		||||
 | 
			
		||||
Bun ships with a built-in high-performance module `bun:sqlite`[^8]:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
import { Database } from "bun:sqlite";
 | 
			
		||||
import * as XLSX from "xlsx";
 | 
			
		||||
 | 
			
		||||
/* open database */
 | 
			
		||||
var db = Database.open("chinook.db");
 | 
			
		||||
 | 
			
		||||
/* get data from the `Invoice` table */
 | 
			
		||||
var aoo = db.prepare("SELECT * FROM 'Invoice' LIMIT 100000").all();
 | 
			
		||||
 | 
			
		||||
/* create worksheet from the row objects */
 | 
			
		||||
var ws = XLSX.utils.json_to_sheet(aoo, {dense: true});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
0) Build `chinook.db` from [the SQL statements](pathname:///sqlite/chinook.sql):
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
curl -LO https://docs.sheetjs.com/sqlite/chinook.sql
 | 
			
		||||
sqlite3 chinook.db ".read chinook.sql"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
1) Install the dependencies:
 | 
			
		||||
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
bun install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
 | 
			
		||||
2) Download [`SheetJSQLiteBun.mjs`](pathname:///sqlite/SheetJSQLiteBun.mjs):
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
curl -LO https://docs.sheetjs.com/sqlite/SheetJSQLiteBun.mjs
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
3) Run the script:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
bun run SheetJSQLiteBun.mjs
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Open `SheetJSQLiteBun.xlsx` with a spreadsheet editor.
 | 
			
		||||
 | 
			
		||||
### Deno
 | 
			
		||||
 | 
			
		||||
Deno `sqlite` library[^9] returns raw arrays of arrays:
 | 
			
		||||
 | 
			
		||||
<CodeBlock language="ts">{`\
 | 
			
		||||
import { DB } from "https://deno.land/x/sqlite/mod.ts";
 | 
			
		||||
// @deno-types="https://cdn.sheetjs.com/xlsx-${current}/package/types/index.d.ts"
 | 
			
		||||
import * as XLSX from "https://cdn.sheetjs.com/xlsx-${current}/package/xlsx.mjs";
 | 
			
		||||
\n\
 | 
			
		||||
/* open database */
 | 
			
		||||
var db = new DB("chinook.db");
 | 
			
		||||
\n\
 | 
			
		||||
/* get data from the \`Invoice\` table */
 | 
			
		||||
var aoa = db.prepareQuery("SELECT * FROM 'Invoice' LIMIT 100000").all();
 | 
			
		||||
\n\
 | 
			
		||||
/* create worksheet from the row objects */
 | 
			
		||||
var data = [query.columns().map(x => x.name)].concat(aoa);
 | 
			
		||||
var ws = XLSX.utils.aoa_to_sheet(data, {dense: true});`}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
 | 
			
		||||
0) Build `chinook.db` from [the SQL statements](pathname:///sqlite/chinook.sql):
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
curl -LO https://docs.sheetjs.com/sqlite/chinook.sql
 | 
			
		||||
sqlite3 chinook.db ".read chinook.sql"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
1) Download [`SheetJSQLiteDeno.ts`](pathname:///sqlite/SheetJSQLiteDeno.ts):
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
curl -LO https://docs.sheetjs.com/sqlite/SheetJSQLiteDeno.ts
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
2) Run the script:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
deno run --allow-read --allow-write SheetJSQLiteDeno.ts
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Open `SheetJSQLiteDeno.xlsx` with a spreadsheet editor.
 | 
			
		||||
 | 
			
		||||
[^1]: See [`json_to_sheet` in "Utilities"](/docs/api/utilities/array#array-of-objects-input)
 | 
			
		||||
[^2]: See ["Sheet Objects"](/docs/csf/sheet) in "SheetJS Data Model" for more details.
 | 
			
		||||
[^3]: See ["Workbook Helpers" in "Utilities"](/docs/api/utilities/wb) for details on `book_new` and `book_append_sheet`.
 | 
			
		||||
[^4]: See ["Workbook Objects"](/docs/csf/book) in "SheetJS Data Model" for more details.
 | 
			
		||||
[^5]: See [`writeFile` in "Writing Files"](/docs/api/write-options)
 | 
			
		||||
[^6]: See [the `sql.js` documentation](https://sql.js.org/documentation/)
 | 
			
		||||
[^7]: The [documentation](https://github.com/WiseLibs/better-sqlite3/blob/master/docs/api.md) can be found in the project repository.
 | 
			
		||||
[^8]: See ["SQLite"](https://bun.sh/docs/api/sqlite) in the BunJS documentation.
 | 
			
		||||
[^9]: See [the `sqlite` module](https://deno.land/x/sqlite) on the Deno module registry.
 | 
			
		||||
@ -183,6 +183,7 @@ The following Web APIs are featured in separate demos:
 | 
			
		||||
    <a href={item.href}>{item.label}</a>{item.customProps?.summary && (" - " + item.customProps.summary)}
 | 
			
		||||
  </li>);
 | 
			
		||||
})}
 | 
			
		||||
<li><a href="/docs/demos/local/websql">Web SQL Database</a></li>
 | 
			
		||||
<li><a href="/docs/demos/local/storageapi">Local Storage API</a></li>
 | 
			
		||||
<li><a href="/docs/demos/local/indexeddb">IndexedDB API</a></li>
 | 
			
		||||
</ul>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										217
									
								
								docz/docs/03-demos/08-local/01-websql.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										217
									
								
								docz/docs/03-demos/08-local/01-websql.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,217 @@
 | 
			
		||||
---
 | 
			
		||||
title: Sheets with WebSQL
 | 
			
		||||
sidebar_label: Web SQL Database
 | 
			
		||||
pagination_prev: demos/data/index
 | 
			
		||||
pagination_next: demos/cloud/index
 | 
			
		||||
sidebar_custom_props:
 | 
			
		||||
  summary: Reading and writing data in an in-browser SQL database
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
import CodeBlock from '@theme/CodeBlock';
 | 
			
		||||
 | 
			
		||||
WebSQL (formally "Web SQL Database") is a popular SQL-based in-browser database
 | 
			
		||||
available in Chromium and related browsers including Google Chrome. In practice,
 | 
			
		||||
it is powered by SQLite. Many SQLite-compatible queries work as-is in WebSQL.
 | 
			
		||||
 | 
			
		||||
The public demo <https://sheetjs.com/sql> generates a database from workbook.
 | 
			
		||||
 | 
			
		||||
:::caution pass
 | 
			
		||||
 | 
			
		||||
WebSQL is only supported in Chromium-based browsers including Chrome.
 | 
			
		||||
 | 
			
		||||
Safari historically supported WebSQL but Safari 13 dropped support.
 | 
			
		||||
 | 
			
		||||
Legacy browsers including Internet Explorer and Firefox never added support.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
:::info pass
 | 
			
		||||
 | 
			
		||||
WebSQL is not commonly available on server-side platforms. Typically scripts
 | 
			
		||||
will directly query SQLite databases using connector modules.
 | 
			
		||||
 | 
			
		||||
[The "SQLite" demo](/docs/demos/data/sqlite) covers NodeJS and other platforms.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
## Overview
 | 
			
		||||
 | 
			
		||||
Environments that support WebSQL expose the `openDatabase` global method. It
 | 
			
		||||
takes 4 arguments:
 | 
			
		||||
- internal database name
 | 
			
		||||
- version string (`1.0`)
 | 
			
		||||
- public display name
 | 
			
		||||
- database size (measured in bytes)
 | 
			
		||||
 | 
			
		||||
The following command attempts to connect to the database named `sheetql`. If
 | 
			
		||||
the database does not exist, it will create a new database with a hint to
 | 
			
		||||
allocate 2MB of space.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const db = openDatabase('sheetql', '1.0', 'SheetJS WebSQL Test', 2097152);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Transactions and Queries
 | 
			
		||||
 | 
			
		||||
Queries are performed within transactions.
 | 
			
		||||
 | 
			
		||||
`Database#transaction` passes a transaction object to the callback argument:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
db.transaction(function(tx) {
 | 
			
		||||
  /* tx is a transaction object */
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Within a transaction, queries are performed with `Transaction#executeSql`. The
 | 
			
		||||
method takes 4 arguments:
 | 
			
		||||
- SQL statement stored in a string
 | 
			
		||||
- Array of parameterized query arguments
 | 
			
		||||
- Success callback
 | 
			
		||||
- Error callback
 | 
			
		||||
 | 
			
		||||
If the query succeeds, the success callback will be invoked with two arguments:
 | 
			
		||||
- Transaction object
 | 
			
		||||
- Result of the query
 | 
			
		||||
 | 
			
		||||
If the query fails, the error callback will be invoked with two arguments:
 | 
			
		||||
- Transaction object
 | 
			
		||||
- Error information
 | 
			
		||||
 | 
			
		||||
The Web SQL Database API is callback-based. The following snippet runs one query
 | 
			
		||||
and wraps the execution in a promise that resolves to the query result or
 | 
			
		||||
rejects with the error:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
function execute_simple_query(db, query) {
 | 
			
		||||
  return new Promise((resolve, reject) => {
 | 
			
		||||
    db.transaction(tx =>
 | 
			
		||||
      tx.executeSQL(query, [],
 | 
			
		||||
        (tx, data) => resolve(data),
 | 
			
		||||
        (tx, err) => reject(err)
 | 
			
		||||
      )
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Importing Data
 | 
			
		||||
 | 
			
		||||
Importing data from spreadsheets is straightforward using the `generate_sql`
 | 
			
		||||
helper function from ["Generating Tables"](/docs/demos/data/sql#generating-tables)
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const stmts = generate_sql(ws, wsname);
 | 
			
		||||
 | 
			
		||||
// NOTE: tx.executeSql and db.transaction use callbacks. This wraps in Promises
 | 
			
		||||
for(var stmt of stmts) await new Promise((res, rej) => {
 | 
			
		||||
  db.transaction(tx =>
 | 
			
		||||
    tx.executeSql(stmt, [],
 | 
			
		||||
      (tx, data) => res(data), // if the query is successful, return the data
 | 
			
		||||
      (tx, err) => rej(err) // if the query fails, reject with the error
 | 
			
		||||
  ));
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Typically worksheet objects are extracted from workbook objects[^1] generated
 | 
			
		||||
from the SheetJS `read` or `readFile` methods[^2].
 | 
			
		||||
 | 
			
		||||
### Exporting Data
 | 
			
		||||
 | 
			
		||||
The result of a SQL SELECT statement is a `SQLResultSet`.  The `rows` property
 | 
			
		||||
is a `SQLResultSetRowList`.  It is an "array-like" structure that has `length`
 | 
			
		||||
and properties like `0`, `1`, etc.  However, this is not a real Array object!
 | 
			
		||||
 | 
			
		||||
A real Array can be created using `Array.from`. The SheetJS `json_to_sheet`
 | 
			
		||||
method[^3] can generate a worksheet object[^4] from the real array:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
db.readTransaction(tx =>
 | 
			
		||||
  tx.executeSQL("SELECT * FROM DatabaseTable", [], (tx, data) => {
 | 
			
		||||
    // data.rows is "array-like", so `Array.from` can make it a real array
 | 
			
		||||
    const aoo = Array.from(data.rows);
 | 
			
		||||
    const ws = XLSX.utils.json_to_sheet(aoo);
 | 
			
		||||
    // ... perform an export here OR wrap in a Promise
 | 
			
		||||
  })
 | 
			
		||||
);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Using `book_new` and `book_append_sheet`[^5], a workbook object can be created.
 | 
			
		||||
This workbook is typically exported to the filesystem with `writeFile`[^6].
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Live Demo
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
 | 
			
		||||
This browser demo was tested in the following environments:
 | 
			
		||||
 | 
			
		||||
| Browser     | Date       |
 | 
			
		||||
|:------------|:-----------|
 | 
			
		||||
| Chrome 117  | 2023-10-13 |
 | 
			
		||||
 | 
			
		||||
Some lesser-used browsers do not support WebSQL:
 | 
			
		||||
 | 
			
		||||
| Browser     | Date       | Support                             |
 | 
			
		||||
|:------------|:-----------|:------------------------------------|
 | 
			
		||||
| Safari 17.0 | 2023-10-13 | Error `Web SQL is deprecated`       |
 | 
			
		||||
| Firefox 118 | 2023-10-13 | Error `openDatabase is not defined` |
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
### Export Demo
 | 
			
		||||
 | 
			
		||||
The following demo generates a database with 5 fixed SQL statements. Queries
 | 
			
		||||
can be changed in the Live Editor.  The WebSQL database can be inspected in the
 | 
			
		||||
"WebSQL" section of the "Application" Tab of Developer Tools:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
```jsx live
 | 
			
		||||
function SheetQL() {
 | 
			
		||||
  const [out, setOut] = React.useState("");
 | 
			
		||||
  const queries = [
 | 
			
		||||
    'DROP TABLE IF EXISTS Presidents',
 | 
			
		||||
    'CREATE TABLE Presidents (Name TEXT, Idx REAL)',
 | 
			
		||||
    'INSERT INTO Presidents  (Name, Idx) VALUES ("Barack Obama", 44)',
 | 
			
		||||
    'INSERT INTO Presidents  (Name, Idx) VALUES ("Donald Trump", 45)',
 | 
			
		||||
    'INSERT INTO Presidents  (Name, Idx) VALUES ("Joseph Biden", 46)'
 | 
			
		||||
  ];
 | 
			
		||||
  const xport = React.useCallback(async() => {
 | 
			
		||||
    /* prep database */
 | 
			
		||||
    const db = openDatabase('sheetql', '1.0', 'SheetJS WebSQL Test', 2097152);
 | 
			
		||||
 | 
			
		||||
    for(var q of queries) await new Promise((res, rej) => {
 | 
			
		||||
      db.transaction((tx) => {
 | 
			
		||||
        tx.executeSql(q, [], (tx, data) => res(data), (tx, err) => rej(err));
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    /* pull data and generate rows */
 | 
			
		||||
    db.readTransaction(tx => {
 | 
			
		||||
      tx.executeSql("SELECT * FROM Presidents", [], (tx, data) => {
 | 
			
		||||
        const aoo = Array.from(data.rows);
 | 
			
		||||
        setOut("QUERY RESULT:\n" + aoo.map(r => JSON.stringify(r)).join("\n") + "\n")
 | 
			
		||||
        const ws = XLSX.utils.json_to_sheet(aoo);
 | 
			
		||||
        const wb = XLSX.utils.book_new();
 | 
			
		||||
        XLSX.utils.book_append_sheet(wb, ws, "Presidents");
 | 
			
		||||
        XLSX.writeFile(wb, "SheetQL.xlsx");
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
  return ( <pre>{out}<button onClick={xport}><b>Fetch!</b></button></pre> );
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Server-Side SQLite
 | 
			
		||||
 | 
			
		||||
**[The exposition has been moved to a separate page.](/docs/demos/data/sqlite)**
 | 
			
		||||
 | 
			
		||||
[^1]: See ["Workbook Object"](/docs/csf/book)
 | 
			
		||||
[^2]: See [`read` and `readFile` in "Reading Files"](/docs/api/parse-options)
 | 
			
		||||
[^3]: See [`json_to_sheet` in "Utilities"](/docs/api/utilities/array#array-of-objects-input)
 | 
			
		||||
[^4]: See ["Sheet Objects"](/docs/csf/sheet)
 | 
			
		||||
[^5]: See ["Workbook Helpers" in "Utilities"](/docs/api/utilities/wb) for details on `book_new` and `book_append_sheet`.
 | 
			
		||||
[^6]: See [`writeFile` in "Writing Files"](/docs/api/write-options)
 | 
			
		||||
@ -22,7 +22,7 @@ tables with a content script and a background script.
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
 | 
			
		||||
This demo was last tested on 2023 June 06 against Chrome 114
 | 
			
		||||
This demo was last tested on 2023 October 14 against Chrome 117.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -94,7 +94,7 @@ This demo was tested in the following deployments:
 | 
			
		||||
 | 
			
		||||
| Architecture | Git Commit | Go version | Date       |
 | 
			
		||||
|:-------------|:-----------|:-----------|:-----------|
 | 
			
		||||
| `darwin-x64` | `28ee0ee`  | `1.19.3`   | 2023-06-05 |
 | 
			
		||||
| `darwin-x64` | `873a149`  | `1.21.3`   | 2023-10-14 |
 | 
			
		||||
| `darwin-arm` | `28ee0ee`  | `1.20.4`   | 2023-06-05 |
 | 
			
		||||
| `win10-x64`  | `81d7606`  | `1.20.2`   | 2023-08-27 |
 | 
			
		||||
| `win11-arm`  | `fc55792`  | `1.21.1`   | 2023-09-25 |
 | 
			
		||||
 | 
			
		||||
@ -44,7 +44,7 @@ These instructions were tested on the following platforms:
 | 
			
		||||
| MacOS 10.13.6 (x64)           | 2023-09-30 |
 | 
			
		||||
| MacOS 13.6 (ARM64)            | 2023-09-30 |
 | 
			
		||||
| Windows 10 (x64) + WSL Ubuntu | 2023-07-23 |
 | 
			
		||||
| Windows 11 (x64) + WSL Ubuntu | 2023-08-31 |
 | 
			
		||||
| Windows 11 (x64) + WSL Ubuntu | 2023-10-14 |
 | 
			
		||||
| Windows 11 (ARM) + WSL Ubuntu | 2023-09-18 |
 | 
			
		||||
 | 
			
		||||
With some additional dependencies, the unminified scripts are reproducible and
 | 
			
		||||
@ -64,7 +64,50 @@ import TabItem from '@theme/TabItem';
 | 
			
		||||
 | 
			
		||||
A) Ensure WSL ("WSL 2" in Windows 10) and the Ubuntu distribution are installed.
 | 
			
		||||
 | 
			
		||||
B) Install mercurial and subversion:
 | 
			
		||||
<details open><summary><b>Installation Notes</b> (click to hide)</summary>
 | 
			
		||||
 | 
			
		||||
In "Turn Windows features on or off", the following features must be enabled:
 | 
			
		||||
 | 
			
		||||
- "Hyper-V" (including every sub-feature)
 | 
			
		||||
- "Virtual Machine Platform"
 | 
			
		||||
- "Windows Hypervisor Platform"
 | 
			
		||||
- "Windows Subsystem for Linux"
 | 
			
		||||
 | 
			
		||||
The following command installs Ubuntu within WSL:
 | 
			
		||||
 | 
			
		||||
```powershell
 | 
			
		||||
wsl --install Ubuntu
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
:::caution pass
 | 
			
		||||
 | 
			
		||||
In the last Windows 11 test, there was a `WSL_E_DEFAULT_DISTRO_NOT_FOUND` error.
 | 
			
		||||
 | 
			
		||||
The resolution is to switch to WSL1, install, and switch back to WSL2:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
wsl --set-default-version 1
 | 
			
		||||
wsl --install Ubuntu
 | 
			
		||||
wsl --set-default-version 2
 | 
			
		||||
wsl --install Ubuntu
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
:::warning pass
 | 
			
		||||
 | 
			
		||||
**WSL will not run in a Windows on ARM VM on computers with the M1 CPU**
 | 
			
		||||
 | 
			
		||||
Apple Silicon M1 processors do not support nested virtualization.
 | 
			
		||||
 | 
			
		||||
M2 processors do support nested virtualization. SheetJS users have reported
 | 
			
		||||
success with Windows on ARM running on computers with the M2 Max CPU.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
 | 
			
		||||
B) Install mercurial and subversion from within WSL:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
sudo apt-get update
 | 
			
		||||
@ -93,7 +136,7 @@ sudo add-apt-repository --remove ppa:mercurial-ppa/releases
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
C) Install NodeJS
 | 
			
		||||
C) Install NodeJS within WSL:
 | 
			
		||||
 | 
			
		||||
:::info pass
 | 
			
		||||
 | 
			
		||||
@ -112,7 +155,9 @@ curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash -
 | 
			
		||||
sudo apt-get install -y nodejs
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Exit the WSL window and open a new one before proceeding:
 | 
			
		||||
D) Exit the WSL session and start a new session
 | 
			
		||||
 | 
			
		||||
E) Install the `n` package and switch NodeJS vesrions:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
# Switch to `n`-managed NodeJS
 | 
			
		||||
@ -130,12 +175,14 @@ sudo apt-get install -y npm
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
D) Test clone the [`js-crc32` repo](https://git.sheetjs.com/sheetjs/js-crc32)
 | 
			
		||||
F) Clone the [`js-crc32` repo](https://git.sheetjs.com/sheetjs/js-crc32)
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
git clone https://git.sheetjs.com/sheetjs/js-crc32
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
:::note pass
 | 
			
		||||
 | 
			
		||||
If this clone fails with an error message that mentions SSL or secure connection
 | 
			
		||||
or certificates, build and install a version of Git with proper SSL support:
 | 
			
		||||
 | 
			
		||||
@ -146,7 +193,9 @@ chmod +x compile-git-with-openssl.sh
 | 
			
		||||
./compile-git-with-openssl.sh
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
E) Set `git` config `core.autocrlf` setting to `false`. The following commands
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
G) Set `git` config `core.autocrlf` setting to `false`. The following commands
 | 
			
		||||
should be run twice, once within PowerShell (if Git for Windows is installed)
 | 
			
		||||
and once within WSL bash:
 | 
			
		||||
 | 
			
		||||
@ -155,10 +204,16 @@ git config --global --add core.autocrlf false
 | 
			
		||||
git config --global --unset core.autocrlf true
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
F) Run `unzip`. If the program is missing, install manually:
 | 
			
		||||
H) Run `unzip`. If the program is missing, install manually:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
sudo apt-get install -y unzip
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
I) Run `make`. If the program is missing, install manually:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
sudo apt-get install -y make
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
  </TabItem>
 | 
			
		||||
@ -207,7 +262,7 @@ for "LTS" and "Current" releases.  The "LTS" version should be installed.
 | 
			
		||||
In local testing, macOS 10.13 required NodeJS version `12.22.12`:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
curl -LO https://nodejs.org/download/release/v12.22.12/node-v12.22.12.pkg 
 | 
			
		||||
curl -LO https://nodejs.org/download/release/v12.22.12/node-v12.22.12.pkg
 | 
			
		||||
open node-v12.22.12.pkg
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -216,6 +216,7 @@ const config = {
 | 
			
		||||
        { from: '/docs/demos/localfile', to: '/docs/demos/local/file/' },
 | 
			
		||||
        { from: '/docs/demos/data/indexeddb', to: '/docs/demos/local/indexeddb/' },
 | 
			
		||||
        { from: '/docs/demos/data/storageapi', to: '/docs/demos/local/storageapi/' },
 | 
			
		||||
        { from: '/docs/demos/data/websql', to: '/docs/demos/local/websql/' },
 | 
			
		||||
        /* desktop */
 | 
			
		||||
        { from: '/docs/demos/cli', to: '/docs/demos/desktop/cli/' },
 | 
			
		||||
        { from: '/docs/getting-started/demos/cli', to: '/docs/demos/desktop/cli/' },
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								docz/static/sqlite/chinook.db
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										
											BIN
										
									
								
								docz/static/sqlite/chinook.db
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
		Loading…
	
		Reference in New Issue
	
	Block a user