@ruiapp/rapid-core 0.1.71 → 0.1.73
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/dataAccess/dataAccessTypes.d.ts +11 -0
- package/dist/dataAccess/propertyMapper.d.ts +3 -2
- package/dist/helpers/metaHelper.d.ts +1 -0
- package/dist/index.js +138 -52
- package/dist/queryBuilder/queryBuilder.d.ts +2 -1
- package/package.json +1 -1
- package/src/dataAccess/dataAccessTypes.ts +122 -109
- package/src/dataAccess/entityManager.ts +1342 -1298
- package/src/dataAccess/propertyMapper.ts +28 -27
- package/src/helpers/metaHelper.ts +13 -0
- package/src/plugins/fileManage/actionHandlers/downloadFile.ts +33 -28
- package/src/queryBuilder/queryBuilder.ts +512 -473
|
@@ -10,6 +10,7 @@ export type ColumnSelectOptions = string | ColumnNameWithTableName;
|
|
|
10
10
|
export type ColumnNameWithTableName = {
|
|
11
11
|
name: string;
|
|
12
12
|
tableName?: string;
|
|
13
|
+
schema?: string;
|
|
13
14
|
};
|
|
14
15
|
export interface FindRowOptions {
|
|
15
16
|
filters?: RowFilterOptions[];
|
|
@@ -48,8 +49,18 @@ export interface FindRowPaginationOptions {
|
|
|
48
49
|
withoutTotal?: boolean;
|
|
49
50
|
}
|
|
50
51
|
export interface FindRowOrderByOptions {
|
|
52
|
+
/**
|
|
53
|
+
* 排序字段
|
|
54
|
+
*/
|
|
51
55
|
field: ColumnSelectOptions;
|
|
56
|
+
/**
|
|
57
|
+
* 是否倒序
|
|
58
|
+
*/
|
|
52
59
|
desc?: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* 关系字段
|
|
62
|
+
*/
|
|
63
|
+
relationField?: ColumnNameWithTableName;
|
|
53
64
|
}
|
|
54
65
|
export interface CountRowOptions {
|
|
55
66
|
filters?: RowFilterOptions[];
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { RpdDataModel } from "../types";
|
|
2
|
-
|
|
3
|
-
export declare function
|
|
2
|
+
import { IRpdServer } from "../core/server";
|
|
3
|
+
export declare function mapPropertyNameToColumnName(server: IRpdServer, model: RpdDataModel, propertyName: string): string;
|
|
4
|
+
export declare function mapPropertyNamesToColumnNames(server: IRpdServer, model: RpdDataModel, propertyNames: string[]): string[];
|
|
@@ -7,3 +7,4 @@ export declare function getEntityProperties(server: IRpdServer, model: RpdDataMo
|
|
|
7
7
|
export declare function getEntityPropertiesIncludingBase(server: IRpdServer, model: RpdDataModel): RpdDataModelProperty[];
|
|
8
8
|
export declare function getEntityPropertyByCode(server: IRpdServer, model: RpdDataModel, propertyCode: string): RpdDataModelProperty;
|
|
9
9
|
export declare function getEntityProperty(server: IRpdServer, model: RpdDataModel, predicate: (item: RpdDataModelProperty) => boolean): RpdDataModelProperty;
|
|
10
|
+
export declare function getEntityPropertyByFieldName(server: IRpdServer, model: RpdDataModel, fieldName: string): RpdDataModelProperty;
|
package/dist/index.js
CHANGED
|
@@ -212,33 +212,50 @@ class QueryBuilder {
|
|
|
212
212
|
quoteObject(name) {
|
|
213
213
|
return `${objLeftQuoteChar}${name}${objRightQuoteChar}`;
|
|
214
214
|
}
|
|
215
|
-
quoteColumn(column, emitTableAlias) {
|
|
215
|
+
quoteColumn(model, column, emitTableAlias) {
|
|
216
216
|
if (typeof column === "string") {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
217
|
+
if (emitTableAlias) {
|
|
218
|
+
return `${objLeftQuoteChar}${model.tableName}${objRightQuoteChar}.${objLeftQuoteChar}${column}${objRightQuoteChar}`;
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
return `${objLeftQuoteChar}${column}${objRightQuoteChar}`;
|
|
222
|
+
}
|
|
221
223
|
}
|
|
222
224
|
else {
|
|
223
|
-
|
|
225
|
+
if (emitTableAlias && column.tableName) {
|
|
226
|
+
return `${objLeftQuoteChar}${column.tableName}${objRightQuoteChar}.${objLeftQuoteChar}${column.name}${objRightQuoteChar}`;
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
return `${objLeftQuoteChar}${column.name}${objRightQuoteChar}`;
|
|
230
|
+
}
|
|
224
231
|
}
|
|
225
232
|
}
|
|
226
233
|
select(model, options) {
|
|
227
234
|
const ctx = {
|
|
235
|
+
model,
|
|
228
236
|
builder: this,
|
|
229
237
|
params: [],
|
|
230
|
-
emitTableAlias:
|
|
238
|
+
emitTableAlias: true,
|
|
231
239
|
};
|
|
232
240
|
let { fields: columns, filters, orderBy, pagination } = options;
|
|
233
241
|
let command = "SELECT ";
|
|
234
242
|
if (!columns || !columns.length) {
|
|
235
|
-
command +=
|
|
243
|
+
command += `${this.quoteObject(model.tableName)}.* FROM `;
|
|
236
244
|
}
|
|
237
245
|
else {
|
|
238
|
-
command += columns.map((column) => this.quoteColumn(column, ctx.emitTableAlias)).join(", ");
|
|
246
|
+
command += columns.map((column) => this.quoteColumn(ctx.model, column, ctx.emitTableAlias)).join(", ");
|
|
239
247
|
command += " FROM ";
|
|
240
248
|
}
|
|
241
249
|
command += this.quoteTable(model);
|
|
250
|
+
if (options.orderBy) {
|
|
251
|
+
options.orderBy
|
|
252
|
+
.filter((orderByItem) => orderByItem.relationField)
|
|
253
|
+
.forEach((orderByItem) => {
|
|
254
|
+
const { relationField } = orderByItem;
|
|
255
|
+
const orderField = orderByItem.field;
|
|
256
|
+
command += ` LEFT JOIN ${this.quoteTable({ schema: orderField.schema, tableName: orderField.tableName })} ON ${this.quoteObject(orderField.tableName)}.id = ${this.quoteObject(relationField.tableName)}.${this.quoteObject(relationField.name)}`;
|
|
257
|
+
});
|
|
258
|
+
}
|
|
242
259
|
if (filters && filters.length) {
|
|
243
260
|
command += " WHERE ";
|
|
244
261
|
command += buildFiltersQuery(ctx, filters);
|
|
@@ -247,7 +264,7 @@ class QueryBuilder {
|
|
|
247
264
|
command += " ORDER BY ";
|
|
248
265
|
command += orderBy
|
|
249
266
|
.map((item) => {
|
|
250
|
-
const quotedName = this.quoteColumn(item.field, ctx.emitTableAlias);
|
|
267
|
+
const quotedName = this.quoteColumn(ctx.model, item.field, ctx.emitTableAlias);
|
|
251
268
|
return item.desc ? quotedName + " DESC" : quotedName;
|
|
252
269
|
})
|
|
253
270
|
.join(", ");
|
|
@@ -267,6 +284,7 @@ class QueryBuilder {
|
|
|
267
284
|
}
|
|
268
285
|
selectDerived(derivedModel, baseModel, options) {
|
|
269
286
|
const ctx = {
|
|
287
|
+
model: derivedModel,
|
|
270
288
|
builder: this,
|
|
271
289
|
params: [],
|
|
272
290
|
emitTableAlias: true,
|
|
@@ -279,12 +297,21 @@ class QueryBuilder {
|
|
|
279
297
|
else {
|
|
280
298
|
command += columns
|
|
281
299
|
.map((column) => {
|
|
282
|
-
return this.quoteColumn(column, ctx.emitTableAlias);
|
|
300
|
+
return this.quoteColumn(derivedModel, column, ctx.emitTableAlias);
|
|
283
301
|
})
|
|
284
302
|
.join(", ");
|
|
285
303
|
command += " FROM ";
|
|
286
304
|
}
|
|
287
305
|
command += `${this.quoteTable(derivedModel)} LEFT JOIN ${this.quoteTable(baseModel)} ON ${this.quoteObject(derivedModel.tableName)}.id = ${this.quoteObject(baseModel.tableName)}.id`;
|
|
306
|
+
if (options.orderBy) {
|
|
307
|
+
options.orderBy
|
|
308
|
+
.filter((orderByItem) => orderByItem.relationField)
|
|
309
|
+
.forEach((orderByItem) => {
|
|
310
|
+
const { relationField } = orderByItem;
|
|
311
|
+
const orderField = orderByItem.field;
|
|
312
|
+
command += ` LEFT JOIN ${this.quoteTable({ schema: orderField.schema, tableName: orderField.tableName })} ON ${this.quoteObject(orderField.tableName)}.id = ${this.quoteObject(relationField.tableName)}.${this.quoteObject(relationField.name)}`;
|
|
313
|
+
});
|
|
314
|
+
}
|
|
288
315
|
if (filters && filters.length) {
|
|
289
316
|
command += " WHERE ";
|
|
290
317
|
command += buildFiltersQuery(ctx, filters);
|
|
@@ -293,7 +320,7 @@ class QueryBuilder {
|
|
|
293
320
|
command += " ORDER BY ";
|
|
294
321
|
command += orderBy
|
|
295
322
|
.map((item) => {
|
|
296
|
-
const quotedName = this.quoteColumn(item.field, ctx.emitTableAlias);
|
|
323
|
+
const quotedName = this.quoteColumn(derivedModel, item.field, ctx.emitTableAlias);
|
|
297
324
|
return item.desc ? quotedName + " DESC" : quotedName;
|
|
298
325
|
})
|
|
299
326
|
.join(", ");
|
|
@@ -313,6 +340,7 @@ class QueryBuilder {
|
|
|
313
340
|
}
|
|
314
341
|
count(model, options) {
|
|
315
342
|
const ctx = {
|
|
343
|
+
model,
|
|
316
344
|
builder: this,
|
|
317
345
|
params: [],
|
|
318
346
|
emitTableAlias: false,
|
|
@@ -331,6 +359,7 @@ class QueryBuilder {
|
|
|
331
359
|
}
|
|
332
360
|
countDerived(derivedModel, baseModel, options) {
|
|
333
361
|
const ctx = {
|
|
362
|
+
model: derivedModel,
|
|
334
363
|
builder: this,
|
|
335
364
|
params: [],
|
|
336
365
|
emitTableAlias: true,
|
|
@@ -350,6 +379,7 @@ class QueryBuilder {
|
|
|
350
379
|
insert(model, options) {
|
|
351
380
|
const params = [];
|
|
352
381
|
const ctx = {
|
|
382
|
+
model,
|
|
353
383
|
builder: this,
|
|
354
384
|
params,
|
|
355
385
|
emitTableAlias: false,
|
|
@@ -386,6 +416,7 @@ class QueryBuilder {
|
|
|
386
416
|
update(model, options) {
|
|
387
417
|
const params = [];
|
|
388
418
|
const ctx = {
|
|
419
|
+
model,
|
|
389
420
|
builder: this,
|
|
390
421
|
params,
|
|
391
422
|
emitTableAlias: false,
|
|
@@ -425,6 +456,7 @@ class QueryBuilder {
|
|
|
425
456
|
delete(model, options) {
|
|
426
457
|
const params = [];
|
|
427
458
|
const ctx = {
|
|
459
|
+
model,
|
|
428
460
|
builder: this,
|
|
429
461
|
params,
|
|
430
462
|
emitTableAlias: false,
|
|
@@ -499,7 +531,7 @@ function buildLogicalFilterQuery(level, ctx, filter) {
|
|
|
499
531
|
return command;
|
|
500
532
|
}
|
|
501
533
|
function buildUnaryFilterQuery(ctx, filter) {
|
|
502
|
-
let command = ctx.builder.quoteColumn(filter.field, ctx.emitTableAlias);
|
|
534
|
+
let command = ctx.builder.quoteColumn(ctx.model, filter.field, ctx.emitTableAlias);
|
|
503
535
|
if (filter.operator === "null") {
|
|
504
536
|
command += " IS NULL";
|
|
505
537
|
}
|
|
@@ -509,7 +541,7 @@ function buildUnaryFilterQuery(ctx, filter) {
|
|
|
509
541
|
return command;
|
|
510
542
|
}
|
|
511
543
|
function buildInFilterQuery(ctx, filter) {
|
|
512
|
-
let command = ctx.builder.quoteColumn(filter.field, ctx.emitTableAlias);
|
|
544
|
+
let command = ctx.builder.quoteColumn(ctx.model, filter.field, ctx.emitTableAlias);
|
|
513
545
|
if (filter.operator === "in") {
|
|
514
546
|
command += " = ";
|
|
515
547
|
}
|
|
@@ -521,49 +553,49 @@ function buildInFilterQuery(ctx, filter) {
|
|
|
521
553
|
return command;
|
|
522
554
|
}
|
|
523
555
|
function buildContainsFilterQuery(ctx, filter) {
|
|
524
|
-
let command = ctx.builder.quoteColumn(filter.field, ctx.emitTableAlias);
|
|
556
|
+
let command = ctx.builder.quoteColumn(ctx.model, filter.field, ctx.emitTableAlias);
|
|
525
557
|
command += " LIKE ";
|
|
526
558
|
ctx.params.push(`%${filter.value}%`);
|
|
527
559
|
command += "$" + ctx.params.length;
|
|
528
560
|
return command;
|
|
529
561
|
}
|
|
530
562
|
function buildNotContainsFilterQuery(ctx, filter) {
|
|
531
|
-
let command = ctx.builder.quoteColumn(filter.field, ctx.emitTableAlias);
|
|
563
|
+
let command = ctx.builder.quoteColumn(ctx.model, filter.field, ctx.emitTableAlias);
|
|
532
564
|
command += " NOT LIKE ";
|
|
533
565
|
ctx.params.push(`%${filter.value}%`);
|
|
534
566
|
command += "$" + ctx.params.length;
|
|
535
567
|
return command;
|
|
536
568
|
}
|
|
537
569
|
function buildStartsWithFilterQuery(ctx, filter) {
|
|
538
|
-
let command = ctx.builder.quoteColumn(filter.field, ctx.emitTableAlias);
|
|
570
|
+
let command = ctx.builder.quoteColumn(ctx.model, filter.field, ctx.emitTableAlias);
|
|
539
571
|
command += " LIKE ";
|
|
540
572
|
ctx.params.push(`${filter.value}%`);
|
|
541
573
|
command += "$" + ctx.params.length;
|
|
542
574
|
return command;
|
|
543
575
|
}
|
|
544
576
|
function buildNotStartsWithFilterQuery(ctx, filter) {
|
|
545
|
-
let command = ctx.builder.quoteColumn(filter.field, ctx.emitTableAlias);
|
|
577
|
+
let command = ctx.builder.quoteColumn(ctx.model, filter.field, ctx.emitTableAlias);
|
|
546
578
|
command += " NOT LIKE ";
|
|
547
579
|
ctx.params.push(`${filter.value}%`);
|
|
548
580
|
command += "$" + ctx.params.length;
|
|
549
581
|
return command;
|
|
550
582
|
}
|
|
551
583
|
function buildEndsWithFilterQuery(ctx, filter) {
|
|
552
|
-
let command = ctx.builder.quoteColumn(filter.field, ctx.emitTableAlias);
|
|
584
|
+
let command = ctx.builder.quoteColumn(ctx.model, filter.field, ctx.emitTableAlias);
|
|
553
585
|
command += " LIKE ";
|
|
554
586
|
ctx.params.push(`%${filter.value}`);
|
|
555
587
|
command += "$" + ctx.params.length;
|
|
556
588
|
return command;
|
|
557
589
|
}
|
|
558
590
|
function buildNotEndsWithFilterQuery(ctx, filter) {
|
|
559
|
-
let command = ctx.builder.quoteColumn(filter.field, ctx.emitTableAlias);
|
|
591
|
+
let command = ctx.builder.quoteColumn(ctx.model, filter.field, ctx.emitTableAlias);
|
|
560
592
|
command += " NOT LIKE ";
|
|
561
593
|
ctx.params.push(`%${filter.value}`);
|
|
562
594
|
command += "$" + ctx.params.length;
|
|
563
595
|
return command;
|
|
564
596
|
}
|
|
565
597
|
function buildRelationalFilterQuery(ctx, filter) {
|
|
566
|
-
let command = ctx.builder.quoteColumn(filter.field, ctx.emitTableAlias);
|
|
598
|
+
let command = ctx.builder.quoteColumn(ctx.model, filter.field, ctx.emitTableAlias);
|
|
567
599
|
command += relationalOperatorsMap.get(filter.operator);
|
|
568
600
|
ctx.params.push(filter.value);
|
|
569
601
|
command += "$" + ctx.params.length;
|
|
@@ -1816,6 +1848,9 @@ function isRelationProperty(property) {
|
|
|
1816
1848
|
function isOneRelationProperty(property) {
|
|
1817
1849
|
return isRelationProperty(property) && property.relation === "one";
|
|
1818
1850
|
}
|
|
1851
|
+
function isManyRelationProperty(property) {
|
|
1852
|
+
return isRelationProperty(property) && property.relation === "many";
|
|
1853
|
+
}
|
|
1819
1854
|
function getEntityPropertiesIncludingBase(server, model) {
|
|
1820
1855
|
if (!model.base) {
|
|
1821
1856
|
return model.properties;
|
|
@@ -1852,6 +1887,16 @@ function getEntityProperty(server, model, predicate) {
|
|
|
1852
1887
|
}
|
|
1853
1888
|
}
|
|
1854
1889
|
return property;
|
|
1890
|
+
}
|
|
1891
|
+
function getEntityPropertyByFieldName(server, model, fieldName) {
|
|
1892
|
+
let property = getEntityPropertyByCode(server, model, fieldName);
|
|
1893
|
+
if (!property) {
|
|
1894
|
+
property = getEntityProperty(server, model, (item) => item.relation === "one" && item.targetIdColumnName === fieldName);
|
|
1895
|
+
}
|
|
1896
|
+
if (!property) {
|
|
1897
|
+
property = getEntityProperty(server, model, (item) => item.columnName === fieldName);
|
|
1898
|
+
}
|
|
1899
|
+
return property;
|
|
1855
1900
|
}
|
|
1856
1901
|
|
|
1857
1902
|
// TODO Generate mapper and cache it.
|
|
@@ -1943,15 +1988,15 @@ function mapEntityToDbRow(server, model, entity) {
|
|
|
1943
1988
|
return result;
|
|
1944
1989
|
}
|
|
1945
1990
|
|
|
1946
|
-
function mapPropertyNameToColumnName(model, propertyName) {
|
|
1991
|
+
function mapPropertyNameToColumnName(server, model, propertyName) {
|
|
1947
1992
|
if (!model.properties) {
|
|
1948
1993
|
return propertyName;
|
|
1949
1994
|
}
|
|
1950
|
-
const property =
|
|
1995
|
+
const property = getEntityPropertyByCode(server, model, propertyName);
|
|
1951
1996
|
if (!property) {
|
|
1952
1997
|
return propertyName;
|
|
1953
1998
|
}
|
|
1954
|
-
if (
|
|
1999
|
+
if (isOneRelationProperty(property)) {
|
|
1955
2000
|
return property.targetIdColumnName;
|
|
1956
2001
|
}
|
|
1957
2002
|
return property.columnName || property.code;
|
|
@@ -2042,23 +2087,60 @@ function convertEntityOrderByToRowOrderBy(server, model, baseModel, orderByList)
|
|
|
2042
2087
|
return null;
|
|
2043
2088
|
}
|
|
2044
2089
|
return orderByList.map((orderBy) => {
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2090
|
+
const fields = orderBy.field.split(".");
|
|
2091
|
+
let orderField;
|
|
2092
|
+
let relationField;
|
|
2093
|
+
if (fields.length === 1) {
|
|
2094
|
+
orderField = fields[0];
|
|
2048
2095
|
}
|
|
2049
|
-
|
|
2050
|
-
|
|
2096
|
+
else {
|
|
2097
|
+
orderField = fields[1];
|
|
2098
|
+
relationField = fields[0];
|
|
2051
2099
|
}
|
|
2052
|
-
if (
|
|
2053
|
-
|
|
2100
|
+
if (relationField) {
|
|
2101
|
+
const relationProperty = getEntityPropertyByCode(server, model, relationField);
|
|
2102
|
+
if (!isRelationProperty(relationProperty)) {
|
|
2103
|
+
throw new Error("orderBy[].relation must be a one-relation property.");
|
|
2104
|
+
}
|
|
2105
|
+
if (isManyRelationProperty(relationProperty)) {
|
|
2106
|
+
throw new Error("orderBy[].relation must be a one-relation property.");
|
|
2107
|
+
}
|
|
2108
|
+
const relationModel = server.getModel({ singularCode: relationProperty.targetSingularCode });
|
|
2109
|
+
let relationBaseModel = null;
|
|
2110
|
+
if (relationModel.base) {
|
|
2111
|
+
relationBaseModel = server.getModel({ singularCode: relationModel.base });
|
|
2112
|
+
}
|
|
2113
|
+
let property = getEntityPropertyByFieldName(server, relationModel, orderField);
|
|
2114
|
+
if (!property) {
|
|
2115
|
+
throw new Error(`Unkown orderBy field '${orderField}' of relation '${relationField}'`);
|
|
2116
|
+
}
|
|
2117
|
+
return {
|
|
2118
|
+
field: {
|
|
2119
|
+
name: mapPropertyNameToColumnName(server, relationModel, orderField),
|
|
2120
|
+
tableName: property.isBaseProperty ? relationBaseModel.tableName : relationModel.tableName,
|
|
2121
|
+
schema: property.isBaseProperty ? relationBaseModel.schema : relationModel.schema,
|
|
2122
|
+
},
|
|
2123
|
+
relationField: {
|
|
2124
|
+
name: mapPropertyNameToColumnName(server, model, relationField),
|
|
2125
|
+
tableName: relationProperty.isBaseProperty ? baseModel.tableName : model.tableName,
|
|
2126
|
+
schema: relationProperty.isBaseProperty ? baseModel.schema : model.schema,
|
|
2127
|
+
},
|
|
2128
|
+
desc: !!orderBy.desc,
|
|
2129
|
+
};
|
|
2130
|
+
}
|
|
2131
|
+
else {
|
|
2132
|
+
let property = getEntityPropertyByFieldName(server, model, orderField);
|
|
2133
|
+
if (!property) {
|
|
2134
|
+
throw new Error(`Unkown orderBy field '${orderField}'`);
|
|
2135
|
+
}
|
|
2136
|
+
return {
|
|
2137
|
+
field: {
|
|
2138
|
+
name: mapPropertyNameToColumnName(server, model, orderField),
|
|
2139
|
+
tableName: property.isBaseProperty ? baseModel.tableName : model.tableName,
|
|
2140
|
+
},
|
|
2141
|
+
desc: !!orderBy.desc,
|
|
2142
|
+
};
|
|
2054
2143
|
}
|
|
2055
|
-
return {
|
|
2056
|
-
field: {
|
|
2057
|
-
name: mapPropertyNameToColumnName(model, orderBy.field),
|
|
2058
|
-
tableName: property.isBaseProperty ? baseModel.tableName : model.tableName,
|
|
2059
|
-
},
|
|
2060
|
-
desc: !!orderBy.desc,
|
|
2061
|
-
};
|
|
2062
2144
|
});
|
|
2063
2145
|
}
|
|
2064
2146
|
async function findEntities(server, dataAccessor, options) {
|
|
@@ -3099,11 +3181,11 @@ class EntityManager {
|
|
|
3099
3181
|
const command = `INSERT INTO ${queryBuilder.quoteTable({
|
|
3100
3182
|
schema: relationProperty.linkSchema,
|
|
3101
3183
|
tableName: relationProperty.linkTableName,
|
|
3102
|
-
})} (${queryBuilder.quoteObject(relationProperty.selfIdColumnName)}, ${queryBuilder.quoteObject(relationProperty.targetIdColumnName)})
|
|
3103
|
-
SELECT $1, $2 WHERE NOT EXISTS (
|
|
3104
|
-
SELECT ${queryBuilder.quoteObject(relationProperty.selfIdColumnName)}, ${queryBuilder.quoteObject(relationProperty.targetIdColumnName)}
|
|
3105
|
-
FROM ${queryBuilder.quoteTable({ schema: relationProperty.linkSchema, tableName: relationProperty.linkTableName })}
|
|
3106
|
-
WHERE ${queryBuilder.quoteObject(relationProperty.selfIdColumnName)}=$1 AND ${queryBuilder.quoteObject(relationProperty.targetIdColumnName)}=$2
|
|
3184
|
+
})} (${queryBuilder.quoteObject(relationProperty.selfIdColumnName)}, ${queryBuilder.quoteObject(relationProperty.targetIdColumnName)})
|
|
3185
|
+
SELECT $1, $2 WHERE NOT EXISTS (
|
|
3186
|
+
SELECT ${queryBuilder.quoteObject(relationProperty.selfIdColumnName)}, ${queryBuilder.quoteObject(relationProperty.targetIdColumnName)}
|
|
3187
|
+
FROM ${queryBuilder.quoteTable({ schema: relationProperty.linkSchema, tableName: relationProperty.linkTableName })}
|
|
3188
|
+
WHERE ${queryBuilder.quoteObject(relationProperty.selfIdColumnName)}=$1 AND ${queryBuilder.quoteObject(relationProperty.targetIdColumnName)}=$2
|
|
3107
3189
|
)`;
|
|
3108
3190
|
const params = [id, relation.id];
|
|
3109
3191
|
await server.queryDatabaseObject(command, params);
|
|
@@ -3143,7 +3225,7 @@ class EntityManager {
|
|
|
3143
3225
|
const { queryBuilder } = server;
|
|
3144
3226
|
if (relationProperty.linkTableName) {
|
|
3145
3227
|
for (const relation of relations) {
|
|
3146
|
-
const command = `DELETE FROM ${queryBuilder.quoteTable({ schema: relationProperty.linkSchema, tableName: relationProperty.linkTableName })}
|
|
3228
|
+
const command = `DELETE FROM ${queryBuilder.quoteTable({ schema: relationProperty.linkSchema, tableName: relationProperty.linkTableName })}
|
|
3147
3229
|
WHERE ${queryBuilder.quoteObject(relationProperty.selfIdColumnName)}=$1 AND ${queryBuilder.quoteObject(relationProperty.targetIdColumnName)}=$2;`;
|
|
3148
3230
|
const params = [id, relation.id];
|
|
3149
3231
|
await server.queryDatabaseObject(command, params);
|
|
@@ -5558,15 +5640,19 @@ const code$7 = "downloadFile";
|
|
|
5558
5640
|
async function handler$7(plugin, ctx, options) {
|
|
5559
5641
|
const { server, applicationConfig, routerContext, input } = ctx;
|
|
5560
5642
|
const { request, response } = routerContext;
|
|
5561
|
-
|
|
5562
|
-
|
|
5563
|
-
|
|
5564
|
-
|
|
5565
|
-
|
|
5566
|
-
|
|
5567
|
-
|
|
5643
|
+
//TODO: only public files can download by this handler
|
|
5644
|
+
let fileKey = input.fileKey;
|
|
5645
|
+
if (!fileKey && input.fileId) {
|
|
5646
|
+
const dataAccessor = ctx.server.getDataAccessor({
|
|
5647
|
+
singularCode: "ecm_storage_object",
|
|
5648
|
+
});
|
|
5649
|
+
const storageObject = await dataAccessor.findById(input.fileId);
|
|
5650
|
+
if (!storageObject) {
|
|
5651
|
+
ctx.output = { error: new Error("Storage object not found.") };
|
|
5652
|
+
return;
|
|
5653
|
+
}
|
|
5654
|
+
fileKey = storageObject.key;
|
|
5568
5655
|
}
|
|
5569
|
-
const fileKey = storageObject.key;
|
|
5570
5656
|
const filePathName = path__default["default"].join(server.config.localFileStoragePath, fileKey);
|
|
5571
5657
|
const attachmentFileName = input.fileName || path__default["default"].basename(fileKey);
|
|
5572
5658
|
response.body = await readFile(filePathName);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { RpdDataModel, CreateEntityOptions, QuoteTableOptions, DatabaseQuery } from "../types";
|
|
2
2
|
import { CountRowOptions, DeleteRowOptions, FindRowOptions, RowFilterOptions, UpdateRowOptions, ColumnSelectOptions } from "../dataAccess/dataAccessTypes";
|
|
3
3
|
export interface BuildQueryContext {
|
|
4
|
+
model: RpdDataModel;
|
|
4
5
|
builder: QueryBuilder;
|
|
5
6
|
params: any[];
|
|
6
7
|
emitTableAlias: boolean;
|
|
@@ -13,7 +14,7 @@ export default class QueryBuilder {
|
|
|
13
14
|
constructor(options: InitQueryBuilderOptions);
|
|
14
15
|
quoteTable(options: QuoteTableOptions): string;
|
|
15
16
|
quoteObject(name: string): string;
|
|
16
|
-
quoteColumn(column: ColumnSelectOptions, emitTableAlias: boolean): string;
|
|
17
|
+
quoteColumn(model: RpdDataModel, column: ColumnSelectOptions, emitTableAlias: boolean): string;
|
|
17
18
|
select(model: RpdDataModel, options: FindRowOptions): DatabaseQuery;
|
|
18
19
|
selectDerived(derivedModel: RpdDataModel, baseModel: RpdDataModel, options: FindRowOptions): DatabaseQuery;
|
|
19
20
|
count(model: RpdDataModel, options: CountRowOptions): DatabaseQuery;
|