Compare commits
8 Commits
openSAP-we
...
openSAP-we
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa74050c52 | ||
|
|
084e6ed51f | ||
|
|
56f696b87d | ||
|
|
84b299a23f | ||
|
|
198c15632e | ||
|
|
aaf42df652 | ||
|
|
d612b7bc0c | ||
|
|
21265e1138 |
@@ -11,7 +11,7 @@ In SAP Business Application Studio, open a terminal.
|
|||||||
Then clone the repo with this specific branch:
|
Then clone the repo with this specific branch:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
git clone https://github.com/sap-samples/cloud-cap-samples projects/cloud-cap-samples -b openSAP-week3-unit6
|
git clone https://github.com/sap-samples/cloud-cap-samples projects/cloud-cap-samples -b openSAP-week1-unit4-final
|
||||||
cd projects/cloud-cap-samples
|
cd projects/cloud-cap-samples
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,11 @@
|
|||||||
"lerna": "npx --no-install lerna -v > /dev/null || npm i lerna --no-save",
|
"lerna": "npx --no-install lerna -v > /dev/null || npm i lerna --no-save",
|
||||||
"install": "(npm -s run lerna) && lerna bootstrap --hoist",
|
"install": "(npm -s run lerna) && lerna bootstrap --hoist",
|
||||||
"cleanup": "lerna clean -y && rm -fr node_modules",
|
"cleanup": "lerna clean -y && rm -fr node_modules",
|
||||||
"bookshop": "cds watch packages/bookshop"
|
"bookshop": "cds watch packages/bookshop",
|
||||||
|
"bookshop-enhanced": "cds watch packages/bookshop-enhanced",
|
||||||
|
"reviews-service": "cds watch packages/reviews-service",
|
||||||
|
"bookstore": "cds watch packages/bookstore",
|
||||||
|
"media-server": "cds watch packages/media-server"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sap/cds": "^3",
|
"@sap/cds": "^3",
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
ID;name
|
||||||
|
101;Emily Brontë
|
||||||
|
107;Charlotte Brontë
|
||||||
|
150;Edgar Allen Poe
|
||||||
|
170;Richard Carpenter
|
||||||
|
6
packages/bookshop/db/data/sap.capire.bookshop-Books.csv
Normal file
6
packages/bookshop/db/data/sap.capire.bookshop-Books.csv
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
ID;title;author_ID;stock
|
||||||
|
201;Wuthering Heights;101;12
|
||||||
|
207;Jane Eyre;107;11
|
||||||
|
251;The Raven;150;333
|
||||||
|
252;Eleonora;150;555
|
||||||
|
271;Catweazle;170;22
|
||||||
|
@@ -1,23 +1,30 @@
|
|||||||
namespace sap.capire.bookshop;
|
namespace sap.capire.bookshop;
|
||||||
|
using { Currency, managed } from '@sap/cds/common';
|
||||||
|
|
||||||
@cds.persistence.exists
|
entity Books : managed {
|
||||||
entity Books {
|
key ID : Integer;
|
||||||
key ID: Integer;
|
title : localized String(111);
|
||||||
title : String(111);
|
descr : localized String(1111);
|
||||||
descr : String(1111);
|
author : Association to Authors;
|
||||||
author : String(50);
|
stock : Integer;
|
||||||
rating : Integer;
|
price : Decimal(9,2);
|
||||||
|
currency : Currency;
|
||||||
}
|
}
|
||||||
|
|
||||||
@cds.persistence.exists
|
entity Authors : managed {
|
||||||
entity BooksDescr {
|
key ID : Integer;
|
||||||
key id : Integer;
|
name : String(111);
|
||||||
book_descr : String(2000);
|
books : Association to many Books on books.author = $self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@cds.persistence.exists
|
entity Orders : managed {
|
||||||
entity BooksInfo (REQ_RATING : Integer) {
|
key ID : UUID;
|
||||||
key id : Integer;
|
OrderNo : String @title:'Order Number'; //> readable key
|
||||||
rating : Integer;
|
Items : Composition of many OrderItems on Items.parent = $self;
|
||||||
book_author_info : String;
|
|
||||||
}
|
}
|
||||||
|
entity OrderItems {
|
||||||
|
key ID : UUID;
|
||||||
|
parent : Association to Orders;
|
||||||
|
book : Association to Books;
|
||||||
|
amount : Integer;
|
||||||
|
}
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"file_suffixes": {
|
|
||||||
"hdbtable": { "plugin_name": "com.sap.hana.di.table", "plugin_version": "11.1.0" },
|
|
||||||
"hdbview": { "plugin_name": "com.sap.hana.di.view" },
|
|
||||||
"hdbfunction": { "plugin_name": "com.sap.hana.di.function" },
|
|
||||||
"hdbtabletype": { "plugin_name": "com.sap.hana.di.tabletype", "plugin_version": "11.1.0" },
|
|
||||||
"hdbtabledata": { "plugin_name": "com.sap.hana.di.tabledata", "plugin_version": "11.1.0" },
|
|
||||||
"csv": { "plugin_name" : "com.sap.hana.di.tabledata.source" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "",
|
|
||||||
"subfolder": "ignore"
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
ID;TITLE;DESCR;AUTHOR;RATING
|
|
||||||
301;Anna Karenina;"Anna Karenina (Russian: «Анна Каренина», IPA: [ˈanːə kɐˈrʲenʲɪnə])[1] is a novel by the Russian author Leo Tolstoy, first published in book form in 1878. Many writers consider Anna Karenina the greatest work of literature ever,[2] and Tolstoy himself called it his first true novel. It was initially released in serial installments from 1873 to 1877 in the periodical The Russian Messenger.";Leo Tolstoy;4
|
|
||||||
307;The Great Gatsby;"The Great Gatsby is a 1925 novel written by American author F. Scott Fitzgerald that follows a cast of characters living in the fictional towns of West Egg and East Egg on prosperous Long Island in the summer of 1922. The story primarily concerns the young and mysterious millionaire Jay Gatsby and his quixotic passion and obsession with the beautiful former debutante Daisy Buchanan. Considered to be Fitzgerald's magnum opus, The Great Gatsby explores themes of decadence, idealism, resistance to change, social upheaval and excess, creating a portrait of the Roaring Twenties that has been described as a cautionary[a] tale regarding the American Dream.";F. Scott Fitzgerald;4
|
|
||||||
406;Harry Potter;"Harry Potter is a series of fantasy novels written by British author J. K. Rowling. The novels chronicle the lives of a young wizard, Harry Potter, and his friends Hermione Granger and Ron Weasley, all of whom are students at Hogwarts School of Witchcraft and Wizardry. The main story arc concerns Harry's struggle against Lord Voldemort, a dark wizard who intends to become immortal, overthrow the wizard governing body known as the Ministry of Magic and subjugate all wizards and Muggles (non-magical people).";J. K. Rowling;5
|
|
||||||
|
@@ -1,8 +0,0 @@
|
|||||||
COLUMN TABLE SAP_CAPIRE_BOOKSHOP_BOOKS (
|
|
||||||
ID INTEGER NOT NULL,
|
|
||||||
TITLE NVARCHAR(111),
|
|
||||||
DESCR NVARCHAR(1111),
|
|
||||||
AUTHOR NVARCHAR(50),
|
|
||||||
RATING INTEGER,
|
|
||||||
PRIMARY KEY(ID)
|
|
||||||
)
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
{
|
|
||||||
"format_version": 1,
|
|
||||||
"imports": [
|
|
||||||
{
|
|
||||||
"target_table": "SAP_CAPIRE_BOOKSHOP_BOOKS",
|
|
||||||
"source_data": {
|
|
||||||
"data_type": "CSV",
|
|
||||||
"file_name": "Books.csv",
|
|
||||||
"has_header": true,
|
|
||||||
"no_data_import": false,
|
|
||||||
"delete_existing_foreign_data": false,
|
|
||||||
"dialect": "HANA",
|
|
||||||
"type_config": {
|
|
||||||
"delimiter": ";"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
FUNCTION SAP_CAPIRE_BOOKSHOP_BOOKSDESCR
|
|
||||||
RETURNS TABLE (ID integer, BOOK_DESCR nvarchar(2000))
|
|
||||||
LANGUAGE SQLSCRIPT
|
|
||||||
AS
|
|
||||||
BEGIN
|
|
||||||
RETURN SELECT
|
|
||||||
100 + ID AS ID,
|
|
||||||
'From my HANA function: A summary for the book ' || TITLE || ': ' || DESCR AS BOOK_DESCR
|
|
||||||
FROM SAP_CAPIRE_BOOKSHOP_BOOKS;
|
|
||||||
END
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
VIEW SAP_CAPIRE_BOOKSHOP_BOOKSINFO (in REQ_RATING integer) AS SELECT
|
|
||||||
ID,
|
|
||||||
RATING,
|
|
||||||
'From my HANA view: The book ' || TITLE || ' is authored by ' || AUTHOR AS BOOK_AUTHOR_INFO
|
|
||||||
FROM SAP_CAPIRE_BOOKSHOP_BOOKS
|
|
||||||
WHERE RATING = :REQ_RATING;
|
|
||||||
@@ -1,25 +1,14 @@
|
|||||||
{
|
{
|
||||||
"name": "@sap/capire-bookshop",
|
"name": "bookshop",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "A simple bookshop application, build in a self-contained all-in-one fashion, i.e. w/o reusing other packages.",
|
"description": "A simple CAP project.",
|
||||||
"license": "SAP SAMPLE CODE LICENSE",
|
"repository": "<Add your repository here>",
|
||||||
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sap/cds": "^3",
|
"@sap/cds": "^3",
|
||||||
"express": "^4",
|
"express": "^4"
|
||||||
"hdb": "^0.17.1"
|
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "cds run --in-memory?",
|
"start": "npx cds run"
|
||||||
"watch": "cds watch"
|
|
||||||
},
|
|
||||||
"cds": {
|
|
||||||
"requires": {
|
|
||||||
"db": {
|
|
||||||
"kind": "sql"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@sap/hdi-deploy": "3.7.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
12
packages/bookshop/sample requests.http
Normal file
12
packages/bookshop/sample requests.http
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
### Submit Orders
|
||||||
|
POST http://localhost:4004/browse/Orders
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{ "OrderNo":"2019-09...", "Items":[
|
||||||
|
{ "book_ID":201, "amount":5 }
|
||||||
|
]}
|
||||||
|
|
||||||
|
# Sending this three times should result in a 409: 5 exceeds stock for book #201
|
||||||
|
|
||||||
|
### Check books entity that stock was reduced
|
||||||
|
GET http://localhost:4004/admin/Books(201)
|
||||||
6
packages/bookshop/srv/admin-service.cds
Normal file
6
packages/bookshop/srv/admin-service.cds
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
using { sap.capire.bookshop as my } from '../db/schema';
|
||||||
|
service AdminService @(_requires:'admin',path:'/admin') {
|
||||||
|
entity Books as projection on my.Books;
|
||||||
|
entity Authors as projection on my.Authors;
|
||||||
|
entity Orders as select from my.Orders;
|
||||||
|
}
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
using { sap.capire.bookshop as db } from '../db/schema';
|
using { sap.capire.bookshop as my } from '../db/schema';
|
||||||
|
service CatalogService @(path:'/browse') {
|
||||||
|
|
||||||
service CatalogService {
|
@readonly entity Books as SELECT from my.Books {*,
|
||||||
entity Books as projection on db.Books;
|
author.name as author
|
||||||
|
} excluding { createdBy, modifiedBy };
|
||||||
|
|
||||||
entity BooksInfo (RATING : Integer) as select from db.BooksInfo(REQ_RATING: :RATING) {*};
|
@requires_: 'authenticated-user'
|
||||||
|
@insertonly entity Orders as projection on my.Orders;
|
||||||
entity BooksDescr as select from db.BooksDescr;
|
|
||||||
}
|
}
|
||||||
28
packages/bookshop/srv/cat-service.js
Normal file
28
packages/bookshop/srv/cat-service.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* Implementation for CatalogService defined in ./cat-service.cds
|
||||||
|
*/
|
||||||
|
module.exports = (srv)=>{
|
||||||
|
|
||||||
|
// Use reflection to get the csn definition of Books
|
||||||
|
const {Books} = cds.entities
|
||||||
|
|
||||||
|
// Add some discount for overstocked books
|
||||||
|
srv.after ('READ','Books', (each)=>{
|
||||||
|
if (each.stock > 111) each.title += ' -- 11% discount!'
|
||||||
|
})
|
||||||
|
|
||||||
|
// Reduce stock of books upon incoming orders
|
||||||
|
srv.before ('CREATE','Orders', async (req)=>{
|
||||||
|
const tx = cds.transaction(req), order = req.data;
|
||||||
|
if (order.Items) {
|
||||||
|
const affectedRows = await tx.run(order.Items.map(item =>
|
||||||
|
UPDATE(Books) .where({ID:item.book_ID})
|
||||||
|
.and(`stock >=`, item.amount)
|
||||||
|
.set(`stock -=`, item.amount)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if (affectedRows.some(row => !row)) req.error(409, 'Sold out, sorry')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
# Get all books
|
|
||||||
GET http://localhost:4004/catalog/Books
|
|
||||||
|
|
||||||
# Get books description from the HANA function
|
|
||||||
GET http://localhost:4004/catalog/BooksDescr
|
|
||||||
|
|
||||||
# Get books with rating 4 via the HANA view
|
|
||||||
GET http://localhost:4004/catalog/BooksInfo(RATING=4)/Set
|
|
||||||
Reference in New Issue
Block a user