prostgles-server 4.2.549 → 4.2.551

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 (91) hide show
  1. package/dist/DboBuilder/TableHandler/TableHandler.d.ts +14 -6
  2. package/dist/DboBuilder/TableHandler/TableHandler.d.ts.map +1 -1
  3. package/dist/DboBuilder/TableHandler/TableHandler.js +9 -9
  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 +30 -17
  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 +21 -13
  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/TableHandler/upsert.js +2 -2
  32. package/dist/DboBuilder/TableHandler/upsert.js.map +1 -1
  33. package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts +6 -1
  34. package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts.map +1 -1
  35. package/dist/DboBuilder/ViewHandler/ViewHandler.js +11 -5
  36. package/dist/DboBuilder/ViewHandler/ViewHandler.js.map +1 -1
  37. package/dist/DboBuilder/ViewHandler/count.d.ts.map +1 -1
  38. package/dist/DboBuilder/ViewHandler/count.js +20 -8
  39. package/dist/DboBuilder/ViewHandler/count.js.map +1 -1
  40. package/dist/DboBuilder/ViewHandler/find.d.ts +0 -12
  41. package/dist/DboBuilder/ViewHandler/find.d.ts.map +1 -1
  42. package/dist/DboBuilder/ViewHandler/find.js +28 -75
  43. package/dist/DboBuilder/ViewHandler/find.js.map +1 -1
  44. package/dist/DboBuilder/ViewHandler/getReturnTypeQuery.d.ts +14 -0
  45. package/dist/DboBuilder/ViewHandler/getReturnTypeQuery.d.ts.map +1 -0
  46. package/dist/DboBuilder/ViewHandler/getReturnTypeQuery.js +32 -0
  47. package/dist/DboBuilder/ViewHandler/getReturnTypeQuery.js.map +1 -0
  48. package/dist/DboBuilder/ViewHandler/size.d.ts.map +1 -1
  49. package/dist/DboBuilder/ViewHandler/size.js +23 -8
  50. package/dist/DboBuilder/ViewHandler/size.js.map +1 -1
  51. package/dist/DboBuilder/dboBuilderUtils.d.ts +1 -1
  52. package/dist/DboBuilder/dboBuilderUtils.d.ts.map +1 -1
  53. package/dist/DboBuilder/dboBuilderUtils.js +2 -2
  54. package/dist/DboBuilder/dboBuilderUtils.js.map +1 -1
  55. package/dist/DboBuilder/parseUpdateRules.js +1 -1
  56. package/dist/DboBuilder/parseUpdateRules.js.map +1 -1
  57. package/dist/PublishParser/publishTypesAndUtils.d.ts +34 -1
  58. package/dist/PublishParser/publishTypesAndUtils.d.ts.map +1 -1
  59. package/dist/PublishParser/publishTypesAndUtils.js.map +1 -1
  60. package/dist/TableConfig/TableConfig.d.ts +3 -15
  61. package/dist/TableConfig/TableConfig.d.ts.map +1 -1
  62. package/dist/TableConfig/TableConfig.js.map +1 -1
  63. package/dist/TableConfig/getCreateSchemaQueries.d.ts +4 -28
  64. package/dist/TableConfig/getCreateSchemaQueries.d.ts.map +1 -1
  65. package/dist/TableConfig/getTableConfigSchemaQueries.d.ts +4 -28
  66. package/dist/TableConfig/getTableConfigSchemaQueries.d.ts.map +1 -1
  67. package/dist/utils/utils.d.ts +1 -0
  68. package/dist/utils/utils.d.ts.map +1 -1
  69. package/dist/utils/utils.js +3 -1
  70. package/dist/utils/utils.js.map +1 -1
  71. package/lib/DboBuilder/TableHandler/TableHandler.ts +17 -10
  72. package/lib/DboBuilder/TableHandler/delete.ts +83 -15
  73. package/lib/DboBuilder/TableHandler/executeHooksCheckAndPostValidation.ts +88 -0
  74. package/lib/DboBuilder/TableHandler/insert/insert.ts +36 -17
  75. package/lib/DboBuilder/TableHandler/insert/insertNestedRecords.ts +1 -2
  76. package/lib/DboBuilder/TableHandler/onDeleteFromFileTable.ts +7 -5
  77. package/lib/DboBuilder/TableHandler/runInsertUpdateQuery.ts +34 -110
  78. package/lib/DboBuilder/TableHandler/update.ts +28 -13
  79. package/lib/DboBuilder/TableHandler/updateBatch.ts +15 -2
  80. package/lib/DboBuilder/TableHandler/upsert.ts +2 -2
  81. package/lib/DboBuilder/ViewHandler/ViewHandler.ts +13 -5
  82. package/lib/DboBuilder/ViewHandler/count.ts +24 -9
  83. package/lib/DboBuilder/ViewHandler/find.ts +36 -96
  84. package/lib/DboBuilder/ViewHandler/getReturnTypeQuery.ts +50 -0
  85. package/lib/DboBuilder/ViewHandler/size.ts +26 -12
  86. package/lib/DboBuilder/dboBuilderUtils.ts +1 -1
  87. package/lib/DboBuilder/parseUpdateRules.ts +1 -1
  88. package/lib/PublishParser/publishTypesAndUtils.ts +42 -1
  89. package/lib/TableConfig/TableConfig.ts +4 -18
  90. package/lib/utils/utils.ts +2 -0
  91. 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> = {
@@ -103,18 +102,24 @@ export async function update(
103
102
  const nestedInserts = getReferenceColumnInserts(this, nData, true);
104
103
  const nestedInsertsResultsObj: Record<string, any> = {};
105
104
  if (nestedInserts.length) {
106
- const updateCount = await this.count(updateFilter.filter);
105
+ const updateCount = await this.count(
106
+ updateFilter.filter,
107
+ undefined,
108
+ undefined,
109
+ tableRules,
110
+ localParams,
111
+ );
107
112
  if (+updateCount > 1) {
108
113
  throw "Cannot do a nestedInsert from an update that targets more than 1 row";
109
114
  }
110
- if (!finalDBtx) {
115
+ if (!transaction) {
111
116
  return wrapInTx();
112
117
  }
113
118
  await Promise.all(
114
119
  nestedInserts.map(async (nestedInsert) => {
115
- const nesedTableHandler = finalDBtx[nestedInsert.tableName];
116
- if (!nesedTableHandler)
117
- throw `nestedInsert Tablehandler not found for ${nestedInsert.tableName}`;
120
+ const nestedTableHandler = transaction.dbTX[nestedInsert.tableName];
121
+ if (!nestedTableHandler)
122
+ throw `nestedInsert TableHandler not found for ${nestedInsert.tableName}`;
118
123
  const refTableRules =
119
124
  !localParams ? undefined : (
120
125
  await getInsertTableRules(
@@ -133,7 +138,7 @@ export async function update(
133
138
  referencingColumn: nestedInsert.insertedFieldName,
134
139
  },
135
140
  };
136
- const nestedInsertResult = (await nesedTableHandler.insert(
141
+ const nestedInsertResult = (await nestedTableHandler.insert(
137
142
  nestedInsert.data,
138
143
  { returning: "*" },
139
144
  undefined,
@@ -170,7 +175,17 @@ export async function update(
170
175
  const queryWithoutUserRLS = query;
171
176
  query = withUserRLS(localParams, query);
172
177
 
173
- if (returnQuery) return query as unknown as void;
178
+ const queryToReturn = await getReturnTypeQuery({
179
+ handler: this,
180
+ localParams,
181
+ queryWithoutRLS: queryWithoutUserRLS,
182
+ queryWithRLS: query,
183
+ returnType: params?.returnType,
184
+ newQuery: undefined,
185
+ });
186
+ if (queryToReturn) {
187
+ return queryToReturn;
188
+ }
174
189
 
175
190
  const result = await runInsertUpdateQuery({
176
191
  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,
@@ -32,8 +32,8 @@ export const upsert = async function (
32
32
  });
33
33
  };
34
34
 
35
- /* Do it within a transaction to ensure consisency */
36
- if (!this.tx) {
35
+ /* Do it within a transaction to ensure consistency */
36
+ if (!this.getTransaction(localParams)) {
37
37
  return this.dboBuilder.getTX((dbTX) => _upsert(dbTX[this.name] as TableHandler));
38
38
  }
39
39
  const result = await _upsert(this);
@@ -104,6 +104,14 @@ export class ViewHandler {
104
104
  });
105
105
  }
106
106
 
107
+ getFinalDBtx = (localParams: LocalParams | undefined) => {
108
+ return localParams?.tx?.dbTX ?? this.tx?.dbTX;
109
+ };
110
+
111
+ getTransaction = (localParams: LocalParams | undefined) => {
112
+ return localParams?.tx || this.tx;
113
+ };
114
+
107
115
  _log = ({
108
116
  command,
109
117
  data,
@@ -298,20 +306,20 @@ export class ViewHandler {
298
306
 
299
307
  intersectColumns(
300
308
  allowedFields: FieldFilter,
301
- dissallowedFields: FieldFilter,
309
+ disallowedFields: FieldFilter,
302
310
  removeDisallowedFields = false,
303
311
  ): string[] {
304
312
  let result: string[] = [];
305
313
  if (allowedFields) {
306
314
  result = this.parseFieldFilter(allowedFields);
307
315
  }
308
- if (dissallowedFields) {
309
- const _dissalowed = this.parseFieldFilter(dissallowedFields);
316
+ if (disallowedFields) {
317
+ const excludedFields = this.parseFieldFilter(disallowedFields);
310
318
 
311
319
  if (!removeDisallowedFields) {
312
- throw `dissallowed/invalid field found for ${this.name}: `;
320
+ throw `disallowed/invalid field found for ${this.name}: `;
313
321
  }
314
- result = result.filter((key) => !_dissalowed.includes(key));
322
+ result = result.filter((key) => !excludedFields.includes(key));
315
323
  }
316
324
 
317
325
  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,42 @@ 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 dbHandler = this.getTransaction(localParams)?.t ?? this.db;
127
+ const queryPromise =
128
+ isOneOrNone ?
129
+ dbHandler.oneOrNone<AnyObject>(query).then((data) => (data ? [data] : []))
130
+ : dbHandler.any<AnyObject>(query);
131
+
132
+ const parsedResult = await queryPromise
133
+ .then((rows) => {
134
+ if (returnType === "values" || returnType === "value") {
135
+ return rows.map((d) => Object.values(d)[0]);
136
+ }
137
+
138
+ return rows;
139
+ })
140
+ .catch((err) =>
141
+ rejectWithPGClientError(err, {
142
+ type: "tableMethod",
143
+ localParams,
144
+ view: this,
145
+ prostgles: this.dboBuilder.prostgles,
146
+ }),
147
+ );
144
148
 
145
149
  await this._log({
146
150
  command,
@@ -148,7 +152,8 @@ export const find = async function (
148
152
  data: { filter, selectParams },
149
153
  duration: Date.now() - start,
150
154
  });
151
- return result;
155
+
156
+ return isOneOrNone ? parsedResult[0] : parsedResult;
152
157
  } catch (e) {
153
158
  await this._log({
154
159
  command,
@@ -165,68 +170,3 @@ export const find = async function (
165
170
  });
166
171
  }
167
172
  };
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
+ };