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

Com o SQLite Wasm com suporte do sistema de arquivos particular 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 SQL da Web para o SQLite Wasm.

Plano de fundo obrigatório

A postagem Como descontinuar e remover o Web SQL anunciou a descontinuação da tecnologia de banco de dados do Web SQL. Embora a tecnologia em si possa ser descontinuada, os casos de uso abordados por ela não são. Por isso, o post de acompanhamento SQLite Wasm no navegador com suporte do sistema de arquivos particular da origem descreve um conjunto de tecnologias de substituição com base no banco de dados SQLite, compilado para WebAssembly (Wasm) e com suporte do sistema de arquivos particular da 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 do SQL da Web para o SQLite Wasm, com o banco de dados SQLite apoiado pelo sistema de arquivos particular de origem. Isso pode servir de base para seu próprio código personalizado para sua necessidade de migração do SQL da Web.

Os bancos de dados do SQL da Web que serão migrados

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

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

Como converter o banco de dados do Web SQL em instruções SQL

Para migrar os dados de forma transparente para o usuário, ou seja, sem exigir que ele realize as etapas de migração por conta própria, as partes dos dados no banco de dados precisam ser traduzidas de volta para as instruções SQL originais que as criaram. Esse desafio já apareceu antes, e o script de migração usado neste artigo (mywebsqldump.js) é baseado em uma biblioteca da comunidade chamada websqldump.js, com alguns ajustes menores. O exemplo de código a seguir mostra o código necessário para traduzir o banco de dados do Web SQL mydatabase para 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

O que resta é executar esses comandos SQL no contexto do SQLite Wasm. Para todos os detalhes sobre a configuração do SQLite Wasm, consulte o artigo SQLite Wasm no navegador com suporte do sistema de arquivos particular da Origin. Confira a essência abaixo. Esse código precisa ser executado em um worker (que a biblioteca cria automaticamente para você), com os cabeçalhos HTTP obrigatórios definidos corretamente. É possível instalar o pacote @sqlite.org/sqlite-wasm pelo 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 de 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 informações de registro em diário. Esses dois arquivos estão no sistema de arquivos particular de origem. Portanto, é necessário usar a extensão do OPFS Explorer para acessá-los.

Inspeção do sistema de arquivos particular de origem com o OPFS Explorer do 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 SQL do Web, clique no arquivo mydatabase.db. A extensão do OPFS Explorer vai mostrar uma caixa de diálogo Save File para que você salve o arquivo no sistema de arquivos visível para o usuário. Com o arquivo do banco de dados salvo, use um app de visualização SQLite para analisar os dados. O Project Fugu API Showcase (link em inglês) apresenta vários apps para trabalhar com SQLite no navegador. 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 você pode ver na captura de tela abaixo, a tabela de tempestade foi importada corretamente para o SQLite.

Explorando o arquivo mydatabase.db na ferramenta Sqlime SQLite Playground. O app é mostrado com a consulta SQL "select star from rainstorms limit 10" sendo executada, resultando nas três linhas dos dados de amostra iniciais do Web SQL.

Liberar o armazenamento do Web SQL

Embora seja impossível excluir um banco de dados do SQL da Web (talvez seja surpreendente), ainda é possível liberar algum armazenamento ao excluir as tabelas do SQL da Web que estão obsoletas depois de migrar os dados para o SQLite Wasm. Para listar todas as tabelas em um banco de dados do Web SQL e excluí-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);
  }
};

Como trabalhar com os dados após a migração

Depois de migrar os dados, trabalhe com eles conforme descrito neste exemplo de código de início. Consulte a referência da API SQLite Wasm para mais detalhes. Novamente, você precisa acessar o SQLite Wasm em um worker se usar o sistema de arquivos particular de origem como back-end de armazenamento.

Testar

Este demonstrativo permite preencher um banco de dados do Web SQL com dados de amostra e, em seguida, fazer o dump dos dados do Web SQL como instruções SQL, que são importados para o SQLite Wasm com o suporte do sistema de arquivos particular de origem. Por fim, você libera espaço de armazenamento excluindo os dados obsoletos do Web SQL. Confira o código-fonte para a implementação completa, incluindo o arquivo mywebsqldump.js corrigido.

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

Conclusões

É possível migrar seus bancos de dados SQL da Web para o SQLite Wasm com o suporte do sistema de arquivos particular de origem de uma forma transparente para os usuários. Os usuários não vão notar que os dados agora estão hospedados no sistema de arquivos particular de origem em um banco de dados SQLite e não mais no Web SQL. No geral, a migração do Web SQL para o SQLite é uma etapa necessária para desenvolvedores da Web que querem garantir a estabilidade e a escalabilidade de 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 o investimento valha a pena.