mirror of
https://github.com/thelounge/thelounge
synced 2024-11-21 19:43:07 +00:00
sqlite: synchronize enable() internally
TL is stupid and doesn't wait for message{Provider,Storage} to settle before it starts using the store. While this should be fixed globally, we can hack around the problem by pushing everything onto the call stack and hope that we'll eventually finish the setup before we blow the stack.
This commit is contained in:
parent
deeea274da
commit
2d4143b779
2 changed files with 37 additions and 6 deletions
|
@ -38,17 +38,30 @@ const schema = [
|
|||
"CREATE INDEX IF NOT EXISTS time ON messages (time)",
|
||||
];
|
||||
|
||||
class Deferred {
|
||||
resolve!: () => void;
|
||||
promise: Promise<void>;
|
||||
|
||||
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<Message[]> {
|
||||
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<SearchResponse> {
|
||||
await this.initDone.promise;
|
||||
|
||||
if (!this.isEnabled) {
|
||||
// this should never be hit as messageProvider is checked in client.search()
|
||||
throw new Error(
|
||||
|
|
|
@ -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'",
|
||||
|
|
Loading…
Reference in a new issue