From 29e106a36b77f6615a9d08f9a7bf127cd89e0487 Mon Sep 17 00:00:00 2001 From: Chris Reeves Date: Tue, 30 Jan 2018 04:14:51 -0500 Subject: [PATCH 1/3] [pg] add special types for array mode queries --- types/pg/index.d.ts | 41 +++++++++++++++++++++++++++++++++-------- types/pg/pg-tests.ts | 30 ++++++++++++++++++++++++++++-- 2 files changed, 61 insertions(+), 10 deletions(-) diff --git a/types/pg/index.d.ts b/types/pg/index.d.ts index 9f945082cd..dde341eba4 100644 --- a/types/pg/index.d.ts +++ b/types/pg/index.d.ts @@ -33,21 +33,24 @@ export interface ClientConfig extends ConnectionConfig { } export interface PoolConfig extends ClientConfig { - // properties from module 'node-pool' - max?: number; - min?: number; - connectionTimeoutMillis?: number; - idleTimeoutMillis?: number; + // properties from module 'node-pool' + max?: number; + min?: number; + connectionTimeoutMillis?: number; + idleTimeoutMillis?: number; - application_name?: string; - Promise?: PromiseConstructorLike; + application_name?: string; + Promise?: PromiseConstructorLike; } export interface QueryConfig { name?: string; text: string; values?: any[]; - rowMode?: string; +} + +export interface QueryArrayConfig extends QueryConfig { + rowMode: 'array'; } export interface QueryResult { @@ -57,6 +60,24 @@ export interface QueryResult { rows: any[]; } +export interface FieldDef { + name: string; + tableID: number; + columnID: number; + dataTypeID: number; + dataTypeSize: number; + dataTypeModifier: number; + format: string; +} + +export interface QueryArrayResult { + command: string; + rowCount: number; + oid: number; + rows: any[][]; + fields: FieldDef[]; +} + export interface Notification { processId: number; channel: string; @@ -84,8 +105,10 @@ export class Pool extends events.EventEmitter { end(callback: () => void): void; query(queryStream: QueryConfig & stream.Readable): stream.Readable; + query(queryConfig: QueryArrayConfig): Promise; query(queryConfig: QueryConfig): Promise; query(queryText: string, values?: any[]): Promise; + query(queryConfig: QueryArrayConfig, callback: (err: Error, result: QueryArrayResult) => void): Query; query(queryTextOrConfig: string | QueryConfig, callback: (err: Error, result: QueryResult) => void): Query; query(queryText: string, values: any[], callback: (err: Error, result: QueryResult) => void): Query; @@ -105,8 +128,10 @@ export class Client extends events.EventEmitter { release(err?: Error): void; query(queryStream: QueryConfig & stream.Readable): stream.Readable; + query(queryConfig: QueryArrayConfig): Promise; query(queryConfig: QueryConfig): Promise; query(queryText: string, values?: any[]): Promise; + query(queryConfig: QueryArrayConfig, callback: (err: Error, result: QueryArrayResult) => void): Query; query(queryTextOrConfig: string | QueryConfig, callback: (err: Error, result: QueryResult) => void): Query; query(queryText: string, values: any[], callback: (err: Error, result: QueryResult) => void): Query; diff --git a/types/pg/pg-tests.ts b/types/pg/pg-tests.ts index 1f1e312544..018145856a 100644 --- a/types/pg/pg-tests.ts +++ b/types/pg/pg-tests.ts @@ -48,8 +48,7 @@ client.query('SELECT $1::text as name', ['brianc'], (err, res) => { const query = { name: 'get-name', text: 'SELECT $1::text', - values: ['brianc'], - rowMode: 'array' + values: ['brianc'] }; client.query(query, (err, res) => { if (err) { @@ -66,6 +65,33 @@ client.query(query) console.error(e.stack); }); +const queryArrMode: pg.QueryArrayConfig = { + name: 'get-name-array', + text: 'SELECT $1::text', + values: ['brianc'], + rowMode: 'array' +}; +client.query(queryArrMode, (err, res) => { + if (err) { + console.error(err.stack); + } else { + console.log(res.rows); + console.log(res.fields.map(f => f.name)); + } +}); +client.query(queryArrMode) + .then(res => { + console.log(res.rows); + console.log(res.fields.map(f => f.name)); + }) + .catch(e => { + console.error(e.stack); + }); +client.query({ + text: 'select 1', + rowMode: 'array', +}).then(res => console.log(res.fields[0])); + client.end((err) => { console.log('client has disconnected'); if (err) { From 429ba7aab38c6da97e0686eda917c14397f1a01f Mon Sep 17 00:00:00 2001 From: Chris Reeves Date: Tue, 30 Jan 2018 04:16:05 -0500 Subject: [PATCH 2/3] [pg] differentiate between pooled and non-pooled clients (release vs end) --- types/pg/index.d.ts | 26 ++++++++++++++++---------- types/pg/pg-tests.ts | 6 ++++++ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/types/pg/index.d.ts b/types/pg/index.d.ts index dde341eba4..3876468087 100644 --- a/types/pg/index.d.ts +++ b/types/pg/index.d.ts @@ -98,8 +98,8 @@ export class Pool extends events.EventEmitter { readonly idleCount: number; readonly waitingCount: number; - connect(): Promise; - connect(callback: (err: Error, client: Client, done: () => void) => void): void; + connect(): Promise; + connect(callback: (err: Error, client: PoolClient, done: () => void) => void): void; end(): Promise; end(callback: () => void): void; @@ -112,21 +112,16 @@ export class Pool extends events.EventEmitter { query(queryTextOrConfig: string | QueryConfig, callback: (err: Error, result: QueryResult) => void): Query; query(queryText: string, values: any[], callback: (err: Error, result: QueryResult) => void): Query; - on(event: "error", listener: (err: Error, client: Client) => void): this; - on(event: "connect" | "acquire", listener: (client: Client) => void): this; + on(event: "error", listener: (err: Error, client: PoolClient) => void): this; + on(event: "connect" | "acquire", listener: (client: PoolClient) => void): this; } -export class Client extends events.EventEmitter { +export class ClientBase extends events.EventEmitter { constructor(config: string | ClientConfig); connect(): Promise; connect(callback: (err: Error) => void): void; - end(): Promise; - end(callback: (err: Error) => void): void; - - release(err?: Error): void; - query(queryStream: QueryConfig & stream.Readable): stream.Readable; query(queryConfig: QueryArrayConfig): Promise; query(queryConfig: QueryConfig): Promise; @@ -151,6 +146,17 @@ export class Client extends events.EventEmitter { on(event: "end", listener: () => void): this; } +export class Client extends ClientBase { + constructor(config: string | ClientConfig); + + end(): Promise; + end(callback: (err: Error) => void): void; +} + +export interface PoolClient extends ClientBase { + release(err?: Error): void; +} + export class Query extends events.EventEmitter { on(event: "row", listener: (row: any, result?: ResultBuilder) => void): this; on(event: "error", listener: (err: Error) => void): this; diff --git a/types/pg/pg-tests.ts b/types/pg/pg-tests.ts index 018145856a..b9b3f80d4e 100644 --- a/types/pg/pg-tests.ts +++ b/types/pg/pg-tests.ts @@ -133,6 +133,12 @@ pool.connect((err, client, done) => { }); }); +pool.connect().then(client => { + client.query({ text: 'SELECT $1::int AS number', values: ['1'], rowMode: 'array' }).then(result => { + console.log(result.rowCount, result.rows[0][0], result.fields[0].name); + }).then(() => client.release(), e => client.release(e)); +}); + pool.on('error', (err, client) => { console.error('idle client error', err.message, err.stack); }); From 7c0d23a048709e57e8aa84e110dc97023e874c17 Mon Sep 17 00:00:00 2001 From: Chris Reeves Date: Tue, 30 Jan 2018 04:59:15 -0500 Subject: [PATCH 3/3] [pg-query-stream] pooled clients don't end, they release --- types/pg-query-stream/pg-query-stream-tests.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/pg-query-stream/pg-query-stream-tests.ts b/types/pg-query-stream/pg-query-stream-tests.ts index 1df78ea648..d59286a654 100644 --- a/types/pg-query-stream/pg-query-stream-tests.ts +++ b/types/pg-query-stream/pg-query-stream-tests.ts @@ -12,7 +12,7 @@ const pool = new pg.Pool(); pool.connect((err, client, done) => { const stream = client.query(query); stream.on('end', () => { - client.end(); + client.release(); }); stream.on('data', (data: any) => { console.log(data);