prostgles-server 4.2.448 → 4.2.450
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/DboBuilderTypes.d.ts +11 -7
- package/dist/DboBuilder/DboBuilderTypes.d.ts.map +1 -1
- package/dist/DboBuilder/DboBuilderTypes.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/Functions/COMPUTED_FIELDS.js +1 -1
- package/dist/DboBuilder/QueryBuilder/Functions/COMPUTED_FIELDS.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/Functions/Functions.d.ts +1 -1
- package/dist/DboBuilder/QueryBuilder/Functions/Functions.d.ts.map +1 -1
- package/dist/DboBuilder/QueryBuilder/Functions/Functions.js +31 -31
- package/dist/DboBuilder/QueryBuilder/Functions/Functions.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/QueryBuilder.d.ts +5 -5
- package/dist/DboBuilder/QueryBuilder/QueryBuilder.d.ts.map +1 -1
- package/dist/DboBuilder/QueryBuilder/QueryBuilder.js +1 -1
- package/dist/DboBuilder/QueryBuilder/QueryBuilder.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/getJoinQuery.d.ts +2 -1
- package/dist/DboBuilder/QueryBuilder/getJoinQuery.d.ts.map +1 -1
- package/dist/DboBuilder/QueryBuilder/getJoinQuery.js +12 -10
- package/dist/DboBuilder/QueryBuilder/getJoinQuery.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/getNewQuery.d.ts +2 -2
- package/dist/DboBuilder/QueryBuilder/getNewQuery.d.ts.map +1 -1
- package/dist/DboBuilder/QueryBuilder/getNewQuery.js +2 -2
- package/dist/DboBuilder/QueryBuilder/getNewQuery.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/getSelectQuery.d.ts.map +1 -1
- package/dist/DboBuilder/QueryBuilder/getSelectQuery.js +6 -12
- package/dist/DboBuilder/QueryBuilder/getSelectQuery.js.map +1 -1
- package/dist/DboBuilder/TableRules/getValidatedRules.d.ts.map +1 -1
- package/dist/DboBuilder/TableRules/getValidatedRules.js +33 -35
- package/dist/DboBuilder/TableRules/getValidatedRules.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/parseComplexFilter.d.ts +2 -2
- package/dist/DboBuilder/ViewHandler/parseComplexFilter.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/parseComplexFilter.js +3 -3
- package/dist/DboBuilder/ViewHandler/parseComplexFilter.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/prepareSortItems.d.ts +2 -2
- package/dist/DboBuilder/ViewHandler/prepareSortItems.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/prepareSortItems.js +6 -4
- package/dist/DboBuilder/ViewHandler/prepareSortItems.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/prepareWhere.d.ts +2 -2
- package/dist/DboBuilder/ViewHandler/prepareWhere.d.ts.map +1 -1
- package/dist/DboBuilder/getCondition.d.ts +2 -2
- package/dist/DboBuilder/getCondition.d.ts.map +1 -1
- package/dist/DboBuilder/getCondition.js +6 -6
- package/dist/DboBuilder/getCondition.js.map +1 -1
- package/dist/DboBuilder/getSubscribeRelatedTables.js +1 -1
- package/dist/DboBuilder/getSubscribeRelatedTables.js.map +1 -1
- package/dist/Filtering.d.ts +1 -1
- package/dist/Filtering.d.ts.map +1 -1
- package/dist/Filtering.js +3 -3
- package/dist/Filtering.js.map +1 -1
- package/dist/PublishParser/PublishParser.d.ts +1 -0
- package/dist/PublishParser/PublishParser.d.ts.map +1 -1
- package/dist/PublishParser/PublishParser.js +52 -2
- package/dist/PublishParser/PublishParser.js.map +1 -1
- package/dist/PublishParser/getSchemaFromPublish.js +1 -1
- package/dist/PublishParser/getSchemaFromPublish.js.map +1 -1
- package/dist/PublishParser/getTableRulesWithoutFileTable.js +1 -1
- package/dist/PublishParser/getTableRulesWithoutFileTable.js.map +1 -1
- package/dist/PublishParser/publishTypesAndUtils.d.ts +14 -1
- package/dist/PublishParser/publishTypesAndUtils.d.ts.map +1 -1
- package/eslint.config.mjs +2 -2
- package/lib/DboBuilder/DboBuilderTypes.ts +12 -7
- package/lib/DboBuilder/QueryBuilder/Functions/COMPUTED_FIELDS.ts +1 -1
- package/lib/DboBuilder/QueryBuilder/Functions/Functions.ts +66 -62
- package/lib/DboBuilder/QueryBuilder/QueryBuilder.ts +6 -6
- package/lib/DboBuilder/QueryBuilder/getJoinQuery.ts +16 -12
- package/lib/DboBuilder/QueryBuilder/getNewQuery.ts +5 -5
- package/lib/DboBuilder/QueryBuilder/getSelectQuery.ts +11 -17
- package/lib/DboBuilder/TableRules/getValidatedRules.ts +39 -40
- package/lib/DboBuilder/ViewHandler/parseComplexFilter.ts +4 -4
- package/lib/DboBuilder/ViewHandler/prepareSortItems.ts +14 -12
- package/lib/DboBuilder/ViewHandler/prepareWhere.ts +6 -6
- package/lib/DboBuilder/getCondition.ts +8 -12
- package/lib/DboBuilder/getSubscribeRelatedTables.ts +1 -1
- package/lib/Filtering.ts +11 -13
- package/lib/PublishParser/PublishParser.ts +62 -5
- package/lib/PublishParser/getSchemaFromPublish.ts +1 -1
- package/lib/PublishParser/getTableRulesWithoutFileTable.ts +2 -2
- package/lib/PublishParser/publishTypesAndUtils.ts +23 -1
- package/package.json +18 -18
|
@@ -6,7 +6,7 @@ import { type SelectItemValidated } from "./QueryBuilder";
|
|
|
6
6
|
import { ROOT_TABLE_ALIAS, ROOT_TABLE_ROW_NUM_ID, indentLines } from "./getSelectQuery";
|
|
7
7
|
import type { ViewHandler } from "../ViewHandler/ViewHandler";
|
|
8
8
|
import { getJoinOnCondition } from "../ViewHandler/getTableJoinQuery";
|
|
9
|
-
import { prepareOrderByQuery } from "../DboBuilder";
|
|
9
|
+
import { prepareOrderByQuery, type PGIdentifier } from "../DboBuilder";
|
|
10
10
|
import { asNameAlias } from "../../utils/asNameAlias";
|
|
11
11
|
|
|
12
12
|
type Args = {
|
|
@@ -47,7 +47,7 @@ const getJoinTable = (
|
|
|
47
47
|
};
|
|
48
48
|
|
|
49
49
|
type GetJoinQueryResult = {
|
|
50
|
-
resultAlias:
|
|
50
|
+
resultAlias: PGIdentifier;
|
|
51
51
|
firstJoinTableJoinFields: string[];
|
|
52
52
|
isOrJoin: boolean;
|
|
53
53
|
type: "cte";
|
|
@@ -68,7 +68,7 @@ type GetJoinQueryResult = {
|
|
|
68
68
|
*/
|
|
69
69
|
export const getJoinQuery = (viewHandler: ViewHandler, { q1, q2 }: Args): GetJoinQueryResult => {
|
|
70
70
|
const paths = parseJoinPath({
|
|
71
|
-
rootTable: q1.table,
|
|
71
|
+
rootTable: q1.table.raw,
|
|
72
72
|
rawPath: q2.joinPath,
|
|
73
73
|
viewHandler: viewHandler,
|
|
74
74
|
allowMultiOrJoin: true,
|
|
@@ -78,7 +78,7 @@ export const getJoinQuery = (viewHandler: ViewHandler, { q1, q2 }: Args): GetJoi
|
|
|
78
78
|
if (q2.joins?.length) {
|
|
79
79
|
throw new Error("Nested joins not supported yet");
|
|
80
80
|
}
|
|
81
|
-
const targetTableAliasRaw = q2.tableAlias || q2.table;
|
|
81
|
+
const targetTableAliasRaw = q2.tableAlias?.raw || q2.table.raw;
|
|
82
82
|
const targetTableAlias = asName(targetTableAliasRaw);
|
|
83
83
|
|
|
84
84
|
const firstJoinTablePath = paths[0]!;
|
|
@@ -101,7 +101,7 @@ export const getJoinQuery = (viewHandler: ViewHandler, { q1, q2 }: Args): GetJoi
|
|
|
101
101
|
|
|
102
102
|
const joinCondition = getJoinOnCondition({
|
|
103
103
|
on: firstJoinTablePath.on,
|
|
104
|
-
leftAlias:
|
|
104
|
+
leftAlias: q1.tableAlias?.escaped || q1.table.escaped,
|
|
105
105
|
rightAlias: targetTableAlias,
|
|
106
106
|
getRightColName: (col) => getJoinCol(col).alias,
|
|
107
107
|
});
|
|
@@ -110,7 +110,9 @@ export const getJoinQuery = (viewHandler: ViewHandler, { q1, q2 }: Args): GetJoi
|
|
|
110
110
|
const selectedFields = rootSelectItems
|
|
111
111
|
.filter((s) => s.selected)
|
|
112
112
|
.map((s) => asNameAlias(s.alias, targetTableAliasRaw));
|
|
113
|
-
const rootNestedSort = q1.orderByItems.filter(
|
|
113
|
+
const rootNestedSort = q1.orderByItems.filter(
|
|
114
|
+
(d) => d.nested?.joinAlias.raw === q2.joinAlias.raw,
|
|
115
|
+
);
|
|
114
116
|
const jsonAgg = `json_agg((SELECT x FROM (SELECT ${selectedFields.join(", ")}) as x )${jsonAggSort}) ${jsonAggLimit} as ${JSON_AGG_FIELD_NAME}`;
|
|
115
117
|
|
|
116
118
|
const { innerQuery } = getInnerJoinQuery({
|
|
@@ -151,7 +153,7 @@ export const getJoinQuery = (viewHandler: ViewHandler, { q1, q2 }: Args): GetJoi
|
|
|
151
153
|
];
|
|
152
154
|
return {
|
|
153
155
|
type: "cte",
|
|
154
|
-
resultAlias: JSON_AGG_FIELD_NAME,
|
|
156
|
+
resultAlias: { raw: JSON_AGG_FIELD_NAME, escaped: JSON_AGG_FIELD_NAME },
|
|
155
157
|
joinLines,
|
|
156
158
|
cteLines: [],
|
|
157
159
|
isOrJoin,
|
|
@@ -171,7 +173,9 @@ export const getJoinQuery = (viewHandler: ViewHandler, { q1, q2 }: Args): GetJoi
|
|
|
171
173
|
`FROM (`,
|
|
172
174
|
...indentLines(innerQuery),
|
|
173
175
|
`) ${targetTableAlias}`,
|
|
174
|
-
...(isOrJoin ?
|
|
176
|
+
...(isOrJoin ?
|
|
177
|
+
[`LEFT JOIN ${q1.table.escaped} ${ROOT_TABLE_ALIAS}`, `ON ${joinCondition}`]
|
|
178
|
+
: []),
|
|
175
179
|
`GROUP BY ${isOrJoin ? rootTableIdField : requiredJoinFields.join(", ")}`,
|
|
176
180
|
];
|
|
177
181
|
|
|
@@ -190,7 +194,7 @@ export const getJoinQuery = (viewHandler: ViewHandler, { q1, q2 }: Args): GetJoi
|
|
|
190
194
|
|
|
191
195
|
return {
|
|
192
196
|
type: "cte",
|
|
193
|
-
resultAlias: JSON_AGG_FIELD_NAME,
|
|
197
|
+
resultAlias: { raw: JSON_AGG_FIELD_NAME, escaped: JSON_AGG_FIELD_NAME },
|
|
194
198
|
joinLines,
|
|
195
199
|
cteLines,
|
|
196
200
|
isOrJoin,
|
|
@@ -218,8 +222,8 @@ const getInnerJoinQuery = ({
|
|
|
218
222
|
const prevTable = getJoinTable(
|
|
219
223
|
!i ?
|
|
220
224
|
q1.tableAlias ?
|
|
221
|
-
|
|
222
|
-
: q1.table
|
|
225
|
+
q1.tableAlias.escaped
|
|
226
|
+
: q1.table.escaped
|
|
223
227
|
: paths[i - 1]!.table,
|
|
224
228
|
i - 1,
|
|
225
229
|
undefined,
|
|
@@ -302,7 +306,7 @@ const getNestedSelectFields = ({
|
|
|
302
306
|
.map((s) => ({
|
|
303
307
|
...s,
|
|
304
308
|
isJoinCol: false,
|
|
305
|
-
query: s.getQuery(targetTableAlias) + " AS " + asName(s.alias),
|
|
309
|
+
query: s.getQuery(targetTableAlias.raw) + " AS " + asName(s.alias),
|
|
306
310
|
}))
|
|
307
311
|
.concat(
|
|
308
312
|
requiredJoinFields.map((f) => ({
|
|
@@ -6,9 +6,9 @@ import type {
|
|
|
6
6
|
SelectParams,
|
|
7
7
|
SimpleJoinSelect,
|
|
8
8
|
} from "prostgles-types";
|
|
9
|
-
import { getKeys, includes, isEmpty, omitKeys } from "prostgles-types";
|
|
9
|
+
import { asName, getKeys, includes, isEmpty, omitKeys } from "prostgles-types";
|
|
10
10
|
import type { ParsedTableRule } from "../../PublishParser/PublishParser";
|
|
11
|
-
import type { Filter, LocalParams, ValidatedTableRules } from "../DboBuilder";
|
|
11
|
+
import type { Filter, LocalParams, PGIdentifier, ValidatedTableRules } from "../DboBuilder";
|
|
12
12
|
import type { ViewHandler } from "../ViewHandler/ViewHandler";
|
|
13
13
|
import { parseJoinPath } from "../ViewHandler/parseJoinPath";
|
|
14
14
|
import { prepareSortItems } from "../ViewHandler/prepareSortItems";
|
|
@@ -91,7 +91,7 @@ const parseJoinSelect = (joinParams: JoinSelect): ParsedJoin => {
|
|
|
91
91
|
export async function getNewQuery(
|
|
92
92
|
_this: ViewHandler,
|
|
93
93
|
filter: Filter,
|
|
94
|
-
selectParams: SelectParams & { joinExpressionAlias?:
|
|
94
|
+
selectParams: SelectParams & { joinExpressionAlias?: PGIdentifier } = {},
|
|
95
95
|
param3_unused = null,
|
|
96
96
|
tableRules: ParsedTableRule | undefined,
|
|
97
97
|
localParams: LocalParams | undefined,
|
|
@@ -133,7 +133,7 @@ export async function getNewQuery(
|
|
|
133
133
|
throwErr(parsedJoin.error);
|
|
134
134
|
return;
|
|
135
135
|
}
|
|
136
|
-
const joinExpressionAlias = joinColumnName;
|
|
136
|
+
const joinExpressionAlias = { raw: joinColumnName, escaped: asName(joinColumnName) };
|
|
137
137
|
const j_path = parseJoinPath({
|
|
138
138
|
rawPath: parsedJoin.type === "simple" ? joinColumnName : parsedJoin.params.path,
|
|
139
139
|
rootTable: _this.name,
|
|
@@ -247,7 +247,7 @@ export async function getNewQuery(
|
|
|
247
247
|
const resQuery: NewQuery = {
|
|
248
248
|
allFields: _this.column_names.slice(0),
|
|
249
249
|
select,
|
|
250
|
-
table: _this.name,
|
|
250
|
+
table: { raw: _this.name, escaped: _this.name },
|
|
251
251
|
joins: joinQueries,
|
|
252
252
|
where,
|
|
253
253
|
whereOpts: filterOpts,
|
|
@@ -18,7 +18,7 @@ export function getSelectQuery(
|
|
|
18
18
|
viewHandler: ViewHandler,
|
|
19
19
|
q: NewQuery,
|
|
20
20
|
depth = 0,
|
|
21
|
-
selectParamsGroupBy: boolean
|
|
21
|
+
selectParamsGroupBy: boolean,
|
|
22
22
|
): string {
|
|
23
23
|
const rootSelect = q.select
|
|
24
24
|
.filter((s) => s.selected)
|
|
@@ -27,7 +27,7 @@ export function getSelectQuery(
|
|
|
27
27
|
const parsedJoins =
|
|
28
28
|
q.joins?.flatMap((q2) => {
|
|
29
29
|
const parsed = getJoinQuery(viewHandler, {
|
|
30
|
-
q1: { ...q, tableAlias: ROOT_TABLE_ALIAS },
|
|
30
|
+
q1: { ...q, tableAlias: { raw: ROOT_TABLE_ALIAS, escaped: ROOT_TABLE_ALIAS } },
|
|
31
31
|
q2: { ...q2 },
|
|
32
32
|
selectParamsGroupBy,
|
|
33
33
|
});
|
|
@@ -40,8 +40,8 @@ export function getSelectQuery(
|
|
|
40
40
|
const selectItems = rootSelect.concat(
|
|
41
41
|
parsedJoins.map((join) => {
|
|
42
42
|
const { joinAlias } = join;
|
|
43
|
-
return `COALESCE(${
|
|
44
|
-
})
|
|
43
|
+
return `COALESCE(${joinAlias.escaped}.${join.resultAlias.escaped}, '[]') as ${joinAlias.escaped}`;
|
|
44
|
+
}),
|
|
45
45
|
);
|
|
46
46
|
|
|
47
47
|
/** OR joins cannot be easily aggregated to one-many with the root table. Must group by root table id */
|
|
@@ -62,9 +62,9 @@ export function getSelectQuery(
|
|
|
62
62
|
if (hasOrJoins) {
|
|
63
63
|
const pkey = viewHandler.columns.find((c) => c.is_pkey);
|
|
64
64
|
joinCtes = [
|
|
65
|
-
`${q.table} AS (`,
|
|
65
|
+
`${q.table.escaped} AS (`,
|
|
66
66
|
` SELECT *, ${pkey ? asName(pkey.name) : "ROW_NUMBER() OVER()"} as ${ROOT_TABLE_ROW_NUM_ID}`,
|
|
67
|
-
` FROM ${q.table}`,
|
|
67
|
+
` FROM ${q.table.escaped}`,
|
|
68
68
|
`)`,
|
|
69
69
|
joinCtes.length ? "," : "",
|
|
70
70
|
...joinCtes,
|
|
@@ -81,7 +81,7 @@ export function getSelectQuery(
|
|
|
81
81
|
...indentLines(selectItems, { appendCommas: true }),
|
|
82
82
|
`FROM ( `,
|
|
83
83
|
` SELECT *`,
|
|
84
|
-
` FROM ${q.table}`,
|
|
84
|
+
` FROM ${q.table.escaped}`,
|
|
85
85
|
...(q.where ? [` ${q.where}`] : []),
|
|
86
86
|
`) ${ROOT_TABLE_ALIAS}`,
|
|
87
87
|
...parsedJoins.flatMap((j) => j.joinLines),
|
|
@@ -104,7 +104,7 @@ type IndentLinesOpts = {
|
|
|
104
104
|
};
|
|
105
105
|
export const indentLines = (
|
|
106
106
|
strArr: (string | undefined | null)[],
|
|
107
|
-
{ numberOfSpaces = 2, indentStr = " ", appendCommas = false }: IndentLinesOpts = {}
|
|
107
|
+
{ numberOfSpaces = 2, indentStr = " ", appendCommas = false }: IndentLinesOpts = {},
|
|
108
108
|
): string[] => {
|
|
109
109
|
const nonEmptyLines = strArr.filter((v) => v);
|
|
110
110
|
|
|
@@ -120,11 +120,10 @@ const indentLinesToString = (
|
|
|
120
120
|
strArr: (string | undefined | null)[],
|
|
121
121
|
numberOfSpaces = 0,
|
|
122
122
|
separator = " \n ",
|
|
123
|
-
indentStr = " "
|
|
123
|
+
indentStr = " ",
|
|
124
124
|
) => indentLines(strArr, { numberOfSpaces, indentStr }).join(separator);
|
|
125
|
-
const
|
|
126
|
-
!q.tableAlias ? q.table : `${q.tableAlias || ""}_${q.table}
|
|
127
|
-
export const getTableAliasAsName = (q: NewQuery) => asName(getTableAlias(q));
|
|
125
|
+
export const getTableAliasAsName = (q: NewQuery) =>
|
|
126
|
+
!q.tableAlias ? q.table.escaped : asName(`${q.tableAlias.raw || ""}_${q.table.raw}`);
|
|
128
127
|
|
|
129
128
|
export const getRootGroupBy = (q: NewQuery, selectParamsGroupBy?: boolean) => {
|
|
130
129
|
const aggs = q.select.filter((s) => s.selected && s.type === "aggregation");
|
|
@@ -133,11 +132,6 @@ export const getRootGroupBy = (q: NewQuery, selectParamsGroupBy?: boolean) => {
|
|
|
133
132
|
if ((selectParamsGroupBy || aggs.length) && nonAggs.length) {
|
|
134
133
|
/** Add ORDER BY items not included in root select */
|
|
135
134
|
const orderByItems: string[] = [];
|
|
136
|
-
// q.orderByItems.forEach(sortItem => {
|
|
137
|
-
// if (!sortItem.nested && "fieldQuery" in sortItem && !orderByItems.includes(sortItem.fieldQuery)) {
|
|
138
|
-
// orderByItems.push(sortItem.fieldQuery);
|
|
139
|
-
// }
|
|
140
|
-
// });
|
|
141
135
|
|
|
142
136
|
return [
|
|
143
137
|
`GROUP BY ${q.select
|
|
@@ -9,7 +9,7 @@ import { asNameAlias } from "../../utils/asNameAlias";
|
|
|
9
9
|
export function getValidatedRules(
|
|
10
10
|
this: ViewHandler,
|
|
11
11
|
tableRules?: ParsedTableRule,
|
|
12
|
-
localParams?: LocalParams
|
|
12
|
+
localParams?: LocalParams,
|
|
13
13
|
): ValidatedTableRules {
|
|
14
14
|
if (localParams?.clientReq?.socket && !tableRules) {
|
|
15
15
|
throw "INTERNAL ERROR: Unexpected case -> localParams && !tableRules";
|
|
@@ -23,15 +23,15 @@ export function getValidatedRules(
|
|
|
23
23
|
({
|
|
24
24
|
type: "column",
|
|
25
25
|
name: fieldName,
|
|
26
|
-
getQuery: ({ tableAlias }) => asNameAlias(fieldName, tableAlias),
|
|
26
|
+
getQuery: ({ tableAliasRaw: tableAlias }) => asNameAlias(fieldName, tableAlias),
|
|
27
27
|
selected: false,
|
|
28
|
-
}) as FieldSpec
|
|
28
|
+
}) as FieldSpec,
|
|
29
29
|
)
|
|
30
30
|
.concat(
|
|
31
31
|
COMPUTED_FIELDS.map((c) => ({
|
|
32
32
|
type: c.type,
|
|
33
33
|
name: c.name,
|
|
34
|
-
getQuery: ({ tableAlias, allowedFields }) =>
|
|
34
|
+
getQuery: ({ tableAliasRaw: tableAlias, allowedFields }) =>
|
|
35
35
|
c.getQuery({
|
|
36
36
|
allowedFields,
|
|
37
37
|
ctidField: undefined,
|
|
@@ -39,10 +39,10 @@ export function getValidatedRules(
|
|
|
39
39
|
|
|
40
40
|
/* CTID not available in AFTER trigger */
|
|
41
41
|
// ctidField: this.is_view? undefined : "ctid",
|
|
42
|
-
tableAlias,
|
|
42
|
+
tableAliasRaw: tableAlias,
|
|
43
43
|
}),
|
|
44
44
|
selected: false,
|
|
45
|
-
}))
|
|
45
|
+
})),
|
|
46
46
|
);
|
|
47
47
|
|
|
48
48
|
if (tableRules) {
|
|
@@ -50,7 +50,7 @@ export function getValidatedRules(
|
|
|
50
50
|
throw "INTERNAL ERROR: Unexpected case -> Empty table rules for " + this.name;
|
|
51
51
|
const throwFieldsErr = (
|
|
52
52
|
command: "select" | "update" | "delete" | "insert",
|
|
53
|
-
fieldType = "fields"
|
|
53
|
+
fieldType = "fields",
|
|
54
54
|
) => {
|
|
55
55
|
throw `Invalid publish.${this.name}.${command} rule -> ${fieldType} setting is missing.\nPlease specify allowed ${fieldType} in this format: "*" | { col_name: false } | { col1: true, col2: true }`;
|
|
56
56
|
},
|
|
@@ -106,7 +106,7 @@ export function getValidatedRules(
|
|
|
106
106
|
returningFields: parseFirstSpecifiedFieldFilter(
|
|
107
107
|
tableRules.update.returningFields,
|
|
108
108
|
tableRules.select?.fields,
|
|
109
|
-
tableRules.update.fields
|
|
109
|
+
tableRules.update.fields,
|
|
110
110
|
),
|
|
111
111
|
filterFields: this.parseFieldFilter(tableRules.update.filterFields),
|
|
112
112
|
};
|
|
@@ -121,7 +121,7 @@ export function getValidatedRules(
|
|
|
121
121
|
returningFields: parseFirstSpecifiedFieldFilter(
|
|
122
122
|
tableRules.insert.returningFields,
|
|
123
123
|
tableRules.select?.fields,
|
|
124
|
-
tableRules.insert.fields
|
|
124
|
+
tableRules.insert.fields,
|
|
125
125
|
),
|
|
126
126
|
};
|
|
127
127
|
}
|
|
@@ -142,36 +142,35 @@ export function getValidatedRules(
|
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
return res;
|
|
145
|
-
} else {
|
|
146
|
-
const allCols = this.column_names.slice(0);
|
|
147
|
-
return {
|
|
148
|
-
allColumns,
|
|
149
|
-
getColumns: true,
|
|
150
|
-
getInfo: true,
|
|
151
|
-
select: {
|
|
152
|
-
fields: allCols,
|
|
153
|
-
filterFields: allCols,
|
|
154
|
-
orderByFields: allCols,
|
|
155
|
-
forcedFilter: {},
|
|
156
|
-
maxLimit: null,
|
|
157
|
-
},
|
|
158
|
-
update: {
|
|
159
|
-
fields: allCols,
|
|
160
|
-
filterFields: allCols,
|
|
161
|
-
forcedFilter: {},
|
|
162
|
-
forcedData: {},
|
|
163
|
-
returningFields: allCols,
|
|
164
|
-
},
|
|
165
|
-
insert: {
|
|
166
|
-
fields: allCols,
|
|
167
|
-
forcedData: {},
|
|
168
|
-
returningFields: allCols,
|
|
169
|
-
},
|
|
170
|
-
delete: {
|
|
171
|
-
filterFields: allCols,
|
|
172
|
-
forcedFilter: {},
|
|
173
|
-
returningFields: allCols,
|
|
174
|
-
},
|
|
175
|
-
};
|
|
176
145
|
}
|
|
146
|
+
const allCols = this.column_names.slice(0);
|
|
147
|
+
return {
|
|
148
|
+
allColumns,
|
|
149
|
+
getColumns: true,
|
|
150
|
+
getInfo: true,
|
|
151
|
+
select: {
|
|
152
|
+
fields: allCols,
|
|
153
|
+
filterFields: allCols,
|
|
154
|
+
orderByFields: allCols,
|
|
155
|
+
forcedFilter: {},
|
|
156
|
+
maxLimit: null,
|
|
157
|
+
},
|
|
158
|
+
update: {
|
|
159
|
+
fields: allCols,
|
|
160
|
+
filterFields: allCols,
|
|
161
|
+
forcedFilter: {},
|
|
162
|
+
forcedData: {},
|
|
163
|
+
returningFields: allCols,
|
|
164
|
+
},
|
|
165
|
+
insert: {
|
|
166
|
+
fields: allCols,
|
|
167
|
+
forcedData: {},
|
|
168
|
+
returningFields: allCols,
|
|
169
|
+
},
|
|
170
|
+
delete: {
|
|
171
|
+
filterFields: allCols,
|
|
172
|
+
forcedFilter: {},
|
|
173
|
+
returningFields: allCols,
|
|
174
|
+
},
|
|
175
|
+
};
|
|
177
176
|
}
|
|
@@ -16,7 +16,7 @@ const allowedComparators = FILTER_OPERANDS; //[">", "<", "=", "<=", ">=", "<>",
|
|
|
16
16
|
type Args = {
|
|
17
17
|
filter: AnyObject;
|
|
18
18
|
complexFilterKey: string;
|
|
19
|
-
|
|
19
|
+
tableAliasRaw: string | undefined;
|
|
20
20
|
allowed_colnames: string[];
|
|
21
21
|
columns: TableSchemaColumn[];
|
|
22
22
|
};
|
|
@@ -33,7 +33,7 @@ type Args = {
|
|
|
33
33
|
export const parseComplexFilter = ({
|
|
34
34
|
filter,
|
|
35
35
|
complexFilterKey,
|
|
36
|
-
|
|
36
|
+
tableAliasRaw,
|
|
37
37
|
allowed_colnames,
|
|
38
38
|
columns,
|
|
39
39
|
}: Args) => {
|
|
@@ -50,7 +50,7 @@ export const parseComplexFilter = ({
|
|
|
50
50
|
if (!allowed_colnames.includes(column)) {
|
|
51
51
|
throw `Dissallowed or Invalid column ${column}. Allowed columns: ${allowed_colnames}`;
|
|
52
52
|
}
|
|
53
|
-
return asNameAlias(column,
|
|
53
|
+
return asNameAlias(column, tableAliasRaw);
|
|
54
54
|
}
|
|
55
55
|
const { funcName, args } = parseFunctionObject(funcData);
|
|
56
56
|
const funcDef = parseFunction({
|
|
@@ -61,7 +61,7 @@ export const parseComplexFilter = ({
|
|
|
61
61
|
});
|
|
62
62
|
return funcDef.getQuery({
|
|
63
63
|
args,
|
|
64
|
-
|
|
64
|
+
tableAliasRaw,
|
|
65
65
|
allColumns: columns,
|
|
66
66
|
allowedFields: allowed_colnames,
|
|
67
67
|
});
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
isEmpty,
|
|
7
7
|
isObject,
|
|
8
8
|
} from "prostgles-types/dist";
|
|
9
|
-
import type { SortItem } from "../DboBuilder";
|
|
9
|
+
import type { PGIdentifier, SortItem } from "../DboBuilder";
|
|
10
10
|
import type { NewQueryJoin, SelectItemValidated } from "../QueryBuilder/QueryBuilder";
|
|
11
11
|
import { asNameAlias } from "../../utils/asNameAlias";
|
|
12
12
|
|
|
@@ -14,9 +14,9 @@ import { asNameAlias } from "../../utils/asNameAlias";
|
|
|
14
14
|
export const prepareSortItems = (
|
|
15
15
|
rawOrderBy: OrderBy | undefined,
|
|
16
16
|
allowed_cols: string[],
|
|
17
|
-
tableAlias:
|
|
17
|
+
tableAlias: PGIdentifier | undefined,
|
|
18
18
|
select: SelectItemValidated[],
|
|
19
|
-
joinQueries: NewQueryJoin[]
|
|
19
|
+
joinQueries: NewQueryJoin[],
|
|
20
20
|
): SortItem[] => {
|
|
21
21
|
if (!rawOrderBy) return [];
|
|
22
22
|
|
|
@@ -48,7 +48,7 @@ export const prepareSortItems = (
|
|
|
48
48
|
.filter(
|
|
49
49
|
(s) =>
|
|
50
50
|
s.type !== "joinedColumn" &&
|
|
51
|
-
(!s.fields.length || s.fields.every((f) => allowed_cols.includes(f)))
|
|
51
|
+
(!s.fields.length || s.fields.every((f) => allowed_cols.includes(f))),
|
|
52
52
|
)
|
|
53
53
|
.map((s) => s.alias);
|
|
54
54
|
|
|
@@ -59,15 +59,15 @@ export const prepareSortItems = (
|
|
|
59
59
|
...jq,
|
|
60
60
|
selectItem,
|
|
61
61
|
joinAlias,
|
|
62
|
-
key: `${joinAlias}.${selectItem.alias}`,
|
|
62
|
+
key: `${joinAlias.raw}.${selectItem.alias}`,
|
|
63
63
|
};
|
|
64
|
-
})
|
|
64
|
+
}),
|
|
65
65
|
);
|
|
66
66
|
const bad_param = orderBy.find(
|
|
67
67
|
({ key }) =>
|
|
68
68
|
!sortableNestedColumns.some((v) => v.key === key) &&
|
|
69
69
|
!validatedAggAliases.includes(key) &&
|
|
70
|
-
!allowed_cols.includes(key)
|
|
70
|
+
!allowed_cols.includes(key),
|
|
71
71
|
);
|
|
72
72
|
if (bad_param) {
|
|
73
73
|
throw "Invalid/disallowed orderBy fields or params: " + bad_param.key;
|
|
@@ -95,9 +95,9 @@ export const prepareSortItems = (
|
|
|
95
95
|
joinAlias,
|
|
96
96
|
selectItemAlias: selectItem.alias,
|
|
97
97
|
isNumeric: selectItem.tsDataType === "number",
|
|
98
|
-
wrapperQuerySortItem: `${asc ? "MIN" : "MAX"}(${asNameAlias(selectItem.alias, joinAlias)}${comparableDataTypeCast}) as ${sortItemAlias}`,
|
|
98
|
+
wrapperQuerySortItem: `${asc ? "MIN" : "MAX"}(${asNameAlias(selectItem.alias, joinAlias.raw)}${comparableDataTypeCast}) as ${sortItemAlias}`,
|
|
99
99
|
},
|
|
100
|
-
fieldQuery: `${
|
|
100
|
+
fieldQuery: `${joinAlias.escaped}.${sortItemAlias + (asc ? "" : " DESC")} ${nulls ? `NULLS ${nulls === "last" ? "LAST" : "FIRST"}` : ""}`,
|
|
101
101
|
};
|
|
102
102
|
}
|
|
103
103
|
/* Order by column index when possible to bypass name collision when ordering by a computed column.
|
|
@@ -106,7 +106,9 @@ export const prepareSortItems = (
|
|
|
106
106
|
|
|
107
107
|
const index = selectedAliases.indexOf(key) + 1;
|
|
108
108
|
let colKey =
|
|
109
|
-
index > 0 && !nullEmpty ?
|
|
109
|
+
index > 0 && !nullEmpty ?
|
|
110
|
+
index
|
|
111
|
+
: [tableAlias?.raw, key].filter(isDefined).map(asName).join(".");
|
|
110
112
|
if (nullEmpty) {
|
|
111
113
|
colKey = `nullif(trim(${colKey}::text), '')`;
|
|
112
114
|
}
|
|
@@ -150,7 +152,7 @@ const throwErr = (rawOrderBy: any) => {
|
|
|
150
152
|
|
|
151
153
|
const parseOrderObj = (
|
|
152
154
|
orderBy: any,
|
|
153
|
-
expectOne = false
|
|
155
|
+
expectOne = false,
|
|
154
156
|
): {
|
|
155
157
|
key: string;
|
|
156
158
|
asc: boolean;
|
|
@@ -171,7 +173,7 @@ const parseOrderObj = (
|
|
|
171
173
|
nullEmpty: { enum: [false, true, null], optional: true },
|
|
172
174
|
} as const,
|
|
173
175
|
orderBy,
|
|
174
|
-
"orderBy"
|
|
176
|
+
"orderBy",
|
|
175
177
|
);
|
|
176
178
|
if (data) {
|
|
177
179
|
const { key, asc = true, nulls, nullEmpty = false } = data;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { AnyObject, FieldFilter} from "prostgles-types/dist";
|
|
1
|
+
import type { AnyObject, FieldFilter } from "prostgles-types/dist";
|
|
2
2
|
import { getKeys, isDefined, isObject } from "prostgles-types/dist";
|
|
3
3
|
import type { ParsedTableRule } from "../../PublishParser/PublishParser";
|
|
4
|
-
import type { ExistsFilterConfig, Filter, LocalParams } from "../DboBuilder";
|
|
4
|
+
import type { ExistsFilterConfig, Filter, LocalParams, PGIdentifier } from "../DboBuilder";
|
|
5
5
|
import { getCondition } from "../getCondition";
|
|
6
6
|
import { type SelectItemValidated } from "../QueryBuilder/QueryBuilder";
|
|
7
7
|
import type { ViewHandler } from "./ViewHandler";
|
|
@@ -12,7 +12,7 @@ export type PrepareWhereParams = {
|
|
|
12
12
|
forcedFilter?: AnyObject;
|
|
13
13
|
filterFields?: FieldFilter;
|
|
14
14
|
addWhere?: boolean;
|
|
15
|
-
tableAlias?:
|
|
15
|
+
tableAlias?: PGIdentifier;
|
|
16
16
|
localParams: LocalParams | undefined;
|
|
17
17
|
tableRule: ParsedTableRule | undefined;
|
|
18
18
|
isHaving?: boolean;
|
|
@@ -20,7 +20,7 @@ export type PrepareWhereParams = {
|
|
|
20
20
|
|
|
21
21
|
export async function prepareWhere(
|
|
22
22
|
this: ViewHandler,
|
|
23
|
-
params: PrepareWhereParams
|
|
23
|
+
params: PrepareWhereParams,
|
|
24
24
|
): Promise<{
|
|
25
25
|
condition: string;
|
|
26
26
|
where: string;
|
|
@@ -48,7 +48,7 @@ export async function prepareWhere(
|
|
|
48
48
|
const parseFullFilter = async (
|
|
49
49
|
f: any,
|
|
50
50
|
parentFilter: any = null,
|
|
51
|
-
isForcedFilterBypass: boolean
|
|
51
|
+
isForcedFilterBypass: boolean,
|
|
52
52
|
): Promise<string> => {
|
|
53
53
|
if (!f) throw "Invalid/missing group filter provided";
|
|
54
54
|
if (!isObject(f)) throw "\nInvalid filter\nExpecting an object but got -> " + JSON.stringify(f);
|
|
@@ -71,7 +71,7 @@ export async function prepareWhere(
|
|
|
71
71
|
const operand = $and ? " AND " : " OR ";
|
|
72
72
|
const conditions = (
|
|
73
73
|
await Promise.all(
|
|
74
|
-
group.map(async (gf) => await parseFullFilter(gf, group, isForcedFilterBypass))
|
|
74
|
+
group.map(async (gf) => await parseFullFilter(gf, group, isForcedFilterBypass)),
|
|
75
75
|
)
|
|
76
76
|
).filter((c) => c);
|
|
77
77
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { asName, pickKeys } from "prostgles-types";
|
|
2
2
|
import { parseFilterItem } from "../Filtering";
|
|
3
3
|
import type { ParsedTableRule } from "../PublishParser/PublishParser";
|
|
4
|
-
import type { ExistsFilterConfig, LocalParams } from "./DboBuilder";
|
|
4
|
+
import type { ExistsFilterConfig, LocalParams, PGIdentifier } from "./DboBuilder";
|
|
5
5
|
import { pgp } from "./DboBuilder";
|
|
6
6
|
import { FUNCTIONS } from "./QueryBuilder/Functions/Functions";
|
|
7
7
|
import { type SelectItemValidated } from "./QueryBuilder/QueryBuilder";
|
|
@@ -24,7 +24,7 @@ export async function getCondition(
|
|
|
24
24
|
filter: any;
|
|
25
25
|
select: SelectItemValidated[] | undefined;
|
|
26
26
|
allowed_colnames: string[];
|
|
27
|
-
tableAlias?:
|
|
27
|
+
tableAlias?: PGIdentifier;
|
|
28
28
|
localParams?: LocalParams;
|
|
29
29
|
tableRules?: ParsedTableRule;
|
|
30
30
|
isHaving?: boolean;
|
|
@@ -63,7 +63,7 @@ export async function getCondition(
|
|
|
63
63
|
args: funcArgs,
|
|
64
64
|
allColumns: this.columns,
|
|
65
65
|
allowedFields: allowed_colnames,
|
|
66
|
-
tableAlias,
|
|
66
|
+
tableAliasRaw: tableAlias?.raw,
|
|
67
67
|
}),
|
|
68
68
|
);
|
|
69
69
|
});
|
|
@@ -74,11 +74,7 @@ export async function getCondition(
|
|
|
74
74
|
await Promise.all(
|
|
75
75
|
existsConfigs.map(
|
|
76
76
|
async (existsConfig) =>
|
|
77
|
-
await getExistsCondition.bind(this)(
|
|
78
|
-
existsConfig,
|
|
79
|
-
tableAlias && asName(tableAlias),
|
|
80
|
-
localParams,
|
|
81
|
-
),
|
|
77
|
+
await getExistsCondition.bind(this)(existsConfig, tableAlias?.escaped, localParams),
|
|
82
78
|
),
|
|
83
79
|
)
|
|
84
80
|
).join(" AND ");
|
|
@@ -94,7 +90,7 @@ export async function getCondition(
|
|
|
94
90
|
if (!p.select) throw new Error("Computed column filter requires p.select.fields");
|
|
95
91
|
computedColConditions.push(
|
|
96
92
|
compCol.getQuery({
|
|
97
|
-
tableAlias,
|
|
93
|
+
tableAliasRaw: tableAlias?.raw,
|
|
98
94
|
allowedFields: p.select.fields,
|
|
99
95
|
allColumns: this.columns,
|
|
100
96
|
|
|
@@ -147,7 +143,7 @@ export async function getCondition(
|
|
|
147
143
|
fields: [f.name],
|
|
148
144
|
getQuery: (tableAlias) =>
|
|
149
145
|
f.getQuery({
|
|
150
|
-
tableAlias,
|
|
146
|
+
tableAliasRaw: tableAlias,
|
|
151
147
|
allColumns: this.columns,
|
|
152
148
|
allowedFields: allowed_colnames,
|
|
153
149
|
}),
|
|
@@ -163,7 +159,7 @@ export async function getCondition(
|
|
|
163
159
|
const complexFilterCondition = parseComplexFilter({
|
|
164
160
|
filter,
|
|
165
161
|
complexFilterKey,
|
|
166
|
-
tableAlias,
|
|
162
|
+
tableAliasRaw: tableAlias?.raw,
|
|
167
163
|
allowed_colnames,
|
|
168
164
|
columns: this.columns,
|
|
169
165
|
});
|
|
@@ -223,7 +219,7 @@ export async function getCondition(
|
|
|
223
219
|
const f = pickKeys(filter, filterKeys);
|
|
224
220
|
const q = parseFilterItem({
|
|
225
221
|
filter: f,
|
|
226
|
-
tableAlias,
|
|
222
|
+
tableAliasRaw: tableAlias?.raw,
|
|
227
223
|
select: allowedSelect,
|
|
228
224
|
allowedColumnNames:
|
|
229
225
|
!tableRules ?
|
|
@@ -76,7 +76,7 @@ export async function getSubscribeRelatedTables(
|
|
|
76
76
|
* Avoid nested exists error. Will affect performance
|
|
77
77
|
*/
|
|
78
78
|
for (const j of newQuery.joins ?? []) {
|
|
79
|
-
await pushRelatedTable(j.table, j.joinPath);
|
|
79
|
+
await pushRelatedTable(j.table.raw, j.joinPath);
|
|
80
80
|
}
|
|
81
81
|
for (const e of newQuery.whereOpts.exists.filter((e) => e.isJoined)) {
|
|
82
82
|
for (const [index, pathItem] of e.parsedPath.entries()) {
|