Từ Web SQL sang SQLite Wasm: hướng dẫn di chuyển cơ sở dữ liệu

Với SQLite Wasm được hệ thống tệp riêng tư nguồn gốc hỗ trợ, công nghệ cơ sở dữ liệu Web SQL sẽ được thay thế linh hoạt cho công nghệ cơ sở dữ liệu Web SQL không dùng nữa. Bài viết này trình bày hướng dẫn di chuyển dữ liệu từ Web SQL sang SQLite Wasm.

Phông nền bắt buộc

Bài đăng Ngừng sử dụng và xoá Web SQL có thông báo về việc ngừng sử dụng công nghệ cơ sở dữ liệu Web SQL. Mặc dù bản thân công nghệ này có thể không được dùng nữa, nhưng các trường hợp sử dụng mà công nghệ này xử lý rất nhiều thì không, vì vậy, bài đăng tiếp theo SQLite Wasm trong trình duyệt được hỗ trợ bởi Hệ thống tệp riêng tư Origin (Hệ thống tệp riêng tư gốc) đã nêu ra một bộ công nghệ thay thế dựa trên cơ sở dữ liệu SQLite, được biên dịch thành Web Assembly ( Wasm) và được hỗ trợ bởi hệ thống tệp riêng tư gốc. Để khép lại vòng tròn, bài viết này trình bày cách di chuyển cơ sở dữ liệu từ Web SQL sang SQLite Wasm.

Di chuyển cơ sở dữ liệu

Bốn bước sau đây thể hiện ý tưởng khái niệm về việc di chuyển cơ sở dữ liệu Web SQL sang SQLite Wasm, với cơ sở dữ liệu SQLite được hệ thống tệp riêng tư nguồn gốc hỗ trợ. Đây có thể là nền tảng cho mã của riêng bạn, được tuỳ chỉnh theo nhu cầu di chuyển Web SQL của bạn.

(Các) cơ sở dữ liệu Web SQL sẽ được di chuyển

Giả định cơ sở của hướng dẫn di chuyển này là bạn có một (hoặc một số) cơ sở dữ liệu Web SQL hiện có chứa dữ liệu liên quan đến ứng dụng. Trong ảnh chụp màn hình dưới đây, bạn sẽ thấy một cơ sở dữ liệu mẫu có tên là mydatabase với bảng dữ liệu về mưa dông giúp ánh xạ tâm trạng đến mức độ nghiêm trọng. Công cụ của Chrome cho nhà phát triển cho phép bạn xem cơ sở dữ liệu Web SQL để gỡ lỗi, như trong ảnh chụp màn hình sau.

Cơ sở dữ liệu Web SQL được kiểm tra trong Công cụ cho nhà phát triển của Chrome. Cơ sở dữ liệu này có tên là mydatabase và lưu trữ một bảng có 3 cột: mã hàng, tâm trạng và mức độ nghiêm trọng. Có 3 hàng dữ liệu mẫu.

Dịch cơ sở dữ liệu Web SQL sang các câu lệnh SQL

Để di chuyển dữ liệu theo cách minh bạch với người dùng, tức là không yêu cầu người dùng tự thực hiện bất kỳ bước di chuyển nào, các phần dữ liệu trong cơ sở dữ liệu cần được dịch trở lại câu lệnh SQL gốc đã tạo các dữ liệu đó lúc đầu. Thử thách này đã được đưa ra trước đó và tập lệnh di chuyển dùng trong bài viết này (mywebsqldump.js) dựa trên thư viện cộng đồng có tên là websqldump.js, với một số điều chỉnh nhỏ. Mã mẫu sau đây cho thấy mã cần thiết để dịch mydatabase trong cơ sở dữ liệu Web SQL sang một tập hợp câu lệnh SQL.

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

Chạy mã này dẫn đến chuỗi câu lệnh SQL bên dưới.

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');

Nhập dữ liệu vào SQLite Wasm

Tất cả những gì còn lại đang thực thi các lệnh SQL này trong ngữ cảnh SQLite Wasm. Để biết mọi thông tin chi tiết về cách thiết lập SQLite Wasm, bạn hãy tham khảo bài viết SQLite Wasm trong trình duyệt được hỗ trợ bởi Hệ thống tệp riêng tư nguồn gốc. Tuy nhiên, nội dung chính của SQLite ở bên dưới. Hãy nhớ rằng mã này cần chạy trong Worker (mà thư viện tự động tạo cho bạn), với tiêu đề HTTP bắt buộc được thiết lập chính xác. Bạn có thể cài đặt gói @sqlite.org/sqlite-wasm từ npm.

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);
  }
})();

