Skip to content

Commit

Permalink
feat: add debugging controls for logs
Browse files Browse the repository at this point in the history
  • Loading branch information
bombillazo committed Feb 16, 2024
1 parent 08320fa commit 4f031f1
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 21 deletions.
37 changes: 21 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,15 @@ A lightweight PostgreSQL driver for Deno focused on developer experience.
[node-postgres](https://github.com/brianc/node-postgres) and
[pq](https://github.com/lib/pq).

## Example
## Documentation

The documentation is available on the deno-postgres website
[https://deno-postgres.com/](https://deno-postgres.com/)

Join the [Discord](https://discord.gg/HEdTCvZUSf) as well! It's a good place to
discuss bugs and features before opening issues.

## Examples

```ts
// deno run --allow-net --allow-read mod.ts
Expand All @@ -32,8 +40,8 @@ await client.connect();
}

{
const result = await client
.queryArray`SELECT ID, NAME FROM PEOPLE WHERE ID = ${1}`;
const result =
await client.queryArray`SELECT ID, NAME FROM PEOPLE WHERE ID = ${1}`;
console.log(result.rows); // [[1, 'Carlos']]
}

Expand All @@ -43,25 +51,14 @@ await client.connect();
}

{
const result = await client
.queryObject`SELECT ID, NAME FROM PEOPLE WHERE ID = ${1}`;
const result =
await client.queryObject`SELECT ID, NAME FROM PEOPLE WHERE ID = ${1}`;
console.log(result.rows); // [{id: 1, name: 'Carlos'}]
}

await client.end();
```

For more examples, visit the documentation available at
[https://deno-postgres.com/](https://deno-postgres.com/)

## Documentation

The documentation is available on the deno-postgres website
[https://deno-postgres.com/](https://deno-postgres.com/)

Join the [Discord](https://discord.gg/HEdTCvZUSf) as well! It's a good place to
discuss bugs and features before opening issues.

## Contributing

### Prerequisites
Expand Down Expand Up @@ -156,6 +153,14 @@ This situation will stabilize as `std` and `deno-postgres` approach version 1.0.
| 1.17.0 | 0.15.0 | 0.17.1 | |
| 1.40.0 | 0.17.2 | | Now available on JSR |

## Breaking changes

Although the `deno-driver` is pretty stable and robust, it is a WIP and we're still exploring the design. Expect some breaking changes as we reach version 1.0 and enhance the feature set. PLease check the Releases for more info on breaking changes. Please reach out if there are any undocumented breaking changes.

## Found issues?

Please file an issue with any problems with the driver in this repository's issue section. If you would like to help, please look at the issues as well. You can pick up one of them and try to implement it.

## Contributing guidelines

When contributing to the repository, make sure to:
Expand Down
50 changes: 46 additions & 4 deletions connection/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
bold,
BufReader,
BufWriter,
cyan,
delay,
joinPath,
yellow,
Expand Down Expand Up @@ -68,6 +69,7 @@ import {
INCOMING_TLS_MESSAGES,
} from "./message_code.ts";
import { hashMd5Password } from "./auth.ts";
import { isDebugOptionEnabled } from "../debug.ts";

// Work around unstable limitation
type ConnectOptions =
Expand Down Expand Up @@ -100,6 +102,14 @@ function logNotice(notice: Notice) {
console.error(`${bold(yellow(notice.severity))}: ${notice.message}`);
}

function logQuery(query: string) {
console.error(`${bold(cyan("QUERY"))}: ${query}`);
}

function logResults(rows: unknown[]) {
console.error(`${bold("RESULTS")}: ${rows}`);
}

const decoder = new TextDecoder();
const encoder = new TextEncoder();

Expand Down Expand Up @@ -695,7 +705,14 @@ export class Connection {
break;
case INCOMING_QUERY_MESSAGES.NOTICE_WARNING: {
const notice = parseNoticeMessage(current_message);
logNotice(notice);
if (
isDebugOptionEnabled(
"notices",
this.#connection_params.controls?.debug,
)
) {
logNotice(notice);
}
result.warnings.push(notice);
break;
}
Expand Down Expand Up @@ -819,6 +836,12 @@ export class Connection {
/**
* https://www.postgresql.org/docs/14/protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY
*/
async #preparedQuery(
query: Query<ResultType.ARRAY>,
): Promise<QueryArrayResult>;
async #preparedQuery(
query: Query<ResultType.OBJECT>,
): Promise<QueryObjectResult>;
async #preparedQuery<T extends ResultType>(
query: Query<T>,
): Promise<QueryResult> {
Expand Down Expand Up @@ -872,7 +895,14 @@ export class Connection {
break;
case INCOMING_QUERY_MESSAGES.NOTICE_WARNING: {
const notice = parseNoticeMessage(current_message);
logNotice(notice);
if (
isDebugOptionEnabled(
"notices",
this.#connection_params.controls?.debug,
)
) {
logNotice(notice);
}
result.warnings.push(notice);
break;
}
Expand Down Expand Up @@ -911,11 +941,23 @@ export class Connection {

await this.#queryLock.pop();
try {
if (
isDebugOptionEnabled("queries", this.#connection_params.controls?.debug)
) {
logQuery(query.text);
}
let result: QueryArrayResult | QueryObjectResult;
if (query.args.length === 0) {
return await this.#simpleQuery(query);
result = await this.#simpleQuery(query);
} else {
return await this.#preparedQuery(query);
result = await this.#preparedQuery(query);
}
if (
isDebugOptionEnabled("results", this.#connection_params.controls?.debug)
) {
logResults(result.rows);
}
return result;
} catch (e) {
if (e instanceof ConnectionError) {
await this.end();
Expand Down
5 changes: 5 additions & 0 deletions connection/connection_params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { parseConnectionUri } from "../utils/utils.ts";
import { ConnectionParamsError } from "../client/error.ts";
import { fromFileUrl, isAbsolute } from "../deps.ts";
import { OidType } from "../query/oid.ts";
import { DebugControls } from "../debug.ts";

/**
* The connection string must match the following URI structure. All parameters but database and user are optional
Expand Down Expand Up @@ -115,6 +116,10 @@ export type DecoderFunction = (value: string, oid: number) => unknown;
* Control the behavior for the client instance
*/
export type ClientControls = {
/**
* Debugging options
*/
debug: DebugControls;
/**
* The strategy to use when decoding results data
*
Expand Down
30 changes: 30 additions & 0 deletions debug.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* Controls debugging behavior {@default false}
*
* - `true` : all debug options are enabled
* - `false` : all debug options are disabled
* - DebugOptions:
* - `query` : Log queries
* - `notices` : Log notices
*/
export type DebugControls = DebugOptions | boolean;

type DebugOptions = {
/** Log queries */
queries?: boolean;
/** Log notices */
notices?: boolean;
/** Log results */
results?: boolean;
};

export const isDebugOptionEnabled = (
option: keyof DebugOptions,
options?: DebugControls,
): boolean => {
if (typeof options === "boolean") {
return options;
}

return !!options?.[option];
};
6 changes: 5 additions & 1 deletion deps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ export { BufWriter } from "https://deno.land/[email protected]/io/buf_writer.ts";
export { copy } from "https://deno.land/[email protected]/bytes/copy.ts";
export { crypto } from "https://deno.land/[email protected]/crypto/crypto.ts";
export { delay } from "https://deno.land/[email protected]/async/delay.ts";
export { bold, yellow } from "https://deno.land/[email protected]/fmt/colors.ts";
export {
bold,
cyan,
yellow,
} from "https://deno.land/[email protected]/fmt/colors.ts";
export {
fromFileUrl,
isAbsolute,
Expand Down
34 changes: 34 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1393,3 +1393,37 @@ await transaction.queryArray`INSERT INTO DONT_DELETE_ME VALUES (2)`; // Still in
await transaction.commit();
// Transaction ends, client gets unlocked
```

## Debugging

The driver can provide different types of logs if as needed. By default, logs
are disabled to keep your environment as uncluttered as possible. Logging can be
enabled by using the `debug` option in the Client `controls` parameter. Pass
`true` to enable all logs, or turn on logs granulary by enabling the following
options:

- `queries` : Logs all SQL queries executed by the client
- `notices` : Logs database notices
- `results` : Logs the result of the queries

```ts
{
const client = new Client({
...
controls: {
// enable all logs
debug: true,
},
});

const client = new Client({
...
controls: {
// only enable logging of SQL query statements
debug: {
queries: true,
},
},
});
}
```

0 comments on commit 4f031f1

Please sign in to comment.