@sap/cds 5.9.7 → 6.0.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 +267 -20
- package/apis/services.d.ts +1 -1
- package/app/fiori/preview.js +2 -6
- package/app/index.js +3 -3
- package/bin/build/buildTaskEngine.js +17 -15
- package/bin/build/buildTaskFactory.js +29 -19
- package/bin/build/buildTaskHandler.js +27 -11
- package/bin/build/buildTaskProvider.js +2 -4
- package/bin/build/buildTaskProviderFactory.js +11 -16
- package/bin/build/constants.js +14 -6
- package/bin/build/csv-reader.js +2 -1
- package/bin/build/index.js +12 -18
- package/bin/build/provider/buildTaskHandlerEdmx.js +3 -39
- package/bin/build/provider/buildTaskHandlerFeatureToggles.js +149 -0
- package/bin/build/provider/buildTaskHandlerInternal.js +2 -3
- package/bin/build/provider/buildTaskProviderInternal.js +108 -239
- package/bin/build/provider/fiori/index.js +2 -2
- package/bin/build/provider/hana/2migration.js +11 -11
- package/bin/build/provider/hana/2tabledata.js +3 -3
- package/bin/build/provider/hana/index.js +89 -99
- package/bin/build/provider/hana/migrationtable.js +4 -3
- package/bin/build/provider/java/index.js +101 -0
- package/bin/build/provider/java-cf/index.js +1 -101
- package/bin/build/provider/mtx/index.js +90 -53
- package/bin/build/provider/mtx/resourcesTarBuilder.js +68 -0
- package/bin/build/provider/mtx-sidecar/index.js +110 -0
- package/bin/build/provider/node-cf/index.js +1 -308
- package/bin/build/provider/nodejs/index.js +189 -0
- package/bin/build/util.js +19 -31
- package/bin/cds.js +5 -3
- package/bin/deploy/to-hana/cfUtil.js +31 -6
- package/bin/deploy/to-hana/gitUtil.js +5 -3
- package/bin/deploy/to-hana/hana.js +9 -10
- package/bin/{build → deploy/to-hana}/mtaUtil.js +10 -9
- package/bin/mtx/in-cds.js +19 -7
- package/bin/serve.js +56 -21
- package/bin/utils/log.js +13 -30
- package/bin/version.js +5 -4
- package/common.cds +61 -16
- package/lib/compile/cdsc.js +3 -2
- package/lib/compile/etc/_localized.js +15 -14
- package/lib/compile/for/drafts.js +3 -4
- package/lib/compile/for/java.js +13 -10
- package/lib/compile/for/nodejs.js +8 -8
- package/lib/compile/for/odata.js +7 -12
- package/lib/compile/for/sql.js +5 -6
- package/lib/compile/index.js +5 -4
- package/lib/compile/load.js +9 -11
- package/lib/compile/minify.js +8 -5
- package/lib/compile/parse.js +4 -2
- package/lib/compile/resolve.js +18 -15
- package/lib/compile/to/edm.js +0 -1
- package/lib/compile/to/gql.js +3 -2
- package/lib/compile/to/json.js +24 -17
- package/lib/connect/bindings.js +3 -2
- package/lib/connect/index.js +5 -5
- package/lib/core/classes.js +74 -2
- package/lib/core/entities.js +52 -3
- package/lib/core/reflect.js +2 -1
- package/lib/deploy.js +11 -8
- package/lib/env/defaults.js +4 -3
- package/lib/env/index.js +71 -31
- package/lib/env/presets.js +1 -14
- package/lib/env/requires.js +71 -20
- package/lib/env/serviceBindings.js +147 -0
- package/lib/i18n/localize.js +22 -23
- package/lib/index.js +148 -144
- package/lib/log/errors.js +55 -12
- package/lib/log/format/kibana.js +1 -1
- package/lib/log/index.js +4 -0
- package/lib/ql/SELECT.js +7 -2
- package/lib/ql/Whereable.js +8 -2
- package/lib/ql/index.js +2 -2
- package/lib/req/assert.js +71 -0
- package/lib/req/cds-context.js +38 -70
- package/lib/req/context.js +34 -21
- package/lib/req/request.js +12 -18
- package/lib/req/response.js +6 -2
- package/lib/req/user.js +30 -22
- package/lib/serve/Service-api.js +17 -12
- package/lib/serve/Service-dispatch.js +5 -9
- package/lib/serve/Service-methods.js +4 -3
- package/lib/serve/Transaction.js +24 -21
- package/lib/serve/adapters.js +15 -5
- package/lib/serve/factory.js +23 -20
- package/lib/serve/index.js +51 -54
- package/lib/utils/axios.js +8 -12
- package/lib/utils/index.js +3 -3
- package/lib/utils/resources/index.js +1 -44
- package/lib/utils/resources/tar.js +2 -1
- package/lib/utils/tests.js +13 -15
- package/libx/_runtime/.eslintrc +1 -1
- package/libx/_runtime/audit/Service.js +6 -4
- package/libx/_runtime/audit/generic/personal/access.js +19 -43
- package/libx/_runtime/audit/generic/personal/index.js +40 -34
- package/libx/_runtime/audit/generic/personal/modification.js +11 -9
- package/libx/_runtime/audit/generic/personal/utils.js +13 -6
- package/libx/_runtime/audit/utils/v2.js +6 -3
- package/libx/_runtime/auth/index.js +71 -66
- package/libx/_runtime/auth/strategies/JWT.js +3 -2
- package/libx/_runtime/auth/strategies/mock.js +54 -53
- package/libx/_runtime/auth/strategies/xssecUtils.js +3 -4
- package/libx/_runtime/auth/strategies/xsuaa.js +3 -2
- package/libx/_runtime/auth/utils.js +2 -15
- package/libx/_runtime/cds-services/adapter/odata-v4/Dispatcher.js +128 -42
- package/libx/_runtime/cds-services/adapter/odata-v4/OData.js +6 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/ODataRequest.js +93 -73
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/action.js +10 -45
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/create.js +5 -9
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/error.js +9 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/metadata.js +4 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/read.js +60 -53
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/request.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/handlers/update.js +15 -21
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/ExpressionToCQN.js +8 -15
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/expandToCQN.js +29 -41
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/index.js +1 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/readToCQN.js +13 -13
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/selectToCQN.js +0 -7
- package/libx/_runtime/cds-services/adapter/odata-v4/odata-to-cqn/utils.js +24 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/edm/EdmEntityContainer.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/uri/UriHelper.js +4 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/utils/PrimitiveValueDecoder.js +4 -5
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/utils/ValueConverter.js +4 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-commons/validator/ValueValidator.js +5 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/core/ResponseHeaderSetter.js +2 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/DebugSerializingCommand.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/PresetResponseHeadersCommand.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/SerializingCommand.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/invocation/SetResponseHeadersCommand.js +1 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/ContextURLFactory.js +3 -2
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/ErrorJsonSerializer.js +3 -1
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/SerializerFactory.js +1 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/okra/odata-server/serializer/TrustedResourceJsonSerializer.js +3 -3
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/data.js +36 -25
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/handlerUtils.js +100 -91
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/metaInfo.js +382 -0
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/oDataConfiguration.js +1 -4
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/omitValues.js +5 -6
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/readAfterWrite.js +77 -21
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/request.js +3 -11
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/result.js +91 -69
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/stream.js +27 -6
- package/libx/_runtime/cds-services/adapter/rest/utils/validation-checks.js +7 -17
- package/libx/_runtime/cds-services/services/Service.js +17 -76
- package/libx/_runtime/cds-services/services/utils/columns.js +6 -4
- package/libx/_runtime/cds-services/services/utils/compareJson.js +1 -53
- package/libx/_runtime/cds-services/services/utils/differ.js +15 -19
- package/libx/_runtime/cds-services/util/assert.js +107 -34
- package/libx/_runtime/cds.js +1 -31
- package/libx/_runtime/common/aspects/Association.js +40 -54
- package/libx/_runtime/common/aspects/any.js +61 -6
- package/libx/_runtime/common/aspects/entity.js +19 -79
- package/libx/_runtime/common/composition/data.js +2 -2
- package/libx/_runtime/common/composition/delete.js +8 -7
- package/libx/_runtime/common/composition/tree.js +10 -10
- package/libx/_runtime/common/composition/update.js +3 -2
- package/libx/_runtime/common/constants/events.js +15 -0
- package/libx/_runtime/common/error/entry.js +9 -3
- package/libx/_runtime/common/error/frontend.js +13 -19
- package/libx/_runtime/common/error/index.js +8 -3
- package/libx/_runtime/common/generic/auth/capabilities.js +2 -1
- package/libx/_runtime/common/generic/auth/constants.js +1 -4
- package/libx/_runtime/common/generic/auth/requires.js +1 -1
- package/libx/_runtime/common/generic/auth/restrict.js +12 -28
- package/libx/_runtime/common/generic/auth/restrictions.js +12 -4
- package/libx/_runtime/common/generic/auth/utils.js +2 -1
- package/libx/_runtime/common/generic/crud.js +9 -60
- package/libx/_runtime/common/generic/etag.js +41 -7
- package/libx/_runtime/common/generic/input.js +128 -66
- package/libx/_runtime/common/generic/paging.js +9 -3
- package/libx/_runtime/common/generic/put.js +2 -2
- package/libx/_runtime/common/generic/sorting.js +7 -3
- package/libx/_runtime/common/generic/temporal.js +0 -5
- package/libx/_runtime/common/i18n/messages.properties +2 -1
- package/libx/_runtime/common/utils/binary.js +69 -0
- package/libx/_runtime/common/utils/cqn.js +39 -14
- package/libx/_runtime/common/utils/cqn2cqn4sql.js +93 -59
- package/libx/_runtime/common/utils/csn.js +87 -85
- package/libx/_runtime/common/utils/dollar.js +8 -7
- package/libx/_runtime/common/utils/draft.js +1 -1
- package/libx/_runtime/common/utils/foreignKeyPropagations.js +23 -7
- package/libx/_runtime/common/utils/generateOnCond.js +2 -1
- package/libx/_runtime/common/utils/keys.js +30 -13
- package/libx/_runtime/common/utils/postProcessing.js +6 -1
- package/libx/_runtime/common/utils/quotingStyles.js +0 -23
- package/libx/_runtime/common/utils/resolveStructured.js +23 -26
- package/libx/_runtime/common/utils/resolveView.js +4 -1
- package/libx/_runtime/common/utils/rewriteAsterisks.js +3 -0
- package/libx/_runtime/common/utils/search2cqn4sql.js +4 -13
- package/libx/_runtime/common/utils/searchToLike.js +9 -13
- package/libx/_runtime/common/utils/streamProp.js +35 -0
- package/libx/_runtime/common/utils/structured.js +12 -18
- package/libx/_runtime/common/utils/template.js +3 -5
- package/libx/_runtime/common/utils/templateProcessor.js +22 -14
- package/libx/_runtime/common/utils/unionCqnTemplate.js +4 -14
- package/libx/_runtime/db/Service.js +2 -1
- package/libx/_runtime/db/expand/expand-v2.js +2 -2
- package/libx/_runtime/db/expand/expandCQNToJoin.js +7 -6
- package/libx/_runtime/db/generic/input.js +14 -17
- package/libx/_runtime/db/generic/integrity.js +1 -2
- package/libx/_runtime/db/generic/update.js +14 -1
- package/libx/_runtime/db/query/read.js +0 -1
- package/libx/_runtime/db/query/update.js +1 -1
- package/libx/_runtime/db/sql-builder/BaseBuilder.js +1 -1
- package/libx/_runtime/db/sql-builder/ExpressionBuilder.js +5 -31
- package/libx/_runtime/db/sql-builder/InsertBuilder.js +1 -1
- package/libx/_runtime/db/sql-builder/ReferenceBuilder.js +0 -9
- package/libx/_runtime/db/sql-builder/SelectBuilder.js +11 -10
- package/libx/_runtime/db/sql-builder/UpdateBuilder.js +2 -2
- package/libx/_runtime/db/sql-builder/annotations.js +1 -2
- package/libx/_runtime/db/utils/coloredTxCommands.js +5 -0
- package/libx/_runtime/db/utils/columns.js +1 -1
- package/libx/_runtime/db/utils/propagateForeignKeys.js +10 -2
- package/libx/_runtime/extensibility/activate.js +69 -0
- package/libx/_runtime/extensibility/add.js +41 -0
- package/libx/_runtime/extensibility/addExtension.js +68 -0
- package/libx/_runtime/extensibility/defaults.js +39 -0
- package/libx/_runtime/extensibility/{uiflex/handler → handler}/transformREAD.js +0 -0
- package/libx/_runtime/extensibility/{uiflex/handler → handler}/transformRESULT.js +2 -2
- package/libx/_runtime/extensibility/{uiflex/handler → handler}/transformWRITE.js +2 -2
- package/libx/_runtime/extensibility/push.js +61 -0
- package/libx/_runtime/extensibility/service.js +21 -0
- package/libx/_runtime/extensibility/{uiflex/utils.js → utils.js} +39 -3
- package/libx/_runtime/extensibility/validation.js +53 -0
- package/libx/_runtime/extensibility/views.js +12 -0
- package/libx/_runtime/fiori/generic/activate.js +6 -4
- package/libx/_runtime/fiori/generic/before.js +17 -29
- package/libx/_runtime/fiori/generic/cancel.js +2 -4
- package/libx/_runtime/fiori/generic/delete.js +2 -4
- package/libx/_runtime/fiori/generic/edit.js +3 -7
- package/libx/_runtime/fiori/generic/index.js +31 -0
- package/libx/_runtime/fiori/generic/new.js +2 -4
- package/libx/_runtime/fiori/generic/patch.js +4 -8
- package/libx/_runtime/fiori/generic/prepare.js +2 -4
- package/libx/_runtime/fiori/generic/read.js +137 -162
- package/libx/_runtime/fiori/generic/readOverDraft.js +10 -4
- package/libx/_runtime/fiori/utils/handler.js +10 -5
- package/libx/_runtime/fiori/utils/where.js +1 -4
- package/libx/_runtime/hana/Service.js +14 -7
- package/libx/_runtime/hana/customBuilder/CustomSelectBuilder.js +1 -1
- package/libx/_runtime/hana/dynatrace.js +2 -2
- package/libx/_runtime/hana/localized.js +7 -6
- package/libx/_runtime/hana/pool.js +9 -6
- package/libx/_runtime/hana/search.js +2 -3
- package/libx/_runtime/hana/{searchToContains.js → search2Contains.js} +5 -2
- package/libx/_runtime/hana/search2cqn4sql.js +20 -17
- package/libx/_runtime/index.js +2 -6
- package/libx/_runtime/messaging/AMQPWebhookMessaging.js +11 -2
- package/libx/_runtime/messaging/common-utils/AMQPClient.js +4 -3
- package/libx/_runtime/messaging/common-utils/appId.js +9 -0
- package/libx/_runtime/messaging/common-utils/authorizedRequest.js +2 -18
- package/libx/_runtime/messaging/common-utils/connections.js +1 -1
- package/libx/_runtime/messaging/enterprise-messaging-shared.js +2 -2
- package/libx/_runtime/messaging/enterprise-messaging-utils/EMManagement.js +305 -231
- package/libx/_runtime/messaging/enterprise-messaging-utils/cloudEvents.js +2 -2
- package/libx/_runtime/messaging/enterprise-messaging-utils/options-management.js +15 -8
- package/libx/_runtime/messaging/enterprise-messaging-utils/options-messaging.js +57 -14
- package/libx/_runtime/messaging/enterprise-messaging.js +14 -19
- package/libx/_runtime/messaging/file-based.js +2 -1
- package/libx/_runtime/messaging/http-utils/token.js +18 -6
- package/libx/_runtime/messaging/message-queuing-utils/options-management.js +22 -12
- package/libx/_runtime/messaging/message-queuing-utils/options-messaging.js +27 -14
- package/libx/_runtime/messaging/message-queuing.js +138 -85
- package/libx/_runtime/messaging/outbox/utils.js +13 -7
- package/libx/_runtime/messaging/redis-messaging.js +0 -1
- package/libx/_runtime/messaging/service.js +4 -1
- package/libx/_runtime/remote/Service.js +24 -18
- package/libx/_runtime/remote/utils/client.js +84 -46
- package/libx/_runtime/remote/utils/data.js +23 -6
- package/libx/_runtime/sqlite/Service.js +14 -13
- package/libx/_runtime/sqlite/convertAssocToOneManaged.js +2 -0
- package/libx/_runtime/sqlite/customBuilder/CustomSelectBuilder.js +1 -0
- package/libx/_runtime/sqlite/execute.js +3 -9
- package/libx/_runtime/types/api.js +23 -11
- package/libx/common/utils/ucsn.js +15 -9
- package/libx/odata/afterburner.js +109 -29
- package/libx/odata/cqn2odata.js +48 -9
- package/libx/odata/grammar.pegjs +261 -157
- package/libx/odata/index.js +21 -9
- package/libx/odata/parseToCqn.js +8 -5
- package/libx/odata/parser.js +1 -1
- package/libx/odata/utils.js +13 -3
- package/libx/rest/RestAdapter.js +173 -113
- package/libx/rest/RestRequest.js +3 -2
- package/libx/rest/middleware/create.js +8 -6
- package/libx/rest/middleware/delete.js +6 -13
- package/libx/rest/middleware/error.js +1 -1
- package/libx/rest/middleware/input.js +6 -6
- package/libx/rest/middleware/operation.js +8 -3
- package/libx/rest/middleware/parse.js +3 -3
- package/libx/rest/middleware/payload.js +12 -0
- package/libx/rest/middleware/read.js +12 -2
- package/libx/rest/middleware/update.js +3 -3
- package/package.json +4 -6
- package/server.js +3 -44
- package/srv/extensibility-service.cds +56 -0
- package/srv/extensibility-service.js +1 -0
- package/srv/extensions.cds +8 -0
- package/srv/model-provider.cds +59 -0
- package/srv/model-provider.js +163 -0
- package/srv/mtx.cds +2 -0
- package/srv/mtx.js +22 -0
- package/srv/outbox.cds +2 -0
- package/tasks/enterprise-messaging-deploy.js +19 -12
- package/lib/serve/Service-compat.js +0 -36
- package/libx/_runtime/audit/generic/personal/constants.js +0 -4
- package/libx/_runtime/auth/strategies/dwc.js +0 -45
- package/libx/_runtime/cds-services/adapter/odata-v4/utils/dispatcherUtils.js +0 -56
- package/libx/_runtime/cds-services/adapter/rest/Rest.js +0 -183
- package/libx/_runtime/cds-services/adapter/rest/RestRequest.js +0 -67
- package/libx/_runtime/cds-services/adapter/rest/handlers/create.js +0 -82
- package/libx/_runtime/cds-services/adapter/rest/handlers/delete.js +0 -39
- package/libx/_runtime/cds-services/adapter/rest/handlers/operation.js +0 -63
- package/libx/_runtime/cds-services/adapter/rest/handlers/read.js +0 -52
- package/libx/_runtime/cds-services/adapter/rest/handlers/update.js +0 -81
- package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/index.js +0 -56
- package/libx/_runtime/cds-services/adapter/rest/rest-to-cqn/utils.js +0 -33
- package/libx/_runtime/cds-services/adapter/rest/to.js +0 -8
- package/libx/_runtime/cds-services/adapter/rest/utils/binary.js +0 -50
- package/libx/_runtime/cds-services/adapter/rest/utils/data.js +0 -117
- package/libx/_runtime/cds-services/adapter/rest/utils/header-checks.js +0 -14
- package/libx/_runtime/cds-services/adapter/rest/utils/key-value-utils.js +0 -30
- package/libx/_runtime/cds-services/adapter/rest/utils/parse-url.js +0 -250
- package/libx/_runtime/cds-services/adapter/rest/utils/result.js +0 -26
- package/libx/_runtime/cds-services/services/utils/handlerUtils.js +0 -200
- package/libx/_runtime/common/aspects/utils.js +0 -152
- package/libx/_runtime/common/toggles/handler.js +0 -21
- package/libx/_runtime/common/utils/extensibilityUtils.js +0 -18
- package/libx/_runtime/extensibility/mps/index.js +0 -5
- package/libx/_runtime/extensibility/mps/service.js +0 -111
- package/libx/_runtime/extensibility/mps/tar.js +0 -42
- package/libx/_runtime/extensibility/mps/utils.js +0 -11
- package/libx/_runtime/extensibility/uiflex/index.js +0 -54
- package/libx/_runtime/extensibility/uiflex/service.js +0 -276
- package/libx/_runtime/messaging/common-utils/naming-conventions.js +0 -20
- package/libx/_runtime/remote/utils/client-types.d.ts +0 -7
- package/libx/gql/GraphQLAdapter.js +0 -33
- package/libx/gql/constants/adapter.js +0 -69
- package/libx/gql/constants/cds.js +0 -18
- package/libx/gql/constants/graphql.js +0 -33
- package/libx/gql/readme.md +0 -1
- package/libx/gql/resolvers/crud/create.js +0 -20
- package/libx/gql/resolvers/crud/delete.js +0 -29
- package/libx/gql/resolvers/crud/index.js +0 -6
- package/libx/gql/resolvers/crud/read.js +0 -30
- package/libx/gql/resolvers/crud/update.js +0 -42
- package/libx/gql/resolvers/crud/utils/index.js +0 -36
- package/libx/gql/resolvers/field.js +0 -5
- package/libx/gql/resolvers/index.js +0 -7
- package/libx/gql/resolvers/mutation.js +0 -23
- package/libx/gql/resolvers/parse/ast/enrich.js +0 -52
- package/libx/gql/resolvers/parse/ast/fragment.js +0 -11
- package/libx/gql/resolvers/parse/ast/fromObject.js +0 -39
- package/libx/gql/resolvers/parse/ast/index.js +0 -3
- package/libx/gql/resolvers/parse/ast/meta.js +0 -4
- package/libx/gql/resolvers/parse/ast/variable.js +0 -7
- package/libx/gql/resolvers/parse/ast2cqn/columns.js +0 -44
- package/libx/gql/resolvers/parse/ast2cqn/entries.js +0 -31
- package/libx/gql/resolvers/parse/ast2cqn/index.js +0 -8
- package/libx/gql/resolvers/parse/ast2cqn/limit.js +0 -6
- package/libx/gql/resolvers/parse/ast2cqn/orderBy.js +0 -24
- package/libx/gql/resolvers/parse/ast2cqn/utils/index.js +0 -3
- package/libx/gql/resolvers/parse/ast2cqn/where.js +0 -70
- package/libx/gql/resolvers/parse/utils/index.js +0 -8
- package/libx/gql/resolvers/query.js +0 -13
- package/libx/gql/resolvers/root.js +0 -34
- package/libx/gql/schema/generate.js +0 -18
- package/libx/gql/schema/index.js +0 -5
- package/libx/gql/schema/mutation.js +0 -76
- package/libx/gql/schema/query.js +0 -108
- package/libx/gql/schema/typeDefMap.js +0 -45
- package/libx/gql/schema/utils/index.js +0 -54
- package/libx/gql/utils/index.js +0 -12
- package/libx/rest/middleware/auth.js +0 -20
- package/libx/rest/middleware/content.js +0 -19
- package/srv/flex.cds +0 -21
- package/srv/flex.js +0 -1
- package/srv/mps.cds +0 -23
- package/srv/mps.js +0 -1
- package/srv/outbox.js +0 -0
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
const { computeColumnsToBeSearched } = require('../../../../libx/_runtime/cds-services/services/utils/columns')
|
|
2
2
|
const searchToLike = require('./searchToLike')
|
|
3
|
-
const { ensureNoDraftsSuffix } = require('./draft')
|
|
4
3
|
const { getEntityNameFromCQN } = require('./entityFromCqn')
|
|
5
4
|
|
|
6
5
|
const _targetFrom = (cqn, options) => {
|
|
@@ -8,12 +7,14 @@ const _targetFrom = (cqn, options) => {
|
|
|
8
7
|
return getEntityNameFromCQN(cqn)
|
|
9
8
|
}
|
|
10
9
|
|
|
11
|
-
|
|
10
|
+
// convert $search system query option to WHERE/HAVING clause using
|
|
11
|
+
// the operator LIKE or CONTAINS
|
|
12
|
+
const search2cqn4sql = (query, model, options = {}) => {
|
|
12
13
|
const cqnSearchPhrase = query.SELECT.search
|
|
13
14
|
if (!cqnSearchPhrase) return
|
|
14
15
|
const { search2cqn4sql } = options
|
|
15
16
|
const { entityName, alias } = _targetFrom(query.SELECT.from, options)
|
|
16
|
-
const entity = model.definitions[
|
|
17
|
+
const entity = model.definitions[entityName]
|
|
17
18
|
const columns = computeColumnsToBeSearched(query, entity, alias)
|
|
18
19
|
|
|
19
20
|
// Call custom (optimized search to cqn for sql implementation) that tries
|
|
@@ -30,14 +31,4 @@ const _search2cqn4sql = (query, model, options = {}) => {
|
|
|
30
31
|
query._aggregated || /* if new parser */ query.SELECT.groupBy ? query.having(expression) : query.where(expression)
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
const search2cqn4sql = (query, model, options) => {
|
|
34
|
-
if (query.SELECT.from.SET) {
|
|
35
|
-
return query.SELECT.from.SET.args.forEach(arg => _search2cqn4sql(arg, model, options))
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return _search2cqn4sql(query, model, options)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// convert $search system query option to WHERE/HAVING clause using
|
|
42
|
-
// the operator LIKE or CONTAINS
|
|
43
34
|
module.exports = search2cqn4sql
|
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
const _createLikeComparison = (searchXpr, columns, excludeSearch) => {
|
|
2
|
-
const likeExpression = []
|
|
2
|
+
const likeExpression = { xpr: [] }
|
|
3
3
|
|
|
4
4
|
columns.forEach((column, index, columns) => {
|
|
5
5
|
// if negated search, we need to add is null check
|
|
6
|
+
let currentExpression = likeExpression
|
|
6
7
|
if (excludeSearch) {
|
|
7
|
-
|
|
8
|
+
currentExpression = { xpr: [column, 'IS NULL', 'OR'] }
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
const searchStringEscaped = searchXpr.val.toLowerCase().replace(/(\^|_|%)/g, '^$1')
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
'lower',
|
|
14
|
-
'(',
|
|
15
|
-
column,
|
|
16
|
-
')',
|
|
13
|
+
currentExpression.xpr.push(
|
|
14
|
+
{ func: 'lower', args: [column] },
|
|
17
15
|
excludeSearch ? 'NOT LIKE' : 'LIKE',
|
|
18
16
|
{ val: `%${searchStringEscaped}%` },
|
|
19
17
|
'ESCAPE',
|
|
@@ -21,11 +19,11 @@ const _createLikeComparison = (searchXpr, columns, excludeSearch) => {
|
|
|
21
19
|
)
|
|
22
20
|
|
|
23
21
|
if (excludeSearch) {
|
|
24
|
-
likeExpression.push(
|
|
22
|
+
likeExpression.xpr.push(currentExpression)
|
|
25
23
|
}
|
|
26
24
|
|
|
27
25
|
if (index !== columns.length - 1) {
|
|
28
|
-
likeExpression.push(excludeSearch ? 'AND' : 'OR')
|
|
26
|
+
likeExpression.xpr.push(excludeSearch ? 'AND' : 'OR')
|
|
29
27
|
}
|
|
30
28
|
})
|
|
31
29
|
|
|
@@ -43,15 +41,13 @@ const searchToLike = (cqnSearchPhrase, columns, expression = []) => {
|
|
|
43
41
|
}
|
|
44
42
|
|
|
45
43
|
if (element.xpr) {
|
|
46
|
-
expression.push(
|
|
47
|
-
searchToLike(element.xpr, columns, expression)
|
|
48
|
-
expression.push(')')
|
|
44
|
+
expression.push({ xpr: searchToLike(element.xpr, columns) })
|
|
49
45
|
return
|
|
50
46
|
}
|
|
51
47
|
|
|
52
48
|
const excludeSearch = cqnSearchPhrase[index - 1] === 'not'
|
|
53
49
|
const likeComparison = _createLikeComparison(element, columns, excludeSearch)
|
|
54
|
-
expression.push(
|
|
50
|
+
expression.push(likeComparison)
|
|
55
51
|
})
|
|
56
52
|
|
|
57
53
|
return expression
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const { ensureNoDraftsSuffix, ensureUnlocalized } = require('../../fiori/utils/handler')
|
|
2
|
+
|
|
3
|
+
const _changeStreamProperties = (target, columns, model) => {
|
|
4
|
+
for (let index = 0; index < columns.length; index++) {
|
|
5
|
+
const col = columns[index]
|
|
6
|
+
const name = col.ref && col.ref[col.ref.length - 1]
|
|
7
|
+
const element = name && target.elements[name]
|
|
8
|
+
const type = element && !element['@Core.IsURL'] && element['@Core.MediaType']
|
|
9
|
+
|
|
10
|
+
if (col.ref && type) {
|
|
11
|
+
if (typeof type === 'object') {
|
|
12
|
+
columns[index] = {
|
|
13
|
+
ref: [...col.ref.slice(0, -1), type['=']],
|
|
14
|
+
as: `${name}@odata.mediaContentType`
|
|
15
|
+
}
|
|
16
|
+
} else {
|
|
17
|
+
columns[index] = { val: type, as: `${name}@odata.mediaContentType` }
|
|
18
|
+
}
|
|
19
|
+
} else if (col.expand && col.ref) {
|
|
20
|
+
const tgt = target.elements[col.ref] && target.elements[col.ref].target
|
|
21
|
+
tgt && _changeStreamProperties(model.definitions[ensureUnlocalized(ensureNoDraftsSuffix(tgt))], col.expand, model)
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const handleStreamProperties = (target, select, model) => {
|
|
27
|
+
const columns = select.SELECT.columns
|
|
28
|
+
if (!columns || !target || !model) return
|
|
29
|
+
if (!select.SELECT._4odata) return
|
|
30
|
+
if (select._streaming) return
|
|
31
|
+
|
|
32
|
+
_changeStreamProperties(target, columns, model)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
module.exports = { handleStreamProperties }
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
const resolveStructured = require('./resolveStructured')
|
|
2
2
|
const { ensureNoDraftsSuffix } = require('../../common/utils/draft')
|
|
3
3
|
const { traverseFroms } = require('../../common/utils/entityFromCqn')
|
|
4
|
-
|
|
4
|
+
|
|
5
5
|
const OPERATIONS_MAP = ['=', '>', '<', '!=', '<>', '>=', '<=', 'like', 'between', 'in', 'not in'].reduce((acc, cur) => {
|
|
6
6
|
acc[cur] = 1
|
|
7
7
|
return acc
|
|
8
8
|
}, {})
|
|
9
9
|
|
|
10
|
+
const NOT_EQUAL = { '!=': 1, '<>': 1 }
|
|
11
|
+
|
|
10
12
|
const _getEntityNamesAndIds = from => {
|
|
11
13
|
const nameAndIds = []
|
|
12
14
|
traverseFroms(from, from => {
|
|
@@ -34,12 +36,7 @@ const _flattenStructuredInExpand = (column, { _target: expandedEntity }) => {
|
|
|
34
36
|
|
|
35
37
|
if (element._isStructured) {
|
|
36
38
|
toBeDeleted.push(propertyName)
|
|
37
|
-
flattenedElements.push(
|
|
38
|
-
...resolveStructured(
|
|
39
|
-
{ structName: element.name, structProperties: expandElement.ref.slice(1) },
|
|
40
|
-
element.elements
|
|
41
|
-
)
|
|
42
|
-
)
|
|
39
|
+
flattenedElements.push(...resolveStructured({ element, structProperties: expandElement.ref.slice(1) }))
|
|
43
40
|
}
|
|
44
41
|
}
|
|
45
42
|
|
|
@@ -64,10 +61,7 @@ const _flattenStructuredOrderBy = (orderBy, csnEntity) => {
|
|
|
64
61
|
}
|
|
65
62
|
|
|
66
63
|
if (element._isStructured) {
|
|
67
|
-
const flattenedStructOrder = resolveStructured(
|
|
68
|
-
{ structName: order.ref[0], structProperties: order.ref.slice(1) },
|
|
69
|
-
element.elements
|
|
70
|
-
)
|
|
64
|
+
const flattenedStructOrder = resolveStructured({ element, structProperties: order.ref.slice(1) })
|
|
71
65
|
newOrder.push(...flattenedStructOrder.map(element => ({ ref: element.ref, sort: order.sort })))
|
|
72
66
|
} else {
|
|
73
67
|
newOrder.push(order)
|
|
@@ -91,7 +85,7 @@ const _getVal = (data, name) => {
|
|
|
91
85
|
|
|
92
86
|
const _filterForStructProperty = (structElement, structData, op, prefix = '', nav = []) => {
|
|
93
87
|
const filterArray = []
|
|
94
|
-
const andOr = op
|
|
88
|
+
const andOr = op in NOT_EQUAL ? 'or' : 'and'
|
|
95
89
|
|
|
96
90
|
for (const elementName in structElement.elements) {
|
|
97
91
|
const element = structElement.elements[elementName]
|
|
@@ -161,7 +155,7 @@ const _transformStructToFlatWhereHaving = ([first, op, second], resArray, struct
|
|
|
161
155
|
const structName = ref[structIdx]
|
|
162
156
|
const structProperties = ref.slice(structIdx + 1)
|
|
163
157
|
const nav = structIdx > 0 ? ref.slice(0, structIdx) : []
|
|
164
|
-
const flattenedElements = resolveStructured({
|
|
158
|
+
const flattenedElements = resolveStructured({ element: structElement, structProperties })
|
|
165
159
|
const flattenedElement = flattenedElements.find(el => el.ref[0] === [structName, ...structProperties].join('_'))
|
|
166
160
|
let structData = val
|
|
167
161
|
try {
|
|
@@ -178,7 +172,7 @@ const _transformStructToFlatWhereHaving = ([first, op, second], resArray, struct
|
|
|
178
172
|
const filterForStructProperty = _filterForStructProperty(nestedElement, structData, op, prefix, nav)
|
|
179
173
|
if (filterForStructProperty.length) {
|
|
180
174
|
filterForStructProperty.pop() // last and/or
|
|
181
|
-
if (op
|
|
175
|
+
if (op in NOT_EQUAL) resArray.push({ xpr: [...filterForStructProperty] })
|
|
182
176
|
else resArray.push(...filterForStructProperty)
|
|
183
177
|
}
|
|
184
178
|
}
|
|
@@ -210,6 +204,7 @@ const flattenStructuredWhereHaving = (filterArray, csnEntity, model) => {
|
|
|
210
204
|
newFilterArray.push({ xpr: flattenStructuredWhereHaving(filterArray[i].xpr, csnEntity, model) })
|
|
211
205
|
continue
|
|
212
206
|
}
|
|
207
|
+
|
|
213
208
|
if (filterArray[i + 1] in OPERATIONS_MAP) {
|
|
214
209
|
const refElement = filterArray[i].ref ? filterArray[i] : filterArray[i + 2]
|
|
215
210
|
|
|
@@ -268,9 +263,7 @@ const _flattenColumns = (SELECT, flattenedElements, toBeDeleted, csnEntity, tabl
|
|
|
268
263
|
|
|
269
264
|
if (element._isStructured) {
|
|
270
265
|
toBeDeleted.push(structName) // works with aliases?
|
|
271
|
-
flattenedElements.push(
|
|
272
|
-
...resolveStructured({ structName, structProperties: cleanedUpRef.slice(1) }, element.elements)
|
|
273
|
-
)
|
|
266
|
+
flattenedElements.push(...resolveStructured({ element, structProperties: cleanedUpRef.slice(1) }))
|
|
274
267
|
}
|
|
275
268
|
if (cleanedUpRef.length < column.ref.length) {
|
|
276
269
|
flattenedElements.forEach(e => e.ref.unshift(tableId))
|
|
@@ -315,5 +308,6 @@ const flattenStructuredSelect = ({ SELECT }, model) => {
|
|
|
315
308
|
module.exports = {
|
|
316
309
|
flattenStructuredSelect,
|
|
317
310
|
flattenStructuredWhereHaving,
|
|
318
|
-
getNavigationIfStruct
|
|
311
|
+
getNavigationIfStruct,
|
|
312
|
+
OPERATIONS_MAP
|
|
319
313
|
}
|
|
@@ -114,6 +114,7 @@ function _getTemplate(model, cache, targetEntity, callbacks, parent = null, _ent
|
|
|
114
114
|
_addSubTemplate(templateElements, elementName, subTemplate)
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
|
+
|
|
117
118
|
return template
|
|
118
119
|
}
|
|
119
120
|
|
|
@@ -143,12 +144,9 @@ module.exports = (usecase, tx, target, ...args) => {
|
|
|
143
144
|
const root = (model && model.definitions[target.name]) || target
|
|
144
145
|
if (!root) return
|
|
145
146
|
|
|
146
|
-
// tx could be the service itself
|
|
147
|
-
// prefer ApplicationService (i.e., tx.context._tx.__proto__)
|
|
147
|
+
// tx could be the service itself -> prefer ApplicationService
|
|
148
148
|
// REVISIT: context._tx is not a stable API -> pls do not rely on that
|
|
149
|
-
const service = tx.context
|
|
150
|
-
? (tx.context._tx && Object.getPrototypeOf(tx.context._tx)) || Object.getPrototypeOf(tx)
|
|
151
|
-
: tx
|
|
149
|
+
const service = tx.context ? (tx.context.tx && Object.getPrototypeOf(tx.context.tx)) || Object.getPrototypeOf(tx) : tx
|
|
152
150
|
if (!service) return
|
|
153
151
|
|
|
154
152
|
// cache templates at service for garbage collection
|
|
@@ -6,18 +6,18 @@ const _formatRowContext = (tKey, keyNames, row) => {
|
|
|
6
6
|
return `${tKey}(${keyValuePairsSerialized})`
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
const _processElement = (processFn, row, key, target, picked = {}, isRoot,
|
|
9
|
+
const _processElement = (processFn, row, key, target, picked = {}, isRoot, pathSegments) => {
|
|
10
10
|
const element = (target.elements || target.params)[key]
|
|
11
11
|
const { plain } = picked
|
|
12
12
|
|
|
13
13
|
if (!plain) return
|
|
14
14
|
/**
|
|
15
|
-
* @type import('../../types/api').
|
|
15
|
+
* @type import('../../types/api').templateElementInfo
|
|
16
16
|
*/
|
|
17
|
-
const elementInfo = { row, key, element, target, plain, isRoot,
|
|
18
|
-
if (!element && target._flat2struct && target._flat2struct[key]) {
|
|
19
|
-
elementInfo.
|
|
20
|
-
elementInfo.
|
|
17
|
+
const elementInfo = { row, key, element, target, plain, isRoot, pathSegments }
|
|
18
|
+
if (!element && target._flat2struct && target._flat2struct[key] && elementInfo.pathSegments) {
|
|
19
|
+
elementInfo.pathSegments = pathSegments.slice(0)
|
|
20
|
+
elementInfo.pathSegments.push(...target._flat2struct[key])
|
|
21
21
|
}
|
|
22
22
|
processFn(elementInfo)
|
|
23
23
|
}
|
|
@@ -26,7 +26,7 @@ const _processRow = (processFn, row, template, tKey, tValue, isRoot, pathOptions
|
|
|
26
26
|
const { template: subTemplate, picked } = tValue
|
|
27
27
|
const key = tKey.split(DELIMITER).pop()
|
|
28
28
|
|
|
29
|
-
_processElement(processFn, row, key, template.target, picked, isRoot, pathOptions.
|
|
29
|
+
_processElement(processFn, row, key, template.target, picked, isRoot, pathOptions.pathSegments)
|
|
30
30
|
|
|
31
31
|
// process deep
|
|
32
32
|
if (subTemplate && typeof row === 'object' && row) {
|
|
@@ -34,29 +34,37 @@ const _processRow = (processFn, row, template, tKey, tValue, isRoot, pathOptions
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
const _getTargetKeyNames = target => {
|
|
38
|
+
const keyNames = []
|
|
39
|
+
for (const keyName in target.keys) {
|
|
40
|
+
if (target.keys[keyName].__isAssociationStrict) continue
|
|
41
|
+
keyNames.push(keyName)
|
|
42
|
+
}
|
|
43
|
+
return keyNames
|
|
44
|
+
}
|
|
45
|
+
|
|
37
46
|
const _processComplex = (processFn, row, template, key, pathOptions) => {
|
|
38
47
|
const value = row && row[key]
|
|
39
|
-
const
|
|
40
|
-
const rows = _is2many ? value : [value]
|
|
48
|
+
const rows = Array.isArray(value) ? value : [value]
|
|
41
49
|
if (rows.length === 0) return
|
|
42
|
-
const keyNames = (template.target
|
|
50
|
+
const keyNames = _getTargetKeyNames(template.target)
|
|
43
51
|
|
|
44
52
|
for (let idx = 0; idx < rows.length; idx++) {
|
|
45
53
|
const row = rows[idx]
|
|
46
54
|
if (row == null) continue
|
|
47
55
|
const args = { processFn, row, template, isRoot: false, pathOptions }
|
|
48
56
|
|
|
49
|
-
let
|
|
57
|
+
let rowContext
|
|
50
58
|
if (pathOptions.includeKeyValues) {
|
|
51
59
|
if (pathOptions.rowKeysGenerator) pathOptions.rowKeysGenerator(keyNames, row, template)
|
|
52
|
-
|
|
60
|
+
rowContext = _formatRowContext(key, keyNames, Object.assign({}, row, pathOptions.extraKeys))
|
|
53
61
|
}
|
|
54
62
|
|
|
55
|
-
if (pathOptions.
|
|
63
|
+
if (pathOptions.pathSegments) pathOptions.pathSegments.push(rowContext || key)
|
|
56
64
|
|
|
57
65
|
templateProcessor(args)
|
|
58
66
|
|
|
59
|
-
if (pathOptions.
|
|
67
|
+
if (pathOptions.pathSegments) pathOptions.pathSegments.pop()
|
|
60
68
|
}
|
|
61
69
|
}
|
|
62
70
|
|
|
@@ -96,7 +96,7 @@ module.exports = {
|
|
|
96
96
|
val: 1
|
|
97
97
|
}
|
|
98
98
|
],
|
|
99
|
-
where: [
|
|
99
|
+
where: [{ xpr: ['%%KEYS%%'] }]
|
|
100
100
|
},
|
|
101
101
|
as: 'HasDraftEntity',
|
|
102
102
|
cast: {
|
|
@@ -125,7 +125,7 @@ module.exports = {
|
|
|
125
125
|
ref: ['DraftAdministrativeData_DraftUUID']
|
|
126
126
|
}
|
|
127
127
|
],
|
|
128
|
-
where: [
|
|
128
|
+
where: [{ xpr: ['%%KEYS%%'] }]
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
],
|
|
@@ -160,19 +160,9 @@ module.exports = {
|
|
|
160
160
|
}
|
|
161
161
|
],
|
|
162
162
|
where: [
|
|
163
|
-
'
|
|
164
|
-
{
|
|
165
|
-
ref: ['filterAdmin', 'InProcessByUser']
|
|
166
|
-
},
|
|
167
|
-
'=',
|
|
168
|
-
{
|
|
169
|
-
val: '%%USER%%'
|
|
170
|
-
},
|
|
171
|
-
')',
|
|
163
|
+
{ xpr: [{ ref: ['filterAdmin', 'InProcessByUser'] }, '=', { val: '%%USER%%' }] },
|
|
172
164
|
'and',
|
|
173
|
-
'
|
|
174
|
-
'%%KEYS%%',
|
|
175
|
-
')'
|
|
165
|
+
{ xpr: ['%%KEYS%%'] }
|
|
176
166
|
]
|
|
177
167
|
}
|
|
178
168
|
}
|
|
@@ -30,7 +30,8 @@ class DatabaseService extends cds.Service {
|
|
|
30
30
|
// if the tx was initiated in messaging, then this.context._model is not unfolded
|
|
31
31
|
// -> use this.context._model._4odata if present
|
|
32
32
|
const { _model } = this.context
|
|
33
|
-
this.model =
|
|
33
|
+
if (_model) this.model = _model._4odata || _model
|
|
34
|
+
else this.model = req._model
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
this._ensureModel._initial = true
|
|
@@ -14,7 +14,7 @@ const _removeParentKeysFromRow = (row, prefix, keys) => {
|
|
|
14
14
|
const _autoExpandNavsAndAttachToResult = async (entity, previousResult, depth, options) => {
|
|
15
15
|
for (const nav in entity._associations) {
|
|
16
16
|
const navigation = entity._associations[nav]
|
|
17
|
-
if (options.onlyCompositions && navigation.
|
|
17
|
+
if (options.onlyCompositions && navigation._isAssociationStrict) continue
|
|
18
18
|
|
|
19
19
|
// do not expand backlinks
|
|
20
20
|
if (navigation._isBacklink) continue
|
|
@@ -94,7 +94,7 @@ const _fkForOnCOnd = (onCond, requiredFks) => {
|
|
|
94
94
|
const _foreignKeysOfTopLevelNavs = (entity, options) => {
|
|
95
95
|
const requiredFks = new Set()
|
|
96
96
|
for (const nav in entity._associations) {
|
|
97
|
-
if (options.onlyCompositions && entity._associations[nav].
|
|
97
|
+
if (options.onlyCompositions && entity._associations[nav]._isAssociationStrict) continue
|
|
98
98
|
const onCond = entity._relations[nav].join('child', 'parent')
|
|
99
99
|
_fkForOnCOnd(onCond, requiredFks)
|
|
100
100
|
}
|
|
@@ -317,7 +317,9 @@ class JoinCQNFromExpanded {
|
|
|
317
317
|
*/
|
|
318
318
|
_adaptWhereOrderBy(cqn, tableAlias) {
|
|
319
319
|
if (cqn.where) {
|
|
320
|
-
cqn.where = cqn.where.map(element =>
|
|
320
|
+
cqn.where = cqn.where.map(element => {
|
|
321
|
+
return this._adaptWhereElement(element, cqn, tableAlias)
|
|
322
|
+
})
|
|
321
323
|
}
|
|
322
324
|
|
|
323
325
|
if (cqn.having) {
|
|
@@ -603,7 +605,7 @@ class JoinCQNFromExpanded {
|
|
|
603
605
|
return {
|
|
604
606
|
args: [cqn, { ref: [draftTable], as: `${tableAlias}_drafts` }],
|
|
605
607
|
join: 'left',
|
|
606
|
-
on: [
|
|
608
|
+
on: [{ xpr: [...on] }]
|
|
607
609
|
}
|
|
608
610
|
}
|
|
609
611
|
|
|
@@ -982,8 +984,7 @@ class JoinCQNFromExpanded {
|
|
|
982
984
|
|
|
983
985
|
if (!column[SKIP_MAPPING]) {
|
|
984
986
|
mappings[column[IDENTIFIER] || identifier] = as
|
|
985
|
-
|
|
986
|
-
if (column[CLEANUP_KEYS] && !cds.env.features.auto_fetch_expand_keys) {
|
|
987
|
+
if (column[CLEANUP_KEYS]) {
|
|
987
988
|
delete aliasedElement[CLEANUP_KEYS]
|
|
988
989
|
if (!mappings[CLEANUP_KEYS]) mappings[CLEANUP_KEYS] = {}
|
|
989
990
|
mappings[CLEANUP_KEYS][column[IDENTIFIER] || identifier] = as
|
|
@@ -1599,7 +1600,7 @@ class JoinCQNFromExpanded {
|
|
|
1599
1600
|
}
|
|
1600
1601
|
|
|
1601
1602
|
_isNotIncludedIn(columns) {
|
|
1602
|
-
if (columns.some(column => isAsteriskColumn(column))) return
|
|
1603
|
+
if (columns.some(column => isAsteriskColumn(column))) return () => false
|
|
1603
1604
|
return entry =>
|
|
1604
1605
|
!columns.some(
|
|
1605
1606
|
column =>
|
|
@@ -1614,7 +1615,7 @@ class JoinCQNFromExpanded {
|
|
|
1614
1615
|
* @private
|
|
1615
1616
|
*/
|
|
1616
1617
|
|
|
1617
|
-
_addMissingJoinElements(columns, joinColumns
|
|
1618
|
+
_addMissingJoinElements(columns, joinColumns) {
|
|
1618
1619
|
const isNotIncludedInColumns = this._isNotIncludedIn(columns)
|
|
1619
1620
|
for (const joinColumn of joinColumns) {
|
|
1620
1621
|
if (isNotIncludedInColumns(joinColumn.ref[1])) {
|
|
@@ -32,8 +32,8 @@ const _processComplexCategory = ({ row, key, val, category, req, element }) => {
|
|
|
32
32
|
category = category.category
|
|
33
33
|
|
|
34
34
|
// propagate keys
|
|
35
|
-
if (category === 'propagateForeignKeys' && row
|
|
36
|
-
propagateForeignKeys(key, row, element._foreignKeys, element.
|
|
35
|
+
if (category === 'propagateForeignKeys' && key in row) {
|
|
36
|
+
propagateForeignKeys(key, row, element._foreignKeys, element.isComposition)
|
|
37
37
|
return
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -41,12 +41,12 @@ const _processComplexCategory = ({ row, key, val, category, req, element }) => {
|
|
|
41
41
|
if (val === undefined && _isManaged(category, req.event)) {
|
|
42
42
|
if (typeof categoryArgs === 'object') {
|
|
43
43
|
const val = categoryArgs['=']
|
|
44
|
-
if (val.match(/^\$/))
|
|
45
|
-
|
|
44
|
+
if (val.match(/^\$/)) {
|
|
45
|
+
row[key] = val === '$uuid' ? cds.utils.uuid() : val
|
|
46
|
+
} else row[key] = row[val]
|
|
46
47
|
} else {
|
|
47
48
|
row[key] = categoryArgs
|
|
48
49
|
}
|
|
49
|
-
return
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
// not null with default for rest response body and ensure utc
|
|
@@ -62,7 +62,9 @@ const _processComplexCategory = ({ row, key, val, category, req, element }) => {
|
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
const _processCategory = (
|
|
65
|
+
const _processCategory = (req, category, { row, key, element }) => {
|
|
66
|
+
const val = row[key]
|
|
67
|
+
|
|
66
68
|
// use args only inside this if (sonar type error warning)
|
|
67
69
|
if (typeof category === 'object') {
|
|
68
70
|
_processComplexCategory({ category, row, key, val, req, element })
|
|
@@ -106,16 +108,11 @@ const _processCategory = ({ category, row, key, element, val, req }) => {
|
|
|
106
108
|
}
|
|
107
109
|
}
|
|
108
110
|
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
const categories = plain.categories
|
|
113
|
-
const val = row[key]
|
|
114
|
-
|
|
115
|
-
for (const category of categories) {
|
|
116
|
-
_processCategory({ category, row, key, element, val, req })
|
|
117
|
-
}
|
|
111
|
+
const _processorFn = req => elementInfo => {
|
|
112
|
+
for (const category of elementInfo.plain.categories) {
|
|
113
|
+
_processCategory(req, category, elementInfo)
|
|
118
114
|
}
|
|
115
|
+
}
|
|
119
116
|
|
|
120
117
|
const _isVirtualOrCalculated = element => {
|
|
121
118
|
if (element.virtual) return true
|
|
@@ -155,7 +152,7 @@ const _pickCRUD = element => {
|
|
|
155
152
|
categories.push({ category: '@cds.on.update', args: element['@cds.on.update'] })
|
|
156
153
|
}
|
|
157
154
|
|
|
158
|
-
if (element.
|
|
155
|
+
if (element._isAssociationStrict && !element._target._hasPersistenceSkip) {
|
|
159
156
|
categories.push('associationEffective')
|
|
160
157
|
}
|
|
161
158
|
|
|
@@ -223,7 +220,7 @@ function _handler(req) {
|
|
|
223
220
|
|
|
224
221
|
const data = Array.isArray(req.data) ? req.data : [req.data]
|
|
225
222
|
for (const row of data) {
|
|
226
|
-
templateProcessor({ processFn:
|
|
223
|
+
templateProcessor({ processFn: _processorFn(req), row, template })
|
|
227
224
|
}
|
|
228
225
|
}
|
|
229
226
|
|
|
@@ -54,8 +54,7 @@ const _runtimeShallCheckIntegrityFor = (assoc, inclComps) => {
|
|
|
54
54
|
|
|
55
55
|
// here, no disqualification and no @assert.integrity specified -> global setting
|
|
56
56
|
const { assert_integrity: ai, assert_integrity_type: ait } = cds.env.features
|
|
57
|
-
if (
|
|
58
|
-
if (ait && ait.match(/db/i)) return false
|
|
57
|
+
if (ai && ait && ait.match(/db/i)) return false
|
|
59
58
|
return true
|
|
60
59
|
}
|
|
61
60
|
|
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
// REVISIT: UpdateResult
|
|
2
2
|
// const UpdateResult = require('../result/UpdateResult')
|
|
3
3
|
|
|
4
|
-
const { allKeysAreProvided } = require('../../cds-services/services/utils/handlerUtils')
|
|
5
4
|
const onlyKeysRemain = require('../../common/utils/onlyKeysRemain')
|
|
5
|
+
const { DRAFT_COLUMNS_MAP } = require('../../common/constants/draft')
|
|
6
|
+
|
|
7
|
+
const allKeysAreProvided = req => {
|
|
8
|
+
const data = req.data && (Array.isArray(req.data) ? req.data : [req.data])
|
|
9
|
+
for (const key of Object.values(req.target.keys || {})) {
|
|
10
|
+
if (key._isAssociationStrict || key.name in DRAFT_COLUMNS_MAP) {
|
|
11
|
+
continue
|
|
12
|
+
}
|
|
13
|
+
for (const d of data) {
|
|
14
|
+
if (d[key.name] === undefined) return false
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return true
|
|
18
|
+
}
|
|
6
19
|
|
|
7
20
|
const _enrichKeysFromOldData = (req, oldData) => {
|
|
8
21
|
const data = req.data && (Array.isArray(req.data) ? req.data : [req.data])
|
|
@@ -29,7 +29,7 @@ const _getFilteredCqns = (cqns, model) => {
|
|
|
29
29
|
)
|
|
30
30
|
if (moreThanManaged) continue
|
|
31
31
|
|
|
32
|
-
const comps = Object.values(entity.associations || {}).filter(assoc => assoc.
|
|
32
|
+
const comps = Object.values(entity.associations || {}).filter(assoc => assoc.isComposition)
|
|
33
33
|
for (const comp of comps) {
|
|
34
34
|
if (_includesCompositionTarget(cqns, comp.target)) {
|
|
35
35
|
moreThanManaged = true
|
|
@@ -56,7 +56,7 @@ class BaseBuilder {
|
|
|
56
56
|
_getDatabaseName(entity) {
|
|
57
57
|
return this._quotingStyle === 'plain'
|
|
58
58
|
? entity
|
|
59
|
-
: getArtifactCdsPersistenceName(entity, this._quotingStyle, this._csn)
|
|
59
|
+
: getArtifactCdsPersistenceName(entity, this._quotingStyle, this._csn, 'hana') // FIXME: SQL dialect instead of hardcoded 'hana'
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
_validateQuotingStyle() {
|
|
@@ -138,6 +138,7 @@ class ExpressionBuilder extends BaseBuilder {
|
|
|
138
138
|
*/
|
|
139
139
|
// eslint-disable-next-line complexity
|
|
140
140
|
_reseverdKeyWords(objects, i) {
|
|
141
|
+
const NOT_EQUAL = { '!=': 1, '<>': 1 }
|
|
141
142
|
if (objects[i] === 'not' && objects[i + 1].func) {
|
|
142
143
|
objects[i + 1].func = `not ${objects[i + 1].func}`
|
|
143
144
|
return 1
|
|
@@ -160,35 +161,19 @@ class ExpressionBuilder extends BaseBuilder {
|
|
|
160
161
|
return 0
|
|
161
162
|
}
|
|
162
163
|
|
|
163
|
-
if ((objects[i + 1] === '=' || objects[i + 1]
|
|
164
|
+
if ((objects[i + 1] === '=' || objects[i + 1] in NOT_EQUAL) && objects[i + 2] && objects[i + 2].val === null) {
|
|
164
165
|
this._addNullOrNotNull(objects[i], objects[i + 1])
|
|
165
166
|
return 3
|
|
166
167
|
}
|
|
167
168
|
|
|
168
|
-
if (objects[i].val === null && (objects[i + 1] === '=' || objects[i + 1]
|
|
169
|
+
if (objects[i].val === null && (objects[i + 1] === '=' || objects[i + 1] in NOT_EQUAL) && objects[i + 2]) {
|
|
169
170
|
this._addNullOrNotNull(objects[i + 2], objects[i + 1])
|
|
170
171
|
return 3
|
|
171
172
|
}
|
|
172
173
|
|
|
173
174
|
if (/^(not )?in+/i.test(objects[i + 1])) {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
return 3
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// map other notation to current notation
|
|
180
|
-
const arr = []
|
|
181
|
-
let skip = 3
|
|
182
|
-
for (let j = i + 3; j < objects.length; j++) {
|
|
183
|
-
skip++
|
|
184
|
-
if (objects[j] === ')') {
|
|
185
|
-
break
|
|
186
|
-
} else if (objects[j].val) {
|
|
187
|
-
arr.push(objects[j].val)
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
this._addInOrNotIn(objects[i], objects[i + 1].toUpperCase(), { val: arr })
|
|
191
|
-
return skip
|
|
175
|
+
this._addInOrNotIn(objects[i], objects[i + 1].toUpperCase(), objects[i + 2])
|
|
176
|
+
return 3
|
|
192
177
|
}
|
|
193
178
|
|
|
194
179
|
return 0
|
|
@@ -226,17 +211,6 @@ class ExpressionBuilder extends BaseBuilder {
|
|
|
226
211
|
* @private
|
|
227
212
|
*/
|
|
228
213
|
_addInOrNotIn(reference, operator, values) {
|
|
229
|
-
if (values.val === null) {
|
|
230
|
-
this._addToOutputObj(new this.ReferenceBuilder(reference, this._options, this._csn).build(), false)
|
|
231
|
-
this._outputObj.sql.push('is null')
|
|
232
|
-
return true
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
if (Array.isArray(values.val)) {
|
|
236
|
-
this._addArrayForInQuery(reference, operator, values.val)
|
|
237
|
-
return true
|
|
238
|
-
}
|
|
239
|
-
|
|
240
214
|
if (Array.isArray(values.list)) {
|
|
241
215
|
this._expressionElementToSQL(reference)
|
|
242
216
|
this._outputObj.sql.push(operator)
|
|
@@ -297,7 +297,7 @@ class InsertBuilder extends BaseBuilder {
|
|
|
297
297
|
_entries(annotatedColumns) {
|
|
298
298
|
const columns = []
|
|
299
299
|
const valuesArray = []
|
|
300
|
-
const insertAnnotatedColumns = (annotatedColumns && annotatedColumns.insertAnnotatedColumns) ||
|
|
300
|
+
const insertAnnotatedColumns = (annotatedColumns && annotatedColumns.insertAnnotatedColumns) || new Map()
|
|
301
301
|
const flattenColumnMap = this._getFlattenColumnMap(this._obj.INSERT.entries, { annotatedColumns })
|
|
302
302
|
const purelyManagedColumns = this._getAnnotatedInsertColumnNames(annotatedColumns).filter(
|
|
303
303
|
colName => !flattenColumnMap.has(colName)
|