Sau khi chạy mã này, hãy kiểm tra tệp cơ sở dữ liệu đã nhập bằng tiện ích OPFS Explorer cho Công cụ của Chrome cho nhà phát triển. Hiện có hai tệp, một tệp có cơ sở dữ liệu thực tế và một tệp có thông tin ghi nhật ký. Lưu ý rằng hai tệp này nằm trong hệ thống tệp riêng tư tại nguồn gốc, vì vậy, bạn cần sử dụng tiện ích OPFS Explorer để xem các tệp này.

Kiểm tra hệ thống tệp riêng tư gốc bằng Công cụ của Chrome cho nhà phát triển của Chrome Explorer. Có hai tệp, một tệp tên là mydatabase.db và một tệp có tên là mydatabase.db-journal.

Để thực sự xác minh rằng dữ liệu đã nhập giống với dữ liệu Web SQL ban đầu, hãy nhấp vào tệp mydatabase.db và tiện ích OPFS Explorer sẽ hiển thị hộp thoại Save File (Lưu tệp) để cho phép bạn lưu tệp trong hệ thống tệp hiển thị cho người dùng. Sau khi lưu tệp cơ sở dữ liệu, hãy dùng ứng dụng trình xem SQLite để khám phá dữ liệu. Project Fugu API Showcase (Giới thiệu API Project Fugu) nêu bật một số ứng dụng dùng để làm việc với SQLite trong trình duyệt. Ví dụ: Sqlime — SQLite Playground cho phép bạn mở tệp cơ sở dữ liệu SQLite qua ổ đĩa cứng và chạy các truy vấn trên cơ sở dữ liệu đó. Như bạn thấy trong ảnh chụp màn hình dưới đây, bảng mưa bão đã được nhập chính xác vào SQLite.

Khám phá tệp mydatabase.db trong công cụ Sqlime SQLite Playground. Ứng dụng xuất hiện với truy vấn SQL chọn sao từ mưa bão (giới hạn 10) được chạy, dẫn đến ba hàng từ dữ liệu mẫu ban đầu từ Web SQL.

Giải phóng bộ nhớ Web SQL

Mặc dù (có thể đáng ngạc nhiên) không thể xoá cơ sở dữ liệu Web SQL, nhưng bạn vẫn nên giải phóng bộ nhớ bằng cách xoá các bảng Web SQL hiện đã lỗi thời sau khi đã di chuyển dữ liệu vào SQLite Wasm. Để liệt kê tất cả bảng trong cơ sở dữ liệu Web SQL và thả các bảng này bằng JavaScript, hãy sử dụng mã như trong đoạn mã sau:

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);
  }
};

Làm việc với dữ liệu sau khi di chuyển

Sau khi bạn di chuyển dữ liệu, hãy làm việc với dữ liệu như nêu trong Mã mẫu bắt đầu sử dụng này. Xem Tài liệu tham khảo về API SQLite Wasm để biết thông tin chi tiết. Xin nhắc lại rằng bạn cần truy cập vào SQLite Wasm qua Worker nếu sử dụng hệ thống tệp riêng tư cho nguồn gốc làm phần phụ trợ lưu trữ.

Hãy dùng thử

Bản minh hoạ này cho phép bạn điền dữ liệu mẫu vào cơ sở dữ liệu Web SQL, sau đó kết xuất dữ liệu Web SQL dưới dạng câu lệnh SQL. Sau đó, dữ liệu này sẽ được nhập vào SQLite Wasm nhờ hệ thống tệp riêng tư của nguồn gốc. Cuối cùng, bạn có thể giải phóng bộ nhớ bằng cách xoá dữ liệu Web SQL lỗi thời. Kiểm tra mã nguồn để triển khai đầy đủ, bao gồm cả tệp mywebsqldump.js đã vá.

Ứng dụng minh hoạ tại web-sql-to-sqlite-wasm.glitch.me.

Kết luận

Bạn có thể di chuyển cơ sở dữ liệu Web SQL sang SQLite Wasm do hệ thống tệp riêng tư gốc hỗ trợ theo cách minh bạch cho người dùng. Họ sẽ không nhận thấy rằng dữ liệu của họ hiện được lưu trữ trong hệ thống tệp riêng tư gốc trong cơ sở dữ liệu SQLite và không còn tồn tại trong Web SQL. Nhìn chung, việc di chuyển từ Web SQL sang SQLite là một bước cần thiết cho các nhà phát triển web muốn đảm bảo tính ổn định và khả năng mở rộng lâu dài cho các ứng dụng của họ. Tuy quy trình này có thể khiến bạn phải tốn công sức ban đầu, nhưng lợi ích của một giải pháp cơ sở dữ liệu mạnh mẽ, linh hoạt và hơn hết là phù hợp với tương lai sẽ khiến bạn phải đầu tư.