diff --git a/types/pg-query-stream/pg-query-stream-tests.ts b/types/pg-query-stream/pg-query-stream-tests.ts index 6c4c034102..1df78ea648 100644 --- a/types/pg-query-stream/pg-query-stream-tests.ts +++ b/types/pg-query-stream/pg-query-stream-tests.ts @@ -8,7 +8,8 @@ const options: QueryStream.Options = { const query = new QueryStream('SELECT * FROM generate_series(0, $1) num', [1000000], options); -pg.connect('', (err, client, done) => { +const pool = new pg.Pool(); +pool.connect((err, client, done) => { const stream = client.query(query); stream.on('end', () => { client.end(); @@ -17,3 +18,4 @@ pg.connect('', (err, client, done) => { console.log(data); }); }); +pool.end(); diff --git a/types/pg/index.d.ts b/types/pg/index.d.ts index 258188c937..c6d82869c3 100644 --- a/types/pg/index.d.ts +++ b/types/pg/index.d.ts @@ -1,6 +1,6 @@ -// Type definitions for pg 6.1 +// Type definitions for pg 7.1 // Project: https://github.com/brianc/node-postgres -// Definitions by: Phips Peter +// Definitions by: Phips Peter // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped /// @@ -9,16 +9,13 @@ import events = require("events"); import stream = require("stream"); import pgTypes = require("pg-types"); -export declare function connect(connection: string, callback: (err: Error, client: Client, done: (err?: any) => void) => void): void; -export declare function connect(config: ClientConfig, callback: (err: Error, client: Client, done: (err?: any) => void) => void): void; -export declare function end(): void; - export interface ConnectionConfig { user?: string; database?: string; password?: string; port?: number; host?: string; + connectionString?: string; } export interface Defaults extends ConnectionConfig { @@ -39,10 +36,9 @@ export interface PoolConfig extends ClientConfig { // properties from module 'node-pool' max?: number; min?: number; - refreshIdle?: boolean; + connectionTimeoutMillis?: number; idleTimeoutMillis?: number; - reapIntervalMillis?: number; - returnToHead?: boolean; + application_name?: string; Promise?: PromiseConstructorLike; } @@ -61,30 +57,34 @@ export interface QueryResult { } export interface Notification { - processId: number, - channel: string, - payload?: string + processId: number; + channel: string; + payload?: string; } export interface ResultBuilder extends QueryResult { addRow(row: any): void; } -export declare class Pool extends events.EventEmitter { +export class Pool extends events.EventEmitter { // `new Pool('pg://user@localhost/mydb')` is not allowed. // But it passes type check because of issue: // https://github.com/Microsoft/TypeScript/issues/7485 constructor(config?: PoolConfig); + readonly totalCount: number; + readonly idleCount: number; + readonly waitingCount: number; + connect(): Promise; connect(callback: (err: Error, client: Client, done: () => void) => void): void; - end(callback?: () => void): Promise; + end(): Promise; + end(callback: () => void): void; query(queryStream: QueryConfig & stream.Readable): stream.Readable; - query(queryTextOrConfig: string | QueryConfig): Promise; - query(queryText: string, values: any[]): Promise; - + query(queryConfig: QueryConfig): Promise; + query(queryText: string, values?: any[]): Promise; query(queryTextOrConfig: string | QueryConfig, callback: (err: Error, result: QueryResult) => void): Query; query(queryText: string, values: any[], callback: (err: Error, result: QueryResult) => void): Query; @@ -92,18 +92,20 @@ export declare class Pool extends events.EventEmitter { on(event: "connect" | "acquire", listener: (client: Client) => void): this; } -export declare class Client extends events.EventEmitter { - constructor(connection: string); +export class Client extends events.EventEmitter { constructor(config: ClientConfig); - connect(callback?: (err: Error) => void): void; - end(callback?: (err: Error) => void): void; + 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(queryTextOrConfig: string | QueryConfig): Promise; - query(queryText: string, values: any[]): Promise; - + query(queryConfig: QueryConfig): Promise; + query(queryText: string, values?: any[]): Promise; query(queryTextOrConfig: string | QueryConfig, callback: (err: Error, result: QueryResult) => void): Query; query(queryText: string, values: any[], callback: (err: Error, result: QueryResult) => void): Query; @@ -116,16 +118,17 @@ export declare class Client extends events.EventEmitter { on(event: "drain", listener: () => void): this; on(event: "error", listener: (err: Error) => void): this; on(event: "notification" | "notice", listener: (message: Notification) => void): this; + // tslint:disable-next-line unified-signatures on(event: "end", listener: () => void): this; } -export declare class Query extends events.EventEmitter { +export class Query extends events.EventEmitter { on(event: "row", listener: (row: any, result?: ResultBuilder) => void): this; on(event: "error", listener: (err: Error) => void): this; on(event: "end", listener: (result: ResultBuilder) => void): this; } -export declare class Events extends events.EventEmitter { +export class Events extends events.EventEmitter { on(event: "error", listener: (err: Error, client: Client) => void): this; } diff --git a/types/pg/pg-tests.ts b/types/pg/pg-tests.ts index 4b4cfba7ec..1f1e312544 100644 --- a/types/pg/pg-tests.ts +++ b/types/pg/pg-tests.ts @@ -1,39 +1,24 @@ import * as pg from "pg"; -var conString = "postgres://username:password@localhost/database"; - // https://github.com/brianc/node-pg-types +// tslint:disable-next-line no-unnecessary-callback-wrapper pg.types.setTypeParser(20, val => Number(val)); -// Client pooling -pg.defaults.ssl = true; -pg.connect(conString, (err, client, done) => { - if (err) { - return console.error("Error fetching client from pool", err); - } - client.query("SELECT $1::int AS number", ["1"], (err, result) => { - if (err) { - done(err); - return console.error("Error running query", err); - } - else { - done(); - } - console.log(result.rows[0]["number"]); - return null; - }); - return null; +const client = new pg.Client({ + host: 'my.database-server.com', + port: 5334, + user: 'database-user', + password: 'secretpassword!!', }); - -// Simple -var client = new pg.Client(conString); client.connect(err => { if (err) { - return console.error("Could not connect to postgres", err); + console.error("Could not connect to postgres", err); + return; } client.query("SELECT NOW() AS 'theTime'", (err, result) => { if (err) { - return console.error("Error running query", err); + console.error("Error running query", err); + return; } console.log(result.rowCount); console.log(result.rows[0]["theTime"]); @@ -44,38 +29,108 @@ client.connect(err => { }); client.on('end', () => console.log("Client was disconnected.")); -// client pooling +client.connect() + .then(() => console.log('connected')) + .catch(e => console.error('connection error', e.stack)); -var config = { - user: 'foo', //env var: PGUSER - database: 'my_db', //env var: PGDATABASE - password: 'secret', //env var: PGPASSWORD - port: 5432, //env var: PGPORT - max: 10, // max number of clients in the pool - idleTimeoutMillis: 30000, // how long a client is allowed to remain idle before being closed - Promise, +client.query('SELECT NOW()', (err, res) => { + if (err) throw err; + console.log(res); + client.end(); +}); + +client.query('SELECT $1::text as name', ['brianc'], (err, res) => { + if (err) throw err; + console.log(res); + client.end(); +}); + +const query = { + name: 'get-name', + text: 'SELECT $1::text', + values: ['brianc'], + rowMode: 'array' }; -var pool = new pg.Pool(config); +client.query(query, (err, res) => { + if (err) { + console.error(err.stack); + } else { + console.log(res.rows); + } +}); +client.query(query) + .then(res => { + console.log(res.rows); + }) + .catch(e => { + console.error(e.stack); + }); +client.end((err) => { + console.log('client has disconnected'); + if (err) { + console.log('error during disconnection', err.stack); + } +}); + +client.end() + .then(() => console.log('client has disconnected')) + .catch(err => console.error('error during disconnection', err.stack)); + +const poolOne = new pg.Pool({ + connectionString: 'postgresql://dbuser:secretpassword@database.server.com:3211/mydb' +}); + +const pool = new pg.Pool({ + host: 'localhost', + port: 5432, + user: 'database-user', + database: 'my_db', + max: 20, + idleTimeoutMillis: 30000, + connectionTimeoutMillis: 2000, +}); +console.log(pool.totalCount); pool.connect((err, client, done) => { - if(err) { - return console.error('error fetching client from pool', err); + if (err) { + console.error('error fetching client from pool', err); + return; } client.query('SELECT $1::int AS number', ['1'], (err, result) => { done(); - if(err) { - return console.error('error running query', err); + if (err) { + console.error('error running query', err); + return; } console.log(result.rows[0].number); }); }); pool.on('error', (err, client) => { - console.error('idle client error', err.message, err.stack) -}) - -pool.end(); -pool.end(() => { - console.log("pool is closed"); + console.error('idle client error', err.message, err.stack); }); + +pool.query('SELECT $1::text as name', ['brianc'], (err, result) => { + if (err) { + console.error('Error executing query', err.stack); + return; + } + console.log(result.rows[0].name); +}); + +pool.query('SELECT $1::text as name', ['brianc']) + .then((res) => console.log(res.rows[0].name)) + .catch(err => console.error('Error executing query', err.stack)); + +pool.end(() => { + console.log('pool has ended'); +}); + +pool.end().then(() => console.log('pool has ended')); + +(async () => { + const client = await pool.connect(); + await client.query('SELECT NOW()'); + client.release(); +})(); diff --git a/types/pg/tsconfig.json b/types/pg/tsconfig.json index 3535f4d43f..caa997a916 100644 --- a/types/pg/tsconfig.json +++ b/types/pg/tsconfig.json @@ -4,9 +4,10 @@ "lib": [ "es6" ], + "target": "es6", "noImplicitAny": true, "noImplicitThis": true, - "strictNullChecks": false, + "strictNullChecks": true, "baseUrl": "../", "typeRoots": [ "../" @@ -19,4 +20,4 @@ "index.d.ts", "pg-tests.ts" ] -} \ No newline at end of file +} diff --git a/types/pg/tslint.json b/types/pg/tslint.json new file mode 100644 index 0000000000..495d29983d --- /dev/null +++ b/types/pg/tslint.json @@ -0,0 +1,5 @@ +{ + "extends": "dtslint/dt.json", + "rules": { + } +} diff --git a/types/pg/v6/index.d.ts b/types/pg/v6/index.d.ts new file mode 100644 index 0000000000..5624989ac7 --- /dev/null +++ b/types/pg/v6/index.d.ts @@ -0,0 +1,128 @@ +// Type definitions for pg 6.1 +// Project: https://github.com/brianc/node-postgres +// Definitions by: Phips Peter +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +/// + +import events = require("events"); +import stream = require("stream"); +import pgTypes = require("pg-types"); + +export declare function connect(connection: string, callback: (err: Error, client: Client, done: (err?: any) => void) => void): void; +export declare function connect(config: ClientConfig, callback: (err: Error, client: Client, done: (err?: any) => void) => void): void; +export declare function end(): void; + +export interface ConnectionConfig { + user?: string; + database?: string; + password?: string; + port?: number; + host?: string; +} + +export interface Defaults extends ConnectionConfig { + poolSize?: number; + poolIdleTimeout?: number; + reapIntervalMillis?: number; + binary?: boolean; + parseInt8?: boolean; +} + +import { TlsOptions } from "tls"; + +export interface ClientConfig extends ConnectionConfig { + ssl?: boolean | TlsOptions; +} + +export interface PoolConfig extends ClientConfig { + // properties from module 'node-pool' + max?: number; + min?: number; + refreshIdle?: boolean; + idleTimeoutMillis?: number; + reapIntervalMillis?: number; + returnToHead?: boolean; + application_name?: string; + Promise?: PromiseConstructorLike; +} + +export interface QueryConfig { + name?: string; + text: string; + values?: any[]; +} + +export interface QueryResult { + command: string; + rowCount: number; + oid: number; + rows: any[]; +} + +export interface ResultBuilder extends QueryResult { + addRow(row: any): void; +} + +export declare class Pool extends events.EventEmitter { + // `new Pool('pg://user@localhost/mydb')` is not allowed. + // But it passes type check because of issue: + // https://github.com/Microsoft/TypeScript/issues/7485 + constructor(config?: PoolConfig); + + connect(): Promise; + connect(callback: (err: Error, client: Client, done: () => void) => void): void; + + end(callback?: () => void): Promise; + + query(queryStream: QueryConfig & stream.Readable): stream.Readable; + query(queryTextOrConfig: string | QueryConfig): Promise; + query(queryText: string, values: any[]): Promise; + + 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; +} + +export declare class Client extends events.EventEmitter { + constructor(connection: string); + constructor(config: ClientConfig); + + connect(callback?: (err: Error) => void): void; + end(callback?: (err: Error) => void): void; + release(err?: Error): void; + + query(queryStream: QueryConfig & stream.Readable): stream.Readable; + query(queryTextOrConfig: string | QueryConfig): Promise; + query(queryText: string, values: any[]): Promise; + + query(queryTextOrConfig: string | QueryConfig, callback: (err: Error, result: QueryResult) => void): Query; + query(queryText: string, values: any[], callback: (err: Error, result: QueryResult) => void): Query; + + copyFrom(queryText: string): stream.Writable; + copyTo(queryText: string): stream.Readable; + + pauseDrain(): void; + resumeDrain(): void; + + on(event: "drain", listener: () => void): this; + on(event: "error", listener: (err: Error) => void): this; + on(event: "notification" | "notice", listener: (message: any) => void): this; + on(event: "end", listener: () => void): this; +} + +export declare class Query extends events.EventEmitter { + on(event: "row", listener: (row: any, result?: ResultBuilder) => void): this; + on(event: "error", listener: (err: Error) => void): this; + on(event: "end", listener: (result: ResultBuilder) => void): this; +} + +export declare class Events extends events.EventEmitter { + on(event: "error", listener: (err: Error, client: Client) => void): this; +} + +export const types: typeof pgTypes; + +export const defaults: Defaults & ClientConfig; diff --git a/types/pg/v6/pg-tests.ts b/types/pg/v6/pg-tests.ts new file mode 100644 index 0000000000..4b4cfba7ec --- /dev/null +++ b/types/pg/v6/pg-tests.ts @@ -0,0 +1,81 @@ +import * as pg from "pg"; + +var conString = "postgres://username:password@localhost/database"; + +// https://github.com/brianc/node-pg-types +pg.types.setTypeParser(20, val => Number(val)); + +// Client pooling +pg.defaults.ssl = true; +pg.connect(conString, (err, client, done) => { + if (err) { + return console.error("Error fetching client from pool", err); + } + client.query("SELECT $1::int AS number", ["1"], (err, result) => { + if (err) { + done(err); + return console.error("Error running query", err); + } + else { + done(); + } + console.log(result.rows[0]["number"]); + return null; + }); + return null; +}); + +// Simple +var client = new pg.Client(conString); +client.connect(err => { + if (err) { + return console.error("Could not connect to postgres", err); + } + client.query("SELECT NOW() AS 'theTime'", (err, result) => { + if (err) { + return console.error("Error running query", err); + } + console.log(result.rowCount); + console.log(result.rows[0]["theTime"]); + client.end(); + return null; + }); + return null; +}); +client.on('end', () => console.log("Client was disconnected.")); + +// client pooling + +var config = { + user: 'foo', //env var: PGUSER + database: 'my_db', //env var: PGDATABASE + password: 'secret', //env var: PGPASSWORD + port: 5432, //env var: PGPORT + max: 10, // max number of clients in the pool + idleTimeoutMillis: 30000, // how long a client is allowed to remain idle before being closed + Promise, +}; +var pool = new pg.Pool(config); + +pool.connect((err, client, done) => { + if(err) { + return console.error('error fetching client from pool', err); + } + client.query('SELECT $1::int AS number', ['1'], (err, result) => { + done(); + + if(err) { + return console.error('error running query', err); + } + console.log(result.rows[0].number); + }); +}); + +pool.on('error', (err, client) => { + console.error('idle client error', err.message, err.stack) +}) + +pool.end(); +pool.end(() => { + console.log("pool is closed"); +}); diff --git a/types/pg/v6/tsconfig.json b/types/pg/v6/tsconfig.json new file mode 100644 index 0000000000..2c44f5862b --- /dev/null +++ b/types/pg/v6/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": false, + "baseUrl": "../../", + "typeRoots": [ + "../../" + ], + "paths": { + "pg": [ "pg/v6" ] + }, + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "pg-tests.ts" + ] +}