perf example

This commit is contained in:
Koch
2022-10-11 15:01:54 +02:00
parent 76195703f4
commit bf0587b028
16 changed files with 530 additions and 0 deletions

View File

@@ -0,0 +1,87 @@
using { sap.capire.performance as my } from '../db/schema';
service PerformanceService {
entity OrdersHeaders as projection on my.OrdersHeaders;
entity OrdersItems as projection on my.OrdersItems;
entity Books as projection on my.Books;
entity Authors as projection on my.Authors;
// 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
};
}

View File

@@ -0,0 +1,37 @@
const cds = require ('@sap/cds')
class OrdersService extends cds.ApplicationService {
/** register custom handlers */
init(){
const { 'Orders.Items':OrderItems } = this.entities
this.before ('UPDATE', 'Orders', async function(req) {
const { ID, Items } = req.data
if (Items) for (let { product_ID, quantity } of Items) {
const { quantity:before } = await cds.tx(req).run (
SELECT.one.from (OrderItems, oi => oi.quantity) .where ({up__ID:ID, product_ID})
)
if (quantity != before) await this.orderChanged (product_ID, quantity-before)
}
})
this.before ('DELETE', 'Orders', async function(req) {
const { ID } = req.data
const Items = await cds.tx(req).run (
SELECT.from (OrderItems, oi => { oi.product_ID, oi.quantity }) .where ({up__ID:ID})
)
if (Items) await Promise.all (Items.map(it => this.orderChanged (it.product_ID, -it.quantity)))
})
return super.init()
}
/** order changed -> broadcast event */
orderChanged (product, deltaQuantity) {
// Emit events to inform subscribers about changes in orders
console.log ('> emitting:', 'OrderChanged', { product, deltaQuantity })
return this.emit ('OrderChanged', { product, deltaQuantity })
}
}
module.exports = OrdersService