examples
This commit is contained in:
24
orders/db/_schema._cds
Normal file
24
orders/db/_schema._cds
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
using { Currency, User, managed, cuid } from '@sap/cds/common';
|
||||||
|
namespace sap.capire.orders;
|
||||||
|
|
||||||
|
entity Orders : cuid, managed {
|
||||||
|
OrderNo : String @title:'Order Number'; //> readable key
|
||||||
|
Items : Composition of many {
|
||||||
|
key ID : UUID;
|
||||||
|
product : Association to Products;
|
||||||
|
quantity : Integer;
|
||||||
|
title : String; //> intentionally replicated as snapshot from product.title
|
||||||
|
price : Double; //> materialized calculated field
|
||||||
|
};
|
||||||
|
buyer : User;
|
||||||
|
currency : Currency;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** This is a stand-in for arbitrary ordered Products */
|
||||||
|
entity Products @(cds.persistence.skip:'always') {
|
||||||
|
key ID : String;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// this is to ensure we have filled-in currencies
|
||||||
|
using from '@capire/common';
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
ID;up__ID;quantity;product_ID;title;price
|
ID;Header_ID;quantity;product_ID;title;price
|
||||||
58040e66-1dcd-4ffb-ab10-fdce32028b79;7e2f2640-6866-4dcf-8f4d-3027aa831cad;1;201;Wuthering Heights;11.11
|
58040e66-1dcd-4ffb-ab10-fdce32028b79;7e2f2640-6866-4dcf-8f4d-3027aa831cad;10;201;Wuthering Heights;11.11
|
||||||
64e718c9-ff99-47f1-8ca3-950c850777d4;7e2f2640-6866-4dcf-8f4d-3027aa831cad;1;271;Catweazle;15
|
64e718c9-ff99-47f1-8ca3-950c850777d4;7e2f2640-6866-4dcf-8f4d-3027aa831cad;501;271;Catweazle;15
|
||||||
e9641166-e050-4261-bfee-d1e797e6cb7f;64e718c9-ff99-47f1-8ca3-950c850777d4;2;252;Eleonora;28
|
e9641166-e050-4261-bfee-d1e797e6cb7f;64e718c9-ff99-47f1-8ca3-950c850777d4;499;252;Eleonora;28
|
||||||
|
@@ -1,82 +0,0 @@
|
|||||||
using { Currency, User, managed, cuid } from '@sap/cds/common';
|
|
||||||
using {Orders, OrderItems} from '../schema';
|
|
||||||
|
|
||||||
namespace sap.capire.orders;
|
|
||||||
|
|
||||||
entity OrdersHeaders : managed {
|
|
||||||
key ID : UUID;
|
|
||||||
OrderNo : String @title:'Order Number'; //> readable key
|
|
||||||
buyer : User;
|
|
||||||
currency : Currency;
|
|
||||||
Items : Composition of many OrdersItems on Items.Header = $self;
|
|
||||||
}
|
|
||||||
|
|
||||||
entity OrdersItems {
|
|
||||||
key ID : UUID;
|
|
||||||
product : Association to Products;
|
|
||||||
quantity : Integer;
|
|
||||||
title : String; //> intentionally replicated as snapshot from product.title
|
|
||||||
price : Double; //> materialized calculated field
|
|
||||||
Header : Association to OrdersHeaders;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// static
|
|
||||||
view OrdersItemsViewJoin as select
|
|
||||||
|
|
||||||
OrdersHeaders.ID as Header_ID,
|
|
||||||
OrdersHeaders.OrderNo as OrderNo,
|
|
||||||
OrdersHeaders.buyer as buyer,
|
|
||||||
OrdersHeaders.currency as currency,
|
|
||||||
OrdersItems.ID as Item_ID,
|
|
||||||
OrdersItems.product as product,
|
|
||||||
OrdersItems.quantity as quantity,
|
|
||||||
OrdersItems.title as title,
|
|
||||||
OrdersItems.price as price
|
|
||||||
|
|
||||||
from OrdersHeaders JOIN OrdersItems on OrdersHeaders.ID = OrdersItems.Header;
|
|
||||||
|
|
||||||
// dynamic entity
|
|
||||||
entity OrderItemsViewAssoc as projection on Orders;
|
|
||||||
|
|
||||||
// sort on right table
|
|
||||||
view SortedOrdersJoin as select
|
|
||||||
OrdersHeaders.ID as Header_ID,
|
|
||||||
OrdersHeaders.OrderNo as OrderNo,
|
|
||||||
OrdersHeaders.buyer as buyer,
|
|
||||||
OrdersHeaders.currency as currency,
|
|
||||||
OrdersItems.ID as Item_ID,
|
|
||||||
OrdersItems.product as product,
|
|
||||||
OrdersItems.quantity as quantity,
|
|
||||||
OrdersItems.title as title,
|
|
||||||
OrdersItems.price as price
|
|
||||||
from OrdersHeaders JOIN OrdersItems on OrdersHeaders.ID = OrdersItems.Header
|
|
||||||
order by title;
|
|
||||||
|
|
||||||
// sort on items and join back to header via assoc
|
|
||||||
view SortedOrdersAssoc as select
|
|
||||||
from OrdersItems {*, Header.OrderNo, Header.buyer, Header.currency }
|
|
||||||
order by OrdersItems.title;
|
|
||||||
|
|
||||||
// filter on right table
|
|
||||||
view FilteredOrdersJoin as select
|
|
||||||
OrdersHeaders.ID as Header_ID,
|
|
||||||
OrdersHeaders.OrderNo as OrderNo,
|
|
||||||
OrdersHeaders.buyer as buyer,
|
|
||||||
OrdersHeaders.currency as currency,
|
|
||||||
OrdersItems.ID as Item_ID,
|
|
||||||
OrdersItems.product as product,
|
|
||||||
OrdersItems.quantity as quantity,
|
|
||||||
OrdersItems.title as title,
|
|
||||||
OrdersItems.price as price
|
|
||||||
from OrdersHeaders JOIN OrdersItems on OrdersHeaders.ID = OrdersItems.Header
|
|
||||||
where price > 100;
|
|
||||||
|
|
||||||
// filter on items and join back to header via assoc
|
|
||||||
view FilteredOrdersAssoc as select
|
|
||||||
from OrdersItems {*, Header.OrderNo, Header.buyer, Header.currency }
|
|
||||||
where OrdersItems.price > 100;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,24 +1,32 @@
|
|||||||
using { Currency, User, managed, cuid } from '@sap/cds/common';
|
using { Currency, User, managed, cuid } from '@sap/cds/common';
|
||||||
|
// using {Orders, OrderItems} from './schema';
|
||||||
|
|
||||||
namespace sap.capire.orders;
|
namespace sap.capire.orders;
|
||||||
|
|
||||||
entity Orders : cuid, managed {
|
entity Products {
|
||||||
|
key ID : String;
|
||||||
|
}
|
||||||
|
|
||||||
|
entity OrdersHeaders : managed {
|
||||||
|
key ID : UUID;
|
||||||
OrderNo : String @title:'Order Number'; //> readable key
|
OrderNo : String @title:'Order Number'; //> readable key
|
||||||
Items : Composition of many {
|
buyer : User;
|
||||||
|
currency : Currency;
|
||||||
|
Items : Composition of many OrdersItems on Items.Header = $self;
|
||||||
|
}
|
||||||
|
|
||||||
|
entity OrdersItems {
|
||||||
key ID : UUID;
|
key ID : UUID;
|
||||||
product : Association to Products;
|
product : Association to Products;
|
||||||
quantity : Integer;
|
quantity : Integer;
|
||||||
title : String; //> intentionally replicated as snapshot from product.title
|
title : String; //> intentionally replicated as snapshot from product.title
|
||||||
price : Double; //> materialized calculated field
|
price : Double; //> materialized calculated field
|
||||||
};
|
Header : Association to OrdersHeaders;
|
||||||
buyer : User;
|
};
|
||||||
currency : Currency;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** This is a stand-in for arbitrary ordered Products */
|
|
||||||
entity Products @(cds.persistence.skip:'always') {
|
|
||||||
key ID : String;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// this is to ensure we have filled-in currencies
|
|
||||||
using from '@capire/common';
|
|
||||||
|
|||||||
@@ -1,5 +1,87 @@
|
|||||||
using { sap.capire.orders as my } from '../db/schema';
|
using { sap.capire.orders as my } from '../db/schema';
|
||||||
|
|
||||||
service OrdersService {
|
service OrdersService {
|
||||||
entity Orders as projection on my.Orders;
|
entity OrdersHeaders as projection on my.OrdersHeaders;
|
||||||
|
entity OrdersItems as projection on my.OrdersItems;
|
||||||
|
entity Products as projection on my.Products;
|
||||||
|
|
||||||
|
|
||||||
|
// static
|
||||||
|
view OrdersItemsViewJoin as select
|
||||||
|
|
||||||
|
OrdersHeaders.ID as Header_ID,
|
||||||
|
OrdersHeaders.OrderNo as OrderNo,
|
||||||
|
OrdersHeaders.buyer as buyer,
|
||||||
|
OrdersHeaders.currency as currency,
|
||||||
|
key OrdersItems.ID as Item_ID,
|
||||||
|
OrdersItems.product as product,
|
||||||
|
OrdersItems.quantity as quantity,
|
||||||
|
OrdersItems.title as title,
|
||||||
|
OrdersItems.price as price
|
||||||
|
|
||||||
|
from OrdersHeaders JOIN OrdersItems on OrdersHeaders.ID = OrdersItems.Header.ID;
|
||||||
|
|
||||||
|
// dynamic entity
|
||||||
|
entity OrderItemsViewAssoc as projection on OrdersHeaders;
|
||||||
|
|
||||||
|
// sort on right table
|
||||||
|
view SortedOrdersJoin as select
|
||||||
|
OrdersHeaders.ID as Header_ID,
|
||||||
|
OrdersHeaders.OrderNo as OrderNo,
|
||||||
|
OrdersHeaders.buyer as buyer,
|
||||||
|
OrdersHeaders.currency as currency,
|
||||||
|
key OrdersItems.ID as Item_ID,
|
||||||
|
OrdersItems.product as product,
|
||||||
|
OrdersItems.quantity as quantity,
|
||||||
|
OrdersItems.title as title,
|
||||||
|
OrdersItems.price as price
|
||||||
|
from OrdersHeaders JOIN OrdersItems on OrdersHeaders.ID = OrdersItems.Header.ID
|
||||||
|
order by title;
|
||||||
|
|
||||||
|
// sort on items and join back to header via assoc
|
||||||
|
|
||||||
|
view SortedOrdersAssoc as select
|
||||||
|
from OrdersItems {*, Header.OrderNo, Header.buyer, Header.currency }
|
||||||
|
order by OrdersItems.title;
|
||||||
|
|
||||||
|
// filter on right table
|
||||||
|
|
||||||
|
view FilteredOrdersJoin as select
|
||||||
|
OrdersHeaders.ID as Header_ID,
|
||||||
|
OrdersHeaders.OrderNo as OrderNo,
|
||||||
|
OrdersHeaders.buyer as buyer,
|
||||||
|
OrdersHeaders.currency as currency,
|
||||||
|
key OrdersItems.ID as Item_ID,
|
||||||
|
OrdersItems.product as product,
|
||||||
|
OrdersItems.quantity as quantity,
|
||||||
|
OrdersItems.title as title,
|
||||||
|
OrdersItems.price as price
|
||||||
|
from OrdersHeaders JOIN OrdersItems on OrdersHeaders.ID = OrdersItems.Header.ID
|
||||||
|
where price > 100;
|
||||||
|
|
||||||
|
// filter on items and join back to header via assoc
|
||||||
|
|
||||||
|
view FilteredOrdersAssoc as select
|
||||||
|
from OrdersItems {*, Header.OrderNo, Header.buyer, Header.currency }
|
||||||
|
where OrdersItems.price > 100;
|
||||||
|
|
||||||
|
|
||||||
|
// TODO avoid CASE and/or JOIN: Denormalization of expensive complex structures,
|
||||||
|
// calculate on write instead of read
|
||||||
|
|
||||||
|
// CASE -> try to remodel to avoid CASE, if re-modelling is not possible,
|
||||||
|
// fill redundant fields at write
|
||||||
|
|
||||||
|
entity OrdersItemsCaseView as projection on OrdersItems {
|
||||||
|
*,
|
||||||
|
case
|
||||||
|
when quantity > 500 then 'Large'
|
||||||
|
when quantity > 100 then 'Medium'
|
||||||
|
else 'Small'
|
||||||
|
end as category : String
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user