Movatterモバイル変換


[0]ホーム

URL:


re>≡CAP 2025 agenda is online - check it out here!
Skip to content

Appearance

Reflecting CDS Models

Find here information about reflecting parsed CDS models in CSN representation.

cds. linked (csn)

Methodcds.linked (orcds.reflect which is an alias to the same method) turns a given parsed model into an instance ofclassLinkedCSN, and all definitions within into instances ofclassLinkedDefinition, recursively.

Declaration:

tsx
function* cds.linked (csn: CSN | string)=> LinkedCSN

A typical usage is like that:

js
let csn= cds.load('some-model.cds')let linked= cds.linked(csn)// linked === csn

Instead of a already compiled CSN, you can also pass a string containing CDL source code:

js
let linked= cds.linked`  entity Books {  key ID: UUID;  title: String;  author: Association to Authors;  }  entity Authors {  key ID: UUID;  name: String;  }`

The passed in model getsmodified, and the returned linked model is actually the modified passed-in csn.

The operation isidempotent, that is, you can repeatedly invoke it on already linked models with zero overhead.

LinkedCSN

Models passed throughcds.linked become instances of this class.

. is_linked

A tag property which istrue for linked models.

. definitions

TheCSN definitions of the model, turned into an instance ofLinkedDefinitions.

. services

. entities

These are convenient shortcuts to access allservice or allentity definitions in a model.
The value is an instance ofLinkedDefinitions.

For example:

js
let m= cds.linked`  namespace my.bookshop;  entity Books {...}  entity Authors {...}  service CatalogService {    entity ListOfBooks as projection on Books {...}  }`// Object naturelet { CatalogService, AdminService }= m.serviceslet { Books, Authors }= m.entities// Array naturefor (let eachof m.entities) console.log(each.name)// Function naturelet { ListOfBooks }= m.entities ('my.bookshop.CatalogService')

In addition to the object and array natures ofLinkedDefinitions these properties also can be used as functions, which allows to optionally specify a namespace to fetch all definitions with prefixed with that. If no namespace is specified, the model's declared namespace is used, if any.

each()

tsx
function* lm.each (   filter : string | def => true/false,   defs?  : linked_definitions)

Fetches definitions matching the given filter, returning an iterator on them.

js
let m= cds.reflect (csn)for (let dof m.each('entity')) {  console.log (d.kind, d.name)}

The first argumentfilter specifies a filter to match definitions, which can be one of:

  • astring referring to akind of definition
  • afunction returningtrue orfalse

Derived kinds are supported, for example,m.each('struct') matches structs as well as entities; kind'any' matches all.

The second optional argumentdefs allows to specify the definitions to fetch in, defaults tothis.definitions.

all()

tsx
function lm.all (   filter : string | def => true/false,   defs?  : linked_definitions)

Convenience shortcut to[... model.each()], for example, the following are equivalent:

js
m.all('entity')//> using shortcut[...m.each('entity')]//> using spread operator

find()

tsx
function lm.find (   filter : string | def => true/false,   defs?  : linked_definitions)

Convenience shortcut to fetch definitions matching the given filter, returning the first match, if any. For example:

js
let service= m.find('service')

The implementation uses to.each() as follows:

js
for (let anyof m.each('service'))return any

foreach()

tsx
function lm.foreach (  filter  : def => true/false | string,  visitor : def => {},  defs?   : linked_definitions)

Calls the visitor for each definition matching the given filter.foreach iterates through the passed in defs only,forall in addition walks through all nested element definitions hierarchically.

  • filter /kind — the filter or kind used to match definitions→ see.each(x)
  • visitor — the callback function
  • defs — the definitions to fetch in, default:this.definitions

Examples:

js
// print the names of all serviceslet m= cds.reflect(csn)m.foreach ('service',s => console.log(s.name))
js
// print the names of all Associations in Books elementlet { Books }= m.entities()m.foreach ('Association',a => console.log(a.name), Books.elements)

