@sap/cds 5.6.2 → 5.7.2
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/CHANGELOG.md +133 -0
- package/_i18n/i18n_fr.properties +4 -4
- package/apis/cds.d.ts +7 -10
- package/apis/connect.d.ts +3 -3
- package/apis/core.d.ts +2 -4
- package/apis/models.d.ts +2 -3
- package/apis/ql.d.ts +0 -1
- package/apis/services.d.ts +7 -3
- package/bin/build/buildTaskFactory.js +16 -10
- package/bin/build/buildTaskProviderFactory.js +3 -3
- package/bin/build/constants.js +2 -1
- package/bin/build/provider/buildTaskProviderInternal.js +14 -14
- package/bin/build/provider/hana/2migration.js +2 -3
- package/bin/build/provider/hana/index.js +34 -0
- package/bin/build/provider/hana/migrationtable.js +90 -22
- package/bin/build/provider/hana/template/undeploy.json +5 -0
- package/bin/build/provider/node-cf/index.js +9 -2
- package/bin/serve.js +16 -18
- package/lib/compile/cdsc.js +15 -5
- package/lib/compile/etc/_localized.js +4 -4
- package/lib/compile/extend.js +8 -0
- package/lib/compile/index.js +3 -1
- package/lib/compile/minify.js +61 -0
- package/lib/compile/resolve.js +4 -1
- package/lib/compile/to/gql.js +9 -0
- package/lib/compile/to/sql.js +26 -30
- package/lib/connect/index.js +1 -1
- package/lib/core/entities.js +0 -3
- package/lib/core/infer.js +1 -0
- package/lib/core/reflect.js +0 -34
- package/lib/deploy.js +25 -17
- package/lib/env/defaults.js +3 -1
- package/lib/env/index.js +13 -4
- package/lib/env/presets.js +38 -0
- package/lib/env/requires.js +16 -11
- package/lib/index.js +13 -11
- package/lib/log/format/kibana.js +4 -2
- package/lib/log/index.js +2 -2
- package/lib/ql/Whereable.js +1 -0
- package/lib/req/cds-context.js +79 -0
- package/lib/req/context.js +5 -77
- package/lib/req/request.js +1 -1
- package/lib/serve/Service-api.js +8 -4
- package/lib/serve/Service-dispatch.js +0 -7
- package/lib/serve/Service-methods.js +6 -8
- package/lib/serve/Transaction.js +35 -30
- package/lib/serve/adapters.js +1 -4
- package/lib/utils/axios.js +1 -1
- package/libx/_runtime/audit/Service.js +44 -20
- package/libx/_runtime/audit/generic/personal/access.js +16 -11
- package/libx/_runtime/audit/generic/personal/modification.js +5 -5
- package/libx/_runtime/audit/generic/personal/utils.js +46 -37
- package/libx/_runtime/{common/auth → auth}/index.js +21 -7
- package/libx/_runtime/{common/auth → auth}/strategies/JWT.js +2 -2
- package/libx/_runtime/{common/auth → auth}/strategies/basic.js +2 -2
- package/libx/_runtime/{common/auth → auth}/strategies/dummy.js +1 -1
- package/libx/_runtime/{common/auth → auth}/strategies/mock.js +2 -2
- package/libx/_runtime/{common/auth → auth}/strategies/utils/uaa.js +1 -1
- package/libx/_runtime/{common/auth → auth}/strategies/utils/xssec.js +0 -0
- package/libx/_runtime/{common/auth → auth}/strategies/xsuaa.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/Dispatcher.js +7 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +0 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +0 -8
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/action.js +3 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +6 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/delete.js +3 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/error.js +2 -11
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +16 -6
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +26 -65
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +0 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +3 -66
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +26 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/readToCQN.js +5 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/utils.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/uri/UriParser.js +13 -10
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/ConditionalRequestControlCommand.js +0 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/validator/ConditionalRequestValidator.js +0 -8
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/stream.js +54 -76
- package/libx/_runtime/cds-services/adapter/rest/RestRequest.js +0 -7
- package/libx/_runtime/cds-services/adapter/rest/handlers/create.js +3 -6
- package/libx/_runtime/cds-services/adapter/rest/handlers/delete.js +3 -6
- package/libx/_runtime/cds-services/adapter/rest/handlers/operation.js +3 -6
- package/libx/_runtime/cds-services/adapter/rest/handlers/read.js +3 -6
- package/libx/_runtime/cds-services/adapter/rest/handlers/update.js +3 -6
- package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/index.js +2 -2
- package/libx/_runtime/cds-services/adapter/rest/utils/parse-url.js +8 -4
- package/libx/_runtime/cds-services/services/Service.js +0 -6
- package/libx/_runtime/cds-services/services/utils/columns.js +10 -3
- package/libx/_runtime/cds-services/services/utils/compareJson.js +4 -7
- package/libx/_runtime/cds-services/services/utils/differ.js +4 -1
- package/libx/_runtime/cds-services/services/utils/handlerUtils.js +1 -41
- package/libx/_runtime/cds-services/util/assert.js +1 -262
- package/libx/_runtime/cds.js +6 -9
- package/libx/_runtime/common/aspects/entity.js +1 -1
- package/libx/_runtime/common/composition/delete.js +4 -2
- package/libx/_runtime/common/composition/update.js +22 -35
- package/libx/_runtime/common/composition/utils.js +3 -7
- package/libx/_runtime/common/error/standardError.js +11 -0
- package/libx/_runtime/common/generic/auth.js +63 -33
- package/libx/_runtime/common/generic/crud.js +11 -23
- package/libx/_runtime/common/generic/input.js +20 -0
- package/libx/_runtime/common/generic/paging.js +2 -2
- package/libx/_runtime/common/generic/put.js +4 -10
- package/libx/_runtime/common/generic/sorting.js +12 -30
- package/libx/_runtime/common/perf/index.js +24 -0
- package/libx/_runtime/common/utils/cqn.js +58 -1
- package/libx/_runtime/common/utils/cqn2cqn4sql.js +297 -121
- package/libx/_runtime/common/utils/csn.js +38 -56
- package/libx/_runtime/common/utils/entityFromCqn.js +6 -6
- package/libx/_runtime/common/utils/resolveView.js +4 -5
- package/libx/_runtime/common/utils/rewriteAsterisks.js +46 -5
- package/libx/_runtime/common/utils/search2cqn4sql.js +21 -9
- package/libx/_runtime/common/utils/structured.js +35 -25
- package/libx/_runtime/db/Service.js +0 -6
- package/libx/_runtime/db/expand/expand-v2.js +130 -0
- package/libx/_runtime/db/expand/expandCQNToJoin.js +38 -52
- package/libx/_runtime/db/expand/index.js +3 -1
- package/libx/_runtime/db/generic/arrayed.js +3 -1
- package/libx/_runtime/db/generic/input.js +52 -10
- package/libx/_runtime/db/generic/integrity.js +367 -26
- package/libx/_runtime/db/generic/virtual.js +51 -13
- package/libx/_runtime/db/query/update.js +9 -3
- package/libx/_runtime/db/sql-builder/ExpressionBuilder.js +8 -9
- package/libx/_runtime/{common → db}/utils/propagateForeignKeys.js +11 -14
- package/libx/_runtime/fiori/generic/activate.js +1 -0
- package/libx/_runtime/fiori/generic/before.js +2 -1
- package/libx/_runtime/fiori/generic/edit.js +1 -0
- package/libx/_runtime/fiori/generic/patch.js +1 -1
- package/libx/_runtime/fiori/generic/read.js +155 -57
- package/libx/_runtime/fiori/uiflex/handler/transformRESULT.js +0 -4
- package/libx/_runtime/fiori/uiflex/index.js +1 -1
- package/libx/_runtime/fiori/uiflex/{extensibility/index.js → service.js} +6 -4
- package/libx/_runtime/fiori/utils/delete.js +7 -1
- package/libx/_runtime/hana/Service.js +1 -8
- package/libx/_runtime/hana/customBuilder/CustomSelectBuilder.js +5 -14
- package/libx/_runtime/hana/execute.js +10 -4
- package/libx/_runtime/hana/pool.js +55 -45
- package/libx/_runtime/hana/search.js +7 -6
- package/libx/_runtime/hana/search2cqn4sql.js +8 -5
- package/libx/_runtime/hana/searchToContains.js +3 -1
- package/libx/_runtime/index.js +5 -5
- package/libx/_runtime/messaging/AMQPWebhookMessaging.js +3 -3
- package/libx/_runtime/messaging/Outbox.js +53 -0
- package/libx/_runtime/messaging/common-utils/AMQPClient.js +17 -10
- package/libx/_runtime/messaging/common-utils/connections.js +14 -9
- package/libx/_runtime/messaging/common-utils/waitingTime.js +2 -0
- package/libx/_runtime/messaging/enterprise-messaging-shared.js +2 -3
- package/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +2 -2
- package/libx/_runtime/messaging/enterprise-messaging.js +21 -15
- package/libx/_runtime/messaging/file-based.js +5 -5
- package/libx/_runtime/messaging/message-queuing.js +2 -3
- package/libx/_runtime/messaging/outbox/OutboxRunner.js +75 -0
- package/libx/_runtime/messaging/outbox/utils.js +192 -0
- package/libx/_runtime/messaging/service.js +16 -30
- package/libx/_runtime/remote/Service.js +15 -0
- package/libx/_runtime/remote/utils/client.js +15 -3
- package/libx/_runtime/remote/utils/{dataConversion.js → data.js} +12 -2
- package/libx/_runtime/sqlite/Service.js +7 -10
- package/libx/_runtime/sqlite/customBuilder/CustomExpressionBuilder.js +19 -0
- package/libx/_runtime/sqlite/execute.js +18 -12
- package/libx/_runtime/types/api.js +2 -1
- package/libx/gql/resolvers/parse/ast2cqn/columns.js +1 -1
- package/libx/odata/{odata2cqn/afterburner.js → afterburner.js} +28 -16
- package/libx/odata/{cqn2odata/index.js → cqn2odata.js} +1 -1
- package/libx/odata/{odata2cqn/grammar.pegjs → grammar.pegjs} +182 -118
- package/libx/odata/index.js +18 -15
- package/libx/odata/parser.js +1 -0
- package/libx/odata/utils.js +57 -0
- package/libx/rest/RestAdapter.js +2 -6
- package/libx/rest/utils/data.js +1 -6
- package/package.json +4 -3
- package/server.js +4 -5
- package/srv/audit-log.cds +87 -0
- package/{libx/_runtime/fiori/uiflex/extensibility/index.cds → srv/flex.cds} +0 -0
- package/srv/flex.js +1 -0
- package/srv/outbox.cds +11 -0
- package/srv/outbox.js +0 -0
- package/libx/_runtime/cds-services/adapter/perf/performance.js +0 -104
- package/libx/_runtime/cds-services/adapter/perf/performanceMeasurement.js +0 -33
- package/libx/odata/odata2cqn/index.js +0 -3
- package/libx/odata/odata2cqn/parser.js +0 -1
- package/libx/odata/readme.md +0 -1
- package/libx/odata/utils/index.js +0 -64
|
@@ -51,12 +51,8 @@ class JoinCQNFromExpanded {
|
|
|
51
51
|
* @returns {this}
|
|
52
52
|
*/
|
|
53
53
|
buildJoinQueries() {
|
|
54
|
-
const unionTableRef = this._getUnionTable(this._SELECT)
|
|
55
54
|
// side effect: this_aliases is set
|
|
56
|
-
const aliases = this._getTableAlias(this._SELECT, []
|
|
57
|
-
|
|
58
|
-
// Add table aliases to all refs in where part obtained from annotations
|
|
59
|
-
this._adaptAliasForWhere(this._SELECT.where)
|
|
55
|
+
const aliases = this._getTableAlias(this._SELECT, [])
|
|
60
56
|
|
|
61
57
|
// Update elements at WHERE, so there are no issues with ambiguity
|
|
62
58
|
this._adaptWhereOrderBy(this._SELECT, aliases)
|
|
@@ -108,7 +104,7 @@ class JoinCQNFromExpanded {
|
|
|
108
104
|
|
|
109
105
|
const unionTableRef = this._getUnionTable(SELECT)
|
|
110
106
|
const unionTable = unionTableRef && unionTableRef.table
|
|
111
|
-
const tableAlias = this._getTableAlias(SELECT, toManyTree
|
|
107
|
+
const tableAlias = this._getTableAlias(SELECT, toManyTree)
|
|
112
108
|
|
|
113
109
|
const readToOneCQN = this._getReadToOneCQN(SELECT, isJoinOfTwoSelects ? 'filterExpand' : tableAlias)
|
|
114
110
|
|
|
@@ -161,11 +157,14 @@ class JoinCQNFromExpanded {
|
|
|
161
157
|
* @returns {string}
|
|
162
158
|
* @private
|
|
163
159
|
*/
|
|
164
|
-
_getTableAlias(SELECT, toManyTree
|
|
165
|
-
return this._createAlias(toManyTree.length === 0 ?
|
|
160
|
+
_getTableAlias(SELECT, toManyTree) {
|
|
161
|
+
return this._createAlias(toManyTree.length === 0 ? this._getRef(SELECT).table : toManyTree.join(':'))
|
|
166
162
|
}
|
|
167
163
|
|
|
168
164
|
_getRef(SELECT) {
|
|
165
|
+
const unionTableRef = this._getUnionTable(SELECT)
|
|
166
|
+
if (unionTableRef) return unionTableRef
|
|
167
|
+
|
|
169
168
|
const table = Object.prototype.hasOwnProperty.call(SELECT.from, 'join')
|
|
170
169
|
? this._getRefFromJoin(SELECT.from.args)
|
|
171
170
|
: SELECT.from
|
|
@@ -256,10 +255,18 @@ class JoinCQNFromExpanded {
|
|
|
256
255
|
: column
|
|
257
256
|
}
|
|
258
257
|
|
|
259
|
-
_adaptJoin(tableAlias, cqn, from) {
|
|
258
|
+
_adaptJoin(tableAlias, cqn, from, mapping = {}) {
|
|
260
259
|
from.args = from.args.slice(0)
|
|
261
260
|
if (Object.prototype.hasOwnProperty.call(from.args[0], 'join')) {
|
|
262
|
-
this._adaptJoin(tableAlias, cqn, from.args[0])
|
|
261
|
+
this._adaptJoin(tableAlias, cqn, from.args[0], mapping)
|
|
262
|
+
if (from.on) {
|
|
263
|
+
// we come here for SiblingEntity with expand
|
|
264
|
+
for (const originalIdentifier in mapping) {
|
|
265
|
+
from.on = from.on.map(column =>
|
|
266
|
+
this._adaptTableNameInColumn(column, originalIdentifier, mapping[originalIdentifier])
|
|
267
|
+
)
|
|
268
|
+
}
|
|
269
|
+
}
|
|
263
270
|
} else {
|
|
264
271
|
const index = from.args[0].ref ? 0 : from.args.length - 1
|
|
265
272
|
const target = Object.assign({}, from.args[index], { as: tableAlias })
|
|
@@ -268,6 +275,7 @@ class JoinCQNFromExpanded {
|
|
|
268
275
|
from.args[index] = target
|
|
269
276
|
from.on = from.on.map(column => this._adaptTableNameInColumn(column, originalIdentifier, tableAlias))
|
|
270
277
|
cqn.columns = cqn.columns.map(column => this._adaptTableNameInColumn(column, originalIdentifier, tableAlias))
|
|
278
|
+
mapping[originalIdentifier] = tableAlias
|
|
271
279
|
}
|
|
272
280
|
}
|
|
273
281
|
|
|
@@ -331,32 +339,6 @@ class JoinCQNFromExpanded {
|
|
|
331
339
|
whereElement.ref && whereElement.ref.splice(0, 1, Object.values(this._aliases)[0])
|
|
332
340
|
}
|
|
333
341
|
|
|
334
|
-
_adaptAliasForFrom(from) {
|
|
335
|
-
if (from.args) {
|
|
336
|
-
from.args.forEach(arg => {
|
|
337
|
-
this._adaptAliasForFrom(arg)
|
|
338
|
-
})
|
|
339
|
-
} else if (from.SELECT) {
|
|
340
|
-
this._adaptAliasForFrom(from.SELECT.from)
|
|
341
|
-
if (from.SELECT.where) {
|
|
342
|
-
this._adaptAliasForWhere(from.SELECT.where)
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
_adaptAliasForWhere(where) {
|
|
348
|
-
if (where) {
|
|
349
|
-
for (const whereElement of where) {
|
|
350
|
-
if (whereElement.SELECT) {
|
|
351
|
-
if (whereElement.SELECT.where) {
|
|
352
|
-
this._adaptAliasForWhere(whereElement.SELECT.where)
|
|
353
|
-
}
|
|
354
|
-
this._adaptAliasForFrom(whereElement.SELECT.from)
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
|
|
360
342
|
_navigationNeedsAlias(element, { table } = {}) {
|
|
361
343
|
const entity = this._csn.definitions[table]
|
|
362
344
|
if (entity) {
|
|
@@ -377,9 +359,9 @@ class JoinCQNFromExpanded {
|
|
|
377
359
|
|
|
378
360
|
if (element.ref.length === 1) {
|
|
379
361
|
element.ref.unshift(tableAlias)
|
|
380
|
-
} else if (this._elementAliasNeedsReplacement(element, this.
|
|
362
|
+
} else if (this._elementAliasNeedsReplacement(element, this._getRef(cqn))) {
|
|
381
363
|
element.ref[0] = tableAlias
|
|
382
|
-
} else if (this._navigationNeedsAlias(element, this.
|
|
364
|
+
} else if (this._navigationNeedsAlias(element, this._getRef(cqn))) {
|
|
383
365
|
element.ref.unshift(tableAlias)
|
|
384
366
|
}
|
|
385
367
|
|
|
@@ -392,7 +374,7 @@ class JoinCQNFromExpanded {
|
|
|
392
374
|
} else if (element.SELECT && element.SELECT.where) {
|
|
393
375
|
element = {
|
|
394
376
|
SELECT: Object.assign({}, element.SELECT, {
|
|
395
|
-
where: this._adaptWhereSELECT(this.
|
|
377
|
+
where: this._adaptWhereSELECT(this._getRef(cqn), element.SELECT.where, tableAlias)
|
|
396
378
|
})
|
|
397
379
|
}
|
|
398
380
|
}
|
|
@@ -588,13 +570,15 @@ class JoinCQNFromExpanded {
|
|
|
588
570
|
const on = []
|
|
589
571
|
for (const key in entity._target.keys) {
|
|
590
572
|
if (key !== 'IsActiveEntity') {
|
|
573
|
+
if (on.length) on.push('AND')
|
|
591
574
|
on.push({ ref: [`${tableAlias}_drafts`, key] }, '=', { ref: [tableAlias, key] })
|
|
592
575
|
}
|
|
593
576
|
}
|
|
577
|
+
|
|
594
578
|
return {
|
|
595
579
|
args: [cqn, { ref: [draftTable], as: `${tableAlias}_drafts` }],
|
|
596
580
|
join: 'left',
|
|
597
|
-
on: on
|
|
581
|
+
on: ['(', ...on, ')']
|
|
598
582
|
}
|
|
599
583
|
}
|
|
600
584
|
|
|
@@ -613,8 +597,8 @@ class JoinCQNFromExpanded {
|
|
|
613
597
|
)
|
|
614
598
|
}
|
|
615
599
|
|
|
616
|
-
_getTarget(entity, column) {
|
|
617
|
-
const navigation = getNavigationIfStruct(entity, column.ref)
|
|
600
|
+
_getTarget(entity, column, parentAlias) {
|
|
601
|
+
const navigation = getNavigationIfStruct(entity, column.ref[0] === parentAlias ? column.ref.slice(1) : column.ref)
|
|
618
602
|
return (navigation && navigation.target) || column.ref[0]
|
|
619
603
|
}
|
|
620
604
|
|
|
@@ -632,17 +616,19 @@ class JoinCQNFromExpanded {
|
|
|
632
616
|
*/
|
|
633
617
|
// eslint-disable-next-line complexity
|
|
634
618
|
_addJoinAndElements({ column, entity, readToOneCQN, toManyTree, parentAlias, defaultLanguage }) {
|
|
635
|
-
const extendedToManyTree = toManyTree.concat(column.ref)
|
|
619
|
+
const extendedToManyTree = toManyTree.concat(column.ref[0] === parentAlias ? column.ref.slice(1) : column.ref)
|
|
636
620
|
const tableAlias = this._createAlias(extendedToManyTree.join(':'))
|
|
637
|
-
const target = this._getTarget(entity, column)
|
|
621
|
+
const target = this._getTarget(entity, column, parentAlias)
|
|
622
|
+
|
|
623
|
+
const name = column.ref[column.ref.length - 1]
|
|
624
|
+
const element = name && entity.elements[name]
|
|
638
625
|
|
|
639
626
|
// if union always only expand with active, otherwise evaluate flag
|
|
640
627
|
// if flag shows false, we check entity for associations to non draft
|
|
641
628
|
const activeTableRequired =
|
|
642
629
|
readToOneCQN[IS_UNION_DRAFT] ||
|
|
643
630
|
readToOneCQN[IS_ACTIVE] ||
|
|
644
|
-
(
|
|
645
|
-
!entity.elements[column.ref[0]]['@odata.draft.enclosed']) ||
|
|
631
|
+
(element && element.type === 'cds.Association' && !element['@odata.draft.enclosed']) ||
|
|
646
632
|
!this._csn.definitions[target]._isDraftEnabled
|
|
647
633
|
|
|
648
634
|
const colTarget = target && ensureUnlocalized(target)
|
|
@@ -652,9 +638,7 @@ class JoinCQNFromExpanded {
|
|
|
652
638
|
(colTarget && this._csn.definitions[colTarget] && this._csn.definitions[colTarget]['@cds.localized'] === false)
|
|
653
639
|
|
|
654
640
|
const join =
|
|
655
|
-
column.ref[0] === 'DraftAdministrativeData' || !
|
|
656
|
-
? 'left'
|
|
657
|
-
: 'inner'
|
|
641
|
+
column.ref[0] === 'DraftAdministrativeData' || !(element && element.notNull) || this._isDraft ? 'left' : 'inner'
|
|
658
642
|
|
|
659
643
|
const args = [
|
|
660
644
|
readToOneCQN.from.SET ? this._unionToSubQuery(readToOneCQN) : readToOneCQN.from,
|
|
@@ -695,11 +679,11 @@ class JoinCQNFromExpanded {
|
|
|
695
679
|
}
|
|
696
680
|
|
|
697
681
|
// special case of navigation to one requires additional LEFT JOIN and CASE for HasDraftEntity
|
|
698
|
-
const compToOne = this._isNavigationToOne(readToOneCQN[IS_ACTIVE],
|
|
682
|
+
const compToOne = this._isNavigationToOne(readToOneCQN[IS_ACTIVE], element)
|
|
699
683
|
const index = column.expand.findIndex(col => col.ref && col.ref[col.ref.length - 1] === 'HasDraftEntity')
|
|
700
684
|
|
|
701
685
|
if (compToOne && index !== -1) {
|
|
702
|
-
readToOneCQN.from = this._addJoinCompToOne(readToOneCQN.from,
|
|
686
|
+
readToOneCQN.from = this._addJoinCompToOne(readToOneCQN.from, element, tableAlias)
|
|
703
687
|
if (activeTableRequired) {
|
|
704
688
|
column.expand[index] = {
|
|
705
689
|
xpr: [
|
|
@@ -849,7 +833,9 @@ class JoinCQNFromExpanded {
|
|
|
849
833
|
const subSelectColumns = this._getSubSelectColumns(readToOneCQN)
|
|
850
834
|
|
|
851
835
|
if (subSelectColumns.length === 0) {
|
|
852
|
-
return entity._relations[
|
|
836
|
+
return entity._relations[
|
|
837
|
+
tableAlias === columns[0] || parentAlias === columns[0] ? columns.slice(1) : columns
|
|
838
|
+
].join(tableAlias, parentAlias)
|
|
853
839
|
}
|
|
854
840
|
|
|
855
841
|
const aliases = this._getAliases(subSelectColumns)
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
const { hasExpand, createJoinCQNFromExpanded } = require('./expandCQNToJoin')
|
|
2
2
|
const rawToExpanded = require('./rawToExpanded')
|
|
3
|
+
const expandV2 = require('./expand-v2')
|
|
3
4
|
|
|
4
5
|
module.exports = {
|
|
5
6
|
hasExpand,
|
|
6
7
|
createJoinCQNFromExpanded,
|
|
7
|
-
rawToExpanded
|
|
8
|
+
rawToExpanded,
|
|
9
|
+
expandV2
|
|
8
10
|
}
|
|
@@ -7,7 +7,9 @@ const _pick = element => {
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
const _processFn = ({ row, key, plain }) => {
|
|
10
|
-
if (plain === 'arrayed' && row && row[key]
|
|
10
|
+
if (plain === 'arrayed' && row && row[key] && (typeof row[key] === 'string' || Buffer.isBuffer(row[key]))) {
|
|
11
|
+
row[key] = JSON.parse(row[key])
|
|
12
|
+
}
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
/**
|
|
@@ -14,7 +14,7 @@ const cds = require('../../cds')
|
|
|
14
14
|
const normalizeTimeData = require('../utils/normalizeTimeData')
|
|
15
15
|
|
|
16
16
|
const { enrichDataWithKeysFromWhere } = require('../../common/utils/keys')
|
|
17
|
-
const
|
|
17
|
+
const propagateForeignKeys = require('../utils/propagateForeignKeys')
|
|
18
18
|
const getTemplate = require('../../common/utils/template')
|
|
19
19
|
const templateProcessor = require('../../common/utils/templateProcessor')
|
|
20
20
|
|
|
@@ -25,12 +25,14 @@ const { DRAFT_COLUMNS_MAP } = require('../../common/constants/draft')
|
|
|
25
25
|
const _isManaged = (category, event) =>
|
|
26
26
|
(category === '@cds.on.insert' && event === 'CREATE') || (category === '@cds.on.update' && event === 'UPDATE')
|
|
27
27
|
|
|
28
|
+
const _shouldGenerateUUID = element => element.key && !DRAFT_COLUMNS_MAP[element.name] && element.type === 'cds.UUID'
|
|
29
|
+
|
|
28
30
|
const _processComplexCategory = ({ row, key, val, category, req, element }) => {
|
|
29
31
|
const categoryArgs = category.args
|
|
30
32
|
category = category.category
|
|
31
33
|
|
|
32
34
|
// propagate keys
|
|
33
|
-
if (category === 'propagateForeignKeys') {
|
|
35
|
+
if (category === 'propagateForeignKeys' && row[key]) {
|
|
34
36
|
propagateForeignKeys(key, row, element._foreignKeys, element._isCompositionEffective)
|
|
35
37
|
return
|
|
36
38
|
}
|
|
@@ -73,6 +75,20 @@ const _processCategory = ({ category, row, key, element, val, req }) => {
|
|
|
73
75
|
return
|
|
74
76
|
}
|
|
75
77
|
|
|
78
|
+
if (category === 'comp2one') {
|
|
79
|
+
if (!val) return
|
|
80
|
+
|
|
81
|
+
for (const keyName in element._target.keys) {
|
|
82
|
+
const k = element._target.keys[keyName]
|
|
83
|
+
if (k.type === 'cds.Association' || k.name === 'IsActiveEntity') continue
|
|
84
|
+
|
|
85
|
+
if (k.type !== 'cds.UUID' && !(k.name in val)) {
|
|
86
|
+
req.error(400, 'ASSERT_NOT_NULL', key + '[' + k + ']', [key + '[' + k + ']'])
|
|
87
|
+
return
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
76
92
|
// not null without default (for better error message)
|
|
77
93
|
if (category === '!default' && val == null && req.event === 'CREATE') {
|
|
78
94
|
req.error(400, 'ASSERT_NOT_NULL', key, [key])
|
|
@@ -101,12 +117,24 @@ const processorFn =
|
|
|
101
117
|
}
|
|
102
118
|
}
|
|
103
119
|
|
|
120
|
+
const _isVirtualOrCalculated = element => {
|
|
121
|
+
if (element.virtual) return true
|
|
122
|
+
if (
|
|
123
|
+
element.parent &&
|
|
124
|
+
element.parent.projection &&
|
|
125
|
+
element.parent.projection.columns &&
|
|
126
|
+
element.parent.projection.columns.find(c => c.as === element.name && (c.xpr || c.val || c.func))
|
|
127
|
+
) {
|
|
128
|
+
return true
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
104
132
|
// params: element, target, parent, templateElements
|
|
105
|
-
const
|
|
133
|
+
const _pickCRUD = element => {
|
|
106
134
|
// collect actions to apply
|
|
107
135
|
const categories = []
|
|
108
136
|
|
|
109
|
-
if (element
|
|
137
|
+
if (_isVirtualOrCalculated(element)) {
|
|
110
138
|
categories.push('virtual')
|
|
111
139
|
return { categories } // > no need to continue
|
|
112
140
|
}
|
|
@@ -136,22 +164,37 @@ const _pick = element => {
|
|
|
136
164
|
categories.push('associationEffective')
|
|
137
165
|
}
|
|
138
166
|
|
|
167
|
+
// REVISIT: element._foreignKeys.length seems to be a very broad check
|
|
139
168
|
if (element.isAssociation && element._foreignKeys.length) {
|
|
140
169
|
categories.push({ category: 'propagateForeignKeys' })
|
|
141
170
|
}
|
|
142
171
|
|
|
143
|
-
|
|
144
|
-
if (element.key && !DRAFT_COLUMNS_MAP[element.name] && element.type === 'cds.UUID') {
|
|
172
|
+
if (_shouldGenerateUUID(element)) {
|
|
145
173
|
categories.push('uuid')
|
|
146
174
|
}
|
|
147
175
|
|
|
176
|
+
if (element.isComposition && element.is2one) {
|
|
177
|
+
categories.push('comp2one')
|
|
178
|
+
}
|
|
179
|
+
|
|
148
180
|
if (categories.length) return { categories }
|
|
149
181
|
}
|
|
150
182
|
|
|
151
|
-
const
|
|
183
|
+
const _pickDraft = element => {
|
|
152
184
|
// collect actions to apply
|
|
153
185
|
const categories = []
|
|
186
|
+
|
|
154
187
|
if (element.virtual) categories.push('virtual')
|
|
188
|
+
|
|
189
|
+
// REVISIT: element._foreignKeys.length seems to be a very broad check
|
|
190
|
+
if (element.isAssociation && element._foreignKeys.length) {
|
|
191
|
+
categories.push({ category: 'propagateForeignKeys' })
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (_shouldGenerateUUID(element)) {
|
|
195
|
+
categories.push('uuid')
|
|
196
|
+
}
|
|
197
|
+
|
|
155
198
|
if (categories.length) return { categories }
|
|
156
199
|
}
|
|
157
200
|
|
|
@@ -174,10 +217,9 @@ function _handler(req) {
|
|
|
174
217
|
|
|
175
218
|
let template
|
|
176
219
|
if (draft) {
|
|
177
|
-
|
|
178
|
-
template = getTemplate('db-virtual', this, target, { pick: _pickVirtual })
|
|
220
|
+
template = getTemplate('db-input-draft', this, target, { pick: _pickDraft })
|
|
179
221
|
} else {
|
|
180
|
-
template = getTemplate('db-input', this, target, { pick:
|
|
222
|
+
template = getTemplate('db-input-crud', this, target, { pick: _pickCRUD })
|
|
181
223
|
}
|
|
182
224
|
|
|
183
225
|
if (template.elements.size === 0) return
|