Compare commits

..

2 Commits

Author SHA1 Message Date
Daniel
adaeb6ab05 cosmetics 2021-03-23 20:48:17 +01:00
Daniel
6e88453dea cds.deploy++ 2021-03-23 20:00:37 +01:00
17 changed files with 67 additions and 76 deletions

1
.env
View File

@@ -1 +0,0 @@
# cdsc

39
.vscode/launch.json vendored
View File

@@ -5,30 +5,27 @@
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": "bookshop", "name": "Attach by Process ID",
"command": "npx cds watch bookshop", "processId": "${command:PickProcess}",
"type": "node-terminal", "request": "attach",
"request": "launch",
"skipFiles": [ "skipFiles": [
"<node_internals>/**", "<node_internals>/**"
"**/node_modules/**", ],
"**/cds/lib/lazy.js", "type": "pwa-node"
"**/cds/lib/req/cls.js",
"**/odata-v4/okra/**"
]
}, },
{ {
"name": "Fiori App", "name": "bookshop",
"command": "npx cds watch fiori", "command": "cds watch bookshop",
"type": "node-terminal",
"request": "launch", "request": "launch",
"skipFiles": [ "type": "node-terminal",
"<node_internals>/**", "skipFiles": ["<node_internals>/**"]
"**/node_modules/**", },
"**/cds/lib/lazy.js", {
"**/cds/lib/req/cls.js", "name": "Fiori app",
"**/odata-v4/okra/**" "command": "cds watch fiori",
] "request": "launch",
"type": "node-terminal",
"skipFiles": ["<node_internals>/**"]
} }
], ],
"inputs": [ "inputs": [
@@ -36,7 +33,7 @@
"type": "pickString", "type": "pickString",
"id": "sample", "id": "sample",
"description": "Which sample do you want to start?", "description": "Which sample do you want to start?",
"options": [ "bookshop", "fiori", "reviews", "reviews" ], "options": ["bookshop", "fiori", "reviews", "reviews/test/bookshop"],
"default": "bookshop" "default": "bookshop"
} }
] ]

11
.vscode/settings.json vendored
View File

@@ -4,14 +4,5 @@
"**/.gitignore": true, "**/.gitignore": true,
"**/.vscode": true, "**/.vscode": true,
"LICENSES/**": true "LICENSES/**": true
}, }
"debug.javascript.terminalOptions": {
"skipFiles": [
"<node_internals>/**",
"**/node_modules/**",
"**/cds/lib/lazy.js",
"**/cds/lib/req/cls.js",
"**/odata-v4/okra/**"
]
},
} }

View File

@@ -83,4 +83,4 @@ In case you've a question, find a bug, or otherwise need support, use our [commu
## License ## License
Copyright (c) 2021 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, version 2.0 except as noted otherwise in the [LICENSE](LICENSE.txt) file. Copyright (c) 2021 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, version 2.0 except as noted otherwise in the [LICENSE](LICENSES/Apache-2.0.txt) file.

View File

