godot-sqlite-kysely
Version:
Kysely dialect for godot-sqlite. Adds SQLite support to Godot/GodotJS.
142 lines (141 loc) • 5.49 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.GodotSQLiteKyselyWorkerConnection = void 0;
const godot_worker_1 = require("godot.worker");
class GodotSQLiteKyselyWorkerConnection {
#nestedTransactionIndex = 0;
#queryCallbacks = new Map();
#queryIndex = 0;
#transferParameters = false;
#worker;
#workerPromise;
#postRequest(message) {
if (this.#transferParameters && message.type === 'query') {
this.#worker.postMessage(message, Array.isArray(message.parameters) ? message.parameters : [message.parameters]);
}
else {
this.#worker.postMessage(message);
}
}
constructor(config, workerModule) {
this.#transferParameters = config.transferQueries ?? false;
this.#worker = new godot_worker_1.JSWorker(workerModule);
this.#workerPromise = new Promise((resolve, reject) => {
this.#worker.onmessage = (response) => {
switch (response.type) {
case 'initializationError':
console.error(`Worker SQLite connection error: ${response}`);
this.#workerPromise = null;
reject(new Error(response.message));
break;
case 'initialized':
this.#workerPromise = null;
resolve();
break;
case 'queryError': {
const { id, message } = response;
const callback = this.#queryCallbacks.get(id);
if (!callback) {
console.error(`Received query error for unknown query index: ${id}`);
break;
}
callback(message);
break;
}
case 'queryResult': {
const { id, result } = response;
const callback = this.#queryCallbacks.get(id);
if (!callback) {
console.error(`Received query result for unknown query index: ${id}`);
break;
}
callback(result);
break;
}
case 'terminated':
break;
default:
console.error('Unhandled worker response: ' + JSON.stringify(response, null, 2));
break;
}
};
this.#worker.onready = () => {
this.#postRequest({
type: 'initialize',
config,
});
};
});
}
close() {
return new Promise((resolve, reject) => {
const previousOnMessage = this.#worker.onmessage;
this.#worker.onmessage = (response) => {
if (response.type === 'terminated') {
try {
this.#worker.terminate();
resolve();
}
catch (e) {
reject(e);
}
}
else {
previousOnMessage?.(response);
}
};
this.#postRequest({
type: 'terminate',
});
});
}
async #postQuery(query, parameters) {
if (this.#workerPromise) {
await this.#workerPromise;
}
const queryIndex = this.#queryIndex++;
return await new Promise((resolve, reject) => {
this.#queryCallbacks.set(queryIndex, (result) => {
this.#queryCallbacks.delete(queryIndex);
if (typeof result === 'string') {
const params = Array.isArray(parameters) ? parameters : [...parameters.proxy()];
reject(new Error(`${result}. Query: ${query} (${params.join(', ')}). `));
}
else {
resolve(result);
}
});
this.#postRequest({
type: 'query',
id: queryIndex,
query,
parameters,
});
});
}
executeQuery(compiledQuery) {
return this.#postQuery(compiledQuery.sql, compiledQuery.parameters);
}
streamQuery(_compiledQuery, _chunkSize) {
throw new Error('Streaming is not supported with SQLite3');
}
async beginTransaction() {
const savepointName = `sp${this.#nestedTransactionIndex++}`;
this.#postQuery(`savepoint ${savepointName}`, []);
}
async commitTransaction() {
if (this.#nestedTransactionIndex <= 0) {
throw new Error('No transactions in progress');
}
const savepointName = `sp${--this.#nestedTransactionIndex}`;
this.#postQuery(`release savepoint ${savepointName}`, []);
}
async rollbackTransaction() {
if (this.#nestedTransactionIndex <= 0) {
throw new Error('No transactions in progress');
}
const savepointName = `sp${--this.#nestedTransactionIndex}`;
this.#postQuery(`rollback to savepoint ${savepointName}`, []);
}
}
exports.GodotSQLiteKyselyWorkerConnection = GodotSQLiteKyselyWorkerConnection;