119 lines
2.6 KiB
JavaScript
119 lines
2.6 KiB
JavaScript
const { Worker } = require('worker_threads');
|
|
const utils = require('./utils');
|
|
const JembaDbChild = require('./JembaDbChild');
|
|
/* API methods:
|
|
openDb
|
|
closeDb
|
|
|
|
create
|
|
drop
|
|
|
|
open
|
|
openAll
|
|
close
|
|
closeAll
|
|
|
|
tableExists
|
|
getInfo
|
|
getDbSize
|
|
|
|
select
|
|
insert
|
|
update
|
|
delete
|
|
|
|
esc
|
|
*/
|
|
|
|
class JembaDbThread {
|
|
constructor() {
|
|
this.worker = null;
|
|
this.listeners = new Map();
|
|
this.requestId = 0;
|
|
|
|
const apiMethods = [
|
|
'create', 'drop', 'open', 'openAll', 'close', 'closeAll',
|
|
'tableExists', 'getDbInfo', 'getDbSize', 'select', 'insert', 'update', 'delete', 'dumpTables'
|
|
];
|
|
|
|
for (const action of apiMethods) {
|
|
this[action] = async(query) => this._action(action, query);
|
|
}
|
|
}
|
|
|
|
_terminate() {
|
|
if (this.worker) {
|
|
for (const listener of this.listeners.values()) {
|
|
listener({error: 'Worker terminated'});
|
|
}
|
|
this.worker.terminate();
|
|
}
|
|
this.worker = null;
|
|
}
|
|
|
|
_runWoker() {
|
|
//const worker = new Worker(`${__dirname}/JembaDbChild.js`);
|
|
const worker = new Worker(JembaDbChild, {eval: true});
|
|
|
|
worker.on('message', (mes) => {
|
|
const listener = this.listeners.get(mes.requestId);
|
|
if (listener)
|
|
listener(mes);
|
|
});
|
|
|
|
worker.on('error', (err) => {
|
|
console.error(err);
|
|
});
|
|
|
|
worker.on('exit', () => {
|
|
this._terminate();
|
|
});
|
|
|
|
this.worker = worker;
|
|
}
|
|
|
|
_action(action, query) {
|
|
return new Promise((resolve, reject) => {
|
|
this.requestId++;
|
|
|
|
const requestId = this.requestId; //!!!
|
|
this.listeners.set(requestId, (mes) => {
|
|
this.listeners.delete(requestId);
|
|
|
|
if (mes.error)
|
|
reject(new Error(mes.error));
|
|
else
|
|
resolve(mes.result);
|
|
});
|
|
|
|
if (this.worker) {
|
|
this.worker.postMessage({requestId: this.requestId, action, query});
|
|
} else {
|
|
reject(new Error('Worker does not exist (database closed?)'));
|
|
}
|
|
});
|
|
}
|
|
|
|
async openDb(query = {}) {
|
|
if (!this.worker) {
|
|
this._runWoker();
|
|
} else {
|
|
throw new Error('Worker has been created already');
|
|
}
|
|
|
|
return this._action('openDb', query);
|
|
}
|
|
|
|
async closeDb() {
|
|
const result = await this._action('closeDb');
|
|
this._terminate();
|
|
//console.log('DB closed');
|
|
return result;
|
|
}
|
|
|
|
esc(obj) {
|
|
return utils.esc(obj);
|
|
}
|
|
}
|
|
|
|
module.exports = JembaDbThread; |