瀏覽器中由來源私人檔案系統支援的 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)。

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

從 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() 方法。這個方法會傳回承諾,並解析為 FileSystemSyncAccessHandle 物件,可用於同步讀取及寫入檔案。此方法的同步性質可帶來效能優勢,但因此只能在專用 Web Workers 中使用,用於處理來源私人檔案系統中的檔案,以免主執行緒遭到封鎖。

設定必要的標頭

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

這些標頭的原因是 SQLite Wasm 會依賴 SharedArrayBuffer,而設定這些標頭是其安全性規定的一部分。

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

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

網路速度測試

SQLite 團隊已對 WebAssembly 實作項目執行一些基準測試,並與已淘汰的 Web SQL 進行比較。這些基準測試顯示,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 Viewer 之類的應用程式檢查資料庫,確保 SQLite Wasm 確實能正常運作。

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

取得協助及提供意見回饋

SQLite Wasm 是由 SQLite 社群開發及維護。請前往支援論壇搜尋及發布內容,以便取得協助及提供意見回饋。您可以在 SQLite 網站上查看完整說明文件