Skip to content
This repository was archived by the owner on Jan 12, 2024. It is now read-only.

Commit ff069eb

Browse files
Dliu/pg browser (#1)
* Changes for websockets and cursors * Add pg browser * Clean up webpack config file * Fix yarn.lock * Modify pg tests * Update packages/pg-cursor/index.js Co-authored-by: Jonathan Mortensen <[email protected]> * Comment clarifications * Update packages/pg-cursor/index.js Co-authored-by: Jonathan Mortensen <[email protected]> * Add comment to connection.end * Add back original IP/hostname functionality * Add 130-tests.js back into test suite * Restore original integration/connection/test-helper * Change some devDependencies back to dependencies * Remove status message logging * Fix stream placeholder logic * Send closing code + status on connection end * Remove commented out original tests * Add simple performance test file * Add cursor -> select example * Add yarn.lock * Add messages.d.ts Co-authored-by: Jonathan Mortensen <[email protected]>
1 parent 21ccd4f commit ff069eb

31 files changed

+47150
-3605
lines changed

package.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,21 @@
2424
"eslint-config-prettier": "^6.12.0",
2525
"eslint-plugin-node": "^11.1.0",
2626
"eslint-plugin-prettier": "^3.1.4",
27-
"lerna": "^3.19.0",
27+
"lerna": "^4.0.0",
2828
"prettier": "2.1.2",
29-
"typescript": "^4.0.3"
29+
"typescript": "^4.0.3",
30+
"webpack-cli": "^4.9.2"
3031
},
3132
"prettier": {
3233
"semi": false,
3334
"printWidth": 120,
3435
"arrowParens": "always",
3536
"trailingComma": "es5",
3637
"singleQuote": true
38+
},
39+
"dependencies": {
40+
"is-ip": "^4.0.0",
41+
"pg": "^8.7.3",
42+
"websocket-stream": "^5.5.2"
3743
}
3844
}

