prostgles-server 4.2.4 → 4.2.6
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/README.md +1 -1
- package/dist/AuthHandler.js +1 -1
- package/dist/AuthHandler.js.map +1 -1
- package/dist/DBEventsManager.js.map +1 -1
- package/dist/DBSchemaBuilder.d.ts +11 -6
- package/dist/DBSchemaBuilder.d.ts.map +1 -1
- package/dist/DBSchemaBuilder.js +8 -0
- package/dist/DBSchemaBuilder.js.map +1 -1
- package/dist/DboBuilder/DboBuilder.d.ts.map +1 -1
- package/dist/DboBuilder/DboBuilder.js +1 -0
- package/dist/DboBuilder/DboBuilder.js.map +1 -1
- package/dist/DboBuilder/DboBuilderTypes.d.ts +6 -1
- package/dist/DboBuilder/DboBuilderTypes.d.ts.map +1 -1
- package/dist/DboBuilder/DboBuilderTypes.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/Functions.js +4 -4
- package/dist/DboBuilder/QueryBuilder/Functions.js.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.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/getNewQuery.d.ts +1 -1
- package/dist/DboBuilder/QueryBuilder/getNewQuery.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/getSelectQuery.js.map +1 -1
- package/dist/DboBuilder/QueryStreamer.js.map +1 -1
- package/dist/DboBuilder/TableHandler/DataValidator.d.ts +63 -0
- package/dist/DboBuilder/TableHandler/DataValidator.d.ts.map +1 -0
- package/dist/DboBuilder/TableHandler/DataValidator.js +259 -0
- package/dist/DboBuilder/TableHandler/DataValidator.js.map +1 -0
- package/dist/DboBuilder/TableHandler/TableHandler.d.ts +11 -11
- package/dist/DboBuilder/TableHandler/TableHandler.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/TableHandler.js +4 -23
- package/dist/DboBuilder/TableHandler/TableHandler.js.map +1 -1
- package/dist/DboBuilder/TableHandler/delete.js.map +1 -1
- package/dist/DboBuilder/TableHandler/insert.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/insert.js +40 -9
- package/dist/DboBuilder/TableHandler/insert.js.map +1 -1
- package/dist/DboBuilder/TableHandler/insertTest.js.map +1 -1
- package/dist/DboBuilder/TableHandler/onDeleteFromFileTable.js.map +1 -1
- package/dist/DboBuilder/TableHandler/runInsertUpdateQuery.d.ts +2 -1
- package/dist/DboBuilder/TableHandler/runInsertUpdateQuery.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/runInsertUpdateQuery.js +5 -4
- package/dist/DboBuilder/TableHandler/runInsertUpdateQuery.js.map +1 -1
- package/dist/DboBuilder/TableHandler/update.d.ts +1 -1
- package/dist/DboBuilder/TableHandler/update.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/update.js +22 -29
- package/dist/DboBuilder/TableHandler/update.js.map +1 -1
- package/dist/DboBuilder/TableHandler/updateBatch.js +1 -1
- package/dist/DboBuilder/TableHandler/updateBatch.js.map +1 -1
- package/dist/DboBuilder/TableHandler/updateFile.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/updateFile.js +1 -1
- package/dist/DboBuilder/TableHandler/updateFile.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts +4 -12
- package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/ViewHandler.js +5 -46
- package/dist/DboBuilder/ViewHandler/ViewHandler.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/getExistsCondition.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/getExistsFilters.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/getTableJoinQuery.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/parseFieldFilter.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/parseJoinPath.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/prepareSortItems.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/prepareWhere.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/validateViewRules.js.map +1 -1
- package/dist/DboBuilder/dboBuilderUtils.d.ts +4 -0
- package/dist/DboBuilder/dboBuilderUtils.d.ts.map +1 -1
- package/dist/DboBuilder/dboBuilderUtils.js +4 -0
- package/dist/DboBuilder/dboBuilderUtils.js.map +1 -1
- package/dist/DboBuilder/find.js.map +1 -1
- package/dist/DboBuilder/getColumns.d.ts.map +1 -1
- package/dist/DboBuilder/getColumns.js +5 -6
- package/dist/DboBuilder/getColumns.js.map +1 -1
- 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/DboBuilder/getTablesForSchemaPostgresSQL.js.map +1 -1
- package/dist/DboBuilder/insertNestedRecords.d.ts +35 -0
- package/dist/DboBuilder/insertNestedRecords.d.ts.map +1 -0
- package/dist/DboBuilder/insertNestedRecords.js +270 -0
- package/dist/DboBuilder/insertNestedRecords.js.map +1 -0
- package/dist/DboBuilder/parseMediaOrNestedInsert.d.ts +29 -0
- package/dist/DboBuilder/parseMediaOrNestedInsert.d.ts.map +1 -0
- package/dist/DboBuilder/parseMediaOrNestedInsert.js +271 -0
- package/dist/DboBuilder/parseMediaOrNestedInsert.js.map +1 -0
- package/dist/DboBuilder/parseUpdateRules.d.ts +3 -3
- package/dist/DboBuilder/parseUpdateRules.d.ts.map +1 -1
- package/dist/DboBuilder/parseUpdateRules.js +21 -13
- package/dist/DboBuilder/parseUpdateRules.js.map +1 -1
- package/dist/DboBuilder/prepareShortestJoinPaths.js.map +1 -1
- package/dist/DboBuilder/runSQL.js.map +1 -1
- package/dist/DboBuilder/subscribe.js.map +1 -1
- package/dist/DboBuilder/uploadFile.js.map +1 -1
- package/dist/FileManager/FileManager.js.map +1 -1
- package/dist/FileManager/getValidatedFileType.js.map +1 -1
- package/dist/FileManager/initFileManager.js.map +1 -1
- package/dist/FileManager/upload.js.map +1 -1
- package/dist/FileManager/uploadStream.js.map +1 -1
- package/dist/Filtering.js.map +1 -1
- package/dist/JSONBValidation/validation.js.map +1 -1
- package/dist/PostgresNotifListenManager.js.map +1 -1
- package/dist/Prostgles.js.map +1 -1
- package/dist/PubSubManager/PubSubManager.js.map +1 -1
- package/dist/PubSubManager/addSub.js.map +1 -1
- package/dist/PubSubManager/addSync.js.map +1 -1
- package/dist/PubSubManager/initPubSubManager.js.map +1 -1
- package/dist/PubSubManager/notifListener.js.map +1 -1
- package/dist/PubSubManager/pushSubData.js.map +1 -1
- package/dist/PublishParser/PublishParser.d.ts +1 -1
- package/dist/PublishParser/PublishParser.d.ts.map +1 -1
- package/dist/PublishParser/PublishParser.js.map +1 -1
- package/dist/PublishParser/getFileTableRules.js.map +1 -1
- package/dist/PublishParser/getSchemaFromPublish.js.map +1 -1
- package/dist/PublishParser/getTableRulesWithoutFileTable.js.map +1 -1
- package/dist/PublishParser/publishTypesAndUtils.d.ts +6 -5
- package/dist/PublishParser/publishTypesAndUtils.d.ts.map +1 -1
- package/dist/RestApi.js.map +1 -1
- package/dist/SchemaWatch.js.map +1 -1
- package/dist/SyncReplication.js.map +1 -1
- package/dist/TableConfig/TableConfig.d.ts +5 -5
- package/dist/TableConfig/TableConfig.d.ts.map +1 -1
- package/dist/TableConfig/TableConfig.js.map +1 -1
- package/dist/TableConfig/getColumnDefinitionQuery.js.map +1 -1
- package/dist/TableConfig/getConstraintDefinitionQueries.js.map +1 -1
- package/dist/TableConfig/getFutureTableSchema.js.map +1 -1
- package/dist/TableConfig/getTableColumnQueries.js.map +1 -1
- package/dist/TableConfig/initTableConfig.js.map +1 -1
- package/dist/initProstgles.js.map +1 -1
- package/dist/runClientRequest.js.map +1 -1
- package/dist/shortestPath.js.map +1 -1
- package/dist/utils.js.map +1 -1
- package/lib/AuthHandler.ts +3 -3
- package/lib/DBSchemaBuilder.ts +25 -10
- package/lib/DboBuilder/DboBuilder.ts +1 -0
- package/lib/DboBuilder/DboBuilderTypes.ts +17 -1
- package/lib/DboBuilder/QueryBuilder/QueryBuilder.ts +1 -1
- package/lib/DboBuilder/TableHandler/DataValidator.ts +425 -0
- package/lib/DboBuilder/TableHandler/TableHandler.ts +17 -36
- package/lib/DboBuilder/TableHandler/insert.ts +45 -13
- package/lib/DboBuilder/TableHandler/runInsertUpdateQuery.ts +8 -5
- package/lib/DboBuilder/TableHandler/update.ts +25 -37
- package/lib/DboBuilder/TableHandler/updateBatch.ts +4 -4
- package/lib/DboBuilder/TableHandler/updateFile.ts +4 -3
- package/lib/DboBuilder/ViewHandler/ViewHandler.ts +3 -54
- package/lib/DboBuilder/dboBuilderUtils.ts +4 -1
- package/lib/DboBuilder/getColumns.ts +6 -7
- package/lib/DboBuilder/{insertDataParse.ts → insertNestedRecords.ts} +58 -49
- package/lib/DboBuilder/parseUpdateRules.ts +22 -22
- package/lib/Prostgles.ts +1 -1
- package/lib/PublishParser/PublishParser.ts +1 -1
- package/lib/PublishParser/publishTypesAndUtils.ts +6 -5
- package/lib/TableConfig/TableConfig.ts +7 -6
- package/lib/TableConfig/initTableConfig.ts +1 -1
- package/lib/initProstgles.ts +1 -1
- package/package.json +3 -3
- package/tests/client/package-lock.json +23 -23
- package/tests/client/package.json +2 -2
- package/tests/client/tsconfig.json +1 -1
- package/tests/isomorphic_queries.ts +16 -10
- package/tests/server/package-lock.json +12 -12
- package/tests/server/package.json +1 -1
- package/tests/server_only_queries.ts +3 -1
- package/lib/DboBuilder/ViewHandler/ColSet.ts +0 -121
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { AnyObject, InsertParams, isObject } from "prostgles-types";
|
|
2
2
|
import { LocalParams, parseError, withUserRLS } from "../DboBuilder";
|
|
3
|
-
import { TableRule } from "../../PublishParser/PublishParser";
|
|
4
|
-
import {
|
|
3
|
+
import { TableRule, ValidateRowBasic } from "../../PublishParser/PublishParser";
|
|
4
|
+
import { insertNestedRecords } from "../insertNestedRecords";
|
|
5
5
|
import { insertTest } from "./insertTest";
|
|
6
6
|
import { TableHandler } from "./TableHandler";
|
|
7
7
|
import { runInsertUpdateQuery } from "./runInsertUpdateQuery";
|
|
8
|
+
import { prepareNewData } from "./DataValidator";
|
|
9
|
+
import { DBOFullyTyped } from "../../DBSchemaBuilder";
|
|
8
10
|
|
|
9
11
|
export async function insert(this: TableHandler, rowOrRows: AnyObject | AnyObject[] = {}, insertParams?: InsertParams, param3_unused?: undefined, tableRules?: TableRule, localParams?: LocalParams): Promise<any | any[] | boolean> {
|
|
10
12
|
|
|
@@ -38,11 +40,26 @@ export async function insert(this: TableHandler, rowOrRows: AnyObject | AnyObjec
|
|
|
38
40
|
}
|
|
39
41
|
validateInsertParams(insertParams);
|
|
40
42
|
|
|
43
|
+
const isMultiInsert = Array.isArray(rowOrRows);
|
|
44
|
+
const preValidatedRows = await Promise.all((isMultiInsert? rowOrRows : [rowOrRows]).map(async nonValidated => {
|
|
45
|
+
const { preValidate, validate } = tableRules?.insert ?? {};
|
|
46
|
+
const { tableConfigurator } = this.dboBuilder.prostgles;
|
|
47
|
+
if(!tableConfigurator) throw "tableConfigurator missing";
|
|
48
|
+
let row = await tableConfigurator.getPreInsertRow(this, { dbx: this.getFinalDbo(localParams), validate, localParams, row: nonValidated })
|
|
49
|
+
if (preValidate) {
|
|
50
|
+
if(!localParams) throw "localParams missing for insert preValidate";
|
|
51
|
+
row = await preValidate({ row, dbx: (this.tx?.dbTX || this.dboBuilder.dbo) as any, localParams });
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return row;
|
|
55
|
+
}));
|
|
56
|
+
const preValidatedrowOrRows = isMultiInsert? preValidatedRows : preValidatedRows[0]!;
|
|
57
|
+
|
|
41
58
|
/**
|
|
42
59
|
* If media it will: upload file and continue insert
|
|
43
60
|
* If nested insert it will: make separate inserts and not continue main insert
|
|
44
61
|
*/
|
|
45
|
-
const mediaOrNestedInsert = await
|
|
62
|
+
const mediaOrNestedInsert = await insertNestedRecords.bind(this)({ data: preValidatedrowOrRows, param2: insertParams, tableRules, localParams });
|
|
46
63
|
const { data, insertResult } = mediaOrNestedInsert;
|
|
47
64
|
if ("insertResult" in mediaOrNestedInsert) {
|
|
48
65
|
return insertResult;
|
|
@@ -55,25 +72,38 @@ export async function insert(this: TableHandler, rowOrRows: AnyObject | AnyObjec
|
|
|
55
72
|
const row = { ..._row };
|
|
56
73
|
|
|
57
74
|
if (!isObject(row)) {
|
|
58
|
-
|
|
59
|
-
throw "\ninvalid insert data provided -> " + JSON.stringify(row);
|
|
75
|
+
throw "\nInvalid insert data provided. Expected an object but received: " + JSON.stringify(row);
|
|
60
76
|
}
|
|
61
77
|
|
|
62
|
-
const { data: validatedRow, allowedCols } =
|
|
78
|
+
const { data: validatedRow, allowedCols } = await prepareNewData({
|
|
79
|
+
row,
|
|
80
|
+
forcedData,
|
|
81
|
+
allowedFields: fields,
|
|
82
|
+
tableRules,
|
|
83
|
+
fixIssues,
|
|
84
|
+
tableConfigurator: this.dboBuilder.prostgles.tableConfigurator,
|
|
85
|
+
tableHandler: this,
|
|
86
|
+
});
|
|
63
87
|
return { validatedRow, allowedCols };
|
|
64
88
|
}));
|
|
65
89
|
const validatedRows = validatedData.map(d => d.validatedRow);
|
|
66
|
-
const allowedCols = Array.from(
|
|
67
|
-
const dbTx = finalDBtx || this.dboBuilder.dbo
|
|
68
|
-
const
|
|
69
|
-
|
|
90
|
+
const allowedCols = Array.from(new Set(validatedData.flatMap(d => d.allowedCols)));
|
|
91
|
+
const dbTx = finalDBtx || this.dboBuilder.dbo;
|
|
92
|
+
const validationOptions = { validate: validate as ValidateRowBasic, localParams };
|
|
93
|
+
// const query = await this.colSet.getInsertQuery(validatedRows, allowedCols, dbTx, validate, localParams);
|
|
94
|
+
const query = (await this.dataValidator.parse({ command: "insert", rows: validatedRows, allowedCols, dbTx, validationOptions })).getQuery();
|
|
70
95
|
const { onConflict } = insertParams ?? {};
|
|
71
96
|
let conflict_query = "";
|
|
72
97
|
if (onConflict === "DoNothing") {
|
|
73
98
|
conflict_query = " ON CONFLICT DO NOTHING ";
|
|
74
99
|
} else if(onConflict === "DoUpdate"){
|
|
75
|
-
if(!pkeyNames.length)
|
|
100
|
+
if(!pkeyNames.length) {
|
|
101
|
+
throw "Cannot do DoUpdate on a table without a primary key";
|
|
102
|
+
}
|
|
76
103
|
const nonPkeyCols = allowedCols.filter(c => !pkeyNames.includes(c));
|
|
104
|
+
if(!nonPkeyCols.length){
|
|
105
|
+
throw "Cannot on conflict DoUpdate on a table with only primary key columns";
|
|
106
|
+
}
|
|
77
107
|
conflict_query = ` ON CONFLICT (${pkeyNames.join(", ")}) DO UPDATE SET ${nonPkeyCols.map(k => `${k} = EXCLUDED.${k}`).join(", ")}`;
|
|
78
108
|
}
|
|
79
109
|
return query + conflict_query;
|
|
@@ -100,14 +130,16 @@ export async function insert(this: TableHandler, rowOrRows: AnyObject | AnyObjec
|
|
|
100
130
|
}
|
|
101
131
|
|
|
102
132
|
return runInsertUpdateQuery({
|
|
103
|
-
rule,
|
|
133
|
+
rule,
|
|
134
|
+
localParams,
|
|
104
135
|
queryWithoutUserRLS,
|
|
105
136
|
tableHandler: this,
|
|
106
137
|
returningFields,
|
|
107
|
-
data:
|
|
138
|
+
data: preValidatedrowOrRows,
|
|
108
139
|
fields,
|
|
109
140
|
params: insertParams,
|
|
110
141
|
type: "insert",
|
|
142
|
+
isMultiInsert,
|
|
111
143
|
});
|
|
112
144
|
|
|
113
145
|
} catch (e) {
|
|
@@ -2,6 +2,7 @@ import { AnyObject, asName, FieldFilter, InsertParams, UpdateParams } from "pros
|
|
|
2
2
|
import { LocalParams, getClientErrorFromPGError, withUserRLS } from "../DboBuilder";
|
|
3
3
|
import { InsertRule, UpdateRule } from "../../PublishParser/PublishParser";
|
|
4
4
|
import { getSelectItemQuery, TableHandler } from "./TableHandler";
|
|
5
|
+
import { DBOFullyTyped } from "../../DBSchemaBuilder";
|
|
5
6
|
|
|
6
7
|
type RunInsertUpdateQueryArgs = {
|
|
7
8
|
tableHandler: TableHandler;
|
|
@@ -14,6 +15,7 @@ type RunInsertUpdateQueryArgs = {
|
|
|
14
15
|
params: InsertParams | undefined
|
|
15
16
|
rule: InsertRule | undefined;
|
|
16
17
|
data: AnyObject | AnyObject[];
|
|
18
|
+
isMultiInsert: boolean;
|
|
17
19
|
nestedInsertsResultsObj?: undefined;
|
|
18
20
|
} | {
|
|
19
21
|
type: "update";
|
|
@@ -23,7 +25,8 @@ type RunInsertUpdateQueryArgs = {
|
|
|
23
25
|
data: undefined;
|
|
24
26
|
});
|
|
25
27
|
|
|
26
|
-
export const runInsertUpdateQuery = async (
|
|
28
|
+
export const runInsertUpdateQuery = async (args: RunInsertUpdateQueryArgs) => {
|
|
29
|
+
const { tableHandler, queryWithoutUserRLS, rule, localParams, fields, returningFields, params, nestedInsertsResultsObj } = args;
|
|
27
30
|
const { name } = tableHandler;
|
|
28
31
|
|
|
29
32
|
const returningSelectItems = await tableHandler.prepareReturning(params?.returning, tableHandler.parseFieldFilter(returningFields))
|
|
@@ -104,13 +107,13 @@ export const runInsertUpdateQuery = async ({ tableHandler, queryWithoutUserRLS,
|
|
|
104
107
|
|
|
105
108
|
const rows = result.modified ?? [];
|
|
106
109
|
for await (const row of rows){
|
|
107
|
-
await postValidate({ row: row ?? {}, dbx: finalDBtx, localParams })
|
|
110
|
+
await postValidate({ row: row ?? {}, dbx: finalDBtx as any, localParams })
|
|
108
111
|
}
|
|
109
112
|
}
|
|
110
113
|
|
|
111
114
|
let returnMany = false;
|
|
112
|
-
if(type === "update"){
|
|
113
|
-
const { multi = true } = params || {};
|
|
115
|
+
if(args.type === "update"){
|
|
116
|
+
const { multi = true } = args.params || {};
|
|
114
117
|
if(!multi && result.row_count && +result.row_count > 1){
|
|
115
118
|
throw `More than 1 row modified: ${result.row_count} rows affected`;
|
|
116
119
|
}
|
|
@@ -120,7 +123,7 @@ export const runInsertUpdateQuery = async ({ tableHandler, queryWithoutUserRLS,
|
|
|
120
123
|
}
|
|
121
124
|
|
|
122
125
|
} else {
|
|
123
|
-
returnMany =
|
|
126
|
+
returnMany = args.isMultiInsert
|
|
124
127
|
}
|
|
125
128
|
|
|
126
129
|
if(!hasReturning) return undefined;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { AnyObject,
|
|
2
|
-
import { Filter, isPlainObject, LocalParams, parseError, withUserRLS } from "../DboBuilder";
|
|
1
|
+
import { AnyObject, UpdateParams } from "prostgles-types";
|
|
3
2
|
import { TableRule } from "../../PublishParser/PublishParser";
|
|
4
|
-
import {
|
|
3
|
+
import { Filter, LocalParams, parseError, withUserRLS } from "../DboBuilder";
|
|
4
|
+
import { getInsertTableRules, getReferenceColumnInserts } from "../insertNestedRecords";
|
|
5
5
|
import { runInsertUpdateQuery } from "./runInsertUpdateQuery";
|
|
6
6
|
import { TableHandler } from "./TableHandler";
|
|
7
7
|
import { updateFile } from "./updateFile";
|
|
8
|
+
import { prepareNewData } from "./DataValidator";
|
|
8
9
|
|
|
9
10
|
export async function update(this: TableHandler, filter: Filter, _newData: AnyObject, params?: UpdateParams, tableRules?: TableRule, localParams?: LocalParams): Promise<AnyObject | void> {
|
|
10
11
|
const ACTION = "update";
|
|
@@ -23,11 +24,15 @@ export async function update(this: TableHandler, filter: Filter, _newData: AnyOb
|
|
|
23
24
|
({ newData } = await updateFile.bind(this)({ newData, filter, localParams, tableRules }));
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
const parsedRules = await this.parseUpdateRules(filter,
|
|
27
|
+
const parsedRules = await this.parseUpdateRules(filter, params, tableRules, localParams)
|
|
27
28
|
if (localParams?.testRule) {
|
|
28
29
|
return parsedRules;
|
|
29
30
|
}
|
|
30
31
|
|
|
32
|
+
if (!newData || !Object.keys(newData).length) {
|
|
33
|
+
throw "no update data provided\nEXPECTING db.table.update(filter, updateData, options)";
|
|
34
|
+
}
|
|
35
|
+
|
|
31
36
|
const { fields, validateRow, forcedData, returningFields, forcedFilter, filterFields } = parsedRules;
|
|
32
37
|
const { onConflict, fixIssues = false } = params || {};
|
|
33
38
|
const { returnQuery = false } = localParams ?? {};
|
|
@@ -39,38 +44,16 @@ export async function update(this: TableHandler, filter: Filter, _newData: AnyOb
|
|
|
39
44
|
if (bad_params && bad_params.length) throw "Invalid params: " + bad_params.join(", ") + " \n Expecting: " + good_params.join(", ");
|
|
40
45
|
}
|
|
41
46
|
|
|
42
|
-
const { data, allowedCols } =
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
md5: string
|
|
51
|
-
}[] = [];
|
|
52
|
-
this.columns.map(c => {
|
|
53
|
-
const d = data[c.name];
|
|
54
|
-
if (c.data_type === "text" && d && isPlainObject(d) && !["from", "to"].find(key => typeof d[key] !== "number")) {
|
|
55
|
-
const unrecProps = Object.keys(d).filter(k => !["from", "to", "text", "md5"].includes(k));
|
|
56
|
-
if (unrecProps.length) throw "Unrecognised params in textPatch field: " + unrecProps.join(", ");
|
|
57
|
-
patchedTextData.push({ ...d, fieldName: c.name } as (typeof patchedTextData)[number]);
|
|
58
|
-
}
|
|
47
|
+
const { data, allowedCols } = await prepareNewData({
|
|
48
|
+
row: newData,
|
|
49
|
+
forcedData,
|
|
50
|
+
allowedFields: fields,
|
|
51
|
+
tableRules,
|
|
52
|
+
fixIssues,
|
|
53
|
+
tableConfigurator: this.dboBuilder.prostgles.tableConfigurator,
|
|
54
|
+
tableHandler: this,
|
|
59
55
|
});
|
|
60
56
|
|
|
61
|
-
if (patchedTextData?.length) {
|
|
62
|
-
if (tableRules && !tableRules.select) throw "Select needs to be permitted to patch data";
|
|
63
|
-
const rows = await this.find(filter, { select: patchedTextData.reduce((a, v) => ({ ...a, [v.fieldName]: 1 }), {}) }, undefined, tableRules);
|
|
64
|
-
|
|
65
|
-
if (rows.length !== 1) {
|
|
66
|
-
throw "Cannot patch data within a filter that affects more/less than 1 row";
|
|
67
|
-
}
|
|
68
|
-
patchedTextData.map(p => {
|
|
69
|
-
data[p.fieldName] = unpatchText(rows[0][p.fieldName], p);
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const nData = { ...data };
|
|
74
57
|
const updateFilter = await this.prepareWhere({
|
|
75
58
|
filter,
|
|
76
59
|
forcedFilter,
|
|
@@ -78,8 +61,12 @@ export async function update(this: TableHandler, filter: Filter, _newData: AnyOb
|
|
|
78
61
|
localParams,
|
|
79
62
|
tableRule: tableRules
|
|
80
63
|
})
|
|
81
|
-
|
|
82
|
-
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Nested inserts
|
|
67
|
+
*/
|
|
68
|
+
const nData = { ...data };
|
|
69
|
+
const nestedInserts = getReferenceColumnInserts(this, nData, true);
|
|
83
70
|
const nestedInsertsResultsObj: Record<string, any> = {};
|
|
84
71
|
if(nestedInserts.length){
|
|
85
72
|
const updateCount = await this.count(updateFilter.filter);
|
|
@@ -105,7 +92,8 @@ export async function update(this: TableHandler, filter: Filter, _newData: AnyOb
|
|
|
105
92
|
}));
|
|
106
93
|
}
|
|
107
94
|
|
|
108
|
-
let query = await this.colSet.getUpdateQuery(nData, allowedCols, this.getFinalDbo(localParams), validateRow, localParams)
|
|
95
|
+
// let query = await this.colSet.getUpdateQuery(nData, allowedCols, this.getFinalDbo(localParams), validateRow, localParams)
|
|
96
|
+
let query = (await this.dataValidator.parse({ command: "update", rows: [nData], allowedCols, dbTx: this.getFinalDbo(localParams), validationOptions: { validate: validateRow, localParams }})).getQuery()
|
|
109
97
|
query += "\n" + updateFilter.where;
|
|
110
98
|
if (onConflict === "DoNothing") query += " ON CONFLICT DO NOTHING ";
|
|
111
99
|
if(onConflict === "DoUpdate"){
|
|
@@ -12,18 +12,18 @@ export async function updateBatch(this: TableHandler, updates: [Filter, AnyObjec
|
|
|
12
12
|
throw `updateBatch not allowed for tables with checkFilter or postValidate rules`
|
|
13
13
|
}
|
|
14
14
|
const updateQueries: string[] = await Promise.all(
|
|
15
|
-
updates.map(async ([filter, data]) => {
|
|
15
|
+
updates.map(async ([filter, data]) => {
|
|
16
16
|
const query = (await this.update(
|
|
17
17
|
filter,
|
|
18
18
|
data,
|
|
19
|
-
{ ...(params
|
|
19
|
+
{ ...(params ?? {}), returning: undefined },
|
|
20
20
|
tableRules,
|
|
21
|
-
{ ...(localParams
|
|
21
|
+
{ ...(localParams ?? {}), returnQuery: "noRLS" }
|
|
22
22
|
)) as unknown as string;
|
|
23
23
|
|
|
24
24
|
return query;
|
|
25
25
|
})
|
|
26
|
-
);
|
|
26
|
+
);
|
|
27
27
|
const queries = [
|
|
28
28
|
withUserRLS(localParams, ""),
|
|
29
29
|
...updateQueries
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { AnyObject, getKeys, isObject } from "prostgles-types";
|
|
2
2
|
import { LocalParams, Media } from "../DboBuilder";
|
|
3
|
-
import { TableRule, ValidateRow } from "../../PublishParser/PublishParser";
|
|
3
|
+
import { TableRule, ValidateRow, ValidateRowBasic } from "../../PublishParser/PublishParser";
|
|
4
4
|
import { omitKeys } from "../../PubSubManager/PubSubManager";
|
|
5
5
|
import { isFile, uploadFile } from "../uploadFile";
|
|
6
6
|
import { TableHandler } from "./TableHandler";
|
|
7
|
+
import { DBOFullyTyped } from "../../DBSchemaBuilder";
|
|
7
8
|
|
|
8
9
|
type Args = {
|
|
9
10
|
newData: AnyObject;
|
|
@@ -32,8 +33,8 @@ export const updateFile = async function(this: TableHandler, { filter, newData,
|
|
|
32
33
|
const fileManager = this.dboBuilder.prostgles.fileManager
|
|
33
34
|
if(!fileManager) throw new Error("fileManager missing");
|
|
34
35
|
if(rule?.validate && !localParams) throw new Error("localParams missing");
|
|
35
|
-
const validate:
|
|
36
|
-
return rule.validate!({ update: row, filter, dbx: this.tx?.dbTX || this.dboBuilder.dbo, localParams: localParams! })
|
|
36
|
+
const validate: ValidateRowBasic | undefined = rule?.validate? async (row) => {
|
|
37
|
+
return rule.validate!({ update: row, filter, dbx: (this.tx?.dbTX || this.dboBuilder.dbo) as any, localParams: localParams! })
|
|
37
38
|
} : undefined;
|
|
38
39
|
|
|
39
40
|
const existingFile: Media | undefined = await (localParams?.tx?.dbTX?.[this.name] as TableHandler || this).findOne({ id: existingMediaId });
|
|
@@ -25,7 +25,6 @@ import { asNameAlias } from "../QueryBuilder/QueryBuilder";
|
|
|
25
25
|
import { find } from "../find";
|
|
26
26
|
import { getColumns } from "../getColumns";
|
|
27
27
|
import { LocalFuncs, subscribe } from "../subscribe";
|
|
28
|
-
import { ColSet } from "./ColSet";
|
|
29
28
|
import { getInfo } from "./getInfo";
|
|
30
29
|
import { parseFieldFilter } from "./parseFieldFilter";
|
|
31
30
|
import { prepareWhere } from "./prepareWhere";
|
|
@@ -46,7 +45,6 @@ export class ViewHandler {
|
|
|
46
45
|
columnsForTypes: ColumnInfo[];
|
|
47
46
|
column_names: string[];
|
|
48
47
|
tableOrViewInfo: TableSchema;// TableOrViewInfo;
|
|
49
|
-
colSet: ColSet;
|
|
50
48
|
tsColumnDefs: string[] = [];
|
|
51
49
|
joins: Join[];
|
|
52
50
|
joinGraph?: Graph;
|
|
@@ -74,16 +72,13 @@ export class ViewHandler {
|
|
|
74
72
|
this.name = tableOrViewInfo.escaped_identifier;
|
|
75
73
|
this.escapedName = tableOrViewInfo.escaped_identifier;
|
|
76
74
|
this.columns = tableOrViewInfo.columns;
|
|
77
|
-
|
|
78
75
|
/* cols are sorted by name to reduce .d.ts schema rewrites */
|
|
79
76
|
this.columnsForTypes = tableOrViewInfo.columns.slice(0).sort((a, b) => a.name.localeCompare(b.name));
|
|
80
77
|
|
|
81
78
|
this.column_names = tableOrViewInfo.columns.map(c => c.name);
|
|
82
79
|
|
|
83
80
|
this.dboBuilder = dboBuilder;
|
|
84
|
-
this.joins = this.dboBuilder.joins ?? [];
|
|
85
|
-
|
|
86
|
-
this.colSet = new ColSet(this.columns, this.name);
|
|
81
|
+
this.joins = this.dboBuilder.joins ?? [];
|
|
87
82
|
this.columnsForTypes.map(({ name, udt_name, is_nullable }) => {
|
|
88
83
|
this.tsColumnDefs.push(`${escapeTSNames(name)}?: ${postgresToTsType(udt_name) as string} ${is_nullable ? " | null " : ""};`);
|
|
89
84
|
});
|
|
@@ -456,54 +451,8 @@ export class ViewHandler {
|
|
|
456
451
|
return result;
|
|
457
452
|
}
|
|
458
453
|
|
|
459
|
-
/**
|
|
460
|
-
* Prepare and validate field object:
|
|
461
|
-
* @example ({ item_id: 1 }, { user_id: 32 }) => { item_id: 1, user_id: 32 }
|
|
462
|
-
* OR
|
|
463
|
-
* ({ a: 1 }, { b: 32 }, ["c", "d"]) => throw "a field is not allowed"
|
|
464
|
-
* @param {Object} obj - initial data
|
|
465
|
-
* @param {Object} forcedData - set/override property
|
|
466
|
-
* @param {string[]} allowed_cols - allowed columns (excluding forcedData) from table rules
|
|
467
|
-
*/
|
|
468
|
-
prepareFieldValues(obj: AnyObject = {}, forcedData: AnyObject = {}, allowed_cols: FieldFilter | undefined, removeDisallowedColumns = false): AnyObject {
|
|
469
|
-
const column_names = this.column_names.slice(0);
|
|
470
|
-
if (!column_names?.length) {
|
|
471
|
-
throw "table column_names mising";
|
|
472
|
-
}
|
|
473
|
-
let _allowed_cols = column_names.slice(0);
|
|
474
|
-
const _obj = { ...obj };
|
|
475
|
-
|
|
476
|
-
if (allowed_cols) {
|
|
477
|
-
_allowed_cols = this.parseFieldFilter(allowed_cols, false);
|
|
478
|
-
}
|
|
479
|
-
let final_filter = { ..._obj };
|
|
480
|
-
const filter_keys: Array<keyof typeof final_filter> = Object.keys(final_filter);
|
|
481
|
-
|
|
482
|
-
if (removeDisallowedColumns && filter_keys.length) {
|
|
483
|
-
final_filter = {};
|
|
484
|
-
filter_keys
|
|
485
|
-
.filter(col => _allowed_cols.includes(col))
|
|
486
|
-
.map(col => {
|
|
487
|
-
final_filter[col] = _obj[col];
|
|
488
|
-
});
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
/* If has keys check against allowed_cols */
|
|
492
|
-
if (final_filter && Object.keys(final_filter).length && _allowed_cols) {
|
|
493
|
-
validateObj(final_filter, _allowed_cols)
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
if (forcedData && Object.keys(forcedData).length) {
|
|
497
|
-
final_filter = { ...final_filter, ...forcedData };
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
validateObj(final_filter, column_names.slice(0));
|
|
501
|
-
return final_filter;
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
|
|
505
454
|
parseFieldFilter(fieldParams: FieldFilter = "*", allow_empty = true, allowed_cols?: string[]): string[] {
|
|
506
|
-
return parseFieldFilter(fieldParams, allow_empty, allowed_cols
|
|
455
|
+
return parseFieldFilter(fieldParams, allow_empty, allowed_cols ?? this.column_names.slice(0))
|
|
507
456
|
}
|
|
508
457
|
|
|
509
458
|
}
|
|
@@ -512,7 +461,7 @@ export class ViewHandler {
|
|
|
512
461
|
/**
|
|
513
462
|
* Throw error if illegal keys found in object
|
|
514
463
|
*/
|
|
515
|
-
|
|
464
|
+
export const validateObj = <T extends Record<string, any>>(obj: T, allowedKeys: string[]): T => {
|
|
516
465
|
if (obj && Object.keys(obj).length) {
|
|
517
466
|
const invalid_keys = Object.keys(obj).filter(k => !allowedKeys.includes(k));
|
|
518
467
|
if (invalid_keys.length) {
|
|
@@ -154,7 +154,10 @@ export const getConstraints = async (db: DB, schema: ProstglesInitOptions["schem
|
|
|
154
154
|
`, { schemaNames });
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
-
|
|
157
|
+
/**
|
|
158
|
+
* @deprecated
|
|
159
|
+
* use isObject
|
|
160
|
+
*/
|
|
158
161
|
export function isPlainObject(o: any): o is Record<string, any> {
|
|
159
162
|
return Object(o) === o && Object.getPrototypeOf(o) === Object.prototype;
|
|
160
163
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AnyObject, PG_COLUMN_UDT_DATA_TYPE,
|
|
3
|
-
ValidatedColumnInfo, _PG_geometric
|
|
3
|
+
ValidatedColumnInfo, _PG_geometric, isObject
|
|
4
4
|
} from "prostgles-types";
|
|
5
5
|
import { isPlainObject, LocalParams, parseError, postgresToTsType } from "./DboBuilder";
|
|
6
6
|
import { TableRule } from "../PublishParser/PublishParser";
|
|
@@ -29,19 +29,18 @@ export async function getColumns(
|
|
|
29
29
|
|
|
30
30
|
if (params && tableRules && isTableHandler(this)) {
|
|
31
31
|
if (
|
|
32
|
-
!
|
|
33
|
-
|
|
34
|
-
!isPlainObject(params.filter) ||
|
|
32
|
+
!isObject(params) ||
|
|
33
|
+
!isObject(params.filter) ||
|
|
35
34
|
params.rule !== "update"
|
|
36
35
|
) {
|
|
37
|
-
throw "params must be { rule: 'update', filter: object
|
|
36
|
+
throw "params must be { rule: 'update', filter: object } but received: " + JSON.stringify(params);
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
if (!tableRules?.update) {
|
|
41
40
|
dynamicUpdateFields = [];
|
|
42
41
|
} else {
|
|
43
|
-
const {
|
|
44
|
-
const updateRules = await this.parseUpdateRules(filter,
|
|
42
|
+
const { filter } = params;
|
|
43
|
+
const updateRules = await this.parseUpdateRules(filter, undefined, tableRules, localParams);
|
|
45
44
|
dynamicUpdateFields = updateRules.fields;
|
|
46
45
|
}
|
|
47
46
|
}
|
|
@@ -1,36 +1,43 @@
|
|
|
1
|
-
import { AnyObject, getKeys, InsertParams, isDefined, isObject
|
|
1
|
+
import { AnyObject, getKeys, InsertParams, isDefined, isObject } from "prostgles-types";
|
|
2
2
|
import { LocalParams, TableHandlers } from "./DboBuilder";
|
|
3
3
|
import { TableRule } from "../PublishParser/PublishParser";
|
|
4
4
|
import { omitKeys } from "../PubSubManager/PubSubManager";
|
|
5
5
|
import { TableHandler } from "./TableHandler/TableHandler";
|
|
6
6
|
|
|
7
|
+
type InsertNestedRecordsArgs = {
|
|
8
|
+
data: (AnyObject | AnyObject[]);
|
|
9
|
+
param2?: InsertParams;
|
|
10
|
+
tableRules?: TableRule;
|
|
11
|
+
localParams?: LocalParams;
|
|
12
|
+
};
|
|
13
|
+
|
|
7
14
|
/**
|
|
8
15
|
* Referenced inserts within a single transaction
|
|
9
16
|
*/
|
|
10
|
-
export async function
|
|
17
|
+
export async function insertNestedRecords(
|
|
11
18
|
this: TableHandler,
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
19
|
+
{
|
|
20
|
+
data,
|
|
21
|
+
param2,
|
|
22
|
+
tableRules,
|
|
23
|
+
localParams = {},
|
|
24
|
+
}: InsertNestedRecordsArgs
|
|
17
25
|
): Promise<{
|
|
18
26
|
data?: AnyObject | AnyObject[];
|
|
19
27
|
insertResult?: AnyObject | AnyObject[];
|
|
20
|
-
}> {
|
|
21
|
-
const localParams = _localParams || {};
|
|
28
|
+
}> {
|
|
22
29
|
const MEDIA_COL_NAMES = ["data", "name"];
|
|
23
30
|
|
|
24
|
-
const
|
|
25
|
-
const getExtraKeys = (d: AnyObject) => getKeys(d).filter(k => {
|
|
31
|
+
const getExtraKeys = (row: AnyObject) => getKeys(row).filter(fieldName => {
|
|
26
32
|
/* If media then use file insert columns */
|
|
27
33
|
if (this.is_media) {
|
|
28
|
-
return !this.column_names.concat(MEDIA_COL_NAMES).includes(
|
|
29
|
-
} else if (!this.columns.find(c => c.name ===
|
|
30
|
-
if (!isObject(
|
|
31
|
-
throw new Error("Invalid/Dissalowed field in data: " +
|
|
32
|
-
} else if (!this.dboBuilder.dbo[
|
|
33
|
-
|
|
34
|
+
return !this.column_names.concat(MEDIA_COL_NAMES).includes(fieldName)
|
|
35
|
+
} else if (!this.columns.find(c => c.name === fieldName)) {
|
|
36
|
+
if (!isObject(row[fieldName]) && !Array.isArray(row[fieldName])) {
|
|
37
|
+
throw new Error("Invalid/Dissalowed field in data: " + fieldName)
|
|
38
|
+
} else if (!this.dboBuilder.dbo[fieldName]) {
|
|
39
|
+
return false;
|
|
40
|
+
// throw new Error("Invalid/Dissalowed nested insert table name in data: " + fieldName)
|
|
34
41
|
}
|
|
35
42
|
return true;
|
|
36
43
|
}
|
|
@@ -46,7 +53,8 @@ export async function insertDataParse(
|
|
|
46
53
|
* If true then will do the full insert within this function
|
|
47
54
|
* Nested insert is not allowed for the file table
|
|
48
55
|
* */
|
|
49
|
-
const
|
|
56
|
+
const isMultiInsert = Array.isArray(data);
|
|
57
|
+
const hasNestedInserts = this.is_media ? false : (isMultiInsert ? data : [data]).some(d => getExtraKeys(d).length || getReferenceColumnInserts(this, d).length);
|
|
50
58
|
|
|
51
59
|
/**
|
|
52
60
|
* Make sure nested insert uses a transaction
|
|
@@ -59,36 +67,34 @@ export async function insertDataParse(
|
|
|
59
67
|
(dbTX[this.name] as TableHandler).insert(
|
|
60
68
|
data,
|
|
61
69
|
param2,
|
|
62
|
-
|
|
70
|
+
undefined,
|
|
63
71
|
tableRules,
|
|
64
72
|
{ tx: { dbTX, t: _t }, ...localParams }
|
|
65
73
|
)
|
|
66
74
|
)
|
|
67
75
|
}
|
|
68
76
|
}
|
|
77
|
+
|
|
69
78
|
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const extraKeys = getExtraKeys(row);
|
|
81
|
-
const colInserts = getReferenceColumnInserts.bind(this)(row);
|
|
79
|
+
const _data = await Promise.all((isMultiInsert ? data : [data]).map(async row => {
|
|
80
|
+
// const { preValidate, validate } = tableRules?.insert ?? {};
|
|
81
|
+
// const { tableConfigurator } = this.dboBuilder.prostgles;
|
|
82
|
+
// if(!tableConfigurator) throw "tableConfigurator missing";
|
|
83
|
+
// let row = await tableConfigurator.getPreInsertRow(this, { dbx: this.getFinalDbo(localParams), validate, localParams, row: _row })
|
|
84
|
+
// if (preValidate) {
|
|
85
|
+
// row = await preValidate({ row, dbx: this.tx?.dbTX || this.dboBuilder.dbo, localParams });
|
|
86
|
+
// }
|
|
82
87
|
|
|
83
88
|
/* Potentially a nested join */
|
|
84
89
|
if (hasNestedInserts) {
|
|
85
|
-
|
|
90
|
+
const extraKeys = getExtraKeys(row);
|
|
91
|
+
const colInserts = getReferenceColumnInserts(this, row);
|
|
92
|
+
|
|
86
93
|
/* Ensure we're using the same transaction */
|
|
87
94
|
const _this = this.tx ? this : dbTX![this.name] as TableHandler;
|
|
88
95
|
|
|
89
96
|
const omitedKeys = extraKeys.concat(colInserts.map(c => c.col));
|
|
90
97
|
|
|
91
|
-
// let rootData = isMultiInsert? data.map(d => omitKeys(d, omitedKeys)) : omitKeys(data, omitedKeys);
|
|
92
98
|
const rootData: AnyObject = omitKeys(row, omitedKeys);
|
|
93
99
|
|
|
94
100
|
let insertedChildren: AnyObject[];
|
|
@@ -204,7 +210,6 @@ export async function insertDataParse(
|
|
|
204
210
|
colsRefT1.map(col => {
|
|
205
211
|
tbl2Row[col.name] = fullRootResult[col.references![0]!.fcols[0]!];
|
|
206
212
|
})
|
|
207
|
-
// console.log({ rootResult, tbl2Row, t3Child, colsRefT3, colsRefT1, t: this.t?.ctx?.start });
|
|
208
213
|
|
|
209
214
|
await childInsert(tbl2Row, tbl2!);//.then(() => {});
|
|
210
215
|
}));
|
|
@@ -286,17 +291,21 @@ const referencedInsert = async (tableHandler: TableHandler, dbTX: TableHandlers
|
|
|
286
291
|
.map(m => (dbTX![targetTable] as TableHandler)
|
|
287
292
|
.insert(m, { returning: "*" }, undefined, childRules, localParams)
|
|
288
293
|
.catch(e => {
|
|
289
|
-
|
|
290
|
-
return Promise.reject(e);
|
|
291
|
-
// return Promise.reject({ childInsertErr: e });
|
|
294
|
+
return Promise.reject(e);
|
|
292
295
|
})
|
|
293
296
|
)
|
|
294
297
|
);
|
|
295
298
|
|
|
296
299
|
}
|
|
297
300
|
|
|
301
|
+
type ReferenceColumnInsert<ExpectSingleInsert> = {
|
|
302
|
+
tableName: string;
|
|
303
|
+
col: string;
|
|
304
|
+
fcol: string;
|
|
305
|
+
singleInsert: boolean;
|
|
306
|
+
data: ExpectSingleInsert extends true? AnyObject : (AnyObject | AnyObject[]);
|
|
307
|
+
}
|
|
298
308
|
|
|
299
|
-
// const ALLOWED_COL_TYPES: PG_COLUMN_UDT_DATA_TYPE[] = ["int2", "int4", "int8", "numeric", "uuid", "text", "varchar", "char"];
|
|
300
309
|
/**
|
|
301
310
|
* Insert through the reference column. e.g.:
|
|
302
311
|
* {
|
|
@@ -304,16 +313,15 @@ const referencedInsert = async (tableHandler: TableHandler, dbTX: TableHandlers
|
|
|
304
313
|
* fkey_column: { ...referenced_table_data }
|
|
305
314
|
* }
|
|
306
315
|
*/
|
|
307
|
-
export const getReferenceColumnInserts =
|
|
308
|
-
return
|
|
309
|
-
.map(
|
|
310
|
-
if(
|
|
311
|
-
const insertedRefCol =
|
|
312
|
-
if(insertedRefCol
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
}
|
|
316
|
+
export const getReferenceColumnInserts = <ExpectSingleInsert extends boolean>(tableHandler: TableHandler, parentRow: AnyObject, expectSingleInsert?: ExpectSingleInsert): ReferenceColumnInsert<ExpectSingleInsert>[] => {
|
|
317
|
+
return Object.entries(parentRow)
|
|
318
|
+
.map(([insertedFieldName, insertedFieldValue]) => {
|
|
319
|
+
if(insertedFieldValue && isObject(insertedFieldValue)){
|
|
320
|
+
const insertedRefCol = tableHandler.columns.find(c => c.name === insertedFieldName && c.references?.length);
|
|
321
|
+
if(!insertedRefCol) return undefined;
|
|
322
|
+
return {
|
|
323
|
+
insertedRefCol,
|
|
324
|
+
insertedRefColRef: insertedRefCol.references!
|
|
317
325
|
}
|
|
318
326
|
}
|
|
319
327
|
|
|
@@ -335,12 +343,13 @@ export const getReferenceColumnInserts = function(this: TableHandler, parentRow:
|
|
|
335
343
|
if(expectSingleInsert && !singleInsert){
|
|
336
344
|
throw "Expected singleInsert";
|
|
337
345
|
}
|
|
338
|
-
|
|
346
|
+
const res = {
|
|
339
347
|
tableName: insertedRefCol.references![0]!.ftable!,
|
|
340
348
|
col: insertedRefCol.name,
|
|
341
349
|
fcol: insertedRefCol.references![0]!.fcols[0]!,
|
|
342
350
|
singleInsert,
|
|
343
351
|
data: parentRow[insertedRefCol.name],
|
|
344
352
|
}
|
|
353
|
+
return res;
|
|
345
354
|
}).filter(isDefined);
|
|
346
355
|
}
|