Utilizza SQLite per gestire in modo efficiente tutte le tue esigenze di archiviazione sul web.
SQLite è un sistema di gestione di database relazionali incorporato, leggero, open source e molto diffuso. Molti sviluppatori lo utilizzano per archiviare i dati in modo strutturato e facile da usare. Grazie alle sue dimensioni ridotte e ai bassi requisiti di memoria, SQLite viene spesso utilizzato come motore di database in dispositivi mobili, applicazioni desktop e browser web.
Una delle caratteristiche principali di SQLite è che è un database serverless, il che significa che non richiede un processo server separato per funzionare. Il database viene invece archiviato in un unico file sul dispositivo dell'utente, il che ne facilita l'integrazione nelle applicazioni.
SQLite basato su Web Assembly
Esistono diverse versioni non ufficiali di SQLite basate su Web Assembly (Wasm), che ne consentono l'utilizzo nei browser web, ad esempio, sql.js. Il progetto secondario sqlite3 WASM/JS è il primo sforzo ufficialmente associato al progetto SQLite che rende le build Wasm della libreria membri consolidati della famiglia di artefatti SQLite supportati. Gli obiettivi concreti di questo progetto includono:
- Associazione di un'API sqlite3 di basso livello che sia il più possibile simile a quella C in termini di utilizzo.
- Un'API orientata agli oggetti di livello superiore, più simile a sql.js e implementazioni in stile Node.js, che comunica direttamente con l'API di basso livello. Questa API deve essere utilizzata dallo stesso thread dell'API di basso livello.
- Un'API basata sui worker che comunica con le API precedenti tramite messaggi worker. Questo è destinato all'uso nel thread principale, con le API di livello inferiore installate in un thread di lavoro e comunicare con loro tramite i messaggi del worker.
- Una variante basata su Promise dell'API Worker che nasconde completamente all'utente gli aspetti della comunicazione tra thread.
- Supporto per l'archiviazione lato client persistente utilizzando le API JavaScript disponibili, incluso l'Origin Private File System (OPFS).
Utilizzo di SQLite Wasm con il backend di persistenza Origin Private File System
Installare la libreria da npm
Installa il pacchetto @sqlite.org/sqlite-wasm da npm con il seguente comando:
npm install @sqlite.org/sqlite-wasm
Origin Private File System
Origin Private File System (OPFS, parte dell'API File System Access) è arricchito da una superficie speciale che consente un accesso molto efficiente ai dati. Questa nuova superficie si differenzia da quelle esistenti in quanto offre l'accesso in scrittura esclusivo e in loco ai contenuti di un file. Questa modifica, insieme alla possibilità di leggere in modo coerente le modifiche non scaricate e alla disponibilità di una variante sincrona su worker dedicati, migliora significativamente le prestazioni e sblocca nuovi casi d'uso.
Come puoi immaginare, l'ultimo punto degli obiettivi del progetto, Supporto per
l'archiviazione lato client persistente utilizzando le API JavaScript disponibili, è accompagnato da
rigidi requisiti di rendimento per quanto riguarda la persistenza dei dati nel file di database.
È qui che entra in gioco Origin Private File System e, più nello specifico, il metodo
createSyncAccessHandle()
degli oggetti
FileSystemFileHandle
. Questo metodo restituisce una promessa che si risolve in un oggetto
FileSystemSyncAccessHandle
che può essere utilizzato per leggere e scrivere in modo sincrono in un file. La natura sincrona di questo metodo offre vantaggi in termini di prestazioni, ma pertanto è utilizzabile solo all'interno di Web Worker dedicati per i file all'interno di Origin Private File System, in modo che il thread principale non possa essere bloccato.
Impostazione delle intestazioni richieste
Tra gli altri file, l'archivio SQLite Wasm scaricato contiene i file sqlite3.js
e sqlite3.wasm
, che costituiscono la build WASM/JS di sqlite3. La directory jswasm
contiene gli artefatti sqlite3 principali e la directory di primo livello
contiene app dimostrative e di test. I browser non pubblicano file Wasm dagli URL file://
, quindi tutte le app che crei con questo linguaggio richiedono un server web e questo server deve includere le seguenti intestazioni nella risposta quando pubblica i file:
Cross-Origin-Opener-Policy
impostato sull'istruzionesame-origin
, che isola il contesto di navigazione esclusivamente nei documenti della stessa origine. I documenti multiorigine non vengono caricati nello stesso contesto di navigazione.Cross-Origin-Embedder-Policy
impostato sulla direttivarequire-corp
, in modo che un documento possa caricare risorse solo dalla stessa origine o risorse contrassegnate esplicitamente come caricabili da un'altra origine.
Il motivo di queste intestazioni è che SQLite Wasm dipende da
SharedArrayBuffer
,
e l'impostazione di queste intestazioni fa parte dei suoi
requisiti di sicurezza.
Se esamini il traffico con DevTools, dovresti trovare le seguenti informazioni:
Test della velocità
Il team di SQLite ha eseguito alcuni benchmark sulla propria implementazione di WebAssembly rispetto all'API SQL web deprecata. Questi benchmark mostrano che SQLite Wasm è in genere veloce quanto SQL web. A volte è un po' più lento, a volte un po' più veloce. Visualizza tutti i dettagli nella pagina dei risultati.
Esempio di codice per iniziare
Come accennato in precedenza, SQLite Wasm con il backend di persistenza Origin Private File System deve essere eseguito da un contesto worker. La buona notizia è che la libreria si occupa automaticamente di tutto questo e puoi utilizzarla direttamente dal thread principale.
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
Guarda il codice riportato sopra in azione nella demo. Assicurati di dare un'occhiata al codice sorgente su GitHub. Nota che la versione incorporata di seguito non utilizza il backend OPFS, ma quando apri la demo in una scheda separata, lo fa.
Eseguire il debug del file system privato di origine
Per eseguire il debug dell'output del file system privato dell'origine di SQLite Wasm, utilizza l'estensione di Chrome OPFS Explorer.
Dopo aver installato l'estensione, apri Chrome DevTools, seleziona la scheda OPFS Explorer e potrai ispezionare ciò che SQLite Wasm scrive nel file system privato dell'origine.
Se selezioni uno dei file nella finestra di OPFS Explorer in DevTools, puoi salvarlo sul disco locale. Puoi quindi utilizzare un'app come SQLite Viewer per esaminare il database e assicurarti che SQLite Wasm funzioni effettivamente come promesso.
Ricevere assistenza e fornire un feedback
SQLite Wasm è sviluppato e gestito dalla community SQLite. Per ricevere assistenza e fornire feedback, cerca e pubblica nel forum di assistenza. La documentazione completa è disponibile sul sito di SQLite.