-
Notifications
You must be signed in to change notification settings - Fork 5
wip: data federation #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 5 commits
350bbaa
a223f50
156cdd0
b16ebfc
9cf85e6
0ada422
94a40d7
f9b432a
36def81
c5b5c2f
afc2c6b
71d789c
cb71c24
57d84fb
eb95bdc
a3d549b
d2aae4f
e66fd93
451febb
662770f
9553ecf
7e915bc
8ded31b
3e59b85
e9c01d0
d36d1f0
2efbb58
96d62a3
da5959f
8bdeb03
9b0d47e
b2ce706
2e8be40
7ebc8a5
0007187
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| const model = require('../../csn.json') | ||
|
|
||
| // Remove includes as Data Sphere doesn't support them | ||
| for (const name in model.definitions) { | ||
| const def = model.definitions[name] | ||
| const includes = def.includes | ||
| if (!includes) continue | ||
| for (const include of includes) { | ||
| const i = model.definitions[include] | ||
| def.elements = { ...def.elements, ...i.elements } | ||
| } | ||
| delete def.includes | ||
| } | ||
|
|
||
| // Inline custom types to simplify managed association removal | ||
| for (const name in model.definitions) { | ||
| const def = model.definitions[name] | ||
| const elements = def.elements | ||
| if (!elements) continue | ||
| for (const col in elements) { | ||
| const element = elements[col] | ||
| const customType = model.definitions[element.type] | ||
| if (!customType) continue | ||
| elements[col] = { ...customType, kind: undefined } | ||
| } | ||
| } | ||
|
|
||
| // Remove managed association as Data Sphere doesn't support them | ||
| for (const name in model.definitions) { | ||
| const def = model.definitions[name] | ||
| const elements = def.elements | ||
| if (!elements) continue | ||
| for (const col in elements) { | ||
| const element = elements[col] | ||
|
|
||
| // Data Sphere doesn't know that value.xpr is a thing that is supposed to be supported | ||
| if (element.value && element.value.xpr) { | ||
| element.xpr = element.value.xpr | ||
| delete element.value | ||
| } | ||
| if (!(element.type in { 'cds.Association': 1, 'cds.Composition': 1 })) continue | ||
| if (!element.keys) continue | ||
| const keys = element.keys | ||
| const on = [] | ||
| let first = true | ||
| for (const k of keys) { | ||
| if (first) first = false | ||
| else on.push('and') | ||
| const foreignKey = `${col}_${k.ref[0]}` | ||
| on.push( | ||
| { ref: [col, k.ref[0]] }, | ||
| '=', | ||
| { ref: [foreignKey] }, | ||
| ) | ||
| const target = model.definitions[element.target] | ||
| elements[foreignKey] = { ...target.elements[k.ref[0]], key: element.key } | ||
| } | ||
| delete element.keys | ||
| delete element.key | ||
| element.on = on | ||
| } | ||
| } | ||
|
|
||
| // Collect all @data.product service to convert to Data Sphere annotation | ||
| const dataProductServices = [] | ||
| for (const name in model.definitions) { | ||
| const def = model.definitions[name] | ||
| if (def.kind !== 'service' || !def['@data.product']) continue | ||
| dataProductServices.push(name) | ||
| } | ||
|
|
||
| // Just keep entities as Data Sphere doesn't handle the other types | ||
| for (const name in model.definitions) { | ||
| const def = model.definitions[name] | ||
| if (def.kind === 'entity') continue | ||
| delete model.definitions[name] | ||
| } | ||
|
|
||
| // Enhance all the entities with Data Sphere annotations for compatibility | ||
| for (const name in model.definitions) { | ||
| const def = model.definitions[name] | ||
| if (def.kind !== 'entity') continue | ||
| delete def['@cds.autoexpose'] | ||
| delete def['@cds.persistence.skip'] | ||
| def['@DataWarehouse.consumption.external'] = dataProductServices.some(s => name.startsWith(s)) | ||
| def['@ObjectModel.modelingPattern'] = { '#': 'DATA_STRUCTURE' } | ||
| def['@ObjectModel.supportedCapabilities'] = [{ '#': 'DATA_STRUCTURE' }] | ||
| if (def.projection) def['@DataWarehouse.sqlEditor.query'] = `SELECT * FROM "${def.projection.from.ref[0]}"` | ||
| } | ||
|
|
||
|
|
||
|
|
||
| const fs = require('node:fs') | ||
| const path = require('node:path') | ||
|
|
||
| const dataSphereString = JSON.stringify(model, null, 2) | ||
| .replace(/\.texts"/g, '_texts"') | ||
|
|
||
| fs.writeFileSync( | ||
| path.resolve(path.dirname(require.resolve('../../csn.json')), 'datasphere.json'), | ||
| dataSphereString | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Move that to |
||
| "file_suffixes": { | ||
| "hdbrole": { | ||
| "plugin_name": "com.sap.hana.di.role" | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Move that to |
||
| "role": { | ||
| "name": "PUBLIC#", | ||
| "object_privileges": [ | ||
| { | ||
| "name": "SAP_CAPIRE_FLIGHTS_DATA_AIRLINES", | ||
| "type": "VIEW", | ||
| "privileges_with_grant_option": [ | ||
| "SELECT" | ||
| ] | ||
| }, | ||
| { | ||
| "name": "SAP_CAPIRE_FLIGHTS_DATA_AIRPORTS", | ||
| "type": "VIEW", | ||
| "privileges_with_grant_option": [ | ||
| "SELECT" | ||
| ] | ||
| }, | ||
| { | ||
| "name": "SAP_CAPIRE_FLIGHTS_DATA_COUNTRIES", | ||
| "type": "VIEW", | ||
| "privileges_with_grant_option": [ | ||
| "SELECT" | ||
| ] | ||
| }, | ||
| { | ||
| "name": "SAP_CAPIRE_FLIGHTS_DATA_COUNTRIES_TEXTS", | ||
| "type": "VIEW", | ||
| "privileges_with_grant_option": [ | ||
| "SELECT" | ||
| ] | ||
| }, | ||
| { | ||
| "name": "SAP_CAPIRE_FLIGHTS_DATA_CURRENCIES", | ||
| "type": "VIEW", | ||
| "privileges_with_grant_option": [ | ||
| "SELECT" | ||
| ] | ||
| }, | ||
| { | ||
| "name": "SAP_CAPIRE_FLIGHTS_DATA_CURRENCIES_TEXTS", | ||
| "type": "VIEW", | ||
| "privileges_with_grant_option": [ | ||
| "SELECT" | ||
| ] | ||
| }, | ||
| { | ||
| "name": "SAP_CAPIRE_FLIGHTS_DATA_FLIGHTS", | ||
| "type": "VIEW", | ||
| "privileges_with_grant_option": [ | ||
| "SELECT" | ||
| ] | ||
| }, | ||
| { | ||
| "name": "SAP_CAPIRE_FLIGHTS_DATA_LANGUAGES", | ||
| "type": "VIEW", | ||
| "privileges_with_grant_option": [ | ||
| "SELECT" | ||
| ] | ||
| }, | ||
| { | ||
| "name": "SAP_CAPIRE_FLIGHTS_DATA_LANGUAGES_TEXTS", | ||
| "type": "VIEW", | ||
| "privileges_with_grant_option": [ | ||
| "SELECT" | ||
| ] | ||
| }, | ||
| { | ||
| "name": "SAP_CAPIRE_FLIGHTS_DATA_SUPPLEMENTTYPES", | ||
| "type": "VIEW", | ||
| "privileges_with_grant_option": [ | ||
| "SELECT" | ||
| ] | ||
| }, | ||
| { | ||
| "name": "SAP_CAPIRE_FLIGHTS_DATA_SUPPLEMENTTYPES_TEXTS", | ||
| "type": "VIEW", | ||
| "privileges_with_grant_option": [ | ||
| "SELECT" | ||
| ] | ||
| }, | ||
| { | ||
| "name": "SAP_CAPIRE_FLIGHTS_DATA_SUPPLEMENTS", | ||
| "type": "VIEW", | ||
| "privileges_with_grant_option": [ | ||
| "SELECT" | ||
| ] | ||
| }, | ||
| { | ||
| "name": "SAP_CAPIRE_FLIGHTS_DATA_SUPPLEMENTS_TEXTS", | ||
| "type": "VIEW", | ||
| "privileges_with_grant_option": [ | ||
| "SELECT" | ||
| ] | ||
| } | ||
| ] | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,3 +2,6 @@ | |
| using from './srv/data-products'; | ||
| using from './srv/srv-events'; | ||
| using from './srv/workarounds'; | ||
|
|
||
| // simulate cds export | ||
| annotate sap.capire.flights.data with @cds.external; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 2b replaced by |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,7 +8,7 @@ service sap.capire.flights.data { | |
| key flight.ID, flight.{*} excluding { ID }, | ||
| key date, // preserve the flight date as a key | ||
| *, // include all other fields from my.Flights | ||
| } excluding { flight }; | ||
| } excluding { flight, date, free_seats }; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added this as the compiler was giving the following message. It was mostly added as a reminder.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, thanks for the background @BobdenOs @stewsk : I'd recommend removing these info messages or just don't display info-level messages by default (as we do in |
||
|
|
||
| // Serve Airlines, Airports, and Supplements data as is | ||
| entity Airlines as projection on my.Airlines; | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.