|
@@ -1,303 +0,0 @@
|
|
|
-/**
|
|
|
- * @module mongoRouter
|
|
|
- *
|
|
|
- * Backend module to store React-Redux components in MongoDB.
|
|
|
- */
|
|
|
-import mongoose from 'mongoose'
|
|
|
-import { Router } from 'express'
|
|
|
-mongoose.Promise = Promise
|
|
|
-
|
|
|
-const MAX_RESULTS = 100
|
|
|
-
|
|
|
-class RESTController {
|
|
|
- constructor (model, key) {
|
|
|
- this.model = model
|
|
|
- this.modelName = model.modelName.toLowerCase()
|
|
|
- this.key = key
|
|
|
- }
|
|
|
-
|
|
|
- create (data) {
|
|
|
- return this.model
|
|
|
- .create(data)
|
|
|
- .then(instance => {
|
|
|
- const response = {}
|
|
|
- response[this.modelName] = instance
|
|
|
- return response
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- read (id) {
|
|
|
- const filter = {}
|
|
|
- filter[this.key] = id
|
|
|
- return this.model
|
|
|
- .findOne(filter)
|
|
|
- .then(instance => {
|
|
|
- const response = {}
|
|
|
- response[this.modelName] = instance
|
|
|
- return response
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- list () {
|
|
|
- return this.model
|
|
|
- .find({})
|
|
|
- .limit(MAX_RESULTS)
|
|
|
- .then(instance => {
|
|
|
- const response = {}
|
|
|
- response[this.modelName] = instance
|
|
|
- return response
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- update (id, data) {
|
|
|
- const filter = {}
|
|
|
- filter[this.key] = id
|
|
|
-
|
|
|
- return this.model
|
|
|
- .findOne(filter)
|
|
|
- .then(instance => {
|
|
|
- for (let attribute in data) {
|
|
|
- if (data.hasOwnProperty(attribute) && attribute !== this.key && attribute !== '_id') {
|
|
|
- instance[attribute] = data[attribute]
|
|
|
- }
|
|
|
- }
|
|
|
- return instance.save()
|
|
|
- })
|
|
|
- .then(instance => {
|
|
|
- const response = {}
|
|
|
- response[this.modelName] = instance
|
|
|
- return response
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- route () {
|
|
|
- const router = new Router()
|
|
|
-
|
|
|
- router.get('/', (req, res) => {
|
|
|
- this
|
|
|
- .list()
|
|
|
- .then(data => res.json(data))
|
|
|
- .then(null, error => res.status(404).send(error))
|
|
|
- })
|
|
|
-
|
|
|
- router.post('/', (req, res) => {
|
|
|
- this
|
|
|
- .create(req.body)
|
|
|
- .then(data => res.json(data))
|
|
|
- .then(null, error => res.status(404).send(error))
|
|
|
- })
|
|
|
-
|
|
|
- router.get('/:key', (req, res) => {
|
|
|
- this
|
|
|
- .read(req.params.key)
|
|
|
- .then(data => res.json(data))
|
|
|
- .then(null, error => res.status(404).send(error))
|
|
|
- })
|
|
|
-
|
|
|
- router.put('/:key', (req, res) => {
|
|
|
- this
|
|
|
- .update(req.params.key, req.body)
|
|
|
- .then(data => res.json(data))
|
|
|
- .then(null, error => res.status(404).send(error))
|
|
|
- })
|
|
|
-
|
|
|
- router.delete('/:key', (req, res) => {
|
|
|
- this
|
|
|
- .delete(req.params.key)
|
|
|
- .then(data => res.json(data))
|
|
|
- .then(null, error => res.status(404).send(error))
|
|
|
- })
|
|
|
-
|
|
|
- return router
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-export default RESTController
|
|
|
-
|
|
|
-/**
|
|
|
- * Generates GET, POST, UPDATE and DELETE handlers which interact with
|
|
|
- * MongoDB.
|
|
|
- *
|
|
|
- * For versioned objects, allow querying for tags or for IDs. When querying
|
|
|
- * tags, return the head version, when querying for IDs, just return the
|
|
|
- * element.
|
|
|
- *
|
|
|
- * @param {object} Model - mongoose model to use
|
|
|
- * @param {boolean} versioned - use a revision control mechanism
|
|
|
- * @return {[type]}
|
|
|
- */
|
|
|
-function routeGen (Model, versioned = true) {
|
|
|
- /** GET handler (request one item or a list of items) */
|
|
|
- const get = (req, res) => {
|
|
|
- let { id } = req.params
|
|
|
-
|
|
|
- /** check whether an id was specified. */
|
|
|
- if (typeof id === 'string' && id.length > 1) {
|
|
|
- try {
|
|
|
- // try to convert the id string to a valid ObjectId
|
|
|
- const _id = mongoose.Types.ObjectId(id)
|
|
|
- // if yes, return the one item
|
|
|
- Model.findOne({ _id }, function (err, item) {
|
|
|
- console.log(item)
|
|
|
- if (err) {
|
|
|
- res.status(404)
|
|
|
- res.send(err)
|
|
|
- return
|
|
|
- }
|
|
|
- res.json(item)
|
|
|
- })
|
|
|
- } catch (err) {
|
|
|
- // If id couldn't be converted, assume it's a tag.
|
|
|
- const tag = id
|
|
|
- // if yes, return the one item
|
|
|
- Model.findOne({ tag, 'history.head': true }, function (err, item) {
|
|
|
- if (err) {
|
|
|
- res.status(404)
|
|
|
- res.send(err)
|
|
|
- return
|
|
|
- }
|
|
|
- res.json(item)
|
|
|
- })
|
|
|
- }
|
|
|
- } else {
|
|
|
- // if not, return a list of items
|
|
|
- // limit the number of returned items and use an offset
|
|
|
- const limit = req.query.limit ? Math.min(Math.max(parseInt(req.query.limit), 1), 100) : 20
|
|
|
- const offset = req.query.offset ? Math.max(parseInt(req.query.offset), 0) : 0
|
|
|
- Model.find({'history.head': true}, {limit: limit, skip: offset}, function (err, items) {
|
|
|
- console.log(err, items)
|
|
|
- if (err) {
|
|
|
- res.status(404)
|
|
|
- res.send(err)
|
|
|
- return
|
|
|
- }
|
|
|
- res.json(items)
|
|
|
- })
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /** POST handler (insert a new item into the database) */
|
|
|
- const post = (req, res) => {
|
|
|
- // create the new item
|
|
|
- console.log(req.body)
|
|
|
- const item = new Model(req.body)
|
|
|
- console.log(item)
|
|
|
-
|
|
|
- // Check, if the model supports revision control
|
|
|
- if (typeof Model.schema.obj.__history !== 'undefined') {
|
|
|
- console.log('creating new history')
|
|
|
- item.__history = {
|
|
|
- author: 'Tomi',
|
|
|
- created: new Date(),
|
|
|
- tag: 'myTag',
|
|
|
- reference: 'reference',
|
|
|
- head: true,
|
|
|
- comment: 'My Comment'
|
|
|
- }
|
|
|
- }
|
|
|
- console.log(item)
|
|
|
-
|
|
|
- // save the item
|
|
|
- console.log('before save')
|
|
|
- const p = item.save()
|
|
|
- console.log(p)
|
|
|
- p.then(savedItem => {
|
|
|
- console.log('in save', savedItem)
|
|
|
- res.status(200)
|
|
|
- res.send({ _id: savedItem._id })
|
|
|
- }).catch(err => {
|
|
|
- console.log('in save', err)
|
|
|
- res.status(422)
|
|
|
- res.send(err)
|
|
|
- })
|
|
|
- console.log('after save', p)
|
|
|
- }
|
|
|
-
|
|
|
- /** PUT handler (update existing project) */
|
|
|
- const put = (req, res) => {
|
|
|
- let id = req.params['0']
|
|
|
- /** check whether an id was specified. */
|
|
|
- if (typeof id === 'string' && id.length > 1) {
|
|
|
- // remove leading slash
|
|
|
- id = id.substring(1)
|
|
|
- try {
|
|
|
- // try to convert the id string to a valid ObjectId
|
|
|
- id = mongoose.Types.ObjectId(req.params['1'].substring(1))
|
|
|
- } catch (err) {
|
|
|
- // If id couldn't be converted, return an error message.
|
|
|
- res.status(422)
|
|
|
- res.send({error: err.message})
|
|
|
- return
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Find the object in the database
|
|
|
- Model.findOne({ _id: id }, function (err, item) {
|
|
|
- if (err) {
|
|
|
- res.status(404)
|
|
|
- res.send(err)
|
|
|
- }
|
|
|
-
|
|
|
- // Check, if the model supports revision control
|
|
|
- if (typeof Model.schema.obj.__history !== 'undefined') {
|
|
|
- // If yes, don't update the item, but create a new one based on the original
|
|
|
- const newItem = Model(item)
|
|
|
- // replace the requested elements
|
|
|
- for (let prop in req.body) {
|
|
|
- newItem[prop] = req.body[prop]
|
|
|
- }
|
|
|
- // give it a new history with updated reference array. Set the head-indicator to true
|
|
|
- newItem.__history.create({
|
|
|
- author: '',
|
|
|
- created: Date(),
|
|
|
- tag: '',
|
|
|
- reference: [ ...item.__history.reference, item._id ],
|
|
|
- head: true
|
|
|
- })
|
|
|
- // set the original item's head indicator to false
|
|
|
- item.__history.head = false
|
|
|
- // save the documents
|
|
|
- newItem.save(function (err) {
|
|
|
- if (err) {
|
|
|
- res.status(422)
|
|
|
- res.send(err)
|
|
|
- }
|
|
|
- res.json({ message: `${Model.modelName} updated.` })
|
|
|
- })
|
|
|
- } else {
|
|
|
- for (let prop in req.body) {
|
|
|
- item[prop] = req.body[prop]
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- item.save(function (err) {
|
|
|
- if (err) {
|
|
|
- res.status(422)
|
|
|
- res.send(err)
|
|
|
- }
|
|
|
- res.json({ message: `${Model.modelName} updated.` })
|
|
|
- })
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- /** DELETE handler (delete project) */
|
|
|
- const del = (req, res) => {
|
|
|
- const id = mongoose.Types.ObjectId(req.params['0'])
|
|
|
-
|
|
|
- Model.remove({ _id: id }, function (err, project) {
|
|
|
- if (err) {
|
|
|
- res.send(err)
|
|
|
- }
|
|
|
- res.json({ message: 'Movie deleted.' })
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- return {
|
|
|
- get,
|
|
|
- post,
|
|
|
- put,
|
|
|
- del
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-export { routeGen }
|