diff --git a/server/plugins/messageStorage/sqlite.ts b/server/plugins/messageStorage/sqlite.ts index 3adea7a4..fb7d9c3e 100644 --- a/server/plugins/messageStorage/sqlite.ts +++ b/server/plugins/messageStorage/sqlite.ts @@ -38,17 +38,30 @@ const schema = [ "CREATE INDEX IF NOT EXISTS time ON messages (time)", ]; +class Deferred { + resolve!: () => void; + promise: Promise; + + constructor() { + this.promise = new Promise((resolve) => { + this.resolve = resolve; + }); + } +} + class SqliteMessageStorage implements ISqliteMessageStorage { client: Client; isEnabled: boolean; database!: Database; + initDone: Deferred; constructor(client: Client) { this.client = client; this.isEnabled = false; + this.initDone = new Deferred(); } - async enable() { + async _enable() { const logsPath = Config.getUserLogsPath(); const sqlitePath = path.join(logsPath, `${this.client.name}.sqlite3`); @@ -70,6 +83,14 @@ class SqliteMessageStorage implements ISqliteMessageStorage { } } + async enable() { + try { + await this._enable(); + } finally { + this.initDone.resolve(); // unblock the instance methods + } + } + async run_migrations() { for (const stmt of schema) { await this.serialize_run(stmt, []); @@ -127,6 +148,8 @@ class SqliteMessageStorage implements ISqliteMessageStorage { } async index(network: Network, channel: Chan, msg: Msg) { + await this.initDone.promise; + if (!this.isEnabled) { return; } @@ -155,6 +178,8 @@ class SqliteMessageStorage implements ISqliteMessageStorage { } async deleteChannel(network: Network, channel: Channel) { + await this.initDone.promise; + if (!this.isEnabled) { return; } @@ -172,6 +197,8 @@ class SqliteMessageStorage implements ISqliteMessageStorage { * @param channel Channel - Channel object for which to load messages for */ async getMessages(network: Network, channel: Channel): Promise { + await this.initDone.promise; + if (!this.isEnabled || Config.values.maxHistory === 0) { return []; } @@ -199,6 +226,8 @@ class SqliteMessageStorage implements ISqliteMessageStorage { } async search(query: SearchQuery): Promise { + await this.initDone.promise; + if (!this.isEnabled) { // this should never be hit as messageProvider is checked in client.search() throw new Error( diff --git a/test/plugins/sqlite.ts b/test/plugins/sqlite.ts index f2ad6750..4476faf0 100644 --- a/test/plugins/sqlite.ts +++ b/test/plugins/sqlite.ts @@ -37,11 +37,6 @@ describe("SQLite Message Storage", function () { fs.rmdir(path.join(Config.getHomePath(), "logs"), done); }); - it("should resolve an empty array when disabled", async function () { - const messages = await store.getMessages(null as any, null as any); - expect(messages).to.be.empty; - }); - it("should create database file", async function () { expect(store.isEnabled).to.be.false; expect(fs.existsSync(expectedPath)).to.be.false; @@ -50,6 +45,13 @@ describe("SQLite Message Storage", function () { expect(store.isEnabled).to.be.true; }); + it("should resolve an empty array when disabled", async function () { + store.isEnabled = false; + const messages = await store.getMessages(null as any, null as any); + expect(messages).to.be.empty; + store.isEnabled = true; + }); + it("should create tables", function (done) { store.database.all( "SELECT name, tbl_name, sql FROM sqlite_master WHERE type = 'table'",