Do Web SQL ao SQLite Wasm: guia de migração do banco de dados

Com o SQLite Wasm apoiado pelo sistema de arquivos privados de origem, há uma substituição versátil para a tecnologia de banco de dados Web SQL descontinuada. Este artigo é um guia para migrar seus dados do Web SQL para o SQLite Wasm.

Plano de fundo obrigatório

A postagem Suspensão e remoção do Web SQL anunciou a descontinuação da tecnologia de banco de dados Web SQL. Embora a tecnologia em si possa ter sido descontinuada, os casos de uso abordados por ela muito não são. Portanto, a postagem de acompanhamento SQLite Wasm no navegador apoiado pelo sistema de arquivos privados de origem (em inglês) descreve um conjunto de substituição de tecnologias com base no banco de dados SQLite, compilado para Web Assembly (Wasm) e apoiado pelo sistema de arquivos privados de origem. Para fechar o círculo, este artigo mostra como migrar bancos de dados do Web SQL para o SQLite Wasm.

Como migrar seus bancos de dados

As quatro etapas a seguir demonstram a ideia conceitual de migrar um banco de dados Web SQL para o SQLite Wasm, com o banco de dados SQLite apoiado pelo sistema de arquivos privados de origem. Ela pode servir como base para seu próprio código personalizado para suas necessidades de migração do Web SQL.

Os bancos de dados Web SQL que serão migrados

A suposição básica deste guia de migração é que você tem um (ou vários) bancos de dados Web SQL que contêm dados relevantes para seu app. Na captura de tela abaixo, você vê um banco de dados de exemplo chamado mydatabase com uma tabela de tempestades que mapeia humores para gravidades. O Chrome DevTools permite conferir bancos de dados do Web SQL para depuração, como mostrado na captura de tela a seguir.

Um banco de dados Web SQL inspecionado no DevTools do Chrome. O banco de dados é chamado mydatabase e hospeda uma tabela com três colunas: ID da linha, humor e gravidade. Há três linhas de dados de amostra.

Como traduzir o banco de dados Web SQL para instruções SQL

Para migrar os dados de maneira transparente para o usuário, ou seja, sem exigir que ele execute uma das etapas de migração por conta própria, os dados no banco de dados precisam ser convertidos de volta nas instruções SQL originais que os criaram. Esse desafio surgiu antes, e o script de migração usado neste artigo (mywebsqldump.js) é baseado em uma biblioteca da comunidade chamada websqldump.js, com alguns pequenos ajustes. O exemplo de código a seguir mostra o código necessário para converter o banco de dados mydatabase da Web SQL em um conjunto de instruções SQL.

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

A execução desse código resulta na string de instruções SQL abaixo.

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

Como importar os dados para o SQLite Wasm

Tudo o que resta é executar esses comandos SQL no contexto do SQLite Wasm. Para ver todos os detalhes sobre a configuração do SQLite Wasm, consulte o artigo SQLite Wasm no navegador apoiado pelo sistema de arquivos privados de origem (link em inglês), mas a essência está novamente abaixo. Lembre-se de que esse código precisa ser executado em um worker (que a biblioteca cria automaticamente para você), com os cabeçalhos HTTP necessários definidos corretamente. Você pode instalar o pacote @sqlite.org/sqlite-wasm a partir do 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);
  }
})();

Depois de executar esse código, inspecione o arquivo do banco de dados importado com a extensão OPFS Explorer do Chrome DevTools. Agora há dois arquivos, um com o banco de dados real e outro com as informações de registro em diário. Esses dois arquivos residem no sistema de arquivos particular de origem. Por isso, é necessário usar a extensão OPFS Explorer para visualizá-los.

Inspeção do sistema de arquivos privados de origem com o OPFS Explorer no Chrome DevTools. Há dois arquivos, um chamado mydatabase.db e outro chamado mydatabase.db-journal.

Para verificar se os dados importados são iguais aos dados iniciais do Web SQL, clique no arquivo mydatabase.db. A extensão OPFS Explorer vai mostrar uma caixa de diálogo Save File que permite salvar o arquivo no sistema de arquivos visível ao usuário. Com o arquivo do banco de dados salvo, use um app visualizador SQLite para explorar os dados. Os Destaques da API Project Fugu apresentam vários apps para trabalhar com o SQLite no navegador (link em inglês). Por exemplo, o Sqlime — SQLite Playground permite abrir um arquivo de banco de dados SQLite no disco rígido e executar consultas no banco de dados. Como mostrado na captura de tela abaixo, a tabela de tempestade foi importada corretamente para o SQLite.

Explorar o arquivo mydatabase.db na ferramenta Sqlime SQLite Playground. O app é mostrado com a estrela de seleção da consulta SQL do limite de chuvas em que 10 está em execução, resultando nas três linhas dos dados de amostra iniciais do Web SQL.

Liberar armazenamento do Web SQL

Embora seja (talvez surpreendentemente) impossível excluir um banco de dados do Web SQL, você ainda deve liberar espaço de armazenamento descartando as tabelas obsoletas do Web SQL depois de migrar os dados para o SQLite Wasm. Para listar todas as tabelas em um banco de dados Web SQL e soltá-las usando JavaScript, use o código como no snippet a seguir:

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

Trabalhar com os dados após a migração

Depois de migrar os dados, trabalhe com os dados conforme descrito neste Exemplo de código de introdução. Consulte a referência da API SQLite Wasm para mais detalhes. Vale lembrar que é necessário acessar o SQLite Wasm de um worker se você usa o sistema de arquivos particular de origem como back-end de armazenamento.

Testar

Esta demonstração permite preencher um banco de dados Web SQL com dados de amostra e, em seguida, despejar esses dados como instruções SQL, que depois são importadas para o SQLite Wasm com base no sistema de arquivos particular de origem. Por fim, libere espaço excluindo os dados obsoletos do Web SQL. Confira o código-fonte para ver a implementação completa, incluindo o arquivo mywebsqldump.js com patch.

O app de demonstração em web-sql-to-sqlite-wasm.glitch.me.

Conclusões

A migração dos bancos de dados Web SQL para o SQLite Wasm apoiado pelo sistema de arquivos privados de origem é possível de maneira transparente para os usuários. Eles não perceberão que os dados agora estão hospedados no sistema de arquivos particular de origem em um banco de dados SQLite e não residem mais no SQL da Web. Em geral, a migração do Web SQL para o SQLite é uma etapa necessária para desenvolvedores da Web que querem garantir a estabilidade e escalonabilidade a longo prazo dos aplicativos. Embora o processo exija algum esforço inicial, os benefícios de uma solução de banco de dados mais robusta, flexível e, acima de tudo, preparada para o futuro fazem com que esse investimento valha a pena.