From 864af0536de250e34e8d206003fdb2ac71a4338a Mon Sep 17 00:00:00 2001 From: Gleb Buzin Date: Tue, 31 May 2022 20:59:23 +0300 Subject: [PATCH 1/2] feat: add option to set database --- src/cli.ts | 2 ++ src/database/databaseFactory.ts | 5 +-- src/database/mySqlDatabase.ts | 9 +++++- src/database/postgresDatabase.ts | 9 +++++- src/main.ts | 36 +++++++-------------- test/unit/database/databaseFactory.test.ts | 10 +++++- test/unit/database/mysqlDatabase.test.ts | 30 ++++++++++++++--- test/unit/database/postgresDatabase.test.ts | 25 ++++++++++++-- test/unit/main.test.ts | 4 +++ 9 files changed, 93 insertions(+), 37 deletions(-) diff --git a/src/cli.ts b/src/cli.ts index f8a7ebea..37af439c 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -36,6 +36,7 @@ import databaseFactory from "./database/databaseFactory"; .option("--host ", "The host for the connection") .option("--user ", "The user for the connection") .option("--password ", "The password for the connection") + .option("--database ", "The database for the connection") .option("--port ", "The port for the connection") .option("--config ", "The path to the configuration file") .parse(process.argv); @@ -96,6 +97,7 @@ import databaseFactory from "./database/databaseFactory"; program.host || configuration?.host || "localhost", program.user || configuration?.user || "root", // bad practice but unfortunately common, make it easier for the user program.password || configuration?.password, + program.database || configuration?.database, program.port || configuration?.port || undefined // let mysql2 or pg figure out the default port ); } diff --git a/src/database/databaseFactory.ts b/src/database/databaseFactory.ts index 6c36956e..8c2224bd 100644 --- a/src/database/databaseFactory.ts +++ b/src/database/databaseFactory.ts @@ -7,13 +7,14 @@ export default function databaseFactory( host: string, user: string, password: string, + database: string, port?: number ): IDatabase { switch (driver) { case "mysql": - return new MySqlDatabase(host, user, password, port); + return new MySqlDatabase(host, user, password, database, port); case "postgres": - return new PostgresDatabase(host, user, password, port); + return new PostgresDatabase(host, user, password, database, port); default: throw new Error(`${driver} driver is unsupported`); } diff --git a/src/database/mySqlDatabase.ts b/src/database/mySqlDatabase.ts index 5699bb76..bb4491bc 100644 --- a/src/database/mySqlDatabase.ts +++ b/src/database/mySqlDatabase.ts @@ -4,11 +4,18 @@ import IDatabase, { sqlError } from "./interface"; export default class MySqlDatabase implements IDatabase { private connection: mysql.Connection; - constructor(host: string, user: string, password: string, port?: number) { + constructor( + host: string, + user: string, + password: string, + database: string, + port?: number + ) { this.connection = mysql.createConnection({ host, user, password, + database, port, }); } diff --git a/src/database/postgresDatabase.ts b/src/database/postgresDatabase.ts index d9878743..0d2d229b 100644 --- a/src/database/postgresDatabase.ts +++ b/src/database/postgresDatabase.ts @@ -4,11 +4,18 @@ import IDatabase, { sqlError } from "./interface"; export default class PostgresDatabase implements IDatabase { private pool: Pool; - constructor(host: string, user: string, password: string, port?: number) { + constructor( + host: string, + user: string, + password: string, + database: string, + port?: number + ) { this.pool = new Pool({ host, user, password, + database, port, }); } diff --git a/src/main.ts b/src/main.ts index 8610c106..262326c5 100644 --- a/src/main.ts +++ b/src/main.ts @@ -14,6 +14,7 @@ interface Parameters { driver?: string; prefix?: string; password?: string; + database?: string; verbosity?: number; } @@ -21,41 +22,26 @@ export default async ({ sql, host, port, - user = '', - prefix = '', - password = '', + user = "", + prefix = "", + password = "", + database = "", verbosity = 0, - driver = 'mysql', + driver = "mysql", }: Parameters): Promise => { - const printer = new Printer( - verbosity, - new JsonFormat(), - ); + const printer = new Printer(verbosity, new JsonFormat()); - let db: IDatabase|undefined; + let db: IDatabase | undefined; if (host) { - db = databaseFactory( - driver, - host, - user, - password, - port, - ) + db = databaseFactory(driver, host, user, password, database, port); } const runner = new CheckerRunner(); - await runner.run( - putContentIntoLines(sql), - printer, - prefix, - [], - driver, - db, - ) + await runner.run(putContentIntoLines(sql), printer, prefix, [], driver, db); if (db) { db.end(); } return printer.messages; -} +}; diff --git a/test/unit/database/databaseFactory.test.ts b/test/unit/database/databaseFactory.test.ts index 65a1d4af..4fdfbb0e 100644 --- a/test/unit/database/databaseFactory.test.ts +++ b/test/unit/database/databaseFactory.test.ts @@ -27,6 +27,7 @@ test.each([ "localhost", "user", "password", + "database", 3306 ); expect(database).toBeInstanceOf(expected); @@ -34,7 +35,14 @@ test.each([ test("it throws an exception if driver is not supported", () => { const t = () => - databaseFactory("mongodb", "localhost", "user", "password", 3306); + databaseFactory( + "mongodb", + "localhost", + "user", + "password", + "database", + 3306 + ); expect(t).toThrow(Error); }); diff --git a/test/unit/database/mysqlDatabase.test.ts b/test/unit/database/mysqlDatabase.test.ts index 3ee3a5b6..bc40c5ea 100644 --- a/test/unit/database/mysqlDatabase.test.ts +++ b/test/unit/database/mysqlDatabase.test.ts @@ -7,6 +7,7 @@ jest.mock("mysql2", () => { host: "localhost", user: "user", password: "password", + database: "database", port: 3306, }); return mock; @@ -22,17 +23,38 @@ jest.mock("mysql2", () => { }); test("it calls createConnection", () => { - const db = new MySqlDatabase("localhost", "user", "password", 3306); + const db = new MySqlDatabase( + "localhost", + "user", + "password", + "database", + 3306 + ); }); test("it calls callback if there is an error", async () => { - const db = new MySqlDatabase("localhost", "user", "password", 3306); + const db = new MySqlDatabase( + "localhost", + "user", + "password", + "database", + 3306 + ); const sql = "SELECT some_column FROM some_table WHERE id = 1"; - expect(await db.lintQuery(sql)).toHaveProperty("sqlMessage", "table does not exist"); + expect(await db.lintQuery(sql)).toHaveProperty( + "sqlMessage", + "table does not exist" + ); }); test("it calls end on connection", () => { - const db = new MySqlDatabase("localhost", "user", "password", 3306); + const db = new MySqlDatabase( + "localhost", + "user", + "password", + "database", + 3306 + ); db.end(); }); diff --git a/test/unit/database/postgresDatabase.test.ts b/test/unit/database/postgresDatabase.test.ts index db5d6e12..fb91b372 100644 --- a/test/unit/database/postgresDatabase.test.ts +++ b/test/unit/database/postgresDatabase.test.ts @@ -7,6 +7,7 @@ jest.mock("pg", () => { host: "localhost", user: "user", password: "password", + database: "database", port: 5432, }); return mock; @@ -23,11 +24,23 @@ jest.mock("pg", () => { }); test("it calls createConnection", () => { - const db = new PostgresDatabase("localhost", "user", "password", 5432); + const db = new PostgresDatabase( + "localhost", + "user", + "password", + "database", + 5432 + ); }); test("it calls callback if there is an error", async () => { - const db = new PostgresDatabase("localhost", "user", "password", 5432); + const db = new PostgresDatabase( + "localhost", + "user", + "password", + "database", + 5432 + ); const sql = "SELECT some_column FROM some_table WHERE id = 1"; expect(await db.lintQuery(sql)).toMatchObject({ @@ -37,7 +50,13 @@ test("it calls callback if there is an error", async () => { }); test("it calls end on connection", () => { - const db = new PostgresDatabase("localhost", "user", "password", 5432); + const db = new PostgresDatabase( + "localhost", + "user", + "password", + "database", + 5432 + ); db.end(); }); diff --git a/test/unit/main.test.ts b/test/unit/main.test.ts index 9609c27c..6fce3b13 100644 --- a/test/unit/main.test.ts +++ b/test/unit/main.test.ts @@ -70,6 +70,7 @@ jest.mock("mysql2", () => { user: "user", host: "localhost", password: "password", + database: "database", }); return mock; }, @@ -90,6 +91,7 @@ test("it uses db connection is provided", async () => { user: "user", host: "localhost", password: "password", + database: "database", sql: "SELECT some_column FROM my_database.some_table;", }; @@ -108,6 +110,7 @@ jest.mock("pg", () => { host: "localhost", user: "user", password: "password", + database: "database", port: 5432, }); return mock; @@ -128,6 +131,7 @@ test("it uses correct driver when provided", async () => { driver: "postgres", host: "localhost", password: "password", + database: "database", port: 5432, sql: "SELECT some_column FROM my_database.some_table;", user: "user", From efaf68b2bfeb168be89e1d16f553f155ed8d6bee Mon Sep 17 00:00:00 2001 From: Gleb Buzin Date: Tue, 31 May 2022 21:06:44 +0300 Subject: [PATCH 2/2] docs(README.md): mention database option --- README.MD | 1 + 1 file changed, 1 insertion(+) diff --git a/README.MD b/README.MD index 4a741a30..5dad4e89 100644 --- a/README.MD +++ b/README.MD @@ -76,6 +76,7 @@ sql-lint accepts an object using the following interface as its only argument driver?: string prefix?: string password?: string + database?: string verbosity?: number } ```