91 lines
2.1 KiB
JavaScript
91 lines
2.1 KiB
JavaScript
const utils = require('./utils');
|
|
const sqlite = require('sqlite');
|
|
|
|
const waitingDelay = 100; //ms
|
|
|
|
class SqliteConnectionPool {
|
|
constructor(connCount, config) {
|
|
this.connCount = connCount;
|
|
this.config = config;
|
|
}
|
|
|
|
async init() {
|
|
const dbFileName = this.config.dataDir + '/' + this.config.dbFileName;
|
|
|
|
this.connections = [];
|
|
this.taken = new Set();
|
|
this.freed = new Set();
|
|
|
|
for (let i = 0; i < this.connCount; i++) {
|
|
|
|
let client = await sqlite.open(dbFileName);
|
|
client.configure('busyTimeout', 10000); //ms
|
|
|
|
client.ret = () => {
|
|
this.taken.delete(i);
|
|
this.freed.add(i);
|
|
};
|
|
|
|
this.freed.add(i);
|
|
this.connections[i] = client;
|
|
}
|
|
}
|
|
|
|
_setImmediate() {
|
|
return new Promise((resolve) => {
|
|
setImmediate(() => {
|
|
return resolve();
|
|
});
|
|
});
|
|
}
|
|
|
|
async get() {
|
|
if (this.closed)
|
|
return;
|
|
|
|
let freeConnIndex = this.freed.values().next().value;
|
|
if (freeConnIndex == null) {
|
|
if (waitingDelay)
|
|
await utils.sleep(waitingDelay);
|
|
return await this._setImmediate().then(() => this.get());
|
|
}
|
|
|
|
this.freed.delete(freeConnIndex);
|
|
this.taken.add(freeConnIndex);
|
|
|
|
return this.connections[freeConnIndex];
|
|
}
|
|
|
|
async run(query) {
|
|
const dbh = await this.get();
|
|
try {
|
|
let result = await dbh.run(query);
|
|
dbh.ret();
|
|
return result;
|
|
} catch (e) {
|
|
dbh.ret();
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
async all(query) {
|
|
const dbh = await this.get();
|
|
try {
|
|
let result = await dbh.all(query);
|
|
dbh.ret();
|
|
return result;
|
|
} catch (e) {
|
|
dbh.ret();
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
async close() {
|
|
for (let i = 0; i < this.connections.length; i++) {
|
|
await this.connections[i].close();
|
|
}
|
|
this.closed = true;
|
|
}
|
|
}
|
|
|
|
module.exports = SqliteConnectionPool; |