瀏覽器中由來源私人檔案系統支援的 SQLite Wasm

使用 SQLite 處理所有儲存空間需求,以便在網路上順暢運作。

SQLite 是熱門的開放原始碼簡易嵌入式關聯資料庫管理系統。許多開發人員都使用這項服務,以易於使用的結構化方式儲存資料。由於 SQLite 的大小和記憶體需求較低,因此經常用於行動裝置、桌面應用程式和網路瀏覽器中,做為資料庫引擎。

SQLite 的主要特色之一,就是採用無伺服器資料庫,因此不需要另外的伺服器程序即可運作。而是將資料庫儲存在使用者裝置上的單一檔案中,以便輕鬆整合至應用程式。

SQLite 標誌。

以 WebAssembly 為基礎的 SQLite

有許多以 WebAssembly (Wasm) 為基礎的非官方 SQLite 版本,可在網路瀏覽器中使用,例如 sql.jssqlite3 WASM/JS 子專案是第一個與 SQLite 專案正式相關的專案,可製作程式庫的 Wasm 版本,建立支援 SQLite 的一系列可交付成果。這項專案的具體目標包括:

  • 繫結低階 sqlite3 API,以便在使用方面盡可能接近 C API。
  • 更高層級的物件導向 API,更類似於 sql.jsNode.js 樣式實作,可直接呼叫低階 API。這個 API 必須與低階 API 在同一個執行緒中使用。
  • 以 worker 為基礎的 API,可透過 worker 訊息與先前的 API 通訊。這個 API 適用於主執行緒,其中較低層級的 API 會安裝在 worker 執行緒中,並透過 worker 訊息與其通訊。
  • 這是 Worker API 的承諾式變化版本,可完全隱藏跨執行緒通訊方面的內容。
  • 支援使用現有 JavaScript API 的持續性用戶端儲存空間,包括原始私人檔案系統 (OPFS)。

搭配使用 SQLite Wasm 與 Origin 私人檔案系統持續性後端

從 npm 安裝程式庫

使用下列指令,從 npm 安裝 @sqlite.org/sqlite-wasm 套件:

npm install @sqlite.org/sqlite-wasm

Origin 私人檔案系統

Origin 私人檔案系統 (OPFS,File System Access API 的一部分) 增添了特殊介面,可提供高效的資料存取功能。這個新的介面不同於現有介面,提供檔案內容直接且專屬的寫入存取權,與現有介面不同。這項變更可讓您持續讀取未刷新的修改內容,並在專屬 worker 上提供同步變化版本,大幅提升效能,並解除新用途的封鎖。

如您所知,專案的最後目標是支援使用現有 JavaScript API 的持續性用戶端儲存空間,這項目標有嚴格的效能要求,必須將資料儲存在資料庫檔案中。這就是 Origin 私人檔案系統,更具體來說,就是 FileSystemFileHandle 物件的 createSyncAccessHandle() 方法。這個方法會傳回 Promise,該 Promise 會解析為 FileSystemSyncAccessHandle 物件,以便同步讀取及寫入檔案。此方法的同步性質具有效能優勢,但只能在專屬網路工作站中用於來源私人檔案系統中的檔案,因此無法封鎖主執行緒。

設定必要標頭

下載的 SQLite Wasm 封存檔除了其他檔案外,還包含 sqlite3.jssqlite3.wasm 檔案,這些檔案組成 sqlite3 WASM/JS 版本。jswasm 目錄包含核心的 SQLite3 成果,頂層目錄則包含示範和測試應用程式。瀏覽器不會透過 file:// 網址提供 Wasm 檔案,因此您使用此方式建構的任何應用程式都需要網路伺服器,且該伺服器在提供檔案時,必須在回應中加入下列標頭:

這類標頭的原因是 SQLite Wasm 依附於 SharedArrayBuffer,而設定這些標頭是其安全性需求的一部分。

如果您使用開發人員工具檢查流量,應該會看到下列資訊:

