SQLite Wasm w przeglądarce korzystającej z prywatnego systemu plików źródła

Dzięki SQLite możesz wydajnie zarządzać wszystkimi zasobami miejsca na dane w internecie.

SQLite to popularny, lekki, wbudowany system zarządzania relacyjną bazą danych oparty na open source. Wielu deweloperów używa go do przechowywania danych w sposób uporządkowany i łatwy w użyciu. Ze względu na niewielki rozmiar i małe wymagania dotyczące pamięci SQLite jest często wykorzystywany jako silnik bazy danych na urządzeniach mobilnych, w aplikacjach na komputery i w przeglądarkach internetowych.

Jedną z kluczowych funkcji SQLite jest to, że jest to baza danych bez serwera, co oznacza, że do działania nie wymaga osobnego procesu serwera. Zamiast tego jest przechowywana w jednym pliku na urządzeniu użytkownika, co ułatwia integrację z aplikacjami.

Logo SQLite

SQLite oparty na WebAssembly

Istnieje wiele nieoficjalnych wersji SQLite opartych na WebAssembly (Wasm), które umożliwiają korzystanie z niej w przeglądarkach internetowych, np. sql.js. Podprojekt WASM/JS sqlite3 to pierwszy projekt oficjalnie powiązany z projektem SQLite polegającym na tworzeniu kompilacji Wasm pochodzących z istniejących w bibliotece członków rodziny obsługiwanych materiałów SQLite. Konkretne cele tego projektu to:

  • Powiązanie interfejsu API sqlite3 niskiego poziomu, który jest jak najbardziej zbliżony do interfejsu C pod względem użycia.
  • interfejs API zorientowany na obiekty, który jest wyższym poziomem interfejsu sql.js i implementacji w stylu Node.js, który bezpośrednio komunikuje się z interfejsem niskiego poziomu; Z tego interfejsu API należy korzystać w tym samym wątku co interfejs API niskiego poziomu.
  • Interfejs API oparty na Workerze, który komunikuje się z poprzednimi interfejsami API za pomocą wiadomości Workera. Jest on przeznaczony do użycia w głównym wątku, z interfejsami API niskiego poziomu zainstalowanymi w wątku Worker, i komunikowania się z nimi za pomocą wiadomości Worker.
  • Oparty na obietnicy wariant interfejsu Worker API, który całkowicie ukrywa przed użytkownikiem aspekty komunikacji między wątkami.
  • Obsługa trwałej pamięci po stronie klienta przy użyciu dostępnych interfejsów API JavaScript, w tym Origin Private File System (OPFS).

Korzystanie z SQLite Wasm z backendem trwałości prywatnego systemu plików Origin

Instalowanie biblioteki z npm

Zainstaluj pakiet @sqlite.org/sqlite-wasm z npm za pomocą tego polecenia:

npm install @sqlite.org/sqlite-wasm

System plików prywatnych Origin

System plików Origin Private File System (OPFS, część interfejsu File System Access API) został wzbogacony o specjalną powierzchnię, która zapewnia bardzo wydajny dostęp do danych. Ta nowa opcja różni się od dotychczasowych tym, że oferuje dostęp do treści pliku w miejscu i z wyłącznością. Ta zmiana wraz z możliwością spójnego odczytu niezmienionych modyfikacji i dostępnością synchronicznego wariantu w przypadku dedykowanych instancji roboczych znacznie poprawia wydajność i pozwala odblokować nowe przypadki użycia.

Jak możesz sobie wyobrazić, ostatni punkt celów projektu, czyli obsługa trwałego magazynu po stronie klienta za pomocą dostępnych interfejsów JavaScript API, wiąże się ze ścisłymi wymaganiami dotyczącymi wydajności w zakresie trwałego przechowywania danych w pliku bazy danych. Właśnie w tym miejscu do akcji wkracza prywatny system plików Origin, a ściślej mówiąc metoda createSyncAccessHandle()FileSystemFileHandleobiektów. Ta metoda zwraca obietnicę, która zwraca obiekt FileSystemSyncAccessHandle, który może być używany do synchronicznego odczytu i zapisu pliku. Asychronicy charakter tej metody zapewnia lepsze osiągi, ale można jej używać tylko w dedykowanych workerach sieciowych w przypadku plików w systemie plików prywatnych Origin, aby nie blokować wątku głównego.

Ustawianie wymaganych nagłówków

Pobrane archiwum SQLite Wasm zawiera m.in. pliki sqlite3.js i sqlite3.wasm, które stanowią wersję sqlite3 WASM/JS. Katalog jswasm zawiera podstawowe materiały dostarczane przez sqlite3, a katalog najwyższego poziomu zawiera aplikacje demonstracyjne i testowe. Przeglądarki nie będą udostępniać plików Wasm z adresów URL file://, więc aplikacje tworzone z ich użyciem wymagają serwera WWW. Serwer musi zawierać w odpowiedzi te nagłówki:

  • Cross-Origin-Opener-Policy ustawiona na dyrektywę same-origin, która izoluje kontekst przeglądania wyłącznie do dokumentów z tej samej domeny. Dokumenty z innych witryn nie są wczytywane w tym samym kontekście przeglądania.
  • Cross-Origin-Embedder-Policy ustawiony na dyrektywę require-corp, dzięki czemu dokument może wczytywać tylko zasoby z tego samego źródła lub zasoby wyraźnie oznaczone jako wczytywane z innego źródła.

