От Web SQL к SQLite Wasm: руководство по миграции базы данных

Благодаря SQLite Wasm, поддерживаемому приватной файловой системой Origin, появилась универсальная замена устаревшей технологии баз данных 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 с таблицей данных о ливнях, которая сопоставляет настроение с интенсивностью. Chrome DevTools позволяет просматривать базы данных Web SQL для отладки , как показано на снимке экрана ниже.

База данных Web SQL, проверенная в DevTools браузера Chrome. База данных называется mydatabase и содержит таблицу с тремя столбцами: идентификатор строки, настроение и уровень серьёзности. В базе данных три строки с примерами данных.

Перевод базы данных 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

Остаётся только выполнить эти SQL-команды в контексте SQLite Wasm. Подробности настройки SQLite Wasm см. в статье SQLite Wasm в браузере на базе Origin Private File System , но суть изложена ниже. Помните, что этот код должен запускаться в Worker (который библиотека автоматически создаёт), с правильно настроенными HTTP-заголовками . Вы можете установить пакет @sqlite.org/sqlite-wasm из 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);
  }
})();

После выполнения этого кода проверьте импортированный файл базы данных с помощью расширения OPFS Explorer для Chrome DevTools. Теперь там два файла: один с самой базой данных, а другой с информацией о журналировании. Обратите внимание, что эти два файла находятся в исходной приватной файловой системе, поэтому для их просмотра необходимо использовать расширение OPFS Explorer.

Проверка исходной приватной файловой системы с помощью OPFS Explorer в Chrome DevTools. В ней есть два файла: mydatabase.db и mydatabase.db-journal.

Чтобы убедиться, что импортированные данные соответствуют исходным данным Web SQL, щелкните файл mydatabase.db , и расширение OPFS Explorer откроет диалоговое окно «Сохранить файл» , позволяющее сохранить файл в видимой пользователю файловой системе. После сохранения файла базы данных используйте приложение для просмотра SQLite, чтобы изучить данные. В Project Fugu API Showcase представлено несколько приложений для работы с SQLite в браузере . Например, Sqlime — SQLite Playground позволяет открыть файл базы данных SQLite с жесткого диска и выполнять запросы к ней. Как видно на снимке экрана ниже, таблица rainstorm была корректно импортирована в SQLite.

Исследование файла mydatabase.db в инструменте Sqlime SQLite Playground. Приложение показано с запущенным SQL-запросом select star from rainstorms limit 10, в результате чего получены три строки из исходного образца данных из Web SQL.

Освобождение хранилища Web SQL

Хотя (как ни странно) удалить базу данных Web SQL невозможно , вам всё равно стоит освободить место в хранилище, удалив устаревшие таблицы Web SQL после переноса данных в SQLite Wasm. Чтобы получить список всех таблиц в базе данных 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);
  }
};

Работа с данными после миграции

После переноса данных работайте с ними, как описано в этом примере кода для начала работы . Подробнее см. в справочнике по API SQLite Wasm . Ещё раз напоминаем, что вам необходимо получить доступ к SQLite Wasm из Worker, если вы используете частную файловую систему источника в качестве бэкэнда хранилища.

Выводы

Миграция баз данных Web SQL в SQLite Wasm, поддерживаемую исходной приватной файловой системой, возможна прозрачно для пользователей. Они не заметят, что их данные теперь хранятся в исходной приватной файловой системе в базе данных SQLite, а не в Web SQL. В целом, миграция с Web SQL на SQLite — необходимый шаг для веб-разработчиков, стремящихся обеспечить долгосрочную стабильность и масштабируемость своих приложений. Хотя этот процесс может потребовать некоторых первоначальных усилий, преимущества более надежного, гибкого и, прежде всего, перспективного решения для работы с базами данных оправдывают эти инвестиции.