sqlocal
Version:
SQLocal makes it easy to run SQLite3 in the browser, backed by the origin private file system.
84 lines • 3.29 kB
JavaScript
import { normalizeDatabaseFile } from '../lib/normalize-database-file.js';
import { parseDatabasePath } from '../lib/parse-database-path.js';
import { SQLiteMemoryDriver } from './sqlite-memory-driver.js';
export class SQLiteOpfsDriver extends SQLiteMemoryDriver {
constructor() {
super(...arguments);
Object.defineProperty(this, "storageType", {
enumerable: true,
configurable: true,
writable: true,
value: 'opfs'
});
}
async init(config) {
const { databasePath } = config;
const flags = this.getFlags(config);
if (!databasePath) {
throw new Error('No databasePath specified');
}
if (!this.sqlite3InitModule) {
const { default: sqlite3InitModule } = await import('@sqlite.org/sqlite-wasm');
this.sqlite3InitModule = sqlite3InitModule;
}
if (!this.sqlite3) {
this.sqlite3 = await this.sqlite3InitModule();
}
if (!('opfs' in this.sqlite3)) {
throw new Error('OPFS not available');
}
if (this.db) {
await this.destroy();
}
this.db = new this.sqlite3.oo1.OpfsDb(databasePath, flags);
this.config = config;
}
async isDatabasePersisted() {
return navigator.storage?.persisted();
}
async import(database) {
if (!this.sqlite3 || !this.config?.databasePath) {
throw new Error('Driver not initialized');
}
await this.destroy();
const data = await normalizeDatabaseFile(database, 'callback');
await this.sqlite3.oo1.OpfsDb.importDb(this.config.databasePath, data);
}
async export() {
if (!this.db || !this.config?.databasePath) {
throw new Error('Driver not initialized');
}
let name, data;
const path = parseDatabasePath(this.config.databasePath);
const { directories, getDirectoryHandle } = path;
name = path.fileName;
const tempFileName = `backup-${Date.now()}--${name}`;
const tempFilePath = `${directories.join('/')}/${tempFileName}`;
this.db.exec({ sql: 'VACUUM INTO ?', bind: [tempFilePath] });
const dirHandle = await getDirectoryHandle();
const fileHandle = await dirHandle.getFileHandle(tempFileName);
const file = await fileHandle.getFile();
data = await file.arrayBuffer();
await dirHandle.removeEntry(tempFileName);
return { name, data };
}
async clear() {
if (!this.config?.databasePath)
throw new Error('Driver not initialized');
await this.destroy();
const { getDirectoryHandle, fileName, tempFileNames } = parseDatabasePath(this.config.databasePath);
const dirHandle = await getDirectoryHandle();
const fileNames = [fileName, ...tempFileNames];
await Promise.all(fileNames.map(async (name) => {
return dirHandle.removeEntry(name).catch((err) => {
if (!(err instanceof DOMException && err.name === 'NotFoundError')) {
throw err;
}
});
}));
}
async destroy() {
this.closeDb();
}
}
//# sourceMappingURL=sqlite-opfs-driver.js.map