LinkedDefinitions

All objects of a linked model containing CSN definitions are instances of this class.

For example, that applies to:

Instances ofLinkedDefinitions allow both, object-style access, as well as array-like access. For example:

js
let linked= cds.linked (model)let { Books, Authors }= linked.entities// object-likelet [ Books, Authors ]= linked.entities// array-like

Note: Orders of definitions could change, so you should always prefer object destructuring over array destructuring.

The array-like nature also allows using these shortcuts infor..of loops, of course. Which means, you can do that:

js
for (let eachof linked.definitions) console.log (each.name)

... instead of iterating definitions usingfor..in loops like that:

js
for (let eachin linked.definitions) {  let d= linked.definitions [each]  console.log (d.name)}

Each entry in an instance ofLinkedDefinitions is aLinkedDefinition.

LinkedDefinition

Allcds.linked definitions are instances of this class, or subclasses thereof. It is accessible throughcds.linked.classes.any.

. is_linked

A tag property which istrue for all linked definitions.

. name

The linked definition's fully qualified name as a non-enumerable property.

. kind

The linked definition's resolved kind as a non-enumerable property. One of:

  • 'context'
  • 'service'
  • 'entity'
  • 'type'
  • 'aspect'
  • 'event'
  • 'element'
  • 'annotation'

... as documented in theCSN specification.

instanceof

You can use JavaScript's standardinstanceof operator in combination with the built-in classes to check a linked definition's type:

js
let { Foo }= cds.linked(csn).entitiesif (Fooinstanceof cds.entity) console.log ("it's an entity")

cds. service

Allservice definitions in a linked model are instances of this class.

tsx
class cds.service extends cds.context {...}

. is_service

A tag property which istrue for linked entity definitions.

. entities

. events

. actions

These properties are convenience shortcuts to access a service definition's exposedentity,type,event,action orfunction definitions.
Their values areLinkedDefinitions.

cds. entity

All entity definitions in a linked model are instances of this class.

tsx
class cds.entity extends cds.struct {...}

Ascds.entity is a subclass ofcds.struct it also inherits all methods from that.

. is_entity

A tag property which istrue for linked entity definitions.

. keys

. associations

. compositions

. actions

These properties are convenient shortcuts to access an entity definition's declaredkeys,Association orComposition elements, as well asbound action orfunction definitions.
Their values areLinkedDefinitions.

. texts

If the entity haslocalized elements, this property is a reference to the respective.texts entity. If not, this property is undefined

. drafts

If draft is enabled, a definition to easily refer todraft data for the current entity is returned.

cds. struct

This is the base class ofstruct elements and types,aspects, andentities.

tsx
class cds.struct extends cds.type {...}

. is_struct

A tag property which istrue for linked struct definitions (types and elements).
It is alsotrue for linked entity definitions, that is, instances of ascds.entity.

. elements

The entity's declared elements asdocumented in the CSN Specification
as an instance ofLinkedDefinitions.

cds. Association

All linked definitions of typeAssociation orComposition, including elements, are instances of this class. Besides the properties specified forAssociations in CSN, linked associations provide the following reflection properties...

. _target

A reference to the association's resolved linked target definition.

. isAssociation

A tag property which istrue for all linked Association definitions, including Compositions.

. isComposition

A tag property which istrue for all linked Composition definitions.

. is2one / 2many

Convenient shortcuts to check whether an association definition has to-one or to-many cardinality.

. keys

The declared or derived foreign keys. As specified inCSN spec this is aprojection of the association target's elements.

. foreignKeys

The effective foreign keys ofmanaged association as linked definitions.
The value is an instance ofLinkedDefinitions.

cds. linked .classes

This property gives you access to the very roots ofcds's type system. When a model is passed throughcds.linked all definitions effectively become instances of one of these classes. In essence they are defined as follows:

