prostgles-server 4.1.128 → 4.1.129

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.
@@ -12,16 +12,15 @@ type ClientStreamedRequest = {
12
12
  };
13
13
  type StreamedQuery = ClientStreamedRequest & {
14
14
  stream: QueryStreamType | undefined;
15
- poolClient: pg.PoolClient | undefined;
15
+ client: pg.Client | undefined;
16
16
  onError: ((error: any) => void);
17
17
  };
18
18
  export declare class QueryStreamer {
19
19
  db: DB;
20
20
  dboBuilder: DboBuilder;
21
21
  socketQueries: Record<string, Record<string, StreamedQuery>>;
22
- pool: pg.Pool;
23
- adminPool: pg.Pool;
24
22
  constructor(dboBuilder: DboBuilder);
23
+ getConnection: (onError: ((err: any) => void) | undefined) => pg.Client;
25
24
  create: (query: ClientStreamedRequest) => Promise<SocketSQLStreamServer>;
26
25
  }
27
26
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"QueryStreamer.d.ts","sourceRoot":"","sources":["../../lib/DboBuilder/QueryStreamer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAY,UAAU,EAAyB,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACrG,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,eAAe,MAAM,iBAAiB,CAAC;AAK9C,KAAK,qBAAqB,GAAG;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,UAAU,GAAG,SAAS,CAAC;IAChC,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAE7B,CAAA;AACD,KAAK,aAAa,GAAG,qBAAqB,GAAG;IAC3C,MAAM,EAAE,eAAe,GAAG,SAAS,CAAC;IACpC,UAAU,EAAE,EAAE,CAAC,UAAU,GAAG,SAAS,CAAC;IACtC,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC,CAAC;CACjC,CAAA;AAWD,qBAAa,aAAa;IACxB,EAAE,EAAE,EAAE,CAAC;IACP,UAAU,EAAE,UAAU,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAM;IAClE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC;IACd,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC;gBACP,UAAU,EAAE,UAAU;IAmBlC,MAAM,UAAiB,qBAAqB,KAAG,QAAQ,qBAAqB,CAAC,CAyJ5E;CACF"}
1
+ {"version":3,"file":"QueryStreamer.d.ts","sourceRoot":"","sources":["../../lib/DboBuilder/QueryStreamer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAY,UAAU,EAAyB,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACrG,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,eAAe,MAAM,iBAAiB,CAAC;AAK9C,KAAK,qBAAqB,GAAG;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,UAAU,GAAG,SAAS,CAAC;IAChC,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAE7B,CAAA;AACD,KAAK,aAAa,GAAG,qBAAqB,GAAG;IAC3C,MAAM,EAAE,eAAe,GAAG,SAAS,CAAC;IACpC,MAAM,EAAE,EAAE,CAAC,MAAM,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC,CAAC;CACjC,CAAA;AAWD,qBAAa,aAAa;IACxB,EAAE,EAAE,EAAE,CAAC;IACP,UAAU,EAAE,UAAU,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAM;gBACtD,UAAU,EAAE,UAAU;IAKlC,aAAa,mBAAoB,GAAG,KAAK,IAAI,4BAO5C;IAED,MAAM,UAAiB,qBAAqB,KAAG,QAAQ,qBAAqB,CAAC,CAqJ5E;CACF"}
@@ -18,26 +18,18 @@ class QueryStreamer {
18
18
  db;
19
19
  dboBuilder;
20
20
  socketQueries = {};
21
- pool;
22
- adminPool;
23
21
  constructor(dboBuilder) {
24
22
  this.dboBuilder = dboBuilder;
25
23
  this.db = dboBuilder.db;
24
+ }
25
+ getConnection = (onError) => {
26
26
  const connectionInfo = typeof this.db.$cn === "string" ? { connectionString: this.db.$cn } : this.db.$cn;
27
- const onPoolError = (err, _client) => {
28
- console.error(err.message);
29
- };
30
- this.pool = new pg.Pool({ ...connectionInfo, max: 50 }).on("error", (error) => {
31
- // if(error.message !== "Connection terminated") return;
32
- Object.entries(this.socketQueries).forEach(([socketId, queries]) => {
33
- Object.entries(queries).forEach(([id, query]) => {
34
- query.onError?.({ message: error.message });
35
- delete this.socketQueries[socketId]?.[id];
36
- });
37
- });
27
+ const client = new pg.Client(connectionInfo);
28
+ client.on("error", (err) => {
29
+ onError?.(err);
38
30
  });
39
- this.adminPool = new pg.Pool(connectionInfo).on("error", onPoolError);
40
- }
31
+ return client;
32
+ };
41
33
  create = async (query) => {
42
34
  const { socket, persistConnection } = query;
43
35
  const socketId = socket.id;
@@ -51,7 +43,7 @@ class QueryStreamer {
51
43
  let errored = false;
52
44
  const socketQuery = {
53
45
  ...query,
54
- poolClient: undefined,
46
+ client: undefined,
55
47
  stream: undefined,
56
48
  onError: (rawError) => {
57
49
  if (errored)
@@ -71,102 +63,98 @@ class QueryStreamer {
71
63
  if (!socketQuery) {
72
64
  throw "socket query not found";
73
65
  }
74
- (async () => {
75
- let emittedPackets = 0;
76
- let batchRows = [];
77
- let finished = false;
78
- const batchSize = 10000;
79
- let stream;
80
- let poolClient;
81
- const emit = (type, stream) => {
82
- const result = stream?._result;
83
- let packet;
84
- const ended = type === "ended";
85
- if (finished)
86
- return;
87
- finished = finished || ended;
88
- if (!emittedPackets) {
89
- if (!result?.fields)
90
- throw "No fields";
91
- const fields = runSQL_1.getDetailedFieldInfo.bind(this.dboBuilder)(result.fields);
92
- packet = { type: "start", rows: batchRows, fields, ended, processId: processID };
66
+ let emittedPackets = 0;
67
+ let batchRows = [];
68
+ let finished = false;
69
+ const batchSize = 10000;
70
+ let stream;
71
+ let poolClient;
72
+ const emit = (type, stream) => {
73
+ const result = stream?._result;
74
+ let packet;
75
+ const ended = type === "ended";
76
+ if (finished)
77
+ return;
78
+ finished = finished || ended;
79
+ if (!emittedPackets) {
80
+ if (!result?.fields)
81
+ throw "No fields";
82
+ const fields = runSQL_1.getDetailedFieldInfo.bind(this.dboBuilder)(result.fields);
83
+ packet = { type: "start", rows: batchRows, fields, ended, processId: processID };
84
+ }
85
+ else {
86
+ packet = { type: "rows", rows: batchRows, ended };
87
+ }
88
+ socket.emit(channel, packet);
89
+ if (ended) {
90
+ if (!result)
91
+ throw "No result info";
92
+ runSQL_1.watchSchemaFallback.bind(this.dboBuilder)({ queryWithoutRLS: query.query, command: result.command });
93
+ }
94
+ emittedPackets++;
95
+ };
96
+ const client = this.getConnection(err => {
97
+ socketQuery.onError(err);
98
+ client.end();
99
+ });
100
+ try {
101
+ await client.connect();
102
+ poolClient = client;
103
+ processID = client.processID;
104
+ const queryStream = new QueryStream(query.query, [], { batchSize: 1e6, highWaterMark: 1e6, rowMode: "array" });
105
+ stream = client.query(queryStream);
106
+ this.socketQueries[socketId][id].client = poolClient;
107
+ this.socketQueries[socketId][id].stream = stream;
108
+ stream.on('data', async (data) => {
109
+ batchRows.push(data);
110
+ if (options?.streamLimit) {
111
+ if (batchRows.length >= options.streamLimit) {
112
+ emit("ended", stream);
113
+ }
93
114
  }
94
- else {
95
- packet = { type: "rows", rows: batchRows, ended };
115
+ if (batchRows.length >= batchSize) {
116
+ emit("rows", stream);
117
+ batchRows = [];
96
118
  }
97
- socket.emit(channel, packet);
98
- if (ended) {
99
- if (!result)
100
- throw "No result info";
101
- runSQL_1.watchSchemaFallback.bind(this.dboBuilder)({ queryWithoutRLS: query.query, command: result.command });
119
+ });
120
+ stream.on('error', error => {
121
+ socketQuery.onError(error);
122
+ });
123
+ stream.on('end', () => {
124
+ emit("ended", stream);
125
+ // release the client when the stream is finished AND connection is not persisted
126
+ if (!options?.persistStreamConnection) {
127
+ delete this.socketQueries[socketId]?.[id];
128
+ client.end();
102
129
  }
103
- emittedPackets++;
104
- };
105
- try {
106
- await this.pool.connect((err, client, done) => {
107
- if (err)
108
- throw err;
109
- if (!client)
110
- throw "No client";
111
- poolClient = client;
112
- processID = client.processID;
113
- const queryStream = new QueryStream(query.query, [], { batchSize, rowMode: "array" });
114
- stream = client.query(queryStream);
115
- this.socketQueries[socketId][id].poolClient = poolClient;
116
- this.socketQueries[socketId][id].stream = stream;
117
- stream.on('data', async (data) => {
118
- batchRows.push(data);
119
- if (options?.streamLimit) {
120
- if (batchRows.length >= options.streamLimit) {
121
- emit("ended", stream);
122
- }
123
- }
124
- if (batchRows.length >= batchSize) {
125
- emit("rows", stream);
126
- batchRows = [];
127
- }
128
- });
129
- stream.on('error', error => {
130
- socketQuery.onError(error);
131
- });
132
- stream.on('end', () => {
133
- emit("ended", stream);
134
- // release the client when the stream is finished
135
- if (!options?.persistStreamConnection) {
136
- delete this.socketQueries[socketId]?.[id];
137
- done();
138
- }
139
- });
140
- });
141
- }
142
- catch (err) {
143
- socketQuery.onError(err);
144
- }
145
- })();
130
+ });
131
+ }
132
+ catch (err) {
133
+ socketQuery.onError(err);
134
+ await client.end();
135
+ }
146
136
  };
147
- const stop = (opts, cb) => {
148
- // Must kill query if not ended
149
- const { stream, poolClient } = this.socketQueries[socketId]?.[id] ?? {};
137
+ const stop = async (opts, cb) => {
138
+ const { stream, client: poolClient } = this.socketQueries[socketId]?.[id] ?? {};
150
139
  if (!stream || !poolClient)
151
140
  return;
152
- this.adminPool.connect(async (err, client, done) => {
153
- if (err)
154
- return cb(null, err);
141
+ const client = this.getConnection(undefined);
142
+ try {
143
+ await client.connect();
155
144
  if (!client)
156
145
  return cb(null, "No client");
157
146
  const stopFunction = opts?.terminate ? "pg_terminate_backend" : "pg_cancel_backend";
158
- client.query(`SELECT ${stopFunction}(pid) FROM pg_stat_activity WHERE pid = $1`, [processID], (err) => {
159
- if (err) {
160
- cb(null, err);
161
- console.error(err);
162
- }
163
- delete this.socketQueries[socketId]?.[id];
164
- poolClient.release();
165
- socket.removeAllListeners(unsubChannel);
166
- socket.removeAllListeners(channel);
167
- done();
168
- });
169
- });
147
+ const rows = await client.query(`SELECT ${stopFunction}(pid), pid, state, query FROM pg_stat_activity WHERE pid = $1 AND query = $2`, [processID, query.query]);
148
+ socket.removeAllListeners(unsubChannel);
149
+ socket.removeAllListeners(channel);
150
+ cb({ processID, info: rows.rows[0] });
151
+ }
152
+ catch (error) {
153
+ cb(null, error);
154
+ }
155
+ finally {
156
+ await client.end();
157
+ }
170
158
  };
171
159
  socket.removeAllListeners(unsubChannel);
172
160
  socket.once(unsubChannel, stop);
@@ -1 +1 @@
1
- {"version":3,"file":"QueryStreamer.js","sourceRoot":"","sources":["../../lib/DboBuilder/QueryStreamer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"QueryStreamer.js","sourceRoot":"","sources":["../../lib/DboBuilder/QueryStreamer.ts"],"names":[],"mappings":"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"}
@@ -19,7 +19,7 @@ type ClientStreamedRequest = {
19
19
  }
20
20
  type StreamedQuery = ClientStreamedRequest & {
21
21
  stream: QueryStreamType | undefined;
22
- poolClient: pg.PoolClient | undefined;
22
+ client: pg.Client | undefined;
23
23
  onError: ((error: any) => void);
24
24
  }
25
25
 
@@ -36,25 +36,18 @@ export class QueryStreamer {
36
36
  db: DB;
37
37
  dboBuilder: DboBuilder;
38
38
  socketQueries: Record<string, Record<string, StreamedQuery>> = {};
39
- pool: pg.Pool;
40
- adminPool: pg.Pool;
41
39
  constructor(dboBuilder: DboBuilder) {
42
40
  this.dboBuilder = dboBuilder;
43
41
  this.db = dboBuilder.db;
42
+ }
43
+
44
+ getConnection = (onError: ((err: any) => void) | undefined) => {
44
45
  const connectionInfo = typeof this.db.$cn === "string"? { connectionString: this.db.$cn } : this.db.$cn as any;
45
- const onPoolError = (err: Error, _client: pg.PoolClient) => {
46
- console.error(err.message);
47
- }
48
- this.pool = new pg.Pool({ ...connectionInfo, max: 50 }).on("error", (error) => {
49
- // if(error.message !== "Connection terminated") return;
50
- Object.entries(this.socketQueries).forEach(([socketId, queries]) => {
51
- Object.entries(queries).forEach(([id, query]) => {
52
- query.onError?.({ message: error.message });
53
- delete this.socketQueries[socketId]?.[id];
54
- });
55
- });
46
+ const client = new pg.Client(connectionInfo);
47
+ client.on("error", (err) => {
48
+ onError?.(err);
56
49
  });
57
- this.adminPool = new pg.Pool(connectionInfo).on("error", onPoolError);
50
+ return client;
58
51
  }
59
52
 
60
53
  create = async (query: ClientStreamedRequest): Promise<SocketSQLStreamServer> => {
@@ -71,7 +64,7 @@ export class QueryStreamer {
71
64
  let errored = false;
72
65
  const socketQuery = {
73
66
  ...query,
74
- poolClient: undefined,
67
+ client: undefined,
75
68
  stream: undefined,
76
69
  onError: (rawError: any) => {
77
70
  if(errored) return;
@@ -86,101 +79,97 @@ export class QueryStreamer {
86
79
  this.socketQueries[socketId]![id] ??= socketQuery;
87
80
  const { options } = query
88
81
  let processID = -1;
82
+
89
83
  const startStream = async () => {
90
84
  const socketQuery = this.socketQueries[socketId]?.[id];
91
85
  if(!socketQuery){
92
86
  throw "socket query not found";
87
+ }
88
+ let emittedPackets = 0;
89
+ let batchRows: any[] = [];
90
+ let finished = false;
91
+ const batchSize = 10000;
92
+ let stream: QueryStreamType;
93
+ let poolClient: pg.Client;
94
+ const emit = (type: "rows" | "ended", stream: QueryStreamType | undefined) => {
95
+ const result = stream?._result as { command: string; fields: any[] } | undefined;
96
+ let packet: SocketSQLStreamPacket | undefined;
97
+ const ended = type === "ended";
98
+ if(finished) return;
99
+ finished = finished || ended;
100
+ if (!emittedPackets) {
101
+ if(!result?.fields) throw "No fields";
102
+ const fields = getDetailedFieldInfo.bind(this.dboBuilder)(result.fields as any);
103
+ packet = { type: "start", rows: batchRows, fields, ended, processId: processID };
104
+ } else {
105
+ packet = { type: "rows", rows: batchRows, ended };
106
+ }
107
+ socket.emit(channel, packet);
108
+ if(ended){
109
+ if(!result) throw "No result info";
110
+ watchSchemaFallback.bind(this.dboBuilder)({ queryWithoutRLS: query.query, command: result.command });
111
+ }
112
+ emittedPackets++;
93
113
  }
94
- (async () => {
95
- let emittedPackets = 0;
96
- let batchRows: any[] = [];
97
- let finished = false;
98
- const batchSize = 10000;
99
- let stream: QueryStreamType;
100
- let poolClient: pg.PoolClient;
101
- const emit = (type: "rows" | "ended", stream: QueryStreamType | undefined) => {
102
- const result = stream?._result as { command: string; fields: any[] } | undefined;
103
- let packet: SocketSQLStreamPacket | undefined;
104
- const ended = type === "ended";
105
- if(finished) return;
106
- finished = finished || ended;
107
- if (!emittedPackets) {
108
- if(!result?.fields) throw "No fields";
109
- const fields = getDetailedFieldInfo.bind(this.dboBuilder)(result.fields as any);
110
- packet = { type: "start", rows: batchRows, fields, ended, processId: processID };
111
- } else {
112
- packet = { type: "rows", rows: batchRows, ended };
114
+ const client = this.getConnection(err => {
115
+ socketQuery.onError(err);
116
+ client.end();
117
+ });
118
+ try {
119
+ await client.connect();
120
+ poolClient = client;
121
+ processID = (client as any).processID
122
+ const queryStream = new QueryStream(query.query, [], { batchSize: 1e6, highWaterMark: 1e6, rowMode: "array" });
123
+ stream = client.query(queryStream);
124
+ this.socketQueries[socketId]![id]!.client = poolClient;
125
+ this.socketQueries[socketId]![id]!.stream = stream;
126
+ stream.on('data', async (data) => {
127
+ batchRows.push(data);
128
+ if(options?.streamLimit) {
129
+ if(batchRows.length >= options.streamLimit){
130
+ emit("ended", stream);
131
+ }
113
132
  }
114
- socket.emit(channel, packet);
115
- if(ended){
116
- if(!result) throw "No result info";
117
- watchSchemaFallback.bind(this.dboBuilder)({ queryWithoutRLS: query.query, command: result.command });
133
+ if (batchRows.length >= batchSize) {
134
+ emit("rows", stream);
135
+ batchRows = [];
118
136
  }
119
- emittedPackets++;
120
- }
121
-
122
- try {
123
-
124
- await this.pool.connect((err, client, done) => {
125
- if (err) throw err;
126
- if (!client) throw "No client";
127
- poolClient = client;
128
- processID = (client as any).processID
129
- const queryStream = new QueryStream(query.query, [], { batchSize, rowMode: "array" });
130
- stream = client.query(queryStream);
131
- this.socketQueries[socketId]![id]!.poolClient = poolClient;
132
- this.socketQueries[socketId]![id]!.stream = stream;
133
- stream.on('data', async (data) => {
134
- batchRows.push(data);
135
- if(options?.streamLimit) {
136
- if(batchRows.length >= options.streamLimit){
137
- emit("ended", stream);
138
- }
139
- }
140
- if (batchRows.length >= batchSize) {
141
- emit("rows", stream);
142
- batchRows = [];
143
- }
144
- });
145
- stream.on('error', error => {
146
- socketQuery.onError(error);
147
- });
148
-
149
- stream.on('end', () => {
150
- emit("ended", stream);
151
- // release the client when the stream is finished
152
- if(!options?.persistStreamConnection){
153
- delete this.socketQueries[socketId]?.[id];
154
- done();
155
- }
156
- })
157
- });
158
- } catch(err){
159
- socketQuery.onError(err);
160
- }
161
- })();
137
+ });
138
+ stream.on('error', error => {
139
+ socketQuery.onError(error);
140
+ });
141
+
142
+ stream.on('end', () => {
143
+ emit("ended", stream);
144
+ // release the client when the stream is finished AND connection is not persisted
145
+ if(!options?.persistStreamConnection){
146
+ delete this.socketQueries[socketId]?.[id];
147
+ client.end();
148
+ }
149
+ });
150
+ } catch(err){
151
+ socketQuery.onError(err);
152
+ await client.end();
153
+ }
162
154
  }
163
155
 
164
- const stop = (opts: { terminate?: boolean; } | undefined, cb: BasicCallback) => {
165
- // Must kill query if not ended
166
- const { stream, poolClient } = this.socketQueries[socketId]?.[id] ?? {};
156
+ const stop = async (opts: { terminate?: boolean; } | undefined, cb: BasicCallback) => {
157
+ const { stream, client: poolClient } = this.socketQueries[socketId]?.[id] ?? {};
167
158
  if(!stream || !poolClient) return;
168
- this.adminPool.connect(async (err, client, done) => {
169
- if (err) return cb(null, err);
159
+ const client = this.getConnection(undefined);
160
+ try {
161
+ await client.connect();
170
162
  if (!client) return cb(null, "No client");
171
163
  const stopFunction = opts?.terminate? "pg_terminate_backend" : "pg_cancel_backend";
172
- client.query(`SELECT ${stopFunction}(pid) FROM pg_stat_activity WHERE pid = $1`, [processID], (err) => {
173
- if(err) {
174
- cb(null, err);
175
- console.error(err);
176
- }
177
- delete this.socketQueries[socketId]?.[id];
178
- poolClient.release();
179
- socket.removeAllListeners(unsubChannel);
180
- socket.removeAllListeners(channel);
181
- done();
182
- });
183
- });
164
+ const rows = await client.query(`SELECT ${stopFunction}(pid), pid, state, query FROM pg_stat_activity WHERE pid = $1 AND query = $2`, [processID, query.query]);
165
+ socket.removeAllListeners(unsubChannel);
166
+ socket.removeAllListeners(channel);
167
+ cb({ processID, info: rows.rows[0] });
168
+ } catch (error){
169
+ cb(null, error);
170
+ } finally {
171
+ await client.end();
172
+ }
184
173
  }
185
174
 
186
175
  socket.removeAllListeners(unsubChannel);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prostgles-server",
3
- "version": "4.1.128",
3
+ "version": "4.1.129",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -5,6 +5,57 @@ import { tryRun, tryRunP } from './isomorphic_queries';
5
5
  import { reject } from 'bluebird';
6
6
 
7
7
  export default async function client_only(db: DBHandlerClient, auth: Auth, log: (...args: any[]) => any, methods, tableSchema: DBSchemaTable[], token: string){
8
+
9
+ await tryRunP("SQL Stream stop kills the query", async (resolve, reject) => {
10
+ const query = "SELECT * FROM pg_sleep(5)"
11
+ const res = await db.sql!(query, {}, { returnType: "stream" });
12
+ const listener = async (packet: SocketSQLStreamPacket) => {
13
+ if(packet.type === "error"){
14
+ const queryState = await db.sql!("SELECT * FROM pg_stat_activity WHERE query = $1", [query], { returnType: "rows" });
15
+ assert.equal(queryState.length, 1);
16
+ assert.equal(queryState[0].state, "idle");
17
+ assert.equal(packet.error.message, "canceling statement due to user request");
18
+ resolve("ok");
19
+ } else {
20
+ assert.equal(packet.type, "start");
21
+ assert.equal(packet.ended, true);
22
+ assert.deepStrictEqual(packet.rows, []);
23
+ reject("ok");
24
+ }
25
+ };
26
+ const startHandler = await res.start(listener);
27
+ setTimeout(() => {
28
+ startHandler.stop().catch(reject);
29
+ }, 1000);
30
+ });
31
+
32
+ await tryRunP("SQL Stream stop with terminate kills the query", async (resolve, reject) => {
33
+ const totalRows = 5e6;
34
+ const query = `SELECT * FROM generate_series(1, ${totalRows})`;
35
+ const res = await db.sql!(query, {}, { returnType: "stream" });
36
+ const rowsReceived: any[] = [];
37
+ const listener = async (packet: SocketSQLStreamPacket) => {
38
+ if(packet.type === "error"){
39
+ const queryState = await db.sql!("SELECT * FROM pg_stat_activity WHERE query = $1", [query], { returnType: "rows" });
40
+ assert.equal(queryState.length, 0);
41
+ resolve("ok");
42
+ } else {
43
+ try {
44
+ rowsReceived.push(...packet.rows);
45
+ console.log(rowsReceived.length)
46
+ assert.equal(packet.ended, false);
47
+ assert.equal(rowsReceived.length < totalRows, true);
48
+ } catch(error){
49
+ reject(error);
50
+ }
51
+ }
52
+ };
53
+ const startHandler = await res.start(listener);
54
+ setTimeout(() => {
55
+ startHandler.stop(true).catch(reject);
56
+ }, 22);
57
+ });
58
+
8
59
  await Promise.all([1e3, 1e2].map(async (numberOfRows) => {
9
60
  await tryRunP("SQL Stream", async (resolve) => {
10
61
  const res = await db.sql!(`SELECT v.* FROM generate_series(1, ${numberOfRows}) v`, {}, { returnType: "stream" });
@@ -112,57 +163,6 @@ export default async function client_only(db: DBHandlerClient, auth: Auth, log:
112
163
  await res.start(listener);
113
164
  });
114
165
 
115
- await tryRunP("SQL Stream stop kills the query", async (resolve, reject) => {
116
- const query = "SELECT * FROM pg_sleep(5)"
117
- const res = await db.sql!(query, {}, { returnType: "stream" });
118
- const listener = async (packet: SocketSQLStreamPacket) => {
119
- if(packet.type === "error"){
120
- const queryState = await db.sql!("SELECT * FROM pg_stat_activity WHERE query = $1", [query], { returnType: "rows" });
121
- assert.equal(queryState.length, 1);
122
- assert.equal(queryState[0].state, "idle");
123
- assert.equal(packet.error.message, "canceling statement due to user request");
124
- resolve("ok");
125
- } else {
126
- assert.equal(packet.type, "start");
127
- assert.equal(packet.ended, true);
128
- assert.deepStrictEqual(packet.rows, []);
129
- reject("ok");
130
- }
131
- };
132
- const startHandler = await res.start(listener);
133
- setTimeout(() => {
134
- startHandler.stop().catch(reject);
135
- }, 1000);
136
- });
137
- // await tryRunP("SQL Stream stop with terminate kills the query", async (resolve, reject) => {
138
- // const totalRows = 5e6;
139
- // const query = `SELECT * FROM generate_series(1, ${totalRows})`;
140
- // const res = await db.sql!(query, {}, { returnType: "stream" });
141
- // const rowsReceived: any[] = [];
142
- // const listener = async (packet: SocketSQLStreamPacket) => {
143
- // if(packet.type === "error"){
144
- // const queryState = await db.sql!("SELECT * FROM pg_stat_activity WHERE query = $1", [query], { returnType: "rows" });
145
- // assert.equal(queryState.length, 1);
146
- // assert.equal(queryState[0].state, "idle");
147
- // assert.equal(packet.error.message, "canceling statement due to user request");
148
- // resolve("ok");
149
- // } else {
150
- // try {
151
- // rowsReceived.push(...packet.rows);
152
- // console.log(rowsReceived.length)
153
- // assert.equal(packet.ended, false);
154
- // assert.equal(rowsReceived.length < totalRows, true);
155
- // } catch(error){
156
- // reject(error);
157
- // }
158
- // }
159
- // };
160
- // const startHandler = await res.start(listener);
161
- // setTimeout(() => {
162
- // startHandler.stop(true).catch(reject);
163
- // }, 22);
164
- // });
165
-
166
166
  // await tryRunP("SQL Stream ensure the connection is never released (same pg_backend_pid is the same for subsequent) queries when using persistConnectionId", async (resolve, reject) => {
167
167
  // const res = await db.sql!("SELECT pg_backend_pid()", {}, { returnType: "stream", persistConnectionId: true });
168
168
  // const listener = async (packet: SocketSQLStreamPacket) => {
@@ -21,7 +21,7 @@
21
21
  },
22
22
  "../..": {
23
23
  "name": "prostgles-server",
24
- "version": "4.1.127",
24
+ "version": "4.1.128",
25
25
  "license": "MIT",
26
26
  "dependencies": {
27
27
  "@types/express": "^4.17.13",