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

SQLite Wasm 由原始私人檔案系統支援,可取代已淘汰的 Web SQL 資料庫技術。本文將說明如何將資料從 Web SQL 遷移至 SQLite Wasm。

必填背景

我們在「淘汰並移除 WebSQL」一文中宣布淘汰 WebSQL 資料庫技術。雖然這項技術本身可能已淘汰,但這項技術所解決的用途並未淘汰,因此後續文章「瀏覽器中的 SQLite Wasm,由原始私人檔案系統提供支援」概述了以 SQLite 資料庫為基礎的替代技術組合,並編譯為 Web Assembly (Wasm),且由原始私人檔案系統提供支援。為此,本文將說明如何將資料庫從 Web SQL 遷移至 SQLite Wasm。

遷移資料庫

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

要遷移的 Web SQL 資料庫

本遷移指南的基本假設是,您擁有一個 (或多個) 現有的 Web SQL 資料庫,用於儲存與應用程式相關的資料。在下方螢幕截圖中,您可以看到名為 mydatabase 的範例資料庫,其中的暴風雨資料表會將天氣狀況對應至嚴重程度。Chrome 開發人員工具可讓您查看 WebSQL 資料庫以進行偵錯,如以下螢幕截圖所示。

在 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 設定的所有詳細資訊,請參閱「Origin 私人檔案系統支援的瀏覽器中的 SQLite Wasm」一文,但重點如下。請注意,這個程式碼必須在工作站 (程式庫會自動為您建立) 中執行,並正確設定必要的 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 Explorer Chrome 開發人員工具檢查來源私人檔案系統。有兩個檔案,一個名為 mydatabase.db,另一個名為 mydatabase.db-journal。

如要實際驗證匯入的資料是否與初始 Web SQL 資料相同,請按一下檔案 mydatabase.db,OPFS Explorer 擴充功能就會顯示「Save File」對話方塊,讓您將檔案儲存在使用者可見的檔案系統中。儲存資料庫檔案後,請使用 SQLite 檢視器應用程式探索資料。Project Fugu API 展示區提供多個可在瀏覽器中使用 SQLite 的應用程式。舉例來說,您可以使用 Sqlime - SQLite Playground 從硬碟開啟 SQLite 資料庫檔案,並在資料庫上執行查詢。如下方螢幕截圖所示,腦力激盪資料表已正確匯入 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 資料庫中填入範例資料,然後將 Web SQL 資料以 SQL 陳述式的形式傾印,並在下一個階段匯入由原始私人檔案系統支援的 SQLite Wasm。最後,您可以刪除過時的 Web SQL 資料來釋出儲存空間。請查看原始碼,瞭解完整實作方式,包括已修補的 mywebsqldump.js 檔案。

位於 web-sql-to-sqlite-wasm.glitch.me 的示範應用程式。

結論

您可以透過透明的方式,將 Web SQL 資料庫遷移至由來源私人檔案系統支援的 SQLite Wasm。他們不會發現自己的資料現在是託管在 SQLite 資料庫中的來源私人檔案系統,而不再位於 Web SQL 中。總體而言,如果網頁開發人員希望確保應用程式的長期穩定性和可擴充性,就必須從 Web SQL 遷移至 SQLite。雖然這個程序可能需要一些初始作業,但更強大、更彈性且最重要的是能因應未來需求的資料庫解決方案,絕對值得您投資。