上述兩個標頭 (Cross-Origin-Embedder-Policy 和 Cross-Origin-Opener-Policy) 已在 Chrome 開發人員工具中加以標示。

網路速度測試

相較於已淘汰的 Web SQL,SQLite 團隊已針對 WebAssembly 實作執行一些基準測試。這些基準測試顯示,SQLite Wasm 的速度通常與 Web SQL 相當。有時速度會稍微變慢,有時則會稍微變快。請前往結果頁面查看所有詳細資料。

程式碼範例入門

如先前所述,含有 Origin 私人檔案系統持久性後端的 SQLite Wasm 需要從 worker 情境中執行。好消息是,程式庫會自動處理所有這些事,您可以直接從主執行緒使用它。

import { sqlite3Worker1Promiser } from '@sqlite.org/sqlite-wasm';

(async () => {
  try {
    console.log('Loading and initializing SQLite3 module...');

    const promiser = await new Promise((resolve) => {
      const _promiser = sqlite3Worker1Promiser({
        onready: () => {
          resolve(_promiser);
        },
      });
    });

    console.log('Done initializing. Running demo...');

    let response;

    response = await promiser('config-get', {});
    console.log('Running SQLite3 version', response.result.version.libVersion);

    response = await promiser('open', {
      filename: 'file:worker-promiser.sqlite3?vfs=opfs',
    });
    const { dbId } = response;
    console.log(
      'OPFS is available, created persisted database at',
      response.result.filename.replace(/^file:(.*?)\?vfs=opfs$/, '$1'),
    );

    await promiser('exec', { dbId, sql: 'CREATE TABLE IF NOT EXISTS t(a,b)' });
    console.log('Creating a table...');

    console.log('Insert some data using exec()...');
    for (let i = 20; i <= 25; ++i) {
      await promiser('exec', {
        dbId,
        sql: 'INSERT INTO t(a,b) VALUES (?,?)',
        bind: [i, i * 2],
      });
    }

    console.log('Query data with exec()');
    await promiser('exec', {
      dbId,
      sql: 'SELECT a FROM t ORDER BY a LIMIT 3',
      callback: (result) => {
        if (!result.row) {
          return;
        }
        console.log(result.row);
      },
    });

    await promiser('close', { dbId });
  } catch (err) {
    if (!(err instanceof Error)) {
      err = new Error(err.result.message);
    }
    console.error(err.name, err.message);
  }
})();

示範

如要瞭解上述程式碼的實際運作情形,請參閱示範。請務必查看 Glitch 上的原始碼。請注意,下方的嵌入式版本不會使用 OPFS 後端,但在分開的分頁中開啟示範畫面時,會使用 OPFS 後端。

對 Origin 私人檔案系統進行偵錯

如要對 SQLite Wasm 的 Origin 私人檔案系統輸出內容進行偵錯,請使用 OPFS Explorer Chrome 擴充功能。

前往 Chrome 線上應用程式商店,下載 OPFS Explorer。

安裝擴充功能後,請開啟 Chrome 開發人員工具,然後選取「OPFS Explorer」分頁,即可檢查 SQLite Wasm 寫入原始私人檔案系統的內容。

OPFS Explorer Chrome 擴充功能,顯示 Origin 私人檔案系統的示範應用程式結構。

如果您在 DevTools 的 OPFS Explorer 視窗中選取任何檔案,即可將檔案儲存至本機磁碟。接著,您可以使用 SQLite 檢視器這類應用程式來檢查資料庫,確認 SQLite Wasm 實際上可以正常運作。

透過 SQLite Viewer 應用程式,透過 SQLite Wasm 示範開啟資料庫檔案。

取得協助及提供意見回饋

SQLite Wasm 是由 SQLite 社群開發及維護。尋求協助及提供意見回饋,方法是在支援論壇中搜尋並張貼問題。您可以在 SQLite 網站上查看完整說明文件