@sap/cds 5.4.3 → 5.5.0
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 +239 -2
- package/apis/ql.d.ts +17 -15
- package/app/index.js +1 -1
- package/bin/build/buildTaskEngine.js +26 -42
- package/bin/build/buildTaskFactory.js +6 -10
- package/bin/build/buildTaskHandler.js +2 -4
- package/bin/build/buildTaskProvider.js +3 -1
- package/bin/build/buildTaskProviderFactory.js +9 -15
- package/bin/build/constants.js +15 -3
- package/bin/build/index.js +5 -4
- package/bin/build/mtaUtil.js +8 -11
- package/bin/build/provider/buildTaskHandlerEdmx.js +63 -6
- package/bin/build/provider/buildTaskHandlerInternal.js +2 -34
- package/bin/build/provider/buildTaskProviderInternal.js +16 -42
- package/bin/build/provider/fiori/index.js +13 -24
- package/bin/build/provider/hana/2migration.js +17 -15
- package/bin/build/provider/hana/2tabledata.js +52 -48
- package/bin/build/provider/hana/index.js +27 -25
- package/bin/build/provider/hana/migrationtable.js +91 -67
- package/bin/build/provider/java-cf/index.js +14 -24
- package/bin/build/provider/mtx/index.js +12 -14
- package/bin/build/provider/node-cf/index.js +18 -32
- package/bin/cds.js +5 -5
- package/bin/serve.js +29 -23
- package/bin/version.js +0 -1
- package/lib/compile/etc/_localized.js +4 -9
- package/lib/compile/for/sql.js +5 -2
- package/lib/compile/parse.js +25 -17
- package/lib/compile/to/srvinfo.js +2 -1
- package/lib/connect/bindings.js +2 -1
- package/lib/connect/index.js +48 -49
- package/lib/core/classes.js +1 -1
- package/lib/core/reflect.js +10 -2
- package/lib/deploy.js +26 -23
- package/lib/env/defaults.js +13 -6
- package/lib/env/index.js +73 -78
- package/lib/env/requires.js +38 -19
- package/lib/index.js +9 -10
- package/lib/lazy.js +2 -2
- package/lib/log/index.js +33 -45
- package/lib/log/service/index.js +2 -2
- package/lib/ql/CREATE.js +14 -9
- package/lib/ql/DELETE.js +6 -5
- package/lib/ql/DROP.js +12 -9
- package/lib/ql/INSERT.js +40 -16
- package/lib/ql/Query.js +67 -40
- package/lib/ql/SELECT.js +162 -127
- package/lib/ql/UPDATE.js +74 -42
- package/lib/ql/Whereable.js +77 -87
- package/lib/ql/index.js +36 -24
- package/lib/ql/parse.js +35 -0
- package/lib/req/context.js +44 -8
- package/lib/req/locale.js +7 -7
- package/lib/serve/Service-api.js +21 -14
- package/lib/serve/Service-dispatch.js +28 -12
- package/lib/serve/Transaction.js +22 -10
- package/lib/serve/index.js +16 -11
- package/lib/utils/axios.js +23 -16
- package/lib/utils/data.js +35 -0
- package/lib/utils/tests.js +27 -18
- package/libx/_runtime/audit/generic/personal/access.js +81 -0
- package/libx/_runtime/audit/generic/personal/constants.js +4 -0
- package/libx/_runtime/audit/generic/personal/index.js +50 -0
- package/libx/_runtime/audit/generic/personal/modification.js +138 -0
- package/libx/_runtime/audit/generic/personal/utils.js +186 -0
- package/libx/_runtime/audit/utils/v2.js +10 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/Dispatcher.js +5 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +6 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/action.js +5 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +5 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/delete.js +2 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/error.js +4 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +7 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +59 -8
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +11 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +6 -10
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +3 -46
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/applyToCQN.js +2 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/createToCQN.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/deleteToCQN.js +4 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/expandToCQN.js +1 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/index.js +0 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/selectHelper.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/updateToCQN.js +2 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/utils.js +16 -18
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/edm/EdmEntityType.js +6 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/format/RepresentationKind.js +4 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/core/OdataRequest.js +1 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/SerializerFactory.js +15 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/validator/OperationValidator.js +1 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/to.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +8 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/handlerUtils.js +6 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/omitValues.js +12 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/readAfterWrite.js +1 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/request.js +7 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +14 -18
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/stream.js +13 -13
- package/libx/_runtime/cds-services/adapter/rest/handlers/create.js +0 -1
- package/libx/_runtime/cds-services/adapter/rest/handlers/operation.js +2 -1
- package/libx/_runtime/cds-services/adapter/rest/handlers/read.js +2 -2
- package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/index.js +2 -4
- package/libx/_runtime/cds-services/adapter/rest/utils/result.js +4 -2
- package/libx/_runtime/cds-services/services/Service.js +40 -5
- package/libx/_runtime/cds-services/services/utils/columns.js +13 -7
- package/libx/_runtime/cds-services/services/utils/compareJson.js +88 -4
- package/libx/_runtime/cds-services/services/utils/differ.js +24 -6
- package/libx/_runtime/cds-services/services/utils/handlerUtils.js +2 -2
- package/libx/_runtime/common/composition/data.js +66 -63
- package/libx/_runtime/common/composition/delete.js +97 -71
- package/libx/_runtime/common/composition/index.js +2 -1
- package/libx/_runtime/common/composition/insert.js +34 -11
- package/libx/_runtime/common/composition/tree.js +119 -92
- package/libx/_runtime/common/composition/update.js +12 -1
- package/libx/_runtime/common/composition/utils.js +1 -3
- package/libx/_runtime/common/constants/draft.js +12 -1
- package/libx/_runtime/common/generic/auth.js +53 -31
- package/libx/_runtime/common/generic/crud.js +14 -13
- package/libx/_runtime/common/generic/input.js +23 -26
- package/libx/_runtime/common/generic/put.js +1 -1
- package/libx/_runtime/common/generic/sorting.js +16 -16
- package/libx/_runtime/common/i18n/index.js +1 -1
- package/libx/_runtime/common/i18n/messages.properties +4 -0
- package/libx/_runtime/common/utils/backlinks.js +12 -5
- package/libx/_runtime/common/utils/cqn.js +6 -1
- package/libx/_runtime/common/utils/cqn2cqn4sql.js +123 -108
- package/libx/_runtime/common/utils/csn.js +56 -4
- package/libx/_runtime/common/utils/data.js +0 -37
- package/libx/_runtime/common/utils/enrichWithKeysFromWhere.js +1 -1
- package/libx/_runtime/common/utils/entityFromCqn.js +7 -24
- package/libx/_runtime/common/utils/foreignKeyPropagations.js +39 -7
- package/libx/_runtime/common/utils/generateOnCond.js +11 -12
- package/libx/_runtime/common/utils/onlyKeysRemain.js +10 -0
- package/libx/_runtime/common/utils/path.js +35 -0
- package/libx/_runtime/common/utils/postProcessing.js +86 -0
- package/libx/_runtime/common/utils/quotingStyles.js +37 -26
- package/libx/_runtime/common/utils/resolveView.js +227 -173
- package/libx/_runtime/common/utils/rewriteAsterisk.js +46 -26
- package/libx/_runtime/common/utils/structured.js +13 -13
- package/libx/_runtime/common/utils/template.js +10 -5
- package/libx/_runtime/common/utils/templateDelimiter.js +1 -0
- package/libx/_runtime/common/utils/templateProcessor.js +28 -72
- package/libx/_runtime/common/utils/union.js +31 -0
- package/libx/_runtime/common/utils/unionCqnTemplate.js +184 -0
- package/libx/_runtime/db/Service.js +1 -1
- package/libx/_runtime/db/data-conversion/timestamp.js +2 -9
- package/libx/_runtime/db/expand/expandCQNToJoin.js +204 -297
- package/libx/_runtime/db/expand/index.js +3 -3
- package/libx/_runtime/db/expand/rawToExpanded.js +36 -7
- package/libx/_runtime/db/generic/index.js +1 -1
- package/libx/_runtime/db/generic/input.js +5 -7
- package/libx/_runtime/db/generic/integrity.js +1 -1
- package/libx/_runtime/db/generic/rewrite.js +2 -10
- package/libx/_runtime/db/generic/update.js +13 -5
- package/libx/_runtime/db/generic/virtual.js +22 -58
- package/libx/_runtime/db/query/delete.js +7 -4
- package/libx/_runtime/db/query/insert.js +6 -4
- package/libx/_runtime/db/query/read.js +21 -8
- package/libx/_runtime/db/query/run.js +4 -1
- package/libx/_runtime/db/query/update.js +5 -4
- package/libx/_runtime/db/sql-builder/ExpressionBuilder.js +35 -2
- package/libx/_runtime/db/sql-builder/FunctionBuilder.js +17 -2
- package/libx/_runtime/db/sql-builder/InsertBuilder.js +6 -5
- package/libx/_runtime/db/sql-builder/ReferenceBuilder.js +10 -0
- package/libx/_runtime/db/sql-builder/SelectBuilder.js +35 -24
- package/libx/_runtime/db/sql-builder/UpdateBuilder.js +14 -4
- package/libx/_runtime/db/sql-builder/arrayed.js +4 -0
- package/libx/_runtime/db/utils/deep.js +8 -0
- package/libx/_runtime/db/utils/generateAliases.js +2 -1
- package/libx/_runtime/fiori/generic/activate.js +19 -15
- package/libx/_runtime/fiori/generic/before.js +3 -11
- package/libx/_runtime/fiori/generic/cancel.js +1 -1
- package/libx/_runtime/fiori/generic/delete.js +3 -1
- package/libx/_runtime/fiori/generic/edit.js +12 -2
- package/libx/_runtime/fiori/generic/new.js +5 -5
- package/libx/_runtime/fiori/generic/patch.js +0 -18
- package/libx/_runtime/fiori/generic/read.js +261 -205
- package/libx/_runtime/fiori/utils/delete.js +36 -7
- package/libx/_runtime/fiori/utils/handler.js +43 -44
- package/libx/_runtime/fiori/utils/where.js +30 -15
- package/libx/_runtime/hana/customBuilder/CustomSelectBuilder.js +4 -6
- package/libx/_runtime/hana/execute.js +3 -3
- package/libx/_runtime/hana/localized.js +4 -4
- package/libx/_runtime/hana/pool.js +29 -14
- package/libx/_runtime/hana/search2cqn4sql.js +2 -1
- package/libx/_runtime/hana/searchToContains.js +18 -14
- package/libx/_runtime/index.js +0 -5
- package/libx/_runtime/messaging/AMQPWebhookMessaging.js +13 -5
- package/libx/_runtime/messaging/common-utils/naming-conventions.js +4 -1
- package/libx/_runtime/messaging/enterprise-messaging-utils/EMManagement.js +31 -19
- package/libx/_runtime/messaging/enterprise-messaging-utils/registerEndpoints.js +1 -2
- package/libx/_runtime/messaging/enterprise-messaging.js +6 -4
- package/libx/_runtime/messaging/service.js +7 -6
- package/libx/_runtime/odata/cqn2odata.js +110 -43
- package/libx/_runtime/odata/index.js +26 -48
- package/libx/_runtime/odata/odata2cqn.js +1 -6154
- package/libx/_runtime/odata/odata2cqn.pegjs +559 -0
- package/libx/_runtime/odata/readToCqn.js +94 -64
- package/libx/_runtime/remote/Service.js +74 -21
- package/libx/_runtime/remote/cqn2odata/index.js +1 -5
- package/libx/_runtime/remote/utils/client.js +24 -101
- package/libx/_runtime/remote/utils/dataConversion.js +27 -12
- package/libx/_runtime/sqlite/Service.js +3 -5
- package/libx/_runtime/sqlite/execute.js +33 -27
- package/libx/_runtime/sqlite/localized.js +12 -7
- package/libx/_runtime/types/api.js +10 -0
- package/package.json +2 -2
- package/server.js +16 -2
- package/lib/ql/grammar.pegjs +0 -208
- package/lib/ql/parser.js +0 -1
- package/lib/ql/rt/DELETE.js +0 -29
- package/lib/ql/rt/INSERT.js +0 -23
- package/lib/ql/rt/Query.js +0 -84
- package/lib/ql/rt/SELECT.js +0 -174
- package/lib/ql/rt/UPDATE.js +0 -119
- package/lib/ql/rt/_helpers.js +0 -91
- package/lib/ql/rt/index.js +0 -32
- package/libx/_runtime/audit/generic/personal.js +0 -260
- package/libx/_runtime/cds-services/statements/BaseStatement.js +0 -72
- package/libx/_runtime/cds-services/statements/Create.js +0 -57
- package/libx/_runtime/cds-services/statements/Delete.js +0 -33
- package/libx/_runtime/cds-services/statements/Drop.js +0 -42
- package/libx/_runtime/cds-services/statements/Insert.js +0 -201
- package/libx/_runtime/cds-services/statements/Select.js +0 -826
- package/libx/_runtime/cds-services/statements/Update.js +0 -181
- package/libx/_runtime/cds-services/statements/Where.js +0 -726
- package/libx/_runtime/cds-services/statements/index.js +0 -25
- package/libx/_runtime/common/generic/resolve-mock.js +0 -9
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
const cds = require('../../cds')
|
|
2
2
|
let LOG = cds.log('app')
|
|
3
3
|
let _event
|
|
4
|
+
const PERSISTENCE_TABLE = '@cds.persistence.table'
|
|
4
5
|
|
|
5
6
|
const getError = require('../error')
|
|
7
|
+
const { getEntityNameFromDeleteCQN, getEntityNameFromUpdateCQN } = require('../utils/cqn')
|
|
6
8
|
|
|
7
9
|
const _setInverseTransition = (mapping, ref, mapped) => {
|
|
8
10
|
const existing = mapping.get(ref)
|
|
@@ -30,7 +32,8 @@ const _inverseTransition = transition => {
|
|
|
30
32
|
|
|
31
33
|
const ref0 = value.ref[0]
|
|
32
34
|
if (value.ref.length > 1) {
|
|
33
|
-
const nested = inverseTransition.mapping.get(ref0) || {
|
|
35
|
+
const nested = inverseTransition.mapping.get(ref0) || {}
|
|
36
|
+
if (!nested.transition) nested.transition = { mapping: new Map() }
|
|
34
37
|
let current = nested.transition.mapping
|
|
35
38
|
for (let i = 1; i < value.ref.length; i++) {
|
|
36
39
|
const last = i === value.ref.length - 1
|
|
@@ -49,15 +52,15 @@ const _inverseTransition = transition => {
|
|
|
49
52
|
return inverseTransition
|
|
50
53
|
}
|
|
51
54
|
|
|
52
|
-
const revertData = (data, transition) => {
|
|
55
|
+
const revertData = (data, transition, service) => {
|
|
53
56
|
if (!transition || !transition.mapping.size) return data
|
|
54
57
|
const inverseTransition = _inverseTransition(transition)
|
|
55
58
|
return Array.isArray(data)
|
|
56
|
-
? data.map(entry => _newData(entry, inverseTransition, true))
|
|
57
|
-
: _newData(data, inverseTransition, true)
|
|
59
|
+
? data.map(entry => _newData(entry, inverseTransition, true, service))
|
|
60
|
+
: _newData(data, inverseTransition, true, service)
|
|
58
61
|
}
|
|
59
62
|
|
|
60
|
-
const _newSubData = (newData, key, transition, el, inverse) => {
|
|
63
|
+
const _newSubData = (newData, key, transition, el, inverse, service) => {
|
|
61
64
|
const val = newData[key]
|
|
62
65
|
if ((!Array.isArray(val) && typeof val === 'object') || (Array.isArray(val) && val.length !== 0)) {
|
|
63
66
|
let mapped = transition.mapping.get(key)
|
|
@@ -66,13 +69,13 @@ const _newSubData = (newData, key, transition, el, inverse) => {
|
|
|
66
69
|
transition.mapping.set(key, mapped)
|
|
67
70
|
}
|
|
68
71
|
if (!mapped.transition) {
|
|
69
|
-
const subTransition = getTransition(el._target)
|
|
72
|
+
const subTransition = getTransition(el._target, service)
|
|
70
73
|
mapped.transition = inverse ? _inverseTransition(subTransition) : subTransition
|
|
71
74
|
}
|
|
72
75
|
if (Array.isArray(val)) {
|
|
73
|
-
newData[key] = val.map(singleVal => _newData(singleVal, mapped.transition, inverse))
|
|
76
|
+
newData[key] = val.map(singleVal => _newData(singleVal, mapped.transition, inverse, service))
|
|
74
77
|
} else {
|
|
75
|
-
newData[key] = _newData(val, mapped.transition, inverse)
|
|
78
|
+
newData[key] = _newData(val, mapped.transition, inverse, service)
|
|
76
79
|
}
|
|
77
80
|
}
|
|
78
81
|
}
|
|
@@ -94,7 +97,7 @@ const _newNestedData = (queryTarget, newData, ref, value) => {
|
|
|
94
97
|
}
|
|
95
98
|
}
|
|
96
99
|
|
|
97
|
-
const _newData = (data, transition, inverse) => {
|
|
100
|
+
const _newData = (data, transition, inverse, service) => {
|
|
98
101
|
// no transition -> nothing to do
|
|
99
102
|
if (transition.target && transition.target.name === transition.queryTarget.name) return data
|
|
100
103
|
|
|
@@ -108,12 +111,17 @@ const _newData = (data, transition, inverse) => {
|
|
|
108
111
|
for (const key in newData) {
|
|
109
112
|
const el = queryTarget && queryTarget.elements && queryTarget.elements[key]
|
|
110
113
|
const isAssoc = el && el.isAssociation
|
|
111
|
-
if (isAssoc)
|
|
114
|
+
if (isAssoc) {
|
|
115
|
+
if (newData[key] || (newData[key] === null && service.name === 'db')) {
|
|
116
|
+
_newSubData(newData, key, transition, el, inverse, service)
|
|
117
|
+
}
|
|
118
|
+
}
|
|
112
119
|
|
|
113
120
|
const mapped = transition.mapping.get(key)
|
|
114
121
|
if (!mapped) {
|
|
115
122
|
// if there is no mapping and no element with the same name in the target, then we don't need the data
|
|
116
|
-
if (typeof newData[key] !== 'object' && !transition.target.elements[key])
|
|
123
|
+
if ((typeof newData[key] !== 'object' || newData[key] === null) && !transition.target.elements[key])
|
|
124
|
+
delete newData[key]
|
|
117
125
|
continue
|
|
118
126
|
}
|
|
119
127
|
|
|
@@ -140,7 +148,7 @@ const _newData = (data, transition, inverse) => {
|
|
|
140
148
|
return newData
|
|
141
149
|
}
|
|
142
150
|
|
|
143
|
-
const _newColumns = (columns = [], transition,
|
|
151
|
+
const _newColumns = (columns = [], transition, service, withAlias = false) => {
|
|
144
152
|
const newColumns = []
|
|
145
153
|
|
|
146
154
|
columns.forEach(column => {
|
|
@@ -165,11 +173,21 @@ const _newColumns = (columns = [], transition, force = false, withAlias = false)
|
|
|
165
173
|
|
|
166
174
|
// ensure that renaming of a redirected assoc are also respected
|
|
167
175
|
if (column.expand) {
|
|
176
|
+
// column.ref might be structured elements
|
|
177
|
+
let def
|
|
178
|
+
column.ref.forEach((ref, i) => {
|
|
179
|
+
if (i === 0) {
|
|
180
|
+
def = transition.queryTarget.elements[ref]
|
|
181
|
+
} else {
|
|
182
|
+
def = def.elements[ref]
|
|
183
|
+
}
|
|
184
|
+
})
|
|
185
|
+
|
|
168
186
|
// reuse _newColumns with new transition
|
|
169
|
-
const expandTarget =
|
|
170
|
-
const subtransition = getTransition(expandTarget,
|
|
187
|
+
const expandTarget = def._target
|
|
188
|
+
const subtransition = getTransition(expandTarget, service)
|
|
171
189
|
|
|
172
|
-
newColumn.expand = _newColumns(column.expand, subtransition,
|
|
190
|
+
newColumn.expand = _newColumns(column.expand, subtransition, service, withAlias)
|
|
173
191
|
}
|
|
174
192
|
newColumns.push(newColumn)
|
|
175
193
|
})
|
|
@@ -192,19 +210,44 @@ const _newInsertColumns = (columns = [], transition) => {
|
|
|
192
210
|
return newColumns
|
|
193
211
|
}
|
|
194
212
|
|
|
195
|
-
const
|
|
213
|
+
const _newWhereRef = (newWhereElement, transition, alias, tableName, isSubSelect) => {
|
|
214
|
+
const newRef = Array.isArray(newWhereElement.ref) ? [...newWhereElement.ref] : [newWhereElement.ref]
|
|
215
|
+
if (newRef[0] === alias) {
|
|
216
|
+
const mapped = transition.mapping.get(newRef[1])
|
|
217
|
+
if (mapped) newRef[1] = mapped.ref[0]
|
|
218
|
+
} else if (newRef[0] === tableName) {
|
|
219
|
+
newRef[0] = transition.target.name
|
|
220
|
+
const mapped = transition.mapping.get(newRef[1])
|
|
221
|
+
if (mapped) newRef[1] = mapped.ref[0]
|
|
222
|
+
} else {
|
|
223
|
+
const mapped = transition.mapping.get(newRef[0])
|
|
224
|
+
if (isSubSelect && mapped) {
|
|
225
|
+
newRef.unshift(transition.target.name)
|
|
226
|
+
newRef[1] = mapped.ref[0]
|
|
227
|
+
} else {
|
|
228
|
+
if (mapped) newRef[0] = mapped.ref[0]
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
newWhereElement.ref = newRef
|
|
232
|
+
}
|
|
196
233
|
|
|
197
|
-
const
|
|
198
|
-
|
|
234
|
+
const _newEntries = (entries = [], transition, service) =>
|
|
235
|
+
entries.map(entry => _newData(entry, transition, false, service))
|
|
199
236
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
237
|
+
const _newWhere = (where = [], transition, tableName, alias, isSubselect = false) => {
|
|
238
|
+
const newWhere = where.map(whereElement => {
|
|
239
|
+
const newWhereElement = { ...whereElement }
|
|
240
|
+
if (!whereElement.ref && !whereElement.SELECT) return whereElement
|
|
241
|
+
if (whereElement.SELECT && whereElement.SELECT.where) {
|
|
242
|
+
newWhereElement.SELECT.where = _newWhere(whereElement.SELECT.where, transition, tableName, alias, true)
|
|
243
|
+
return newWhereElement
|
|
244
|
+
} else {
|
|
245
|
+
if (newWhereElement.ref) {
|
|
246
|
+
_newWhereRef(newWhereElement, transition, alias, tableName, isSubselect)
|
|
247
|
+
return newWhereElement
|
|
248
|
+
} else {
|
|
249
|
+
return whereElement
|
|
250
|
+
}
|
|
208
251
|
}
|
|
209
252
|
})
|
|
210
253
|
|
|
@@ -237,7 +280,7 @@ const _rewriteQueryPath = (path, transitions) => {
|
|
|
237
280
|
if (f.id) {
|
|
238
281
|
return {
|
|
239
282
|
id: target.name,
|
|
240
|
-
where: _newWhere(f.where, transitions[0])
|
|
283
|
+
where: _newWhere(f.where, transitions[0], f.id)
|
|
241
284
|
}
|
|
242
285
|
}
|
|
243
286
|
} else {
|
|
@@ -250,14 +293,14 @@ const _rewriteQueryPath = (path, transitions) => {
|
|
|
250
293
|
const transitionMapping = transitions[i - 1].mapping.get(f.id)
|
|
251
294
|
return {
|
|
252
295
|
id: (transitionMapping && transitionMapping.ref && transitionMapping.ref[0]) || f.id,
|
|
253
|
-
where: _newWhere(f.where, transitions[i])
|
|
296
|
+
where: _newWhere(f.where, transitions[i], f.id)
|
|
254
297
|
}
|
|
255
298
|
}
|
|
256
299
|
}
|
|
257
300
|
})
|
|
258
301
|
}
|
|
259
302
|
|
|
260
|
-
const _newUpdate = (query, transitions) => {
|
|
303
|
+
const _newUpdate = (query, transitions, service) => {
|
|
261
304
|
const targetTransition = transitions[transitions.length - 1]
|
|
262
305
|
const targetName = targetTransition.target.name
|
|
263
306
|
const newUpdate = { ...query.UPDATE }
|
|
@@ -267,9 +310,16 @@ const _newUpdate = (query, transitions) => {
|
|
|
267
310
|
ref: _rewriteQueryPath(query.UPDATE.entity, transitions)
|
|
268
311
|
}
|
|
269
312
|
: targetName
|
|
270
|
-
if (newUpdate.data) newUpdate.data = _newData(newUpdate.data, targetTransition)
|
|
271
|
-
if (newUpdate.with) newUpdate.with = _newData(newUpdate.with, targetTransition)
|
|
272
|
-
if (newUpdate.where)
|
|
313
|
+
if (newUpdate.data) newUpdate.data = _newData(newUpdate.data, targetTransition, false, service)
|
|
314
|
+
if (newUpdate.with) newUpdate.with = _newData(newUpdate.with, targetTransition, false, service)
|
|
315
|
+
if (newUpdate.where) {
|
|
316
|
+
newUpdate.where = _newWhere(
|
|
317
|
+
newUpdate.where,
|
|
318
|
+
targetTransition,
|
|
319
|
+
getEntityNameFromUpdateCQN(query),
|
|
320
|
+
query.UPDATE.entity.as
|
|
321
|
+
)
|
|
322
|
+
}
|
|
273
323
|
Object.defineProperty(newUpdate, '_transitions', {
|
|
274
324
|
enumerable: false,
|
|
275
325
|
value: transitions
|
|
@@ -277,7 +327,7 @@ const _newUpdate = (query, transitions) => {
|
|
|
277
327
|
return newUpdate
|
|
278
328
|
}
|
|
279
329
|
|
|
280
|
-
const _newSelect = (query, transitions,
|
|
330
|
+
const _newSelect = (query, transitions, service) => {
|
|
281
331
|
const targetTransition = transitions[transitions.length - 1]
|
|
282
332
|
const newSelect = { ...query.SELECT }
|
|
283
333
|
newSelect.from = {
|
|
@@ -285,11 +335,19 @@ const _newSelect = (query, transitions, force) => {
|
|
|
285
335
|
ref: _rewriteQueryPath(query.SELECT.from, transitions)
|
|
286
336
|
}
|
|
287
337
|
if (!newSelect.columns && targetTransition.mapping.size) newSelect.columns = _initialColumns(targetTransition)
|
|
288
|
-
if (newSelect.columns)
|
|
338
|
+
if (newSelect.columns)
|
|
339
|
+
newSelect.columns = _newColumns(newSelect.columns, targetTransition, service, service.kind !== 'app-service')
|
|
289
340
|
if (newSelect.having) newSelect.having = _newColumns(newSelect.having, targetTransition)
|
|
290
341
|
if (newSelect.groupBy) newSelect.groupBy = _newColumns(newSelect.groupBy, targetTransition)
|
|
291
342
|
if (newSelect.orderBy) newSelect.orderBy = _newColumns(newSelect.orderBy, targetTransition)
|
|
292
|
-
if (newSelect.where)
|
|
343
|
+
if (newSelect.where) {
|
|
344
|
+
newSelect.where = _newWhere(
|
|
345
|
+
newSelect.where,
|
|
346
|
+
targetTransition,
|
|
347
|
+
query.SELECT.from && query.SELECT.from.ref[0],
|
|
348
|
+
query.SELECT.from && query.SELECT.from.as
|
|
349
|
+
)
|
|
350
|
+
}
|
|
293
351
|
Object.defineProperty(newSelect, '_transitions', {
|
|
294
352
|
enumerable: false,
|
|
295
353
|
value: transitions
|
|
@@ -297,7 +355,7 @@ const _newSelect = (query, transitions, force) => {
|
|
|
297
355
|
return newSelect
|
|
298
356
|
}
|
|
299
357
|
|
|
300
|
-
const _newInsert = (query, transitions) => {
|
|
358
|
+
const _newInsert = (query, transitions, service) => {
|
|
301
359
|
const targetTransition = transitions[transitions.length - 1]
|
|
302
360
|
const targetName = targetTransition.target.name
|
|
303
361
|
const newInsert = { ...query.INSERT }
|
|
@@ -308,7 +366,7 @@ const _newInsert = (query, transitions) => {
|
|
|
308
366
|
}
|
|
309
367
|
: targetName
|
|
310
368
|
if (newInsert.columns) newInsert.columns = _newInsertColumns(newInsert.columns, targetTransition)
|
|
311
|
-
if (newInsert.entries) newInsert.entries = _newEntries(newInsert.entries, targetTransition)
|
|
369
|
+
if (newInsert.entries) newInsert.entries = _newEntries(newInsert.entries, targetTransition, service)
|
|
312
370
|
Object.defineProperty(newInsert, '_transitions', {
|
|
313
371
|
enumerable: false,
|
|
314
372
|
value: transitions
|
|
@@ -326,7 +384,14 @@ const _newDelete = (query, transitions) => {
|
|
|
326
384
|
ref: _rewriteQueryPath(query.DELETE.from, transitions)
|
|
327
385
|
}
|
|
328
386
|
: targetName
|
|
329
|
-
if (newDelete.where)
|
|
387
|
+
if (newDelete.where) {
|
|
388
|
+
newDelete.where = _newWhere(
|
|
389
|
+
newDelete.where,
|
|
390
|
+
targetTransition,
|
|
391
|
+
getEntityNameFromDeleteCQN(query),
|
|
392
|
+
query.DELETE.from.as
|
|
393
|
+
)
|
|
394
|
+
}
|
|
330
395
|
Object.defineProperty(newDelete, '_transitions', {
|
|
331
396
|
enumerable: false,
|
|
332
397
|
value: transitions
|
|
@@ -334,73 +399,41 @@ const _newDelete = (query, transitions) => {
|
|
|
334
399
|
return newDelete
|
|
335
400
|
}
|
|
336
401
|
|
|
337
|
-
const _isPersistenceTable = target =>
|
|
338
|
-
|
|
339
|
-
const hasOwnProperty = Object.prototype.hasOwnProperty
|
|
340
|
-
const isPersistenceTable = hasOwnProperty.call(target, persistenceTableTerm) && target[persistenceTableTerm]
|
|
341
|
-
return isPersistenceTable
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
const _queryColumns = (target, force = false) => {
|
|
345
|
-
const columns = (target && target.query && target.query.SELECT && target.query.SELECT.columns) || []
|
|
346
|
-
if (force) return columns
|
|
347
|
-
|
|
348
|
-
// If the entity is annotated with the annotation `@cds.persistence.table`
|
|
349
|
-
// and elements aliases exist, the aliases must be used as column references.
|
|
350
|
-
// The reason is that in this scenario, the cds compiler generate a table
|
|
351
|
-
// instead of a view.
|
|
352
|
-
if (_isPersistenceTable(target)) {
|
|
353
|
-
return columns.map(column => {
|
|
354
|
-
return { ref: [column.as || column.ref[0]] }
|
|
355
|
-
})
|
|
356
|
-
}
|
|
402
|
+
const _isPersistenceTable = target =>
|
|
403
|
+
Object.prototype.hasOwnProperty.call(target, PERSISTENCE_TABLE) && target[PERSISTENCE_TABLE]
|
|
357
404
|
|
|
358
|
-
|
|
359
|
-
|
|
405
|
+
const _findRenamed = (cqnColumns, column) =>
|
|
406
|
+
cqnColumns.find(
|
|
407
|
+
cqnColumn =>
|
|
408
|
+
cqnColumn.as &&
|
|
409
|
+
((column.ref && column.ref[column.ref.length - 1] === cqnColumn.as) ||
|
|
410
|
+
(column.as === cqnColumn.as && Object.prototype.hasOwnProperty.call(cqnColumn, 'val')))
|
|
411
|
+
)
|
|
360
412
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
const
|
|
364
|
-
|
|
365
|
-
const
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
)
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
const aliasOfTargetEntity = target.query.SELECT && target.query.SELECT.from && target.query.SELECT.from.as
|
|
380
|
-
renamedColumn.ref =
|
|
381
|
-
aliasOfTargetEntity && queryColumn.ref[0] === aliasOfTargetEntity ? queryColumn.ref.slice(1) : queryColumn.ref
|
|
382
|
-
}
|
|
383
|
-
if (queryColumn.val) renamedColumn.val = queryColumn.val
|
|
384
|
-
return renamedColumn
|
|
413
|
+
const _queryColumns = (target, columns = [], persistenceTable = false, force = false) => {
|
|
414
|
+
if (!(target && target.query && target.query.SELECT)) return columns
|
|
415
|
+
const cqnColumns = target.query.SELECT.columns || []
|
|
416
|
+
const from = target.query.SELECT.from
|
|
417
|
+
const isTargetAliased = from.as && !target.query._target.query && cqnColumns.some(c => c.ref && c.ref[0] === from.as)
|
|
418
|
+
if (!columns.length) columns = Object.keys(target.elements).map(e => ({ ref: [e], as: e }))
|
|
419
|
+
return columns.reduce((res, column) => {
|
|
420
|
+
const renamed = _findRenamed(cqnColumns, column)
|
|
421
|
+
if (renamed) {
|
|
422
|
+
if (renamed.val) return res.concat({ as: renamed.as, val: renamed.val })
|
|
423
|
+
// There could be some `where` clause inside `ref` which we don't support yet
|
|
424
|
+
if (!renamed.ref || renamed.ref.some(e => typeof e !== 'string') || renamed.xpr) return res
|
|
425
|
+
if (isTargetAliased) renamed.ref.shift()
|
|
426
|
+
// If the entity is annotated with the annotation `@cds.persistence.table`
|
|
427
|
+
// and elements aliases exist, the aliases must be used as column references.
|
|
428
|
+
// The reason is that in this scenario, the cds compiler generate a table
|
|
429
|
+
// instead of a view. If forced, skip this.
|
|
430
|
+
column.ref = !force && persistenceTable ? [renamed.as] : [...renamed.ref]
|
|
385
431
|
}
|
|
386
|
-
|
|
387
|
-
return column
|
|
388
|
-
})
|
|
389
|
-
|
|
390
|
-
return renamedColumns
|
|
432
|
+
res.push(column)
|
|
433
|
+
return _appendForeignKeys(res, target, columns, column)
|
|
434
|
+
}, [])
|
|
391
435
|
}
|
|
392
436
|
|
|
393
|
-
const _merge = (aliased, inherited) =>
|
|
394
|
-
inherited.reduce(
|
|
395
|
-
(res, el1) =>
|
|
396
|
-
(!aliased.some(el2 => el2.ref && ((el1.as && el2.ref[0] === el1.as) || (el1.ref && el2.ref[0] === el1.ref[0]))) &&
|
|
397
|
-
res.concat(el1)) ||
|
|
398
|
-
res,
|
|
399
|
-
[]
|
|
400
|
-
)
|
|
401
|
-
|
|
402
|
-
const _starColumns = elements => Object.keys(elements).map(element => ({ ref: [element] }))
|
|
403
|
-
|
|
404
437
|
const _mappedValue = (col, alias) => {
|
|
405
438
|
const key = col.as || col.ref[0]
|
|
406
439
|
|
|
@@ -412,35 +445,33 @@ const _mappedValue = (col, alias) => {
|
|
|
412
445
|
return [key, { val: col.val }]
|
|
413
446
|
}
|
|
414
447
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
const _isProjection = (target, force) => target.query && target.query._target && (force || !_isPersistenceTable(target))
|
|
419
|
-
|
|
420
|
-
const getDBTable = (target, force) => {
|
|
421
|
-
if (_isProjection(target, force)) {
|
|
422
|
-
return getDBTable(target.query._target, force)
|
|
448
|
+
const getDBTable = target => {
|
|
449
|
+
if (target.query && target.query._target && !_isPersistenceTable(target)) {
|
|
450
|
+
return getDBTable(target.query._target)
|
|
423
451
|
}
|
|
424
452
|
return target
|
|
425
453
|
}
|
|
426
454
|
|
|
427
|
-
const
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
const
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
455
|
+
const _appendForeignKeys = (newColumns, target, columns, { as, ref = [] }) => {
|
|
456
|
+
const el = target.elements[as] || target.query._target.elements[ref[ref.length - 1]]
|
|
457
|
+
if (el && el.isAssociation && el.keys) {
|
|
458
|
+
for (const key of el.keys) {
|
|
459
|
+
// .as and .ref has a different meaning here
|
|
460
|
+
// .as means the original property name, if the foreign key is renamed
|
|
461
|
+
const keyName = key.as || key.ref[0]
|
|
462
|
+
const keyAlias = key.ref[0]
|
|
463
|
+
const found = columns.find(col => col.as === `${as}_${keyAlias}`)
|
|
464
|
+
if (found) {
|
|
465
|
+
found.ref = [`${ref.join('_')}_${keyName}`]
|
|
466
|
+
} else {
|
|
467
|
+
newColumns.push({
|
|
468
|
+
ref: [`${ref.join('_')}_${keyName}`],
|
|
469
|
+
as: `${as}_${keyAlias}`
|
|
440
470
|
})
|
|
441
471
|
}
|
|
442
472
|
}
|
|
443
473
|
}
|
|
474
|
+
return newColumns
|
|
444
475
|
}
|
|
445
476
|
|
|
446
477
|
const _checkForForbiddenViews = queryTarget => {
|
|
@@ -461,43 +492,24 @@ const _checkForForbiddenViews = queryTarget => {
|
|
|
461
492
|
}
|
|
462
493
|
}
|
|
463
494
|
|
|
464
|
-
const
|
|
465
|
-
if (columns.length > 0) return columns
|
|
466
|
-
|
|
467
|
-
const cqnColumns = _queryColumns(target, force)
|
|
468
|
-
|
|
469
|
-
const plainColumns = cqnColumns
|
|
470
|
-
// There could be some `where` clause inside `ref` which we don't support yet
|
|
471
|
-
.filter(c => c !== '*' && !(c.ref && c.ref.some(ele => typeof ele !== 'string')) && !c.xpr)
|
|
472
|
-
.map(c => ({ ref: (c.as && [c.as]) || c.ref }))
|
|
473
|
-
_includeForeignKeys(columns, target, force)
|
|
474
|
-
|
|
475
|
-
const _target = target.query && target.query._target
|
|
476
|
-
if (_target && cqnColumns.some(c => c === '*')) {
|
|
477
|
-
// 'alias' is required to properly perform mapping
|
|
478
|
-
const starColumns = _starColumns(_target.elements).map(c => (c.as && c) || { as: c.ref[0], ref: c.ref })
|
|
479
|
-
columns.push(..._merge(plainColumns, starColumns))
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
columns.push(...plainColumns)
|
|
483
|
-
|
|
484
|
-
return columns
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
const _getTransitionData = (target, columns, force, skipForbiddenViewCheck) => {
|
|
495
|
+
const _getTransitionData = (target, columns, service, skipForbiddenViewCheck) => {
|
|
488
496
|
// REVISIT: Find less param polluting way to skip forbidden view check for reads
|
|
489
497
|
if (!skipForbiddenViewCheck) _checkForForbiddenViews(target)
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
498
|
+
const targetStartsWithSrvName = service.namespace && target.name.startsWith(`${service.namespace}.`)
|
|
499
|
+
const persistenceTable = _isPersistenceTable(target)
|
|
500
|
+
columns = _queryColumns(target, columns, persistenceTable, service.name !== 'db' && !targetStartsWithSrvName)
|
|
501
|
+
if (persistenceTable && service.name === 'db') {
|
|
502
|
+
return { target, transitionColumns: columns }
|
|
493
503
|
}
|
|
494
|
-
|
|
495
|
-
if (
|
|
496
|
-
|
|
504
|
+
// stop projection resolving if it starts with the service name prefix or if there is nothing to resolve anymore
|
|
505
|
+
if ((service.name !== 'db' && targetStartsWithSrvName) || !(target.query && target.query._target)) {
|
|
506
|
+
return { target, transitionColumns: columns }
|
|
507
|
+
}
|
|
508
|
+
// continue projection resolving if the target is a projection
|
|
509
|
+
if (target.query && target.query._target) {
|
|
497
510
|
const newTarget = target.query._target
|
|
498
|
-
return _getTransitionData(newTarget, columns,
|
|
511
|
+
return _getTransitionData(newTarget, columns, service, skipForbiddenViewCheck)
|
|
499
512
|
}
|
|
500
|
-
|
|
501
513
|
return { target, transitionColumns: columns }
|
|
502
514
|
}
|
|
503
515
|
|
|
@@ -505,16 +517,16 @@ const _getTransitionData = (target, columns, force, skipForbiddenViewCheck) => {
|
|
|
505
517
|
* If no entity definition is found, no transition is done.
|
|
506
518
|
*
|
|
507
519
|
* @param queryTarget
|
|
508
|
-
* @param
|
|
520
|
+
* @param service
|
|
509
521
|
* @param skipForbiddenViewCheck
|
|
510
522
|
*/
|
|
511
|
-
const getTransition = (queryTarget,
|
|
523
|
+
const getTransition = (queryTarget, service, skipForbiddenViewCheck) => {
|
|
512
524
|
// Never resolve unknown targets (e.g. for drafts)
|
|
513
|
-
if (!queryTarget
|
|
525
|
+
if (!queryTarget) {
|
|
514
526
|
return { target: queryTarget, queryTarget, mapping: new Map() }
|
|
515
527
|
}
|
|
516
528
|
|
|
517
|
-
const { target: _target, transitionColumns } = _getTransitionData(queryTarget, [],
|
|
529
|
+
const { target: _target, transitionColumns } = _getTransitionData(queryTarget, [], service, skipForbiddenViewCheck)
|
|
518
530
|
const query = queryTarget.query
|
|
519
531
|
const alias = query && query.SELECT && query.SELECT.from && query.SELECT.from.as
|
|
520
532
|
const mappedColumns = transitionColumns.map(column => _mappedValue(column, alias))
|
|
@@ -522,11 +534,11 @@ const getTransition = (queryTarget, force, skipForbiddenViewCheck) => {
|
|
|
522
534
|
return { target: _target, queryTarget, mapping }
|
|
523
535
|
}
|
|
524
536
|
|
|
525
|
-
const _entityTransitionsForTarget = (from, model,
|
|
537
|
+
const _entityTransitionsForTarget = (from, model, service) => {
|
|
526
538
|
let previousEntity
|
|
527
539
|
|
|
528
540
|
if (typeof from === 'string') {
|
|
529
|
-
return model.definitions[from] && [getTransition(model.definitions[from],
|
|
541
|
+
return model.definitions[from] && [getTransition(model.definitions[from], service)]
|
|
530
542
|
}
|
|
531
543
|
|
|
532
544
|
return from.ref.map((f, i) => {
|
|
@@ -536,22 +548,30 @@ const _entityTransitionsForTarget = (from, model, force) => {
|
|
|
536
548
|
const entity = model.definitions[element]
|
|
537
549
|
if (entity) {
|
|
538
550
|
previousEntity = entity
|
|
539
|
-
return getTransition(entity,
|
|
551
|
+
return getTransition(entity, service)
|
|
540
552
|
}
|
|
541
553
|
}
|
|
542
554
|
|
|
543
555
|
if (previousEntity) {
|
|
544
556
|
const entity = previousEntity.elements[element] && previousEntity.elements[element]._target
|
|
545
|
-
|
|
546
557
|
if (entity) {
|
|
558
|
+
// > assoc
|
|
547
559
|
previousEntity = entity
|
|
548
|
-
return getTransition(entity,
|
|
560
|
+
return getTransition(entity, service)
|
|
561
|
+
} else {
|
|
562
|
+
// > struct
|
|
563
|
+
previousEntity = previousEntity.elements[element]
|
|
564
|
+
return {
|
|
565
|
+
target: previousEntity,
|
|
566
|
+
queryTarget: previousEntity,
|
|
567
|
+
mapping: new Map()
|
|
568
|
+
}
|
|
549
569
|
}
|
|
550
570
|
}
|
|
551
571
|
})
|
|
552
572
|
}
|
|
553
573
|
|
|
554
|
-
const _newQuery = (query, event, model,
|
|
574
|
+
const _newQuery = (query, event, model, service) => {
|
|
555
575
|
const [_prop, _func] = {
|
|
556
576
|
SELECT: ['from', _newSelect],
|
|
557
577
|
INSERT: ['into', _newInsert],
|
|
@@ -559,25 +579,25 @@ const _newQuery = (query, event, model, force) => {
|
|
|
559
579
|
DELETE: ['from', _newDelete]
|
|
560
580
|
}[event]
|
|
561
581
|
const newQuery = Object.create(query)
|
|
562
|
-
const transitions = _entityTransitionsForTarget(query[event][_prop], model,
|
|
563
|
-
newQuery[event] = (transitions[0] && _func(newQuery, transitions,
|
|
582
|
+
const transitions = _entityTransitionsForTarget(query[event][_prop], model, service)
|
|
583
|
+
newQuery[event] = (transitions[0] && _func(newQuery, transitions, service)) || { ...query[event] }
|
|
564
584
|
return newQuery
|
|
565
585
|
}
|
|
566
586
|
|
|
567
|
-
const resolveView = (query, model,
|
|
587
|
+
const resolveView = (query, model, service) => {
|
|
568
588
|
// swap logger
|
|
569
589
|
const _LOG = LOG
|
|
570
|
-
LOG = cds.log(
|
|
590
|
+
LOG = cds.log(service.kind) // REVISIT: Avoid obtaining loggers per request!
|
|
571
591
|
|
|
572
592
|
// If the query is a projection, one must follow it
|
|
573
593
|
// to let the underlying service know its true entity.
|
|
594
|
+
if (query.cmd) _event = query.cmd
|
|
595
|
+
else if (query.SELECT) _event = 'SELECT'
|
|
596
|
+
else if (query.INSERT) _event = 'INSERT'
|
|
597
|
+
else if (query.UPDATE) _event = 'UPDATE'
|
|
598
|
+
else if (query.DELETE) _event = 'DELETE'
|
|
574
599
|
|
|
575
|
-
|
|
576
|
-
if (query.INSERT) _event = 'INSERT'
|
|
577
|
-
if (query.UPDATE) _event = 'UPDATE'
|
|
578
|
-
if (query.DELETE) _event = 'DELETE'
|
|
579
|
-
|
|
580
|
-
const newQuery = _newQuery(query, _event, model, force)
|
|
600
|
+
const newQuery = _newQuery(query, _event, model, service)
|
|
581
601
|
|
|
582
602
|
// restore logger and clear _event
|
|
583
603
|
LOG = _LOG
|
|
@@ -586,9 +606,43 @@ const resolveView = (query, model, component, force) => {
|
|
|
586
606
|
return newQuery
|
|
587
607
|
}
|
|
588
608
|
|
|
609
|
+
/**
|
|
610
|
+
* Restores the link of req.data and req.query in case req.query was overwritten.
|
|
611
|
+
* Only applicable for UPDATEs and INSERTs.
|
|
612
|
+
*
|
|
613
|
+
* @param {*} req
|
|
614
|
+
*/
|
|
615
|
+
const restoreLink = req => {
|
|
616
|
+
if (req.query.INSERT && req.query.INSERT.entries) {
|
|
617
|
+
if (Array.isArray(req.query.INSERT.entries)) req.data = req.query.INSERT.entries[0]
|
|
618
|
+
else req.data = req.query.INSERT.entries
|
|
619
|
+
} else if (req.query.UPDATE && req.query.UPDATE.data) {
|
|
620
|
+
req.data = req.query.UPDATE.data
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
/**
|
|
625
|
+
* Retrieves the actual query target by evaluating the created transitions.
|
|
626
|
+
* @param {*} q - the resolved query
|
|
627
|
+
* @returns {*} csn entity or undefined
|
|
628
|
+
*/
|
|
629
|
+
const findQueryTarget = q => {
|
|
630
|
+
return q.SELECT
|
|
631
|
+
? q.SELECT._transitions[q.SELECT._transitions.length - 1].target
|
|
632
|
+
: q.INSERT
|
|
633
|
+
? q.INSERT._transitions[q.INSERT._transitions.length - 1].target
|
|
634
|
+
: q.UPDATE
|
|
635
|
+
? q.UPDATE._transitions[q.UPDATE._transitions.length - 1].target
|
|
636
|
+
: q.DELETE
|
|
637
|
+
? q.DELETE._transitions[q.DELETE._transitions.length - 1].target
|
|
638
|
+
: undefined
|
|
639
|
+
}
|
|
640
|
+
|
|
589
641
|
module.exports = {
|
|
642
|
+
findQueryTarget,
|
|
590
643
|
getDBTable,
|
|
591
644
|
resolveView,
|
|
592
645
|
getTransition,
|
|
646
|
+
restoreLink,
|
|
593
647
|
revertData
|
|
594
648
|
}
|