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

37
.vscode/launch.json vendored
View File

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

11
.vscode/settings.json vendored
View File

@@ -4,14 +4,5 @@
"**/.gitignore": true,
"**/.vscode": 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
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;
entity Books : managed {

View File

@@ -4,7 +4,7 @@
"description": "A simple self-contained bookshop service.",
"dependencies": {
"@capire/common": "*",
"@sap/cds": "^5.0.4",
"@sap/cds": ">=4",
"express": "^4.17.1",
"passport": "0.4.1"
},
@@ -16,8 +16,9 @@
"cds": {
"requires": {
"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';
service AdminService @(requires:'admin') {
entity Books as SELECT from my.Books { *,
// key ID, key validFrom
};
entity Books as projection on my.Books;
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
this.on ('submitOrder', async req => {
const {book,amount} = req.data
let {stock} = await SELECT `stock` .from (Books,book)
const {book,amount} = req.data, tx = cds.tx(req)
let {stock} = await tx.read('stock').from(Books,book)
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 })
return { stock }
}
@@ -16,8 +16,10 @@ class CatalogService extends cds.ApplicationService { init(){
})
// Add some discount for overstocked books
this.after ('READ','ListOfBooks', each => {
if (each.stock > 111) each.title += ` -- 11% discount!`
this.after ('READ','Books', each => {
if (each.stock > 111) {
each.title += ` -- 11% discount!`
}
})
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;
product : Association to Products @assert.integrity:false; // REVISIT: this is a temporary workaround for a glitch in cds-runtime
amount : Integer;
title : String; //> intentionally replicated as snapshot from product.title
title : String;
price : Double;
}

View File

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

View File

@@ -2,10 +2,10 @@
## 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
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
```
In the second one start the `fiori` app:
In the second one start the bookshop:
```sh
npm run fiori
npm run bookshop
```

View File

@@ -1,10 +1,11 @@
const {expect} = require('../test')
const cds = require('@sap/cds/lib')
// monkey patching older releases:
if (!cds.compile.cdl) cds.compile.cdl = cds.parse
const { parse:cdr } = cds.ql
// should become cds.compile(...) when cds5 is released
const model = cds.compile.to.csn (`
const model = cds.compile.cdl (`
entity Categories {
key ID : Integer;
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
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', ()=>{
srv.on('reviewed', ()=> ++M)
srv.on('reviewed', (_,next)=> { ++M; return next() })
})
it ('should add review', async ()=>{