sqlocal
Version:
SQLocal makes it easy to run SQLite3 in the browser, backed by the origin private file system.
175 lines • 5.71 kB
JavaScript
import { normalizeDatabaseFile } from '../lib/normalize-database-file.js';
export class SQLiteMemoryDriver {
constructor(sqlite3InitModule) {
Object.defineProperty(this, "sqlite3InitModule", {
enumerable: true,
configurable: true,
writable: true,
value: sqlite3InitModule
});
Object.defineProperty(this, "sqlite3", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "db", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "config", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "pointers", {
enumerable: true,
configurable: true,
writable: true,
value: []
});
Object.defineProperty(this, "storageType", {
enumerable: true,
configurable: true,
writable: true,
value: 'memory'
});
}
async init(config) {
const { databasePath } = config;
const flags = this.getFlags(config);
if (!this.sqlite3InitModule) {
const { default: sqlite3InitModule } = await import('@sqlite.org/sqlite-wasm');
this.sqlite3InitModule = sqlite3InitModule;
}
if (!this.sqlite3) {
this.sqlite3 = await this.sqlite3InitModule();
}
if (this.db) {
await this.destroy();
}
this.db = new this.sqlite3.oo1.DB(databasePath, flags);
this.config = config;
}
async exec(statement) {
if (!this.db)
throw new Error('Driver not initialized');
return this.execOnDb(this.db, statement);
}
async execBatch(statements) {
if (!this.db)
throw new Error('Driver not initialized');
const results = [];
this.db.transaction((tx) => {
for (let statement of statements) {
const statementData = this.execOnDb(tx, statement);
results.push(statementData);
}
});
return results;
}
async isDatabasePersisted() {
return false;
}
async getDatabaseSizeBytes() {
const sizeResult = await this.exec({
sql: `SELECT page_count * page_size AS size
FROM pragma_page_count(), pragma_page_size()`,
method: 'get',
});
const size = sizeResult?.rows?.[0];
if (typeof size !== 'number') {
throw new Error('Failed to query database size');
}
return size;
}
async createFunction(fn) {
if (!this.db)
throw new Error('Driver not initialized');
switch (fn.type) {
case 'callback':
case 'scalar':
this.db.createFunction({
name: fn.name,
xFunc: (_, ...args) => fn.func(...args),
arity: -1,
});
break;
case 'aggregate':
this.db.createFunction({
name: fn.name,
xStep: (_, ...args) => fn.func.step(...args),
xFinal: (_, ...args) => fn.func.final(...args),
arity: -1,
});
break;
}
}
async import(database) {
if (!this.sqlite3 || !this.db || !this.config) {
throw new Error('Driver not initialized');
}
const data = await normalizeDatabaseFile(database, 'buffer');
const dataPointer = this.sqlite3.wasm.allocFromTypedArray(data);
this.pointers.push(dataPointer);
const resultCode = this.sqlite3.capi.sqlite3_deserialize(this.db, 'main', dataPointer, data.byteLength, data.byteLength, this.config.readOnly
? this.sqlite3.capi.SQLITE_DESERIALIZE_READONLY
: this.sqlite3.capi.SQLITE_DESERIALIZE_RESIZEABLE);
this.db.checkRc(resultCode);
}
async export() {
if (!this.sqlite3 || !this.db) {
throw new Error('Driver not initialized');
}
return {
name: 'database.sqlite3',
data: this.sqlite3.capi.sqlite3_js_db_export(this.db),
};
}
async clear() { }
async destroy() {
this.closeDb();
this.pointers.forEach((pointer) => this.sqlite3?.wasm.dealloc(pointer));
this.pointers = [];
}
getFlags(config) {
const { readOnly, verbose } = config;
const parts = [readOnly === true ? 'r' : 'cw', verbose === true ? 't' : ''];
return parts.join('');
}
execOnDb(db, statement) {
const statementData = {
rows: [],
columns: [],
};
const rows = db.exec({
sql: statement.sql,
bind: statement.params,
returnValue: 'resultRows',
rowMode: 'array',
columnNames: statementData.columns,
});
switch (statement.method) {
case 'run':
break;
case 'get':
statementData.rows = rows[0] ?? [];
break;
case 'all':
default:
statementData.rows = rows;
break;
}
return statementData;
}
closeDb() {
if (this.db) {
this.db.close();
this.db = undefined;
}
}
}
//# sourceMappingURL=sqlite-memory-driver.js.map