Source: components/bridge-store.js

  1. "use strict";
  2. var Promise = require("bluebird");
  3. // wrapper to use promises
  4. var callbackFn = function(d, err, result) {
  5. if (err) {
  6. d.reject(err);
  7. }
  8. else {
  9. d.resolve(result);
  10. }
  11. };
  12. /**
  13. * Bridge store base class
  14. * @constructor
  15. * @param {Datastore} db
  16. */
  17. function BridgeStore(db) {
  18. this.db = db;
  19. }
  20. /**
  21. * INSERT a multiple documents.
  22. * @param {Object} objects
  23. * @param {Deferred=} defer
  24. * @return {Promise}
  25. */
  26. BridgeStore.prototype.insert = function(objects, defer) {
  27. defer = defer || new Promise.defer();
  28. this.db.insert(objects, function(err, result) {
  29. callbackFn(defer, err, result);
  30. });
  31. return defer.promise;
  32. };
  33. /**
  34. * UPSERT a single document.
  35. * @param {Object} query
  36. * @param {Object} updateVals
  37. * @param {Deferred=} defer
  38. * @return {Promise}
  39. */
  40. BridgeStore.prototype.upsert = function(query, updateVals, defer) {
  41. defer = defer || new Promise.defer();
  42. this.db.update(query, updateVals, {upsert: true}, function(err, result) {
  43. callbackFn(defer, err, result);
  44. });
  45. return defer.promise;
  46. };
  47. /**
  48. * INSERT IF NOT EXISTS a single document.
  49. * @param {Object} query
  50. * @param {Object} insertObj
  51. * @return {Promise}
  52. */
  53. BridgeStore.prototype.insertIfNotExists = function(query, insertObj) {
  54. var self = this;
  55. return self.selectOne(query).then(function(doc) {
  56. if (doc) {
  57. return Promise.resolve();
  58. }
  59. return self.insert(insertObj);
  60. });
  61. };
  62. /**
  63. * UPDATE a single document. If the document already exists, this will NOT update
  64. * it.
  65. * @param {Object} query
  66. * @param {Object} updateVals
  67. * @param {Deferred=} defer
  68. * @return {Promise}
  69. */
  70. BridgeStore.prototype.update = function(query, updateVals, defer) {
  71. defer = defer || new Promise.defer();
  72. this.db.update(query, updateVals, {upsert: false}, function(err, result) {
  73. callbackFn(defer, err, result);
  74. });
  75. return defer.promise;
  76. };
  77. /**
  78. * DELETE multiple documents.
  79. * @param {Object} query
  80. * @param {Deferred=} defer
  81. * @return {Promise}
  82. */
  83. BridgeStore.prototype.delete = function(query, defer) {
  84. defer = defer || new Promise.defer();
  85. this.db.remove(query, {multi: true}, function(err, result) {
  86. callbackFn(defer, err, result);
  87. });
  88. return defer.promise;
  89. };
  90. /**
  91. * SELECT a single document.
  92. * @param {Object} query
  93. * @param {Function} transformFn
  94. * @param {Deferred=} defer
  95. * @return {Promise}
  96. */
  97. BridgeStore.prototype.selectOne = function(query, transformFn, defer) {
  98. defer = defer || new Promise.defer();
  99. this.db.findOne(query, function(err, doc) {
  100. callbackFn(defer, err, transformFn ? transformFn(doc) : doc);
  101. });
  102. return defer.promise;
  103. };
  104. /**
  105. * SELECT a number of documents.
  106. * @param {Object} query
  107. * @param {Function} transformFn
  108. * @param {Deferred=} defer
  109. * @return {Promise}
  110. */
  111. BridgeStore.prototype.select = function(query, transformFn, defer) {
  112. defer = defer || new Promise.defer();
  113. this.db.find(query, function(err, docs) {
  114. callbackFn(defer, err, transformFn ? transformFn(docs) : docs);
  115. });
  116. return defer.promise;
  117. };
  118. /**
  119. * Set a UNIQUE key constraint on the given field.
  120. * @param {string} fieldName The field name. Use dot notation for nested objects.
  121. * @param {boolean} sparse Allow sparse entries (undefined won't cause a key
  122. * violation). Default: false.
  123. */
  124. BridgeStore.prototype.setUnique = function(fieldName, sparse) {
  125. sparse = sparse || false;
  126. this.db.ensureIndex({
  127. fieldName: fieldName,
  128. unique: true,
  129. sparse: sparse
  130. });
  131. };
  132. /**
  133. * Convenience method to convert a document to something.
  134. * @param {Function} func The function which will be called with a single document
  135. * object. Guaranteed not to be null.
  136. * @return {Function} A <code>transformFn</code> function to pass to the standard
  137. * select/delete/upsert/etc methods.
  138. */
  139. BridgeStore.prototype.convertTo = function(func) {
  140. return function(doc) {
  141. if (!doc) { // findOne query will return 'null' on no matches.
  142. return null;
  143. }
  144. if (Array.isArray(doc)) {
  145. return doc.map(function(d) {
  146. return func(d);
  147. });
  148. }
  149. return func(doc);
  150. };
  151. };
  152. module.exports = BridgeStore;