Compare commits

..

2 Commits

Author SHA1 Message Date
D065023
9ae57008c5 fixed version 2019-10-25 09:54:46 +02:00
johannes-vogel
2c1079bc5b Update README.md 2019-09-23 14:13:03 +02:00
14 changed files with 2 additions and 191 deletions

View File

@@ -1,3 +1,3 @@
# Final state of exercise 3 for CAA265 - Rapid Service Development with SAP Cloud Application Programming Model
# Final state of exercise 1 for CAA265 - Rapid Service Development with SAP Cloud Application Programming Model
**DO NOT MERGE IN MASTER**

View File

@@ -1,3 +1,3 @@
{
"cds_version": "^3.17.4"
}
}

View File

@@ -9,7 +9,6 @@
},
"dependencies": {
"@sap/capire-products": "^1.0.0",
"reviews-service": "file:packages/reviews-service-1.0.0.tgz",
"@sap/cds": "^3.17.4",
"express": "^4.17.1"
},
@@ -17,16 +16,5 @@
"build": "cds build/all --clean",
"deploy": "cds deploy",
"start": "cds run"
},
"cds": {
"requires": {
"sap.capire.reviews.ReviewsService": {
"model": "reviews-service",
"kind": "odata",
"credentials": {
"file": "default"
}
}
}
}
}

View File

@@ -14,11 +14,4 @@ service CatalogService {
using { sap.capire.products.AdminService } from '@sap/capire-products';
extend service AdminService with {
entity Authors as projection on my.Authors;
}
// Adding reviews via capire-reviews service
using { sap.capire.reviews.ReviewsService as external} from 'reviews-service';
extend service CatalogService {
@readonly entity Reviews @(cds.persistence.skip) as projection on external.Reviews;
}

View File

@@ -15,21 +15,4 @@ module.exports = async (srv) => {
}
})))
})
const reviews_srv = await cds.connect.to('sap.capire.reviews.ReviewsService')
// react on event messages from reviews service
reviews_srv.on('reviewed', (msg) => {
console.debug('> received', msg)
})
// delegate requests to reviews service
srv.on('READ', 'Reviews', async (req) => {
const { Reviews } = reviews_srv.entities
const tx = reviews_srv.transaction(req)
const results = await tx.read(Reviews)
return results
})
}

Binary file not shown.

View File

@@ -1,6 +0,0 @@
{
"build": {
"target": ".",
"tasks": []
}
}

View File

@@ -1,15 +0,0 @@
.che/
.gen/
gen/
mta_archives/
node_modules/
target/
.cds_gen.log
connection.properties
*.db
.DS_Store
*.orig
_out
default-*.json
package-lock.json

View File

@@ -1,16 +0,0 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "cds run",
"request": "launch",
"type": "node", "runtimeExecutable": "npx","runtimeArgs": [ "-n" ],
"args": [ "--","cds","run","--in-memory?" ], // the leading "--" arg ensures it works with as well as without debugging
"console": "integratedTerminal",
"skipFiles": [ "<node_internals>/**" ]
}
]
}

View File

@@ -1,30 +0,0 @@
namespace sap.capire.reviews;
using { User } from '@sap/cds/common';
// Reviewed subjects can be any entity that is uniquely identified
type ReviewedSubject : String(111);
entity Reviews {
key ID : String(36);
subject : ReviewedSubject;
reviewer : User;
rating : Rating;
title : String(111);
text : String(1111);
date : DateTime;
likes : Composition of many Likes on likes.review = $self;
liked : Integer default 0; // counter for likes as helpful review (count of all _likes belonging to this review)
}
type Rating : Integer enum {
Best = 5;
Good = 4;
Avg = 3;
Poor = 2;
Worst = 1;
}
entity Likes {
key review : Association to Reviews;
key user : User;
}

View File

@@ -1 +0,0 @@
using from './srv/reviews-service';

View File

@@ -1,19 +0,0 @@
{
"name": "reviews-service",
"version": "1.0.0",
"description": "Generated by cds init",
"repository": "<Add your repository here>",
"license": "ISC",
"dependencies": {
"@sap/cds": "^3.17.4",
"express": "^4.17.1"
},
"engines": {
"node": "^8.9"
},
"scripts": {
"build": "cds build/all --clean",
"deploy": "cds deploy",
"start": "cds run"
}
}

View File

@@ -1,26 +0,0 @@
namespace sap.capire.reviews;
using { sap.capire.reviews as my } from '../db/schema';
service ReviewsService {
event reviewed : { subject:String; rating: Decimal(2,1) };
// API
entity Reviews as projection on my.Reviews excluding { likes }
action like (review:Reviews.ID);
action unlike (review:Reviews.ID);
// Input validation
annotate Reviews with {
subject @mandatory;
title @mandatory;
rating @mandatory @assert.enum;
}
// Auto-fill reviewers and review dates
annotate Reviews with {
reviewer @cds.on.insert:$user;
date @cds.on.insert:$now;
date @cds.on.update:$now;
}
}

View File

@@ -1,40 +0,0 @@
const cds = require('@sap/cds')
module.exports = cds.service.impl((srv) => {
// Get the CSN definition for Reviews from the db schema for sub-sequent queries
// ( Note: we explicitly specify the namespace to support embedded reuse )
const { Reviews, Likes } = cds.entities('sap.capire.reviews')
// Increment counter for reviews considered helpful
srv.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.transaction(req)
return tx.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'))
})
// Delete a former like by the same user
srv.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.transaction(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 }))
})
// Emit an event to inform subscribers about new avg ratings for reviewed subjects
// ( Note: req.on.succeeded ensures we only do that if there's no error )
srv.after(['CREATE', 'UPDATE', 'DELETE'], 'Reviews', async (_, req) => {
const { subject } = req.data
const { rating } = await cds.transaction(req).run(
SELECT.one(['avg(rating) as rating']).from(Reviews).where({ subject })
)
req.on('succeeded', () => {
srv.emit('reviewed', { subject, rating })
console.log(`Reviewed event was emitted for book "${subject}" with rating ${rating}.`)
})
})
})