diff --git a/package.json b/package.json index 017d41aa..499371c6 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,9 @@ "bookshop": "cds watch packages/bookshop", "bookshop-enhanced": "cds watch packages/bookshop-enhanced", "reviews-service": "cds watch packages/reviews-service", - "bookstore": "cds watch packages/bookstore" + + "bookstore": "cds watch packages/bookstore", + "media-server": "cds watch packages/media-server" }, "dependencies": { "@sap/cds": "latest", diff --git a/packages/media-server/db/data-model.cds b/packages/media-server/db/data-model.cds new file mode 100644 index 00000000..2ad6c28e --- /dev/null +++ b/packages/media-server/db/data-model.cds @@ -0,0 +1,13 @@ +namespace sap.capire.media; + +entity Media { + + key id:Integer; + @Core.MediaType: mediaType + content : LargeBinary ; + + @Core.IsMediaType: true + mediaType : String; + fileName : String; + applicationName:String; +} \ No newline at end of file diff --git a/packages/media-server/index.cds b/packages/media-server/index.cds deleted file mode 100644 index 552aaf97..00000000 --- a/packages/media-server/index.cds +++ /dev/null @@ -1,15 +0,0 @@ -namespace sap.capire.media; - -service MediaServer { - entity Images { - key url : URL; - type : String enum { jpeg; png; gif; }; - content : Image; - } -} - -type ImageURL : URL; -// type ImageURL : Association to MediaServer.Images; -//> would need Assotiations targeting off service to turn into references w/ foreign keys -type Image : LargeBinary @stream; -type URL : String(222); diff --git a/packages/media-server/package.json b/packages/media-server/package.json index 8c5de4d5..c144037d 100644 --- a/packages/media-server/package.json +++ b/packages/media-server/package.json @@ -6,6 +6,19 @@ "license": "SAP SAMPLE CODE LICENSE", "dependencies": { "@sap/cds": "latest", - "express": "*" + "express": "*", + "lokijs": "^1.5.6" + }, + "files": [ + "db", + "srv", + "index.cds" + ], + "cds": { + "requires": { + "db": { + "kind": "sql" + } + } } } diff --git a/packages/media-server/srv/media-service.cds b/packages/media-server/srv/media-service.cds new file mode 100644 index 00000000..09441897 --- /dev/null +++ b/packages/media-server/srv/media-service.cds @@ -0,0 +1,8 @@ +using { sap.capire.media as db } from '../db/data-model'; +namespace sap.capire.media; + +service MediaServer { + entity Media as projection on db.Media ; +} + + \ No newline at end of file diff --git a/packages/media-server/srv/media-service.js b/packages/media-server/srv/media-service.js new file mode 100644 index 00000000..f70d3b90 --- /dev/null +++ b/packages/media-server/srv/media-service.js @@ -0,0 +1,68 @@ +const loki = require('lokijs') +const db = new loki('DB') +const mediaDB = db.addCollection('Media') +const { Readable, PassThrough } = require('stream') + +module.exports = srv => { + srv.before('CREATE', 'Media', req => { + const obj = mediaDB.insert({ media: '' }) + req.data.id = obj.$loki + }) + + srv.on('UPDATE', 'Media', (req, next) => { + const url = req._.req.path + if (url.includes('content')) { + const id = req.data.id + const obj = mediaDB.get(id) + if (!obj) { + req.reject(404, 'No record found for the ID') + return + } + const stream = new PassThrough() + const chunks = [] + stream.on('data', chunk => { + chunks.push(chunk) + }) + stream.on('end', () => { + obj.media = Buffer.concat(chunks).toString('base64') + mediaDB.update(obj) + }) + req.data.content.pipe(stream) + } else return next() + }) + + srv.on('READ', 'Media', (req, next) => { + const url = req._.req.path + if (url.includes('content')) { + const id = req.data.id + const mediaObj = mediaDB.get(id) + if (!mediaObj) { + req.reject(404, 'Media not found for the ID') + return + } + const decodedMedia = new Buffer( + mediaObj.media.split(';base64,').pop(), + 'base64' + ) + return _formatResult(decodedMedia) + } else return next() //> delegate to next/default handlers + }) + + srv.on('DELETE', 'Media', (req, next) => { + const id = req.data.id + mediaDB + .chain() + .find({ $loki: id }) + .remove() + return next() //> delegate to next/default handlers + }) + + function _formatResult (decodedMedia) { + const readable = new Readable() + const result = new Array() + readable.push(decodedMedia) + readable.push(null) + result.push({ value: readable }) + return result + } +}