SQLite-Wasm im Browser, der vom ursprünglichen privaten Dateisystem gesichert wurde

Mit SQLite können Sie alle Ihre Speicheranforderungen im Web leistungsstark bewältigen.

SQLite ist ein beliebtes, Open-Source-System zur Verwaltung relationaler Datenbanken, das sich leicht einbetten lässt. Viele Entwickler verwenden es, um Daten auf strukturierte und nutzerfreundliche Weise zu speichern. Aufgrund der geringen Größe und der geringen Speicheranforderungen wird SQLite häufig als Datenbankmodul in mobilen Geräten, Desktopanwendungen und Webbrowsern eingesetzt.

Eines der Hauptmerkmale von SQLite ist, dass es sich um eine serverlose Datenbank handelt, d. h., für den Betrieb ist kein separater Serverprozess erforderlich. Stattdessen wird die Datenbank in einer einzigen Datei auf dem Gerät des Nutzers gespeichert, was die Integration in Anwendungen erleichtert.

SQLite-Logo

SQLite basierend auf Web Assembly

Es gibt eine Reihe inoffizieller SQLite-Versionen, die auf Web Assembly (Wasm) basieren und die Verwendung in Webbrowsern ermöglichen, z. B. sql.js. Das sqlite3 WASM/JS-Unterprojekt ist die erste Initiative, die offiziell mit dem SQLite-Projekt in Verbindung steht. Damit sind Wasm-Builds der Bibliothek nun Teil der unterstützten SQLite-Entwicklungsprodukte. Zu den konkreten Zielen dieses Projekts gehören:

  • Binden einer Squarelite3-API auf niedriger Ebene, die für die Nutzung so nah wie möglich an der C-1 liegt.
  • Eine objektorientierte API höherer Ebene, die eher mit sql.js und Implementierungen im Node.js-Stil vergleichbar ist und direkt mit der Low-Level-API kommuniziert. Diese API muss aus demselben Thread wie die Low-Level-API verwendet werden.
  • Eine Worker-basierte API, die über Worker-Nachrichten mit den vorherigen APIs kommuniziert. Diese API ist für die Verwendung im Haupt-Thread vorgesehen. Die APIs der unteren Ebene werden in einem Worker-Thread installiert und über Worker-Nachrichten mit ihnen kommuniziert.
  • Eine Promise-basierte Variante der Worker API, die die Thread-übergreifenden Kommunikationsaspekte vor dem Nutzer vollständig verbirgt.
  • Unterstützung für persistenten clientseitigen Speicher mithilfe verfügbarer JavaScript APIs, einschließlich des Origin Private File Systems (OPFS).

SQLite Wasm mit dem Origin Private File System-Persistenz-Backend verwenden

Bibliothek über npm installieren

Installieren Sie das Paket @sqlite.org/sqlite-wasm von npm mit dem folgenden Befehl:

npm install @sqlite.org/sqlite-wasm

Origin Private File System

Das Origin Private File System (OPFS, Teil der File System Access API) wird durch eine spezielle Oberfläche ergänzt, die einen sehr leistungsfähigen Zugriff auf Daten ermöglicht. Diese neue Oberfläche unterscheidet sich von den vorhandenen Oberflächen dadurch, dass sie einen lokalen und exklusiven Schreibzugriff auf die Inhalte einer Datei bietet. Diese Änderung, die Möglichkeit, nicht gepufferte Änderungen konsistent zu lesen, und die Verfügbarkeit einer synchronen Variante auf dedizierten Workern verbessern die Leistung erheblich und ermöglichen neue Anwendungsfälle.

Wie Sie sich vorstellen können, ist der letzte Punkt der Projektziele, die Unterstützung für persistenten clientseitigen Speicher mithilfe der verfügbaren JavaScript APIs, mit strengen Leistungsanforderungen für das Speichern von Daten in der Datenbankdatei verbunden. Hier kommt das Origin Private File System und genauer gesagt die Methode createSyncAccessHandle() von FileSystemFileHandle-Objekten ins Spiel. Diese Methode gibt ein Promise zurück, das in ein FileSystemSyncAccessHandle-Objekt aufgelöst wird, mit dem synchron aus einer Datei gelesen und in eine Datei geschrieben werden kann. Der synchrone Charakter dieser Methode bringt Leistungsvorteile mit sich. Sie kann jedoch nur in dedizierten Web Workers für Dateien innerhalb des privaten Dateisystems des Ursprungsservers verwendet werden, sodass der Hauptthread nicht blockiert werden kann.

