SqliteConnectionPool.js 2.1 KB

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