prostgles-server 4.2.559 → 4.2.561
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/dist/DboBuilder/DboBuilder.d.ts +3 -3
- package/dist/DboBuilder/DboBuilder.d.ts.map +1 -1
- package/dist/DboBuilder/DboBuilder.js +18 -29
- package/dist/DboBuilder/DboBuilder.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts +19 -4
- package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/ViewHandler.js +18 -2
- package/dist/DboBuilder/ViewHandler/ViewHandler.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/count.d.ts +2 -1
- package/dist/DboBuilder/ViewHandler/count.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/count.js +5 -2
- package/dist/DboBuilder/ViewHandler/count.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/find.d.ts +4 -1
- package/dist/DboBuilder/ViewHandler/find.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/find.js +9 -5
- package/dist/DboBuilder/ViewHandler/find.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/getDbHandlerWithAbort.d.ts +9 -0
- package/dist/DboBuilder/ViewHandler/getDbHandlerWithAbort.d.ts.map +1 -0
- package/dist/DboBuilder/ViewHandler/getDbHandlerWithAbort.js +81 -0
- package/dist/DboBuilder/ViewHandler/getDbHandlerWithAbort.js.map +1 -0
- package/dist/DboBuilder/ViewHandler/size.d.ts +2 -1
- package/dist/DboBuilder/ViewHandler/size.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/size.js +7 -5
- package/dist/DboBuilder/ViewHandler/size.js.map +1 -1
- package/dist/DboBuilder/dboBuilderUtils.d.ts +1 -0
- package/dist/DboBuilder/dboBuilderUtils.d.ts.map +1 -1
- package/dist/DboBuilder/dboBuilderUtils.js +4 -2
- package/dist/DboBuilder/dboBuilderUtils.js.map +1 -1
- package/dist/DboBuilder/{QueryStreamer.d.ts → runSql/QueryStreamer.d.ts} +4 -6
- package/dist/DboBuilder/runSql/QueryStreamer.d.ts.map +1 -0
- package/dist/DboBuilder/{QueryStreamer.js → runSql/QueryStreamer.js} +5 -22
- package/dist/DboBuilder/runSql/QueryStreamer.js.map +1 -0
- package/dist/DboBuilder/runSql/getAdminClient.d.ts +26 -0
- package/dist/DboBuilder/runSql/getAdminClient.d.ts.map +1 -0
- package/dist/DboBuilder/runSql/getAdminClient.js +32 -0
- package/dist/DboBuilder/runSql/getAdminClient.js.map +1 -0
- package/dist/Logging.d.ts +9 -2
- package/dist/Logging.d.ts.map +1 -1
- package/dist/Prostgles.d.ts +2 -0
- package/dist/Prostgles.d.ts.map +1 -1
- package/dist/Prostgles.js +3 -1
- package/dist/Prostgles.js.map +1 -1
- package/dist/PublishParser/PublishParser.d.ts.map +1 -1
- package/dist/PublishParser/PublishParser.js +2 -1
- package/dist/PublishParser/PublishParser.js.map +1 -1
- package/dist/WebsocketAPI/onSocketConnected.d.ts.map +1 -1
- package/dist/WebsocketAPI/onSocketConnected.js +12 -7
- package/dist/WebsocketAPI/onSocketConnected.js.map +1 -1
- package/dist/initProstgles.d.ts.map +1 -1
- package/dist/initProstgles.js +2 -0
- package/dist/initProstgles.js.map +1 -1
- package/dist/runClientRequest.d.ts +1 -1
- package/dist/runClientRequest.d.ts.map +1 -1
- package/dist/runClientRequest.js +29 -6
- package/dist/runClientRequest.js.map +1 -1
- package/lib/DboBuilder/DboBuilder.ts +20 -31
- package/lib/DboBuilder/ViewHandler/ViewHandler.ts +35 -3
- package/lib/DboBuilder/ViewHandler/count.ts +6 -2
- package/lib/DboBuilder/ViewHandler/find.ts +16 -7
- package/lib/DboBuilder/ViewHandler/getDbHandlerWithAbort.ts +108 -0
- package/lib/DboBuilder/ViewHandler/size.ts +8 -5
- package/lib/DboBuilder/dboBuilderUtils.ts +4 -1
- package/lib/DboBuilder/{QueryStreamer.ts → runSql/QueryStreamer.ts} +10 -32
- package/lib/DboBuilder/runSql/getAdminClient.ts +31 -0
- package/lib/Logging.ts +20 -10
- package/lib/Prostgles.ts +4 -1
- package/lib/PublishParser/PublishParser.ts +3 -1
- package/lib/WebsocketAPI/onSocketConnected.ts +12 -7
- package/lib/initProstgles.ts +3 -0
- package/lib/runClientRequest.ts +50 -10
- package/package.json +2 -2
- package/dist/DboBuilder/QueryStreamer.d.ts.map +0 -1
- package/dist/DboBuilder/QueryStreamer.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runClientRequest.d.ts","sourceRoot":"","sources":["../lib/runClientRequest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAA0B,MAAM,iBAAiB,CAAC;AAC1E,OAAO,
|
|
1
|
+
{"version":3,"file":"runClientRequest.d.ts","sourceRoot":"","sources":["../lib/runClientRequest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAA0B,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAML,KAAK,SAAS,EACf,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAK1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,sCAAsC,CAAC;AA8B5E,KAAK,IAAI,GAAG;IACV,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAUF,eAAO,MAAM,gBAAgB,GAC3B,MAAM,SAAS,EACf,kBAAkB,IAAI,EACtB,WAAW,iBAAiB,EAC5B,OAAO,eAAe,GAAG,SAAS,8BAgInC,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,MAAM,SAAS,EACf,WAAW,iBAAiB;;;;;;;;EAa7B,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,MAAM,SAAS,EACf,iBAAiB,UAAU,EAC3B,WAAW,iBAAiB,iBAqB7B,CAAC;AAEF,KAAK,UAAU,GAAG;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AACF,eAAO,MAAM,eAAe,GAC1B,MAAM,SAAS,EACf,iBAAiB,UAAU,EAC3B,WAAW,iBAAiB,qBAuC7B,CAAC"}
|
package/dist/runClientRequest.js
CHANGED
|
@@ -20,12 +20,14 @@ const TABLE_METHODS = {
|
|
|
20
20
|
getInfo: 1,
|
|
21
21
|
sync: 1,
|
|
22
22
|
insertMany: 1,
|
|
23
|
+
abort: 1,
|
|
23
24
|
};
|
|
24
25
|
const TABLE_METHODS_KEYS = (0, prostgles_types_1.getKeys)(TABLE_METHODS);
|
|
25
26
|
const SOCKET_ONLY_COMMANDS = [
|
|
26
27
|
"subscribe",
|
|
27
28
|
"subscribeOne",
|
|
28
29
|
"sync",
|
|
30
|
+
"abort",
|
|
29
31
|
];
|
|
30
32
|
const runClientRequest = async function (nonValidatedArgs, clientReq, scope) {
|
|
31
33
|
/* Channel name will only include client-sent params so we ignore table_rules enforced params */
|
|
@@ -37,7 +39,15 @@ const runClientRequest = async function (nonValidatedArgs, clientReq, scope) {
|
|
|
37
39
|
command: { enum: TABLE_METHODS_KEYS },
|
|
38
40
|
param1: { type: "any", optional: true },
|
|
39
41
|
param2: { type: "any", optional: true },
|
|
40
|
-
param3: {
|
|
42
|
+
param3: {
|
|
43
|
+
type: {
|
|
44
|
+
abortSignalId: { type: "string", optional: true },
|
|
45
|
+
returning: { type: "any", optional: true },
|
|
46
|
+
returnQuery: { type: "boolean", optional: true },
|
|
47
|
+
returnType: { type: "string", optional: true },
|
|
48
|
+
},
|
|
49
|
+
optional: true,
|
|
50
|
+
},
|
|
41
51
|
}, nonValidatedArgs, "tableName");
|
|
42
52
|
if (validation.error !== undefined) {
|
|
43
53
|
throw validation.error;
|
|
@@ -56,11 +66,6 @@ const runClientRequest = async function (nonValidatedArgs, clientReq, scope) {
|
|
|
56
66
|
throw clientInfo;
|
|
57
67
|
}
|
|
58
68
|
const parsedTableRule = await this.publishParser.getParsedTableRule({ tableName, clientReq }, clientInfo, scope);
|
|
59
|
-
this.publishParser.validateRequestRule({ tableName, command, clientReq }, parsedTableRule, scope);
|
|
60
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
61
|
-
if (!parsedTableRule) {
|
|
62
|
-
throw `Invalid OR disallowed request: ${tableName}.${command} `;
|
|
63
|
-
}
|
|
64
69
|
const sessionUser = !clientInfo.user ? undefined : ({
|
|
65
70
|
...(0, parseFieldFilter_1.parseFieldFilter)(
|
|
66
71
|
//@ts-ignore
|
|
@@ -72,6 +77,24 @@ const runClientRequest = async function (nonValidatedArgs, clientReq, scope) {
|
|
|
72
77
|
isRemoteRequest: { user: sessionUser },
|
|
73
78
|
scope,
|
|
74
79
|
};
|
|
80
|
+
if (command === "abort") {
|
|
81
|
+
const validation = (0, prostgles_types_1.getJSONBObjectSchemaValidationError)({
|
|
82
|
+
tableName: { type: "string" },
|
|
83
|
+
command: { enum: ["abort"] },
|
|
84
|
+
param1: {
|
|
85
|
+
type: { command: { enum: prostgles_types_1.ABORTABLE_METHODS }, abortSignalId: "string" },
|
|
86
|
+
},
|
|
87
|
+
}, nonValidatedArgs, "tableName", undefined, { allowExtraProperties: true });
|
|
88
|
+
if (validation.error !== undefined) {
|
|
89
|
+
throw validation.error;
|
|
90
|
+
}
|
|
91
|
+
this.publishParser.validateRequestRule({ tableName, command: validation.data.param1.command, clientReq }, parsedTableRule, scope);
|
|
92
|
+
tableHandler.abortRequests.add(validation.data.param1.abortSignalId);
|
|
93
|
+
return tableHandler.abortRemoteQuery(validation.data.param1.abortSignalId, localParams);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
this.publishParser.validateRequestRule({ tableName, command, clientReq }, parsedTableRule, scope);
|
|
97
|
+
}
|
|
75
98
|
if (param3 && param3.returnQuery) {
|
|
76
99
|
const isAllowed = await (0, runSQL_1.canRunSQL)(this, clientReq);
|
|
77
100
|
if (isAllowed) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runClientRequest.js","sourceRoot":"","sources":["../lib/runClientRequest.ts"],"names":[],"mappings":";;;AACA,
|
|
1
|
+
{"version":3,"file":"runClientRequest.js","sourceRoot":"","sources":["../lib/runClientRequest.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,7 +20,7 @@ import type {
|
|
|
20
20
|
TableSchema,
|
|
21
21
|
TxCB,
|
|
22
22
|
} from "./DboBuilderTypes";
|
|
23
|
-
import { QueryStreamer } from "./QueryStreamer";
|
|
23
|
+
import { QueryStreamer } from "./runSql/QueryStreamer";
|
|
24
24
|
import { TableHandler } from "./TableHandler/TableHandler";
|
|
25
25
|
import type { JoinPaths } from "./ViewHandler/ViewHandler";
|
|
26
26
|
import { parseJoinPath } from "./ViewHandler/parseJoinPath";
|
|
@@ -69,18 +69,27 @@ export class DboBuilder {
|
|
|
69
69
|
|
|
70
70
|
queryStreamer: QueryStreamer;
|
|
71
71
|
|
|
72
|
+
private constructor(prostgles: Prostgles) {
|
|
73
|
+
this.prostgles = prostgles;
|
|
74
|
+
if (!this.prostgles.db) throw "db missing";
|
|
75
|
+
this.db = this.prostgles.db;
|
|
76
|
+
this.dbo = {};
|
|
77
|
+
this.dboMap = new Map();
|
|
78
|
+
this.queryStreamer = new QueryStreamer(this);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
private init = async () => {
|
|
82
|
+
await this.build();
|
|
83
|
+
/* If watchSchema is enabled then PubSubManager must be created (if possible) because it creates the event trigger */
|
|
84
|
+
if (this.prostgles.schemaWatch?.type.watchType === "DDL_trigger") {
|
|
85
|
+
await this.getPubSubManager();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return this;
|
|
89
|
+
};
|
|
90
|
+
|
|
72
91
|
get tables(): TableSchema[] {
|
|
73
92
|
return this.tablesOrViews ?? [];
|
|
74
|
-
// .map(({ name, columns }) => {
|
|
75
|
-
// const info = this.dboMap.get(name)?.tableOrViewInfo;
|
|
76
|
-
// if (!info) return undefined;
|
|
77
|
-
// return {
|
|
78
|
-
// name,
|
|
79
|
-
// info,
|
|
80
|
-
// columns,
|
|
81
|
-
// } satisfies DbTableInfo;
|
|
82
|
-
// })
|
|
83
|
-
// .filter(isDefined);
|
|
84
93
|
}
|
|
85
94
|
|
|
86
95
|
getDetailedFieldInfo = async (fields: pg.IColumn[]) => {
|
|
@@ -130,32 +139,12 @@ export class DboBuilder {
|
|
|
130
139
|
|
|
131
140
|
onSchemaChange?: (event: { command: string; query: string }) => void;
|
|
132
141
|
|
|
133
|
-
private constructor(prostgles: Prostgles) {
|
|
134
|
-
this.prostgles = prostgles;
|
|
135
|
-
if (!this.prostgles.db) throw "db missing";
|
|
136
|
-
this.db = this.prostgles.db;
|
|
137
|
-
this.dbo = {};
|
|
138
|
-
this.dboMap = new Map();
|
|
139
|
-
this.queryStreamer = new QueryStreamer(this);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
private init = async () => {
|
|
143
|
-
await this.build();
|
|
144
|
-
/* If watchSchema is enabled then PubSubManager must be created (if possible) because it creates the event trigger */
|
|
145
|
-
if (this.prostgles.schemaWatch?.type.watchType === "DDL_trigger") {
|
|
146
|
-
await this.getPubSubManager();
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
return this;
|
|
150
|
-
};
|
|
151
|
-
|
|
152
142
|
public static create = async (prostgles: Prostgles): Promise<DboBuilder> => {
|
|
153
143
|
const res = new DboBuilder(prostgles);
|
|
154
144
|
return await res.init();
|
|
155
145
|
};
|
|
156
146
|
|
|
157
147
|
destroy = async () => {
|
|
158
|
-
await this.queryStreamer.destroy().catch(console.error);
|
|
159
148
|
return this._pubSubManager?.destroy();
|
|
160
149
|
};
|
|
161
150
|
|
|
@@ -20,7 +20,7 @@ import type { TableSchema } from "../DboBuilderTypes";
|
|
|
20
20
|
import { getValidatedTableRules } from "../TableRules/getValidatedTableRules";
|
|
21
21
|
import { getColumns } from "../getColumns";
|
|
22
22
|
import { count } from "./count";
|
|
23
|
-
import { find } from "./find";
|
|
23
|
+
import { find, type Param3 } from "./find";
|
|
24
24
|
import { getInfo } from "./getInfo";
|
|
25
25
|
import { parseFieldFilter } from "./parseFieldFilter";
|
|
26
26
|
import { prepareWhere } from "./prepareWhere";
|
|
@@ -30,6 +30,8 @@ import { subscribe } from "./subscribe";
|
|
|
30
30
|
import { validateViewRules } from "./validateViewRules";
|
|
31
31
|
import { escapeTSNames } from "../../utils/utils";
|
|
32
32
|
import type { TableDefinition } from "../../TableConfig/TableConfig";
|
|
33
|
+
import { getDbHandlerWithAbort } from "./getDbHandlerWithAbort";
|
|
34
|
+
import type { VoidFunction } from "../../SchemaWatch/SchemaWatch";
|
|
33
35
|
|
|
34
36
|
export type JoinPaths = {
|
|
35
37
|
t1: string;
|
|
@@ -112,6 +114,36 @@ export class ViewHandler {
|
|
|
112
114
|
return localParams?.tx || this.tx;
|
|
113
115
|
};
|
|
114
116
|
|
|
117
|
+
abortRemoteQuery = (abortSignalId: string, localParams: LocalParams) => {
|
|
118
|
+
const sid = this.dboBuilder.prostgles.authHandler.getSIDNoError(localParams.clientReq);
|
|
119
|
+
if (!sid) {
|
|
120
|
+
throw new Error(
|
|
121
|
+
"Cannot get SID from client request. Ensure that the client is authenticated before using abortable queries.",
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
const abortableQuery = this.activeQueries.get(abortSignalId);
|
|
125
|
+
if (!abortableQuery || abortableQuery.sid !== sid) {
|
|
126
|
+
throw new Error(
|
|
127
|
+
`No active query found with abortSignalId ${abortSignalId}. Ensure that the query was initiated with the correct abortSignalId.`,
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
abortableQuery.abort();
|
|
131
|
+
this.abortRequests.delete(abortSignalId);
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
activeQueries = new Map<
|
|
135
|
+
string,
|
|
136
|
+
{
|
|
137
|
+
abort: VoidFunction;
|
|
138
|
+
query: string;
|
|
139
|
+
start: number;
|
|
140
|
+
sid: string | undefined;
|
|
141
|
+
socketId: string | undefined;
|
|
142
|
+
}
|
|
143
|
+
>();
|
|
144
|
+
abortRequests = new Set<string>();
|
|
145
|
+
getDbHandlerWithAbort = getDbHandlerWithAbort.bind(this);
|
|
146
|
+
|
|
115
147
|
_log = ({
|
|
116
148
|
command,
|
|
117
149
|
data,
|
|
@@ -178,7 +210,7 @@ export class ViewHandler {
|
|
|
178
210
|
async findOne(
|
|
179
211
|
filter?: Filter,
|
|
180
212
|
selectParams?: SelectParams,
|
|
181
|
-
|
|
213
|
+
param3?: Param3,
|
|
182
214
|
table_rules?: ParsedTableRule,
|
|
183
215
|
localParams?: LocalParams,
|
|
184
216
|
): Promise<any> {
|
|
@@ -191,7 +223,7 @@ export class ViewHandler {
|
|
|
191
223
|
const result = await this.find(
|
|
192
224
|
filter,
|
|
193
225
|
{ ...params, limit: 1, returnType: "row" },
|
|
194
|
-
|
|
226
|
+
param3,
|
|
195
227
|
table_rules,
|
|
196
228
|
localParams,
|
|
197
229
|
);
|
|
@@ -8,12 +8,13 @@ import {
|
|
|
8
8
|
} from "../dboBuilderUtils";
|
|
9
9
|
import type { ViewHandler } from "./ViewHandler";
|
|
10
10
|
import { getReturnTypeQuery } from "./getReturnTypeQuery";
|
|
11
|
+
import type { Param3 } from "./find";
|
|
11
12
|
|
|
12
13
|
export async function count(
|
|
13
14
|
this: ViewHandler,
|
|
14
15
|
_filter?: Filter,
|
|
15
16
|
selectParams?: SelectParams,
|
|
16
|
-
|
|
17
|
+
param3?: Param3,
|
|
17
18
|
table_rules?: ParsedTableRule,
|
|
18
19
|
localParams?: LocalParams,
|
|
19
20
|
): Promise<number> {
|
|
@@ -54,7 +55,10 @@ export async function count(
|
|
|
54
55
|
return queryToReturn as unknown[];
|
|
55
56
|
}
|
|
56
57
|
|
|
57
|
-
const handler = this.
|
|
58
|
+
const handler = this.getDbHandlerWithAbort(localParams, {
|
|
59
|
+
abortSignal: selectParams?.abortSignal,
|
|
60
|
+
abortSignalId: param3?.abortSignalId,
|
|
61
|
+
});
|
|
58
62
|
return handler.one(queryWithRLS).then(({ count }) => +count);
|
|
59
63
|
});
|
|
60
64
|
|
|
@@ -13,19 +13,23 @@ import { getSelectQuery } from "../QueryBuilder/getSelectQuery";
|
|
|
13
13
|
import { getReturnTypeQuery } from "./getReturnTypeQuery";
|
|
14
14
|
import type { ViewHandler } from "./ViewHandler";
|
|
15
15
|
|
|
16
|
+
export type Param3 = {
|
|
17
|
+
abortSignalId?: string;
|
|
18
|
+
};
|
|
19
|
+
|
|
16
20
|
export const find = async function (
|
|
17
21
|
this: ViewHandler,
|
|
18
|
-
filter
|
|
22
|
+
filter: Filter = {},
|
|
19
23
|
selectParams?: SelectParams,
|
|
20
|
-
|
|
24
|
+
param3?: Param3,
|
|
21
25
|
tableRules?: ParsedTableRule,
|
|
22
26
|
localParams?: LocalParams,
|
|
23
27
|
): Promise<any[]> {
|
|
24
28
|
const start = Date.now();
|
|
25
|
-
const
|
|
26
|
-
|
|
29
|
+
const { limit, returnType, abortSignal } = selectParams ?? {};
|
|
30
|
+
|
|
31
|
+
const command = limit === 1 && returnType === "row" ? "findOne" : "find";
|
|
27
32
|
try {
|
|
28
|
-
filter = filter || {};
|
|
29
33
|
const allowedReturnTypes = Object.keys({
|
|
30
34
|
row: 1,
|
|
31
35
|
statement: 1,
|
|
@@ -52,6 +56,7 @@ export const find = async function (
|
|
|
52
56
|
returnType: 1,
|
|
53
57
|
groupBy: 1,
|
|
54
58
|
having: 1,
|
|
59
|
+
abortSignal: 1,
|
|
55
60
|
} satisfies Record<keyof SelectParams, 1>);
|
|
56
61
|
|
|
57
62
|
const invalidParams = Object.keys(selectParams).filter((k) => !validParamNames.includes(k));
|
|
@@ -96,7 +101,7 @@ export const find = async function (
|
|
|
96
101
|
this,
|
|
97
102
|
filter,
|
|
98
103
|
selectParamsLimitCheck,
|
|
99
|
-
|
|
104
|
+
undefined,
|
|
100
105
|
tableRules,
|
|
101
106
|
localParams,
|
|
102
107
|
);
|
|
@@ -109,6 +114,7 @@ export const find = async function (
|
|
|
109
114
|
);
|
|
110
115
|
|
|
111
116
|
const queryWithRLS = withUserRLS(localParams, queryWithoutRLS);
|
|
117
|
+
|
|
112
118
|
const queryToReturn = await getReturnTypeQuery({
|
|
113
119
|
handler: this,
|
|
114
120
|
localParams,
|
|
@@ -123,7 +129,10 @@ export const find = async function (
|
|
|
123
129
|
|
|
124
130
|
const query = queryWithRLS;
|
|
125
131
|
const isOneOrNone = returnType === "row" || returnType === "value";
|
|
126
|
-
const dbHandler = this.
|
|
132
|
+
const dbHandler = this.getDbHandlerWithAbort(localParams, {
|
|
133
|
+
abortSignal,
|
|
134
|
+
abortSignalId: param3?.abortSignalId,
|
|
135
|
+
});
|
|
127
136
|
const queryPromise =
|
|
128
137
|
isOneOrNone ?
|
|
129
138
|
dbHandler.oneOrNone<AnyObject>(query).then((data) => (data ? [data] : []))
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { DB } from "../../initProstgles";
|
|
2
|
+
import { QUERY_ID_PREFIX, type LocalParams } from "../DboBuilder";
|
|
3
|
+
import type { ViewHandler } from "./ViewHandler";
|
|
4
|
+
import type * as pgPromise from "pg-promise";
|
|
5
|
+
|
|
6
|
+
export function getDbHandlerWithAbort(
|
|
7
|
+
this: ViewHandler,
|
|
8
|
+
localParams: LocalParams | undefined,
|
|
9
|
+
params: { abortSignal: AbortSignal | undefined; abortSignalId: string | undefined },
|
|
10
|
+
): Pick<DB | pgPromise.ITask<{}>, "any" | "one" | "many" | "manyOrNone" | "none" | "oneOrNone"> {
|
|
11
|
+
if (params.abortSignal && params.abortSignalId) {
|
|
12
|
+
throw new Error("Cannot provide both abortSignal and abortSignalId");
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (params.abortSignal?.aborted) {
|
|
16
|
+
throw new Error("Query aborted before execution");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const abortSignal =
|
|
20
|
+
params.abortSignal ?? AbortSignal.timeout(localParams?.clientReq ? 7_000 : 120_000);
|
|
21
|
+
const abortSignalId = params.abortSignalId ?? crypto.randomUUID();
|
|
22
|
+
|
|
23
|
+
if (this.activeQueries.has(abortSignalId)) {
|
|
24
|
+
throw new Error(
|
|
25
|
+
`A query with abortSignalId ${params.abortSignalId} is already active. Ensure that each query has a unique abortSignalId.`,
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
const handler = this.getTransaction(localParams)?.t ?? this.db;
|
|
29
|
+
const { adminClient } = this.dboBuilder.prostgles;
|
|
30
|
+
if (!adminClient) {
|
|
31
|
+
throw new Error(
|
|
32
|
+
"adminClient not available. Ensure prostgles.adminClient is initialized before using abortable queries.",
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
const sid = this.dboBuilder.prostgles.authHandler.getSIDNoError(localParams?.clientReq);
|
|
36
|
+
if (!sid && localParams?.clientReq) {
|
|
37
|
+
throw new Error(
|
|
38
|
+
"Cannot get SID from client request. Ensure that the client is authenticated before using abortable queries.",
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
const withAbortQuery = <Args extends unknown[], R extends Promise<any>>(
|
|
42
|
+
func: (query: string, ...args: Args) => R,
|
|
43
|
+
) => {
|
|
44
|
+
return (query: string, ...args: Args) => {
|
|
45
|
+
const queryIdPrefix = query.split("\n", 1)[0];
|
|
46
|
+
|
|
47
|
+
const queryHasIdPrefix = queryIdPrefix?.startsWith(QUERY_ID_PREFIX);
|
|
48
|
+
if (!queryIdPrefix || !queryHasIdPrefix) {
|
|
49
|
+
throw new Error(
|
|
50
|
+
"Query does not have a prostgles query id prefix. Ensure that the query is generated using prostgles methods that include the query id.",
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const abort = () => {
|
|
55
|
+
void this._log({
|
|
56
|
+
data: { query, abortSignalId },
|
|
57
|
+
command: "abort",
|
|
58
|
+
localParams,
|
|
59
|
+
duration: Date.now() - (this.activeQueries.get(abortSignalId)?.start ?? Date.now()),
|
|
60
|
+
error: new Error("Query aborted"),
|
|
61
|
+
});
|
|
62
|
+
/** Only terminate if there is exactly one matching query with a query id prefix */
|
|
63
|
+
|
|
64
|
+
this.abortRequests.delete(abortSignalId);
|
|
65
|
+
void adminClient
|
|
66
|
+
.query(
|
|
67
|
+
`
|
|
68
|
+
SELECT pg_cancel_backend(pid), *
|
|
69
|
+
FROM pg_stat_activity
|
|
70
|
+
WHERE query LIKE $1 AND pid <> pg_backend_pid()
|
|
71
|
+
`,
|
|
72
|
+
[`${queryIdPrefix}%`],
|
|
73
|
+
)
|
|
74
|
+
.catch((err) => {
|
|
75
|
+
// ignore error
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
if (this.abortRequests.has(abortSignalId)) {
|
|
80
|
+
this.abortRequests.delete(abortSignalId);
|
|
81
|
+
throw new Error(`Abort requested`);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
this.activeQueries.set(abortSignalId, {
|
|
85
|
+
query,
|
|
86
|
+
start: Date.now(),
|
|
87
|
+
sid,
|
|
88
|
+
abort,
|
|
89
|
+
socketId: localParams?.clientReq?.socket?.id,
|
|
90
|
+
});
|
|
91
|
+
abortSignal.addEventListener("abort", abort);
|
|
92
|
+
return func(query, ...args).finally(() => {
|
|
93
|
+
abortSignal.removeEventListener("abort", abort);
|
|
94
|
+
this.activeQueries.delete(abortSignalId);
|
|
95
|
+
this.abortRequests.delete(abortSignalId);
|
|
96
|
+
});
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
manyOrNone: withAbortQuery(handler.manyOrNone.bind(handler)),
|
|
102
|
+
one: withAbortQuery(handler.one.bind(handler)),
|
|
103
|
+
oneOrNone: withAbortQuery(handler.oneOrNone.bind(handler)),
|
|
104
|
+
any: withAbortQuery(handler.any.bind(handler)),
|
|
105
|
+
none: withAbortQuery(handler.none.bind(handler)),
|
|
106
|
+
many: withAbortQuery(handler.many.bind(handler)),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
@@ -8,11 +8,12 @@ import {
|
|
|
8
8
|
} from "../dboBuilderUtils";
|
|
9
9
|
import type { ViewHandler } from "./ViewHandler";
|
|
10
10
|
import { getReturnTypeQuery } from "./getReturnTypeQuery";
|
|
11
|
+
import type { Param3 } from "./find";
|
|
11
12
|
export async function size(
|
|
12
13
|
this: ViewHandler,
|
|
13
14
|
_filter?: Filter,
|
|
14
15
|
selectParams?: SelectParams,
|
|
15
|
-
|
|
16
|
+
param3?: Param3,
|
|
16
17
|
table_rules?: ParsedTableRule,
|
|
17
18
|
localParams?: LocalParams,
|
|
18
19
|
): Promise<string> {
|
|
@@ -22,7 +23,7 @@ export async function size(
|
|
|
22
23
|
const result = await this.find(
|
|
23
24
|
filter,
|
|
24
25
|
{ ...selectParams, limit: 2 },
|
|
25
|
-
|
|
26
|
+
param3,
|
|
26
27
|
table_rules,
|
|
27
28
|
localParams,
|
|
28
29
|
).then(async (_allowed) => {
|
|
@@ -57,9 +58,11 @@ export async function size(
|
|
|
57
58
|
return queryToReturn as unknown[];
|
|
58
59
|
}
|
|
59
60
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
const handler = this.getDbHandlerWithAbort(localParams, {
|
|
62
|
+
abortSignal: selectParams?.abortSignal,
|
|
63
|
+
abortSignalId: param3?.abortSignalId,
|
|
64
|
+
});
|
|
65
|
+
return handler.one<{ size: string | null }>(queryWithRLS).then(({ size }) => size || "0");
|
|
63
66
|
});
|
|
64
67
|
await this._log({
|
|
65
68
|
command: "size",
|
|
@@ -176,6 +176,8 @@ export const getCanExecute = async (db: DB) => {
|
|
|
176
176
|
return false;
|
|
177
177
|
};
|
|
178
178
|
|
|
179
|
+
export const QUERY_ID_PREFIX = "-- prostgles query id: ";
|
|
180
|
+
|
|
179
181
|
export const withUserRLS = (localParams: LocalParams | undefined, query: string) => {
|
|
180
182
|
const user = localParams?.isRemoteRequest?.user;
|
|
181
183
|
const queryPrefix = `SET SESSION "prostgles.user" \nTO`;
|
|
@@ -184,5 +186,6 @@ export const withUserRLS = (localParams: LocalParams | undefined, query: string)
|
|
|
184
186
|
firstQuery = pgp.as.format(`${queryPrefix} \${user};`, { user });
|
|
185
187
|
}
|
|
186
188
|
|
|
187
|
-
|
|
189
|
+
const queryId = crypto.randomUUID();
|
|
190
|
+
return [QUERY_ID_PREFIX + queryId, firstQuery, query].filter(Boolean).join("\n");
|
|
188
191
|
};
|
|
@@ -2,13 +2,14 @@ import * as pg from "pg";
|
|
|
2
2
|
import type CursorType from "pg-cursor";
|
|
3
3
|
import type { SQLOptions, SocketSQLStreamPacket, SocketSQLStreamServer } from "prostgles-types";
|
|
4
4
|
import { CHANNELS, omitKeys, pickKeys } from "prostgles-types";
|
|
5
|
-
import type { BasicCallback } from "
|
|
6
|
-
import type { VoidFunction } from "
|
|
7
|
-
import type { DB } from "
|
|
8
|
-
import type { DboBuilder } from "
|
|
9
|
-
import type { PRGLIOSocket } from "
|
|
10
|
-
import { getErrorAsObject, getSerializedClientErrorFromPGError } from "
|
|
11
|
-
import { getDetailedFieldInfo } from "./
|
|
5
|
+
import type { BasicCallback } from "../../PubSubManager/PubSubManager";
|
|
6
|
+
import type { VoidFunction } from "../../SchemaWatch/SchemaWatch";
|
|
7
|
+
import type { DB } from "../../initProstgles";
|
|
8
|
+
import type { DboBuilder } from "../DboBuilder";
|
|
9
|
+
import type { PRGLIOSocket } from "../DboBuilderTypes";
|
|
10
|
+
import { getErrorAsObject, getSerializedClientErrorFromPGError } from "../dboBuilderUtils";
|
|
11
|
+
import { getDetailedFieldInfo } from "./runSqlUtils";
|
|
12
|
+
import { getConnectionDetails } from "./getAdminClient";
|
|
12
13
|
const Cursor = require("pg-cursor") as typeof CursorType;
|
|
13
14
|
|
|
14
15
|
type ClientStreamedRequest = {
|
|
@@ -44,36 +45,13 @@ export class QueryStreamer {
|
|
|
44
45
|
db: DB;
|
|
45
46
|
dboBuilder: DboBuilder;
|
|
46
47
|
socketQueries: Map<string, Map<number, StreamedQuery>> = new Map();
|
|
47
|
-
adminClient: pg.Client;
|
|
48
48
|
constructor(dboBuilder: DboBuilder) {
|
|
49
49
|
this.dboBuilder = dboBuilder;
|
|
50
50
|
this.db = dboBuilder.db;
|
|
51
|
-
const setAdminClient = () => {
|
|
52
|
-
this.adminClient = this.getConnection(undefined, { keepAlive: true });
|
|
53
|
-
return this.adminClient.connect();
|
|
54
|
-
};
|
|
55
|
-
this.adminClient = this.getConnection(
|
|
56
|
-
(error) => {
|
|
57
|
-
if (error.message?.includes("database") && error.message?.includes("does not exist"))
|
|
58
|
-
return;
|
|
59
|
-
console.log("Admin client error. Reconnecting...", error);
|
|
60
|
-
void setAdminClient();
|
|
61
|
-
},
|
|
62
|
-
{ keepAlive: true },
|
|
63
|
-
);
|
|
64
|
-
void this.adminClient.connect();
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
destroy() {
|
|
68
|
-
return this.adminClient.end().catch((err) => {
|
|
69
|
-
console.error("Error ending admin client connection", err);
|
|
70
|
-
});
|
|
71
51
|
}
|
|
72
52
|
|
|
73
53
|
getConnection = (onError: ((err: any) => void) | undefined, extraOptions?: pg.ClientConfig) => {
|
|
74
|
-
const
|
|
75
|
-
typeof this.db.$cn === "string" ? { connectionString: this.db.$cn } : (this.db.$cn as any);
|
|
76
|
-
const client = new pg.Client({ ...connectionInfo, ...extraOptions });
|
|
54
|
+
const client = new pg.Client({ ...getConnectionDetails(this.db), ...extraOptions });
|
|
77
55
|
client.on("error", (err) => {
|
|
78
56
|
onError?.(err);
|
|
79
57
|
});
|
|
@@ -272,7 +250,7 @@ export class QueryStreamer {
|
|
|
272
250
|
}
|
|
273
251
|
try {
|
|
274
252
|
const stopFunction = opts?.terminate ? "pg_terminate_backend" : "pg_cancel_backend";
|
|
275
|
-
const rows = await this.adminClient
|
|
253
|
+
const rows = await this.dboBuilder.prostgles.adminClient!.query(
|
|
276
254
|
`SELECT ${stopFunction}(pid), pid, state, query FROM pg_stat_activity WHERE pid = $1`,
|
|
277
255
|
[processID],
|
|
278
256
|
);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as pg from "pg";
|
|
2
|
+
import type { DB } from "../../initProstgles";
|
|
3
|
+
|
|
4
|
+
export const getAdminClient = async (db: DB, onDbDropped?: () => void): Promise<pg.Client> => {
|
|
5
|
+
const adminClient = new pg.Client({
|
|
6
|
+
...getConnectionDetails(db),
|
|
7
|
+
application_name: "prostgles-admin-client",
|
|
8
|
+
keepAlive: true,
|
|
9
|
+
});
|
|
10
|
+
if (onDbDropped) {
|
|
11
|
+
adminClient.on("error", (err) => {
|
|
12
|
+
if (
|
|
13
|
+
err.message.includes("terminating connection due to administrator command") ||
|
|
14
|
+
(err.message.includes("database") && err.message.includes("does not exist"))
|
|
15
|
+
) {
|
|
16
|
+
onDbDropped();
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
await adminClient.connect();
|
|
21
|
+
return adminClient;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const getConnectionDetails = (db: DB) => {
|
|
25
|
+
const opts = db.$pool.options as pg.ClientConfig;
|
|
26
|
+
return {
|
|
27
|
+
...opts,
|
|
28
|
+
password: opts.password,
|
|
29
|
+
keepAlive: true,
|
|
30
|
+
} satisfies pg.ClientConfig;
|
|
31
|
+
};
|
package/lib/Logging.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AnyObject, ClientSchema, TableHandler } from "prostgles-types";
|
|
1
|
+
import type { ABORTABLE_METHODS, AnyObject, ClientSchema, TableHandler } from "prostgles-types";
|
|
2
2
|
import type { LocalParams } from "./DboBuilder/DboBuilder";
|
|
3
3
|
import type { PubSubManagerTriggers, SyncParams } from "./PubSubManager/PubSubManager";
|
|
4
4
|
import type { NotifTypeName } from "./PubSubManager/PubSubManagerUtils";
|
|
@@ -14,15 +14,25 @@ export namespace EventTypes {
|
|
|
14
14
|
error?: any;
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
export type Table =
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
17
|
+
export type Table =
|
|
18
|
+
| (ClientInfo &
|
|
19
|
+
DebugInfo & {
|
|
20
|
+
type: "table";
|
|
21
|
+
tableName: string;
|
|
22
|
+
command: keyof TableHandler | "sync";
|
|
23
|
+
txInfo: AnyObject | undefined;
|
|
24
|
+
data: AnyObject;
|
|
25
|
+
localParams: LocalParams | undefined;
|
|
26
|
+
})
|
|
27
|
+
| (ClientInfo &
|
|
28
|
+
DebugInfo & {
|
|
29
|
+
type: "table";
|
|
30
|
+
tableName: string;
|
|
31
|
+
command: "abort";
|
|
32
|
+
txInfo: AnyObject | undefined;
|
|
33
|
+
data: AnyObject;
|
|
34
|
+
localParams: LocalParams | undefined;
|
|
35
|
+
});
|
|
26
36
|
|
|
27
37
|
export type Sync = ClientInfo &
|
|
28
38
|
DebugInfo & {
|