@@ -1,4 +1,4 @@
using { Currency, managed, temporal, sap } from '@sap/cds/common'; using { Currency, managed, sap } from '@sap/cds/common';
namespace sap.capire.bookshop; namespace sap.capire.bookshop;
entity Books : managed { entity Books : managed {

View File

@@ -4,7 +4,7 @@
"description": "A simple self-contained bookshop service.", "description": "A simple self-contained bookshop service.",
"dependencies": { "dependencies": {
"@capire/common": "*", "@capire/common": "*",
"@sap/cds": "^5.0.4", "@sap/cds": ">=4",
"express": "^4.17.1", "express": "^4.17.1",
"passport": "0.4.1" "passport": "0.4.1"
}, },
@@ -16,7 +16,8 @@
"cds": { "cds": {
"requires": { "requires": {
"db": { "db": {
"kind": "sql" "kind": "sqlite",
"model": "*"
} }
} }
} }

BIN
bookshop/sqlite.db Normal file

Binary file not shown.

View File

@@ -1,27 +1,5 @@
using { sap.capire.bookshop as my } from '../db/schema'; using { sap.capire.bookshop as my } from '../db/schema';
service AdminService @(requires:'admin') { service AdminService @(requires:'admin') {
entity Books as projection on my.Books;
entity Books as SELECT from my.Books { *,
// key ID, key validFrom
};
entity Authors as projection on my.Authors; entity Authors as projection on my.Authors;
// @cds.redirection.target:false
// entity Books.history @(cds.temporal:false) as projection on Books {
// *,
// key ID,
// key validFrom @(cds.valid.from:false),
// validTo @(cds.valid.to:false),
// };
}
// entity NonTemporalBook as projection on my.Books {
// *,
// key ID,
// key validFrom @(cds.valid.from:false),
// validTo @(cds.valid.to:false),
// };
extend my.Books with {
history : Composition of many my.Books on history.ID = $self.ID;
} }

View File

@@ -5,10 +5,10 @@ class CatalogService extends cds.ApplicationService { init(){
// Reduce stock of ordered books if available stock suffices // Reduce stock of ordered books if available stock suffices
this.on ('submitOrder', async req => { this.on ('submitOrder', async req => {
const {book,amount} = req.data const {book,amount} = req.data, tx = cds.tx(req)
let {stock} = await SELECT `stock` .from (Books,book) let {stock} = await tx.read('stock').from(Books,book)
if (stock >= amount) { if (stock >= amount) {
await UPDATE (Books,book) .with (`stock -=`, amount) await tx.update (Books,book).with ({ stock: stock -= amount })
await this.emit ('OrderedBook', { book, amount, buyer:req.user.id }) await this.emit ('OrderedBook', { book, amount, buyer:req.user.id })
return { stock } return { stock }
} }
@@ -16,8 +16,10 @@ class CatalogService extends cds.ApplicationService { init(){
}) })
// Add some discount for overstocked books // Add some discount for overstocked books
this.after ('READ','ListOfBooks', each => { this.after ('READ','Books', each => {
if (each.stock > 111) each.title += ` -- 11% discount!` if (each.stock > 111) {
each.title += ` -- 11% discount!`
}
}) })
return super.init() return super.init()

19
bookshop/srv/server.js Normal file
View File

@@ -0,0 +1,19 @@
const cds = require ('@sap/cds')
cds.on('listening', async ()=>{ try { //> just to see the output at the end; will later on be in db service impl
console.log ('\nFilling database with initial data...')
const m = cds.model.minified() //> we likely should do that by default
const tx = cds.tx()
tx.run ([ //> this will be replaced by
DELETE.from ('sap.capire.bookshop.Authors'),
DELETE.from ('sap.capire.bookshop.Books'),
DELETE.from ('sap.capire.bookshop.Books.texts'),
DELETE.from ('sap.capire.bookshop.Genres'),
DELETE.from ('sap.common.Currencies'),
DELETE.from ('sap.common.Currencies.texts'),
])
await cds.deploy(m).to(tx,{ddl:false})
await tx.commit()
} catch(e) { console.error(e) }})
module.exports = cds.server

View File

@@ -13,7 +13,7 @@ entity Orders_Items {
up_ : Association to Orders; up_ : Association to Orders;
product : Association to Products @assert.integrity:false; // REVISIT: this is a temporary workaround for a glitch in cds-runtime product : Association to Products @assert.integrity:false; // REVISIT: this is a temporary workaround for a glitch in cds-runtime
amount : Integer; amount : Integer;
title : String; //> intentionally replicated as snapshot from product.title title : String;
price : Double; price : Double;
} }

View File

@@ -20,7 +20,6 @@
"sqlite3": "^5.0.0" "sqlite3": "^5.0.0"
}, },
"scripts": { "scripts": {
"cleanup": "rm -rf node_modules && rm -rf */node_modules && rm -rf */*/node_modules",
"registry": "node .registry/server.js", "registry": "node .registry/server.js",
"bookshop": "cds watch bookshop", "bookshop": "cds watch bookshop",
"fiori": "cds watch fiori", "fiori": "cds watch fiori",

View File

@@ -2,10 +2,10 @@
## Run all-in-one ## Run all-in-one
Open a terminal window and run the `fiori` app in it: Open a terminal window and run the bookshop in it:
```sh ```sh
npm run fiori npm run bookshop
``` ```
@@ -17,8 +17,8 @@ Open two terminal windows. In the first one start the reviews service stand-alon
npm run reviews-service npm run reviews-service
``` ```
In the second one start the `fiori` app: In the second one start the bookshop:
```sh ```sh
npm run fiori npm run bookshop
``` ```

View File

@@ -1,10 +1,11 @@
const {expect} = require('../test') const {expect} = require('../test')
const cds = require('@sap/cds/lib') const cds = require('@sap/cds/lib')
// monkey patching older releases:
if (!cds.compile.cdl) cds.compile.cdl = cds.parse
const { parse:cdr } = cds.ql const { parse:cdr } = cds.ql
// should become cds.compile(...) when cds5 is released const model = cds.compile.cdl (`
const model = cds.compile.to.csn (`
entity Categories { entity Categories {
key ID : Integer; key ID : Integer;
name : String; name : String;

View File

@@ -1,2 +1,6 @@
const cds = require('@sap/cds')
module.exports = cds.test.in(__dirname,'..') const test = require('@sap/cds/lib/utils/tests').in(__dirname,'..')
module.exports = Object.assign(test,{run:test})
// REVISIT: With upcoming release of @sap/cds this should become:
// module.exports = require('@sap/cds/tests').in(__dirname,'..')

View File

@@ -20,11 +20,11 @@ describe('Messaging', ()=>{
let N=0, received=[], M=0 let N=0, received=[], M=0
it ('should add messaging event handlers', ()=>{ it ('should add messaging event handlers', ()=>{
srv.on('reviewed', (msg)=> received.push(msg)) srv.on('reviewed', (msg,next)=> { received.push(msg); return next() })
}) })
it ('should add more messaging event handlers', ()=>{ it ('should add more messaging event handlers', ()=>{
srv.on('reviewed', ()=> ++M) srv.on('reviewed', (_,next)=> { ++M; return next() })
}) })
it ('should add review', async ()=>{ it ('should add review', async ()=>{