prostgles-server 4.2.549 → 4.2.550
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/TableHandler/TableHandler.d.ts +18 -5
- package/dist/DboBuilder/TableHandler/TableHandler.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/TableHandler.js +12 -6
- package/dist/DboBuilder/TableHandler/TableHandler.js.map +1 -1
- package/dist/DboBuilder/TableHandler/delete.d.ts +1 -1
- package/dist/DboBuilder/TableHandler/delete.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/delete.js +56 -13
- package/dist/DboBuilder/TableHandler/delete.js.map +1 -1
- package/dist/DboBuilder/TableHandler/executeHooksCheckAndPostValidation.d.ts +21 -0
- package/dist/DboBuilder/TableHandler/executeHooksCheckAndPostValidation.d.ts.map +1 -0
- package/dist/DboBuilder/TableHandler/executeHooksCheckAndPostValidation.js +69 -0
- package/dist/DboBuilder/TableHandler/executeHooksCheckAndPostValidation.js.map +1 -0
- package/dist/DboBuilder/TableHandler/insert/insert.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/insert/insert.js +21 -11
- package/dist/DboBuilder/TableHandler/insert/insert.js.map +1 -1
- package/dist/DboBuilder/TableHandler/insert/insertNestedRecords.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/insert/insertNestedRecords.js +1 -2
- package/dist/DboBuilder/TableHandler/insert/insertNestedRecords.js.map +1 -1
- package/dist/DboBuilder/TableHandler/onDeleteFromFileTable.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/onDeleteFromFileTable.js +2 -1
- package/dist/DboBuilder/TableHandler/onDeleteFromFileTable.js.map +1 -1
- package/dist/DboBuilder/TableHandler/runInsertUpdateQuery.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/runInsertUpdateQuery.js +24 -95
- package/dist/DboBuilder/TableHandler/runInsertUpdateQuery.js.map +1 -1
- package/dist/DboBuilder/TableHandler/update.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/update.js +20 -12
- package/dist/DboBuilder/TableHandler/update.js.map +1 -1
- package/dist/DboBuilder/TableHandler/updateBatch.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/updateBatch.js +13 -1
- package/dist/DboBuilder/TableHandler/updateBatch.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts +1 -1
- package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/ViewHandler.js +5 -5
- package/dist/DboBuilder/ViewHandler/ViewHandler.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/count.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/count.js +20 -8
- package/dist/DboBuilder/ViewHandler/count.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/find.d.ts +0 -12
- package/dist/DboBuilder/ViewHandler/find.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/find.js +27 -75
- package/dist/DboBuilder/ViewHandler/find.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/getReturnTypeQuery.d.ts +14 -0
- package/dist/DboBuilder/ViewHandler/getReturnTypeQuery.d.ts.map +1 -0
- package/dist/DboBuilder/ViewHandler/getReturnTypeQuery.js +32 -0
- package/dist/DboBuilder/ViewHandler/getReturnTypeQuery.js.map +1 -0
- package/dist/DboBuilder/ViewHandler/size.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/size.js +23 -8
- package/dist/DboBuilder/ViewHandler/size.js.map +1 -1
- package/dist/DboBuilder/dboBuilderUtils.d.ts +1 -1
- package/dist/DboBuilder/dboBuilderUtils.d.ts.map +1 -1
- package/dist/DboBuilder/dboBuilderUtils.js +2 -2
- package/dist/DboBuilder/dboBuilderUtils.js.map +1 -1
- package/dist/DboBuilder/parseUpdateRules.js +1 -1
- package/dist/DboBuilder/parseUpdateRules.js.map +1 -1
- package/dist/PublishParser/publishTypesAndUtils.d.ts +34 -1
- package/dist/PublishParser/publishTypesAndUtils.d.ts.map +1 -1
- package/dist/PublishParser/publishTypesAndUtils.js.map +1 -1
- package/dist/TableConfig/TableConfig.d.ts +3 -15
- package/dist/TableConfig/TableConfig.d.ts.map +1 -1
- package/dist/TableConfig/TableConfig.js.map +1 -1
- package/dist/TableConfig/getCreateSchemaQueries.d.ts +4 -28
- package/dist/TableConfig/getCreateSchemaQueries.d.ts.map +1 -1
- package/dist/TableConfig/getTableConfigSchemaQueries.d.ts +4 -28
- package/dist/TableConfig/getTableConfigSchemaQueries.d.ts.map +1 -1
- package/dist/utils/utils.d.ts +1 -0
- package/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +3 -1
- package/dist/utils/utils.js.map +1 -1
- package/lib/DboBuilder/TableHandler/TableHandler.ts +21 -6
- package/lib/DboBuilder/TableHandler/delete.ts +83 -15
- package/lib/DboBuilder/TableHandler/executeHooksCheckAndPostValidation.ts +88 -0
- package/lib/DboBuilder/TableHandler/insert/insert.ts +25 -11
- package/lib/DboBuilder/TableHandler/insert/insertNestedRecords.ts +1 -2
- package/lib/DboBuilder/TableHandler/onDeleteFromFileTable.ts +7 -5
- package/lib/DboBuilder/TableHandler/runInsertUpdateQuery.ts +34 -110
- package/lib/DboBuilder/TableHandler/update.ts +21 -12
- package/lib/DboBuilder/TableHandler/updateBatch.ts +15 -2
- package/lib/DboBuilder/ViewHandler/ViewHandler.ts +5 -5
- package/lib/DboBuilder/ViewHandler/count.ts +24 -9
- package/lib/DboBuilder/ViewHandler/find.ts +35 -96
- package/lib/DboBuilder/ViewHandler/getReturnTypeQuery.ts +50 -0
- package/lib/DboBuilder/ViewHandler/size.ts +26 -12
- package/lib/DboBuilder/dboBuilderUtils.ts +1 -1
- package/lib/DboBuilder/parseUpdateRules.ts +1 -1
- package/lib/PublishParser/publishTypesAndUtils.ts +42 -1
- package/lib/TableConfig/TableConfig.ts +4 -18
- package/lib/utils/utils.ts +2 -0
- package/package.json +1 -1
|
@@ -2,9 +2,10 @@ import type { AnyObject, FieldFilter, InsertParams, UpdateParams } from "prostgl
|
|
|
2
2
|
import { asName } from "prostgles-types";
|
|
3
3
|
import type { InsertRule, UpdateRule } from "../../PublishParser/PublishParser";
|
|
4
4
|
import type { LocalParams } from "../DboBuilder";
|
|
5
|
-
import {
|
|
5
|
+
import { rejectWithPGClientError, withUserRLS } from "../DboBuilder";
|
|
6
6
|
import type { TableHandler } from "./TableHandler";
|
|
7
7
|
import { getSelectItemQuery } from "./TableHandler";
|
|
8
|
+
import { executeHooksCheckAndPostValidation } from "./executeHooksCheckAndPostValidation";
|
|
8
9
|
|
|
9
10
|
type RunInsertUpdateQueryArgs = {
|
|
10
11
|
tableHandler: TableHandler;
|
|
@@ -71,7 +72,12 @@ export const runInsertUpdateQuery = async (args: RunInsertUpdateQueryArgs) => {
|
|
|
71
72
|
RETURNING *
|
|
72
73
|
)
|
|
73
74
|
SELECT
|
|
74
|
-
count(*) as row_count,
|
|
75
|
+
count(*) as row_count,
|
|
76
|
+
EXISTS (
|
|
77
|
+
SELECT *
|
|
78
|
+
FROM ${escapedTableName}
|
|
79
|
+
${checkCondition}
|
|
80
|
+
) AS failed_check,
|
|
75
81
|
(
|
|
76
82
|
SELECT json_agg(item)
|
|
77
83
|
FROM (
|
|
@@ -86,127 +92,47 @@ export const runInsertUpdateQuery = async (args: RunInsertUpdateQueryArgs) => {
|
|
|
86
92
|
FROM ${escapedTableName}
|
|
87
93
|
WHERE ${hasReturning ? "TRUE" : "FALSE"}
|
|
88
94
|
) item
|
|
89
|
-
) as modified_returning
|
|
90
|
-
(
|
|
91
|
-
SELECT json_agg(item)
|
|
92
|
-
FROM (
|
|
93
|
-
SELECT *
|
|
94
|
-
FROM ${escapedTableName}
|
|
95
|
-
${checkCondition}
|
|
96
|
-
LIMIT 5
|
|
97
|
-
) item
|
|
98
|
-
) AS failed_check
|
|
95
|
+
) as modified_returning
|
|
99
96
|
FROM ${escapedTableName}
|
|
100
97
|
`;
|
|
101
98
|
|
|
102
99
|
const allowedFieldKeys = tableHandler.parseFieldFilter(fields);
|
|
103
|
-
let result: {
|
|
104
|
-
row_count: number | null;
|
|
105
|
-
modified: AnyObject[] | null;
|
|
106
|
-
failed_check: AnyObject[] | null;
|
|
107
|
-
modified_returning: AnyObject[] | null;
|
|
108
|
-
};
|
|
109
100
|
|
|
110
101
|
const queryType = "one";
|
|
111
102
|
|
|
112
|
-
const tx =
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
.
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
localParams,
|
|
130
|
-
view: tableHandler,
|
|
131
|
-
allowedKeys: allowedFieldKeys,
|
|
132
|
-
prostgles: tableHandler.dboBuilder.prostgles,
|
|
133
|
-
}),
|
|
134
|
-
);
|
|
135
|
-
}
|
|
103
|
+
const tx = tableHandler.getTransaction(localParams)?.t;
|
|
104
|
+
const queryPromise: Promise<{
|
|
105
|
+
row_count: number | null;
|
|
106
|
+
modified: AnyObject[] | null;
|
|
107
|
+
failed_check: boolean | null;
|
|
108
|
+
modified_returning: AnyObject[] | null;
|
|
109
|
+
}> = tx ? tx[queryType](query) : tableHandler.db.tx((t) => t[queryType](query));
|
|
110
|
+
|
|
111
|
+
const result = await queryPromise.catch((err: unknown) =>
|
|
112
|
+
rejectWithPGClientError(err, {
|
|
113
|
+
type: "tableMethod",
|
|
114
|
+
localParams,
|
|
115
|
+
view: tableHandler,
|
|
116
|
+
allowedKeys: allowedFieldKeys,
|
|
117
|
+
prostgles: tableHandler.dboBuilder.prostgles,
|
|
118
|
+
}),
|
|
119
|
+
);
|
|
136
120
|
|
|
137
|
-
if (checkFilter && result.failed_check
|
|
121
|
+
if (checkFilter && result.failed_check) {
|
|
138
122
|
throw new Error(
|
|
139
123
|
`Insert ${name} records failed the check condition: ${JSON.stringify(checkFilter, null, 2)}`,
|
|
140
124
|
);
|
|
141
125
|
}
|
|
142
126
|
|
|
143
127
|
const rows = result.modified ?? [];
|
|
144
|
-
const finalDBtx = tableHandler.getFinalDBtx(localParams);
|
|
145
|
-
const { postValidate } = rule ?? {};
|
|
146
|
-
const hooks = tableHandler.getHooksAndChecks(
|
|
147
|
-
command === "insert" ? { name: command, rule } : { name: command, rule },
|
|
148
|
-
);
|
|
149
|
-
let changedFieldsSet = undefined as undefined | Set<string>;
|
|
150
|
-
const getChangedFieldsSet = () => {
|
|
151
|
-
changedFieldsSet ??= new Set<string>(
|
|
152
|
-
(isArray(data) ? data : [data]).map((row) => Object.keys(row)).flat(),
|
|
153
|
-
);
|
|
154
|
-
return changedFieldsSet;
|
|
155
|
-
};
|
|
156
|
-
const applicableHooks = hooks.filter((hook) => {
|
|
157
|
-
if (hook.type === "checkFilter") return;
|
|
158
|
-
if (hook.type === "postValidate") return true;
|
|
159
|
-
const { commands, changedFields } = hook;
|
|
160
|
-
return (
|
|
161
|
-
commands[command] &&
|
|
162
|
-
(!changedFields || changedFields.some((f) => getChangedFieldsSet().has(f)))
|
|
163
|
-
);
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
if (postValidate && !localParams) {
|
|
167
|
-
throw new Error("Unexpected: no localParams for postValidate");
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
if (applicableHooks.length) {
|
|
171
|
-
if (!finalDBtx) throw new Error("Unexpected: no dbTX for hooks/postValidate");
|
|
172
|
-
|
|
173
|
-
for (const row of rows) {
|
|
174
|
-
const commonParams = {
|
|
175
|
-
row: row,
|
|
176
|
-
tx: tx || tableHandler.db,
|
|
177
|
-
dbx: finalDBtx,
|
|
178
|
-
command,
|
|
179
|
-
data,
|
|
180
|
-
} as const;
|
|
181
|
-
for (const hook of applicableHooks) {
|
|
182
|
-
if (hook.type === "afterEach") {
|
|
183
|
-
await hook.validate({
|
|
184
|
-
...commonParams,
|
|
185
|
-
localParams,
|
|
186
|
-
});
|
|
187
|
-
} else if (hook.type === "postValidate") {
|
|
188
|
-
if (!localParams) throw new Error("Unexpected: no localParams for postValidate");
|
|
189
|
-
await hook.validate({
|
|
190
|
-
...commonParams,
|
|
191
|
-
localParams,
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
128
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
rows,
|
|
205
|
-
localParams,
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
}
|
|
129
|
+
await executeHooksCheckAndPostValidation({
|
|
130
|
+
tableHandler,
|
|
131
|
+
operation: command === "insert" ? { name: "insert", rule } : { name: "update", rule },
|
|
132
|
+
localParams,
|
|
133
|
+
rows,
|
|
134
|
+
data,
|
|
135
|
+
});
|
|
210
136
|
|
|
211
137
|
let returnMany = false;
|
|
212
138
|
if (args.command === "update") {
|
|
@@ -231,5 +157,3 @@ export const runInsertUpdateQuery = async (args: RunInsertUpdateQueryArgs) => {
|
|
|
231
157
|
|
|
232
158
|
return returnMany ? modified_returning : modified_returning?.[0];
|
|
233
159
|
};
|
|
234
|
-
|
|
235
|
-
const isArray = <T>(data: T): data is Extract<T, readonly unknown[]> => Array.isArray(data);
|
|
@@ -8,6 +8,7 @@ import { runInsertUpdateQuery } from "./runInsertUpdateQuery";
|
|
|
8
8
|
import type { TableHandler } from "./TableHandler";
|
|
9
9
|
import { updateFile } from "./updateFile";
|
|
10
10
|
import { getInsertTableRules } from "./insert/getInsertTableRules";
|
|
11
|
+
import { getReturnTypeQuery } from "../ViewHandler/getReturnTypeQuery";
|
|
11
12
|
|
|
12
13
|
export async function update(
|
|
13
14
|
this: TableHandler,
|
|
@@ -20,11 +21,10 @@ export async function update(
|
|
|
20
21
|
const ACTION = "update";
|
|
21
22
|
const start = Date.now();
|
|
22
23
|
try {
|
|
23
|
-
|
|
24
|
-
const finalDBtx = this.getFinalDBtx(localParams);
|
|
24
|
+
const transaction = this.getTransaction(localParams);
|
|
25
25
|
const wrapInTx = () =>
|
|
26
|
-
this.dboBuilder.getTX((
|
|
27
|
-
(
|
|
26
|
+
this.dboBuilder.getTX((th) =>
|
|
27
|
+
(th[this.name] as Partial<typeof this> | undefined)?.[ACTION]?.(
|
|
28
28
|
filter,
|
|
29
29
|
_newData,
|
|
30
30
|
params,
|
|
@@ -33,7 +33,7 @@ export async function update(
|
|
|
33
33
|
),
|
|
34
34
|
);
|
|
35
35
|
const rule = tableRules?.[ACTION];
|
|
36
|
-
if (this.shouldWrapInTx({ name: ACTION, rule }, localParams)) {
|
|
36
|
+
if (this.shouldWrapInTx({ name: ACTION, rule }, localParams).shouldWrap) {
|
|
37
37
|
return wrapInTx();
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -60,7 +60,6 @@ export async function update(
|
|
|
60
60
|
const { fields, validateRow, forcedData, returningFields, forcedFilter, filterFields } =
|
|
61
61
|
parsedRules;
|
|
62
62
|
const { removeDisallowedFields = false } = params || {};
|
|
63
|
-
const { returnQuery = false } = localParams ?? {};
|
|
64
63
|
|
|
65
64
|
if (params) {
|
|
66
65
|
const good_paramsObj: Record<keyof UpdateParams, 1> = {
|
|
@@ -107,14 +106,14 @@ export async function update(
|
|
|
107
106
|
if (+updateCount > 1) {
|
|
108
107
|
throw "Cannot do a nestedInsert from an update that targets more than 1 row";
|
|
109
108
|
}
|
|
110
|
-
if (!
|
|
109
|
+
if (!transaction) {
|
|
111
110
|
return wrapInTx();
|
|
112
111
|
}
|
|
113
112
|
await Promise.all(
|
|
114
113
|
nestedInserts.map(async (nestedInsert) => {
|
|
115
|
-
const
|
|
116
|
-
if (!
|
|
117
|
-
throw `nestedInsert
|
|
114
|
+
const nestedTableHandler = transaction.dbTX[nestedInsert.tableName];
|
|
115
|
+
if (!nestedTableHandler)
|
|
116
|
+
throw `nestedInsert TableHandler not found for ${nestedInsert.tableName}`;
|
|
118
117
|
const refTableRules =
|
|
119
118
|
!localParams ? undefined : (
|
|
120
119
|
await getInsertTableRules(
|
|
@@ -133,7 +132,7 @@ export async function update(
|
|
|
133
132
|
referencingColumn: nestedInsert.insertedFieldName,
|
|
134
133
|
},
|
|
135
134
|
};
|
|
136
|
-
const nestedInsertResult = (await
|
|
135
|
+
const nestedInsertResult = (await nestedTableHandler.insert(
|
|
137
136
|
nestedInsert.data,
|
|
138
137
|
{ returning: "*" },
|
|
139
138
|
undefined,
|
|
@@ -170,7 +169,17 @@ export async function update(
|
|
|
170
169
|
const queryWithoutUserRLS = query;
|
|
171
170
|
query = withUserRLS(localParams, query);
|
|
172
171
|
|
|
173
|
-
|
|
172
|
+
const queryToReturn = await getReturnTypeQuery({
|
|
173
|
+
handler: this,
|
|
174
|
+
localParams,
|
|
175
|
+
queryWithoutRLS: queryWithoutUserRLS,
|
|
176
|
+
queryWithRLS: query,
|
|
177
|
+
returnType: params?.returnType,
|
|
178
|
+
newQuery: undefined,
|
|
179
|
+
});
|
|
180
|
+
if (queryToReturn) {
|
|
181
|
+
return queryToReturn;
|
|
182
|
+
}
|
|
174
183
|
|
|
175
184
|
const result = await runInsertUpdateQuery({
|
|
176
185
|
tableHandler: this,
|
|
@@ -2,12 +2,13 @@ import type { AnyObject, UpdateParams } from "prostgles-types";
|
|
|
2
2
|
import type { ParsedTableRule } from "../../PublishParser/PublishParser";
|
|
3
3
|
import type { Filter, LocalParams } from "../DboBuilder";
|
|
4
4
|
import {
|
|
5
|
-
|
|
5
|
+
rejectWithPGClientError,
|
|
6
6
|
getErrorAsObject,
|
|
7
7
|
getSerializedClientErrorFromPGError,
|
|
8
8
|
withUserRLS,
|
|
9
9
|
} from "../DboBuilder";
|
|
10
10
|
import type { TableHandler } from "./TableHandler";
|
|
11
|
+
import { getReturnTypeQuery } from "../ViewHandler/getReturnTypeQuery";
|
|
11
12
|
|
|
12
13
|
export async function updateBatch(
|
|
13
14
|
this: TableHandler,
|
|
@@ -38,6 +39,18 @@ export async function updateBatch(
|
|
|
38
39
|
);
|
|
39
40
|
const queries = [withUserRLS(localParams, ""), ...updateQueries];
|
|
40
41
|
|
|
42
|
+
const queryToReturn = await getReturnTypeQuery({
|
|
43
|
+
handler: this,
|
|
44
|
+
localParams,
|
|
45
|
+
queryWithoutRLS: queries.slice(1).join(";\n"),
|
|
46
|
+
queryWithRLS: queries.join(";\n"),
|
|
47
|
+
returnType: params?.returnType,
|
|
48
|
+
newQuery: undefined,
|
|
49
|
+
});
|
|
50
|
+
if (queryToReturn) {
|
|
51
|
+
return queryToReturn as unknown[];
|
|
52
|
+
}
|
|
53
|
+
|
|
41
54
|
const t = localParams?.tx?.t ?? this.tx?.t;
|
|
42
55
|
if (t) {
|
|
43
56
|
const result = await t.none(queries.join(";\n"));
|
|
@@ -54,7 +67,7 @@ export async function updateBatch(
|
|
|
54
67
|
return t.none(queries.join(";\n"));
|
|
55
68
|
})
|
|
56
69
|
.catch((err) =>
|
|
57
|
-
|
|
70
|
+
rejectWithPGClientError(err, {
|
|
58
71
|
type: "tableMethod",
|
|
59
72
|
localParams,
|
|
60
73
|
view: this,
|
|
@@ -298,20 +298,20 @@ export class ViewHandler {
|
|
|
298
298
|
|
|
299
299
|
intersectColumns(
|
|
300
300
|
allowedFields: FieldFilter,
|
|
301
|
-
|
|
301
|
+
disallowedFields: FieldFilter,
|
|
302
302
|
removeDisallowedFields = false,
|
|
303
303
|
): string[] {
|
|
304
304
|
let result: string[] = [];
|
|
305
305
|
if (allowedFields) {
|
|
306
306
|
result = this.parseFieldFilter(allowedFields);
|
|
307
307
|
}
|
|
308
|
-
if (
|
|
309
|
-
const
|
|
308
|
+
if (disallowedFields) {
|
|
309
|
+
const excludedFields = this.parseFieldFilter(disallowedFields);
|
|
310
310
|
|
|
311
311
|
if (!removeDisallowedFields) {
|
|
312
|
-
throw `
|
|
312
|
+
throw `disallowed/invalid field found for ${this.name}: `;
|
|
313
313
|
}
|
|
314
|
-
result = result.filter((key) => !
|
|
314
|
+
result = result.filter((key) => !excludedFields.includes(key));
|
|
315
315
|
}
|
|
316
316
|
|
|
317
317
|
return result;
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
withUserRLS,
|
|
8
8
|
} from "../dboBuilderUtils";
|
|
9
9
|
import type { ViewHandler } from "./ViewHandler";
|
|
10
|
+
import { getReturnTypeQuery } from "./getReturnTypeQuery";
|
|
10
11
|
|
|
11
12
|
export async function count(
|
|
12
13
|
this: ViewHandler,
|
|
@@ -32,15 +33,29 @@ export async function count(
|
|
|
32
33
|
returnQuery: "noRLS",
|
|
33
34
|
bypassLimit: true,
|
|
34
35
|
})) as unknown as string;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
findQuery
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
|
|
37
|
+
const queryWithoutUserRLS = `
|
|
38
|
+
SELECT COUNT(*)
|
|
39
|
+
FROM (
|
|
40
|
+
${findQuery}
|
|
41
|
+
) t
|
|
42
|
+
`;
|
|
43
|
+
const queryWithRLS = withUserRLS(localParams, queryWithoutUserRLS);
|
|
44
|
+
|
|
45
|
+
const queryToReturn = await getReturnTypeQuery({
|
|
46
|
+
handler: this,
|
|
47
|
+
localParams,
|
|
48
|
+
queryWithoutRLS: queryWithoutUserRLS,
|
|
49
|
+
queryWithRLS,
|
|
50
|
+
returnType: selectParams?.returnType,
|
|
51
|
+
newQuery: undefined,
|
|
52
|
+
});
|
|
53
|
+
if (queryToReturn) {
|
|
54
|
+
return queryToReturn as unknown[];
|
|
55
|
+
}
|
|
56
|
+
|
|
42
57
|
const handler = this.tx?.t ?? this.db;
|
|
43
|
-
return handler.one(
|
|
58
|
+
return handler.one(queryWithRLS).then(({ count }) => +count);
|
|
44
59
|
});
|
|
45
60
|
|
|
46
61
|
await this._log({
|
|
@@ -49,7 +64,7 @@ export async function count(
|
|
|
49
64
|
data: { filter },
|
|
50
65
|
duration: Date.now() - start,
|
|
51
66
|
});
|
|
52
|
-
return result;
|
|
67
|
+
return result as number;
|
|
53
68
|
} catch (e) {
|
|
54
69
|
await this._log({
|
|
55
70
|
command: "count",
|
|
@@ -1,18 +1,16 @@
|
|
|
1
|
-
import type { SelectParams } from "prostgles-types";
|
|
1
|
+
import type { AnyObject, SelectParams } from "prostgles-types";
|
|
2
2
|
import { isObject } from "prostgles-types";
|
|
3
3
|
import type { ParsedTableRule } from "../../PublishParser/PublishParser";
|
|
4
4
|
import type { Filter, LocalParams } from "../DboBuilder";
|
|
5
5
|
import {
|
|
6
|
-
getClientErrorFromPGError,
|
|
7
6
|
getErrorAsObject,
|
|
8
7
|
getSerializedClientErrorFromPGError,
|
|
8
|
+
rejectWithPGClientError,
|
|
9
9
|
withUserRLS,
|
|
10
10
|
} from "../DboBuilder";
|
|
11
11
|
import { getNewQuery } from "../QueryBuilder/getNewQuery";
|
|
12
12
|
import { getSelectQuery } from "../QueryBuilder/getSelectQuery";
|
|
13
|
-
import
|
|
14
|
-
import { canRunSQL } from "../runSql/runSQL";
|
|
15
|
-
import type { TableHandler } from "../TableHandler/TableHandler";
|
|
13
|
+
import { getReturnTypeQuery } from "./getReturnTypeQuery";
|
|
16
14
|
import type { ViewHandler } from "./ViewHandler";
|
|
17
15
|
|
|
18
16
|
export const find = async function (
|
|
@@ -111,36 +109,41 @@ export const find = async function (
|
|
|
111
109
|
);
|
|
112
110
|
|
|
113
111
|
const queryWithRLS = withUserRLS(localParams, queryWithoutRLS);
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
// await this.db.any(withUserRLS(localParams, "EXPLAIN " + queryWithRLS));
|
|
118
|
-
// return [];
|
|
119
|
-
// } catch (e) {
|
|
120
|
-
// console.error(e);
|
|
121
|
-
// throw `Internal error: publish config is not valid for publish.${this.name}.select `;
|
|
122
|
-
// }
|
|
123
|
-
// }
|
|
124
|
-
|
|
125
|
-
/** Used for subscribe */
|
|
126
|
-
if (localParams?.returnNewQuery) return newQuery as unknown as any;
|
|
127
|
-
if (localParams?.returnQuery) {
|
|
128
|
-
if (localParams.returnQuery === "where-condition") {
|
|
129
|
-
return newQuery.whereOpts.condition as any;
|
|
130
|
-
}
|
|
131
|
-
return (localParams.returnQuery === "noRLS" ?
|
|
132
|
-
queryWithoutRLS
|
|
133
|
-
: queryWithRLS) as unknown as any[];
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
const result = await runQueryReturnType({
|
|
112
|
+
const queryToReturn = await getReturnTypeQuery({
|
|
113
|
+
handler: this,
|
|
114
|
+
localParams,
|
|
137
115
|
queryWithoutRLS,
|
|
138
116
|
queryWithRLS,
|
|
139
117
|
returnType,
|
|
140
|
-
handler: this,
|
|
141
|
-
localParams,
|
|
142
118
|
newQuery,
|
|
143
119
|
});
|
|
120
|
+
if (queryToReturn) {
|
|
121
|
+
return queryToReturn as unknown[];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const query = queryWithRLS;
|
|
125
|
+
const isOneOrNone = returnType === "row" || returnType === "value";
|
|
126
|
+
const queryPromise =
|
|
127
|
+
isOneOrNone ?
|
|
128
|
+
this.db.oneOrNone<AnyObject>(query).then((data) => (data ? [data] : []))
|
|
129
|
+
: this.db.any<AnyObject>(query);
|
|
130
|
+
|
|
131
|
+
const parsedResult = await queryPromise
|
|
132
|
+
.then((rows) => {
|
|
133
|
+
if (returnType === "values" || returnType === "value") {
|
|
134
|
+
return rows.map((d) => Object.values(d)[0]);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return rows;
|
|
138
|
+
})
|
|
139
|
+
.catch((err) =>
|
|
140
|
+
rejectWithPGClientError(err, {
|
|
141
|
+
type: "tableMethod",
|
|
142
|
+
localParams,
|
|
143
|
+
view: this,
|
|
144
|
+
prostgles: this.dboBuilder.prostgles,
|
|
145
|
+
}),
|
|
146
|
+
);
|
|
144
147
|
|
|
145
148
|
await this._log({
|
|
146
149
|
command,
|
|
@@ -148,7 +151,8 @@ export const find = async function (
|
|
|
148
151
|
data: { filter, selectParams },
|
|
149
152
|
duration: Date.now() - start,
|
|
150
153
|
});
|
|
151
|
-
|
|
154
|
+
|
|
155
|
+
return isOneOrNone ? parsedResult[0] : parsedResult;
|
|
152
156
|
} catch (e) {
|
|
153
157
|
await this._log({
|
|
154
158
|
command,
|
|
@@ -165,68 +169,3 @@ export const find = async function (
|
|
|
165
169
|
});
|
|
166
170
|
}
|
|
167
171
|
};
|
|
168
|
-
|
|
169
|
-
type RunQueryReturnTypeArgs = {
|
|
170
|
-
queryWithRLS: string;
|
|
171
|
-
queryWithoutRLS: string;
|
|
172
|
-
returnType: SelectParams["returnType"];
|
|
173
|
-
handler: ViewHandler | TableHandler;
|
|
174
|
-
localParams: LocalParams | undefined;
|
|
175
|
-
newQuery: NewQuery | undefined;
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
export const runQueryReturnType = async ({
|
|
179
|
-
newQuery,
|
|
180
|
-
handler,
|
|
181
|
-
localParams,
|
|
182
|
-
queryWithRLS,
|
|
183
|
-
queryWithoutRLS,
|
|
184
|
-
returnType,
|
|
185
|
-
}: RunQueryReturnTypeArgs) => {
|
|
186
|
-
const query = queryWithRLS;
|
|
187
|
-
const sqlTypes = ["statement", "statement-no-rls", "statement-where"] as const;
|
|
188
|
-
if (!returnType || returnType === "values") {
|
|
189
|
-
return handler.dbHandler
|
|
190
|
-
.any(query)
|
|
191
|
-
.then((data) => {
|
|
192
|
-
if (returnType === "values") {
|
|
193
|
-
return data.map((d) => Object.values(d)[0]);
|
|
194
|
-
}
|
|
195
|
-
return data;
|
|
196
|
-
})
|
|
197
|
-
.catch((err) =>
|
|
198
|
-
getClientErrorFromPGError(err, {
|
|
199
|
-
type: "tableMethod",
|
|
200
|
-
localParams,
|
|
201
|
-
view: handler,
|
|
202
|
-
prostgles: handler.dboBuilder.prostgles,
|
|
203
|
-
}),
|
|
204
|
-
);
|
|
205
|
-
} else if (sqlTypes.some((v) => v === returnType)) {
|
|
206
|
-
if (!(await canRunSQL(handler.dboBuilder.prostgles, localParams?.clientReq))) {
|
|
207
|
-
throw `Not allowed: { returnType: ${JSON.stringify(returnType)} } requires execute sql privileges `;
|
|
208
|
-
}
|
|
209
|
-
if (returnType === "statement-no-rls") {
|
|
210
|
-
return queryWithoutRLS as unknown;
|
|
211
|
-
}
|
|
212
|
-
if (returnType === "statement-where") {
|
|
213
|
-
if (!newQuery) throw `returnType ${returnType} not possible for this command type`;
|
|
214
|
-
return newQuery.whereOpts.condition as unknown;
|
|
215
|
-
}
|
|
216
|
-
return query as unknown as unknown[];
|
|
217
|
-
} else if (["row", "value"].includes(returnType)) {
|
|
218
|
-
return handler.dbHandler
|
|
219
|
-
.oneOrNone(query)
|
|
220
|
-
.then((data) => {
|
|
221
|
-
return data && returnType === "value" ? Object.values(data)[0] : data;
|
|
222
|
-
})
|
|
223
|
-
.catch((err) =>
|
|
224
|
-
getClientErrorFromPGError(err, {
|
|
225
|
-
type: "tableMethod",
|
|
226
|
-
localParams,
|
|
227
|
-
view: handler,
|
|
228
|
-
prostgles: handler.dboBuilder.prostgles,
|
|
229
|
-
}),
|
|
230
|
-
);
|
|
231
|
-
}
|
|
232
|
-
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { SelectParams } from "prostgles-types";
|
|
2
|
+
import type { LocalParams } from "../DboBuilder";
|
|
3
|
+
import type { NewQuery } from "../QueryBuilder/QueryBuilder";
|
|
4
|
+
import { canRunSQL } from "../runSql/runSQL";
|
|
5
|
+
import type { TableHandler } from "../TableHandler/TableHandler";
|
|
6
|
+
import type { ViewHandler } from "./ViewHandler";
|
|
7
|
+
|
|
8
|
+
const sqlTypes = ["statement", "statement-no-rls", "statement-where"] as const;
|
|
9
|
+
|
|
10
|
+
export const getReturnTypeQuery = async ({
|
|
11
|
+
handler,
|
|
12
|
+
returnType,
|
|
13
|
+
localParams,
|
|
14
|
+
queryWithRLS,
|
|
15
|
+
queryWithoutRLS,
|
|
16
|
+
newQuery,
|
|
17
|
+
}: {
|
|
18
|
+
handler: TableHandler | ViewHandler;
|
|
19
|
+
returnType: SelectParams["returnType"];
|
|
20
|
+
localParams: LocalParams | undefined;
|
|
21
|
+
queryWithRLS: string;
|
|
22
|
+
queryWithoutRLS: string;
|
|
23
|
+
newQuery: NewQuery | undefined;
|
|
24
|
+
}) => {
|
|
25
|
+
/** Used for subscribe */
|
|
26
|
+
if (localParams?.returnNewQuery) {
|
|
27
|
+
return newQuery;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (returnType === "statement-where" || localParams?.returnQuery === "where-condition") {
|
|
31
|
+
if (!newQuery) {
|
|
32
|
+
throw `returnType ${returnType} not possible for this command type`;
|
|
33
|
+
}
|
|
34
|
+
return newQuery.whereOpts.condition as unknown;
|
|
35
|
+
}
|
|
36
|
+
if (localParams?.returnQuery) {
|
|
37
|
+
return localParams.returnQuery === "noRLS" ? queryWithoutRLS : queryWithRLS;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (!sqlTypes.some((v) => v === returnType)) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (!(await canRunSQL(handler.dboBuilder.prostgles, localParams?.clientReq))) {
|
|
44
|
+
throw `Not allowed: { returnType: ${JSON.stringify(returnType)} } requires execute sql privileges `;
|
|
45
|
+
}
|
|
46
|
+
if (returnType === "statement-no-rls") {
|
|
47
|
+
return queryWithoutRLS as unknown;
|
|
48
|
+
}
|
|
49
|
+
return queryWithRLS as unknown as unknown[];
|
|
50
|
+
};
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
withUserRLS,
|
|
8
8
|
} from "../dboBuilderUtils";
|
|
9
9
|
import type { ViewHandler } from "./ViewHandler";
|
|
10
|
+
import { getReturnTypeQuery } from "./getReturnTypeQuery";
|
|
10
11
|
export async function size(
|
|
11
12
|
this: ViewHandler,
|
|
12
13
|
_filter?: Filter,
|
|
@@ -25,7 +26,7 @@ export async function size(
|
|
|
25
26
|
table_rules,
|
|
26
27
|
localParams,
|
|
27
28
|
).then(async (_allowed) => {
|
|
28
|
-
const
|
|
29
|
+
const selectQueryWithoutRLS = (await this.find(
|
|
29
30
|
filter,
|
|
30
31
|
{
|
|
31
32
|
...selectParams,
|
|
@@ -34,18 +35,31 @@ export async function size(
|
|
|
34
35
|
undefined,
|
|
35
36
|
table_rules,
|
|
36
37
|
{ ...localParams, returnQuery: "noRLS", bypassLimit: true },
|
|
37
|
-
)) as
|
|
38
|
-
|
|
38
|
+
)) as unknown as string;
|
|
39
|
+
|
|
40
|
+
const queryWithoutUserRLS = `
|
|
41
|
+
SELECT sum(pg_column_size((prgl_size_query.*))) as size
|
|
42
|
+
FROM (
|
|
43
|
+
${selectQueryWithoutRLS}
|
|
44
|
+
) prgl_size_query
|
|
45
|
+
`;
|
|
46
|
+
const queryWithRLS = withUserRLS(localParams, queryWithoutUserRLS);
|
|
47
|
+
|
|
48
|
+
const queryToReturn = await getReturnTypeQuery({
|
|
49
|
+
handler: this,
|
|
39
50
|
localParams,
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
51
|
+
queryWithoutRLS: queryWithoutUserRLS,
|
|
52
|
+
queryWithRLS,
|
|
53
|
+
returnType: selectParams?.returnType,
|
|
54
|
+
newQuery: undefined,
|
|
55
|
+
});
|
|
56
|
+
if (queryToReturn) {
|
|
57
|
+
return queryToReturn as unknown[];
|
|
58
|
+
}
|
|
47
59
|
|
|
48
|
-
return (this.tx?.t || this.db)
|
|
60
|
+
return (this.tx?.t || this.db)
|
|
61
|
+
.one<{ size: string | null }>(queryWithRLS)
|
|
62
|
+
.then(({ size }) => size || "0");
|
|
49
63
|
});
|
|
50
64
|
await this._log({
|
|
51
65
|
command: "size",
|
|
@@ -53,7 +67,7 @@ export async function size(
|
|
|
53
67
|
data: { filter, selectParams },
|
|
54
68
|
duration: Date.now() - start,
|
|
55
69
|
});
|
|
56
|
-
return result;
|
|
70
|
+
return result as string;
|
|
57
71
|
} catch (e) {
|
|
58
72
|
await this._log({
|
|
59
73
|
command: "size",
|