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.
Files changed (88) hide show
  1. package/dist/DboBuilder/TableHandler/TableHandler.d.ts +18 -5
  2. package/dist/DboBuilder/TableHandler/TableHandler.d.ts.map +1 -1
  3. package/dist/DboBuilder/TableHandler/TableHandler.js +12 -6
  4. package/dist/DboBuilder/TableHandler/TableHandler.js.map +1 -1
  5. package/dist/DboBuilder/TableHandler/delete.d.ts +1 -1
  6. package/dist/DboBuilder/TableHandler/delete.d.ts.map +1 -1
  7. package/dist/DboBuilder/TableHandler/delete.js +56 -13
  8. package/dist/DboBuilder/TableHandler/delete.js.map +1 -1
  9. package/dist/DboBuilder/TableHandler/executeHooksCheckAndPostValidation.d.ts +21 -0
  10. package/dist/DboBuilder/TableHandler/executeHooksCheckAndPostValidation.d.ts.map +1 -0
  11. package/dist/DboBuilder/TableHandler/executeHooksCheckAndPostValidation.js +69 -0
  12. package/dist/DboBuilder/TableHandler/executeHooksCheckAndPostValidation.js.map +1 -0
  13. package/dist/DboBuilder/TableHandler/insert/insert.d.ts.map +1 -1
  14. package/dist/DboBuilder/TableHandler/insert/insert.js +21 -11
  15. package/dist/DboBuilder/TableHandler/insert/insert.js.map +1 -1
  16. package/dist/DboBuilder/TableHandler/insert/insertNestedRecords.d.ts.map +1 -1
  17. package/dist/DboBuilder/TableHandler/insert/insertNestedRecords.js +1 -2
  18. package/dist/DboBuilder/TableHandler/insert/insertNestedRecords.js.map +1 -1
  19. package/dist/DboBuilder/TableHandler/onDeleteFromFileTable.d.ts.map +1 -1
  20. package/dist/DboBuilder/TableHandler/onDeleteFromFileTable.js +2 -1
  21. package/dist/DboBuilder/TableHandler/onDeleteFromFileTable.js.map +1 -1
  22. package/dist/DboBuilder/TableHandler/runInsertUpdateQuery.d.ts.map +1 -1
  23. package/dist/DboBuilder/TableHandler/runInsertUpdateQuery.js +24 -95
  24. package/dist/DboBuilder/TableHandler/runInsertUpdateQuery.js.map +1 -1
  25. package/dist/DboBuilder/TableHandler/update.d.ts.map +1 -1
  26. package/dist/DboBuilder/TableHandler/update.js +20 -12
  27. package/dist/DboBuilder/TableHandler/update.js.map +1 -1
  28. package/dist/DboBuilder/TableHandler/updateBatch.d.ts.map +1 -1
  29. package/dist/DboBuilder/TableHandler/updateBatch.js +13 -1
  30. package/dist/DboBuilder/TableHandler/updateBatch.js.map +1 -1
  31. package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts +1 -1
  32. package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts.map +1 -1
  33. package/dist/DboBuilder/ViewHandler/ViewHandler.js +5 -5
  34. package/dist/DboBuilder/ViewHandler/ViewHandler.js.map +1 -1
  35. package/dist/DboBuilder/ViewHandler/count.d.ts.map +1 -1
  36. package/dist/DboBuilder/ViewHandler/count.js +20 -8
  37. package/dist/DboBuilder/ViewHandler/count.js.map +1 -1
  38. package/dist/DboBuilder/ViewHandler/find.d.ts +0 -12
  39. package/dist/DboBuilder/ViewHandler/find.d.ts.map +1 -1
  40. package/dist/DboBuilder/ViewHandler/find.js +27 -75
  41. package/dist/DboBuilder/ViewHandler/find.js.map +1 -1
  42. package/dist/DboBuilder/ViewHandler/getReturnTypeQuery.d.ts +14 -0
  43. package/dist/DboBuilder/ViewHandler/getReturnTypeQuery.d.ts.map +1 -0
  44. package/dist/DboBuilder/ViewHandler/getReturnTypeQuery.js +32 -0
  45. package/dist/DboBuilder/ViewHandler/getReturnTypeQuery.js.map +1 -0
  46. package/dist/DboBuilder/ViewHandler/size.d.ts.map +1 -1
  47. package/dist/DboBuilder/ViewHandler/size.js +23 -8
  48. package/dist/DboBuilder/ViewHandler/size.js.map +1 -1
  49. package/dist/DboBuilder/dboBuilderUtils.d.ts +1 -1
  50. package/dist/DboBuilder/dboBuilderUtils.d.ts.map +1 -1
  51. package/dist/DboBuilder/dboBuilderUtils.js +2 -2
  52. package/dist/DboBuilder/dboBuilderUtils.js.map +1 -1
  53. package/dist/DboBuilder/parseUpdateRules.js +1 -1
  54. package/dist/DboBuilder/parseUpdateRules.js.map +1 -1
  55. package/dist/PublishParser/publishTypesAndUtils.d.ts +34 -1
  56. package/dist/PublishParser/publishTypesAndUtils.d.ts.map +1 -1
  57. package/dist/PublishParser/publishTypesAndUtils.js.map +1 -1
  58. package/dist/TableConfig/TableConfig.d.ts +3 -15
  59. package/dist/TableConfig/TableConfig.d.ts.map +1 -1
  60. package/dist/TableConfig/TableConfig.js.map +1 -1
  61. package/dist/TableConfig/getCreateSchemaQueries.d.ts +4 -28
  62. package/dist/TableConfig/getCreateSchemaQueries.d.ts.map +1 -1
  63. package/dist/TableConfig/getTableConfigSchemaQueries.d.ts +4 -28
  64. package/dist/TableConfig/getTableConfigSchemaQueries.d.ts.map +1 -1
  65. package/dist/utils/utils.d.ts +1 -0
  66. package/dist/utils/utils.d.ts.map +1 -1
  67. package/dist/utils/utils.js +3 -1
  68. package/dist/utils/utils.js.map +1 -1
  69. package/lib/DboBuilder/TableHandler/TableHandler.ts +21 -6
  70. package/lib/DboBuilder/TableHandler/delete.ts +83 -15
  71. package/lib/DboBuilder/TableHandler/executeHooksCheckAndPostValidation.ts +88 -0
  72. package/lib/DboBuilder/TableHandler/insert/insert.ts +25 -11
  73. package/lib/DboBuilder/TableHandler/insert/insertNestedRecords.ts +1 -2
  74. package/lib/DboBuilder/TableHandler/onDeleteFromFileTable.ts +7 -5
  75. package/lib/DboBuilder/TableHandler/runInsertUpdateQuery.ts +34 -110
  76. package/lib/DboBuilder/TableHandler/update.ts +21 -12
  77. package/lib/DboBuilder/TableHandler/updateBatch.ts +15 -2
  78. package/lib/DboBuilder/ViewHandler/ViewHandler.ts +5 -5
  79. package/lib/DboBuilder/ViewHandler/count.ts +24 -9
  80. package/lib/DboBuilder/ViewHandler/find.ts +35 -96
  81. package/lib/DboBuilder/ViewHandler/getReturnTypeQuery.ts +50 -0
  82. package/lib/DboBuilder/ViewHandler/size.ts +26 -12
  83. package/lib/DboBuilder/dboBuilderUtils.ts +1 -1
  84. package/lib/DboBuilder/parseUpdateRules.ts +1 -1
  85. package/lib/PublishParser/publishTypesAndUtils.ts +42 -1
  86. package/lib/TableConfig/TableConfig.ts +4 -18
  87. package/lib/utils/utils.ts +2 -0
  88. 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 { getClientErrorFromPGError, withUserRLS } from "../DboBuilder";
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 = localParams?.tx?.t || tableHandler.tx?.t;
113
- if (tx) {
114
- result = await tx[queryType](query).catch((err: unknown) =>
115
- getClientErrorFromPGError(err, {
116
- type: "tableMethod",
117
- localParams,
118
- view: tableHandler,
119
- allowedKeys: allowedFieldKeys,
120
- prostgles: tableHandler.dboBuilder.prostgles,
121
- }),
122
- );
123
- } else {
124
- result = await tableHandler.db
125
- .tx((t) => (t as any)[queryType](query))
126
- .catch((err) =>
127
- getClientErrorFromPGError(err, {
128
- type: "tableMethod",
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?.length) {
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
- for (const hook of applicableHooks) {
198
- if (hook.type === "afterAll") {
199
- await hook.validate({
200
- tx: tx || tableHandler.db,
201
- dbx: finalDBtx,
202
- command,
203
- data: Array.isArray(data) ? data : [data],
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
- /** postValidate */
24
- const finalDBtx = this.getFinalDBtx(localParams);
24
+ const transaction = this.getTransaction(localParams);
25
25
  const wrapInTx = () =>
26
- this.dboBuilder.getTX((_dbtx) =>
27
- (_dbtx[this.name] as Partial<typeof this> | undefined)?.[ACTION]?.(
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 (!finalDBtx) {
109
+ if (!transaction) {
111
110
  return wrapInTx();
112
111
  }
113
112
  await Promise.all(
114
113
  nestedInserts.map(async (nestedInsert) => {
115
- const nesedTableHandler = finalDBtx[nestedInsert.tableName];
116
- if (!nesedTableHandler)
117
- throw `nestedInsert Tablehandler not found for ${nestedInsert.tableName}`;
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 nesedTableHandler.insert(
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
- if (returnQuery) return query as unknown as void;
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
- getClientErrorFromPGError,
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
- getClientErrorFromPGError(err, {
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
- dissallowedFields: FieldFilter,
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 (dissallowedFields) {
309
- const _dissalowed = this.parseFieldFilter(dissallowedFields);
308
+ if (disallowedFields) {
309
+ const excludedFields = this.parseFieldFilter(disallowedFields);
310
310
 
311
311
  if (!removeDisallowedFields) {
312
- throw `dissallowed/invalid field found for ${this.name}: `;
312
+ throw `disallowed/invalid field found for ${this.name}: `;
313
313
  }
314
- result = result.filter((key) => !_dissalowed.includes(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
- const query = [
36
- withUserRLS(localParams, ""),
37
- "SELECT COUNT(*)",
38
- "FROM (",
39
- findQuery,
40
- ") t",
41
- ].join("\n");
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(query).then(({ count }) => +count);
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 type { NewQuery } from "../QueryBuilder/QueryBuilder";
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
- // THIS HANGS TESTS
115
- // if (testRule) {
116
- // try {
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
- return result;
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 q: string = (await this.find(
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 any;
38
- const query = withUserRLS(
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
- `${withUserRLS(localParams, "")}
41
- SELECT sum(pg_column_size((prgl_size_query.*))) as size
42
- FROM (
43
- ${q}
44
- ) prgl_size_query
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).one(query).then(({ size }) => size || "0");
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",
@@ -96,7 +96,7 @@ export function getSerializedClientErrorFromPGError(
96
96
  }
97
97
  return errObject;
98
98
  }
99
- export function getClientErrorFromPGError(
99
+ export function rejectWithPGClientError(
100
100
  rawError: any,
101
101
  args: GetSerializedClientErrorFromPGErrorArgs,
102
102
  ) {