@sap/cds-compiler 5.9.4 → 6.0.10
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 +104 -319
- package/README.md +1 -1
- package/bin/cds_update_identifiers.js +3 -5
- package/bin/cdsc.js +22 -8
- package/bin/cdshi.js +1 -1
- package/bin/cdsse.js +4 -4
- package/doc/CHANGELOG_BETA.md +11 -0
- package/doc/CHANGELOG_DEPRECATED.md +29 -0
- package/lib/api/main.js +8 -5
- package/lib/api/options.js +12 -10
- package/lib/base/builtins.js +1 -0
- package/lib/base/message-registry.js +190 -96
- package/lib/base/messages.js +29 -20
- package/lib/base/model.js +14 -24
- package/lib/checks/actionsFunctions.js +10 -20
- package/lib/checks/annotationsOData.js +1 -1
- package/lib/checks/elements.js +30 -10
- package/lib/checks/enums.js +31 -0
- package/lib/checks/foreignKeys.js +2 -2
- package/lib/checks/hasPersistedElements.js +5 -0
- package/lib/checks/invalidTarget.js +1 -1
- package/lib/checks/managedWithoutKeys.js +5 -4
- package/lib/checks/queryNoDbArtifacts.js +10 -8
- package/lib/checks/types.js +5 -5
- package/lib/checks/validator.js +6 -4
- package/lib/compiler/assert-consistency.js +12 -9
- package/lib/compiler/checks.js +18 -50
- package/lib/compiler/define.js +6 -6
- package/lib/compiler/extend.js +2 -1
- package/lib/compiler/generate.js +14 -17
- package/lib/compiler/populate.js +8 -31
- package/lib/compiler/propagator.js +21 -35
- package/lib/compiler/resolve.js +35 -22
- package/lib/compiler/shared.js +7 -1
- package/lib/compiler/tweak-assocs.js +1 -1
- package/lib/compiler/utils.js +1 -1
- package/lib/edm/annotations/edmJson.js +20 -15
- package/lib/edm/annotations/genericTranslation.js +7 -8
- package/lib/edm/csn2edm.js +46 -50
- package/lib/edm/edm.js +8 -7
- package/lib/edm/edmPreprocessor.js +33 -83
- package/lib/edm/edmUtils.js +2 -2
- package/lib/gen/BaseParser.js +55 -44
- package/lib/gen/CdlGrammar.checksum +1 -1
- package/lib/gen/CdlParser.js +1133 -1150
- package/lib/json/from-csn.js +70 -43
- package/lib/json/to-csn.js +6 -8
- package/lib/language/multiLineStringParser.js +3 -2
- package/lib/main.d.ts +58 -24
- package/lib/model/csnUtils.js +28 -39
- package/lib/model/xprAsTree.js +23 -9
- package/lib/modelCompare/compare.js +5 -4
- package/lib/optionProcessor.js +21 -17
- package/lib/parsers/AstBuildingParser.js +63 -11
- package/lib/parsers/XprTree.js +57 -3
- package/lib/parsers/identifiers.js +1 -1
- package/lib/parsers/index.js +0 -3
- package/lib/render/manageConstraints.js +25 -25
- package/lib/render/toCdl.js +173 -170
- package/lib/render/toHdbcds.js +126 -128
- package/lib/render/toRename.js +7 -7
- package/lib/render/toSql.js +128 -125
- package/lib/render/utils/common.js +47 -22
- package/lib/render/utils/delta.js +25 -25
- package/lib/render/utils/operators.js +2 -2
- package/lib/render/utils/pretty.js +5 -5
- package/lib/render/utils/sql.js +13 -13
- package/lib/render/utils/standardDatabaseFunctions.js +115 -103
- package/lib/render/utils/unique.js +4 -4
- package/lib/transform/db/applyTransformations.js +1 -1
- package/lib/transform/db/assertUnique.js +2 -2
- package/lib/transform/db/associations.js +6 -7
- package/lib/transform/db/assocsToQueries/utils.js +4 -5
- package/lib/transform/db/backlinks.js +12 -9
- package/lib/transform/db/cdsPersistence.js +8 -7
- package/lib/transform/db/constraints.js +13 -10
- package/lib/transform/db/expansion.js +7 -3
- package/lib/transform/db/flattening.js +4 -14
- package/lib/transform/db/processSqlServices.js +2 -1
- package/lib/transform/db/temporal.js +5 -7
- package/lib/transform/db/views.js +2 -4
- package/lib/transform/draft/db.js +8 -8
- package/lib/transform/draft/odata.js +10 -7
- package/lib/transform/forOdata.js +10 -5
- package/lib/transform/forRelationalDB.js +5 -75
- package/lib/transform/localized.js +1 -1
- package/lib/transform/odata/createForeignKeys.js +11 -10
- package/lib/transform/odata/flattening.js +8 -4
- package/lib/transform/odata/foreignKeyRefsInXprAnnos.js +96 -0
- package/lib/transform/odata/typesExposure.js +3 -3
- package/lib/transform/transformUtils.js +4 -8
- package/lib/transform/translateAssocsToJoins.js +14 -7
- package/lib/transform/universalCsn/universalCsnEnricher.js +10 -4
- package/lib/utils/objectUtils.js +0 -17
- package/package.json +10 -13
- package/share/messages/def-upcoming-virtual-change.md +1 -1
- package/LICENSE +0 -37
- package/bin/cds_remove_invalid_whitespace.js +0 -138
- package/doc/CHANGELOG_ARCHIVE.md +0 -3604
- package/lib/gen/genericAntlrParser.js +0 -3
- package/lib/gen/language.checksum +0 -1
- package/lib/gen/language.interp +0 -456
- package/lib/gen/language.tokens +0 -180
- package/lib/gen/languageLexer.interp +0 -439
- package/lib/gen/languageLexer.js +0 -1483
- package/lib/gen/languageLexer.tokens +0 -167
- package/lib/gen/languageParser.js +0 -24941
- package/lib/language/antlrParser.js +0 -205
- package/lib/language/errorStrategy.js +0 -646
- package/lib/language/genericAntlrParser.js +0 -1572
- package/lib/parsers/CdlGrammar.g4 +0 -2070
package/lib/render/toHdbcds.js
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
const {
|
|
4
4
|
getLastPartOf, getLastPartOfRef,
|
|
5
5
|
hasValidSkipOrExists, getNormalizedQuery,
|
|
6
|
-
getRootArtifactName, getResultingName, getNamespace, forEachMember, getVariableReplacement,
|
|
7
|
-
pathName,
|
|
6
|
+
getRootArtifactName, getResultingName, getNamespace, forEachMember, getVariableReplacement,
|
|
7
|
+
pathName, hasPersistenceSkipAnnotation,
|
|
8
8
|
} = require('../model/csnUtils');
|
|
9
9
|
const { isBuiltinType, isMagicVariable } = require('../base/builtins');
|
|
10
10
|
const keywords = require('../base/keywords');
|
|
@@ -18,7 +18,7 @@ const {
|
|
|
18
18
|
renderReferentialConstraint,
|
|
19
19
|
} = require('./utils/sql');
|
|
20
20
|
const DuplicateChecker = require('./DuplicateChecker');
|
|
21
|
-
const {
|
|
21
|
+
const { forEachDefinition, isDeprecatedEnabled } = require('../base/model');
|
|
22
22
|
const { checkCSNVersion } = require('../json/csnVersion');
|
|
23
23
|
const { timetrace } = require('../utils/timetrace');
|
|
24
24
|
|
|
@@ -55,7 +55,7 @@ class HdbcdsRenderEnvironment {
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
withIncreasedIndent() {
|
|
58
|
-
return new HdbcdsRenderEnvironment({ ...this, namePrefix: '', indent: ` ${this.indent}` });
|
|
58
|
+
return new HdbcdsRenderEnvironment({ ...this, namePrefix: '', indent: ` ${ this.indent }` });
|
|
59
59
|
}
|
|
60
60
|
withSubPath(path) {
|
|
61
61
|
return new HdbcdsRenderEnvironment({ ...this, path: [ ...this.path, ...path ] });
|
|
@@ -84,7 +84,7 @@ function getEscapedHanaComment( obj ) {
|
|
|
84
84
|
* @returns {string}
|
|
85
85
|
*/
|
|
86
86
|
function renderStringForHdbcds( str ) {
|
|
87
|
-
return `'${str.replace(/'/g, '\'\'')}'`;
|
|
87
|
+
return `'${ str.replace(/'/g, '\'\'') }'`;
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
/**
|
|
@@ -117,25 +117,24 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
117
117
|
const typeRefWithoutParams = typeRef.substring(0, typeRef.indexOf('(')) || typeRef;
|
|
118
118
|
typeRef = typeRef.replace(typeRefWithoutParams, hanaSqlType);
|
|
119
119
|
}
|
|
120
|
-
return `CAST(${this.renderExpr(withoutCast(x))} AS ${typeRef})`;
|
|
120
|
+
return `CAST(${ this.renderExpr(withoutCast(x)) } AS ${ typeRef })`;
|
|
121
121
|
},
|
|
122
122
|
val: renderExpressionLiteral,
|
|
123
|
-
enum: x => `#${x['#']}`,
|
|
123
|
+
enum: x => `#${ x['#'] }`,
|
|
124
124
|
ref: renderExpressionRef,
|
|
125
|
-
aliasOnly: x => x.as,
|
|
126
125
|
windowFunction: renderExpressionFunc,
|
|
127
126
|
func: renderExpressionFunc,
|
|
128
127
|
xpr(x) {
|
|
129
128
|
const xprEnv = this.env.withSubPath([ 'xpr' ]);
|
|
130
129
|
if (this.isNestedXpr && !x.cast)
|
|
131
|
-
return `(${this.renderSubExpr(x.xpr, xprEnv)})`;
|
|
130
|
+
return `(${ this.renderSubExpr(x.xpr, xprEnv) })`;
|
|
132
131
|
return this.renderSubExpr(x.xpr, xprEnv);
|
|
133
132
|
},
|
|
134
133
|
SELECT(x) {
|
|
135
|
-
return `(${renderQuery(x, false, this.env.withIncreasedIndent())})`;
|
|
134
|
+
return `(${ renderQuery(x, false, this.env.withIncreasedIndent()) })`;
|
|
136
135
|
},
|
|
137
136
|
SET(x) {
|
|
138
|
-
return `${renderQuery(x, false, this.env.withIncreasedIndent())}`;
|
|
137
|
+
return `${ renderQuery(x, false, this.env.withIncreasedIndent()) }`;
|
|
139
138
|
},
|
|
140
139
|
});
|
|
141
140
|
|
|
@@ -259,7 +258,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
259
258
|
case 'event':
|
|
260
259
|
return '';
|
|
261
260
|
default:
|
|
262
|
-
throw new ModelError(`Unknown artifact kind: ${art.kind}`);
|
|
261
|
+
throw new ModelError(`Unknown artifact kind: ${ art.kind }`);
|
|
263
262
|
}
|
|
264
263
|
}
|
|
265
264
|
|
|
@@ -270,7 +269,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
270
269
|
* @returns {object} Dictionary with direct sub-artifacts
|
|
271
270
|
*/
|
|
272
271
|
function getSubArtifacts( artifactName ) {
|
|
273
|
-
const prefix = `${artifactName}.`;
|
|
272
|
+
const prefix = `${ artifactName }.`;
|
|
274
273
|
const result = Object.create(null);
|
|
275
274
|
for (const name in csn.definitions) {
|
|
276
275
|
// We have a direct child if its name starts with prefix and contains no more dots
|
|
@@ -334,23 +333,23 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
334
333
|
if (isShadowed) {
|
|
335
334
|
const subArtifacts = getSubArtifacts(artifactName);
|
|
336
335
|
for (const name in subArtifacts)
|
|
337
|
-
result += renderDefinition(`${artifactName}.${name}`, subArtifacts[name], env);
|
|
336
|
+
result += renderDefinition(`${ artifactName }.${ name }`, subArtifacts[name], env);
|
|
338
337
|
|
|
339
|
-
return `${result}\n`;
|
|
338
|
+
return `${ result }\n`;
|
|
340
339
|
}
|
|
341
340
|
|
|
342
341
|
const childEnv = env.withIncreasedIndent();
|
|
343
|
-
result += `${env.indent}context ${renderArtifactName(artifactName, env, true)}`;
|
|
342
|
+
result += `${ env.indent }context ${ renderArtifactName(artifactName, env, true) }`;
|
|
344
343
|
result += ' {\n';
|
|
345
344
|
const subArtifacts = getSubArtifacts(artifactName);
|
|
346
345
|
let renderedSubArtifacts = '';
|
|
347
346
|
for (const name in subArtifacts)
|
|
348
|
-
renderedSubArtifacts += renderDefinition(`${artifactName}.${name}`, subArtifacts[name], updatePrefixForDottedName(childEnv, name));
|
|
347
|
+
renderedSubArtifacts += renderDefinition(`${ artifactName }.${ name }`, subArtifacts[name], updatePrefixForDottedName(childEnv, name));
|
|
349
348
|
|
|
350
349
|
if (renderedSubArtifacts === '')
|
|
351
350
|
return '';
|
|
352
351
|
|
|
353
|
-
return `${result + renderedSubArtifacts + env.indent}};\n`;
|
|
352
|
+
return `${ result + renderedSubArtifacts + env.indent }};\n`;
|
|
354
353
|
}
|
|
355
354
|
|
|
356
355
|
/**
|
|
@@ -411,7 +410,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
411
410
|
const childEnv = addNamePrefix(env, getLastPartOf(artifactName));
|
|
412
411
|
const subArtifacts = getSubArtifacts(artifactName);
|
|
413
412
|
for (const name in subArtifacts)
|
|
414
|
-
result += renderDefinition(`${artifactName}.${name}`, subArtifacts[name], updatePrefixForDottedName(childEnv, name));
|
|
413
|
+
result += renderDefinition(`${ artifactName }.${ name }`, subArtifacts[name], updatePrefixForDottedName(childEnv, name));
|
|
415
414
|
|
|
416
415
|
return result;
|
|
417
416
|
}
|
|
@@ -432,7 +431,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
432
431
|
globalDuplicateChecker.addArtifact(art['@cds.persistence.name'], env.path, artifactName);
|
|
433
432
|
|
|
434
433
|
if (hasHanaComment(art, options))
|
|
435
|
-
result += `${env.indent}@Comment: '${getEscapedHanaComment(art)}'\n`;
|
|
434
|
+
result += `${ env.indent }@Comment: '${ getEscapedHanaComment(art) }'\n`;
|
|
436
435
|
|
|
437
436
|
// tables can have @sql.prepend and @sql.append
|
|
438
437
|
const { front, back } = getSqlSnippets(options, art);
|
|
@@ -440,10 +439,10 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
440
439
|
if (front) // attach @sql.prepend after adding @Comment annotation
|
|
441
440
|
result += front;
|
|
442
441
|
|
|
443
|
-
result += `${env.indent + (art.abstract ? 'abstract ' : '')}entity ${normalizedArtifactName}`;
|
|
442
|
+
result += `${ env.indent + (art.abstract ? 'abstract ' : '') }entity ${ normalizedArtifactName }`;
|
|
444
443
|
if (art.includes) {
|
|
445
444
|
// Includes are never flattened (don't exist in HANA)
|
|
446
|
-
result += ` : ${art.includes.map((name, i) => renderAbsoluteNameWithQuotes(name, env.withSubPath([ 'includes', i ]))).join(', ')}`;
|
|
445
|
+
result += ` : ${ art.includes.map((name, i) => renderAbsoluteNameWithQuotes(name, env.withSubPath([ 'includes', i ]))).join(', ') }`;
|
|
447
446
|
}
|
|
448
447
|
result += ' {\n';
|
|
449
448
|
const duplicateChecker = new DuplicateChecker(); // registry for all artifact names and element names
|
|
@@ -455,13 +454,13 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
455
454
|
result += renderElement(name, art.elements[name], childEnv.withSubPath([ 'elements', name ]), duplicateChecker);
|
|
456
455
|
|
|
457
456
|
duplicateChecker.check(error);
|
|
458
|
-
result += `${env.indent}}`;
|
|
459
|
-
result += `${renderTechnicalConfiguration(art.technicalConfig, env)}`;
|
|
457
|
+
result += `${ env.indent }}`;
|
|
458
|
+
result += `${ renderTechnicalConfiguration(art.technicalConfig, env) }`;
|
|
460
459
|
|
|
461
460
|
if (back)
|
|
462
461
|
result += back;
|
|
463
462
|
|
|
464
|
-
return `${result};\n`;
|
|
463
|
+
return `${ result };\n`;
|
|
465
464
|
}
|
|
466
465
|
|
|
467
466
|
/**
|
|
@@ -510,11 +509,11 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
510
509
|
if (!tc)
|
|
511
510
|
throw new ModelError('Expecting a SAP HANA technical configuration');
|
|
512
511
|
|
|
513
|
-
result += `\n${env.indent}technical ${tc.calculated ? '' : 'hana '}configuration {\n`;
|
|
512
|
+
result += `\n${ env.indent }technical ${ tc.calculated ? '' : 'hana ' }configuration {\n`;
|
|
514
513
|
|
|
515
514
|
// Store type (must be separate because SQL wants it between 'CREATE' and 'TABLE')
|
|
516
515
|
if (tc.storeType)
|
|
517
|
-
result += `${tc.storeType} store;\n`;
|
|
516
|
+
result += `${ tc.storeType } store;\n`;
|
|
518
517
|
|
|
519
518
|
// Fixed parts belonging to the table (includes migration, unload prio, extended storage,
|
|
520
519
|
// auto merge, partitioning, ...)
|
|
@@ -527,7 +526,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
527
526
|
// object. Semantically equivalent because a "trivial" SQL renderer would just
|
|
528
527
|
// concatenate them.
|
|
529
528
|
for (const xpr of tc.tableSuffix)
|
|
530
|
-
result += `${childEnv.indent + renderExpr(xpr, childEnv)};\n`;
|
|
529
|
+
result += `${ childEnv.indent + renderExpr(xpr, childEnv) };\n`;
|
|
531
530
|
}
|
|
532
531
|
|
|
533
532
|
// Indices and full-text indices
|
|
@@ -535,10 +534,10 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
535
534
|
if (Array.isArray(tc.indexes[idxName][0])) {
|
|
536
535
|
// FIXME: Should we allow multiple indices with the same name at all?
|
|
537
536
|
for (const index of tc.indexes[idxName])
|
|
538
|
-
result += `${childEnv.indent + renderExpr(index, childEnv)};\n`;
|
|
537
|
+
result += `${ childEnv.indent + renderExpr(index, childEnv) };\n`;
|
|
539
538
|
}
|
|
540
539
|
else {
|
|
541
|
-
result += `${childEnv.indent + renderExpr(tc.indexes[idxName], childEnv)};\n`;
|
|
540
|
+
result += `${ childEnv.indent + renderExpr(tc.indexes[idxName], childEnv) };\n`;
|
|
542
541
|
}
|
|
543
542
|
}
|
|
544
543
|
// Fuzzy search indices
|
|
@@ -547,13 +546,13 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
547
546
|
// FIXME: Should we allow multiple fuzzy search indices on the same column at all?
|
|
548
547
|
// And if not, why do we wrap this into an array?
|
|
549
548
|
for (const index of tc.fzindexes[columnName])
|
|
550
|
-
result += `${childEnv.indent + renderExpr(fixFuzzyIndex(index, columnName), childEnv)};\n`;
|
|
549
|
+
result += `${ childEnv.indent + renderExpr(fixFuzzyIndex(index, columnName), childEnv) };\n`;
|
|
551
550
|
}
|
|
552
551
|
else {
|
|
553
|
-
result += `${childEnv.indent + renderExpr(fixFuzzyIndex(tc.fzindexes[columnName], columnName), childEnv)};\n`;
|
|
552
|
+
result += `${ childEnv.indent + renderExpr(fixFuzzyIndex(tc.fzindexes[columnName], columnName), childEnv) };\n`;
|
|
554
553
|
}
|
|
555
554
|
}
|
|
556
|
-
result += `${env.indent}}`;
|
|
555
|
+
result += `${ env.indent }}`;
|
|
557
556
|
return result;
|
|
558
557
|
|
|
559
558
|
|
|
@@ -599,7 +598,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
599
598
|
duplicateChecker.addElement(quotedElementName, env.path, elementName);
|
|
600
599
|
|
|
601
600
|
if (hasHanaComment(elm, options))
|
|
602
|
-
result += `${env.indent}@Comment: '${getEscapedHanaComment(elm)}'\n`;
|
|
601
|
+
result += `${ env.indent }@Comment: '${ getEscapedHanaComment(elm) }'\n`;
|
|
603
602
|
|
|
604
603
|
result += env.indent + (elm.key && !isSubElement ? 'key ' : '') +
|
|
605
604
|
(elm.masked ? 'masked ' : '') +
|
|
@@ -610,7 +609,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
610
609
|
if (!elm.value?.stored) {
|
|
611
610
|
result += renderNullability(elm);
|
|
612
611
|
if (elm.default && !elm.target)
|
|
613
|
-
result += ` default ${renderExpr(elm.default, env.withSubPath([ 'default' ]))}`;
|
|
612
|
+
result += ` default ${ renderExpr(elm.default, env.withSubPath([ 'default' ])) }`;
|
|
614
613
|
}
|
|
615
614
|
|
|
616
615
|
// (table) elements can only have a @sql.append
|
|
@@ -619,7 +618,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
619
618
|
if (back)
|
|
620
619
|
result += back;
|
|
621
620
|
|
|
622
|
-
return `${result};\n`;
|
|
621
|
+
return `${ result };\n`;
|
|
623
622
|
}
|
|
624
623
|
|
|
625
624
|
/**
|
|
@@ -634,20 +633,20 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
634
633
|
function renderViewSource( source, env ) {
|
|
635
634
|
// Sub-SELECT
|
|
636
635
|
if (source.SELECT || source.SET) {
|
|
637
|
-
let result = `(${renderQuery(source, false, env.withIncreasedIndent())})`;
|
|
636
|
+
let result = `(${ renderQuery(source, false, env.withIncreasedIndent()) })`;
|
|
638
637
|
if (source.as)
|
|
639
|
-
result += ` as ${formatIdentifier(source.as)}`;
|
|
638
|
+
result += ` as ${ formatIdentifier(source.as) }`;
|
|
640
639
|
return result;
|
|
641
640
|
}
|
|
642
641
|
// JOIN
|
|
643
642
|
else if (source.join) {
|
|
644
643
|
// One join operation, possibly with ON-condition
|
|
645
|
-
let result = `${renderViewSource(source.args[0], env.withSubPath([ 'args', 0 ]))}`;
|
|
644
|
+
let result = `${ renderViewSource(source.args[0], env.withSubPath([ 'args', 0 ])) }`;
|
|
646
645
|
for (let i = 1; i < source.args.length; i++) {
|
|
647
|
-
result = `(${result} ${source.join} `;
|
|
648
|
-
result += `join ${renderViewSource(source.args[i], env.withSubPath([ 'args', i ]))}`;
|
|
646
|
+
result = `(${ result } ${ source.join } `;
|
|
647
|
+
result += `join ${ renderViewSource(source.args[i], env.withSubPath([ 'args', i ])) }`;
|
|
649
648
|
if (source.on)
|
|
650
|
-
result += ` on ${renderExpr(source.on, env.withSubPath([ 'on' ]))}`;
|
|
649
|
+
result += ` on ${ renderExpr(source.on, env.withSubPath([ 'on' ])) }`;
|
|
651
650
|
|
|
652
651
|
result += ')';
|
|
653
652
|
}
|
|
@@ -670,7 +669,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
670
669
|
function renderAbsolutePath( path, env ) {
|
|
671
670
|
// Sanity checks
|
|
672
671
|
if (!path.ref)
|
|
673
|
-
throw new ModelError(`Expecting ref in path: ${JSON.stringify(path)}`);
|
|
672
|
+
throw new ModelError(`Expecting ref in path: ${ JSON.stringify(path) }`);
|
|
674
673
|
|
|
675
674
|
|
|
676
675
|
// Determine the absolute name of the first artifact on the path (before any associations or element traversals)
|
|
@@ -685,16 +684,16 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
685
684
|
|
|
686
685
|
// Even the first step might have parameters and/or a filter
|
|
687
686
|
if (path.ref[0].args)
|
|
688
|
-
result += `(${renderArgs(path.ref[0], ':', env.withSubPath([ 'ref', 0 ]))})`;
|
|
687
|
+
result += `(${ renderArgs(path.ref[0], ':', env.withSubPath([ 'ref', 0 ])) })`;
|
|
689
688
|
|
|
690
689
|
if (path.ref[0].where) {
|
|
691
|
-
const cardinality = path.ref[0].cardinality ? (`${path.ref[0].cardinality.max}: `) : '';
|
|
692
|
-
result += `[${cardinality}${renderExpr(path.ref[0].where, env.withSubPath([ 'ref', 0, 'where' ]))}]`;
|
|
690
|
+
const cardinality = path.ref[0].cardinality ? (`${ path.ref[0].cardinality.max }: `) : '';
|
|
691
|
+
result += `[${ cardinality }${ renderExpr(path.ref[0].where, env.withSubPath([ 'ref', 0, 'where' ])) }]`;
|
|
693
692
|
}
|
|
694
693
|
|
|
695
694
|
// Add any path steps (possibly with parameters and filters) that may follow after that
|
|
696
695
|
if (path.ref.length > 1)
|
|
697
|
-
result += `.${renderTypeRef({ ref: path.ref.slice(1) }, env)}`;
|
|
696
|
+
result += `.${ renderTypeRef({ ref: path.ref.slice(1) }, env) }`;
|
|
698
697
|
|
|
699
698
|
return result;
|
|
700
699
|
}
|
|
@@ -716,11 +715,11 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
716
715
|
const implicitAlias = path.ref.length === 0 ? getLastPartOf(getResultingName(csn, options.sqlMapping, path.ref[0])) : getLastPartOfRef(path.ref);
|
|
717
716
|
if (path.as) {
|
|
718
717
|
// Source had an alias - render it
|
|
719
|
-
result += ` as ${formatIdentifier(path.as)}`;
|
|
718
|
+
result += ` as ${ formatIdentifier(path.as) }`;
|
|
720
719
|
}
|
|
721
720
|
else if (getLastPartOf(result) !== formatIdentifier(implicitAlias)) {
|
|
722
721
|
// Render an artificial alias if the result would produce a different one
|
|
723
|
-
result += ` as ${formatIdentifier(implicitAlias)}`;
|
|
722
|
+
result += ` as ${ formatIdentifier(implicitAlias) }`;
|
|
724
723
|
}
|
|
725
724
|
return result;
|
|
726
725
|
}
|
|
@@ -742,10 +741,9 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
742
741
|
// Render 'null as <alias>' only for database and if element is virtual
|
|
743
742
|
if (element?.virtual) {
|
|
744
743
|
if (isDeprecatedEnabled(options, '_renderVirtualElements'))
|
|
745
|
-
return `${env.indent}null as ${formatIdentifier(leaf)}`;
|
|
744
|
+
return `${ env.indent }null as ${ formatIdentifier(leaf) }`;
|
|
746
745
|
return '';
|
|
747
746
|
}
|
|
748
|
-
|
|
749
747
|
return renderNonVirtualColumn();
|
|
750
748
|
|
|
751
749
|
|
|
@@ -769,15 +767,15 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
769
767
|
alias = leaf;
|
|
770
768
|
|
|
771
769
|
if (alias)
|
|
772
|
-
result += ` as ${formatIdentifier(alias)}`;
|
|
770
|
+
result += ` as ${ formatIdentifier(alias) }`;
|
|
773
771
|
|
|
774
772
|
// Explicit type provided for the view element?
|
|
775
773
|
if (col.cast?.target) {
|
|
776
774
|
// Special case: Explicit association type is actually a redirect
|
|
777
775
|
// Redirections are never flattened (don't exist in HANA)
|
|
778
|
-
result += ` : redirected to ${renderAbsoluteNameWithQuotes(col.cast.target, env.withSubPath([ 'cast', 'target' ]))}`;
|
|
776
|
+
result += ` : redirected to ${ renderAbsoluteNameWithQuotes(col.cast.target, env.withSubPath([ 'cast', 'target' ])) }`;
|
|
779
777
|
if (col.cast.on)
|
|
780
|
-
result += ` on ${renderExpr(col.cast.on, env.withSubPath([ 'cast', 'on' ]))}`;
|
|
778
|
+
result += ` on ${ renderExpr(col.cast.on, env.withSubPath([ 'cast', 'on' ])) }`;
|
|
781
779
|
}
|
|
782
780
|
|
|
783
781
|
return result;
|
|
@@ -800,16 +798,16 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
800
798
|
globalDuplicateChecker.addArtifact(art['@cds.persistence.name'], artifactPath, artifactName);
|
|
801
799
|
|
|
802
800
|
if (hasHanaComment(art, options))
|
|
803
|
-
result += `${env.indent}@Comment: '${getEscapedHanaComment(art)}'\n`;
|
|
801
|
+
result += `${ env.indent }@Comment: '${ getEscapedHanaComment(art) }'\n`;
|
|
804
802
|
|
|
805
|
-
result += `${env.indent}${art.abstract ? 'abstract ' : ''}view ${renderArtifactName(artifactName, env)}`;
|
|
803
|
+
result += `${ env.indent }${ art.abstract ? 'abstract ' : '' }view ${ renderArtifactName(artifactName, env) }`;
|
|
806
804
|
if (art.params) {
|
|
807
805
|
const childEnv = env.withIncreasedIndent();
|
|
808
806
|
const parameters = Object.keys(art.params)
|
|
809
807
|
.map(name => renderParameter(name, art.params[name], childEnv.withSubPath([ 'params', name ])))
|
|
810
808
|
.join(',\n');
|
|
811
809
|
// SAP HANA only understands the 'with parameters' syntax'
|
|
812
|
-
result += ` with parameters\n${parameters}\n${env.indent}as `;
|
|
810
|
+
result += ` with parameters\n${ parameters }\n${ env.indent }as `;
|
|
813
811
|
}
|
|
814
812
|
else {
|
|
815
813
|
result += ' as ';
|
|
@@ -846,34 +844,34 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
846
844
|
// Set operator, like UNION, INTERSECT, ...
|
|
847
845
|
if (query.SET) {
|
|
848
846
|
// First arg may be leading query
|
|
849
|
-
result += `(${renderQuery(query.SET.args[0], isLeadingQuery, env.withSubPath([ 'SET', 'args', 0 ]), elements || query.SET.elements)}`;
|
|
847
|
+
result += `(${ renderQuery(query.SET.args[0], isLeadingQuery, env.withSubPath([ 'SET', 'args', 0 ]), elements || query.SET.elements) }`;
|
|
850
848
|
// FIXME: Clarify if set operators can be n-ary (assuming binary here)
|
|
851
849
|
if (query.SET.op) {
|
|
852
850
|
// Loop over all other arguments, i.e. for A UNION B UNION C UNION D ...
|
|
853
851
|
for (let i = 1; i < query.SET.args.length; i++)
|
|
854
|
-
result += `\n${env.indent}${query.SET.op}${query.SET.all ? ' all' : ''} ${renderQuery(query.SET.args[i], false, env.withSubPath([ 'SET', 'args', i ]), elements || query.SET.elements)}`;
|
|
852
|
+
result += `\n${ env.indent }${ query.SET.op }${ query.SET.all ? ' all' : '' } ${ renderQuery(query.SET.args[i], false, env.withSubPath([ 'SET', 'args', i ]), elements || query.SET.elements) }`;
|
|
855
853
|
}
|
|
856
854
|
result += ')';
|
|
857
855
|
// Set operation may also have an ORDER BY and LIMIT/OFFSET (in contrast to the ones belonging to
|
|
858
856
|
// each SELECT)
|
|
859
857
|
if (query.SET.orderBy)
|
|
860
|
-
result += `${continueIndent(result, env)}order by ${query.SET.orderBy.map((entry, i) => renderOrderByEntry(entry, env.withSubPath([ 'SET', 'orderBy', i ]))).join(', ')}`;
|
|
858
|
+
result += `${ continueIndent(result, env) }order by ${ query.SET.orderBy.map((entry, i) => renderOrderByEntry(entry, env.withSubPath([ 'SET', 'orderBy', i ]))).join(', ') }`;
|
|
861
859
|
|
|
862
860
|
if (query.SET.limit)
|
|
863
|
-
result += `${continueIndent(result, env)}${renderLimit(query.SET.limit, env.withSubPath([ 'SET', 'limit' ]))}`;
|
|
861
|
+
result += `${ continueIndent(result, env) }${ renderLimit(query.SET.limit, env.withSubPath([ 'SET', 'limit' ])) }`;
|
|
864
862
|
|
|
865
863
|
return result;
|
|
866
864
|
}
|
|
867
865
|
// Otherwise must have a SELECT
|
|
868
866
|
else if (!query.SELECT) {
|
|
869
|
-
throw new ModelError(`Unexpected query operation ${JSON.stringify(query)} at ${JSON.stringify(env.path)}`);
|
|
867
|
+
throw new ModelError(`Unexpected query operation ${ JSON.stringify(query) } at ${ JSON.stringify(env.path) }`);
|
|
870
868
|
}
|
|
871
869
|
|
|
872
870
|
if (!isProjection)
|
|
873
871
|
env = env.withSubPath([ 'SELECT' ]);
|
|
874
872
|
|
|
875
873
|
const select = query.SELECT;
|
|
876
|
-
result += `select from ${renderViewSource(select.from, env.withSubPath([ 'from' ]))}`;
|
|
874
|
+
result += `select from ${ renderViewSource(select.from, env.withSubPath([ 'from' ])) }`;
|
|
877
875
|
|
|
878
876
|
const childEnv = env.withIncreasedIndent();
|
|
879
877
|
childEnv.currentArtifactName = $PROJECTION; // $self to be replaced by $projection
|
|
@@ -885,7 +883,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
885
883
|
if (elems) {
|
|
886
884
|
result += ' mixin {\n';
|
|
887
885
|
result += elems;
|
|
888
|
-
result += `${env.indent}} into`;
|
|
886
|
+
result += `${ env.indent }} into`;
|
|
889
887
|
}
|
|
890
888
|
}
|
|
891
889
|
result += select.distinct ? ' distinct' : '';
|
|
@@ -895,12 +893,12 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
895
893
|
.map((col, i) => renderViewColumn(col, elements || select.elements, childEnv.withSubPath([ 'columns', i ])))
|
|
896
894
|
.filter(s => s !== '')
|
|
897
895
|
.join(',\n');
|
|
898
|
-
result += `\n${env.indent}}`;
|
|
896
|
+
result += `\n${ env.indent }}`;
|
|
899
897
|
}
|
|
900
898
|
if (select.excluding) {
|
|
901
|
-
const excludingList = select.excluding.map(id => `${childEnv.indent}${formatIdentifier(id)}`).join(',\n');
|
|
902
|
-
result += ` excluding {\n${excludingList}\n`;
|
|
903
|
-
result += `${env.indent}}`;
|
|
899
|
+
const excludingList = select.excluding.map(id => `${ childEnv.indent }${ formatIdentifier(id) }`).join(',\n');
|
|
900
|
+
result += ` excluding {\n${ excludingList }\n`;
|
|
901
|
+
result += `${ env.indent }}`;
|
|
904
902
|
}
|
|
905
903
|
|
|
906
904
|
return renderSelectProperties(select, result, env);
|
|
@@ -916,19 +914,19 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
916
914
|
*/
|
|
917
915
|
function renderSelectProperties( select, alreadyRendered, env ) {
|
|
918
916
|
if (select.where)
|
|
919
|
-
alreadyRendered += `${continueIndent(alreadyRendered, env)}where ${renderExpr(select.where, env.withSubPath([ 'where' ]))}`;
|
|
917
|
+
alreadyRendered += `${ continueIndent(alreadyRendered, env) }where ${ renderExpr(select.where, env.withSubPath([ 'where' ])) }`;
|
|
920
918
|
|
|
921
919
|
if (select.groupBy)
|
|
922
|
-
alreadyRendered += `${continueIndent(alreadyRendered, env)}group by ${select.groupBy.map((expr, i) => renderExpr(expr, env.withSubPath([ 'groupBy', i ]))).join(', ')}`;
|
|
920
|
+
alreadyRendered += `${ continueIndent(alreadyRendered, env) }group by ${ select.groupBy.map((expr, i) => renderExpr(expr, env.withSubPath([ 'groupBy', i ]))).join(', ') }`;
|
|
923
921
|
|
|
924
922
|
if (select.having)
|
|
925
|
-
alreadyRendered += `${continueIndent(alreadyRendered, env)}having ${renderExpr(select.having, env.withSubPath([ 'having' ]))}`;
|
|
923
|
+
alreadyRendered += `${ continueIndent(alreadyRendered, env) }having ${ renderExpr(select.having, env.withSubPath([ 'having' ])) }`;
|
|
926
924
|
|
|
927
925
|
if (select.orderBy)
|
|
928
|
-
alreadyRendered += `${continueIndent(alreadyRendered, env)}order by ${select.orderBy.map((entry, i) => renderOrderByEntry(entry, env.withSubPath([ 'orderBy', i ]))).join(', ')}`;
|
|
926
|
+
alreadyRendered += `${ continueIndent(alreadyRendered, env) }order by ${ select.orderBy.map((entry, i) => renderOrderByEntry(entry, env.withSubPath([ 'orderBy', i ]))).join(', ') }`;
|
|
929
927
|
|
|
930
928
|
if (select.limit)
|
|
931
|
-
alreadyRendered += `${continueIndent(alreadyRendered, env)}${renderLimit(select.limit, env.withSubPath([ 'limit' ]))}`;
|
|
929
|
+
alreadyRendered += `${ continueIndent(alreadyRendered, env) }${ renderLimit(select.limit, env.withSubPath([ 'limit' ])) }`;
|
|
932
930
|
|
|
933
931
|
return alreadyRendered;
|
|
934
932
|
}
|
|
@@ -946,7 +944,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
946
944
|
return ' ';
|
|
947
945
|
}
|
|
948
946
|
// Otherwise, start new line and indent normally
|
|
949
|
-
return `\n${env.withIncreasedIndent().indent}`;
|
|
947
|
+
return `\n${ env.withIncreasedIndent().indent }`;
|
|
950
948
|
}
|
|
951
949
|
|
|
952
950
|
/**
|
|
@@ -959,11 +957,11 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
959
957
|
function renderLimit( limit, env ) {
|
|
960
958
|
let result = '';
|
|
961
959
|
if (limit.rows !== undefined)
|
|
962
|
-
result += `limit ${renderExpr(limit.rows, env.withSubPath([ 'rows' ]))}`;
|
|
960
|
+
result += `limit ${ renderExpr(limit.rows, env.withSubPath([ 'rows' ])) }`;
|
|
963
961
|
|
|
964
962
|
if (limit.offset !== undefined) {
|
|
965
|
-
const indent = result !== '' ? `\n${env.withIncreasedIndent().indent}` : '';
|
|
966
|
-
result += `${indent}offset ${renderExpr(limit.offset, env.withSubPath([ 'offset' ]))}`;
|
|
963
|
+
const indent = result !== '' ? `\n${ env.withIncreasedIndent().indent }` : '';
|
|
964
|
+
result += `${ indent }offset ${ renderExpr(limit.offset, env.withSubPath([ 'offset' ])) }`;
|
|
967
965
|
}
|
|
968
966
|
|
|
969
967
|
return result;
|
|
@@ -980,10 +978,10 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
980
978
|
function renderOrderByEntry( entry, env ) {
|
|
981
979
|
let result = renderExpr(entry, env);
|
|
982
980
|
if (entry.sort)
|
|
983
|
-
result += ` ${entry.sort}`;
|
|
981
|
+
result += ` ${ entry.sort }`;
|
|
984
982
|
|
|
985
983
|
if (entry.nulls)
|
|
986
|
-
result += ` nulls ${entry.nulls}`;
|
|
984
|
+
result += ` nulls ${ entry.nulls }`;
|
|
987
985
|
|
|
988
986
|
return result;
|
|
989
987
|
}
|
|
@@ -999,7 +997,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
999
997
|
function renderParameter( parName, par, env ) {
|
|
1000
998
|
if (par.notNull === true || par.notNull === false)
|
|
1001
999
|
info('query-ignoring-param-nullability', env.path, { '#': 'std' });
|
|
1002
|
-
return `${env.indent + formatParamIdentifier(parName, env.path)} : ${renderTypeReference(par, env)}`;
|
|
1000
|
+
return `${ env.indent + formatParamIdentifier(parName, env.path) } : ${ renderTypeReference(par, env) }`;
|
|
1003
1001
|
}
|
|
1004
1002
|
|
|
1005
1003
|
/**
|
|
@@ -1015,10 +1013,10 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1015
1013
|
if (art.kind === 'aspect' || art.kind === 'type' && !hdbcdsNames || art.kind === 'type' && hdbcdsNames && !art.elements)
|
|
1016
1014
|
return '';
|
|
1017
1015
|
let result = '';
|
|
1018
|
-
result += `${env.indent + (art.kind)} ${renderArtifactName(artifactName, env, true)}`;
|
|
1016
|
+
result += `${ env.indent + (art.kind) } ${ renderArtifactName(artifactName, env, true) }`;
|
|
1019
1017
|
if (art.includes) {
|
|
1020
1018
|
// Includes are never flattened (don't exist in HANA)
|
|
1021
|
-
result += ` : ${art.includes.map(name => renderAbsoluteNameWithQuotes(name, env)).join(', ')}`;
|
|
1019
|
+
result += ` : ${ art.includes.map(name => renderAbsoluteNameWithQuotes(name, env)).join(', ') }`;
|
|
1022
1020
|
}
|
|
1023
1021
|
if (art.elements && !art.type) {
|
|
1024
1022
|
const childEnv = env.withIncreasedIndent();
|
|
@@ -1027,11 +1025,11 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1027
1025
|
for (const name in art.elements)
|
|
1028
1026
|
result += renderElement(name, art.elements[name], childEnv.withSubPath([ 'elements', name ]));
|
|
1029
1027
|
|
|
1030
|
-
result += `${env.indent}};\n`;
|
|
1028
|
+
result += `${ env.indent }};\n`;
|
|
1031
1029
|
}
|
|
1032
1030
|
else {
|
|
1033
1031
|
// Derived type or annotation with non-anonymous type
|
|
1034
|
-
result += ` : ${renderTypeReference(art, env)};\n`;
|
|
1032
|
+
result += ` : ${ renderTypeReference(art, env) };\n`;
|
|
1035
1033
|
}
|
|
1036
1034
|
return result;
|
|
1037
1035
|
}
|
|
@@ -1050,7 +1048,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1050
1048
|
// Array type: Render items instead
|
|
1051
1049
|
if (elm.items && !elm.type) {
|
|
1052
1050
|
// HANA CDS does not support keyword many
|
|
1053
|
-
let rc = `array of ${renderTypeReference(elm.items, env.withSubPath([ 'items' ]))}`;
|
|
1051
|
+
let rc = `array of ${ renderTypeReference(elm.items, env.withSubPath([ 'items' ])) }`;
|
|
1054
1052
|
if (elm.items.notNull != null)
|
|
1055
1053
|
rc += elm.items.notNull ? ' not null' : ' null';
|
|
1056
1054
|
return rc;
|
|
@@ -1062,7 +1060,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1062
1060
|
// Anonymous structured type
|
|
1063
1061
|
if (!elm.type && !elm.value) {
|
|
1064
1062
|
if (!elm.elements)
|
|
1065
|
-
throw new ModelError(`Missing type of: ${JSON.stringify(elm)}`);
|
|
1063
|
+
throw new ModelError(`Missing type of: ${ JSON.stringify(elm) }`);
|
|
1066
1064
|
|
|
1067
1065
|
result += '{\n';
|
|
1068
1066
|
const childEnv = env.withIncreasedIndent();
|
|
@@ -1071,7 +1069,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1071
1069
|
for (const name in elm.elements)
|
|
1072
1070
|
result += renderElement(name, elm.elements[name], childEnv.withSubPath([ 'elements', name ]), null, dontRenderKeyForNestedElement);
|
|
1073
1071
|
|
|
1074
|
-
result += `${env.indent}}`;
|
|
1072
|
+
result += `${ env.indent }}`;
|
|
1075
1073
|
return result;
|
|
1076
1074
|
}
|
|
1077
1075
|
|
|
@@ -1082,7 +1080,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1082
1080
|
if (elm.type?.ref) {
|
|
1083
1081
|
// Reference to another element
|
|
1084
1082
|
// For HANA CDS, we need a 'type of'
|
|
1085
|
-
result += `type of ${renderAbsolutePath(elm.type, env.withSubPath([ 'type' ]))}`;
|
|
1083
|
+
result += `type of ${ renderAbsolutePath(elm.type, env.withSubPath([ 'type' ])) }`;
|
|
1086
1084
|
}
|
|
1087
1085
|
else if (isBuiltinType(elm.type)) {
|
|
1088
1086
|
// If we get here, it must be a named type
|
|
@@ -1098,7 +1096,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1098
1096
|
if (!elm.value.stored)
|
|
1099
1097
|
throw new CompilerAssertion('Found calculated element on-read in rendering; should have been replaced!');
|
|
1100
1098
|
message('def-unsupported-calc-elem', env.path, { '#': 'hdbcds' });
|
|
1101
|
-
result += ` GENERATED ALWAYS AS ${renderExpr(elm.value, env.withSubPath([ 'value' ]))}`;
|
|
1099
|
+
result += ` GENERATED ALWAYS AS ${ renderExpr(elm.value, env.withSubPath([ 'value' ])) }`;
|
|
1102
1100
|
return result;
|
|
1103
1101
|
}
|
|
1104
1102
|
|
|
@@ -1112,7 +1110,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1112
1110
|
*/
|
|
1113
1111
|
function renderAssociationType( elm, env ) {
|
|
1114
1112
|
// Type, cardinality and target
|
|
1115
|
-
let result = `association${renderCardinality(elm.cardinality)} to `;
|
|
1113
|
+
let result = `association${ renderCardinality(elm.cardinality) } to `;
|
|
1116
1114
|
|
|
1117
1115
|
// normal target or named aspect
|
|
1118
1116
|
if (elm.target || elm.targetAspect && typeof elm.targetAspect === 'string') {
|
|
@@ -1131,7 +1129,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1131
1129
|
|
|
1132
1130
|
// ON-condition (if any)
|
|
1133
1131
|
if (elm.on) {
|
|
1134
|
-
result += ` on ${renderExpr(elm.on, env.withSubPath([ 'on' ]))}`;
|
|
1132
|
+
result += ` on ${ renderExpr(elm.on, env.withSubPath([ 'on' ])) }`;
|
|
1135
1133
|
}
|
|
1136
1134
|
else if (elm.targetAspect?.elements) { // anonymous aspect
|
|
1137
1135
|
const childEnv = env.withIncreasedIndent();
|
|
@@ -1139,12 +1137,12 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1139
1137
|
for (const name in elm.targetAspect.elements)
|
|
1140
1138
|
result += renderElement(name, elm.targetAspect.elements[name], childEnv.withSubPath([ 'targetAspect', 'elements', name ]));
|
|
1141
1139
|
|
|
1142
|
-
result += `${env.indent}}`;
|
|
1140
|
+
result += `${ env.indent }}`;
|
|
1143
1141
|
}
|
|
1144
1142
|
|
|
1145
1143
|
// Foreign keys (if any, unless we also have an ON_condition (which means we have been transformed from managed to unmanaged)
|
|
1146
1144
|
if (elm.keys && !elm.on)
|
|
1147
|
-
result += ` { ${Object.keys(elm.keys).map(name => renderForeignKey(elm.keys[name], env.withSubPath([ 'keys', name ]))).join(', ')} }`;
|
|
1145
|
+
result += ` { ${ Object.keys(elm.keys).map(name => renderForeignKey(elm.keys[name], env.withSubPath([ 'keys', name ]))).join(', ') } }`;
|
|
1148
1146
|
|
|
1149
1147
|
return result;
|
|
1150
1148
|
}
|
|
@@ -1203,27 +1201,27 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1203
1201
|
else if (typeof s === 'object') {
|
|
1204
1202
|
// Sanity check
|
|
1205
1203
|
if (!s.func && !s.id)
|
|
1206
|
-
throw new ModelError(`Unknown path step object: ${JSON.stringify(s)}`);
|
|
1204
|
+
throw new ModelError(`Unknown path step object: ${ JSON.stringify(s) }`);
|
|
1207
1205
|
|
|
1208
1206
|
// Not really a path step but an object-like function call
|
|
1209
1207
|
if (s.func)
|
|
1210
|
-
return `${s.func}(${renderArgs(s, '=>', env)})`;
|
|
1208
|
+
return `${ s.func }(${ renderArgs(s, '=>', env) })`;
|
|
1211
1209
|
|
|
1212
1210
|
// Path step, possibly with view parameters and/or filters
|
|
1213
|
-
let result = `${formatIdentifier(s.id)}`;
|
|
1211
|
+
let result = `${ formatIdentifier(s.id) }`;
|
|
1214
1212
|
if (s.args) {
|
|
1215
1213
|
// View parameters
|
|
1216
|
-
result += `(${renderArgs(s, ':', env)})`;
|
|
1214
|
+
result += `(${ renderArgs(s, ':', env) })`;
|
|
1217
1215
|
}
|
|
1218
1216
|
if (s.where) {
|
|
1219
1217
|
// Filter, possibly with cardinality
|
|
1220
|
-
const cardinality = s.cardinality ? `${s.cardinality.max}: ` : '';
|
|
1221
|
-
result += `[${cardinality}${renderExpr(s.where, env.withSubPath([ 'where' ]))}]`;
|
|
1218
|
+
const cardinality = s.cardinality ? `${ s.cardinality.max }: ` : '';
|
|
1219
|
+
result += `[${ cardinality }${ renderExpr(s.where, env.withSubPath([ 'where' ])) }]`;
|
|
1222
1220
|
}
|
|
1223
1221
|
return result;
|
|
1224
1222
|
}
|
|
1225
1223
|
|
|
1226
|
-
throw new ModelError(`Unknown path step: ${JSON.stringify(s)} at ${JSON.stringify(env.path)}`);
|
|
1224
|
+
throw new ModelError(`Unknown path step: ${ JSON.stringify(s) } at ${ JSON.stringify(env.path) }`);
|
|
1227
1225
|
}
|
|
1228
1226
|
|
|
1229
1227
|
/**
|
|
@@ -1241,7 +1239,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1241
1239
|
case 'date':
|
|
1242
1240
|
case 'time':
|
|
1243
1241
|
case 'timestamp':
|
|
1244
|
-
return `${x.literal}'${x.val}'`;
|
|
1242
|
+
return `${ x.literal }'${ x.val }'`;
|
|
1245
1243
|
case 'string':
|
|
1246
1244
|
return renderStringForHdbcds(x.val);
|
|
1247
1245
|
case 'object':
|
|
@@ -1250,7 +1248,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1250
1248
|
|
|
1251
1249
|
// otherwise fall through to
|
|
1252
1250
|
default:
|
|
1253
|
-
throw new ModelError(`Unknown literal or type: ${JSON.stringify(x)}`);
|
|
1251
|
+
throw new ModelError(`Unknown literal or type: ${ JSON.stringify(x) }`);
|
|
1254
1252
|
}
|
|
1255
1253
|
}
|
|
1256
1254
|
|
|
@@ -1317,13 +1315,13 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1317
1315
|
|
|
1318
1316
|
const prefix = x.param ? ':' : '';
|
|
1319
1317
|
const ref = x.ref.map((step, index) => renderPathStep(step, index, this.env.withSubPath([ 'ref', index ]))).join('.');
|
|
1320
|
-
return `${prefix}${ref}`;
|
|
1318
|
+
return `${ prefix }${ ref }`;
|
|
1321
1319
|
}
|
|
1322
1320
|
|
|
1323
1321
|
function renderTypeRef( x, env ) {
|
|
1324
1322
|
const prefix = x.param ? ':' : '';
|
|
1325
1323
|
const ref = x.ref.map((step, index) => renderPathStep(step, index, env.withSubPath([ 'ref', index ]))).join('.');
|
|
1326
|
-
return `${prefix}${ref}`;
|
|
1324
|
+
return `${ prefix }${ ref }`;
|
|
1327
1325
|
}
|
|
1328
1326
|
|
|
1329
1327
|
/**
|
|
@@ -1345,12 +1343,12 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1345
1343
|
else if (typeof args === 'object') {
|
|
1346
1344
|
// if this is a function param which is not a reference to the model, we must not quote it
|
|
1347
1345
|
return Object.keys(args)
|
|
1348
|
-
.map(key => `${node.func ? key : formatIdentifier(key)} ${sep} ${renderExpr(args[key], env.withSubPath([ 'args', key ]))}`)
|
|
1346
|
+
.map(key => `${ node.func ? key : formatIdentifier(key) } ${ sep } ${ renderExpr(args[key], env.withSubPath([ 'args', key ])) }`)
|
|
1349
1347
|
.join(', ');
|
|
1350
1348
|
}
|
|
1351
1349
|
|
|
1352
1350
|
|
|
1353
|
-
throw new ModelError(`Unknown args: ${JSON.stringify(args)}`);
|
|
1351
|
+
throw new ModelError(`Unknown args: ${ JSON.stringify(args) }`);
|
|
1354
1352
|
}
|
|
1355
1353
|
|
|
1356
1354
|
/**
|
|
@@ -1365,15 +1363,15 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1365
1363
|
|
|
1366
1364
|
let result = '[';
|
|
1367
1365
|
if (card.src !== undefined)
|
|
1368
|
-
result += `${card.src}, `;
|
|
1366
|
+
result += `${ card.src }, `;
|
|
1369
1367
|
|
|
1370
1368
|
if (card.min !== undefined)
|
|
1371
|
-
result += `${card.min}..`;
|
|
1369
|
+
result += `${ card.min }..`;
|
|
1372
1370
|
|
|
1373
1371
|
if (card.max !== undefined)
|
|
1374
1372
|
result += card.max;
|
|
1375
1373
|
|
|
1376
|
-
return `${result}]`;
|
|
1374
|
+
return `${ result }]`;
|
|
1377
1375
|
}
|
|
1378
1376
|
|
|
1379
1377
|
/**
|
|
@@ -1400,8 +1398,8 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1400
1398
|
* @returns {string} Rendered foreign key
|
|
1401
1399
|
*/
|
|
1402
1400
|
function renderForeignKey( fKey, env ) {
|
|
1403
|
-
const alias = fKey.as ? (` as ${formatIdentifier(fKey.as)}`) : '';
|
|
1404
|
-
return `${renderExpr(fKey, env)}${alias}`;
|
|
1401
|
+
const alias = fKey.as ? (` as ${ formatIdentifier(fKey.as) }`) : '';
|
|
1402
|
+
return `${ renderExpr(fKey, env) }${ alias }`;
|
|
1405
1403
|
}
|
|
1406
1404
|
|
|
1407
1405
|
/**
|
|
@@ -1426,7 +1424,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1426
1424
|
if (elm.srid !== undefined)
|
|
1427
1425
|
params.push(elm.srid);
|
|
1428
1426
|
|
|
1429
|
-
return params.length === 0 ? '' : `(${params.join(', ')})`;
|
|
1427
|
+
return params.length === 0 ? '' : `(${ params.join(', ') })`;
|
|
1430
1428
|
}
|
|
1431
1429
|
|
|
1432
1430
|
/**
|
|
@@ -1471,7 +1469,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1471
1469
|
|
|
1472
1470
|
// Another special case: If we are rendering for HANA, and if the first path step is an artifact that is
|
|
1473
1471
|
// 'implemented in' something, we need to treat the whole name like a top-level id.
|
|
1474
|
-
if (csn.definitions[absName]
|
|
1472
|
+
if (csn.definitions[absName]?.['@cds.persistence.exists']) {
|
|
1475
1473
|
env.topLevelAliases[absName] = {
|
|
1476
1474
|
quotedName: quoteAbsoluteNameAsId(absName),
|
|
1477
1475
|
quotedAlias: quoteId(createTopLevelAliasName(absName)),
|
|
@@ -1499,11 +1497,11 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1499
1497
|
const prefix = absName.slice(0, absName.length - realName.length);
|
|
1500
1498
|
const nonTopLevelPrefix = prefix.slice(topLevelName.length + 1, -1); // also trim off .
|
|
1501
1499
|
if (nonTopLevelPrefix)
|
|
1502
|
-
return `${topLevelAlias.quotedAlias}.${quotePathString(nonTopLevelPrefix)}.${quotePathString(realName)}`;
|
|
1500
|
+
return `${ topLevelAlias.quotedAlias }.${ quotePathString(nonTopLevelPrefix) }.${ quotePathString(realName) }`;
|
|
1503
1501
|
|
|
1504
|
-
return `${topLevelAlias.quotedAlias}.${quotePathString(realName)}`;
|
|
1502
|
+
return `${ topLevelAlias.quotedAlias }.${ quotePathString(realName) }`;
|
|
1505
1503
|
}
|
|
1506
|
-
return `${topLevelAlias.quotedAlias}.${quotePathString(realName)}`;
|
|
1504
|
+
return `${ topLevelAlias.quotedAlias }.${ quotePathString(realName) }`;
|
|
1507
1505
|
}
|
|
1508
1506
|
|
|
1509
1507
|
/**
|
|
@@ -1516,7 +1514,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1516
1514
|
*/
|
|
1517
1515
|
function createTopLevelAliasName( topLevelName ) {
|
|
1518
1516
|
// FIXME: We should rather check for conflicts than just using something obscure like this ...
|
|
1519
|
-
return `__${topLevelName.replace(/::/g, '__').replace(/\./g, '_')}`;
|
|
1517
|
+
return `__${ topLevelName.replace(/::/g, '__').replace(/\./g, '_') }`;
|
|
1520
1518
|
}
|
|
1521
1519
|
|
|
1522
1520
|
/**
|
|
@@ -1531,10 +1529,10 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1531
1529
|
Object.keys(env.topLevelAliases)
|
|
1532
1530
|
.filter(name => env.topLevelAliases[name].quotedAlias !== formatIdentifier(uppercaseAndUnderscore(artifactName))) // avoid "using FOO as FOO" in FOO.cds
|
|
1533
1531
|
.forEach((name) => {
|
|
1534
|
-
const nativeObjectExists = csn.definitions[name]
|
|
1532
|
+
const nativeObjectExists = csn.definitions[name]?.['@cds.persistence.exists'];
|
|
1535
1533
|
if (!plainNames && nativeObjectExists)
|
|
1536
1534
|
checkForNameClashesWithNativeObject(name);
|
|
1537
|
-
distinct[`using ${env.topLevelAliases[name].quotedName} as ${env.topLevelAliases[name].quotedAlias};\n`] = '';
|
|
1535
|
+
distinct[`using ${ env.topLevelAliases[name].quotedName } as ${ env.topLevelAliases[name].quotedAlias };\n`] = '';
|
|
1538
1536
|
});
|
|
1539
1537
|
/**
|
|
1540
1538
|
* If we generate a `using <native object> from <bar>` clause,
|
|
@@ -1560,7 +1558,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1560
1558
|
return isContextRendered(artName);
|
|
1561
1559
|
if ([ 'action', 'function', 'event' ].includes(art.kind) || options.sqlMapping !== 'hdbcds' && art.kind === 'type')
|
|
1562
1560
|
return false;
|
|
1563
|
-
return !(
|
|
1561
|
+
return !(art['@cds.persistence.exists'] || hasPersistenceSkipAnnotation(art));
|
|
1564
1562
|
}
|
|
1565
1563
|
|
|
1566
1564
|
/**
|
|
@@ -1575,7 +1573,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1575
1573
|
const subArtifacts = getSubArtifacts(contextName);
|
|
1576
1574
|
return Object.entries(subArtifacts).some(([ artName, art ]) => {
|
|
1577
1575
|
if (art.kind === 'context')
|
|
1578
|
-
return isContextRendered(`${contextName}.${artName}`);
|
|
1576
|
+
return isContextRendered(`${ contextName }.${ artName }`);
|
|
1579
1577
|
return isArtifactRendered(art, artName);
|
|
1580
1578
|
});
|
|
1581
1579
|
}
|
|
@@ -1591,7 +1589,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1591
1589
|
usingName = usingName.replace(/"/g, '');
|
|
1592
1590
|
if (usingName.indexOf('::') !== -1) {
|
|
1593
1591
|
const parts = usingName.split('::');
|
|
1594
|
-
return `${parts[0]}.${parts[1].split('.')[0]}`;
|
|
1592
|
+
return `${ parts[0] }.${ parts[1].split('.')[0] }`;
|
|
1595
1593
|
}
|
|
1596
1594
|
return usingName.split('.')[0];
|
|
1597
1595
|
}
|
|
@@ -1617,7 +1615,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1617
1615
|
// The top-level artifact's parent would be the namespace (if any)
|
|
1618
1616
|
const namespace = getNamespace(csn, topLevelName);
|
|
1619
1617
|
if (namespace)
|
|
1620
|
-
return `${env.indent}namespace ${quotePathString(namespace)};\n`;
|
|
1618
|
+
return `${ env.indent }namespace ${ quotePathString(namespace) };\n`;
|
|
1621
1619
|
|
|
1622
1620
|
return '';
|
|
1623
1621
|
}
|
|
@@ -1666,7 +1664,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1666
1664
|
* @returns {HdbcdsRenderEnvironment} New environment with added prefix
|
|
1667
1665
|
*/
|
|
1668
1666
|
function addNamePrefix( env, id ) {
|
|
1669
|
-
return env.cloneWith({ namePrefix: `${env.namePrefix + quoteId(id)}.` });
|
|
1667
|
+
return env.cloneWith({ namePrefix: `${ env.namePrefix + quoteId(id) }.` });
|
|
1670
1668
|
}
|
|
1671
1669
|
|
|
1672
1670
|
/**
|
|
@@ -1692,7 +1690,7 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1692
1690
|
const resultingName = getResultingName(csn, options.sqlMapping, absPath);
|
|
1693
1691
|
|
|
1694
1692
|
if (hdbcdsNames && namespace)
|
|
1695
|
-
return `${quotePathString(namespace)}::${quotePathString(resultingName.slice(namespace.length + 2))}`;
|
|
1693
|
+
return `${ quotePathString(namespace) }::${ quotePathString(resultingName.slice(namespace.length + 2)) }`;
|
|
1696
1694
|
|
|
1697
1695
|
return quotePathString(resultingName);
|
|
1698
1696
|
}
|
|
@@ -1727,11 +1725,11 @@ function toHdbcdsSource( csn, options, messageFunctions ) {
|
|
|
1727
1725
|
if (hdbcdsNames) {
|
|
1728
1726
|
const namespace = getNamespace(csn, absName);
|
|
1729
1727
|
if (namespace) {
|
|
1730
|
-
const id = `${namespace}::${resultingName.substring(namespace.length + 2)}`;
|
|
1731
|
-
return `"${id.replace(/"/g, '""')}"`;
|
|
1728
|
+
const id = `${ namespace }::${ resultingName.substring(namespace.length + 2) }`;
|
|
1729
|
+
return `"${ id.replace(/"/g, '""') }"`;
|
|
1732
1730
|
}
|
|
1733
1731
|
}
|
|
1734
|
-
return `"${resultingName.replace(/"/g, '""')}"`;
|
|
1732
|
+
return `"${ resultingName.replace(/"/g, '""') }"`;
|
|
1735
1733
|
}
|
|
1736
1734
|
|
|
1737
1735
|
/**
|