Skip to content

Commit

Permalink
feat: add support for getting result metadata (#96)
Browse files Browse the repository at this point in the history
  • Loading branch information
uki00a authored May 21, 2020
1 parent 57e13a9 commit a712453
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 0 deletions.
10 changes: 10 additions & 0 deletions connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,8 @@ export class Connection {
// command complete
// TODO: this is duplicated in next loop
case "C":
const commandTag = this._readCommandTag(msg);
result.handleCommandComplete(commandTag);
result.done();
break;
default:
Expand All @@ -316,6 +318,8 @@ export class Connection {
break;
// command complete
case "C":
const commandTag = this._readCommandTag(msg);
result.handleCommandComplete(commandTag);
result.done();
break;
// ready for query
Expand Down Expand Up @@ -505,6 +509,8 @@ export class Connection {
break;
// command complete
case "C":
const commandTag = this._readCommandTag(msg);
result.handleCommandComplete(commandTag);
result.done();
break outerLoop;
// error response
Expand Down Expand Up @@ -569,6 +575,10 @@ export class Connection {
return row;
}

_readCommandTag(msg: Message) {
return msg.reader.readString(msg.byteCount);
}

async initSQL(): Promise<void> {
const config: QueryConfig = { text: "select 1;", args: [] };
const query = new Query(config);
Expand Down
28 changes: 28 additions & 0 deletions query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@ import { encode, EncodedArg } from "./encode.ts";

import { decode } from "./decode.ts";

const commandTagRegexp = /^([A-Za-z]+)(?: (\d+))?(?: (\d+))?/;

type CommandType = (
| "INSERT"
| "DELETE"
| "UPDATE"
| "SELECT"
| "MOVE"
| "FETCH"
| "COPY"
);

export interface QueryConfig {
text: string;
args?: Array<unknown>;
Expand All @@ -15,6 +27,8 @@ export class QueryResult {
public rowDescription!: RowDescription;
private _done = false;
public rows: any[] = []; // actual results
public rowCount?: number;
public command!: CommandType;

constructor(public query: Query) {}

Expand Down Expand Up @@ -48,6 +62,20 @@ export class QueryResult {
this.rows.push(parsedRow);
}

handleCommandComplete(commandTag: string): void {
const match = commandTagRegexp.exec(commandTag);
if (match) {
this.command = match[1] as CommandType;
if (match[3]) {
// COMMAND OID ROWS
this.rowCount = parseInt(match[3], 10);
} else {
// COMMAND ROWS
this.rowCount = parseInt(match[2], 10);
}
}
}

rowsOfObjects() {
return this.rows.map((row) => {
const rv: { [key: string]: any } = {};
Expand Down
55 changes: 55 additions & 0 deletions tests/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Client } from "../mod.ts";
import { assertEquals } from "../test_deps.ts";
import { DEFAULT_SETUP, TEST_CONNECTION_PARAMS } from "./constants.ts";
import { getTestClient } from "./helpers.ts";
import { QueryResult } from "../query.ts";

const CLIENT = new Client(TEST_CONNECTION_PARAMS);

Expand Down Expand Up @@ -136,3 +137,57 @@ testClient(async function multiQueryWithManyQueryTypeArray() {

assertEquals(result[2].rows.length, 2);
});

testClient(async function resultMetadata() {
let result: QueryResult;

// simple select
result = await CLIENT.query("SELECT * FROM ids WHERE id = 100");
assertEquals(result.command, "SELECT");
assertEquals(result.rowCount, 1);

// parameterized select
result = await CLIENT.query(
"SELECT * FROM ids WHERE id IN ($1, $2)",
200,
300,
);
assertEquals(result.command, "SELECT");
assertEquals(result.rowCount, 2);

// simple delete
result = await CLIENT.query("DELETE FROM ids WHERE id IN (100, 200)");
assertEquals(result.command, "DELETE");
assertEquals(result.rowCount, 2);

// parameterized delete
result = await CLIENT.query("DELETE FROM ids WHERE id = $1", 300);
assertEquals(result.command, "DELETE");
assertEquals(result.rowCount, 1);

// simple insert
result = await CLIENT.query("INSERT INTO ids VALUES (4), (5)");
assertEquals(result.command, "INSERT");
assertEquals(result.rowCount, 2);

// parameterized insert
result = await CLIENT.query("INSERT INTO ids VALUES ($1)", 3);
assertEquals(result.command, "INSERT");
assertEquals(result.rowCount, 1);

// simple update
result = await CLIENT.query(
"UPDATE ids SET id = 500 WHERE id IN (500, 600)",
);
assertEquals(result.command, "UPDATE");
assertEquals(result.rowCount, 2);

// parameterized update
result = await CLIENT.query("UPDATE ids SET id = 400 WHERE id = $1", 400);
assertEquals(result.command, "UPDATE");
assertEquals(result.rowCount, 1);
}, [
"DROP TABLE IF EXISTS ids",
"CREATE UNLOGGED TABLE ids (id integer)",
"INSERT INTO ids VALUES (100), (200), (300), (400), (500), (600)",
]);

0 comments on commit a712453

Please sign in to comment.