Te nagłówki są potrzebne, ponieważ SQLite Wasm zależy od SharedArrayBuffer, a ustawianie tych nagłówków jest częścią wymagań dotyczących bezpieczeństwa.

Jeśli sprawdzisz ruch za pomocą Narzędzi deweloperskich, otrzymasz te informacje:

Dwa wspomniane wyżej nagłówki – Cross-Origin-Embedder-Policy i cross-Origin-Opener-Policy zaznaczone w Narzędziach deweloperskich w Chrome.

Speedtest

Zespół SQLite przeprowadził testy porównawcze swojej implementacji WebAssembly w porównaniu z wycofaną wersją Web SQL. Te testy porównawcze pokazują, że SQLite Wasm jest na ogół tak samo szybki jak Web SQL. Czasami jest to trochę wolniej, a czasami szybciej. Wszystkie szczegóły znajdziesz na stronie wyników.

Przykładowy kod na początek

Jak już wspomnieliśmy, backend instancji SQLite Wasm z prywatnym systemem plików punktu początkowego musi być uruchamiany w kontekście instancji roboczej. Dobrą wiadomością jest to, że biblioteka automatycznie zadba o wszystko za Ciebie i będziesz mieć do niej dostęp bezpośrednio z głównego wątku.

import { sqlite3Worker1Promiser } from '@sqlite.org/sqlite-wasm';

(async () => {
  try {
    console.log('Loading and initializing SQLite3 module...');

    const promiser = await new Promise((resolve) => {
      const _promiser = sqlite3Worker1Promiser({
        onready: () => {
          resolve(_promiser);
        },
      });
    });

    console.log('Done initializing. Running demo...');

    let response;

    response = await promiser('config-get', {});
    console.log('Running SQLite3 version', response.result.version.libVersion);

    response = await promiser('open', {
      filename: 'file:worker-promiser.sqlite3?vfs=opfs',
    });
    const { dbId } = response;
    console.log(
      'OPFS is available, created persisted database at',
      response.result.filename.replace(/^file:(.*?)\?vfs=opfs$/, '$1'),
    );

    await promiser('exec', { dbId, sql: 'CREATE TABLE IF NOT EXISTS t(a,b)' });
    console.log('Creating a table...');

    console.log('Insert some data using exec()...');
    for (let i = 20; i <= 25; ++i) {
      await promiser('exec', {
        dbId,
        sql: 'INSERT INTO t(a,b) VALUES (?,?)',
        bind: [i, i * 2],
      });
    }

    console.log('Query data with exec()');
    await promiser('exec', {
      dbId,
      sql: 'SELECT a FROM t ORDER BY a LIMIT 3',
      callback: (result) => {
        if (!result.row) {
          return;
        }
        console.log(result.row);
      },
    });

    await promiser('close', { dbId });
  } catch (err) {
    if (!(err instanceof Error)) {
      err = new Error(err.result.message);
    }
    console.error(err.name, err.message);
  }
})();

Prezentacja

Zobacz, jak działa kod powyżej, w prezentacji. Sprawdź kod źródłowy w Glitch. Zwróć uwagę, że poniższa wersja osadzona nie korzysta z backendu OPFS, ale po otwarciu wersji demonstracyjnej w oddzielnej karcie już tak.

Debugowanie prywatnego systemu plików Origin

Aby debugować dane wyjściowe systemu plików SQLite Wasm Origin Private File System, użyj rozszerzenia OPFS Explorer do Chrome.

OPFS Explorer w Chrome Web Store.

Po zainstalowaniu rozszerzenia otwórz Narzędzia deweloperskie w Chrome i wybierz kartę OPFS Explorer. Dzięki temu będziesz mieć możliwość sprawdzenia, co SQLite Wasm zapisuje w Origin Private File System.

Rozszerzenie do Chrome OPFS Explorer pokazujące strukturę prywatnego systemu plików punktu początkowego w aplikacji w wersji demonstracyjnej.

Jeśli w oknie Eksploratora OPFS w narzędziach dla deweloperów wybierzesz dowolny plik, możesz go zapisać na dysku lokalnym. Następnie możesz użyć aplikacji takiej jak SQLite Viewer, aby sprawdzić bazę danych i upewnić się, że SQLite Wasm działa zgodnie z obietnicą.

Aplikacja SQLite Viewer używana do otwierania pliku bazy danych z wersji demonstracyjnej SQLite Wasm.

Uzyskiwanie pomocy i przesyłanie opinii

Projekt SQLite Wasm został opracowany i utrzymywany przez społeczność SQLite. Aby uzyskać pomoc i przesłać opinię, wyszukaj na forum pomocy i opublikuj tam swój wpis. Pełna dokumentacja jest dostępna na stronie SQLite.