SqliteConnectionPool.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. const Promise = require('bluebird');
  2. const utils = require('./utils');
  3. const sqlite = require('sqlite');
  4. const waitingDelay = 100; //ms
  5. class SqliteConnectionPool {
  6. constructor(connCount, logger, config) {
  7. this.connCount = connCount;
  8. this.logger = logger;
  9. this.config = config;
  10. }
  11. async init() {
  12. this.logger.log('Opening database');
  13. utils.mkDirIfNotExistsSync(this.config.dataDir);
  14. const dbFileName = this.config.dataDir + '/' + this.config.dbFileName;
  15. this.connections = [];
  16. this.taken = new Set();
  17. this.freed = new Set();
  18. for (let i = 0; i < this.connCount; i++) {
  19. let client = await sqlite.open(dbFileName);
  20. client.configure('busyTimeout', 10000); //ms
  21. client.ret = () => {
  22. this.taken.delete(i);
  23. this.freed.add(i);
  24. };
  25. this.freed.add(i);
  26. this.connections[i] = client;
  27. }
  28. }
  29. _setImmediate() {
  30. return new Promise((resolve) => {
  31. setImmediate(() => {
  32. return resolve();
  33. });
  34. });
  35. }
  36. async get() {
  37. if (this.closed)
  38. return;
  39. let freeConnIndex = this.freed.values().next().value;
  40. if (freeConnIndex == null) {
  41. if (waitingDelay)
  42. await utils.sleep(waitingDelay);
  43. return await this._setImmediate().then(() => this.get());
  44. }
  45. this.freed.delete(freeConnIndex);
  46. this.taken.add(freeConnIndex);
  47. return this.connections[freeConnIndex];
  48. }
  49. async run(query) {
  50. const dbh = await this.get();
  51. try {
  52. let result = await dbh.run(query);
  53. dbh.ret();
  54. return result;
  55. } catch (e) {
  56. dbh.ret();
  57. throw e;
  58. }
  59. }
  60. async all(query) {
  61. const dbh = await this.get();
  62. try {
  63. let result = await dbh.all(query);
  64. dbh.ret();
  65. return result;
  66. } catch (e) {
  67. dbh.ret();
  68. throw e;
  69. }
  70. }
  71. async close() {
  72. for (let i = 0; i < this.connections.length; i++) {
  73. await this.connections[i].close();
  74. }
  75. this.closed = true;
  76. }
  77. }
  78. module.exports = SqliteConnectionPool;