86 lines
3.3 KiB
JavaScript
86 lines
3.3 KiB
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(sqlite3InitModule) {
|
|
super(sqlite3InitModule);
|
|
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;
|
|
this.initWriteHook();
|
|
}
|
|
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();
|
|
this.writeCallbacks.clear();
|
|
}
|
|
}
|
|
//# sourceMappingURL=sqlite-opfs-driver.js.map
|