Benefiting from cds.context

This commit is contained in:
Daniel
2020-12-17 16:39:01 +01:00
parent 86e5c429bd
commit 9e45ac2f0c
6 changed files with 20 additions and 26 deletions

View File

@@ -7,6 +7,6 @@ module.exports = cds.service.impl (function(){
/** Generate primary keys for target entity in request */
async function genid (req) {
const {ID} = await cds.tx(req).run (SELECT.one.from(req.target).columns('max(ID) as ID'))
const {ID} = await SELECT.one.from(req.target).columns('max(ID) as ID')
req.data.ID = ID - ID % 100 + 100 + 1
}

View File

@@ -1,15 +1,15 @@
const cds = require('@sap/cds')
const { Books } = cds.entities ('sap.capire.bookshop')
class CatalogService extends cds.ApplicationService { async init(){
class CatalogService extends cds.ApplicationService { init(){
// Reduce stock of ordered books if available stock suffices
this.on ('submitOrder', async req => {
const {book,amount} = req.data, tx = cds.tx(req)
let {stock} = await tx.read('stock').from(Books,book)
const {book,amount} = req.data
let {stock} = await SELECT('stock').from(Books,book)
if (stock >= amount) {
await tx.update (Books,book).with ({ stock: stock -= amount })
this.emit ('OrderedBook', { book, amount, buyer:req.user.id })
await UPDATE (Books,book).with ({ stock: stock -= amount })
await this.emit ('OrderedBook', { book, amount, buyer:req.user.id })
return { stock }
}
else return req.error (409,`${amount} exceeds stock for book #${book}`)

View File

@@ -20,7 +20,7 @@ module.exports = async()=>{ // called by server.js
CatalogService.prepend (srv => srv.on ('READ', 'Books/reviews', (req) => {
console.debug ('> delegating request to ReviewsService')
const [id] = req.params, { columns, limit } = req.query.SELECT
return ReviewsService.tx(req).read ('Reviews',columns).limit(limit).where({subject:String(id)})
return ReviewsService.read ('Reviews',columns).limit(limit).where({subject:String(id)})
}))
//
@@ -28,8 +28,8 @@ module.exports = async()=>{ // called by server.js
//
CatalogService.on ('OrderedBook', async (msg) => {
const { book, amount, buyer } = msg.data
const { title, price } = await db.tx(msg).read (Books, book, b => { b.title, b.price })
return OrdersService.tx(msg).create ('Orders').entries({
const { title, price } = await SELECT.from (Books, book, b => { b.title, b.price })
return OrdersService.create ('Orders').entries({
OrderNo: 'Order at '+ (new Date).toLocaleString(),
Items: [{ product:{ID:`${book}`}, title, price, amount }],
buyer, createdBy: buyer
@@ -43,7 +43,6 @@ module.exports = async()=>{ // called by server.js
console.debug ('> received:', msg.event, msg.data)
const { subject, rating } = msg.data
return UPDATE(Books,subject).with({rating})
// ^ Note: the framework will execute this and take care for db.tx
})
//

View File

@@ -8,18 +8,14 @@ class OrdersService extends cds.ApplicationService {
this.before ('UPDATE', 'Orders', async function(req) {
const { ID, Items } = req.data
if (Items) for (let { product_ID, amount } of Items) {
const { amount:before } = await cds.tx(req).run (
SELECT.one.from (OrderItems, oi => oi.amount) .where ({up__ID:ID, product_ID})
)
if (amount != before) this.orderChanged (product_ID, amount-before)
const { amount:before } = await SELECT.one.from (OrderItems, oi => oi.amount) .where ({up__ID:ID, product_ID})
if (amount != before) await this.orderChanged (product_ID, amount-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.amount }) .where ({up__ID:ID})
)
const Items = await SELECT.from (OrderItems, oi => { oi.product_ID, oi.amount }) .where ({up__ID:ID})
if (Items) for (let it of Items) this.orderChanged (it.product_ID, -it.amount)
})

View File

@@ -31,6 +31,9 @@
"mocha": {
"parallel": true
},
"engines": {
"node": ">= 12.18"
},
"jest": {
"testEnvironment": "node"
},

View File

@@ -1,5 +1,5 @@
const cds = require ('@sap/cds')
module.exports = cds.service.impl (async function(){
module.exports = cds.service.impl (function(){
// Get the CSN definition for Reviews from the db schema for sub-sequent queries
// ( Note: we explicitly specify the namespace to support embedded reuse )
@@ -12,9 +12,7 @@ module.exports = cds.service.impl (async function(){
// Emit an event to inform subscribers about new avg ratings for reviewed subjects
this.after (['CREATE','UPDATE','DELETE'], 'Reviews', async function(_,req) {
const {subject} = req.data
const {rating} = await cds.tx(req) .run (
SELECT.one (['round(avg(rating),2) as rating']) .from (Reviews) .where ({subject})
)
const {rating} = await SELECT.one (['round(avg(rating),2) as rating']) .from (Reviews) .where ({subject})
global.it || console.log ('< emitting:', 'reviewed', { subject, rating })
this.emit ('reviewed', { subject, rating })
})
@@ -23,8 +21,7 @@ module.exports = cds.service.impl (async function(){
this.on ('like', (req) => {
if (!req.user) return req.reject(400, 'You must be identified to like a review')
const {review} = req.data, {user} = req
const tx = cds.tx(req)
return tx.run ([
return cds.run ([
INSERT.into (Likes) .entries ({review_ID: review, user: user.id}),
UPDATE (Reviews) .set({liked: {'+=': 1}}) .where({ID:review})
]).catch(() => req.reject(400, 'You already liked that review'))
@@ -34,9 +31,8 @@ module.exports = cds.service.impl (async function(){
this.on ('unlike', async (req) => {
if (!req.user) return req.reject(400, 'You must be identified to remove a former like of yours')
const {review} = req.data, {user} = req
const tx = cds.tx(req)
const affectedRows = await tx.run (DELETE.from (Likes) .where ({review_ID: review,user: user.id}))
if (affectedRows === 1) return tx.run (UPDATE (Reviews) .set ({liked: {'-=': 1}}) .where ({ID:review}))
const affectedRows = await DELETE.from (Likes) .where ({review_ID: review,user: user.id})
if (affectedRows === 1) return UPDATE (Reviews) .set ({liked: {'-=': 1}}) .where ({ID:review})
})
})