從網路 SQL 到 SQLite Wasm:資料庫遷移指南

有了以來源私人檔案系統為基礎的 SQLite Wasm,就能取代已淘汰的 Web SQL 資料庫技術。本文將說明如何將資料從 Web SQL 遷移至 SQLite Wasm。

必要背景

淘汰並移除 Web SQL」一文宣布淘汰 Web SQL 資料庫技術。雖然這項技術本身可能已淘汰,但其用途仍相當重要,因此後續文章「在瀏覽器中使用 SQLite Wasm,並以 Origin Private File System 做為後端」說明瞭以 SQLite 資料庫為基礎的替代技術組合,編譯為 Web Assembly (Wasm),並以 Origin Private File System 做為後端。為完成這個循環,本文將說明如何將資料庫從 Web SQL 遷移至 SQLite Wasm。

遷移資料庫

以下四個步驟說明將 Web SQL 資料庫遷移至 SQLite Wasm 的概念,其中 SQLite 資料庫由來源私人檔案系統支援。您可以根據您的 Web SQL 遷移需求,自訂程式碼並以此為基礎。

要遷移的 Web SQL 資料庫

本遷移指南的基本假設是,您有一個 (或多個) 現有的 Web SQL 資料庫,其中包含與應用程式相關的資料。在下方的螢幕截圖中,您可以看到名為「mydatabase」的範例資料庫,其中包含一個 rainstorms 資料表,可將情緒對應至嚴重程度。如以下螢幕截圖所示,您可以使用 Chrome 開發人員工具查看 Web SQL 資料庫以進行偵錯

在 Chrome 開發人員工具中檢查的 Web SQL 資料庫。資料庫名為「mydatabase」,並代管一個資料表,其中包含三個資料欄:資料列 ID、情緒和嚴重程度。這裡有三行樣本資料。

將 Web SQL 資料庫轉換為 SQL 陳述式

如要以使用者無須自行執行任何遷移步驟的方式遷移資料,資料庫中的資料必須翻譯回當初建立資料的原始 SQL 陳述式。這個挑戰先前也出現過,而本文使用的遷移指令碼 mywebsqldump.js 是以名為 websqldump.js 的社群程式庫為基礎,並經過一些微調。下列程式碼範例顯示將 Web SQL 資料庫 mydatabase 轉換為一組 SQL 陳述式所需的程式碼。

websqldump.export({
  database: 'mydatabase',
  version: '1.0',
  success: function(sql) {
    // The SQL statements.
  },
  error: function(err) {
    // Handle the error.
  }
});

執行這段程式碼會產生下列 SQL 陳述式字串。

CREATE TABLE IF NOT EXISTS rainstorms (mood text, severity int);
INSERT INTO rainstorms(mood,severity) VALUES ('somber','6');
INSERT INTO rainstorms(mood,severity) VALUES ('rainy','8');
INSERT INTO rainstorms(mood,severity) VALUES ('stormy','2');

將資料匯入 SQLite Wasm

剩下的工作是在 SQLite Wasm 的環境中執行這些 SQL 指令。如要瞭解如何設定 SQLite Wasm,請參閱「SQLite Wasm in the browser backed by the Origin Private File System」一文,但重點如下。請注意,這段程式碼必須在 Worker 中執行 (程式庫會自動為您建立),且必要的 HTTP 標頭必須正確設定。您可以從 npm 安裝 @sqlite.org/sqlite-wasm 套件。

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

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

    let response;

    response = await promiser('open', {
      filename: 'file:mydatabase.db?vfs=opfs',
    });
    const { dbId } = response;

    const sql = `
      CREATE TABLE IF NOT EXISTS rainstorms (mood text, severity int);
      INSERT INTO rainstorms(mood,severity) VALUES ('somber','6');
      INSERT INTO rainstorms(mood,severity) VALUES ('rainy','8');
      INSERT INTO rainstorms(mood,severity) VALUES ('stormy','2');`
    await promiser('exec', { dbId, sql });

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

執行這段程式碼後,請使用 OPFS Explorer Chrome 開發人員工具擴充功能檢查匯入的資料庫檔案。現在有兩個檔案,一個是實際的資料庫,另一個是記錄資訊。請注意,這兩個檔案位於來源私有檔案系統中,因此您必須使用 OPFS Explorer 擴充功能才能查看。

使用 OPFS 瀏覽器 Chrome 開發人員工具檢查來源私有檔案系統。這兩個檔案分別是 mydatabase.db 和 mydatabase.db-journal。

如要實際驗證匯入的資料是否與初始 Web SQL 資料相同,請按一下檔案 mydatabase.db,OPFS Explorer 擴充功能會顯示「Save File」對話方塊,讓您將檔案儲存在使用者可見的檔案系統中。儲存資料庫檔案後,請使用 SQLite 檢視器應用程式探索資料。Project Fugu API Showcase 提供了多個可在瀏覽器中處理 SQLite 的應用程式。舉例來說,您可以使用 Sqlime - SQLite Playground 開啟硬碟中的 SQLite 資料庫檔案,並對資料庫執行查詢。如下方螢幕截圖所示,rainstorm 資料表已正確匯入 SQLite。

在 Sqlime SQLite Playground 工具中探索 mydatabase.db 檔案。應用程式會顯示執行的 SQL 查詢 (select star from rainstorms limit 10),並從 Web SQL 的初始範例資料中產生三列資料。

釋出 Web SQL 儲存空間

雖然無法刪除 Web SQL 資料庫 (或許令人驚訝),但將資料遷移至 SQLite Wasm 後,您仍應捨棄現已過時的 Web SQL 資料表,藉此釋出一些儲存空間。如要列出 Web SQL 資料庫中的所有資料表,並使用 JavaScript 捨棄這些資料表,請使用下列程式碼片段中的程式碼:

const dropAllTables = () => {
  try {
    db.transaction(function (tx) {
      tx.executeSql(
        "SELECT name FROM sqlite_master WHERE type='table' AND name !='__WebKitDatabaseInfoTable__'",
        [],
        function (tx, result) {
          const len = result.rows.length;
          const tableNames = [];
          for (let i = 0; i < len; i++) {
            const tableName = result.rows.item(i).name;
            tableNames.push(`'${tableName}'`);
            db.transaction(function (tx) {
              tx.executeSql('DROP TABLE ' + tableName);
            });
          }
          console.log(`Dropped table${tableNames.length > 1 ? 's' : ''}: ${tableNames.join(', ')}.`);
        }
      );
    });
  } catch (err) {
    console.error(err.name, err.message);
  }
};

遷移後如何處理資料

遷移資料後,請按照這份入門程式碼範例的說明使用資料。詳情請參閱 SQLite Wasm API 參考資料。再次提醒,如果您使用來源私有檔案系統做為儲存空間後端,就必須從 Worker 存取 SQLite Wasm。

結論

您可以將 Web SQL 資料庫遷移至以來源私人檔案系統為基礎的 SQLite Wasm,使用者不會察覺任何異狀。他們不會發現自己的資料現在是儲存在 SQLite 資料庫的來源私有檔案系統中,而不是 Web SQL。總而言之,對於想確保應用程式長期穩定性和可擴充性的網頁開發人員來說,從 Web SQL 遷移至 SQLite 是必要步驟。雖然這個程序可能需要一些初步工作,但更強大、彈性且最重要的是能因應未來需求的資料庫解決方案,絕對值得您投入。