ちょっとニッチな使い方をしてみたいと思います。
初めに ブラウザの JavaScript で SQLite の wasm版 を動かして、ネットワーク上の SQLite をダウンロード・SELECT実行をします。
探したところ、空のDBに新規でテーブルを作って、データを入れて、そのデータを取得するって記事がほとんどでした。
今回のポイントは、ネットワーク上の SQLite をダウンロードするってのがミソになるかと思っています。
DBは使いたいけど、バックエンドサーバはいらないって人に、うってつけなんじゃないでしょうか。
React はオマケですね。
GitHub Page にデプロイしても、DBが使えるのはいいですね。
環境
Windows 11 Home 22H2
create-react-app 5.0.1
事前に React のプロジェクトを作成しておきます。
1 npx create-react-app --template typescript my-react-app
ネットワーク上に配置する「mydb.sqlite3」も作成しておきます。
1 2 3 4 5 CREATE TABLE Test(id TEXT PRIMARY KEY, name TEXT, create_at TEXT); INSERT INTO Test VALUES ('1','test', DATETIME('now', 'localtime')); INSERT INTO Test VALUES ('2','テスト', DATETIME('now', 'localtime')); INSERT INTO Test VALUES ('3','テスト3', DATETIME('now', 'localtime')); INSERT INTO Test VALUES ('4','テスト4', DATETIME('now', 'localtime'));
作ったら、プロジェクトフォルダーの「public」フォルダー内に置いておきます。このフォルダーにあるファイルは、無条件でウェブに配置されるためです。
手順 モジュール モジュール「SQLite Wasm 」を使います。
https://github.com/tomayac/sqlite-wasm
コマンドプロンプトで次のコマンドを実行します。
1 npm install @sqlite.org/sqlite-wasm
Windows PowerShell の場合次のエラーが発生する。
1 2 3 4 5 6 7 8 PS D:\React\my-react-app> npm install @sqlite.org/sqlite-wasm 発生場所 行:1 文字:13 + npm install @sqlite.org/sqlite-wasm + ~~~~~~~ 分配演算子 '@' を使用して式で変数を参照することはできません。コマンドの引数として使用できるのは '@sqlite' だけです。式 で変数を参照するには、'$sqlite' を使用してください。 + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : SplattingNotPermitted
mydb.sqlite3 をダウンロードしてデータ取得 次のコードを「App.tsx」に貼り付けます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 import React from 'react'; import logo from './logo.svg'; import './App.css'; import sqlite3InitModule from '@sqlite.org/sqlite-wasm'; const log = (...args: any[]) => console.log(...args); const error = (...args: any[]) => console.error(...args); const start = function (sqlite3: any) { log('Running SQLite3 version', sqlite3.version.libVersion); const readDatabase = (arrayBuffer: any) => { const bytes = new Uint8Array(arrayBuffer); const p = sqlite3.wasm.allocFromTypedArray(bytes); const db = new sqlite3.oo1.DB(); sqlite3.capi.sqlite3_deserialize(db.pointer, "main", p, bytes.length, bytes.length, sqlite3.capi.SQLITE_DESERIALIZE_FREEONCLOSE | sqlite3.capi.SQLITE_DESERIALIZE_RESIZEABLE); return db; }; (async function () { const dataPromise = await fetch('mydb.sqlite3').then(res => res.arrayBuffer()); const u8array = new Uint8Array(dataPromise); const db = readDatabase(u8array); // Your SQLite code here. db.exec({ sql: 'SELECT * FROM Test ORDER BY id LIMIT 3', callback: (row: any) => { log(row); }, }); })(); }; function App() { const didLogRef = React.useRef(false); React.useEffect(() => { if (didLogRef.current == false) { didLogRef.current = true; log('Loading and initializing SQLite3 module...'); sqlite3InitModule({ print: log, printErr: error, }).then((sqlite3: any) => { try { log('Done initializing. Running demo...'); start(sqlite3); } catch (err: any) { error(err.name, err.message); } }); } }, []); return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <p> Edit <code>src/App.tsx</code> and save to reload. </p> <a className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer" > Learn React </a> </header> </div> ); } export default App;
4~32行目 と 36~51行目 が追加したコードです。
確認 開発者ツールを開いて画面更新をおこなうと、コンソールにSELECT結果が出力されます。
ネットワークタブを見ると「mydb.sqlite3」をダウンロードしていることが分かるかと思います。
終わりに デモ デモページを公開しました。
https://noitaro.github.io/react-sqlite-select-web/
参考 https://github.com/tomayac/sqlite-wasm
https://javascript.plainenglish.io/sqlite-3-in-action-how-to-open-a-local-database-with-javascript-and-webassembly-d766d0743a79
https://zenn.dev/knaka0209/books/96eca53ecdb2cd/viewer/d8ca93
https://qiita.com/kaikusakari/items/f30c97385e6b0118f4f0