@sap/cds-compiler 2.7.0 → 2.11.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 +167 -0
- package/bin/cdsc.js +42 -25
- package/bin/cdsse.js +1 -0
- package/doc/CHANGELOG_BETA.md +10 -0
- package/lib/api/.eslintrc.json +2 -0
- package/lib/api/main.js +17 -33
- package/lib/api/options.js +25 -13
- package/lib/api/validate.js +33 -9
- package/lib/backends.js +9 -8
- package/lib/base/dictionaries.js +2 -1
- package/lib/base/keywords.js +32 -2
- package/lib/base/message-registry.js +26 -2
- package/lib/base/messages.js +25 -9
- package/lib/base/model.js +5 -3
- package/lib/base/optionProcessorHelper.js +56 -22
- package/lib/checks/onConditions.js +5 -0
- package/lib/checks/selectItems.js +4 -0
- package/lib/checks/types.js +26 -2
- package/lib/checks/unknownMagic.js +41 -0
- package/lib/checks/validator.js +7 -2
- package/lib/compiler/assert-consistency.js +18 -5
- package/lib/compiler/base.js +65 -0
- package/lib/compiler/builtins.js +30 -1
- package/lib/compiler/checks.js +5 -2
- package/lib/compiler/definer.js +145 -120
- package/lib/compiler/index.js +16 -4
- package/lib/compiler/propagator.js +5 -2
- package/lib/compiler/resolver.js +207 -47
- package/lib/compiler/shared.js +47 -200
- package/lib/compiler/utils.js +173 -0
- package/lib/edm/annotations/genericTranslation.js +183 -187
- package/lib/edm/csn2edm.js +94 -98
- package/lib/edm/edm.js +16 -20
- package/lib/edm/edmPreprocessor.js +302 -115
- package/lib/edm/edmUtils.js +31 -12
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +28 -1
- package/lib/gen/language.tokens +79 -69
- package/lib/gen/languageLexer.interp +28 -1
- package/lib/gen/languageLexer.js +879 -805
- package/lib/gen/languageLexer.tokens +71 -62
- package/lib/gen/languageParser.js +5308 -4308
- package/lib/json/from-csn.js +59 -30
- package/lib/json/to-csn.js +354 -105
- package/lib/language/antlrParser.js +11 -0
- package/lib/language/errorStrategy.js +1 -0
- package/lib/language/genericAntlrParser.js +81 -14
- package/lib/language/language.g4 +163 -31
- package/lib/main.d.ts +136 -17
- package/lib/main.js +7 -1
- package/lib/model/api.js +78 -0
- package/lib/model/csnRefs.js +115 -32
- package/lib/model/csnUtils.js +71 -33
- package/lib/model/enrichCsn.js +36 -9
- package/lib/model/revealInternalProperties.js +20 -4
- package/lib/modelCompare/compare.js +2 -1
- package/lib/optionProcessor.js +33 -16
- package/lib/render/.eslintrc.json +3 -1
- package/lib/render/DuplicateChecker.js +1 -1
- package/lib/render/toCdl.js +60 -17
- package/lib/render/toHdbcds.js +122 -74
- package/lib/render/toSql.js +57 -32
- package/lib/render/utils/common.js +6 -10
- package/lib/sql-identifier.js +6 -1
- package/lib/transform/db/constraints.js +273 -119
- package/lib/transform/db/draft.js +9 -6
- package/lib/transform/db/expansion.js +19 -7
- package/lib/transform/db/flattening.js +31 -7
- package/lib/transform/db/transformExists.js +344 -66
- package/lib/transform/db/views.js +438 -0
- package/lib/transform/forHanaNew.js +65 -436
- package/lib/transform/forOdataNew.js +21 -10
- package/lib/transform/localized.js +2 -0
- package/lib/transform/odata/attachPath.js +19 -4
- package/lib/transform/odata/generateForeignKeyElements.js +11 -10
- package/lib/transform/odata/referenceFlattener.js +44 -38
- package/lib/transform/odata/sortByAssociationDependency.js +2 -2
- package/lib/transform/odata/structuralPath.js +72 -0
- package/lib/transform/odata/structureFlattener.js +13 -10
- package/lib/transform/odata/typesExposure.js +22 -12
- package/lib/transform/transformUtilsNew.js +55 -9
- package/lib/transform/translateAssocsToJoins.js +11 -17
- package/lib/transform/universalCsnEnricher.js +67 -0
- package/lib/utils/file.js +5 -3
- package/lib/utils/term.js +65 -42
- package/lib/utils/timetrace.js +48 -26
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,173 @@
|
|
|
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 2.11.2 - 2021-12-06
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- to.sql/hdi/hdbcds:
|
|
15
|
+
+ No foreign key constraint will be rendered for managed `composition of one` if annotated with `@assert.integrity: false`
|
|
16
|
+
+ Correctly handle managed associations with other managed associations as foreign keys in conjunction with `exists`
|
|
17
|
+
|
|
18
|
+
## Version 2.11.0 - 2021-12-02
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- Option `defaultBinaryLength` to set a `length` type facet for all definitions with type `cds.Binary`. This option
|
|
23
|
+
overrides the default binary length in the database backends and is also used as `MaxLength` attribute in Odata.
|
|
24
|
+
- If doc-comments are ignored by the compiler, an info message is now emitted. A doc-comment is ignored,
|
|
25
|
+
if it can't be assigned to an artifact. For example for two subsequent doc-comments, the first doc-comment
|
|
26
|
+
is ignored. To suppress these info messages, explicitly set option `docComment` to `false`.
|
|
27
|
+
- `cdsc`:
|
|
28
|
+
- `cdsc explain list` can now be used to get a list of message IDs with explanation texts.
|
|
29
|
+
- `cdsc` now respects the environment variable `NO_COLOR`. If set, no ANSI escape codes will be used.
|
|
30
|
+
Can be overwritten by `cdsc --color always`.
|
|
31
|
+
- to.sql/hdi: Support SQL Window Functions
|
|
32
|
+
- to.sql/hdi/hdbcds:
|
|
33
|
+
+ Support configuration of `$session` and `$user` via option `variableReplacements`.
|
|
34
|
+
+ Restricted support for SQL foreign key constraints if option `assertIntegrityType` is set to `"DB"`.
|
|
35
|
+
The behavior of this feature might change in the future.
|
|
36
|
+
|
|
37
|
+
### Changed
|
|
38
|
+
|
|
39
|
+
- Updated OData vocabularies 'Common' and 'UI'.
|
|
40
|
+
- to.sql/hdi/hdbcds: The default length of `cds.Binary` is set to `5000` similar to `cds.String`.
|
|
41
|
+
|
|
42
|
+
### Removed
|
|
43
|
+
|
|
44
|
+
- to.hdbcds: Doc comments on view columns are not rendered anymore. Doc comments on string literals will make the deployment fail
|
|
45
|
+
as the SAP HANA CDS compiler concatenates the doc comment with the string literal. Besides that, doc comments on view columns
|
|
46
|
+
are not transported to the database by SAP HANA CDS.
|
|
47
|
+
- to.hdbcds/sql/hdi: Forbid associations in filters after `exists` (except for nested `exists`), as the final behavior is not yet specified.
|
|
48
|
+
|
|
49
|
+
### Fixed
|
|
50
|
+
|
|
51
|
+
- CSN parser: doc-comment extensions are no longer ignored.
|
|
52
|
+
- Properly check for duplicate annotation definitions.
|
|
53
|
+
- Correctly apply annotations on inherited enum symbols.
|
|
54
|
+
- Correctly apply annotations on elements in an inherited structure array.
|
|
55
|
+
- Fix a bug in API `defaultStringLength` value evaluation.
|
|
56
|
+
- Fix crash if named arguments are used in a function that's inside a `CASE` statement.
|
|
57
|
+
- to.sql/hdi/hdbcds:
|
|
58
|
+
+ Properly flatten ad-hoc defined elements in `returns` / `params` of `actions` and `functions`.
|
|
59
|
+
+ Correctly handle `*` in non-first position.
|
|
60
|
+
+ Correctly handle action return types
|
|
61
|
+
+ Correctly handle mixin association named `$self`
|
|
62
|
+
- to.cdl: doc-comments are no longer rendered twice.
|
|
63
|
+
- to.edm(x):
|
|
64
|
+
+ Fix a bug in V2/V4 partner ship calculation.
|
|
65
|
+
+ Remove warning of unknown types for Open Types in `@Core.Dictionary`.
|
|
66
|
+
+ An empty CSN no longer results in a JavaScript type error
|
|
67
|
+
|
|
68
|
+
## Version 2.10.4 - 2021-11-05
|
|
69
|
+
|
|
70
|
+
### Fixed
|
|
71
|
+
|
|
72
|
+
- to.sql/hdi/hdbcds:
|
|
73
|
+
+ Correctly complain about `exists` in conjunction with non-associations/compositions
|
|
74
|
+
+ Don't resolve types in action returns, as this causes issues with $self-resolution
|
|
75
|
+
|
|
76
|
+
- to.edm(x): Be robust against transitively untyped keys in stacked view hierarchies
|
|
77
|
+
|
|
78
|
+
## Version 2.10.2 - 2021-10-29
|
|
79
|
+
|
|
80
|
+
### Fixed
|
|
81
|
+
|
|
82
|
+
- to.sql/hdi/hdbcds: Correctly handle `exists` in conjunction with mixin-associations
|
|
83
|
+
|
|
84
|
+
## Version 2.10.0 - 2021-10-28
|
|
85
|
+
|
|
86
|
+
### Added
|
|
87
|
+
|
|
88
|
+
- Support arbitrary paths after `$user` - similar to `$session`.
|
|
89
|
+
- Support scale `floating` and `variable` for `cds.Decimal` in CDL and CSN. Backend specific handling is descibed in their sections.
|
|
90
|
+
- Allow select item wildcard (`*`) in a `select`/`projection` at any position, not just the first.
|
|
91
|
+
|
|
92
|
+
- to.edm(x):
|
|
93
|
+
+ In Odata V4 generate transitive navigation property binding paths along containment hierarchies and terminate on the
|
|
94
|
+
first non-containment association. The association target is either an explicit Edm.EntitySet in the same EntityContainer
|
|
95
|
+
or in a referred EntityContainer (cross service references) or an implicit EntitySet identified by the containment path
|
|
96
|
+
originating from an explicit EntitySet. This enhancement has an observable effect only in structured format with containment
|
|
97
|
+
turned on.
|
|
98
|
+
+ Support for scales `variable` and `floating`:
|
|
99
|
+
+ V4: `variable` and `floating` are rendered as `Scale="variable"`. Since V4 does not support `floating`, it is aproximated as `variable`.
|
|
100
|
+
+ V2: `variable` and `floating` are announced via property annotation `sap:variable-scale="true"`
|
|
101
|
+
|
|
102
|
+
- to.sql/hdi/hdbcds:
|
|
103
|
+
+ Reject scale `floating` and `variable`.
|
|
104
|
+
+ Reject arbitrary `$user` or `$session` paths that cannot be translated to valid SQL.
|
|
105
|
+
+ Following a valid `exists`, further `exists` can be used inside of the filter-expression: `exists assoc[exists another[1=1]]`
|
|
106
|
+
+ `exists` can now be followed by more than one association step.
|
|
107
|
+
`exists assoc.anotherassoc.moreassoc` is semantically equivalent to `exists assoc[exists anotherassoc[exists moreassoc]]`
|
|
108
|
+
|
|
109
|
+
### Changed
|
|
110
|
+
|
|
111
|
+
- to.odata: Inform when overwriting draft action annotations like `@Common.DraftRoot.ActivationAction`.
|
|
112
|
+
|
|
113
|
+
## Version 2.9.0 - 2021-10-15
|
|
114
|
+
|
|
115
|
+
### Changed
|
|
116
|
+
|
|
117
|
+
- to.edm(x): Raise `odata-spec-violation-type` to a downgradable error.
|
|
118
|
+
|
|
119
|
+
### Fixed
|
|
120
|
+
|
|
121
|
+
- to.edm(x):
|
|
122
|
+
+ Fix a bug in annotation propagation to foreign keys.
|
|
123
|
+
+ Don't render annotations for not rendered stream element in V2.
|
|
124
|
+
- to.hdi:
|
|
125
|
+
+ for naming mode "hdbcds" and "quoted" parameter definitions are not quoted anymore.
|
|
126
|
+
- to.hdi/sql/hdbcds:
|
|
127
|
+
+ Correctly handle explicit and implicit alias during flattening.
|
|
128
|
+
+ Raise an error for `@odata.draft.enabled` artifacts with elements without types - instead of crashing with internal assertions.
|
|
129
|
+
|
|
130
|
+
## Version 2.8.0 - 2021-10-07
|
|
131
|
+
|
|
132
|
+
### Added
|
|
133
|
+
|
|
134
|
+
- Allow defining unmanaged associations in anonymous aspects of compositions.
|
|
135
|
+
- Enable extensions of anonymous aspects for managed compositions of aspects.
|
|
136
|
+
- When the option `addTextsLanguageAssoc` is set to true and
|
|
137
|
+
the model contains an entity `sap.common.Languages` with an element `code`,
|
|
138
|
+
all generated texts entities additionally contain an element `language`
|
|
139
|
+
which is an association to `sap.common.Languages` using element `local`.
|
|
140
|
+
- for.odata:
|
|
141
|
+
+ In `--odata-format=flat`, structured view parameters are flattened like elements.
|
|
142
|
+
- to.hdbcds
|
|
143
|
+
+ Use "smart quotes" for naming mode "plain" - automatically quote identifier which are reserved keywords or non-regular.
|
|
144
|
+
|
|
145
|
+
### Changed
|
|
146
|
+
|
|
147
|
+
- for.odata:
|
|
148
|
+
+ In `--data-format=structured`, anonymous sub elements of primary keys and parameters are set to `notNull:true`,
|
|
149
|
+
an existing `notNull` attribute is _not_ overwritten. Referred named types are _not_ modified.
|
|
150
|
+
- to.edm(x):
|
|
151
|
+
+ Improve specification violation checks of (nested) keys:
|
|
152
|
+
+ All (sub-)elements must be `Nullable: false` (error).
|
|
153
|
+
+ Must represent a single value (error).
|
|
154
|
+
+ In V4 must be a specification compliant Edm.PrimitiveType (warning).
|
|
155
|
+
- to.hdi/hdbcds/sql: $user.\<xy\> now has \<xy\> added as alias - "$user.\<xy\> as \<xy\>"
|
|
156
|
+
|
|
157
|
+
### Fixed
|
|
158
|
+
|
|
159
|
+
- Properly generate auto-exposed entities for associations in parameters.
|
|
160
|
+
- Correctly apply extensions to anonymous array item types.
|
|
161
|
+
- Correctly apply/render annotations to anonymous action return types.
|
|
162
|
+
- With CSN flavor `plain` (`gensrc`), correctly render annotations on elements
|
|
163
|
+
of referred structure types as `annotate` statements in the CSN's `extensions` property.
|
|
164
|
+
- to.cdl:
|
|
165
|
+
+ Correctly render extensions on array item types
|
|
166
|
+
+ Correctly render annotations on action return types
|
|
167
|
+
- to/for: Correctly handle CSN input where the prototype of objects is not the "default"
|
|
168
|
+
- to.hdi:
|
|
169
|
+
+ for naming mode "hdbcds" and "quoted" parameter definitions are now quoted.
|
|
170
|
+
+ for naming mode "plain", smart quotation is applied to parameter definitions if they are reserved words.
|
|
171
|
+
- to.hdi/hdbcds/sql:
|
|
172
|
+
+ Ensure that cdl-style casts to localized types do not lose their localized property
|
|
173
|
+
+ Fix a small memory leak during rendering of SQL/HDBCDS.
|
|
174
|
+
- to.edm(x): Remove ambiguous `Partner` attribute from `NavigationProperty`. A forward association referred
|
|
175
|
+
to by multiple backlinks (`$self` comparisons) is no longer partner to an arbitrary backlink.
|
|
176
|
+
|
|
10
177
|
## Version 2.7.0 - 2021-09-22
|
|
11
178
|
|
|
12
179
|
### Added
|
package/bin/cdsc.js
CHANGED
|
@@ -26,8 +26,10 @@ const path = require('path');
|
|
|
26
26
|
const { reveal } = require('../lib/model/revealInternalProperties');
|
|
27
27
|
const enrichCsn = require('../lib/model/enrichCsn');
|
|
28
28
|
const { optionProcessor } = require('../lib/optionProcessor');
|
|
29
|
-
const {
|
|
30
|
-
|
|
29
|
+
const {
|
|
30
|
+
explainMessage, hasMessageExplanation, sortMessages, messageIdsWithExplanation,
|
|
31
|
+
} = require('../lib/base/messages');
|
|
32
|
+
const { term } = require('../lib/utils/term');
|
|
31
33
|
const { splitLines } = require('../lib/utils/file');
|
|
32
34
|
const { addLocalizationViews } = require('../lib/transform/localized');
|
|
33
35
|
const { availableBetaFlags } = require('../lib/base/model');
|
|
@@ -52,9 +54,11 @@ function remapCmdOptions(options, cmdOptions) {
|
|
|
52
54
|
options.sqlMapping = value;
|
|
53
55
|
break;
|
|
54
56
|
case 'user':
|
|
55
|
-
if (!options.
|
|
56
|
-
options.
|
|
57
|
-
options.
|
|
57
|
+
if (!options.variableReplacements)
|
|
58
|
+
options.variableReplacements = {};
|
|
59
|
+
if (!options.variableReplacements.$user)
|
|
60
|
+
options.variableReplacements.$user = {};
|
|
61
|
+
options.variableReplacements.$user.id = value;
|
|
58
62
|
break;
|
|
59
63
|
case 'dialect':
|
|
60
64
|
options.sqlDialect = value;
|
|
@@ -63,9 +67,11 @@ function remapCmdOptions(options, cmdOptions) {
|
|
|
63
67
|
options.odataVersion = value;
|
|
64
68
|
break;
|
|
65
69
|
case 'locale':
|
|
66
|
-
if (!options.
|
|
67
|
-
options.
|
|
68
|
-
options.
|
|
70
|
+
if (!options.variableReplacements)
|
|
71
|
+
options.variableReplacements = {};
|
|
72
|
+
if (!options.variableReplacements.$user)
|
|
73
|
+
options.variableReplacements.$user = {};
|
|
74
|
+
options.variableReplacements.$user.locale = value;
|
|
69
75
|
break;
|
|
70
76
|
default:
|
|
71
77
|
options[key] = value;
|
|
@@ -124,8 +130,6 @@ try {
|
|
|
124
130
|
global.cds = {};
|
|
125
131
|
global.cds.home = cmdLine.options.cdsHome;
|
|
126
132
|
}
|
|
127
|
-
// Default color mode is 'auto'
|
|
128
|
-
term.useColor(cmdLine.options.color || 'auto');
|
|
129
133
|
|
|
130
134
|
// Set default command if required
|
|
131
135
|
cmdLine.command = cmdLine.command || 'toCsn';
|
|
@@ -137,10 +141,7 @@ try {
|
|
|
137
141
|
if (cmdLine.command === 'parseCdl') {
|
|
138
142
|
cmdLine.command = 'toCsn';
|
|
139
143
|
cmdLine.options.parseCdl = true;
|
|
140
|
-
|
|
141
|
-
const err = `'parseCdl' expects exactly one file! ${cmdLine.args.files.length} provided.`;
|
|
142
|
-
displayUsage(err, optionProcessor.commands.parseCdl.helpText, 2);
|
|
143
|
-
}
|
|
144
|
+
cmdLine.args.files = [ cmdLine.args.file ];
|
|
144
145
|
}
|
|
145
146
|
|
|
146
147
|
if (cmdLine.options.directBackend)
|
|
@@ -155,6 +156,14 @@ try {
|
|
|
155
156
|
});
|
|
156
157
|
}
|
|
157
158
|
|
|
159
|
+
// remap string values for `assertIntegrity` option to boolean
|
|
160
|
+
if (cmdLine.options.assertIntegrity &&
|
|
161
|
+
cmdLine.options.assertIntegrity === 'true' ||
|
|
162
|
+
cmdLine.options.assertIntegrity === 'false'
|
|
163
|
+
)
|
|
164
|
+
cmdLine.options.assertIntegrity = Boolean(cmdLine.options.assertIntegrity);
|
|
165
|
+
|
|
166
|
+
|
|
158
167
|
// Enable all beta-flags if betaMode is set to true
|
|
159
168
|
if (cmdLine.options.betaMode)
|
|
160
169
|
cmdLine.options.beta = availableBetaFlags;
|
|
@@ -231,6 +240,8 @@ function executeCommandLine(command, options, args) {
|
|
|
231
240
|
if (options.out && options.out !== '-' && !fs.existsSync(options.out))
|
|
232
241
|
fs.mkdirSync(options.out);
|
|
233
242
|
|
|
243
|
+
// Default color mode is 'auto'
|
|
244
|
+
const colorTerm = term(options.color || 'auto');
|
|
234
245
|
|
|
235
246
|
// Add implementation functions corresponding to commands here
|
|
236
247
|
const commands = {
|
|
@@ -393,14 +404,15 @@ function executeCommandLine(command, options, args) {
|
|
|
393
404
|
}
|
|
394
405
|
|
|
395
406
|
function explain() {
|
|
396
|
-
if (args.
|
|
397
|
-
|
|
407
|
+
if (args.messageId === 'list') {
|
|
408
|
+
console.log(messageIdsWithExplanation().join('\n'));
|
|
409
|
+
throw new ProcessExitError(0);
|
|
410
|
+
}
|
|
398
411
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
console.error(`Message '${id}' does not have an explanation!`);
|
|
412
|
+
if (!hasMessageExplanation(args.messageId))
|
|
413
|
+
console.error(`Message '${args.messageId}' does not have an explanation!`);
|
|
402
414
|
else
|
|
403
|
-
console.log(explainMessage(
|
|
415
|
+
console.log(explainMessage(args.messageId));
|
|
404
416
|
}
|
|
405
417
|
|
|
406
418
|
// Display error messages in `err` resulting from a compilation. Also set
|
|
@@ -464,16 +476,20 @@ function executeCommandLine(command, options, args) {
|
|
|
464
476
|
hasAtLeastOneExplanation = hasAtLeastOneExplanation || main.hasMessageExplanation(msg.messageId);
|
|
465
477
|
const name = msg.location && msg.location.file;
|
|
466
478
|
const fullFilePath = name ? path.resolve('', name) : undefined;
|
|
467
|
-
const context = fullFilePath
|
|
479
|
+
const context = fullFilePath ? sourceLines(fullFilePath) : [];
|
|
468
480
|
log(main.messageStringMultiline(msg, {
|
|
469
|
-
normalizeFilename,
|
|
481
|
+
normalizeFilename,
|
|
482
|
+
noMessageId: !options.showMessageId,
|
|
483
|
+
withLineSpacer: true,
|
|
484
|
+
hintExplanation: true,
|
|
485
|
+
color: options.color,
|
|
470
486
|
}));
|
|
471
487
|
if (context)
|
|
472
|
-
log(main.messageContext(context, msg));
|
|
488
|
+
log(main.messageContext(context, msg, { color: options.color }));
|
|
473
489
|
log(); // newline
|
|
474
490
|
});
|
|
475
491
|
if (options.showMessageId && hasAtLeastOneExplanation)
|
|
476
|
-
log(`${
|
|
492
|
+
log(`${colorTerm.help('help')}: Messages marked with '…' have an explanation text. Use \`cdsc explain <message-id>\` for a more detailed error description.`);
|
|
477
493
|
}
|
|
478
494
|
return model;
|
|
479
495
|
}
|
|
@@ -549,10 +565,11 @@ function executeCommandLine(command, options, args) {
|
|
|
549
565
|
}
|
|
550
566
|
|
|
551
567
|
function catchErrors(err) {
|
|
568
|
+
// @ts-ignore
|
|
552
569
|
if (err instanceof Error && err.hasBeenReported)
|
|
553
570
|
return;
|
|
554
571
|
console.error( '' );
|
|
555
|
-
console.error( 'INTERNAL ERROR:
|
|
572
|
+
console.error( 'INTERNAL ERROR:' );
|
|
556
573
|
console.error( util.inspect(err, false, null) );
|
|
557
574
|
console.error( '' );
|
|
558
575
|
process.exitCode = 70;
|
package/bin/cdsse.js
CHANGED
package/doc/CHANGELOG_BETA.md
CHANGED
|
@@ -8,6 +8,16 @@ Note: `beta` fixes, changes and features are listed in this ChangeLog just for i
|
|
|
8
8
|
The compiler behavior concerning `beta` features can change at any time without notice.
|
|
9
9
|
**Don't use `beta` fixes, changes and features in productive mode.**
|
|
10
10
|
|
|
11
|
+
## Version 2.11.0
|
|
12
|
+
|
|
13
|
+
### Removed `foreignKeyConstraints`
|
|
14
|
+
|
|
15
|
+
## Version 2.10.4
|
|
16
|
+
|
|
17
|
+
### Fixed `nestedProjections`
|
|
18
|
+
|
|
19
|
+
- to.sql/hdi/hdbcds: Correctly handle a `*` at the not-first place in the query
|
|
20
|
+
|
|
11
21
|
## Version 2.6.0
|
|
12
22
|
|
|
13
23
|
### Removed `pretransformedCSN`
|
package/lib/api/.eslintrc.json
CHANGED
package/lib/api/main.js
CHANGED
|
@@ -14,7 +14,7 @@ const { toSqlDdl } = require('../render/toSql');
|
|
|
14
14
|
const { compareModels } = require('../modelCompare/compare');
|
|
15
15
|
const sortViews = require('../model/sortViews');
|
|
16
16
|
const { getResultingName } = require('../model/csnUtils');
|
|
17
|
-
const timetrace = require('../utils/timetrace');
|
|
17
|
+
const { timetrace } = require('../utils/timetrace');
|
|
18
18
|
const { transformForHanaWithCsn } = require('../transform/forHanaNew');
|
|
19
19
|
|
|
20
20
|
/**
|
|
@@ -135,7 +135,7 @@ function odataInternal(csn, internalOptions) {
|
|
|
135
135
|
* Return a odata-transformed CSN
|
|
136
136
|
*
|
|
137
137
|
* @param {CSN.Model} csn Clean input CSN
|
|
138
|
-
* @param {
|
|
138
|
+
* @param {ODataOptions} [options={}] Options
|
|
139
139
|
* @returns {oDataCSN} Return an oData-pre-processed CSN
|
|
140
140
|
*/
|
|
141
141
|
function odata(csn, options = {}) {
|
|
@@ -454,7 +454,7 @@ function hdbcds(csn, options = {}) {
|
|
|
454
454
|
* Generate a edm document for the given service
|
|
455
455
|
*
|
|
456
456
|
* @param {CSN|oDataCSN} csn Clean input CSN or a pre-transformed CSN
|
|
457
|
-
* @param {
|
|
457
|
+
* @param {ODataOptions} [options={}] Options
|
|
458
458
|
* @returns {edm} The JSON representation of the service
|
|
459
459
|
*/
|
|
460
460
|
function edm(csn, options = {}) {
|
|
@@ -484,7 +484,7 @@ edm.all = edmall;
|
|
|
484
484
|
* Generate edm documents for all services
|
|
485
485
|
*
|
|
486
486
|
* @param {CSN|oDataCSN} csn Clean input CSN or a pre-transformed CSN
|
|
487
|
-
* @param {
|
|
487
|
+
* @param {ODataOptions} [options={}] Options
|
|
488
488
|
* @returns {edms} { <service>:<JSON representation>, ...}
|
|
489
489
|
*/
|
|
490
490
|
function edmall(csn, options = {}) {
|
|
@@ -494,19 +494,17 @@ function edmall(csn, options = {}) {
|
|
|
494
494
|
if (internalOptions.version === 'v2')
|
|
495
495
|
error(null, null, 'OData JSON output is not available for OData V2');
|
|
496
496
|
|
|
497
|
-
let servicesAll;
|
|
498
|
-
|
|
499
497
|
const result = {};
|
|
498
|
+
let oDataCsn = csn;
|
|
500
499
|
|
|
501
|
-
if (isPreTransformed(csn, 'odata'))
|
|
500
|
+
if (isPreTransformed(csn, 'odata'))
|
|
502
501
|
checkPreTransformedCsn(csn, internalOptions, relevantOdataOptions, warnAboutMismatchOdata, 'for.odata');
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
const services = servicesAll.edmj;
|
|
502
|
+
|
|
503
|
+
else
|
|
504
|
+
oDataCsn = odataInternal(csn, internalOptions);
|
|
505
|
+
|
|
506
|
+
const servicesJson = backends.preparedCsnToEdmAll(oDataCsn, internalOptions);
|
|
507
|
+
const services = servicesJson.edmj;
|
|
510
508
|
for (const serviceName in services) {
|
|
511
509
|
const lEdm = services[serviceName];
|
|
512
510
|
// FIXME: Why only metadata_json - isn't this rather a 'combined_json' ? If so, rename it!
|
|
@@ -518,7 +516,7 @@ function edmall(csn, options = {}) {
|
|
|
518
516
|
* Generate a edmx document for the given service
|
|
519
517
|
*
|
|
520
518
|
* @param {CSN|oDataCSN} csn Clean input CSN or a pre-transformed CSN
|
|
521
|
-
* @param {
|
|
519
|
+
* @param {ODataOptions} [options={}] Options
|
|
522
520
|
* @returns {edmx} The XML representation of the service
|
|
523
521
|
*/
|
|
524
522
|
function edmx(csn, options = {}) {
|
|
@@ -549,7 +547,7 @@ edmx.all = edmxall;
|
|
|
549
547
|
* Generate edmx documents for all services
|
|
550
548
|
*
|
|
551
549
|
* @param {CSN|oDataCSN} csn Clean input CSN or a pre-transformed CSN
|
|
552
|
-
* @param {
|
|
550
|
+
* @param {ODataOptions} [options={}] Options
|
|
553
551
|
* @returns {edmxs} { <service>:<XML representation>, ...}
|
|
554
552
|
*/
|
|
555
553
|
function edmxall(csn, options = {}) {
|
|
@@ -711,20 +709,6 @@ function publishCsnProcessor( processor, _name ) {
|
|
|
711
709
|
* @property {Array} [messages] Allows collecting all messages in the options instead of printing them to stderr.
|
|
712
710
|
*/
|
|
713
711
|
|
|
714
|
-
/**
|
|
715
|
-
* Options available for all oData-based functions
|
|
716
|
-
*
|
|
717
|
-
* @typedef {object} oDataOptions
|
|
718
|
-
* @property {object} [beta] Enable experimental features - not for productive use!
|
|
719
|
-
* @property {boolean} [longAutoexposed=false] Deprecated: Produce long names (with underscores) for autoexposed entities
|
|
720
|
-
* @property {Map<string, number>} [severities={}] Map of message-id and severity that allows setting the severity for the given message
|
|
721
|
-
* @property {Array} [messages] Allows collecting all messages in the options instead of printing them to stderr.
|
|
722
|
-
* @property {oDataVersion} [odataVersion='v4'] Odata version to use
|
|
723
|
-
* @property {oDataFormat} [odataFormat='flat'] Wether to generate oData as flat or as structured. Structured only with v4.
|
|
724
|
-
* @property {NamingMode} [sqlMapping='plain'] Naming mode to use
|
|
725
|
-
* @property {string} [service] If a single service is to be rendered
|
|
726
|
-
*/
|
|
727
|
-
|
|
728
712
|
/**
|
|
729
713
|
* Options available for to.hdi
|
|
730
714
|
*
|
|
@@ -755,9 +739,9 @@ function publishCsnProcessor( processor, _name ) {
|
|
|
755
739
|
* @typedef {object} sqlOptions
|
|
756
740
|
* @property {NamingMode} [sqlMapping='plain'] Naming mode to use
|
|
757
741
|
* @property {SQLDialect} [sqlDialect='sqlite'] SQL dialect to use
|
|
758
|
-
* @property {object} [
|
|
759
|
-
* @property {string} [
|
|
760
|
-
* @property {string} [
|
|
742
|
+
* @property {object} [variableReplacements] Object containing values for magic variables like "$user"
|
|
743
|
+
* @property {string} [variableReplacements.$user.locale] Value for the "$user.locale" variable
|
|
744
|
+
* @property {string} [variableReplacements.$user.id] Value for the "$userid" variable
|
|
761
745
|
* @property {object} [beta] Enable experimental features - not for productive use!
|
|
762
746
|
* @property {boolean} [longAutoexposed=false] Deprecated: Produce long names (with underscores) for autoexposed entities
|
|
763
747
|
* @property {Map<string, number>} [severities={}] Map of message-id and severity that allows setting the severity for the given message
|
package/lib/api/options.js
CHANGED
|
@@ -10,18 +10,22 @@ const publicOptionsNewAPI = [
|
|
|
10
10
|
// GENERAL
|
|
11
11
|
'beta',
|
|
12
12
|
'deprecated',
|
|
13
|
+
'addTextsLanguageAssoc',
|
|
13
14
|
'localizedLanguageFallback', // why can't I define the option type here?
|
|
14
15
|
'severities',
|
|
15
16
|
'messages',
|
|
16
17
|
'withLocations',
|
|
18
|
+
'defaultBinaryLength',
|
|
17
19
|
'defaultStringLength',
|
|
20
|
+
'csnFlavor',
|
|
18
21
|
// DB
|
|
19
22
|
'sqlDialect',
|
|
20
23
|
'sqlMapping',
|
|
21
24
|
'sqlChangeMode',
|
|
22
25
|
'allowCsnDowngrade',
|
|
23
26
|
'joinfk',
|
|
24
|
-
'magicVars',
|
|
27
|
+
'magicVars', // deprecated
|
|
28
|
+
'variableReplacements',
|
|
25
29
|
// ODATA
|
|
26
30
|
'odataVersion',
|
|
27
31
|
'odataFormat',
|
|
@@ -45,9 +49,10 @@ const privateOptions = [
|
|
|
45
49
|
'traceParserAmb',
|
|
46
50
|
'testMode',
|
|
47
51
|
'testSortCsn',
|
|
48
|
-
'
|
|
49
|
-
'
|
|
50
|
-
'
|
|
52
|
+
'integrityNotEnforced',
|
|
53
|
+
'integrityNotValidated',
|
|
54
|
+
'assertIntegrity',
|
|
55
|
+
'assertIntegrityType',
|
|
51
56
|
'noRecompile',
|
|
52
57
|
'internalMsg',
|
|
53
58
|
'disableHanaComments', // in case of issues with hana comment rendering
|
|
@@ -68,10 +73,11 @@ const overallOptions = publicOptionsNewAPI.concat(privateOptions);
|
|
|
68
73
|
* @param {FlatOptions} [hardRequire={}] Hard requirements to enforce
|
|
69
74
|
* @param {object} [customValidators] Custom validations to run instead of defaults
|
|
70
75
|
* @param {string[]} [combinationValidators] Option combinations to validate
|
|
76
|
+
* @param {string} moduleName The called module, e.g. 'for.odata', 'to.hdi'. Needed to initialize the message functions
|
|
71
77
|
* @returns {TranslatedOptions} General cds options
|
|
72
78
|
*/
|
|
73
79
|
function translateOptions(input = {}, defaults = {}, hardRequire = {},
|
|
74
|
-
customValidators = {}, combinationValidators = []) {
|
|
80
|
+
customValidators = {}, combinationValidators = [], moduleName = '') {
|
|
75
81
|
const options = Object.assign({}, defaults);
|
|
76
82
|
const inputOptionNames = Object.keys(input);
|
|
77
83
|
for (const name of overallOptions) {
|
|
@@ -90,6 +96,7 @@ function translateOptions(input = {}, defaults = {}, hardRequire = {},
|
|
|
90
96
|
// Validate the filtered input options
|
|
91
97
|
// only "new-style" options are here
|
|
92
98
|
validate(options,
|
|
99
|
+
moduleName,
|
|
93
100
|
// TODO: is there a better place to specify the type of option values?
|
|
94
101
|
Object.assign( {
|
|
95
102
|
localizedLanguageFallback: generateStringValidator([ 'none', 'coalesce' ]),
|
|
@@ -105,6 +112,10 @@ function translateOptions(input = {}, defaults = {}, hardRequire = {},
|
|
|
105
112
|
mapToOldNames(optionName, optionValue);
|
|
106
113
|
}
|
|
107
114
|
|
|
115
|
+
// Convenience for $user -> $user.id replacement
|
|
116
|
+
if (options.variableReplacements && options.variableReplacements.$user && typeof options.variableReplacements.$user === 'string')
|
|
117
|
+
options.variableReplacements.$user = { id: options.variableReplacements.$user };
|
|
118
|
+
|
|
108
119
|
/**
|
|
109
120
|
* Map a new-style option to it's old format
|
|
110
121
|
*
|
|
@@ -126,6 +137,7 @@ function translateOptions(input = {}, defaults = {}, hardRequire = {},
|
|
|
126
137
|
case 'sqlMapping':
|
|
127
138
|
options.names = optionValue;
|
|
128
139
|
break;
|
|
140
|
+
// No need to remap variableReplacements here - we use the new mechanism with that directly
|
|
129
141
|
case 'magicVars':
|
|
130
142
|
if (optionValue.user)
|
|
131
143
|
options.user = optionValue.user;
|
|
@@ -141,11 +153,11 @@ function translateOptions(input = {}, defaults = {}, hardRequire = {},
|
|
|
141
153
|
|
|
142
154
|
module.exports = {
|
|
143
155
|
to: {
|
|
144
|
-
cdl: options => translateOptions(options),
|
|
156
|
+
cdl: options => translateOptions(options, undefined, undefined, undefined, undefined, 'to.cdl'),
|
|
145
157
|
sql: (options) => {
|
|
146
158
|
const hardOptions = { src: 'sql' };
|
|
147
159
|
const defaultOptions = { sqlMapping: 'plain', sqlDialect: 'plain' };
|
|
148
|
-
const processed = translateOptions(options, defaultOptions, hardOptions, undefined, [ 'sql-dialect-and-naming' ]);
|
|
160
|
+
const processed = translateOptions(options, defaultOptions, hardOptions, undefined, [ 'sql-dialect-and-naming' ], 'to.sql');
|
|
149
161
|
|
|
150
162
|
const result = Object.assign({}, processed);
|
|
151
163
|
result.toSql = Object.assign({}, processed);
|
|
@@ -155,7 +167,7 @@ module.exports = {
|
|
|
155
167
|
hdi: (options) => {
|
|
156
168
|
const hardOptions = { src: 'hdi' };
|
|
157
169
|
const defaultOptions = { sqlMapping: 'plain', sqlDialect: 'hana' };
|
|
158
|
-
const processed = translateOptions(options, defaultOptions, hardOptions, { sqlDialect: generateStringValidator([ 'hana' ]) });
|
|
170
|
+
const processed = translateOptions(options, defaultOptions, hardOptions, { sqlDialect: generateStringValidator([ 'hana' ]) }, undefined, 'to.hdi');
|
|
159
171
|
|
|
160
172
|
const result = Object.assign({}, processed);
|
|
161
173
|
result.toSql = Object.assign({}, processed);
|
|
@@ -164,7 +176,7 @@ module.exports = {
|
|
|
164
176
|
},
|
|
165
177
|
hdbcds: (options) => {
|
|
166
178
|
const defaultOptions = { sqlMapping: 'plain', sqlDialect: 'hana' };
|
|
167
|
-
const processed = translateOptions(options, defaultOptions, {}, { sqlDialect: generateStringValidator([ 'hana' ]) });
|
|
179
|
+
const processed = translateOptions(options, defaultOptions, {}, { sqlDialect: generateStringValidator([ 'hana' ]) }, undefined, 'to.hdbcds');
|
|
168
180
|
|
|
169
181
|
const result = Object.assign({}, processed);
|
|
170
182
|
result.forHana = Object.assign({}, processed);
|
|
@@ -174,7 +186,7 @@ module.exports = {
|
|
|
174
186
|
edm: (options) => {
|
|
175
187
|
const hardOptions = { json: true, combined: true };
|
|
176
188
|
const defaultOptions = { odataVersion: 'v4', odataFormat: 'flat' };
|
|
177
|
-
const processed = translateOptions(options, defaultOptions, hardOptions, { odataVersion: generateStringValidator([ 'v4' ]) }, [ 'valid-structured' ]);
|
|
189
|
+
const processed = translateOptions(options, defaultOptions, hardOptions, { odataVersion: generateStringValidator([ 'v4' ]) }, [ 'valid-structured' ], 'to.edm');
|
|
178
190
|
|
|
179
191
|
const result = Object.assign({}, processed);
|
|
180
192
|
result.toOdata = Object.assign({}, processed);
|
|
@@ -186,7 +198,7 @@ module.exports = {
|
|
|
186
198
|
const defaultOptions = {
|
|
187
199
|
odataVersion: 'v4', odataFormat: 'flat',
|
|
188
200
|
};
|
|
189
|
-
const processed = translateOptions(options, defaultOptions, hardOptions, undefined, [ 'valid-structured' ]);
|
|
201
|
+
const processed = translateOptions(options, defaultOptions, hardOptions, undefined, [ 'valid-structured' ], 'to.edmx');
|
|
190
202
|
|
|
191
203
|
const result = Object.assign({}, processed);
|
|
192
204
|
result.toOdata = Object.assign({}, processed);
|
|
@@ -198,7 +210,7 @@ module.exports = {
|
|
|
198
210
|
|
|
199
211
|
odata: (options) => {
|
|
200
212
|
const defaultOptions = { odataVersion: 'v4', odataFormat: 'flat' };
|
|
201
|
-
const processed = translateOptions(options, defaultOptions, undefined, undefined, [ 'valid-structured' ]);
|
|
213
|
+
const processed = translateOptions(options, defaultOptions, undefined, undefined, [ 'valid-structured' ], 'for.odata');
|
|
202
214
|
|
|
203
215
|
const result = Object.assign({}, processed);
|
|
204
216
|
result.toOdata = Object.assign({}, processed);
|
|
@@ -208,7 +220,7 @@ module.exports = {
|
|
|
208
220
|
},
|
|
209
221
|
hana: (options) => {
|
|
210
222
|
const defaultOptions = { sqlMapping: 'plain', sqlDialect: 'hana' };
|
|
211
|
-
const processed = translateOptions(options, defaultOptions);
|
|
223
|
+
const processed = translateOptions(options, defaultOptions, undefined, undefined, undefined, 'for.hana');
|
|
212
224
|
|
|
213
225
|
const result = Object.assign({}, processed);
|
|
214
226
|
result.forHana = Object.assign({}, processed);
|