@sap/cds-compiler 3.0.0 → 3.1.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.
Files changed (79) hide show
  1. package/CHANGELOG.md +104 -9
  2. package/bin/.eslintrc.json +2 -1
  3. package/bin/cdsc.js +28 -16
  4. package/doc/API.md +11 -0
  5. package/doc/CHANGELOG_ARCHIVE.md +1 -1
  6. package/doc/CHANGELOG_BETA.md +24 -2
  7. package/doc/CHANGELOG_DEPRECATED.md +21 -1
  8. package/lib/api/main.js +92 -40
  9. package/lib/api/options.js +2 -3
  10. package/lib/base/keywords.js +64 -1
  11. package/lib/base/message-registry.js +33 -5
  12. package/lib/base/messages.js +54 -65
  13. package/lib/base/model.js +2 -0
  14. package/lib/base/optionProcessorHelper.js +53 -21
  15. package/lib/checks/actionsFunctions.js +8 -7
  16. package/lib/checks/selectItems.js +96 -14
  17. package/lib/checks/types.js +5 -8
  18. package/lib/checks/validator.js +1 -2
  19. package/lib/compiler/assert-consistency.js +65 -13
  20. package/lib/compiler/base.js +6 -4
  21. package/lib/compiler/builtins.js +93 -4
  22. package/lib/compiler/checks.js +1 -1
  23. package/lib/compiler/define.js +28 -23
  24. package/lib/compiler/extend.js +20 -11
  25. package/lib/compiler/finalize-parse-cdl.js +5 -9
  26. package/lib/compiler/index.js +2 -0
  27. package/lib/compiler/populate.js +37 -32
  28. package/lib/compiler/propagator.js +11 -6
  29. package/lib/compiler/resolve.js +15 -19
  30. package/lib/compiler/shared.js +54 -18
  31. package/lib/compiler/tweak-assocs.js +5 -11
  32. package/lib/compiler/utils.js +15 -6
  33. package/lib/edm/annotations/genericTranslation.js +12 -2
  34. package/lib/edm/annotations/preprocessAnnotations.js +18 -15
  35. package/lib/edm/csn2edm.js +18 -17
  36. package/lib/edm/edm.js +22 -13
  37. package/lib/edm/edmAnnoPreprocessor.js +349 -0
  38. package/lib/edm/edmInboundChecks.js +85 -0
  39. package/lib/edm/edmPreprocessor.js +336 -665
  40. package/lib/edm/edmUtils.js +86 -45
  41. package/lib/gen/Dictionary.json +29 -9
  42. package/lib/gen/language.checksum +1 -1
  43. package/lib/gen/language.interp +1 -2
  44. package/lib/gen/languageLexer.js +3 -0
  45. package/lib/gen/languageParser.js +4332 -4496
  46. package/lib/inspect/.eslintrc.json +4 -0
  47. package/lib/inspect/index.js +14 -0
  48. package/lib/inspect/inspectModelStatistics.js +81 -0
  49. package/lib/inspect/inspectPropagation.js +189 -0
  50. package/lib/inspect/inspectUtils.js +44 -0
  51. package/lib/json/from-csn.js +19 -20
  52. package/lib/json/to-csn.js +11 -8
  53. package/lib/language/genericAntlrParser.js +150 -92
  54. package/lib/language/language.g4 +47 -74
  55. package/lib/main.d.ts +1 -0
  56. package/lib/model/api.js +1 -1
  57. package/lib/model/csnRefs.js +56 -29
  58. package/lib/model/csnUtils.js +29 -14
  59. package/lib/model/revealInternalProperties.js +6 -4
  60. package/lib/modelCompare/compare.js +3 -0
  61. package/lib/optionProcessor.js +81 -38
  62. package/lib/render/toCdl.js +57 -32
  63. package/lib/render/toHdbcds.js +1 -1
  64. package/lib/render/toSql.js +31 -11
  65. package/lib/render/utils/common.js +3 -4
  66. package/lib/transform/db/associations.js +43 -35
  67. package/lib/transform/db/cdsPersistence.js +0 -1
  68. package/lib/transform/db/flattening.js +3 -4
  69. package/lib/transform/db/transformExists.js +7 -5
  70. package/lib/transform/draft/db.js +1 -1
  71. package/lib/transform/forHanaNew.js +11 -2
  72. package/lib/transform/forOdataNew.js +4 -4
  73. package/lib/transform/localized.js +15 -11
  74. package/lib/transform/odata/typesExposure.js +14 -5
  75. package/lib/utils/file.js +28 -18
  76. package/lib/utils/moduleResolve.js +0 -1
  77. package/package.json +3 -4
  78. package/share/messages/syntax-expected-integer.md +9 -8
  79. package/lib/checks/unknownMagic.js +0 -41
