@m2k-5f/pgtx 2.7.2 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -37
- package/dist/batch.d.ts +4 -1
- package/dist/batch.d.ts.map +1 -1
- package/dist/batch.js +14 -7
- package/dist/clauses/fragment.clause.js +1 -1
- package/dist/connection.d.ts +17 -16
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +231 -175
- package/dist/error.d.ts +6 -1
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +26 -7
- package/dist/pool.d.ts +1 -1
- package/dist/pool.d.ts.map +1 -1
- package/dist/pool.js +5 -3
- package/dist/protocol/connection-request-writer.d.ts +107 -11
- package/dist/protocol/connection-request-writer.d.ts.map +1 -1
- package/dist/protocol/connection-request-writer.js +442 -48
- package/dist/protocol/connection-response-reader.d.ts +75 -30
- package/dist/protocol/connection-response-reader.d.ts.map +1 -1
- package/dist/protocol/connection-response-reader.js +285 -289
- package/dist/protocol/constants.d.ts +37 -30
- package/dist/protocol/constants.d.ts.map +1 -1
- package/dist/protocol/constants.js +43 -37
- package/dist/protocol/socket-authorization.d.ts.map +1 -1
- package/dist/protocol/socket-authorization.js +3 -3
- package/dist/protocol/socket-connector.d.ts +4 -4
- package/dist/protocol/socket-connector.d.ts.map +1 -1
- package/dist/protocol/socket-connector.js +2 -2
- package/dist/protocol/types.d.ts +14 -0
- package/dist/protocol/types.d.ts.map +1 -0
- package/dist/protocol/types.js +264 -0
- package/dist/query.d.ts +34 -24
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +45 -30
- package/dist/queue.d.ts +1 -0
- package/dist/queue.d.ts.map +1 -1
- package/dist/queue.js +1 -0
- package/dist/types.d.ts +3 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/template-compiler.d.ts +5 -2
- package/dist/utils/template-compiler.d.ts.map +1 -1
- package/dist/utils/template-compiler.js +4 -1
- package/dist/utils.d.ts +8 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +73 -0
- package/package.json +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { INT4Length } from "./constants";
|
|
2
2
|
import { PostgresError } from "../error";
|
|
3
|
-
|
|
3
|
+
import { handlers } from "./types";
|
|
4
4
|
const POSTGRES_EPOCH_MS = 946684800000;
|
|
5
5
|
export class ConnectionResponseBuffer {
|
|
6
6
|
constructor(buffer) {
|
|
@@ -10,6 +10,25 @@ export class ConnectionResponseBuffer {
|
|
|
10
10
|
static from(buffer) {
|
|
11
11
|
return new ConnectionResponseBuffer(buffer);
|
|
12
12
|
}
|
|
13
|
+
hasMore() {
|
|
14
|
+
return this.caret < this.buffer.length;
|
|
15
|
+
}
|
|
16
|
+
skipBytes(byteCount) {
|
|
17
|
+
this.caret += byteCount;
|
|
18
|
+
}
|
|
19
|
+
hasFullPacket() {
|
|
20
|
+
const availableBytes = this.buffer.length - this.caret;
|
|
21
|
+
if (availableBytes < 5)
|
|
22
|
+
return false;
|
|
23
|
+
const packetLength = this.buffer.readInt32BE(this.caret + 1);
|
|
24
|
+
if (availableBytes < 1 + packetLength)
|
|
25
|
+
return false;
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
getResidualBuffer() {
|
|
29
|
+
return this.buffer.subarray(this.caret);
|
|
30
|
+
}
|
|
31
|
+
// ------ primitives ------
|
|
13
32
|
readChar() {
|
|
14
33
|
const char = String.fromCharCode(this.buffer[this.caret]);
|
|
15
34
|
this.caret += 1;
|
|
@@ -36,111 +55,16 @@ export class ConnectionResponseBuffer {
|
|
|
36
55
|
this.caret += length;
|
|
37
56
|
return text;
|
|
38
57
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
readRawBinaryString(length) {
|
|
43
|
-
const text = this.buffer.toString('latin1', this.caret, this.caret + length);
|
|
44
|
-
this.caret += length;
|
|
45
|
-
return text;
|
|
46
|
-
}
|
|
47
|
-
readBinaryDate() {
|
|
48
|
-
const daysSince2000 = this.readInt32();
|
|
49
|
-
const ms = POSTGRES_EPOCH_MS + (daysSince2000 * 86400000);
|
|
50
|
-
return new Date(ms);
|
|
51
|
-
}
|
|
52
|
-
readBinaryTimestamp() {
|
|
53
|
-
const microSecondsSince2000 = this.readInt64();
|
|
54
|
-
const msSince2000 = Number(microSecondsSince2000 / 1000);
|
|
55
|
-
return new Date(POSTGRES_EPOCH_MS + msSince2000);
|
|
56
|
-
}
|
|
57
|
-
readBinaryTime() {
|
|
58
|
-
const microSecondsSinceMidnight = this.readInt64();
|
|
59
|
-
const totalMs = Number(microSecondsSinceMidnight / 1000);
|
|
60
|
-
const seconds = Math.floor(totalMs / 1000);
|
|
61
|
-
const ms = totalMs % 1000;
|
|
62
|
-
const minutes = Math.floor(seconds / 60);
|
|
63
|
-
const hours = Math.floor(minutes / 60);
|
|
64
|
-
return `${String(hours).padStart(2, '0')}:${String(minutes % 60).padStart(2, '0')}:${String(seconds % 60).padStart(2, '0')}.${String(ms).padStart(3, '0')}`;
|
|
65
|
-
}
|
|
66
|
-
skipBytes(byteCount) {
|
|
67
|
-
this.caret += byteCount;
|
|
68
|
-
}
|
|
69
|
-
hasFullPacket() {
|
|
70
|
-
const availableBytes = this.buffer.length - this.caret;
|
|
71
|
-
if (availableBytes < 5)
|
|
72
|
-
return false;
|
|
73
|
-
const packetLength = this.buffer.readInt32BE(this.caret + 1);
|
|
74
|
-
if (availableBytes < 1 + packetLength)
|
|
75
|
-
return false;
|
|
76
|
-
return true;
|
|
77
|
-
}
|
|
78
|
-
getResidualBuffer() {
|
|
79
|
-
return this.buffer.subarray(this.caret);
|
|
80
|
-
}
|
|
81
|
-
readBool() {
|
|
82
|
-
const value = this.buffer[this.caret] !== 0;
|
|
83
|
-
this.caret++;
|
|
58
|
+
readUInt16() {
|
|
59
|
+
const value = this.buffer.readUInt16BE(this.caret);
|
|
60
|
+
this.caret += 2;
|
|
84
61
|
return value;
|
|
85
62
|
}
|
|
86
|
-
|
|
87
|
-
const value = this.buffer.
|
|
88
|
-
this.caret +=
|
|
63
|
+
readUInt32() {
|
|
64
|
+
const value = this.buffer.readUInt32BE(this.caret);
|
|
65
|
+
this.caret += 4;
|
|
89
66
|
return value;
|
|
90
67
|
}
|
|
91
|
-
readInt64() {
|
|
92
|
-
const hi = this.buffer.readInt32BE(this.caret);
|
|
93
|
-
const lo = this.buffer.readUInt32BE(this.caret + 4);
|
|
94
|
-
this.caret += 8;
|
|
95
|
-
return (hi * 4294967296) + lo;
|
|
96
|
-
}
|
|
97
|
-
readNumeric() {
|
|
98
|
-
const ndigits = this.readInt16();
|
|
99
|
-
const weight = this.readInt16();
|
|
100
|
-
const sign = this.readInt16();
|
|
101
|
-
const dscale = this.readInt16();
|
|
102
|
-
if (sign === 0xC000 || sign === -16384)
|
|
103
|
-
return 'NaN';
|
|
104
|
-
const digits = new Array(ndigits);
|
|
105
|
-
for (let i = 0; i < ndigits; i++) {
|
|
106
|
-
digits[i] = this.readInt16();
|
|
107
|
-
}
|
|
108
|
-
const highExp = Math.max(weight, 0);
|
|
109
|
-
const lowExp = Math.min(weight - ndigits + 1, -1);
|
|
110
|
-
let intPart = '';
|
|
111
|
-
for (let exp = highExp; exp >= 0; exp--) {
|
|
112
|
-
const idx = weight - exp;
|
|
113
|
-
const digit = (idx >= 0 && idx < ndigits) ? digits[idx] : 0;
|
|
114
|
-
intPart += exp === highExp ? String(digit) : String(digit).padStart(4, '0');
|
|
115
|
-
}
|
|
116
|
-
if (intPart === '')
|
|
117
|
-
intPart = '0';
|
|
118
|
-
let fracPart = '';
|
|
119
|
-
for (let exp = -1; exp >= lowExp; exp--) {
|
|
120
|
-
const idx = weight - exp;
|
|
121
|
-
const digit = (idx >= 0 && idx < ndigits) ? digits[idx] : 0;
|
|
122
|
-
fracPart += String(digit).padStart(4, '0');
|
|
123
|
-
}
|
|
124
|
-
if (dscale > 0) {
|
|
125
|
-
fracPart = fracPart.padEnd(dscale, '0').slice(0, dscale);
|
|
126
|
-
}
|
|
127
|
-
else {
|
|
128
|
-
fracPart = '';
|
|
129
|
-
}
|
|
130
|
-
const negative = sign === 0x4000 || sign === 16384;
|
|
131
|
-
const result = fracPart ? `${intPart}.${fracPart}` : intPart;
|
|
132
|
-
return negative ? `-${result}` : result;
|
|
133
|
-
}
|
|
134
|
-
readBinaryTimetz() {
|
|
135
|
-
const time = this.readBinaryTime();
|
|
136
|
-
const zoneOffsetSeconds = this.readInt32();
|
|
137
|
-
const offsetMinutesTotal = -zoneOffsetSeconds / 60;
|
|
138
|
-
const sign = offsetMinutesTotal >= 0 ? '+' : '-';
|
|
139
|
-
const abs = Math.abs(offsetMinutesTotal);
|
|
140
|
-
const offH = Math.floor(abs / 60);
|
|
141
|
-
const offM = abs % 60;
|
|
142
|
-
return `${time}${sign}${String(offH).padStart(2, '0')}:${String(offM).padStart(2, '0')}`;
|
|
143
|
-
}
|
|
144
68
|
readFloat32() {
|
|
145
69
|
const value = this.buffer.readFloatBE(this.caret);
|
|
146
70
|
this.caret += 4;
|
|
@@ -151,13 +75,8 @@ export class ConnectionResponseBuffer {
|
|
|
151
75
|
this.caret += 8;
|
|
152
76
|
return value;
|
|
153
77
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
return buf.toString('hex', 0, 4) + '-' +
|
|
157
|
-
buf.toString('hex', 4, 6) + '-' +
|
|
158
|
-
buf.toString('hex', 6, 8) + '-' +
|
|
159
|
-
buf.toString('hex', 8, 10) + '-' +
|
|
160
|
-
buf.toString('hex', 10, 16);
|
|
78
|
+
readByte() {
|
|
79
|
+
return this.buffer[this.caret++];
|
|
161
80
|
}
|
|
162
81
|
readBytes(length) {
|
|
163
82
|
const result = Buffer.allocUnsafe(length);
|
|
@@ -165,42 +84,42 @@ export class ConnectionResponseBuffer {
|
|
|
165
84
|
this.caret += length;
|
|
166
85
|
return result;
|
|
167
86
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
hash ^= this.buffer[i];
|
|
173
|
-
hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
|
|
174
|
-
}
|
|
175
|
-
return hash >>> 0;
|
|
87
|
+
readBool() {
|
|
88
|
+
const value = this.buffer[this.caret] !== 0;
|
|
89
|
+
this.caret++;
|
|
90
|
+
return value;
|
|
176
91
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
92
|
+
readBigInt64() {
|
|
93
|
+
const value = this.buffer.readBigInt64BE(this.caret);
|
|
94
|
+
this.caret += 8;
|
|
95
|
+
return value;
|
|
181
96
|
}
|
|
182
|
-
|
|
183
|
-
|
|
97
|
+
readInt64() {
|
|
98
|
+
const hi = this.buffer.readInt32BE(this.caret);
|
|
99
|
+
const lo = this.buffer.readUInt32BE(this.caret + 4);
|
|
100
|
+
this.caret += 8;
|
|
101
|
+
return (hi * 4294967296) + lo;
|
|
184
102
|
}
|
|
103
|
+
// ------ commands ------
|
|
185
104
|
readType() {
|
|
186
|
-
return { type: this.
|
|
105
|
+
return { type: this.readByte(), length: this.readInt32() - INT4Length };
|
|
187
106
|
}
|
|
188
107
|
readAuthentication() {
|
|
189
|
-
return this.
|
|
108
|
+
return this.readInt32();
|
|
190
109
|
}
|
|
191
110
|
readMD5Salt() {
|
|
192
|
-
return this.
|
|
111
|
+
return this.readBytes(4);
|
|
193
112
|
}
|
|
194
113
|
readParameterStatus() {
|
|
195
114
|
return {
|
|
196
|
-
name: this.
|
|
197
|
-
value: this.
|
|
115
|
+
name: this.readCString(),
|
|
116
|
+
value: this.readCString()
|
|
198
117
|
};
|
|
199
118
|
}
|
|
200
119
|
readBackendKeyData() {
|
|
201
120
|
return {
|
|
202
|
-
PID: this.
|
|
203
|
-
secret: this.
|
|
121
|
+
PID: this.readInt32(),
|
|
122
|
+
secret: this.readInt32()
|
|
204
123
|
};
|
|
205
124
|
}
|
|
206
125
|
readErrorResponse() {
|
|
@@ -214,10 +133,10 @@ export class ConnectionResponseReader {
|
|
|
214
133
|
let dataType = '';
|
|
215
134
|
let constraint = '';
|
|
216
135
|
while (true) {
|
|
217
|
-
const marker = this.
|
|
136
|
+
const marker = this.readChar();
|
|
218
137
|
if (marker === '\0')
|
|
219
138
|
break;
|
|
220
|
-
const text = this.
|
|
139
|
+
const text = this.readCString();
|
|
221
140
|
switch (marker) {
|
|
222
141
|
case 'S':
|
|
223
142
|
severity = text;
|
|
@@ -251,12 +170,12 @@ export class ConnectionResponseReader {
|
|
|
251
170
|
return new PostgresError(message, code, detail, severity, where, hint, position, dataType, constraint);
|
|
252
171
|
}
|
|
253
172
|
readReadyForQuery() {
|
|
254
|
-
return this.
|
|
173
|
+
return this.readByte();
|
|
255
174
|
}
|
|
256
175
|
readSaslMechanisms() {
|
|
257
176
|
const mechanisms = [];
|
|
258
177
|
while (true) {
|
|
259
|
-
const mech = this.
|
|
178
|
+
const mech = this.readCString();
|
|
260
179
|
if (mech === "")
|
|
261
180
|
break;
|
|
262
181
|
mechanisms.push(mech);
|
|
@@ -264,181 +183,258 @@ export class ConnectionResponseReader {
|
|
|
264
183
|
return mechanisms;
|
|
265
184
|
}
|
|
266
185
|
readSaslMessage(length) {
|
|
267
|
-
return this.
|
|
186
|
+
return this.readRawString(length - 4);
|
|
268
187
|
}
|
|
269
188
|
readRowDescription() {
|
|
270
|
-
const columnsCount = this.
|
|
189
|
+
const columnsCount = this.readInt16();
|
|
271
190
|
const columns = new Array(columnsCount);
|
|
272
191
|
for (let i = 0; i < columnsCount; i++) {
|
|
273
|
-
const name = this.
|
|
274
|
-
this.
|
|
275
|
-
this.
|
|
192
|
+
const name = this.readCString();
|
|
193
|
+
this.readInt32();
|
|
194
|
+
this.readInt16();
|
|
276
195
|
columns[i] = {
|
|
277
196
|
name: name,
|
|
278
|
-
typeOID: this.
|
|
197
|
+
typeOID: this.readInt32(),
|
|
279
198
|
};
|
|
280
|
-
this.
|
|
281
|
-
this.
|
|
199
|
+
this.readInt32();
|
|
200
|
+
this.readInt32();
|
|
282
201
|
}
|
|
283
202
|
return columns;
|
|
284
203
|
}
|
|
204
|
+
readNotificationResponse() {
|
|
205
|
+
this.readInt32();
|
|
206
|
+
const name = this.readCString();
|
|
207
|
+
const payload = this.readCString();
|
|
208
|
+
return { name, payload };
|
|
209
|
+
}
|
|
210
|
+
readCommandComplete() {
|
|
211
|
+
return this.readCString();
|
|
212
|
+
}
|
|
213
|
+
readParameterDescription() {
|
|
214
|
+
const count = this.readInt16();
|
|
215
|
+
const description = Array(count);
|
|
216
|
+
for (let i = 0; i < count; i++) {
|
|
217
|
+
description[i] = this.readInt32();
|
|
218
|
+
}
|
|
219
|
+
return description;
|
|
220
|
+
}
|
|
221
|
+
// ------ binary types parsers ------
|
|
222
|
+
readBinaryDate() {
|
|
223
|
+
const daysSince2000 = this.readInt32();
|
|
224
|
+
const ms = POSTGRES_EPOCH_MS + (daysSince2000 * 86400000);
|
|
225
|
+
return new Date(ms);
|
|
226
|
+
}
|
|
227
|
+
readBinaryTimestamp() {
|
|
228
|
+
const microSecondsSince2000 = this.readInt64();
|
|
229
|
+
const msSince2000 = Number(microSecondsSince2000 / 1000);
|
|
230
|
+
return new Date(POSTGRES_EPOCH_MS + msSince2000);
|
|
231
|
+
}
|
|
232
|
+
readBinaryTime() {
|
|
233
|
+
const microSecondsSinceMidnight = this.readInt64();
|
|
234
|
+
const totalMs = Number(microSecondsSinceMidnight / 1000);
|
|
235
|
+
const seconds = Math.floor(totalMs / 1000);
|
|
236
|
+
const ms = totalMs % 1000;
|
|
237
|
+
const minutes = Math.floor(seconds / 60);
|
|
238
|
+
const hours = Math.floor(minutes / 60);
|
|
239
|
+
return `${String(hours).padStart(2, '0')}:${String(minutes % 60).padStart(2, '0')}:${String(seconds % 60).padStart(2, '0')}.${String(ms).padStart(3, '0')}`;
|
|
240
|
+
}
|
|
241
|
+
readBinaryTimetz() {
|
|
242
|
+
const time = this.readBinaryTime();
|
|
243
|
+
const zoneOffsetSeconds = this.readInt32();
|
|
244
|
+
const offsetMinutesTotal = -zoneOffsetSeconds / 60;
|
|
245
|
+
const sign = offsetMinutesTotal >= 0 ? '+' : '-';
|
|
246
|
+
const abs = Math.abs(offsetMinutesTotal);
|
|
247
|
+
const offH = Math.floor(abs / 60);
|
|
248
|
+
const offM = abs % 60;
|
|
249
|
+
return `${time}${sign}${String(offH).padStart(2, '0')}:${String(offM).padStart(2, '0')}`;
|
|
250
|
+
}
|
|
251
|
+
readBinaryNumeric() {
|
|
252
|
+
const ndigits = this.readInt16();
|
|
253
|
+
const weight = this.readInt16();
|
|
254
|
+
const sign = this.readInt16();
|
|
255
|
+
const dscale = this.readInt16();
|
|
256
|
+
if (sign === 0xC000 || sign === -16384)
|
|
257
|
+
return 'NaN';
|
|
258
|
+
const digits = new Array(ndigits);
|
|
259
|
+
for (let i = 0; i < ndigits; i++) {
|
|
260
|
+
digits[i] = this.readInt16();
|
|
261
|
+
}
|
|
262
|
+
const highExp = Math.max(weight, 0);
|
|
263
|
+
const lowExp = Math.min(weight - ndigits + 1, -1);
|
|
264
|
+
let intPart = '';
|
|
265
|
+
for (let exp = highExp; exp >= 0; exp--) {
|
|
266
|
+
const idx = weight - exp;
|
|
267
|
+
const digit = (idx >= 0 && idx < ndigits) ? digits[idx] : 0;
|
|
268
|
+
intPart += exp === highExp ? String(digit) : String(digit).padStart(4, '0');
|
|
269
|
+
}
|
|
270
|
+
if (intPart === '')
|
|
271
|
+
intPart = '0';
|
|
272
|
+
let fracPart = '';
|
|
273
|
+
for (let exp = -1; exp >= lowExp; exp--) {
|
|
274
|
+
const idx = weight - exp;
|
|
275
|
+
const digit = (idx >= 0 && idx < ndigits) ? digits[idx] : 0;
|
|
276
|
+
fracPart += String(digit).padStart(4, '0');
|
|
277
|
+
}
|
|
278
|
+
if (dscale > 0) {
|
|
279
|
+
fracPart = fracPart.padEnd(dscale, '0').slice(0, dscale);
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
fracPart = '';
|
|
283
|
+
}
|
|
284
|
+
const negative = sign === 0x4000 || sign === 16384;
|
|
285
|
+
const result = fracPart ? `${intPart}.${fracPart}` : intPart;
|
|
286
|
+
return negative ? `-${result}` : result;
|
|
287
|
+
}
|
|
288
|
+
readBinaryInterval() {
|
|
289
|
+
const microseconds = this.readBigInt64();
|
|
290
|
+
const days = this.readInt32();
|
|
291
|
+
const months = this.readInt32();
|
|
292
|
+
return { months, days, microseconds };
|
|
293
|
+
}
|
|
294
|
+
readBinaryJson(fieldLength) {
|
|
295
|
+
return JSON.parse(this.readRawString(fieldLength));
|
|
296
|
+
}
|
|
297
|
+
readBinaryJsonb(fieldLength) {
|
|
298
|
+
this.skipBytes(1);
|
|
299
|
+
return JSON.parse(this.readRawString(fieldLength - 1));
|
|
300
|
+
}
|
|
301
|
+
readBinaryMacaddr() {
|
|
302
|
+
const bytes = this.readBytes(6);
|
|
303
|
+
return Array.from(bytes)
|
|
304
|
+
.map(b => b.toString(16).padStart(2, '0'))
|
|
305
|
+
.join(':');
|
|
306
|
+
}
|
|
307
|
+
readBinaryOid() {
|
|
308
|
+
return this.readUInt32();
|
|
309
|
+
}
|
|
310
|
+
readBinaryXid() {
|
|
311
|
+
return this.readUInt32();
|
|
312
|
+
}
|
|
313
|
+
readBinaryCid() {
|
|
314
|
+
return this.readUInt32();
|
|
315
|
+
}
|
|
316
|
+
readBinaryRegproc() {
|
|
317
|
+
return this.readUInt32();
|
|
318
|
+
}
|
|
319
|
+
readBinaryLseg() {
|
|
320
|
+
return {
|
|
321
|
+
a: this.readBinaryPoint(),
|
|
322
|
+
b: this.readBinaryPoint(),
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
readBinaryPath() {
|
|
326
|
+
const closed = this.readByte() !== 0;
|
|
327
|
+
const npoints = this.readInt32();
|
|
328
|
+
const points = new Array(npoints);
|
|
329
|
+
for (let i = 0; i < npoints; i++) {
|
|
330
|
+
points[i] = this.readBinaryPoint();
|
|
331
|
+
}
|
|
332
|
+
return { closed, points };
|
|
333
|
+
}
|
|
334
|
+
readBinaryBox() {
|
|
335
|
+
return {
|
|
336
|
+
high: this.readBinaryPoint(),
|
|
337
|
+
low: this.readBinaryPoint(),
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
readBinaryPolygon() {
|
|
341
|
+
const npoints = this.readInt32();
|
|
342
|
+
const points = new Array(npoints);
|
|
343
|
+
for (let i = 0; i < npoints; i++) {
|
|
344
|
+
points[i] = this.readBinaryPoint();
|
|
345
|
+
}
|
|
346
|
+
return { points };
|
|
347
|
+
}
|
|
348
|
+
readBinaryLine() {
|
|
349
|
+
return {
|
|
350
|
+
a: this.readFloat64(),
|
|
351
|
+
b: this.readFloat64(),
|
|
352
|
+
c: this.readFloat64(),
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
readBinaryUuid() {
|
|
356
|
+
const buf = this.readBytes(16);
|
|
357
|
+
return buf.toString('hex', 0, 4) + '-' +
|
|
358
|
+
buf.toString('hex', 4, 6) + '-' +
|
|
359
|
+
buf.toString('hex', 6, 8) + '-' +
|
|
360
|
+
buf.toString('hex', 8, 10) + '-' +
|
|
361
|
+
buf.toString('hex', 10, 16);
|
|
362
|
+
}
|
|
363
|
+
readBinaryArray(fieldLength, elementParser) {
|
|
364
|
+
if (fieldLength === 0)
|
|
365
|
+
return [];
|
|
366
|
+
const ndims = this.readInt32();
|
|
367
|
+
const hasNull = this.readInt32();
|
|
368
|
+
const elementOid = this.readInt32();
|
|
369
|
+
if (ndims === 0)
|
|
370
|
+
return [];
|
|
371
|
+
if (ndims > 1) {
|
|
372
|
+
for (let d = 1; d < ndims; d++) {
|
|
373
|
+
this.readInt32();
|
|
374
|
+
this.readInt32();
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
const dimLength = this.readInt32();
|
|
378
|
+
const lbound = this.readInt32();
|
|
379
|
+
const result = new Array(dimLength);
|
|
380
|
+
for (let i = 0; i < dimLength; i++) {
|
|
381
|
+
const itemLength = this.readInt32();
|
|
382
|
+
if (itemLength === -1) {
|
|
383
|
+
result[i] = null;
|
|
384
|
+
}
|
|
385
|
+
else {
|
|
386
|
+
result[i] = elementParser(itemLength);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
return result;
|
|
390
|
+
}
|
|
391
|
+
readBinaryInet(fieldLength) {
|
|
392
|
+
const family = this.readByte();
|
|
393
|
+
const bits = this.readByte();
|
|
394
|
+
const isCidr = this.readByte();
|
|
395
|
+
const nb = this.readByte();
|
|
396
|
+
if (nb === 4) {
|
|
397
|
+
const b1 = this.readByte();
|
|
398
|
+
const b2 = this.readByte();
|
|
399
|
+
const b3 = this.readByte();
|
|
400
|
+
const b4 = this.readByte();
|
|
401
|
+
return `${b1}.${b2}.${b3}.${b4}`;
|
|
402
|
+
}
|
|
403
|
+
else if (nb === 16) {
|
|
404
|
+
const parts = [];
|
|
405
|
+
for (let i = 0; i < 8; i++) {
|
|
406
|
+
parts.push(this.readUInt16().toString(16));
|
|
407
|
+
}
|
|
408
|
+
return parts.join(':');
|
|
409
|
+
}
|
|
410
|
+
this.skipBytes(fieldLength - 4);
|
|
411
|
+
return '';
|
|
412
|
+
}
|
|
413
|
+
readBinaryPoint() {
|
|
414
|
+
return {
|
|
415
|
+
x: this.readFloat64(),
|
|
416
|
+
y: this.readFloat64()
|
|
417
|
+
};
|
|
418
|
+
}
|
|
285
419
|
readDataRow(descriptions, int8toBigint) {
|
|
286
|
-
const fieldsCount = this.
|
|
420
|
+
const fieldsCount = this.readInt16();
|
|
287
421
|
const row = {};
|
|
288
422
|
for (let i = 0; i < fieldsCount; i++) {
|
|
289
|
-
const fieldLength = this.
|
|
423
|
+
const fieldLength = this.readInt32();
|
|
290
424
|
const desc = descriptions[i];
|
|
291
425
|
const key = desc.name;
|
|
292
426
|
if (fieldLength === -1) {
|
|
293
427
|
row[key] = null;
|
|
294
428
|
continue;
|
|
295
429
|
}
|
|
296
|
-
const
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
case DataTypeOids.Bpchar:
|
|
302
|
-
{
|
|
303
|
-
if (fieldLength <= 32) {
|
|
304
|
-
let cacheForColumn = columnValueCache.get(i);
|
|
305
|
-
if (!cacheForColumn) {
|
|
306
|
-
cacheForColumn = new Map();
|
|
307
|
-
columnValueCache.set(i, cacheForColumn);
|
|
308
|
-
}
|
|
309
|
-
const byteHash = this.buffer.getBufferHash(fieldLength);
|
|
310
|
-
let cachedString = cacheForColumn.get(byteHash);
|
|
311
|
-
if (cachedString === undefined) {
|
|
312
|
-
cachedString = this.buffer.readRawString(fieldLength);
|
|
313
|
-
if (cacheForColumn.size < 512) {
|
|
314
|
-
cacheForColumn.set(byteHash, cachedString);
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
else {
|
|
318
|
-
this.buffer.skipBytes(fieldLength);
|
|
319
|
-
}
|
|
320
|
-
row[key] = cachedString;
|
|
321
|
-
}
|
|
322
|
-
else {
|
|
323
|
-
row[key] = this.buffer.readRawString(fieldLength);
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
break;
|
|
327
|
-
case DataTypeOids.Int2:
|
|
328
|
-
{
|
|
329
|
-
row[key] = this.buffer.readInt16();
|
|
330
|
-
}
|
|
331
|
-
break;
|
|
332
|
-
case DataTypeOids.Int4:
|
|
333
|
-
{
|
|
334
|
-
row[key] = this.buffer.readInt32();
|
|
335
|
-
}
|
|
336
|
-
break;
|
|
337
|
-
case DataTypeOids.Int8:
|
|
338
|
-
{
|
|
339
|
-
row[key] = int8toBigint ? this.buffer.readBigInt64() : this.buffer.readInt64();
|
|
340
|
-
}
|
|
341
|
-
break;
|
|
342
|
-
case DataTypeOids.Float4:
|
|
343
|
-
{
|
|
344
|
-
row[key] = this.buffer.readFloat32();
|
|
345
|
-
}
|
|
346
|
-
break;
|
|
347
|
-
case DataTypeOids.Float8:
|
|
348
|
-
{
|
|
349
|
-
row[key] = this.buffer.readFloat64();
|
|
350
|
-
}
|
|
351
|
-
break;
|
|
352
|
-
case DataTypeOids.Bool:
|
|
353
|
-
{
|
|
354
|
-
row[key] = this.buffer.readBool();
|
|
355
|
-
}
|
|
356
|
-
break;
|
|
357
|
-
case DataTypeOids.Bytea:
|
|
358
|
-
{
|
|
359
|
-
row[key] = this.buffer.readBytes(fieldLength);
|
|
360
|
-
}
|
|
361
|
-
break;
|
|
362
|
-
case DataTypeOids.Jsonb:
|
|
363
|
-
{
|
|
364
|
-
this.buffer.skipBytes(1);
|
|
365
|
-
row[key] = JSON.parse(this.buffer.readRawString(fieldLength - 1));
|
|
366
|
-
}
|
|
367
|
-
break;
|
|
368
|
-
case DataTypeOids.Json:
|
|
369
|
-
{
|
|
370
|
-
row[key] = JSON.parse(this.buffer.readRawString(fieldLength));
|
|
371
|
-
}
|
|
372
|
-
break;
|
|
373
|
-
case DataTypeOids.Date:
|
|
374
|
-
{
|
|
375
|
-
row[key] = this.buffer.readBinaryDate();
|
|
376
|
-
}
|
|
377
|
-
break;
|
|
378
|
-
case DataTypeOids.Timestamp:
|
|
379
|
-
case DataTypeOids.Timestamptz:
|
|
380
|
-
{
|
|
381
|
-
row[key] = this.buffer.readBinaryTimestamp();
|
|
382
|
-
}
|
|
383
|
-
break;
|
|
384
|
-
case DataTypeOids.Uuid:
|
|
385
|
-
{
|
|
386
|
-
row[key] = this.buffer.readUuid();
|
|
387
|
-
}
|
|
388
|
-
break;
|
|
389
|
-
case DataTypeOids.Time:
|
|
390
|
-
{
|
|
391
|
-
row[key] = this.buffer.readBinaryTime();
|
|
392
|
-
}
|
|
393
|
-
break;
|
|
394
|
-
case DataTypeOids.Timetz:
|
|
395
|
-
{
|
|
396
|
-
row[key] = this.buffer.readBinaryTimetz();
|
|
397
|
-
}
|
|
398
|
-
break;
|
|
399
|
-
case DataTypeOids.Numeric:
|
|
400
|
-
{
|
|
401
|
-
row[key] = this.buffer.readNumeric();
|
|
402
|
-
}
|
|
403
|
-
break;
|
|
404
|
-
default:
|
|
405
|
-
{
|
|
406
|
-
this.buffer.skipBytes(fieldLength);
|
|
407
|
-
row[key] = null;
|
|
408
|
-
}
|
|
409
|
-
break;
|
|
430
|
+
const handler = handlers[desc.typeOID];
|
|
431
|
+
if (!handler) {
|
|
432
|
+
this.skipBytes(fieldLength);
|
|
433
|
+
row[key] = undefined;
|
|
434
|
+
continue;
|
|
410
435
|
}
|
|
436
|
+
row[key] = handler.read(this, fieldLength, int8toBigint);
|
|
411
437
|
}
|
|
412
438
|
return row;
|
|
413
439
|
}
|
|
414
|
-
readNotificationResponse() {
|
|
415
|
-
this.buffer.readInt32();
|
|
416
|
-
const name = this.buffer.readCString();
|
|
417
|
-
const payload = this.buffer.readCString();
|
|
418
|
-
return { name, payload };
|
|
419
|
-
}
|
|
420
|
-
readCommandComplete() {
|
|
421
|
-
return this.buffer.readCString();
|
|
422
|
-
}
|
|
423
|
-
hasMore() {
|
|
424
|
-
return this.buffer.hasMore();
|
|
425
|
-
}
|
|
426
|
-
hasFullPacket() {
|
|
427
|
-
return this.buffer.hasFullPacket();
|
|
428
|
-
}
|
|
429
|
-
getResidualBuffer() {
|
|
430
|
-
return this.buffer.getResidualBuffer();
|
|
431
|
-
}
|
|
432
|
-
readParseComplete() { }
|
|
433
|
-
readBindComplete() { }
|
|
434
|
-
readParameterDescription() {
|
|
435
|
-
const count = this.buffer.readInt16();
|
|
436
|
-
for (let i = 0; i < count; i++) {
|
|
437
|
-
this.buffer.readInt32();
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
readNoData() { }
|
|
441
|
-
skip(count) {
|
|
442
|
-
this.buffer.skipBytes(count);
|
|
443
|
-
}
|
|
444
440
|
}
|