@sap/cds-compiler 2.15.2 → 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +66 -1590
- package/bin/cdsc.js +42 -46
- package/doc/CHANGELOG_ARCHIVE.md +1592 -0
- package/doc/CHANGELOG_BETA.md +3 -4
- package/doc/CHANGELOG_DEPRECATED.md +35 -1
- package/doc/{DeprecatedOptions.md → DeprecatedOptions_v2.md} +3 -1
- package/doc/Versioning.md +20 -1
- package/lib/api/.eslintrc.json +2 -2
- package/lib/api/main.js +312 -143
- package/lib/api/options.js +15 -85
- package/lib/api/validate.js +6 -10
- package/lib/base/keywords.js +280 -110
- package/lib/base/message-registry.js +80 -24
- package/lib/base/messages.js +103 -52
- package/lib/base/model.js +44 -2
- package/lib/base/optionProcessorHelper.js +53 -21
- package/lib/checks/actionsFunctions.js +7 -5
- package/lib/checks/annotationsOData.js +1 -1
- package/lib/checks/cdsPersistence.js +1 -0
- package/lib/checks/elements.js +6 -6
- package/lib/checks/invalidTarget.js +1 -1
- package/lib/checks/nonexpandableStructured.js +1 -1
- package/lib/checks/queryNoDbArtifacts.js +2 -1
- package/lib/checks/selectItems.js +5 -1
- package/lib/checks/types.js +4 -2
- package/lib/checks/utils.js +2 -2
- package/lib/checks/validator.js +2 -1
- package/lib/compiler/assert-consistency.js +15 -10
- package/lib/compiler/builtins.js +127 -10
- package/lib/compiler/define.js +6 -4
- package/lib/compiler/extend.js +63 -12
- package/lib/compiler/finalize-parse-cdl.js +20 -9
- package/lib/compiler/index.js +25 -11
- package/lib/compiler/moduleLayers.js +7 -0
- package/lib/compiler/populate.js +16 -14
- package/lib/compiler/propagator.js +3 -3
- package/lib/compiler/resolve.js +194 -222
- package/lib/compiler/shared.js +56 -76
- package/lib/compiler/tweak-assocs.js +9 -10
- package/lib/compiler/utils.js +7 -2
- package/lib/edm/annotations/genericTranslation.js +60 -6
- package/lib/edm/annotations/preprocessAnnotations.js +10 -11
- package/lib/edm/csn2edm.js +39 -41
- package/lib/edm/edm.js +22 -15
- package/lib/edm/edmPreprocessor.js +66 -69
- package/lib/edm/edmUtils.js +12 -62
- package/lib/gen/Dictionary.json +8 -6
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +8 -30
- package/lib/gen/language.tokens +105 -114
- package/lib/gen/languageLexer.interp +1 -34
- package/lib/gen/languageLexer.js +889 -1007
- package/lib/gen/languageLexer.tokens +95 -106
- package/lib/gen/languageParser.js +20717 -22376
- package/lib/json/from-csn.js +73 -68
- package/lib/json/to-csn.js +13 -10
- package/lib/language/antlrParser.js +2 -2
- package/lib/language/docCommentParser.js +61 -38
- package/lib/language/errorStrategy.js +52 -40
- package/lib/language/genericAntlrParser.js +333 -259
- package/lib/language/language.g4 +600 -645
- package/lib/language/multiLineStringParser.js +14 -42
- package/lib/language/textUtils.js +44 -0
- package/lib/main.d.ts +27 -42
- package/lib/main.js +104 -81
- package/lib/model/csnRefs.js +2 -1
- package/lib/model/csnUtils.js +183 -285
- package/lib/model/revealInternalProperties.js +32 -9
- package/lib/model/sortViews.js +32 -31
- package/lib/optionProcessor.js +64 -57
- package/lib/render/.eslintrc.json +1 -1
- package/lib/render/DuplicateChecker.js +4 -7
- package/lib/render/manageConstraints.js +70 -2
- package/lib/render/toCdl.js +334 -339
- package/lib/render/toHdbcds.js +20 -16
- package/lib/render/toRename.js +44 -22
- package/lib/render/toSql.js +60 -54
- package/lib/render/utils/common.js +15 -1
- package/lib/render/utils/sql.js +20 -19
- package/lib/sql-identifier.js +6 -0
- package/lib/transform/db/.eslintrc.json +3 -2
- package/lib/transform/db/cdsPersistence.js +5 -15
- package/lib/transform/db/constraints.js +1 -1
- package/lib/transform/db/expansion.js +7 -6
- package/lib/transform/db/flattening.js +18 -19
- package/lib/transform/db/views.js +3 -3
- package/lib/transform/draft/.eslintrc.json +2 -2
- package/lib/transform/draft/db.js +6 -6
- package/lib/transform/draft/odata.js +6 -7
- package/lib/transform/forHanaNew.js +19 -22
- package/lib/transform/forOdataNew.js +13 -15
- package/lib/transform/localized.js +35 -25
- package/lib/transform/odata/toFinalBaseType.js +11 -9
- package/lib/transform/odata/typesExposure.js +3 -3
- package/lib/transform/odata/utils.js +1 -38
- package/lib/transform/transformUtilsNew.js +63 -77
- package/lib/transform/translateAssocsToJoins.js +6 -2
- package/lib/transform/universalCsn/.eslintrc.json +2 -2
- package/lib/transform/universalCsn/coreComputed.js +11 -6
- package/lib/transform/universalCsn/universalCsnEnricher.js +33 -5
- package/lib/utils/file.js +31 -21
- package/lib/utils/timetrace.js +20 -21
- package/package.json +34 -4
- package/share/messages/syntax-expected-integer.md +9 -8
- package/doc/ApiMigration.md +0 -237
- package/doc/CommandLineMigration.md +0 -58
- package/doc/ErrorMessages.md +0 -175
- package/doc/FioriAnnotations.md +0 -94
- package/doc/ODataTransformation.md +0 -273
- package/lib/backends.js +0 -529
- package/lib/fix_antlr4-8_warning.js +0 -56
|
@@ -29,10 +29,7 @@ module.exports = (csn, options) => {
|
|
|
29
29
|
const definitionPropagationRules = {
|
|
30
30
|
'@cds.autoexpose': onlyViaArtifact,
|
|
31
31
|
'@fiori.draft.enabled': onlyViaArtifact,
|
|
32
|
-
'@':
|
|
33
|
-
if (source[prop] !== null)
|
|
34
|
-
target[prop] = source[prop];
|
|
35
|
-
},
|
|
32
|
+
'@': nullStopsPropagation,
|
|
36
33
|
// Example: `type E : F;` does not have `elements`, but they are required for e.g. OData.
|
|
37
34
|
elements: onlyTypeDef,
|
|
38
35
|
'@cds.persistence.exists': skip,
|
|
@@ -48,7 +45,7 @@ module.exports = (csn, options) => {
|
|
|
48
45
|
'@cds.autoexposed': skip,
|
|
49
46
|
'@cds.redirection.target': skip,
|
|
50
47
|
type: always,
|
|
51
|
-
doc:
|
|
48
|
+
doc: nullStopsPropagation,
|
|
52
49
|
length: always,
|
|
53
50
|
precision: always,
|
|
54
51
|
scale: always,
|
|
@@ -94,6 +91,10 @@ module.exports = (csn, options) => {
|
|
|
94
91
|
}, // overwrite from defProps
|
|
95
92
|
kind: skip,
|
|
96
93
|
val: always,
|
|
94
|
+
type: notWithItemsOrElements,
|
|
95
|
+
target: notWithItemsOrElements,
|
|
96
|
+
keys: notWithItemsOrElements,
|
|
97
|
+
cardinality: notWithItemsOrElements,
|
|
97
98
|
};
|
|
98
99
|
|
|
99
100
|
generate();
|
|
@@ -702,6 +703,19 @@ function notWithTypeOrigin(prop, target, source) {
|
|
|
702
703
|
target[prop] = source[prop];
|
|
703
704
|
}
|
|
704
705
|
|
|
706
|
+
/**
|
|
707
|
+
* The value `null` tells us to skip the propagation of the property.
|
|
708
|
+
* This is the case e.g. for `doc` or for annotations.
|
|
709
|
+
*
|
|
710
|
+
* @param {string} prop
|
|
711
|
+
* @param {CSN.Element} target
|
|
712
|
+
* @param {CSN.Element} source
|
|
713
|
+
*/
|
|
714
|
+
function nullStopsPropagation(prop, target, source) {
|
|
715
|
+
if (source[prop] !== null)
|
|
716
|
+
target[prop] = source[prop];
|
|
717
|
+
}
|
|
718
|
+
|
|
705
719
|
/**
|
|
706
720
|
* Special propagation rules for .items - depending on the exact type of .items and the
|
|
707
721
|
* way it was referenced (type of, direct type, direct many), we need to propagate (or not).
|
|
@@ -722,6 +736,20 @@ function specialItemsRules(prop, target, source) {
|
|
|
722
736
|
target[prop] = source[prop];
|
|
723
737
|
}
|
|
724
738
|
|
|
739
|
+
/**
|
|
740
|
+
* Don't propagate certain properties if the target already has a .items or .elements
|
|
741
|
+
*
|
|
742
|
+
* This happens with .expand/.inline
|
|
743
|
+
*
|
|
744
|
+
* @param {string} prop
|
|
745
|
+
* @param {CSN.Element} target
|
|
746
|
+
* @param {CSN.Element} source
|
|
747
|
+
*/
|
|
748
|
+
function notWithItemsOrElements(prop, target, source) {
|
|
749
|
+
if (!target.items && !target.elements || !source.target)
|
|
750
|
+
target[prop] = source[prop];
|
|
751
|
+
}
|
|
752
|
+
|
|
725
753
|
/**
|
|
726
754
|
* Some properties must not be copied over if the type of this member
|
|
727
755
|
* is a reference to another element.
|
package/lib/utils/file.js
CHANGED
|
@@ -61,12 +61,12 @@ function cdsFs(fileCache, enableTrace) {
|
|
|
61
61
|
};
|
|
62
62
|
|
|
63
63
|
function realpath(path, cb) {
|
|
64
|
-
return fs.realpath(path, cb);
|
|
64
|
+
return fs.realpath.native(path, cb);
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
function realpathSync(path, cb) {
|
|
68
68
|
try {
|
|
69
|
-
cb(null, fs.realpathSync(path));
|
|
69
|
+
cb(null, fs.realpathSync.native(path));
|
|
70
70
|
}
|
|
71
71
|
catch (err) {
|
|
72
72
|
cb(err, null);
|
|
@@ -87,7 +87,7 @@ function cdsFs(fileCache, enableTrace) {
|
|
|
87
87
|
}
|
|
88
88
|
let body = fileCache[filename];
|
|
89
89
|
if (body && typeof body === 'object' && body.realname) {
|
|
90
|
-
filename = body.realname; // use fs.realpath name
|
|
90
|
+
filename = body.realname; // use fs.realpath.native name
|
|
91
91
|
body = fileCache[filename];
|
|
92
92
|
}
|
|
93
93
|
if (body !== undefined && body !== true) { // true: we just know it is there
|
|
@@ -113,11 +113,16 @@ function cdsFs(fileCache, enableTrace) {
|
|
|
113
113
|
traceFS( 'READFILE:start:', filename );
|
|
114
114
|
// TODO: set cache directly to some "delay" - store error differently?
|
|
115
115
|
// e.g. an error of callback functions!
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
116
|
+
try {
|
|
117
|
+
reader(filename, enc, (err, data) => {
|
|
118
|
+
fileCache[filename] = err || data;
|
|
119
|
+
traceFS('READFILE:data:', filename, err || data);
|
|
120
|
+
cb(err, data);
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
cb(err); // if filename is not a valid (e.g. contains NUL byte), readFile() may throw
|
|
125
|
+
}
|
|
121
126
|
}
|
|
122
127
|
};
|
|
123
128
|
}
|
|
@@ -143,19 +148,24 @@ function cdsFs(fileCache, enableTrace) {
|
|
|
143
148
|
// in the future (if we do module resolve ourself with just readFile),
|
|
144
149
|
// we avoid parallel readFile by storing having an array of `cb`s in
|
|
145
150
|
// fileCache[ filename ] before starting fs.readFile().
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
fileCache[filename]
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
151
|
+
try {
|
|
152
|
+
fsStat(filename, (err, stat) => {
|
|
153
|
+
if (err)
|
|
154
|
+
body = (err.code === 'ENOENT' || err.code === 'ENOTDIR') ? false : err;
|
|
155
|
+
else
|
|
156
|
+
body = !!(stat.isFile() || stat.isFIFO());
|
|
157
|
+
if (fileCache[filename] === undefined) // parallel readFile() has been processed
|
|
158
|
+
fileCache[filename] = body;
|
|
159
|
+
traceFS('ISFILE:data:', filename, body);
|
|
160
|
+
if (body instanceof Error)
|
|
161
|
+
cb(err);
|
|
162
|
+
else
|
|
163
|
+
cb(null, body);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
catch (err) {
|
|
167
|
+
cb(err); // if filename is not a valid (e.g. contains NUL byte), fsStat() may throw
|
|
168
|
+
}
|
|
159
169
|
}
|
|
160
170
|
};
|
|
161
171
|
}
|
package/lib/utils/timetrace.js
CHANGED
|
@@ -14,47 +14,43 @@ class StopWatch {
|
|
|
14
14
|
*/
|
|
15
15
|
constructor(id) {
|
|
16
16
|
this.id = id;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
// eslint-disable-next-line no-multi-assign
|
|
20
|
-
this.startTime = this.lapTime = process.hrtime();
|
|
17
|
+
this.startTime = process.hrtime.bigint();
|
|
18
|
+
this.lapTime = this.startTime;
|
|
21
19
|
}
|
|
22
20
|
|
|
23
21
|
/**
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
* Start watch.
|
|
23
|
+
*/
|
|
26
24
|
start() {
|
|
27
|
-
|
|
28
|
-
this.
|
|
25
|
+
this.startTime = process.hrtime.bigint();
|
|
26
|
+
this.lapTime = this.startTime;
|
|
29
27
|
}
|
|
30
28
|
|
|
31
29
|
/**
|
|
32
|
-
* Stop and return delta T
|
|
30
|
+
* Stop and return delta T in nanoseconds,
|
|
33
31
|
* but do not set start time
|
|
34
32
|
*/
|
|
35
33
|
stop() {
|
|
36
|
-
|
|
34
|
+
const endTime = process.hrtime.bigint();
|
|
35
|
+
return endTime - this.startTime;
|
|
37
36
|
}
|
|
38
37
|
|
|
39
|
-
/**
|
|
40
|
-
* return lap time
|
|
41
|
-
*/
|
|
42
38
|
lap() {
|
|
43
|
-
const
|
|
44
|
-
|
|
39
|
+
const endTime = process.hrtime.bigint();
|
|
40
|
+
const dt = endTime - this.startTime;
|
|
41
|
+
this.lapTime = process.hrtime.bigint();
|
|
45
42
|
return dt;
|
|
46
43
|
}
|
|
47
44
|
|
|
48
|
-
// stop as sec.ns float
|
|
49
45
|
stopInFloatSecs() {
|
|
50
46
|
const dt = this.stop();
|
|
51
|
-
return dt
|
|
47
|
+
return dt / BigInt(1000000000);
|
|
52
48
|
}
|
|
53
49
|
|
|
54
50
|
// lap as sec.ns float
|
|
55
51
|
lapInFloatSecs() {
|
|
56
52
|
const dt = this.lap();
|
|
57
|
-
return dt
|
|
53
|
+
return dt / BigInt(1000000000);
|
|
58
54
|
}
|
|
59
55
|
}
|
|
60
56
|
|
|
@@ -63,7 +59,7 @@ class StopWatch {
|
|
|
63
59
|
*
|
|
64
60
|
* Results are logged to stderr
|
|
65
61
|
*
|
|
66
|
-
* To enable time tracing, set
|
|
62
|
+
* To enable time tracing, set CDSC_TIMETRACING to true in the environment
|
|
67
63
|
*
|
|
68
64
|
* @class TimeTracer
|
|
69
65
|
*/
|
|
@@ -107,10 +103,13 @@ class TimeTracer {
|
|
|
107
103
|
stop() {
|
|
108
104
|
try {
|
|
109
105
|
const current = this.traceStack.pop();
|
|
110
|
-
const
|
|
106
|
+
const dt = current.stop();
|
|
111
107
|
const base = `${ ' '.repeat(this.traceStack.length * 2) }${ current.id } took:`;
|
|
108
|
+
const sec = (dt / BigInt(1000000000)).toString();
|
|
109
|
+
// first, get remaining ns, then convert to ms.
|
|
110
|
+
const msec = ((dt % BigInt(1000000000)) / BigInt(1000000)).toString();
|
|
112
111
|
// eslint-disable-next-line no-console
|
|
113
|
-
console.error( `${ base }${ ' '.repeat(60 - base.length) } %ds %dms`,
|
|
112
|
+
console.error( `${ base }${ ' '.repeat(60 - base.length) } %ds %dms`, sec, msec );
|
|
114
113
|
}
|
|
115
114
|
catch (e) {
|
|
116
115
|
// eslint-disable-next-line no-console
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sap/cds-compiler",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.2",
|
|
4
4
|
"description": "CDS (Core Data Services) compiler and backends",
|
|
5
5
|
"homepage": "https://cap.cloud.sap/",
|
|
6
6
|
"author": "SAP SE (https://www.sap.com)",
|
|
7
7
|
"license": "SEE LICENSE IN LICENSE",
|
|
8
|
+
"type": "commonjs",
|
|
8
9
|
"bin": {
|
|
9
10
|
"cdsc": "bin/cdsc.js",
|
|
10
11
|
"cdshi": "bin/cdshi.js",
|
|
@@ -13,13 +14,42 @@
|
|
|
13
14
|
"main": "lib/main.js",
|
|
14
15
|
"types": "lib/main.d.ts",
|
|
15
16
|
"scripts": {
|
|
16
|
-
"
|
|
17
|
+
"download": "node scripts/downloadANTLR.js",
|
|
18
|
+
"gen": "node ./scripts/build.js && node scripts/genGrammarChecksum.js",
|
|
19
|
+
"xmakeBeforeInstall": "echo \"Due to binary mirror, use sqlite 5.0.8 explicitly\" && npm install --save --save-exact --no-package-lock sqlite3@5.0.8",
|
|
20
|
+
"xmakeAfterInstall": "npm run gen",
|
|
21
|
+
"xmakePrepareRelease": "echo \"$(node scripts/stripReadme.js README.md)\" > README.md && node scripts/assertSnapshotVersioning.js && node scripts/assertChangelog.js && node scripts/cleanup.js --remove-dev",
|
|
22
|
+
"test": "node scripts/verifyGrammarChecksum.js && mocha --reporter min --reporter-option maxDiffSize=0 scripts/testLazyLoading.js && mocha --parallel --reporter min --reporter-option maxDiffSize=0 test/ test3/",
|
|
23
|
+
"testverbose": "node scripts/verifyGrammarChecksum.js && mocha --parallel test/ test3/",
|
|
24
|
+
"test3": "node scripts/verifyGrammarChecksum.js && node scripts/linter/lintTests.js test3/ && mocha --reporter-option maxDiffSize=0 scripts/linter/lintMessages.js test3/",
|
|
25
|
+
"deployTest3SQL": "deployRefs=true mocha --reporter-option maxDiffSize=0 test3/testHANASQLDeployment.js",
|
|
26
|
+
"deployTest3": "deployRefs=true mocha --reporter-option maxDiffSize=0 test3/testDeployment.js",
|
|
27
|
+
"deployDiffs": "deployRefs=true mocha --reporter-option maxDiffSize=0 test3/deployDiffs.js",
|
|
28
|
+
"gentest3": "cross-env MAKEREFS=${MAKEREFS:-'true'} mocha --reporter-option maxDiffSize=0 test3/testRefFiles.js",
|
|
29
|
+
"testdb": "node scripts/verifyGrammarChecksum.js && cross-env TESTDB='TRUE' mocha",
|
|
30
|
+
"testmigration": "npm install --no-save @sap/hana-client@2.3.123 @sap/hdi-deploy@3.10.0 && node scripts/verifyGrammarChecksum.js && cross-env TESTMIGRATION='TRUE' mocha",
|
|
31
|
+
"testall": "npm install --no-save @sap/hana-client@2.3.123 @sap/hdi-deploy@3.10.0 && node scripts/verifyGrammarChecksum.js && cross-env TESTDB='TRUE' TESTMIGRATION='TRUE' mocha",
|
|
32
|
+
"coverage": "cross-env nyc mocha --reporter-option maxDiffSize=0 test/ test3/ && nyc report --reporter=lcov",
|
|
33
|
+
"lint": "eslint bin/ benchmark/ lib/ test/ test3/ scripts/ types/ && node scripts/linter/lintGrammar.js && node scripts/linter/lintTests.js test3/ && markdownlint README.md CHANGELOG.md doc/ internalDoc/ && cd share/messages && markdownlint .",
|
|
34
|
+
"tslint": "tsc --pretty -p .",
|
|
35
|
+
"updateVocs": "node scripts/odataAnnotations/generateDictMain.js && npm run generateAllRefs",
|
|
36
|
+
"generateCompilerRefs": "cross-env MAKEREFS='true' mocha test/testCompiler.js",
|
|
37
|
+
"generateEdmRefs": "cross-env MAKEREFS='true' mocha test/testEdmPositive.js",
|
|
38
|
+
"generateForHanaRefs": "cross-env MAKEREFS='true' mocha test/testHanaTransformation.js",
|
|
39
|
+
"generateOdataRefs": "cross-env MAKEREFS='true' mocha test/testODataTransformation.js",
|
|
40
|
+
"generateOdataAnnoRefs": "cross-env MAKEREFS='true' mocha test/testODataAnnotations.js",
|
|
41
|
+
"generateToSqlRefs": "cross-env MAKEREFS='true' mocha test/testToSql.js",
|
|
42
|
+
"generateToRenameRefs": "cross-env MAKEREFS='true' mocha test/testToRename.js",
|
|
43
|
+
"generateChecksRefs": "cross-env MAKEREFS='true' mocha test/testChecks.js",
|
|
44
|
+
"generateScenarioRefs": "cross-env MAKEREFS='true' mocha test/testScenarios.js",
|
|
45
|
+
"generateDraftRefs": "cross-env MAKEREFS='true' mocha test/testDraft.js",
|
|
46
|
+
"generateAllRefs": "node scripts/verifyGrammarChecksum.js && cross-env MAKEREFS='true' mocha --reporter-option maxDiffSize=0 test/ test3/"
|
|
17
47
|
},
|
|
18
48
|
"keywords": [
|
|
19
49
|
"CDS"
|
|
20
50
|
],
|
|
21
51
|
"dependencies": {
|
|
22
|
-
"antlr4": "4.
|
|
52
|
+
"antlr4": "4.9.3"
|
|
23
53
|
},
|
|
24
54
|
"files": [
|
|
25
55
|
"bin",
|
|
@@ -32,6 +62,6 @@
|
|
|
32
62
|
"LICENSE"
|
|
33
63
|
],
|
|
34
64
|
"engines": {
|
|
35
|
-
"node": ">=
|
|
65
|
+
"node": ">=14"
|
|
36
66
|
}
|
|
37
67
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# syntax-expected-integer
|
|
2
2
|
|
|
3
3
|
The compiler expects a safe integer here.
|
|
4
|
-
The last safe
|
|
4
|
+
The last safe integer is `2^53 - 1` or `9007199254740991`.
|
|
5
5
|
|
|
6
|
-
A safe integer is an integer that
|
|
6
|
+
A safe integer is an integer that fulfills all of the following:
|
|
7
7
|
|
|
8
|
-
-
|
|
9
|
-
-
|
|
8
|
+
- Can be exactly represented as an IEEE-754 double precision number.
|
|
9
|
+
- The IEEE-754 representation cannot be the result of rounding any
|
|
10
10
|
other integer to fit the IEEE-754 representation.
|
|
11
11
|
|
|
12
12
|
The message's severity is `Error`.
|
|
@@ -15,13 +15,14 @@ The message's severity is `Error`.
|
|
|
15
15
|
|
|
16
16
|
Erroneous code example:
|
|
17
17
|
|
|
18
|
+
<!-- cds-mode: ignore -->
|
|
18
19
|
```cdl
|
|
19
20
|
type LengthIsUnsafe : String(9007199254740992);
|
|
20
21
|
type NotAnInteger : String(42.1);
|
|
21
22
|
```
|
|
22
23
|
|
|
23
|
-
In the
|
|
24
|
-
safe
|
|
24
|
+
In the erroneous example, the string length for the type `LengthIsUnsafe` is
|
|
25
|
+
not a safe integer. It is too large.
|
|
25
26
|
Likewise, the string length for the type `NotAnInteger` is a decimal.
|
|
26
27
|
|
|
27
28
|
## How to Fix
|
|
@@ -33,5 +34,5 @@ type LengthIsSafe : String(9007199254740991);
|
|
|
33
34
|
type AnInteger : String(42);
|
|
34
35
|
```
|
|
35
36
|
|
|
36
|
-
If not feasible, a string representation of the
|
|
37
|
-
|
|
37
|
+
If it's not feasible to use a safe integer, a string representation of the
|
|
38
|
+
number needs to be used, for example, in annotation values.
|
package/doc/ApiMigration.md
DELETED
|
@@ -1,237 +0,0 @@
|
|
|
1
|
-
# API Migration
|
|
2
|
-
|
|
3
|
-
> Status Oct 2019: this document is still valid, but the recommended API will change (again) in the near future.
|
|
4
|
-
> The future version of this document (renamed to `API.md`) will basically explain the recommended API,
|
|
5
|
-
> the migration will only be a minor aspect and explained in a later section.
|
|
6
|
-
|
|
7
|
-
<!-- The option handling might also change: -->
|
|
8
|
-
<!-- the backend-specific structure is overly complex and not always appriopriate (e.g. naming mode). -->
|
|
9
|
-
|
|
10
|
-
With revision 1.0.24, the CDS compiler offers new API backend functions, i.e. new functions for the
|
|
11
|
-
generation of output from (augmented) CSN models. The new functions and their options are closely
|
|
12
|
-
aligned with the new command line interface `cdsc`. The old backend functions are deprecated, will
|
|
13
|
-
not be extended with new features, and will be removed in a subsequent release. Note that only these
|
|
14
|
-
API functions from `lib/main.js` are supported - **all internal functions are subject to change without
|
|
15
|
-
notice**.
|
|
16
|
-
|
|
17
|
-
Please see the function headers in `lib/backends.js` for a description of the new API functions (for a
|
|
18
|
-
snapshot of the current version, see below).
|
|
19
|
-
|
|
20
|
-
## Some helpful hints
|
|
21
|
-
|
|
22
|
-
Please note the following general concepts regarding the new API functions:
|
|
23
|
-
- The behavior of the compiler and of all backend API functions is controlled by a common `options` object,
|
|
24
|
-
with subsections for each backend function, e.g. `options: {toHana: {src: true}, toOdata: {version: 'v2'}}`.
|
|
25
|
-
- Options can either be specified with one of the `compile` functions (transported within the model to the
|
|
26
|
-
backends), or explicitly at the invocation of a backend API function.
|
|
27
|
-
- Options are merged, with precedence given to those specified explicitly at the backend API functions.
|
|
28
|
-
- When invoking a backend function with options that all belong to this backend function, the subsection wrapper
|
|
29
|
-
can be omitted, i.e. `toHana(model, {toHana: {src: true}})` is equivalent to `toHana(model, {src: true})`.
|
|
30
|
-
- Most backend API functions have a combination of options controlling _what_ is generated
|
|
31
|
-
(e.g. `toHana: {src: true}`) and options modifying _how_ things are generated (e.g. `toOdata: {version: 'v2'}`).
|
|
32
|
-
|
|
33
|
-
## Migration guide
|
|
34
|
-
|
|
35
|
-
The following table shows replacements for the deprecated API functions (relying on default options where possible):
|
|
36
|
-
|
|
37
|
-
| Deprecated function call | New function call |
|
|
38
|
-
| -------------------------- | ------------------------------------------- |
|
|
39
|
-
| `toHanaCdl(model)` | `toHana(model)`|
|
|
40
|
-
| `forHana(model)` | `toHana(model, {csn: true})`|
|
|
41
|
-
| `toOdataOutput(model, {oDataVersion: 'v2'}` | `toOdata(model, {version: 'v2', xml: true, json: true, separate: true, combined: true, csn: true})`|
|
|
42
|
-
| `toSqlDdl(model)` | `toSql(model)`|
|
|
43
|
-
| `compactJson(model)` | `toCsn(model)`|
|
|
44
|
-
|
|
45
|
-
## Changes in behavior
|
|
46
|
-
|
|
47
|
-
The following changes have been made to the behavior of `toOdata` in comparison to `toOdataOutput`:
|
|
48
|
-
- Output is now generated either for ODATA V2 or for V4. The old `toOdataOutput` function produced the `annotations` output with
|
|
49
|
-
an extra invocation of the backend using `oDataVersion: 'v4'` even if the original invocation specified `oDataVersion: 'v2'`,
|
|
50
|
-
resulting in slightly different output. The `combined` output always had the correct versioning.
|
|
51
|
-
- The `metadata_json` output is now an object, not a string.
|
|
52
|
-
|
|
53
|
-
## Snapshot of backend API function documentation
|
|
54
|
-
|
|
55
|
-
Note that these backend API functions are all exposed in `lib/main.js` (which is **the only external API**), but
|
|
56
|
-
their documentation is currently located in `lib/backends.js` (this will likely change).
|
|
57
|
-
|
|
58
|
-
### `toHana(model, options)`
|
|
59
|
-
|
|
60
|
-
```
|
|
61
|
-
// Transform an augmented CSN 'model' into HANA-compatible CDS source.
|
|
62
|
-
// The following options control what is actually generated:
|
|
63
|
-
// options : {
|
|
64
|
-
// toHana.names : either 'plain' (generate uppercased flattened entity names with
|
|
65
|
-
// underscores) or 'quoted' (default, generate entity names with nested
|
|
66
|
-
// contexts as in CDL)
|
|
67
|
-
// toHana.associations : either 'assocs' (default, keep associations as they are if possible)
|
|
68
|
-
// or 'joins' (replace associations by joins)
|
|
69
|
-
// toHana.src : if true, generate HANA CDS source files (default)
|
|
70
|
-
// toHana.csn : if true, generate the transformed CSN model
|
|
71
|
-
// }
|
|
72
|
-
// Options provided here are merged with (and take precedence over) options from 'model'.
|
|
73
|
-
// If 'toHana.names' is not provided, 'quoted' is used.
|
|
74
|
-
// If 'toHana.associations' is not provided, 'assocs' is used.
|
|
75
|
-
// If neither 'toHana.src' nor 'toHana.csn' are provided, the default is to generate only HANA CDS
|
|
76
|
-
// source files.
|
|
77
|
-
// If all provided options are part of 'toHana', the 'toHana' wrapper can be omitted.
|
|
78
|
-
// The result object contains the generation results as follows (as enabled in 'options'):
|
|
79
|
-
// result : {
|
|
80
|
-
// csn : the (compact) transformed CSN model
|
|
81
|
-
// _augmentedCsn : (subject to change): the augmented CSN model
|
|
82
|
-
// hdbcds : a dictionary of top-level artifact names, containing for each name 'X':
|
|
83
|
-
// <X> : the HANA CDS source string of the artifact 'X'. Please note that the
|
|
84
|
-
// name of 'X' may contain characters that are not legal for filenames on
|
|
85
|
-
// all operating systems (e.g. ':', '\' or '/').
|
|
86
|
-
// messages : an array of strings with warnings (if any)
|
|
87
|
-
// }
|
|
88
|
-
function toHana(model, options) {
|
|
89
|
-
...
|
|
90
|
-
}
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
### `toOdata(model, options)`
|
|
94
|
-
|
|
95
|
-
```
|
|
96
|
-
// Generate ODATA for augmented CSN `model` using `options`.
|
|
97
|
-
// Before anything is generated, the following transformations are applied to 'model':
|
|
98
|
-
// FIXME: Verify that this is still correct
|
|
99
|
-
// - Flatten structured elements (and foreign keys of managed associations pointing to
|
|
100
|
-
// keys that are themselves managed associations).
|
|
101
|
-
// - Generate foreign key fields for entities with managed associations (annotated with
|
|
102
|
-
// '@odata.foreignKey4'). Propagate along projections accordingly. Names are built using
|
|
103
|
-
// <assoc>_<key>, conflicts are checked.
|
|
104
|
-
// - Complete the 'foreignKeys' property for all managed associations, so that there
|
|
105
|
-
// is always a 'generatedFieldName' for the corresponding generated foreign key field.
|
|
106
|
-
// - Implicitly redirect associations based on exposure
|
|
107
|
-
// - Check that exposed associations do not point to non-exposed targets
|
|
108
|
-
// - Unravel derived type chains, propagating annotations upwards.
|
|
109
|
-
// - Rename annotations according to a fixed list of short-hands
|
|
110
|
-
// The following options control what is actually generated:
|
|
111
|
-
// options : {
|
|
112
|
-
// toOdata.version : either 'v2' or 'v4' (default)
|
|
113
|
-
// toOdata.xml : if true, generate XML output (default)
|
|
114
|
-
// toOdata.json : if true, generate JSON output (not available for ODATA V2)
|
|
115
|
-
// toOdata.separate : if true, generate XML 'metadata' and XML 'annotations' separately
|
|
116
|
-
// toOdata.combined : if true, generate XML metadata and XML annotations together as
|
|
117
|
-
// 'combined' (default)
|
|
118
|
-
// toOdata.csn : if true, generate the transformed CSN model
|
|
119
|
-
// }
|
|
120
|
-
// Options provided here are merged with (and take precedence over) options from 'model'.
|
|
121
|
-
// If 'toOdata.version' is not provided, 'v4' is used.
|
|
122
|
-
// If neither 'toOdata.xml' nor 'toOdata.json' nor 'toOdata.csn' are provided, the default is
|
|
123
|
-
// to generate only XML output. If neither 'toOdata.separate' nor 'toOdata.combined' are provided,
|
|
124
|
-
// the default is to generate only combined XML output.
|
|
125
|
-
// If all provided options are part of 'toOdata', the 'toOdata' wrapper can be omitted.
|
|
126
|
-
//
|
|
127
|
-
// The result object contains the generation results as follows (as enabled in 'options'):
|
|
128
|
-
// result : {
|
|
129
|
-
// csn : the (compact) transformed CSN model including all services
|
|
130
|
-
// _augmentedCsn : (subject to change): the augmented CSN model including all services
|
|
131
|
-
// services : a dictionary of service names, containing for each name:
|
|
132
|
-
// <servicename> : {
|
|
133
|
-
// annotations : an XML string with EDMX annotations for service 'svc'
|
|
134
|
-
// metadata : an XML string with EDMX metadata for service 'svc'
|
|
135
|
-
// combined : an XML string with both EDMX metadata and annotations for service 'svc'
|
|
136
|
-
// metadata_json : a JSON object (not a string!) with EDM metadata for service 'svc'
|
|
137
|
-
// }
|
|
138
|
-
// messages : an array of strings with warnings (if any)
|
|
139
|
-
// }
|
|
140
|
-
// If 'model' does not contain any services, 'csn' will still contain the transformed model, but
|
|
141
|
-
// 'services' will be an empty dictionary.
|
|
142
|
-
//
|
|
143
|
-
// Throws a CompilationError on errors.
|
|
144
|
-
function toOdata(model, options) {
|
|
145
|
-
...
|
|
146
|
-
}
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
### `toCdl(model, options)`
|
|
150
|
-
|
|
151
|
-
```
|
|
152
|
-
// Generate CDS source text for augmented CSN model 'model'.
|
|
153
|
-
// The following options control what is actually generated:
|
|
154
|
-
// options : {
|
|
155
|
-
// FIXME: This option should be removed and something like 'toCdl.dialect: 'hana' be
|
|
156
|
-
// used instead.
|
|
157
|
-
// hanaFlavor : if true, HANA-specific source dialect is generated (affects e.g. the
|
|
158
|
-
// translation of '$self.foo' in paths and ::-ish namespace declarations)
|
|
159
|
-
// }
|
|
160
|
-
// One source is created per top-level artifact.
|
|
161
|
-
// Return a dictionary of top-level artifacts
|
|
162
|
-
// by their names, like this:
|
|
163
|
-
// { "foo" : "using XY; context foo {...};",
|
|
164
|
-
// "bar::wiz" : "namespace bar::; entity wiz {...};"
|
|
165
|
-
// }
|
|
166
|
-
// Throws a CompilationError on errors.
|
|
167
|
-
function toCdl(model, options) {
|
|
168
|
-
...
|
|
169
|
-
}
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
### `toSwagger(model, options)`
|
|
173
|
-
|
|
174
|
-
```
|
|
175
|
-
// Generate OpenAPI JSON version 3 for the augmented CSN 'model'.
|
|
176
|
-
// Return an object representing the Swagger JSON:
|
|
177
|
-
// {
|
|
178
|
-
// openapi: '3.0.0',
|
|
179
|
-
// info: { ... },
|
|
180
|
-
// paths: { ...},
|
|
181
|
-
// components: {
|
|
182
|
-
// schemas: { ... }
|
|
183
|
-
// }
|
|
184
|
-
// }
|
|
185
|
-
//
|
|
186
|
-
// Throws a CompilationError on errors.
|
|
187
|
-
function toSwagger(model, options) {
|
|
188
|
-
...
|
|
189
|
-
}
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
### `toSql(model, options)`
|
|
193
|
-
|
|
194
|
-
```
|
|
195
|
-
// Generate SQL DDL statements for augmented CSN 'model'.
|
|
196
|
-
// The following options control what is actually generated:
|
|
197
|
-
// options : {
|
|
198
|
-
// toSql.names : either 'plain' (generate uppercased flattened table/view names with
|
|
199
|
-
// underscores) or 'quoted' (default, generate quoted table/view names
|
|
200
|
-
// with dots as in CDL)
|
|
201
|
-
// toSql.associations : either 'assocs' (default, keep associations as they are if possible)
|
|
202
|
-
// or 'joins' (replace associations by joins)
|
|
203
|
-
// toSql.src : if 'sql', generate SQL DDL source files (default)
|
|
204
|
-
// toSql.csn : if true, generate the transformed CSN model
|
|
205
|
-
// }
|
|
206
|
-
// Options provided here are merged with (and take precedence over) options from 'model'.
|
|
207
|
-
// If 'toSql.names' is not provided, 'quoted' is used.
|
|
208
|
-
// If 'toSql.associations' is not provided, 'assocs' is used.
|
|
209
|
-
// If neither 'toSql.src' nor 'toSql.csn' are provided, the default is to generate only SQL DDL
|
|
210
|
-
// source files.
|
|
211
|
-
// If all provided options are part of 'toSql', the 'toSql' wrapper can be omitted.
|
|
212
|
-
// The result object contains the generation results as follows (as enabled in 'options'):
|
|
213
|
-
// result : {
|
|
214
|
-
// csn : the (compact) transformed CSN model
|
|
215
|
-
// _augmentedCsn : (subject to change): the augmented CSN model
|
|
216
|
-
// sql : a dictionary of top-level artifact names, containing for each name 'X':
|
|
217
|
-
// <X> : a string with SQL DDL statements for artifact 'X', terminated with ';'.
|
|
218
|
-
// Please note that the name of 'X' may contain characters that are not
|
|
219
|
-
// legal for filenames on all operating systems (e.g. ':', '\' or '/').
|
|
220
|
-
// messages : an array of strings with warnings (if any)
|
|
221
|
-
// }
|
|
222
|
-
// Throws a CompilationError on errors.
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
### `toCsn(model, options)`
|
|
226
|
-
|
|
227
|
-
```
|
|
228
|
-
// Generate compact CSN for augmented CSN 'model'
|
|
229
|
-
// The following options control what is actually generated:
|
|
230
|
-
// options : {
|
|
231
|
-
// testMode : if true, the result is extra-stable for automated tests (sorted, no 'version')
|
|
232
|
-
// }
|
|
233
|
-
// Options provided here are merged with (and take precedence over) options from 'model'.
|
|
234
|
-
function toCsn(model, options) {
|
|
235
|
-
...
|
|
236
|
-
}
|
|
237
|
-
```
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
# Command Line Migration
|
|
2
|
-
|
|
3
|
-
> Status Oct 2019: this document is still basically valid.
|
|
4
|
-
> The future version of this document (renamed to `CommandLine.md`) will basically explain the recommended CLI options,
|
|
5
|
-
> the migration will only be a minor aspect and explained in a later section.
|
|
6
|
-
|
|
7
|
-
<!-- The option handling might also change: -->
|
|
8
|
-
<!-- the backend-specific structure is overly complex and not always appriopriate (e.g. naming mode). -->
|
|
9
|
-
<!-- The placement of options should not depend on a not always apparent distinction between command-specific and general options. -->
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
With revision 1.5.1, the `cdsc` command line interface has been adapted to use commands with
|
|
13
|
-
options.
|
|
14
|
-
|
|
15
|
-
Usage is now `cdsc <command> [options] <files...>` instead of `cdsc [options] <file...>`.
|
|
16
|
-
|
|
17
|
-
The generation options (`--toHana`, `--toSql`, ...) have been replaced by commands
|
|
18
|
-
(`toHana`, `toSql`, ...). This allows for better per-command options, which can now be optional,
|
|
19
|
-
can use more single-letter abbreviations, and now match those from the `options` object in the API.
|
|
20
|
-
|
|
21
|
-
Some examples:
|
|
22
|
-
|
|
23
|
-
| Old command line | New command line |
|
|
24
|
-
| -------------------------- | --------------------------------------------- |
|
|
25
|
-
| `cdsc --new-csn --toHana csn,plain foo.cds` | `cdsc --new-csn toHana --csn --names plain foo.cds` |
|
|
26
|
-
| `cdsc -R --H csn,plain foo.cds` | `cdsc -R H -c -n plain foo.cds` |
|
|
27
|
-
| `cdsc --toOdata xml,v2,separate foo.cds` | `cdsc toOdata --xml --version v2 --separate foo.cds` |
|
|
28
|
-
| `cdsc --toSql src foo.cds` | `cdsc toSql foo.cds` |
|
|
29
|
-
| `cdsc foo.cds` | `cdsc foo.cds` |
|
|
30
|
-
|
|
31
|
-
List of commands (as of v1.5.1):
|
|
32
|
-
|
|
33
|
-
```
|
|
34
|
-
Commands
|
|
35
|
-
H, toHana [options] <files...> Generate HANA CDS source files
|
|
36
|
-
O, toOdata [options] <files...> Generate ODATA metadata and annotations
|
|
37
|
-
C, toCdl <files...> Generate CDS source files
|
|
38
|
-
S, toSwagger [options] <files...> Generate Swagger (OpenAPI) JSON
|
|
39
|
-
Q, toSql [options] <files...> Generate SQL DDL statements
|
|
40
|
-
toCsn [options] <files...> (default) Generate original model as CSN
|
|
41
|
-
toTntSpecificOutput <files...> (internal) Generate TNT-specific post-processed CSN
|
|
42
|
-
toRename [options] <files...> (internal) Generate SQL DDL rename statements
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
Please see `cdsc --help` for the list of commands and general options, or `cdsc <command> --help`
|
|
46
|
-
for help regarding a specific command.
|
|
47
|
-
|
|
48
|
-
## Some helpful hints
|
|
49
|
-
|
|
50
|
-
Please note the following general concepts regarding the new command line:
|
|
51
|
-
- General options can be placed anywhere, command specific options must appear after the command.
|
|
52
|
-
- In the unlikely case that a file name starts with `-`, please use `--` to indicate the end of options.
|
|
53
|
-
- The `src` argument of `toHana`, `toCdl`, `toSql` is now optional (and it would now be `--src`).
|
|
54
|
-
- If no command is specified, the default is `toCsn --flavor client` (as before).
|
|
55
|
-
- When no `--out` option is provided or if `-` is specified as output directory , all output will
|
|
56
|
-
go to `<stdout>` instead of being written to files (like before).
|
|
57
|
-
- The `--raw-output` option also affects all commands where a CSN file is generated.
|
|
58
|
-
Instead of `...csn.json`, a `...csn_raw.txt` will be produced (like before).
|