package/CHANGELOG.md CHANGED
@@ -7,27 +7,105 @@
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.1.2 - 2022-08-19
11
+
12
+ ### Fixed
13
+
14
+ - to.edm(x):
15
+ + `@Capabilities` 'pull up' for containment trees should not prefix the
16
+ dynamic annotation paths of the root container.
17
+ + Remove service namespace prefix of a parameter type for function/action annotation targets
18
+ in multi schema mode if the parameter type is defined in an alternative schema.
19
+
20
+ ## Version 3.1.0 - 2022-08-04
21
+
22
+ ### Added
23
+
24
+ - Extending an artifact with multiple includes in one extend statement is now possible:
25
+ `extend SomeEntity with FirstInclude, SecondInclude;`
26
+ - Aspects can now have actions and functions, similar to entities. Aspects can be extended by actions as well.
27
+ - `cdsc`:
28
+ - `toCsn` now supports `--with-locations` which adds a `$location` property to artifacts
29
+ - `toHana`/`toSql` now supports `--disable-hana-comments`, which disables rendering of doc-comments for HANA.
30
+ - to.hdi/sql/hdbcds: Support FK-access in `ORDER BY` and `GROUP BY`
31
+ - to.hdi.migration: Detect an implicit change from `not null` to `null` and render corresponding `ALTER`
32
+
33
+ ### Changed
34
+
35
+ - compiler: If an unknown file extension is used but the file starts with
36
+ an opening curly brace (`{`), it will be parsed as CSN.
37
+ - to.edm(x): In V4 containment mode, pull up `@Capabilities` annotations from the containees to the root container (set)
38
+ and translate them into corresponding `@Capabilities.NavigationRestrictions`. If a `NavigationRestriction` is already available
39
+ for that containment path, capabilities are merged into this path. Capability annotation value paths are prefixed with
40
+ the navigation restriction path.
41
+ The capability 'pull up' has an effect on entity annotations only. `@Capabilities` assignments on compositions are not pulled
42
+ up but rendered to the association type which is important to enable dynamic capabilities on 'to-many' relations and to avoid
43
+ ambiguities in entity set capabilities.
44
+ - Update OData vocabularies 'Analytics', 'Capabilities', 'Common', 'Core', 'DataIntegration', 'Graph', 'PersonalData', 'UI', 'Validation'.
45
+
46
+ ### Fixed
47
+
48
+ - Syntax of date/time literals are now checked against ISO 8601. If the format is invalid, a warning is emitted.
49
+ - The code completion directly after the `(` for functions with special syntax
50
+ now suggests all valid keywords, like for `extract` or `locate_regexpr`.
51
+ - compiler:
52
+ + `cast(elem as EnumType)` crashed the compiler.
53
+ + Annotations on sub-elements in query entities were lost during re-compilation.
54
+ + An association's cardinality was lost for associations published in projections.
55
+ + Annotations on indirect action parameters were lost in CSN flavor `gensrc`.
56
+ + If a file's content starts with `{` and if neither file extension is known nor
57
+ `fallbackParser` is set, assume the source is CSN.
58
+ - all backends: references in `order by` _expressions_ are correctly resolved.
59
+ - to.edm(x):
60
+ + Allow cross service references for unmanaged associations and improve warning message for muted associations.
61
+ + Nested `@UI.TextArrangement` has precedence over `@TextArrangement` shortcut annotation for `@Common.Text`.
62
+ - to.hdi.migration:
63
+ + Doc comments rendered the _full doc comment_ instead of only the first paragraph, as `to.hdi` does.
64
+ + Respect option `disableHanaComments` when rendering the `ALTER` statements
65
+ - to.hdi/sql/hdbcds:
66
+ + Check for invalid usages of `$self` and give helpful errors
67
+ + Correctly resolve association-steps in the from-clause in conjunction with `exists`
68
+
69
+ ## Version 3.0.2 - 2022-07-05
70
+
71
+ ### Fixed
72
+
73
+ - to.sql: For `sqlDialect` `plain`, `$now` is replaced by `CURRENT_TIMESTAMP` again.
74
+ - compiler:
75
+ + Don't crash if a USING filename is invalid on the operating system, e.g. if `\0` is used.
76
+ + Info messages for annotations on localized convenience views are only emitted for unknown ones.
77
+ + Improve error message for an `extend` statement which had added a new element
78
+ and tried to extend that element further. Similarly for a new action.
79
+ (If you consider this really of any use, use two `extend` statements.)
80
+ - for.odata: expand `@readonly`/`@insertonly` on aspects as for entities into `@Capabilities`.
81
+ - to.edm(x):
82
+ + Exclude managed association as primary key on value list annotation preprocessing.
83
+ + Don't render annotations for aspects defined in a service.
84
+
10
85
  ## Version 3.0.0 - 2022-06-23