js
class any {...}class context extends any {...}cds.service= class service extends context {...}cds.type= class type extends any {...}              class scalar extends type {...}                class boolean extends scalar {...}                class number extends scalar {...}                class date extends scalar {...}                class string extends scalar {...}cds.array= class array extends type {...}cds.struct= class struct extends type {...}cds.entity= class entity extends struct {...}cds.event= class event extends struct {...}cds.Association= class Association extends type {...}cds.Composition= class Composition extends Association {...}

A few prominent ones of the above classes are available through top-level shortcuts as indicated by thecds.<classname> = prefixes in the above pseudo code, find more details on these in the following sections.

For example, you can use these classes as follows:

js
let m= cds.linked`   entity Books { author: Association to Authors; }   entity Authors { key ID: UUID; }`)let { Books, Authors }= m.entitieslet isEntity= Booksinstanceof cds.entitylet keys= Books.keyslet { author }= Books.elementsif (author.is2many)...

mixin()

Provided a convenient way to enhance one or more of the builtin classes with additional methods. Use it like that:

js
const cds = require ('@sap/cds')// simplistic csn2cdl enablementcds.linked.classes .mixin (  class type {    toCDL(){return `${this.kind} ${this.name} : ${this.typeAsCDL()};\n` }    typeAsCDL(){return `${this.type.replace(/^cds\./,'')}` }  },  class struct {    typeAsCDL() {return `{\n${ Object.values(this.elements).map (      e => `  ${e.toCDL()}`    ).join('')}}`}  },  class entity extends cds.struct {    typeAsCDL() {return (      this.includes? this.includes+' ' : ''    )+ super.typeAsCDL() }  },  class Association {    typeAsCDL(){return `Association to ${this.target}` }  },)// test drivelet m= cds.linked`  entity Books : cuid { title:String; author: Association to Authors }  entity Authors : cuid { name:String; }  aspect cuid : { key ID:UUID; }`m.foreach (d => console.log(d.toCDL()))

cds. builtin. types

This property gives you access to all prototypes of the builtin classes as well as to all linked definitions of thebuiltin pre-defined types. The resulting object is in turn like thedefinitions in aLinkedCSN.

Actually, at runtime CDS is in fact bootstrapped out of this using coreCSN object structures andcds.linked techniques. Think of it to be constructed as follows:

js
cds.builtin.types= cds.linked`  using from './roots';  context cds {    type UUID         : String(36);    type Boolean      : boolean;    type Integer      : number;    type UInt8        : Integer;    type Int16        : Integer;    type Int32        : Integer;    type Int64        : Integer;    type Integer64    : Integer;    type Decimal      : number;    type Double       : number;    type Date         : date;    type Time         : date;    type DateTime     : date;    type Timestamp    : date;    type String       : string;    type Binary       : string;    type LargeString  : string;    type LargeBinary  : string;    type Map          : struct;  }`.definitions

With./roots being this in-memory CSN:

js
const {any,context,service ,  type,scalar,string,number,boolean,date,  array,struct,entity,event,aspect  Association,Composition}= cds.linked.classesconst roots = module.exports = {definitions:{  any:new any,  context:new context ({type:'any'}),  type:new type ({type:'any'}),    scalar:new scalar ({type:'type'}),      string:new string ({type:'scalar'}),      number:new number ({type:'scalar'}),      boolean:new boolean ({type:'scalar'}),      date:new date ({type:'scalar'}),    array:new array ({type:'type'}),    struct:new struct ({type:'type'}),      entity:new entity ({type:'struct'}),      event:new event ({type:'struct'}),      aspect:new aspect ({type:'struct'}),    Association:new Association ({type:'type'}),      Composition:new Composition ({type:'Association'}),  service:new service ({type:'context'}),}}

Indentation indicates inheritance.

Was this page helpful?


[8]ページ先頭

©2009-2025 Movatter.jp