Erforderliche Header festlegen

Das heruntergeladene SQLite-Wasm-Archiv enthält unter anderem die Dateien sqlite3.js und sqlite3.wasm, die den sqlite3-Wasm/JS-Build bilden. Das Verzeichnis jswasm enthält die Squarelite3-Kernergebnisse und das Verzeichnis der obersten Ebene enthält Demonstrations- und Testanwendungen. Browser stellen keine Wasm-Dateien von file://-URLs bereit. Daher benötigen alle Anwendungen, die Sie damit erstellen, einen Webserver. Dieser Server muss beim Bereitstellen der Dateien in der Antwort die folgenden Header enthalten:

  • Cross-Origin-Opener-Policy ist auf die same-origin-Anweisung festgelegt, wodurch der Browserkontext ausschließlich auf Dokumente desselben Ursprungs beschränkt wird. Dokumente verschiedener Herkunft werden nicht im selben Browserkontext geladen.
  • Cross-Origin-Embedder-Policy ist auf die require-corp-Richtlinie festgelegt, sodass in einem Dokument nur Ressourcen aus demselben Ursprung oder Ressourcen geladen werden können, die ausdrücklich als von einem anderen Ursprung ladbar gekennzeichnet sind.

Der Grund für diese Header ist, dass SQLite Wasm von SharedArrayBuffer abhängt und die Einstellung dieser Header Teil der Sicherheitsanforderungen ist.

Wenn Sie den Traffic mit den Entwicklertools prüfen, sollten Sie die folgenden Informationen sehen:

Die beiden oben genannten Header „Cross-Origin-Embedder-Policy“ und „Cross-Origin-Opener-Policy“ werden in den Chrome-Entwicklertools hervorgehoben.

Geschwindigkeitstest

Das SQLite-Team hat einige Benchmarks für seine WebAssembly-Implementierung im Vergleich zur eingestellten Web SQL-Version durchgeführt. Diese Benchmarks zeigen, dass SQLite Wasm im Allgemeinen etwa so schnell ist wie Web SQL. Manchmal ist es etwas langsamer, manchmal etwas schneller. Alle Details finden Sie auf der Ergebnisseite.

Codebeispiel für den Einstieg

Wie bereits erwähnt, muss SQLite Wasm mit dem Origin Private File System-Persistenz-Backend in einem Worker-Kontext ausgeführt werden. Die gute Nachricht ist, dass die Bibliothek all das automatisch für Sie erledigt und Sie sie direkt über den Hauptthread verwenden können.

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

Demo

In der Demo können Sie sich den obigen Code in Aktion ansehen. Sehen Sie sich den Quellcode auf Glitch an. Beachten Sie, dass in der eingebetteten Version unten das OPFS-Backend nicht verwendet wird. Wenn Sie die Demo jedoch in einem separaten Tab öffnen, wird es verwendet.

Origin Private File System debuggen

Verwenden Sie die Chrome-Erweiterung OPFS Explorer, um die Ausgabe des Origin Private File Systems von SQLite Wasm zu debuggen.

OPFS Explorer im Chrome Web Store

Öffnen Sie nach der Installation der Erweiterung die Chrome-Entwicklertools und wählen Sie den Tab OPFS Explorer aus. Sie können dann prüfen, was SQLite Wasm in das Origin Private File System schreibt.

OPFS Explorer-Chrome-Erweiterung, die die Struktur des Origin Private File Systems der Demo-App zeigt

Wenn du eine der Dateien im OPFS-Explorer-Fenster in den Entwicklertools auswählst, kannst du sie auf dem lokalen Laufwerk speichern. Sie können dann eine Anwendung wie SQLite Viewer verwenden, um die Datenbank zu überprüfen, um sich zu vergewissern, dass SQLite Wasm tatsächlich wie versprochen funktioniert.

SQLite Viewer App, mit der eine Datenbankdatei aus der SQLite Wasm-Demo geöffnet wird.

Hilfe erhalten und Feedback geben

SQLite Wasm wird von der SQLite-Community entwickelt und gepflegt. Im Supportforum können Sie Hilfe erhalten und Feedback geben. Die vollständige Dokumentation finden Sie auf der SQLite-Website.