11
86
 
12
87
  ### Added
13
88
 
14
89
  - Instead of requiring all files on startup, they are required on an as-needed basis to reduce startup times.
15
- - Allow `*` as argument in SQL functions `count`, `min`, `max`, `sum`, `avg`, `stddev`, `var`.
90
+ - CDL parser: support SQL functions `locate_regexpr`, `occurrences_regexpr`,
91
+ `replace_regexpr` and `substring_regexpr` with their special argument syntax.
92
+ - CDL parser: the names `trim` and `extract` are not reserved anymore.
16
93
 
17
94
  ### Changed
18
95
 
19
96
  - cds-compiler now requires Node 14.
20
97
  - `compile()` and its derivates now use `fs.realpath.native()` instead of `fs.realpath()`.
21
- - Multi-line doc comments without leading `*` were inconsistently trimmed.
98
+ - CDL parser:
99
+ + Multi-line doc comments without leading `*` were inconsistently trimmed.
100
+ + As before, a structure value for an annotation assignment in a CDL source is flattened,
101
+ i.e. `@Anno: { foo: 1, @bar: 2 }` becomes `@Anno.foo: 1 @Anno.@bar: 2`.
102
+ Now, the structure property name `$value` is basically ignored:
103
+ `@Anno: { $value: 1, @bar: 2 }` becomes `@Anno: 1 @Anno.@bar: 2`.
104
+ The advantage is that overwriting or appending the annotation value works as expected.
105
+ + Keywords `not null` is only valid after `many String enum {...}` and no longer after `String`.
22
106
  - `@cds.persistence.skip` and `@cds.persistence.exists` are both copied to generated child artifacts
23
107
  such as localized convenience views, texts entities and managed compositions.
24
- - As before, a structure value for an annotation assignment in a CDL source is flattened,
25
- i.e. `@Anno: { foo: 1, @bar: 2 }` becomes `@Anno.foo: 1 @Anno.@bar: 2`.
26
- Now, the structure property name `$value` is basically ignored:
27
- `@Anno: { $value: 1, @bar: 2 }` becomes `@Anno: 1 @Anno.@bar: 2`.
28
- The advantage is that overwriting or appending the annotation value works as expected.
29
108
  - Update OData vocabularies 'Common', 'UI'.
30
- - Keywords `not null` is only valid after `many String enum {...}` and no longer after `String`.
31
109
  - (Sub-)Elements of localized convenience views can now be annotated, e.g. `annotate localized.E:elem`.
32
110
  - `getArtifactCdsPersistenceName` now enforces the `csn` argument and can optionally have the `sqlDialect` passed in.
33
111
  - `getElementCdsPersistenceName` can optionally have the `sqlDialect` passed in.
@@ -36,9 +114,26 @@ The compiler behavior concerning `beta` features can change at any time without
36
114
 
37
115
  - All v2 deprecated flags.
38
116
  - Keyword `masked`.
39
- - `*` as generic argument to SQL functions/expressions.
117
+ - CDL parser: `*` is not parsed anymore as argument to all SQL functions;
118
+ it is now only allowed for `count`, `min`, `max`, `sum`, `avg`, `stddev`, `var`.
40
119
  - All non-SNAPI options.
41
120
 
