From ee4e83bebc29e1de4f56ebdffa7dc812e6e1544c Mon Sep 17 00:00:00 2001 From: Wolvan Date: Sun, 30 Jan 2022 17:54:07 +0100 Subject: [PATCH] Implement MySQL table prefix The table prefix can be used to differentiate installs on the same MySQL database. By default, no prefix is set. --- src/MySQLStorage.ts | 10 +++++----- src/main.ts | 4 +++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/MySQLStorage.ts b/src/MySQLStorage.ts index 7e3713e..7cc4d6a 100644 --- a/src/MySQLStorage.ts +++ b/src/MySQLStorage.ts @@ -7,7 +7,7 @@ import { BackendPoll as Poll } from "./Poll"; export default class MySQLStorage extends Storage { #db: mysql.Connection; - #options: mysql.ConnectionOptions; + #options: mysql.ConnectionOptions & { tablePrefix?: string }; #createConnection(mysqlInstance?: mysql.Connection): void { if (!mysqlInstance) this.#db = mysql.createConnection(this.#options); this.#db.on("error", (err: mysql.QueryError) => { @@ -15,7 +15,7 @@ export default class MySQLStorage extends Storage { }); } - constructor(options: mysql.ConnectionOptions) { + constructor(options: mysql.ConnectionOptions & { tablePrefix?: string }) { super(); this.#options = options; console.debug("Initiating MySQLStorage."); @@ -25,7 +25,7 @@ export default class MySQLStorage extends Storage { async init(): Promise { await this.#db.promise().query(` - CREATE TABLE IF NOT EXISTS polls ( + CREATE TABLE IF NOT EXISTS ${ this.#options.tablePrefix || "" }polls ( id_str VARCHAR(32) NOT NULL PRIMARY KEY, title VARCHAR(${MAX_CHARACTER_LENGTH}) NOT NULL DEFAULT '', dupe_check_mode ENUM('none', 'ip', 'cookie') NOT NULL DEFAULT 'ip', @@ -42,7 +42,7 @@ export default class MySQLStorage extends Storage { } async getItem(key: string): Promise { - const [rows] = await this.#db.promise().execute("SELECT * FROM polls WHERE id_str = ? AND deleted_at IS NULL;", [key]); + const [rows] = await this.#db.promise().execute(`SELECT * FROM ${ this.#options.tablePrefix || "" }polls WHERE id_str = ? AND deleted_at IS NULL;`, [key]); if (!rows || !Array.isArray(rows) || !rows.length) return null; const row = rows[0] as { id_str: string, @@ -68,7 +68,7 @@ export default class MySQLStorage extends Storage { async setItem(key: string, value: Poll): Promise { await this.#db.promise().execute(` - INSERT INTO polls + INSERT INTO ${ this.#options.tablePrefix || "" }polls (id_str, title, dupe_check_mode, multi_select, captcha, dupe_data, options, creation_time) VALUES (?, ?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE diff --git a/src/main.ts b/src/main.ts index f10623c..6a0c17f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -24,6 +24,7 @@ async function main(): Promise { ["--mysql-user ", "MySQL user", "root"], ["--mysql-password ", "MySQL password", "root"], ["--mysql-database ", "MySQL database", "polls"], + ["--mysql-table-prefix ", "MySQL table prefix", ""], ["--mysql-ssl", "Use SSL for MySQL connection"], ["--backend-base-url ", "Base URL for the backend server", null], ], ".poll-horse-config"); @@ -56,7 +57,8 @@ async function main(): Promise { user: opts.mysqlUser, password: opts.mysqlPassword, database: opts.mysqlDatabase, - ssl: opts.mysqlSsl + ssl: opts.mysqlSsl, + tablePrefix: opts.mysqlTablePrefix, }) : new FlatFileStorage({ dir: resolve(process.cwd(), program.opts().dataDirectory) }); await storage.init();