Compare commits
8 Commits
openSAP-we
...
openSAP-we
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b31657f69 | ||
|
|
2f52cbd918 | ||
|
|
71742e1e35 | ||
|
|
25e3d5261c | ||
|
|
edc2fdae91 | ||
|
|
13480ad99e | ||
|
|
8071faa62d | ||
|
|
9ea294586a |
@@ -11,7 +11,7 @@ In SAP Business Application Studio, open a terminal.
|
||||
Then clone the repo with this specific branch:
|
||||
|
||||
```sh
|
||||
git clone https://github.com/sap-samples/cloud-cap-samples projects/cloud-cap-samples -b openSAP-week1-unit4-final
|
||||
git clone https://github.com/sap-samples/cloud-cap-samples projects/cloud-cap-samples -b openSAP-week3-unit6
|
||||
cd projects/cloud-cap-samples
|
||||
```
|
||||
|
||||
|
||||
@@ -8,11 +8,7 @@
|
||||
"lerna": "npx --no-install lerna -v > /dev/null || npm i lerna --no-save",
|
||||
"install": "(npm -s run lerna) && lerna bootstrap --hoist",
|
||||
"cleanup": "lerna clean -y && rm -fr node_modules",
|
||||
"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"
|
||||
"bookshop": "cds watch packages/bookshop"
|
||||
},
|
||||
"dependencies": {
|
||||
"@sap/cds": "^3",
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
ID;name
|
||||
101;Emily Brontë
|
||||
107;Charlotte Brontë
|
||||
150;Edgar Allen Poe
|
||||
170;Richard Carpenter
|
||||
|
@@ -1,6 +0,0 @@
|
||||
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,30 +1,23 @@
|
||||
namespace sap.capire.bookshop;
|
||||
using { Currency, managed } from '@sap/cds/common';
|
||||
|
||||
entity Books : managed {
|
||||
key ID : Integer;
|
||||
title : localized String(111);
|
||||
descr : localized String(1111);
|
||||
author : Association to Authors;
|
||||
stock : Integer;
|
||||
price : Decimal(9,2);
|
||||
currency : Currency;
|
||||
@cds.persistence.exists
|
||||
entity Books {
|
||||
key ID: Integer;
|
||||
title : String(111);
|
||||
descr : String(1111);
|
||||
author : String(50);
|
||||
rating : Integer;
|
||||
}
|
||||
|
||||
entity Authors : managed {
|
||||
key ID : Integer;
|
||||
name : String(111);
|
||||
books : Association to many Books on books.author = $self;
|
||||
@cds.persistence.exists
|
||||
entity BooksDescr {
|
||||
key id : Integer;
|
||||
book_descr : String(2000);
|
||||
}
|
||||
|
||||
entity Orders : managed {
|
||||
key ID : UUID;
|
||||
OrderNo : String @title:'Order Number'; //> readable key
|
||||
Items : Composition of many OrderItems on Items.parent = $self;
|
||||
}
|
||||
entity OrderItems {
|
||||
key ID : UUID;
|
||||
parent : Association to Orders;
|
||||
book : Association to Books;
|
||||
amount : Integer;
|
||||
@cds.persistence.exists
|
||||
entity BooksInfo (REQ_RATING : Integer) {
|
||||
key id : Integer;
|
||||
rating : Integer;
|
||||
book_author_info : String;
|
||||
}
|
||||
10
packages/bookshop/db/src/.hdiconfig
Normal file
10
packages/bookshop/db/src/.hdiconfig
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"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" }
|
||||
}
|
||||
}
|
||||
4
packages/bookshop/db/src/.hdinamespace
Normal file
4
packages/bookshop/db/src/.hdinamespace
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "",
|
||||
"subfolder": "ignore"
|
||||
}
|
||||
4
packages/bookshop/db/src/data/Books.csv
Normal file
4
packages/bookshop/db/src/data/Books.csv
Normal file
@@ -0,0 +1,4 @@
|
||||
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
|
||||
|
@@ -0,0 +1,8 @@
|
||||
COLUMN TABLE SAP_CAPIRE_BOOKSHOP_BOOKS (
|
||||
ID INTEGER NOT NULL,
|
||||
TITLE NVARCHAR(111),
|
||||
DESCR NVARCHAR(1111),
|
||||
AUTHOR NVARCHAR(50),
|
||||
RATING INTEGER,
|
||||
PRIMARY KEY(ID)
|
||||
)
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"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": ";"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
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
|
||||
@@ -0,0 +1,6 @@
|
||||
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,14 +1,25 @@
|
||||
{
|
||||
"name": "bookshop",
|
||||
"name": "@sap/capire-bookshop",
|
||||
"version": "1.0.0",
|
||||
"description": "A simple CAP project.",
|
||||
"repository": "<Add your repository here>",
|
||||
"license": "ISC",
|
||||
"description": "A simple bookshop application, build in a self-contained all-in-one fashion, i.e. w/o reusing other packages.",
|
||||
"license": "SAP SAMPLE CODE LICENSE",
|
||||
"dependencies": {
|
||||
"@sap/cds": "^3",
|
||||
"express": "^4"
|
||||
"express": "^4",
|
||||
"hdb": "^0.17.1"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "npx cds run"
|
||||
"start": "cds run --in-memory?",
|
||||
"watch": "cds watch"
|
||||
},
|
||||
"cds": {
|
||||
"requires": {
|
||||
"db": {
|
||||
"kind": "sql"
|
||||
}
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sap/hdi-deploy": "3.7.0"
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
### 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)
|
||||
@@ -1,6 +0,0 @@
|
||||
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,10 +1,9 @@
|
||||
using { sap.capire.bookshop as my } from '../db/schema';
|
||||
service CatalogService @(path:'/browse') {
|
||||
using { sap.capire.bookshop as db } from '../db/schema';
|
||||
|
||||
@readonly entity Books as SELECT from my.Books {*,
|
||||
author.name as author
|
||||
} excluding { createdBy, modifiedBy };
|
||||
service CatalogService {
|
||||
entity Books as projection on db.Books;
|
||||
|
||||
@requires_: 'authenticated-user'
|
||||
@insertonly entity Orders as projection on my.Orders;
|
||||
entity BooksInfo (RATING : Integer) as select from db.BooksInfo(REQ_RATING: :RATING) {*};
|
||||
|
||||
entity BooksDescr as select from db.BooksDescr;
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/**
|
||||
* 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')
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
8
packages/bookshop/tests/CatalogService.http
Normal file
8
packages/bookshop/tests/CatalogService.http
Normal file
@@ -0,0 +1,8 @@
|
||||
# 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