RESTControllerVersioned.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /**
  2. * @module RESTControllerVersioned
  3. */
  4. import * as debugStuff from 'debug'
  5. const debug = debugStuff.debug('dbApiRESTCtrlVer')
  6. import RESTController from './RESTController'
  7. const MAX_RESULTS = 100
  8. /**
  9. * REST controller for MongoDB backend.
  10. */
  11. class RESTControllerVersioned extends RESTController {
  12. constructor (model, key = '_id', subDocuments = {}) {
  13. super(model, key, subDocuments)
  14. this.filterOptions = { limit: MAX_RESULTS, skip: 0 }
  15. this.filterCriteria = { '_history.head': true }
  16. debug('created RESTControllerVersioned', this.modelName)
  17. }
  18. /**
  19. * Override create function to support versioning.
  20. *
  21. * This function generates a history object to allow revision control
  22. * of the data elements.
  23. *
  24. * @param {object} data object
  25. * @return {Promise}
  26. */
  27. create (data) {
  28. debug('create data item', data)
  29. const { author, version, comment, ...newData } = data
  30. const history = {
  31. author,
  32. created: new Date(),
  33. version,
  34. comment,
  35. head: true,
  36. reference: []
  37. }
  38. newData._history = history
  39. const p = this.model
  40. .create(newData)
  41. .then(instance => {
  42. debug('created instance', instance)
  43. return instance
  44. })
  45. // debug('create return value', p)
  46. return p
  47. }
  48. /**
  49. * Override read to search by default for head version of given tag.
  50. *
  51. * @param {[type]}
  52. * @return {[type]}
  53. */
  54. read (tag) {
  55. if (typeof tag === 'string') {
  56. tag = { tag: tag }
  57. }
  58. debug('reading data item', tag)
  59. const filter = { ...this.filterCriteria, ...tag }
  60. const p = this.model
  61. .findOne(filter)
  62. .then(instance => {
  63. debug('read instance', instance)
  64. return instance
  65. })
  66. // debug('read return value', p)
  67. return p
  68. }
  69. /**
  70. * Get a list of all DB items.
  71. *
  72. * @return {Promise}
  73. */
  74. list (filter = this.filterCriteria) {
  75. debug('reading data list')
  76. const p = this.model
  77. .find(filter)
  78. .limit(MAX_RESULTS)
  79. .then(instance => {
  80. debug('read list instance', instance)
  81. return instance
  82. })
  83. // debug('read return value', p)
  84. return p
  85. }
  86. /**
  87. * Override update to support versioning.
  88. *
  89. * @param {String} id
  90. * @param {String} data
  91. * @return {Promise}
  92. */
  93. update (tag, data) {
  94. if (typeof tag === 'string') {
  95. tag = { tag: tag }
  96. }
  97. debug('update data item', tag, data)
  98. const filter = { ...this.filterCriteria, ...tag }
  99. const p = this.model
  100. .findOne(filter)
  101. .then(instance => {
  102. debug('found data instance', instance)
  103. instance._history.head = false
  104. return instance.save()
  105. })
  106. .then(instance => {
  107. const { _id, __v, _history, ...oldData } = instance._doc
  108. debug('creating new data instance', oldData)
  109. const { author, version, comment, ...newItems } = data
  110. const newData = { ...oldData, ...newItems }
  111. newData._history = {
  112. author,
  113. created: new Date(),
  114. version,
  115. comment,
  116. head: true,
  117. reference: [ _id, ..._history.reference ]
  118. }
  119. return this.model
  120. .create(newData)
  121. .then(instance => {
  122. debug('created instance', instance)
  123. return instance
  124. })
  125. })
  126. // debug('read return value', p)
  127. return p
  128. }
  129. /**
  130. * Override delete. We don't delete. Just not our thing...
  131. *
  132. * @param {String} id
  133. * @return {Promise}
  134. */
  135. delete (tag) {
  136. if (typeof tag === 'string') {
  137. tag = { tag: tag }
  138. }
  139. debug('delete data item', tag)
  140. const filter = { ...this.filterCriteria, ...tag }
  141. const p = this.model
  142. .findOne(filter)
  143. .then(instance => {
  144. instance._history.head = false
  145. return instance.save()
  146. })
  147. // debug('read return value', p)
  148. return p
  149. }
  150. }
  151. export default RESTControllerVersioned