Merge branch 'storageCleanup'

This commit is contained in:
Reto Brunner 2023-01-22 15:23:56 +01:00
commit 375164ca88
6 changed files with 30 additions and 40 deletions

View file

@ -138,12 +138,12 @@ class Client {
if (!Config.values.public && client.config.log) { if (!Config.values.public && client.config.log) {
if (Config.values.messageStorage.includes("sqlite")) { if (Config.values.messageStorage.includes("sqlite")) {
client.messageProvider = new SqliteMessageStorage(client); client.messageProvider = new SqliteMessageStorage(client.name);
client.messageStorage.push(client.messageProvider); client.messageStorage.push(client.messageProvider);
} }
if (Config.values.messageStorage.includes("text")) { if (Config.values.messageStorage.includes("text")) {
client.messageStorage.push(new TextFileMessageStorage(client)); client.messageStorage.push(new TextFileMessageStorage(client.name));
} }
for (const messageStorage of client.messageStorage) { for (const messageStorage of client.messageStorage) {

View file

@ -287,7 +287,7 @@ class Chan {
} }
client.messageProvider client.messageProvider
.getMessages(network, this) .getMessages(network, this, () => client.idMsg++)
.then((messages) => { .then((messages) => {
if (messages.length === 0) { if (messages.length === 0) {
if (network.irc!.network.cap.isEnabled("znc.in/playback")) { if (network.irc!.network.cap.isEnabled("znc.in/playback")) {

View file

@ -5,14 +5,9 @@ import path from "path";
import fs from "fs/promises"; import fs from "fs/promises";
import Config from "../../config"; import Config from "../../config";
import Msg, {Message} from "../../models/msg"; import Msg, {Message} from "../../models/msg";
import Client from "../../client";
import Chan, {Channel} from "../../models/chan"; import Chan, {Channel} from "../../models/chan";
import Helper from "../../helper"; import Helper from "../../helper";
import type { import type {SearchResponse, SearchQuery, SearchableMessageStorage} from "./types";
SearchResponse,
SearchQuery,
SqliteMessageStorage as ISqliteMessageStorage,
} from "./types";
import Network from "../../models/network"; import Network from "../../models/network";
// TODO; type // TODO; type
@ -49,21 +44,21 @@ class Deferred {
} }
} }
class SqliteMessageStorage implements ISqliteMessageStorage { class SqliteMessageStorage implements SearchableMessageStorage {
client: Client;
isEnabled: boolean; isEnabled: boolean;
database!: Database; database!: Database;
initDone: Deferred; initDone: Deferred;
userName: string;
constructor(client: Client) { constructor(userName: string) {
this.client = client; this.userName = userName;
this.isEnabled = false; this.isEnabled = false;
this.initDone = new Deferred(); this.initDone = new Deferred();
} }
async _enable() { async _enable() {
const logsPath = Config.getUserLogsPath(); const logsPath = Config.getUserLogsPath();
const sqlitePath = path.join(logsPath, `${this.client.name}.sqlite3`); const sqlitePath = path.join(logsPath, `${this.userName}.sqlite3`);
try { try {
await fs.mkdir(logsPath, {recursive: true}); await fs.mkdir(logsPath, {recursive: true});
@ -190,13 +185,11 @@ class SqliteMessageStorage implements ISqliteMessageStorage {
]); ]);
} }
/** async getMessages(
* Load messages for given channel on a given network and resolve a promise with loaded messages. network: Network,
* channel: Channel,
* @param network Network - Network object where the channel is nextID: () => number
* @param channel Channel - Channel object for which to load messages for ): Promise<Message[]> {
*/
async getMessages(network: Network, channel: Channel): Promise<Message[]> {
await this.initDone.promise; await this.initDone.promise;
if (!this.isEnabled || Config.values.maxHistory === 0) { if (!this.isEnabled || Config.values.maxHistory === 0) {
@ -219,7 +212,7 @@ class SqliteMessageStorage implements ISqliteMessageStorage {
msg.type = row.type; msg.type = row.type;
const newMsg = new Msg(msg); const newMsg = new Msg(msg);
newMsg.id = this.client.idMsg++; newMsg.id = nextID();
return newMsg; return newMsg;
}); });

View file

@ -5,17 +5,16 @@ import filenamify from "filenamify";
import Config from "../../config"; import Config from "../../config";
import {MessageStorage} from "./types"; import {MessageStorage} from "./types";
import Client from "../../client";
import Channel from "../../models/chan"; import Channel from "../../models/chan";
import {Message, MessageType} from "../../models/msg"; import {Message, MessageType} from "../../models/msg";
import Network from "../../models/network"; import Network from "../../models/network";
class TextFileMessageStorage implements MessageStorage { class TextFileMessageStorage implements MessageStorage {
client: Client;
isEnabled: boolean; isEnabled: boolean;
username: string;
constructor(client: Client) { constructor(username: string) {
this.client = client; this.username = username;
this.isEnabled = false; this.isEnabled = false;
} }
@ -36,7 +35,7 @@ class TextFileMessageStorage implements MessageStorage {
const logPath = path.join( const logPath = path.join(
Config.getUserLogsPath(), Config.getUserLogsPath(),
this.client.name, this.username,
TextFileMessageStorage.getNetworkFolderName(network) TextFileMessageStorage.getNetworkFolderName(network)
); );

View file

@ -6,7 +6,6 @@ import {Network} from "../../models/network";
import Client from "../../client"; import Client from "../../client";
interface MessageStorage { interface MessageStorage {
client: Client;
isEnabled: boolean; isEnabled: boolean;
enable(): Promise<void>; enable(): Promise<void>;
@ -17,7 +16,7 @@ interface MessageStorage {
deleteChannel(network: Network, channel: Channel): Promise<void>; deleteChannel(network: Network, channel: Channel): Promise<void>;
getMessages(network: Network, channel: Channel): Promise<Message[]>; getMessages(network: Network, channel: Channel, nextID: () => number): Promise<Message[]>;
canProvideMessages(): boolean; canProvideMessages(): boolean;
} }
@ -35,7 +34,6 @@ export type SearchResponse = SearchQuery & {
type SearchFunction = (query: SearchQuery) => Promise<SearchResponse>; type SearchFunction = (query: SearchQuery) => Promise<SearchResponse>;
export interface SqliteMessageStorage extends MessageStorage { export interface SearchableMessageStorage extends MessageStorage {
database: Database; search: SearchFunction;
search: SearchFunction | [];
} }

View file

@ -6,7 +6,6 @@ import util from "../util";
import Msg, {MessageType} from "../../server/models/msg"; import Msg, {MessageType} from "../../server/models/msg";
import Config from "../../server/config"; import Config from "../../server/config";
import MessageStorage from "../../server/plugins/messageStorage/sqlite"; import MessageStorage from "../../server/plugins/messageStorage/sqlite";
import Client from "../../server/client";
describe("SQLite Message Storage", function () { describe("SQLite Message Storage", function () {
// Increase timeout due to unpredictable I/O on CI services // Increase timeout due to unpredictable I/O on CI services
@ -17,10 +16,7 @@ describe("SQLite Message Storage", function () {
let store: MessageStorage; let store: MessageStorage;
before(function (done) { before(function (done) {
store = new MessageStorage({ store = new MessageStorage("testUser");
name: "testUser",
idMsg: 1,
} as Client);
// Delete database file from previous test run // Delete database file from previous test run
if (fs.existsSync(expectedPath)) { if (fs.existsSync(expectedPath)) {
@ -47,7 +43,7 @@ describe("SQLite Message Storage", function () {
it("should resolve an empty array when disabled", async function () { it("should resolve an empty array when disabled", async function () {
store.isEnabled = false; store.isEnabled = false;
const messages = await store.getMessages(null as any, null as any); const messages = await store.getMessages(null as any, null as any, null as any);
expect(messages).to.be.empty; expect(messages).to.be.empty;
store.isEnabled = true; store.isEnabled = true;
}); });
@ -106,13 +102,15 @@ describe("SQLite Message Storage", function () {
}); });
it("should retrieve previously stored message", async function () { it("should retrieve previously stored message", async function () {
let msgid = 0;
const messages = await store.getMessages( const messages = await store.getMessages(
{ {
uuid: "this-is-a-network-guid", uuid: "this-is-a-network-guid",
} as any, } as any,
{ {
name: "#thisisaCHANNEL", name: "#thisisaCHANNEL",
} as any } as any,
() => msgid++
); );
expect(messages).to.have.lengthOf(1); expect(messages).to.have.lengthOf(1);
const msg = messages[0]; const msg = messages[0];
@ -138,9 +136,11 @@ describe("SQLite Message Storage", function () {
); );
} }
let msgId = 0;
const messages = await store.getMessages( const messages = await store.getMessages(
{uuid: "retrieval-order-test-network"} as any, {uuid: "retrieval-order-test-network"} as any,
{name: "#channel"} as any {name: "#channel"} as any,
() => msgId++
); );
expect(messages).to.have.lengthOf(2); expect(messages).to.have.lengthOf(2);
expect(messages.map((i_1) => i_1.text)).to.deep.equal(["msg 198", "msg 199"]); expect(messages.map((i_1) => i_1.text)).to.deep.equal(["msg 198", "msg 199"]);