@sap/cds-compiler 3.5.2 → 3.6.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 +63 -1
- package/bin/cdsc.js +14 -6
- package/doc/CHANGELOG_ARCHIVE.md +10 -10
- package/doc/CHANGELOG_DEPRECATED.md +2 -2
- package/lib/api/main.js +32 -55
- package/lib/api/options.js +1 -0
- package/lib/api/validate.js +5 -0
- package/lib/base/message-registry.js +104 -32
- package/lib/base/messages.js +277 -212
- package/lib/base/model.js +33 -22
- package/lib/base/optionProcessorHelper.js +9 -2
- package/lib/base/shuffle.js +50 -0
- package/lib/checks/actionsFunctions.js +37 -20
- package/lib/checks/foreignKeys.js +13 -6
- package/lib/checks/nonexpandableStructured.js +1 -2
- package/lib/checks/onConditions.js +21 -19
- package/lib/checks/parameters.js +1 -1
- package/lib/checks/queryNoDbArtifacts.js +2 -0
- package/lib/checks/types.js +16 -22
- package/lib/compiler/assert-consistency.js +31 -28
- package/lib/compiler/builtins.js +20 -4
- package/lib/compiler/checks.js +72 -63
- package/lib/compiler/define.js +396 -314
- package/lib/compiler/extend.js +55 -49
- package/lib/compiler/index.js +5 -0
- package/lib/compiler/populate.js +28 -11
- package/lib/compiler/propagator.js +2 -1
- package/lib/compiler/resolve.js +29 -20
- package/lib/compiler/shared.js +15 -10
- package/lib/compiler/utils.js +7 -7
- package/lib/edm/annotations/genericTranslation.js +51 -46
- package/lib/edm/annotations/preprocessAnnotations.js +39 -42
- package/lib/edm/csn2edm.js +69 -21
- package/lib/edm/edm.js +2 -2
- package/lib/edm/edmInboundChecks.js +6 -8
- package/lib/edm/edmPreprocessor.js +88 -80
- package/lib/edm/edmUtils.js +6 -15
- package/lib/gen/Dictionary.json +81 -13
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +2 -1
- package/lib/gen/languageParser.js +4680 -4484
- package/lib/inspect/inspectModelStatistics.js +2 -1
- package/lib/inspect/inspectPropagation.js +2 -1
- package/lib/json/from-csn.js +131 -78
- package/lib/json/to-csn.js +39 -23
- package/lib/language/antlrParser.js +0 -3
- package/lib/language/docCommentParser.js +7 -3
- package/lib/language/errorStrategy.js +3 -2
- package/lib/language/genericAntlrParser.js +96 -41
- package/lib/language/language.g4 +112 -128
- package/lib/language/multiLineStringParser.js +2 -1
- package/lib/main.d.ts +115 -2
- package/lib/main.js +16 -3
- package/lib/model/csnRefs.js +3 -3
- package/lib/model/csnUtils.js +109 -179
- package/lib/model/enrichCsn.js +13 -8
- package/lib/model/revealInternalProperties.js +4 -3
- package/lib/optionProcessor.js +23 -3
- package/lib/render/manageConstraints.js +11 -15
- package/lib/render/toCdl.js +144 -47
- package/lib/render/toHdbcds.js +22 -22
- package/lib/render/toRename.js +3 -4
- package/lib/render/toSql.js +29 -20
- package/lib/render/utils/delta.js +3 -1
- package/lib/render/utils/sql.js +3 -16
- package/lib/transform/db/associations.js +6 -6
- package/lib/transform/db/cdsPersistence.js +3 -3
- package/lib/transform/db/constraints.js +8 -8
- package/lib/transform/db/expansion.js +4 -4
- package/lib/transform/db/flattening.js +12 -15
- package/lib/transform/db/temporal.js +4 -3
- package/lib/transform/db/transformExists.js +2 -1
- package/lib/transform/draft/db.js +7 -7
- package/lib/transform/forOdataNew.js +15 -4
- package/lib/transform/forRelationalDB.js +53 -39
- package/lib/transform/odata/toFinalBaseType.js +106 -82
- package/lib/transform/odata/typesExposure.js +26 -17
- package/lib/transform/odata/utils.js +1 -1
- package/lib/transform/parseExpr.js +1 -1
- package/lib/transform/transformUtilsNew.js +33 -10
- package/lib/transform/translateAssocsToJoins.js +8 -7
- package/lib/transform/universalCsn/coreComputed.js +7 -5
- package/lib/transform/universalCsn/universalCsnEnricher.js +12 -4
- package/lib/utils/timetrace.js +2 -2
- package/package.json +1 -2
package/CHANGELOG.md
CHANGED
|
@@ -7,11 +7,71 @@
|
|
|
7
7
|
Note: `beta` fixes, changes and features are usually not listed in this ChangeLog but [here](doc/CHANGELOG_BETA.md).
|
|
8
8
|
The compiler behavior concerning `beta` features can change at any time without notice.
|
|
9
9
|
|
|
10
|
+
## Version 3.6.0 - 2023-01-25
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- API: There are new API functions for `to.cdl`: `smartId`, `smartFunctionId` and `delimitedId`.
|
|
15
|
+
- CDL parser: when defining a parameter for entities, actions or functions,
|
|
16
|
+
you can use a regular identifier for its name even if that is a reserved name like `in`.
|
|
17
|
+
- The first parameter of a bound action or function can be typed with `$self` or `many $self`
|
|
18
|
+
even if no type named `$self` exists.
|
|
19
|
+
- If an aspect `sap.common.TextsAspect` exists in the `sap.common` context, it will be included
|
|
20
|
+
in all `.texts` entities. This allows to extend `.texts` entities via extending the aspect.
|
|
21
|
+
Example:
|
|
22
|
+
```cds
|
|
23
|
+
entity E {
|
|
24
|
+
key id : Integer;
|
|
25
|
+
content: localized String;
|
|
26
|
+
}
|
|
27
|
+
extend sap.common.TextsAspect with {
|
|
28
|
+
elem: String;
|
|
29
|
+
};
|
|
30
|
+
// from @sap/cds common.cds
|
|
31
|
+
aspect sap.common.TextsAspect {
|
|
32
|
+
key locale: String;
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
- to.edm(x): Support explicit binding parameter `<id>: [many] $self` for OData V4 only.
|
|
36
|
+
The explicit binding parameter is rendered as any other parameter and `$self` is replaced with
|
|
37
|
+
the binding type but only if no `$self` definition exists in the model. This gives full control
|
|
38
|
+
over the binding parameter including name, nullability, default value and annotations.
|
|
39
|
+
The explicit binding parameter is ignored for OData V2 and has precedence over `@cds.odata.bindingparameter`.
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
|
|
43
|
+
- Many messages concerning the CDL and CSN syntax are improved:
|
|
44
|
+
affects message ids (`syntax-…`), message texts and the error locations.
|
|
45
|
+
- Duplicate doc-comments are now errors, similar to duplicate annotations.
|
|
46
|
+
- Update OData vocabularies 'Aggregation', 'Analytics', 'Capabilities','Common', 'ODM', 'Offline',
|
|
47
|
+
'PDF', 'Session', 'UI'.
|
|
48
|
+
|
|
49
|
+
### Fixed
|
|
50
|
+
|
|
51
|
+
- If an entity with parameters is auto-exposed, the generated projection now has
|
|
52
|
+
the same formal parameters and its query forwards these parameters to the origin entity.
|
|
53
|
+
- to.hdbcds: Aliases for foreign `keys` were not quoted if necessary.
|
|
54
|
+
- to.cdl:
|
|
55
|
+
+ Aliases for `expand` and foreign `keys` were not quoted if necessary.
|
|
56
|
+
+ Query functions that are CDL keywords were not properly quoted.
|
|
57
|
+
+ CSN `doc` properties containing `*/` resulted in invalid CDL.
|
|
58
|
+
To avoid compilation issues, `*/` is escaped as `*\/`.
|
|
59
|
+
- to.edm(x): Respect record type hint `$Type` in EDM JSON as full qualified `@type` URI property.
|
|
60
|
+
|
|
61
|
+
## Version 3.5.4 - 2023-01-10
|
|
62
|
+
|
|
63
|
+
### Fixed
|
|
64
|
+
|
|
65
|
+
- Allow window functions also with a deprecated flag being set.
|
|
66
|
+
- to.edm(x): Fix program abort due to malformed error location in EDM annotation preprocessing.
|
|
67
|
+
- to.sql/hdi/hdbcds: The option `pre2134ReferentialConstraintNames` can be used to omit the referential
|
|
68
|
+
constraint identifier prefix `c__`.
|
|
69
|
+
|
|
10
70
|
## Version 3.5.2 - 2022-12-20
|
|
11
71
|
|
|
12
72
|
### Fixed
|
|
13
73
|
|
|
14
|
-
- to.sql/hdi/hdbcds: Don't process references in actions, as they have no impact on the database - avoids internal errors
|
|
74
|
+
- to.sql/hdi/hdbcds: Don't process references in actions, as they have no impact on the database - avoids internal errors.
|
|
15
75
|
|
|
16
76
|
## Version 3.5.0 - 2022-12-07
|
|
17
77
|
|
|
@@ -43,6 +103,8 @@ The compiler behavior concerning `beta` features can change at any time without
|
|
|
43
103
|
as the renderer does not modify it.
|
|
44
104
|
- A new warning is emitted if compositions of anonymous aspects are used with the `Association`
|
|
45
105
|
keyword instead of `Composition`. Replace the former with the latter to fix the warning.
|
|
106
|
+
- The previous info messages about annotating undefined artifacts (e.g. `anno-undefined-art`)
|
|
107
|
+
are now warnings.
|
|
46
108
|
|
|
47
109
|
### Removed
|
|
48
110
|
|
package/bin/cdsc.js
CHANGED
|
@@ -128,8 +128,7 @@ function cdsc_main() {
|
|
|
128
128
|
return;
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
// Default warning level is 2 (info)
|
|
132
|
-
// FIXME: Is that not set anywhere in the API?
|
|
131
|
+
// Default warning level is 2 (info); default value only needed for cdsc output
|
|
133
132
|
if (!cmdLine.options.warning)
|
|
134
133
|
cmdLine.options.warning = 2;
|
|
135
134
|
|
|
@@ -184,6 +183,15 @@ function cdsc_main() {
|
|
|
184
183
|
if (cmdLine.options.betaMode)
|
|
185
184
|
cmdLine.options.beta = availableBetaFlags;
|
|
186
185
|
|
|
186
|
+
const { shuffle } = cmdLine.options;
|
|
187
|
+
if (shuffle != null) {
|
|
188
|
+
const num = Number.parseInt( shuffle, 10 );
|
|
189
|
+
cmdLine.options.testMode = (num > 0)
|
|
190
|
+
? num
|
|
191
|
+
: Math.floor( Math.random() * 4294967296 ) + 1;
|
|
192
|
+
console.error( `Running ‘${cmdLine.command}’ with test-mode shuffle ${cmdLine.options.testMode} …` );
|
|
193
|
+
}
|
|
194
|
+
|
|
187
195
|
// If set through CLI (and not options file), `deprecated` is a string and needs processing.
|
|
188
196
|
if (cmdLine.options.deprecated && typeof cmdLine.options.deprecated === 'string') {
|
|
189
197
|
const features = cmdLine.options.deprecated.split(',');
|
|
@@ -382,7 +390,7 @@ function executeCommandLine( command, options, args ) {
|
|
|
382
390
|
function manageConstraints( model ) {
|
|
383
391
|
const csn = options.directBackend ? model : compactModel(model, options);
|
|
384
392
|
const alterConstraintsResult = alterConstraintsWithCsn(csn, options);
|
|
385
|
-
const { src } = options
|
|
393
|
+
const { src } = options || {};
|
|
386
394
|
Object.keys(alterConstraintsResult).forEach((id) => {
|
|
387
395
|
const renderedConstraintStatement = alterConstraintsResult[id];
|
|
388
396
|
if (src === 'hdi')
|
|
@@ -492,7 +500,7 @@ function executeCommandLine( command, options, args ) {
|
|
|
492
500
|
}
|
|
493
501
|
else if (options.noMessageContext) {
|
|
494
502
|
messages.filter(msg => (messageLevels[msg.severity] <= options.warning))
|
|
495
|
-
.forEach(msg => log(main.messageString(msg, normalizeFilename,
|
|
503
|
+
.forEach(msg => log(main.messageString(msg, normalizeFilename, !!options.noMessageId)));
|
|
496
504
|
}
|
|
497
505
|
else {
|
|
498
506
|
// Contains file-contents that are split at '\n'. Try to avoid multiple `.split()` calls.
|
|
@@ -509,7 +517,7 @@ function executeCommandLine( command, options, args ) {
|
|
|
509
517
|
const fullFilePath = name ? path.resolve('', name) : undefined;
|
|
510
518
|
log(main.messageStringMultiline(msg, {
|
|
511
519
|
normalizeFilename,
|
|
512
|
-
noMessageId:
|
|
520
|
+
noMessageId: !!options.noMessageId,
|
|
513
521
|
withLineSpacer: true,
|
|
514
522
|
hintExplanation: true,
|
|
515
523
|
color: options.color,
|
|
@@ -521,7 +529,7 @@ function executeCommandLine( command, options, args ) {
|
|
|
521
529
|
}
|
|
522
530
|
log(); // newline
|
|
523
531
|
});
|
|
524
|
-
if (options.
|
|
532
|
+
if (!options.noMessageId && hasAtLeastOneExplanation)
|
|
525
533
|
log(`${colorTerm.asHelp('help')}: Messages marked with '…' have an explanation text. Use \`cdsc explain <message-id>\` for a more detailed error description.`);
|
|
526
534
|
}
|
|
527
535
|
return model;
|
package/doc/CHANGELOG_ARCHIVE.md
CHANGED
|
@@ -584,7 +584,7 @@ synchronously.
|
|
|
584
584
|
for a local definition of `Foo` probably having a different full name.
|
|
585
585
|
+ Localized convenience views are no longer generated by the core compiler but added by the `for.odata`
|
|
586
586
|
and `to.sql/hdi/hdbcds` processing on demand.
|
|
587
|
-
+ Minimize name clashes when calculating names for
|
|
587
|
+
+ Minimize name clashes when calculating names for auto-exposed entities,
|
|
588
588
|
extends the v1 option `dependentAutoexposed` to sub artifacts of entites (see “Added”).
|
|
589
589
|
+ Ambiguities when redirecting associations now always lead to compile errors;
|
|
590
590
|
you might want to use the new annotation `@cds.redirection.target` to solve them.
|
|
@@ -760,7 +760,7 @@ synchronously.
|
|
|
760
760
|
|
|
761
761
|
### Fixed
|
|
762
762
|
|
|
763
|
-
- Correct calculation of dependent
|
|
763
|
+
- Correct calculation of dependent auto-exposed entity name
|
|
764
764
|
(fixing a potential regression with v1.50.0)
|
|
765
765
|
- to.hdi.migration: Correctly handle "temporal" and other cases when rendering expressions
|
|
766
766
|
- to.edm(x):
|
|
@@ -1177,7 +1177,7 @@ synchronously.
|
|
|
1177
1177
|
- Properly consider targets of compositions in `mixin`s to be autoexposed.
|
|
1178
1178
|
- Uniformly limit propagation of `@cds.autoexposed`, i.e.
|
|
1179
1179
|
there is not inheritance from a query source navigating along an association.
|
|
1180
|
-
Previously, compiling a compiled model could lead to new
|
|
1180
|
+
Previously, compiling a compiled model could lead to new auto-exposed entities.
|
|
1181
1181
|
- OData:
|
|
1182
1182
|
+ V2: Distribute various `@sap` specific annotations to the entity container.
|
|
1183
1183
|
+ Always set attribute `Nullable` on properties of type `Collection()`.
|
|
@@ -1196,7 +1196,7 @@ synchronously.
|
|
|
1196
1196
|
- Allow to declare `many/array of` elements, parameters and return types to be `(not) null`.
|
|
1197
1197
|
The nullability applies to the array items of the element, not the element itself.
|
|
1198
1198
|
- New boolean option `dependentAutoexposed` to avoid name clashes in dependent
|
|
1199
|
-
|
|
1199
|
+
auto-exposed entities (text entities, components of managed compositions).
|
|
1200
1200
|
- cdsc: Add toOdata version 'v4x' to combine `{ version: 'v4', odataFormat: 'structured', odataContainment: true }`.
|
|
1201
1201
|
|
|
1202
1202
|
### Changed
|
|
@@ -1971,7 +1971,7 @@ Changes
|
|
|
1971
1971
|
|
|
1972
1972
|
Fixes
|
|
1973
1973
|
|
|
1974
|
-
* Make `annotate` statements on members of
|
|
1974
|
+
* Make `annotate` statements on members of auto-exposed entities and
|
|
1975
1975
|
automatically created text entities work.
|
|
1976
1976
|
|
|
1977
1977
|
## Version 1.17.2
|
|
@@ -2098,7 +2098,7 @@ Fixes
|
|
|
2098
2098
|
* Consider associations in `from` clause for `on` condition rewrite.
|
|
2099
2099
|
* Make the CSN parser always produce the correct result for `null`.
|
|
2100
2100
|
* Propagate `@cds.autoexpose` along primary query source in all circumstances.
|
|
2101
|
-
* Make `annotate` statements on
|
|
2101
|
+
* Make `annotate` statements on auto-exposed entities work in circumstances.
|
|
2102
2102
|
* Do not dump when magic variables like `$now` or `current_date` had been used
|
|
2103
2103
|
in an entitiy for which the compiler creates a localized convenience view.
|
|
2104
2104
|
* Fix order problem in creation of association `DraftAdministrativeData` for draft enabled entities.
|
|
@@ -2223,7 +2223,7 @@ Changes
|
|
|
2223
2223
|
+ Auto-exposure via `Composition of` now works in all circumstances.
|
|
2224
2224
|
+ Other features like "localized" work for auto-exposed entity and/or with implicitly redirected association.
|
|
2225
2225
|
+ __Redirections for associations which are sub elements do not work__.
|
|
2226
|
-
* The name of an
|
|
2226
|
+
* The name of an auto-exposed entity now looks like `<Service>.<LastNamePart>`
|
|
2227
2227
|
where `<LastNamePart>` is the part of the name of the original entity after the final dot.
|
|
2228
2228
|
If you get an error because of name clashes, just expose one entity explicitly
|
|
2229
2229
|
(or use the option `longAutoexposed`).
|
|
@@ -2307,7 +2307,7 @@ Changes
|
|
|
2307
2307
|
* Produce all CSN output in version 1.0 by default.
|
|
2308
2308
|
* Virtual elements cannot be used in expressions.
|
|
2309
2309
|
* Command `toRename` creates a stored procedure instead of individual statements.
|
|
2310
|
-
* Don't
|
|
2310
|
+
* Don't auto-expose composition target which is annotated with `@cds.autoexpose: false`.
|
|
2311
2311
|
|
|
2312
2312
|
Fixes
|
|
2313
2313
|
* OData:
|
|
@@ -2323,8 +2323,8 @@ Fixes
|
|
|
2323
2323
|
## Version 1.10.0
|
|
2324
2324
|
|
|
2325
2325
|
Features
|
|
2326
|
-
* Annotate entities with `@cds.autoexposed` that are
|
|
2327
|
-
* Always
|
|
2326
|
+
* Annotate entities with `@cds.autoexposed` that are auto-exposed in a service.
|
|
2327
|
+
* Always auto-expose composition targets without annotating them with `@cds.autoexpose`.
|
|
2328
2328
|
* For associations in a service with targets which are not in a service:
|
|
2329
2329
|
+ automatically exclude them if the associaiton is inferred (via select * or include),
|
|
2330
2330
|
+ signal an error if the association is explicitly defined in the service.
|
|
@@ -115,12 +115,12 @@ behavior (without v1 options `dependentAutoexposed` and `longAutoexposed`).
|
|
|
115
115
|
### Added `longAutoexposed`
|
|
116
116
|
|
|
117
117
|
When this option is set (and `generatedEntityNameWithUnderscore`),
|
|
118
|
-
the names of
|
|
118
|
+
the names of auto-exposed entities are calculated according to the
|
|
119
119
|
compiler v1 option `longAutoexposed`.
|
|
120
120
|
|
|
121
121
|
### Added `generatedEntityNameWithUnderscore`
|
|
122
122
|
|
|
123
|
-
Keep using `_` is separator for generated
|
|
123
|
+
Keep using `_` is separator for generated auto-exposed entities and for entities
|
|
124
124
|
created for managed compositions. It also disables a definition `A.B.C` if `A`
|
|
125
125
|
or `A.B` is a definition other than a context or service (v1 behavior).
|
|
126
126
|
|
package/lib/api/main.js
CHANGED
|
@@ -130,6 +130,7 @@ function isPreTransformed( csn, transformation ) {
|
|
|
130
130
|
* @returns {object} Return an oData-pre-processed CSN
|
|
131
131
|
*/
|
|
132
132
|
function odataInternal( csn, internalOptions ) {
|
|
133
|
+
internalOptions.transformation = 'odata';
|
|
133
134
|
const oDataCsn = forOdataNew.transform4odataWithCsn(csn, internalOptions);
|
|
134
135
|
attachTransformerCharacteristics(oDataCsn, 'odata', internalOptions, relevantOdataOptions, warnAboutMismatchOdata);
|
|
135
136
|
return oDataCsn;
|
|
@@ -143,6 +144,7 @@ function odataInternal( csn, internalOptions ) {
|
|
|
143
144
|
* @returns {oDataCSN} Return an oData-pre-processed CSN
|
|
144
145
|
*/
|
|
145
146
|
function odata( csn, options = {} ) {
|
|
147
|
+
traceApi("Options passed into 'for.odata'", options);
|
|
146
148
|
const internalOptions = prepareOptions.for.odata(options);
|
|
147
149
|
return odataInternal(csn, internalOptions);
|
|
148
150
|
}
|
|
@@ -151,11 +153,12 @@ function odata( csn, options = {} ) {
|
|
|
151
153
|
* Process the given csn back to cdl.
|
|
152
154
|
*
|
|
153
155
|
* @param {object} csn CSN to process
|
|
154
|
-
* @param {object} [
|
|
156
|
+
* @param {object} [options={}] Options
|
|
155
157
|
* @returns {object} { model: string, namespace: string }
|
|
156
158
|
*/
|
|
157
|
-
function cdl( csn,
|
|
158
|
-
|
|
159
|
+
function cdl( csn, options = {} ) {
|
|
160
|
+
traceApi("Options passed into 'to.cdl'", options);
|
|
161
|
+
const internalOptions = prepareOptions.to.cdl(options);
|
|
159
162
|
return toCdl.csnToCdl(csn, internalOptions);
|
|
160
163
|
}
|
|
161
164
|
|
|
@@ -214,6 +217,7 @@ function forHdbcds( csn, options = {} ) {
|
|
|
214
217
|
* @returns {SQL[]} Array of SQL statements, tables first, views second
|
|
215
218
|
*/
|
|
216
219
|
function sql( csn, options = {} ) {
|
|
220
|
+
traceApi("Options passed into 'to.sql'", options);
|
|
217
221
|
const internalOptions = prepareOptions.to.sql(options);
|
|
218
222
|
internalOptions.transformation = 'sql';
|
|
219
223
|
|
|
@@ -226,50 +230,6 @@ function sql( csn, options = {} ) {
|
|
|
226
230
|
return result.map(obj => obj.sql).filter(create => create);
|
|
227
231
|
}
|
|
228
232
|
|
|
229
|
-
/**
|
|
230
|
-
* Render the given deltaCSN as SQL.
|
|
231
|
-
*
|
|
232
|
-
* @param {CSN.Model} csn A clean input CSN
|
|
233
|
-
* @param {CSN.Model} deltaCsn A CSN representing new entities and extensions
|
|
234
|
-
* @param {SqlOptions} [options={}] Options
|
|
235
|
-
* @returns {object} - definitions: An array of objects with all artifacts in the after-image. Each object specifies
|
|
236
|
-
* the artifact filename, the suffix, and the corresponding SQL statement to create
|
|
237
|
-
* the artifact.
|
|
238
|
-
* - deletions: An array of objects with the deleted artifacts. Each object specifies the artifact
|
|
239
|
-
* filename and the suffix.
|
|
240
|
-
* - migrations: An array of objects with the changed (migrated) artifacts. Each object specifies the
|
|
241
|
-
* artifact filename, the suffix, and the changeset (an array of changes, each specifying
|
|
242
|
-
* whether it incurs potential data loss, and its respective SQL statement(s), with
|
|
243
|
-
* multiple statements concatenated as a multi-line string in case the change e.g.
|
|
244
|
-
* consists of a column drop and add).
|
|
245
|
-
*/
|
|
246
|
-
function mtx( csn, deltaCsn, options = {} ) {
|
|
247
|
-
if (!baseModel.isBetaEnabled(options, 'to.mtx'))
|
|
248
|
-
throw new Error('to.mtx is only available with beta flag `to.mtx`');
|
|
249
|
-
|
|
250
|
-
const internalOptions = prepareOptions.to.sql(options);
|
|
251
|
-
// TODO: Use compiler.compileSources() when this function is moved to lib/main.js
|
|
252
|
-
const merged = toCsn.compactModel(compiler.compileSourcesX({ 'base.csn': csn, 'delta.csn': deltaCsn }), options);
|
|
253
|
-
const baseSql = forSql(csn, options);
|
|
254
|
-
const mergedSql = forSql(merged, options);
|
|
255
|
-
const diff = modelCompare.compareModels(baseSql, mergedSql, options);
|
|
256
|
-
// Delete artifacts that are already present in csn
|
|
257
|
-
Object.keys(baseSql.definitions).forEach((artifactName) => {
|
|
258
|
-
if (diff.definitions[artifactName]) // don't render again, but need info for primary key extension
|
|
259
|
-
diff.definitions[artifactName]['@cds.persistence.skip'] = true;
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
internalOptions.forHana = true;
|
|
263
|
-
internalOptions.beta.sqlExtensions = true;
|
|
264
|
-
const { deletions, migrations, ...additions } = toSql.toSqlDdl(diff, internalOptions);
|
|
265
|
-
|
|
266
|
-
return {
|
|
267
|
-
additions: createSqlDefinitions(additions, mergedSql),
|
|
268
|
-
deletions: createSqlDeletions(deletions, baseSql),
|
|
269
|
-
migrations: createSqlMigrations(migrations, mergedSql),
|
|
270
|
-
};
|
|
271
|
-
}
|
|
272
|
-
|
|
273
233
|
/**
|
|
274
234
|
* Process the given CSN into HDI artifacts.
|
|
275
235
|
*
|
|
@@ -278,6 +238,7 @@ function mtx( csn, deltaCsn, options = {} ) {
|
|
|
278
238
|
* @returns {HDIArtifacts} { <filename>:<content>, ...}
|
|
279
239
|
*/
|
|
280
240
|
function hdi( csn, options = {} ) {
|
|
241
|
+
traceApi("Options passed into 'to.hdi'", options);
|
|
281
242
|
const internalOptions = prepareOptions.to.hdi(options);
|
|
282
243
|
|
|
283
244
|
// we need the CSN for view sorting
|
|
@@ -380,14 +341,15 @@ function remapName( key, csn, filter = () => true ) {
|
|
|
380
341
|
* - createsAndAlters: An array of SQL statements to ALTER/CREATE tables/views
|
|
381
342
|
*/
|
|
382
343
|
function sqlMigration( csn, options, beforeImage ) {
|
|
344
|
+
traceApi("Options passed into 'to.sql.migration'", options);
|
|
383
345
|
const internalOptions = prepareOptions.to.sql(options);
|
|
384
|
-
const { error, throwWithError } = messages.makeMessageFunction(csn,
|
|
346
|
+
const { error, throwWithError } = messages.makeMessageFunction(csn, internalOptions, 'to.sql.migration');
|
|
385
347
|
|
|
386
348
|
// Prepare after-image.
|
|
387
|
-
const afterImage = forSql(csn,
|
|
349
|
+
const afterImage = forSql(csn, internalOptions);
|
|
388
350
|
// Compare both images.
|
|
389
351
|
const diff = modelCompare.compareModels(beforeImage || afterImage, afterImage, internalOptions);
|
|
390
|
-
const diffFilterObj = diffFilter[
|
|
352
|
+
const diffFilterObj = diffFilter[internalOptions.sqlDialect];
|
|
391
353
|
|
|
392
354
|
if (diffFilterObj) {
|
|
393
355
|
diff.extensions.forEach(ex => diffFilterObj.extension(ex, error));
|
|
@@ -489,6 +451,7 @@ function sqlMigration( csn, options, beforeImage ) {
|
|
|
489
451
|
* @returns {migration} The migration result
|
|
490
452
|
*/
|
|
491
453
|
function hdiMigration( csn, options, beforeImage ) {
|
|
454
|
+
traceApi("Options passed into 'to.hdi.migration'", options);
|
|
492
455
|
const internalOptions = prepareOptions.to.hdi(options);
|
|
493
456
|
|
|
494
457
|
// Prepare after-image.
|
|
@@ -569,6 +532,7 @@ sql.migration = sqlMigration;
|
|
|
569
532
|
* @returns {HDBCDS} { <filename>:<content>, ...}
|
|
570
533
|
*/
|
|
571
534
|
function hdbcds( csn, options = {} ) {
|
|
535
|
+
traceApi("Options passed into 'to.hdbcds'", options);
|
|
572
536
|
const internalOptions = prepareOptions.to.hdbcds(options);
|
|
573
537
|
internalOptions.transformation = 'hdbcds';
|
|
574
538
|
|
|
@@ -585,6 +549,7 @@ function hdbcds( csn, options = {} ) {
|
|
|
585
549
|
* @returns {edm} The JSON representation of the service
|
|
586
550
|
*/
|
|
587
551
|
function edm( csn, options = {} ) {
|
|
552
|
+
traceApi("Options passed into 'to.edm'", options);
|
|
588
553
|
// If not provided at all, set service to undefined to trigger validation
|
|
589
554
|
const internalOptions = prepareOptions.to.edm(
|
|
590
555
|
// eslint-disable-next-line comma-dangle
|
|
@@ -615,6 +580,7 @@ edm.all = edmall;
|
|
|
615
580
|
* @returns {edms} { <service>:<JSON representation>, ...}
|
|
616
581
|
*/
|
|
617
582
|
function edmall( csn, options = {} ) {
|
|
583
|
+
traceApi("Options passed into 'to.edm.all'", options);
|
|
618
584
|
const internalOptions = prepareOptions.to.edm(options);
|
|
619
585
|
const { error } = messages.makeMessageFunction(csn, internalOptions, 'for.odata');
|
|
620
586
|
|
|
@@ -645,6 +611,7 @@ function edmall( csn, options = {} ) {
|
|
|
645
611
|
* @returns {edmx} The XML representation of the service
|
|
646
612
|
*/
|
|
647
613
|
function edmx( csn, options = {} ) {
|
|
614
|
+
traceApi("Options passed into 'to.edmx'", options);
|
|
648
615
|
// If not provided at all, set service to undefined to trigger validation
|
|
649
616
|
const internalOptions = prepareOptions.to.edmx(
|
|
650
617
|
// eslint-disable-next-line comma-dangle
|
|
@@ -676,6 +643,7 @@ edmx.all = edmxall;
|
|
|
676
643
|
* @returns {edmxs} { <service>:<XML representation>, ...}
|
|
677
644
|
*/
|
|
678
645
|
function edmxall( csn, options = {} ) {
|
|
646
|
+
traceApi("Options passed into 'to.edmx.all'", options);
|
|
679
647
|
const internalOptions = prepareOptions.to.edmx(options);
|
|
680
648
|
|
|
681
649
|
const result = {};
|
|
@@ -792,6 +760,20 @@ function flattenResultStructure( toProcess ) {
|
|
|
792
760
|
return result;
|
|
793
761
|
}
|
|
794
762
|
|
|
763
|
+
/**
|
|
764
|
+
* Print args to stderr if CDSC_TRACE_API is set
|
|
765
|
+
*
|
|
766
|
+
* @param {...any} args
|
|
767
|
+
*/
|
|
768
|
+
function traceApi( ...args ) {
|
|
769
|
+
if (process?.env?.CDSC_TRACE_API !== undefined) {
|
|
770
|
+
for (const arg of args) {
|
|
771
|
+
// eslint-disable-next-line no-console
|
|
772
|
+
console.error( `${ typeof arg === 'object' ? JSON.stringify(arg, null, 2) : arg }`);
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
|
|
795
777
|
module.exports = {
|
|
796
778
|
odata: publishCsnProcessor(odata, 'for.odata'),
|
|
797
779
|
cdl: publishCsnProcessor(cdl, 'to.cdl'),
|
|
@@ -804,8 +786,6 @@ module.exports = {
|
|
|
804
786
|
for_sql: publishCsnProcessor(forSql, 'for.sql'),
|
|
805
787
|
for_hdi: publishCsnProcessor(forHdi, 'for.hdi'),
|
|
806
788
|
for_hdbcds: publishCsnProcessor(forHdbcds, 'for.hdbcds'),
|
|
807
|
-
/** beta - WIP */
|
|
808
|
-
mtx: publishCsnProcessor(mtx, 'to.mtx'),
|
|
809
789
|
/** Deprecated, will be removed in cds-compiler@v4 */
|
|
810
790
|
preparedCsnToEdmx,
|
|
811
791
|
preparedCsnToEdm,
|
|
@@ -826,9 +806,6 @@ function publishCsnProcessor( processor, _name ) {
|
|
|
826
806
|
if (processor.migration)
|
|
827
807
|
api.migration = publishCsnProcessor(processor.migration, `${ _name }.migration`);
|
|
828
808
|
|
|
829
|
-
if (processor.mtx)
|
|
830
|
-
api.mtx = publishCsnProcessor(processor.mtx, `${ _name }.mtx`);
|
|
831
|
-
|
|
832
809
|
return api;
|
|
833
810
|
|
|
834
811
|
/**
|
package/lib/api/options.js
CHANGED
package/lib/api/validate.js
CHANGED
|
@@ -109,6 +109,11 @@ const validators = {
|
|
|
109
109
|
expected: () => 'type string',
|
|
110
110
|
found: val => `type ${ typeof val }`,
|
|
111
111
|
},
|
|
112
|
+
testMode: {
|
|
113
|
+
validate: val => typeof val === 'boolean' || typeof val === 'number',
|
|
114
|
+
expected: () => 'type boolean|number',
|
|
115
|
+
found: val => `type ${ typeof val }`,
|
|
116
|
+
},
|
|
112
117
|
dictionaryPrototype: {
|
|
113
118
|
validate: () => true,
|
|
114
119
|
},
|