121
+ ## Version 2.15.8 - 2022-08-02
122
+
123
+ ### Fixed
124
+
125
+ - to.edm(x): Nested `@UI.TextArrangement` has precedence over `@TextArrangement` shortcut annotation for `@Common.Text`.
126
+ - to.hdi.migration:
127
+ + Respect option `disableHanaComments` when rendering the `ALTER` statements
128
+ + Doc comments rendered the _full doc comment_ instead of only the first paragraph, as `to.hdi` does.
129
+ - compiler: An association's cardinality was lost for associations published in projections.
130
+
131
+ ## Version 2.15.6 - 2022-07-26
132
+
133
+ ### Fixed
134
+
135
+ - Annotations on sub-elements were lost during re-compilation.
136
+
42
137
  ## Version 2.15.4 - 2022-06-09
43
138
 
44
139
  ### Fixed
@@ -11,6 +11,7 @@
11
11
  "no-process-exit": "off",
12
12
  "camelcase": "off",
13
13
  "radix": "off",
14
- "no-shadow": "warn"
14
+ "no-shadow": "warn",
15
+ "global-require": "off"
15
16
  }
16
17
  }
package/bin/cdsc.js CHANGED
@@ -63,9 +63,6 @@ function remapCmdOptions(options, command) {
63
63
 
64
64
  for (const [ key, value ] of Object.entries(options[command])) {
65
65
  switch (key) {
66
- case 'names':
67
- options.sqlMapping = value;
68
- break;
69
66
  case 'user':
70
67
  if (!options.variableReplacements)
71
68
  options.variableReplacements = {};
@@ -73,12 +70,6 @@ function remapCmdOptions(options, command) {
73
70
  options.variableReplacements.$user = {};
74
71
  options.variableReplacements.$user.id = value;
75
72
  break;
76
- case 'dialect':
77
- options.sqlDialect = value;
78
- break;
79
- case 'version':
80
- options.odataVersion = value;
81
- break;
82
73
  case 'locale':
83
74
  if (!options.variableReplacements)
84
75
  options.variableReplacements = {};
@@ -89,9 +80,6 @@ function remapCmdOptions(options, command) {
89
80
  case 'serviceNames':
90
81
  options.serviceNames = value.split(',');
91
82
  break;
92
- case 'flavor':
93
- options.csnFlavor = value;
94
- break;
95
83
  default:
96
84
  options[key] = value;
97
85
  }
@@ -158,12 +146,17 @@ function cdsc_main() {
158
146
  if (cmdLine.options.rawOutput)
159
147
  cmdLine.options.attachValidNames = true;
160
148
 
161
- // Internally, parseCdl is an option so we map the command to it.
149
+ // Internally, parseCdl/parseOnly are options, so we map the command to it.
162
150
  if (cmdLine.command === 'parseCdl') {
163
151
  cmdLine.command = 'toCsn';
164
152
  cmdLine.options.parseCdl = true;
165
153
  cmdLine.args.files = [ cmdLine.args.file ];
166
154
  }
155
+ else if (cmdLine.command === 'parseOnly') {
156
+ cmdLine.command = 'toCsn';
157
+ cmdLine.options.parseOnly = true;
158
+ cmdLine.args.files = [ cmdLine.args.file ];
159
+ }
167
160
 
168
161
  if (cmdLine.options.directBackend)
169
162
  validateDirectBackendOption(cmdLine.command, cmdLine.options, cmdLine.args);
@@ -269,6 +262,7 @@ function executeCommandLine(command, options, args) {
269
262
  toRename,
270
263
  manageConstraints,
271
264
  toSql,
265
+ inspect,
272
266
  };
273
267
  const commandsWithoutCompilation = {
274
268
  explain,
@@ -432,6 +426,24 @@ function executeCommandLine(command, options, args) {
432
426
  console.log(explainMessage(args.messageId));
433
427
  }
434
428
 
429
+ function inspect(model) {
430
+ const inspectModel = require('../lib/inspect');
431
+
432
+ if (options.statistics) {
433
+ const result = inspectModel.inspectModelStatistics(model, options);
434
+ if (result)
435
+ console.log(result);
436
+ }
437
+
438
+ if (options.propagation) {
439
+ const result = inspectModel.inspectPropagation(model, options, options.propagation);
440
+ if (result)
441
+ console.log(result);
442
+ }
443
+
444
+ return model;
445
+ }
446
+
435
447
  // Display error messages in `err` resulting from a compilation. Also set
436
448
  // process.exitCode - process.exit() will force the process to exit as quickly
437
449
  // as possible = is problematic, since console.error() might be asynchronous
@@ -525,7 +537,7 @@ function executeCommandLine(command, options, args) {
525
537
  else if (options.internalMsg) {
526
538
  writeToFileOrDisplay(options.out, `${name}_raw.txt`, util.inspect(reveal(xsn).messages, { depth: null, maxArrayLength: null }), true);
527
539
  }
528
- else if (!options.lintMode) {
540
+ else if (!options.parseOnly) { // no output if parseOnly but not rawOutput
529
541
  const csn = compactModel(xsn, options);
530
542
  if (command === 'toCsn' && options.withLocalized)
531
543
  addLocalizationViews(csn, options);
@@ -545,7 +557,7 @@ function executeCommandLine(command, options, args) {
545
557
  if (options.internalMsg) {
546
558
  writeToFileOrDisplay(options.out, `${name}_raw.txt`, options.messages, true);
547
559
  }
548
- else if (!options.lintMode && !options.internalMsg) {
560
+ else if (!options.internalMsg) {
549
561
  if (command === 'toCsn' && options.withLocalized)
550
562
  addLocalizationViews(csn, options);
551
563
  writeToFileOrDisplay(options.out, `${name}.json`, csn, true);
@@ -558,7 +570,7 @@ function executeCommandLine(command, options, args) {
558
570
  // If displaying to stdout, prepend a headline containing 'filename', unless 'omitHeadline' is set.
559
571
  // For filenames, illegal characters (slash, backslash, colon) are replaced by '_'.
560
572
  function writeToFileOrDisplay(dir, fileName, content, omitHeadline = false) {
561
- if (options.lintMode && !options.rawOutput || options.internalMsg)
573
+ if (options.internalMsg)
562
574
  return;
563
575
  fileName = fileName.replace(/[:/\\]/g, '_');
564
576
 
package/doc/API.md ADDED
@@ -0,0 +1,11 @@
1
+ # CDS Compiler API Documentation
2
+
3
+ The API of `@sap/cds-compiler` is described in a TypeScript declaration file
4
+ [`main.d.ts`](../lib/main.d.ts).
5
+
6
+ Refer to that file for documentation on option names, API calls, and more.
7
+
8
+ You can use [TypeDoc] to render an HTML documentation from it.
9
+
10
+
11
+ [TypeDoc]: https://typedoc.org/
@@ -270,7 +270,7 @@ The compiler behaviour concerning `beta` features can change at any time without
270
270
  - to.sql/hdi/hdbcds:
271
271
  + Doc comments are translated into HANA comments (or into `@Comment` annotation for `to.hdbcds`).
272
272
  Such comments are possible on entities, views, elements of entities and `to.hdbcds` also supports comments on view columns.
273
- Generation can be disabled via option `disableHanaComments`. Entites/views (and their elements/columns)
273
+ Generation can be disabled via option `disableHanaComments`. Entities/views (and their elements/columns)
274
274
  annotated with `@cds.persistence.journal` for `to.hdi`/`to.sql` will not have comments rendered.
275
275
  + Generation of temporal `WHERE` clause can be suppressed by annotating the `validFrom`/`validTo` elements of the projection with `false` or `null`.
276
276
  - to.sql/hdi/hdbcds/edm(x)/for.odata: Structure/managed association comparisons (tuple comparisons) are now
@@ -8,7 +8,29 @@ 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 3.0.0 - 2022-XX-YY
11
+ ## Version 3.1.0 - 2022-08-04
12
+
13
+ ### Added `optionalActionFunctionParameters`
14
+
15
+ - to.edm(x): Annotate optional function/action parameters with `@Core.OptionalParameter` for OData V4.
16
+ An action/function parameter is optional if
17
+ 1) it is already annotated with `@Core.OptionalParameter` regardless of its definition.
18
+ 2) it has a default value (including null), regardless of it's nullability
19
+ 3) it has NO default value but is nullable (the implicit default value is null)
20
+
21
+ If a mandatory parameter (not null and no default value) appears after an optional
22
+ parameter, a warning is raised, Core.OptionalParameter requires that all optional
23
+ parameters appear rightmost.
24
+
25
+ ### Added `odataOpenType`
26
+
27
+ - to.edm(x): Support annotation `@open` on entity and structured type level to declare the corresponding entity/complex type to
28
+ be `OpenType=true`. If an open structured type is declared closed (with a falsy annotation value), the corresponding EDM type
29
+ is closed as well and suffixed with `_closed` (or `_open` vice versa).
30
+ No further checks are performed on possibly open foreign or primary key types nor on eventually bucket elements to store the
31
+ additional data.
32
+
33
+ ## Version 3.0.0 - 2022-06-23
12
34
 
13
35
  ### Removed `addTextsLanguageAssoc`
14
36
 
@@ -134,7 +156,7 @@ When the beta option `subElemRedirections` is set to true,
134
156
  _all_ array (new!) and structure types are expanded when referenced:
135
157
  managed associations (and compositions to entities) in that array are
136
158
  implicitly redirected when necessary.
137
- See [below for details](#version-1300---20200612).
159
+ See [below for details](#version-1300---2020-06-12).
138
160
 
139
161
  Nested array types (without intermediate structure types) are not supported.
140
162
 
@@ -11,10 +11,28 @@ Note: `deprecated` features are listed in this ChangeLog just for information.
11
11
  **When the `deprecated` option is set, the `beta` option is ignored,
12
12
  and several new features are not available.**
13
13
 
14
- ## Version 3.0.0 - 2022-XX-YY
14
+ ## Version 3.1.0 - 2022-08-04
15
+
16
+ ### Added `autoCorrectOrderBySourceRefs`
17
+
18
+ When this option is set, calling `compile` auto-corrects direct `order by`
19
+ source element references without table alias for SELECT queries by adding the
20
+ table alias to the `ref`.
21
+
22
+ Using this option might lead to surprising results when elements are added to
23
+ existing models: `order by` specifications might change their semantics without
24
+ any extra messages.
25
+
26
+ ## Version 3.0.0 - 2022-06-23
15
27
 
16
28
  Version 3 of the cds-compiler removes all v2 deprecated flags.
17
29
 
30
+ ### Add `eagerPersistenceForGeneratedEntities`
31
+
32
+ If enabled, the old behavior regarding `@cds.persistence.skip` and `@cds.persistence.exists`
33
+ is restored, i.e. these annotations are not copied from parent to generated child entities, nor
34
+ is `@cds.persistence.exists` copied to localized convenience views.
35
+
18
36
  ### Removed `createLocalizedViews`
19
37
 
20
38
  ### Removed `downgradableErrors`
@@ -25,6 +43,8 @@ Version 3 of the cds-compiler removes all v2 deprecated flags.
25
43
 
26
44
  ### Removed `noElementsExpansion`
27
45
 
46
+ <!-- fully removed with 3.1.0 -->
47
+
28
48
  ### Removed `noInheritedAutoexposeViaComposition`
29
49
 
30
50
  ### Removed `noScopedRedirections`
package/lib/api/main.js CHANGED
@@ -226,6 +226,50 @@ function sql(csn, options = {}) {
226
226
  return result.map(obj => obj.sql).filter(create => create);
227
227
  }
228
228
 
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
+
229
273
  /**
230
274
  * Process the given CSN into HDI artifacts.
231
275
  *
@@ -357,49 +401,55 @@ function hdiMigration(csn, options, beforeImage) {
357
401
 
358
402
  return {
359
403
  afterImage,
360
- definitions: createDefinitions(),
361
- deletions: createDeletions(),
362
- migrations: createMigrations(),
404
+ definitions: createSqlDefinitions(hdbkinds, afterImage),
405
+ deletions: createSqlDeletions(deletions, beforeImage),
406
+ migrations: createSqlMigrations(migrations, afterImage),
363
407
  };
408
+ }
364
409
 
365
- /**
366
- * From the given HDI artifacts, create the the correct result structure.
367
- *
368
- * @returns {object[]} Array of objects, each having: name, suffix and sql
369
- */
370
- function createDefinitions() {
371
- const result = [];
372
- forEach(hdbkinds, (kind, artifacts) => {
373
- const suffix = `.${ kind }`;
374
- forEach(artifacts, (name, sqlStatement) => {
375
- if ( kind !== 'hdbindex' )
376
- result.push({ name: getFileName(name, afterImage), suffix, sql: sqlStatement });
377
- else
378
- result.push({ name, suffix, sql: sqlStatement });
379
- });
410
+ /**
411
+ * From the given SQLs, create the correct result structure.
412
+ *
413
+ * @param {object} hdbkinds Object of hdbkinds (such as `hdbindex`) mapped to dictionary of artifacts.
414
+ * @param {CSN.Model} afterImage CSN, used to create correct file names in result structure.
415
+ * @returns {object[]} Array of objects, each having: name, suffix and sql
416
+ */
417
+ function createSqlDefinitions(hdbkinds, afterImage) {
418
+ const result = [];
419
+ forEach(hdbkinds, (kind, artifacts) => {
420
+ const suffix = `.${ kind }`;
421
+ forEach(artifacts, (name, sqlStatement) => {
422
+ if ( kind !== 'hdbindex' )
423
+ result.push({ name: getFileName(name, afterImage), suffix, sql: sqlStatement });
424
+ else
425
+ result.push({ name, suffix, sql: sqlStatement });
380
426
  });
381
- return result;
382
- }
383
- /**
384
- * From the given deletions, create the correct result structure.
385
- *
386
- * @returns {object[]} Array of objects, each having: name and suffix - only .hdbtable as suffix for now
387
- */
388
- function createDeletions() {
389
- const result = [];
390
- forEach(deletions, name => result.push({ name: getFileName(name, beforeImage), suffix: '.hdbtable' }));
391
- return result;
392
- }
393
- /**
394
- * From the given migrations, create the correct result structure.
395
- *
396
- * @returns {object[]} Array of objects, each having: name, suffix and changeset.
397
- */
398
- function createMigrations() {
399
- const result = [];
400
- forEach(migrations, (name, changeset) => result.push({ name: getFileName(name, afterImage), suffix: '.hdbmigrationtable', changeset }));
401
- return result;
402
- }
427
+ });
428
+ return result;
429
+ }
430
+ /**
431
+ * From the given deletions, create the correct result structure.
432
+ *
433
+ * @param {object} deletions Dictionary of deletions, only keys are used.
434
+ * @param {CSN.Model} beforeImage CSN used to create correct file names in result structure.
435
+ * @returns {object[]} Array of objects, each having: name and suffix - only .hdbtable as suffix for now
436
+ */
437
+ function createSqlDeletions(deletions, beforeImage) {
438
+ const result = [];
439
+ forEach(deletions, name => result.push({ name: getFileName(name, beforeImage), suffix: '.hdbtable' }));
440
+ return result;
441
+ }
442
+ /**
443
+ * From the given migrations, create the correct result structure.
444
+ *
445
+ * @param {object} migrations Dictionary of changesets (migrations).
446
+ * @param {CSN.Model} afterImage CSN used to create correct file names in result structure.
447
+ * @returns {object[]} Array of objects, each having: name, suffix and changeset.
448
+ */
449
+ function createSqlMigrations(migrations, afterImage) {
450
+ const result = [];
451
+ forEach(migrations, (name, changeset) => result.push({ name: getFileName(name, afterImage), suffix: '.hdbmigrationtable', changeset }));
452
+ return result;
403
453
  }
404
454
 
405
455
  hdi.migration = hdiMigration;
@@ -649,6 +699,8 @@ module.exports = {
649
699
  for_sql: publishCsnProcessor(forSql, 'for.sql'),
650
700
  for_hdi: publishCsnProcessor(forHdi, 'for.hdi'),
651
701
  for_hdbcds: publishCsnProcessor(forHdbcds, 'for.hdbcds'),
702
+ /** beta - WIP */
703
+ mtx: publishCsnProcessor(mtx, 'to.mtx'),
652
704
  /** Deprecated, will be removed in cds-compiler@v4 */
653
705
  preparedCsnToEdmx,
654
706
  preparedCsnToEdm,
@@ -57,9 +57,7 @@ const privateOptions = [
57
57
  'noRecompile',
58
58
  'internalMsg',
59
59
  'disableHanaComments', // in case of issues with hana comment rendering
60
- 'dependentAutoexposed', // deprecated, no effect - TODO: safe to remove?
61
- 'longAutoexposed', // deprecated, no effect - TODO: safe to remove?
62
- 'localizedWithoutCoalesce', // deprecated version of 'localizedLanguageFallback',
60
+ 'localizedWithoutCoalesce', // deprecated version of 'localizedLanguageFallback', TODO(v4): Remove option
63
61
  ];
64
62
 
65
63
  const overallOptions = publicOptionsNewAPI.concat(privateOptions);
@@ -159,6 +157,7 @@ module.exports = {
159
157
  return translateOptions(options, defaultOptions, hardOptions, undefined, undefined, 'for.hana');
160
158
  },
161
159
  },
160
+ overallOptions, // exported for testing
162
161
  };
163
162
 
164
163