packages/pg-connection-string/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"chai": "^4.1.1",
3131
"coveralls": "^3.0.4",
3232
"istanbul": "^0.4.5",
33-
"mocha": "^7.1.2"
33+
"mocha": "^9.2.0"
3434
},
3535
"files": [
3636
"index.js",

packages/pg-cursor/index.js

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class Cursor extends EventEmitter {
2323
this._portal = null
2424
this._ifNoData = this._ifNoData.bind(this)
2525
this._rowDescription = this._rowDescription.bind(this)
26+
this.moveAllAndClosing = false
2627
}
2728

2829
_ifNoData() {
@@ -42,7 +43,8 @@ class Cursor extends EventEmitter {
4243
submit(connection) {
4344
this.state = 'submitted'
4445
this.connection = connection
45-
this._portal = 'C_' + nextUniqueID++
46+
// the portal name must start with a lowercase c, for some reason
47+
this._portal = 'c_' + nextUniqueID++
4648

4749
const con = connection
4850

@@ -133,7 +135,9 @@ class Cursor extends EventEmitter {
133135

134136
handleCommandComplete(msg) {
135137
this._result.addCommandComplete(msg)
136-
this._closePortal()
138+
if (!this.moveAllAndClosing) {
139+
this._closePortal()
140+
}
137141
}
138142

139143
handlePortalSuspended() {
@@ -202,6 +206,49 @@ class Cursor extends EventEmitter {
202206
this.connection.end()
203207
}
204208

209+
_promisifiedQuery(text) {
210+
return new Promise((resolve, reject) => {
211+
try {
212+
var res = this.connection.query(text)
213+
resolve(res)
214+
} catch (e) {
215+
reject(e)
216+
}
217+
})
218+
}
219+
220+
moveAllAndClose(cb) {
221+
this.moveAllAndClosing = true
222+
if (this.state === 'done' || this.state == 'error') {
223+
return this.close(cb)
224+
}
225+
return this._promisifiedQuery("MOVE ALL FROM " + this._portal).then(() => {
226+
this._close_checkFinished(cb)
227+
})
228+
}
229+
230+
_close_checkFinished(cb) {
231+
this._closePortal()
232+
// delay the callback until portal is finished closing
233+
// (this means a closeComplete followed by a readyForQuery)
234+
// (when moveAllAndClose calls closePortal, client will receive a readyForQuery generated by "MOVE ALL" simple query before receiving a closeComplete and a subsequent readyForQuery)
235+
var finishedClosing = false
236+
this.connection.once('closeComplete', function () {
237+
finishedClosing = true
238+
})
239+
240+
const _handleReadyForQueryInClose = () => {
241+
if (finishedClosing) {
242+
cb()
243+
this.moveAllAndClosing = false
244+
this.connection.removeListener('readyForQuery', _handleReadyForQueryInClose)
245+
}
246+
}
247+
248+
this.connection.on('readyForQuery', _handleReadyForQueryInClose)
249+
return
250+
}
251+
205252
close(cb) {
206253
let promise
207254

packages/pg-cursor/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"author": "Brian M. Carlson",
1818
"license": "MIT",
1919
"devDependencies": {
20-
"mocha": "^7.1.2",
20+
"mocha": "^9.2.1",
2121
"pg": "^8.7.3"
2222
},
2323
"peerDependencies": {

packages/pg-pool/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ class Pool extends EventEmitter {
8686
this.options.allowExitOnIdle = this.options.allowExitOnIdle || false
8787
this.options.maxLifetimeSeconds = this.options.maxLifetimeSeconds || 0
8888
this.log = this.options.log || function () {}
89-
this.Client = this.options.Client || Client || require('pg').Client
89+
this.Client = this.options.Client || Client || require('../pg/lib/index.js').Client
9090
this.Promise = this.options.Promise || global.Promise
9191

9292
if (typeof this.options.idleTimeoutMillis === 'undefined') {

packages/pg-pool/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
"co": "4.6.0",
3232
"expect.js": "0.3.1",
3333
"lodash": "^4.17.11",
34-
"mocha": "^7.1.2",
34+
"mocha": "^9.2.0",
3535
"pg-cursor": "^1.3.0"
3636
},
3737
"peerDependencies": {
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
/// <reference types="node" />
2+
export declare type Mode = 'text' | 'binary';
3+
export declare type MessageName = 'parseComplete' | 'bindComplete' | 'closeComplete' | 'noData' | 'portalSuspended' | 'replicationStart' | 'emptyQuery' | 'copyDone' | 'copyData' | 'rowDescription' | 'parameterDescription' | 'parameterStatus' | 'backendKeyData' | 'notification' | 'readyForQuery' | 'commandComplete' | 'dataRow' | 'copyInResponse' | 'copyOutResponse' | 'authenticationOk' | 'authenticationMD5Password' | 'authenticationCleartextPassword' | 'authenticationSASL' | 'authenticationSASLContinue' | 'authenticationSASLFinal' | 'error' | 'notice';
4+
export interface BackendMessage {
5+
name: MessageName;
6+
length: number;
7+
}
8+
export declare const parseComplete: BackendMessage;
9+
export declare const bindComplete: BackendMessage;
10+
export declare const closeComplete: BackendMessage;
11+
export declare const noData: BackendMessage;
12+
export declare const portalSuspended: BackendMessage;
13+
export declare const replicationStart: BackendMessage;
14+
export declare const emptyQuery: BackendMessage;
15+
export declare const copyDone: BackendMessage;
16+
interface NoticeOrError {
17+
message: string | undefined;
18+
severity: string | undefined;
19+
code: string | undefined;
20+
detail: string | undefined;
21+
hint: string | undefined;
22+
position: string | undefined;
23+
internalPosition: string | undefined;
24+
internalQuery: string | undefined;
25+
where: string | undefined;
26+
schema: string | undefined;
27+
table: string | undefined;
28+
column: string | undefined;
29+
dataType: string | undefined;
30+
constraint: string | undefined;
31+
file: string | undefined;
32+
line: string | undefined;
33+
routine: string | undefined;
34+
}
35+
export declare class DatabaseError extends Error implements NoticeOrError {
36+
readonly length: number;
37+
readonly name: MessageName;
38+
severity: string | undefined;
39+
code: string | undefined;
40+
detail: string | undefined;
41+
hint: string | undefined;
42+
position: string | undefined;
43+
internalPosition: string | undefined;
44+
internalQuery: string | undefined;
45+
where: string | undefined;
46+
schema: string | undefined;
47+
table: string | undefined;
48+
column: string | undefined;
49+
dataType: string | undefined;
50+
constraint: string | undefined;
51+
file: string | undefined;
52+
line: string | undefined;
53+
routine: string | undefined;
54+
constructor(message: string, length: number, name: MessageName);
55+
}
56+
export declare class CopyDataMessage {
57+
readonly length: number;
58+
readonly chunk: Buffer;
59+
readonly name = "copyData";
60+
constructor(length: number, chunk: Buffer);
61+
}
62+
export declare class CopyResponse {
63+
readonly length: number;
64+
readonly name: MessageName;
65+
readonly binary: boolean;
66+
readonly columnTypes: number[];
67+
constructor(length: number, name: MessageName, binary: boolean, columnCount: number);
68+
}
69+
export declare class Field {
70+
readonly name: string;
71+
readonly tableID: number;
72+
readonly columnID: number;
73+
readonly dataTypeID: number;
74+
readonly dataTypeSize: number;
75+
readonly dataTypeModifier: number;
76+
readonly format: Mode;
77+
constructor(name: string, tableID: number, columnID: number, dataTypeID: number, dataTypeSize: number, dataTypeModifier: number, format: Mode);
78+
}
79+
export declare class RowDescriptionMessage {
80+
readonly length: number;
81+
readonly fieldCount: number;
82+
readonly name: MessageName;
83+
readonly fields: Field[];
84+
constructor(length: number, fieldCount: number);
85+
}
86+
export declare class ParameterDescriptionMessage {
87+
readonly length: number;
88+
readonly parameterCount: number;
89+
readonly name: MessageName;
90+
readonly dataTypeIDs: number[];
91+
constructor(length: number, parameterCount: number);
92+
}
93+
export declare class ParameterStatusMessage {
94+
readonly length: number;
95+
readonly parameterName: string;
96+
readonly parameterValue: string;
97+
readonly name: MessageName;
98+
constructor(length: number, parameterName: string, parameterValue: string);
99+
}
100+
export declare class AuthenticationMD5Password implements BackendMessage {
101+
readonly length: number;
102+
readonly salt: Buffer;
103+
readonly name: MessageName;
104+
constructor(length: number, salt: Buffer);
105+
}
106+
export declare class BackendKeyDataMessage {
107+
readonly length: number;
108+
readonly processID: number;
109+
readonly secretKey: number;
110+
readonly name: MessageName;
111+
constructor(length: number, processID: number, secretKey: number);
112+
}
113+
export declare class NotificationResponseMessage {
114+
readonly length: number;
115+
readonly processId: number;
116+
readonly channel: string;
117+
readonly payload: string;
118+
readonly name: MessageName;
119+
constructor(length: number, processId: number, channel: string, payload: string);
120+
}
121+
export declare class ReadyForQueryMessage {
122+
readonly length: number;
123+
readonly status: string;
124+
readonly name: MessageName;
125+
constructor(length: number, status: string);
126+
}
127+
export declare class CommandCompleteMessage {
128+
readonly length: number;
129+
readonly text: string;
130+
readonly name: MessageName;
131+
constructor(length: number, text: string);
132+
}
133+
export declare class DataRowMessage {
134+
length: number;
135+
fields: any[];
136+
readonly fieldCount: number;
137+
readonly name: MessageName;
138+
constructor(length: number, fields: any[]);
139+
}
140+
export declare class NoticeMessage implements BackendMessage, NoticeOrError {
141+
readonly length: number;
142+
readonly message: string | undefined;
143+
constructor(length: number, message: string | undefined);
144+
readonly name = "notice";
145+
severity: string | undefined;
146+
code: string | undefined;
147+
detail: string | undefined;
148+
hint: string | undefined;
149+
position: string | undefined;
150+
internalPosition: string | undefined;
151+
internalQuery: string | undefined;
152+
where: string | undefined;
153+
schema: string | undefined;
154+
table: string | undefined;
155+
column: string | undefined;
156+
dataType: string | undefined;
157+
constraint: string | undefined;
158+
file: string | undefined;
159+
line: string | undefined;
160+
routine: string | undefined;
161+
}
162+
export {};

packages/pg-protocol/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"@types/node": "^12.12.21",
1212
"chai": "^4.2.0",
1313
"chunky": "^0.0.0",
14-
"mocha": "^7.1.2",
14+
"mocha": "^9.2.0",
1515
"ts-node": "^8.5.4",
1616
"typescript": "^4.0.3"
1717
},

packages/pg-query-stream/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@
3333
"@types/mocha": "^8.0.3",
3434
"@types/node": "^14.0.0",
3535
"@types/pg": "^7.14.5",
36-
"JSONStream": "~0.7.1",
3736
"concat-stream": "~1.0.1",
3837
"eslint-plugin-promise": "^3.5.0",
39-
"mocha": "^7.1.2",
38+
"JSONStream": "~0.7.1",
39+
"mocha": "^9.2.0",
4040
"pg": "^8.7.3",
4141
"stream-spec": "~0.3.5",
4242
"stream-tester": "0.0.5",

packages/pg/Makefile

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ test-connection:
3333
@echo "***Testing connection***"
3434
@node script/create-test-tables.js $(params)
3535

36+
test-unit-connection: test-connection
37+
@find test/unit/connection -name "*-tests.js" | $(node-command)
38+
3639
test-missing-native:
3740
@echo "***Testing optional native install***"
3841
@rm -rf node_modules/pg-native
@@ -53,6 +56,26 @@ test-integration: test-connection
5356
@echo "***Testing Pure Javascript***"
5457
@find test/integration -name "*-tests.js" | $(node-command)
5558

59+
test-integration-client: test-connection
60+
@echo "***Testing integration for client***"
61+
@find test/integration/client -name "*-tests.js" | $(node-command)
62+
63+
test-integration-connection: test-connection
64+
@echo "***Testing integration for connection***"
65+
@find test/integration/connection -name "*-tests.js" | $(node-command)
66+
67+
test-integration-connection-pool: test-connection
68+
@echo "***Testing integration for connection***"
69+
@find test/integration/connection-pool -name "*-tests.js" | $(node-command)
70+
71+
test-gh-issues: test-connection
72+
@echo "***Testing gh-issues***"
73+
@find test/integration/gh-issues -name "*-tests.js" | $(node-command)
74+
75+
test-unit-client: test-connection
76+
@echo "***Testing integration for client***"
77+
@find test/unit/client -name "*-tests.js" | $(node-command)
78+
5679
test-binary: test-connection
5780
@echo "***Testing Pure Javascript (binary)***"
5881
@find test/integration -name "*-tests.js" | $(node-command) binary

0 commit comments

Comments
 (0)