Skip to content
Merged
2 changes: 1 addition & 1 deletion README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ Below is the list that have direct support for `sql-lint` either through plugins

## Checks

A quick rundown of the checks is below but you should [read the documentation](https://sql-lint.readthedocs.io/en/latest/files/checks.html)
A quick rundown of the checks is below but you should [read the documentation](https://sql-lint.readthedocs.io/en/latest/files/checks.html)
for an exhaustive list.

`sql-lint` comes with its own suite of checks. It
Expand Down
11 changes: 10 additions & 1 deletion docs/files/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ You should put the following in there for more intelligent errors to come throug
"host": "localhost",
"user": "root",
"password": "hunter2",
"port": 3306
"port": 3306,
"database": "your_database"
}
```

Expand Down Expand Up @@ -68,6 +69,12 @@ The port to connect to.

Optional, default is `3306`.

### `database`

The database to connect to.

Optional, default is no database, where you will have to specify the database in your queries.

### `ignore-errors`

Don't want to be warned about a particular error?
Expand Down Expand Up @@ -115,6 +122,8 @@ The below configuration contains every option available.
"host": "localhost",
"user": "root",
"password": "password",
"port": 3306,
"database": "your_database",
"ignore-errors": [
"odd-code-point",
"missing-where",
Expand Down
3 changes: 3 additions & 0 deletions docs/files/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ Change your config file in `~/.config/sql-lint/config.json` to have the followin
}
```

Optionally, you can also add `"database": "your_database_name"` if you want to connect
to a specific database. However, most tests were written without this option.

## This documentation

This documentation is built on `sphinx` and `readthedocs`. To run it locally,
Expand Down
1 change: 0 additions & 1 deletion src/checker/checkerRunner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ class CheckerRunner {
printer.warnAboutUncategoriseableQuery(content, tokenised, prefix);
}


for (const check of checks) {
const checker = factory.build(check);

Expand Down
4 changes: 3 additions & 1 deletion src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import databaseFactory from "./database/databaseFactory";
.option("--host <string>", "The host for the database connection")
.option("--user <string>", "The user for the database connection")
.option("--password <string>", "The password for the database connection")
.option("--database <string>", "The database for the database connection")
.option("--port <string>", "The port for the database connection")
.option("--config <string>", "The path to the configuration file")
.option("--ignore-errors <string...>", "The errors to ignore (comma separated)")
Expand Down Expand Up @@ -113,7 +114,8 @@ 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.port || configuration?.port || undefined // let mysql2 or pg figure out the default port
program.port || configuration?.port || undefined, // let mysql2 or pg figure out the default port
program.database || configuration?.database || undefined,
);
}

Expand Down
7 changes: 4 additions & 3 deletions src/database/databaseFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ export default function databaseFactory(
host: string,
user: string,
password: string,
port?: number
port?: number,
database?: string
): IDatabase {
switch (driver) {
case "mysql":
return new MySqlDatabase(host, user, password, port);
return new MySqlDatabase(host, user, password, port, database);
case "postgres":
return new PostgresDatabase(host, user, password, port);
return new PostgresDatabase(host, user, password, port, database);
default:
throw new Error(`${driver} driver is unsupported`);
}
Expand Down
9 changes: 8 additions & 1 deletion src/database/mySqlDatabase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,19 @@ 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,
port?: number,
database?: string
) {
this.connection = mysql.createConnection({
host,
user,
password,
port,
database,
});
}

Expand Down
9 changes: 8 additions & 1 deletion src/database/postgresDatabase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,19 @@ 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,
port?: number,
database?: string
) {
this.pool = new Pool({
host,
user,
password,
port,
database,
});
}

Expand Down
36 changes: 11 additions & 25 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ interface Parameters {
host?: string;
user?: string;
port?: number;
database?: string;
driver?: string;
prefix?: string;
password?: string;
Expand All @@ -21,41 +22,26 @@ export default async ({
sql,
host,
port,
user = '',
prefix = '',
password = '',
database,
user = "",
prefix = "",
password = "",
verbosity = 0,
driver = 'mysql',
driver = "mysql",
}: Parameters): Promise<IMessage[]> => {
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, port, database);
}

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;
}
};
4 changes: 2 additions & 2 deletions src/reader/reader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ export function putContentIntoLines(contents: string): Query[] {
currentQueryContent += char;
continue;
}

if (escape) {
escape = false;
currentQueryContent += char;
continue;
}

// Toggle string state
if (char === "'" || char === "\"") {
if (char === "'" || char === '"') {
if (currentQuote === null) {
currentQuote = char;
} else if (currentQuote === char) {
Expand Down
22 changes: 9 additions & 13 deletions test/integration/sql-lint.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,15 @@ test("it brings back a version number", (done) => {
shelltest().cmd(`${sqlLint} --version`).expect("stdout", /^\d/).end(done);
});

test("--port is a valid option", (done) => {
shelltest()
.cmd(`${sqlLint} --help`)
.expect("stdout", /.*--port.*/)
.end(done);
});

test("--config is a valid option", (done) => {
shelltest()
.cmd(`${sqlLint} --help`)
.expect("stdout", /.*--config.*/)
.end(done);
});
test.each(["--port", "--config", "--database"])(
"%s is a valid option",
(option) => {
shelltest()
.cmd(`${sqlLint} --help`)
.expect("stdout", new RegExp(`.*${option}.*`))
.end();
}
);

test("Good queries exit with 0", (done) => {
shelltest()
Expand Down
2 changes: 1 addition & 1 deletion test/unit/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ test.each([
error: "[sql-lint: trailing-whitespace] Trailing whitespace",
},
],
])("it can run programmatically", async (sql, expected) => {
])("it can run programmatically (%s)", async (sql, expected) => {
const errors = await sqlLint({ sql: sql });
expect(errors[0]).toMatchObject(expected);
});
Expand Down