modifier.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. // Copyright 2015 The MemDB Authors.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
  12. // implied. See the License for the specific language governing
  13. // permissions and limitations under the License. See the AUTHORS file
  14. // for names of contributors.
  15. 'use strict';
  16. var utils = require('./utils');
  17. //http://docs.mongodb.org/manual/reference/limits/#Restrictions-on-Field-Names
  18. var verifyDoc = function(doc){
  19. if(doc === null || typeof(doc) !== 'object'){
  20. return;
  21. }
  22. for(var key in doc){
  23. if(key[0] === '$'){
  24. throw new Error('Document fields can not start with "$"');
  25. }
  26. if(key.indexOf('.') !== -1){
  27. throw new Error('Document fields can not contain "."');
  28. }
  29. verifyDoc(doc[key]);
  30. }
  31. };
  32. exports.$insert = function(doc, param){
  33. param = param || {};
  34. if(doc !== null){
  35. throw new Error('doc already exists');
  36. }
  37. verifyDoc(param);
  38. return param;
  39. };
  40. exports.$replace = function(doc, param){
  41. param = param || {};
  42. if(doc === null){
  43. throw new Error('doc not exist');
  44. }
  45. verifyDoc(param);
  46. return param;
  47. };
  48. exports.$remove = function(doc, param){
  49. if(doc === null){
  50. throw new Error('doc not exist');
  51. }
  52. return null;
  53. };
  54. exports.$set = function(doc, param){
  55. if(doc === null){
  56. throw new Error('doc not exist');
  57. }
  58. for(var path in param){
  59. verifyDoc(param[path]);
  60. utils.setObjPath(doc, path, param[path]);
  61. }
  62. return doc;
  63. };
  64. exports.$unset = function(doc, param){
  65. if(doc === null){
  66. throw new Error('doc not exist');
  67. }
  68. for(var path in param){
  69. if(!!param[path]){
  70. utils.deleteObjPath(doc, path);
  71. }
  72. }
  73. return doc;
  74. };
  75. exports.$inc = function(doc, param){
  76. if(doc === null){
  77. throw new Error('doc not exist');
  78. }
  79. for(var path in param){
  80. var value = utils.getObjPath(doc, path);
  81. var delta = param[path];
  82. if(value === undefined){
  83. value = 0;
  84. }
  85. if(typeof(value) !== 'number' || typeof(delta) !== 'number'){
  86. throw new Error('$inc non-number');
  87. }
  88. utils.setObjPath(doc, path, value + delta);
  89. }
  90. return doc;
  91. };
  92. exports.$push = function(doc, param){
  93. if(doc === null){
  94. throw new Error('doc not exist');
  95. }
  96. for(var path in param){
  97. var arr = utils.getObjPath(doc, path);
  98. if(arr === undefined){
  99. utils.setObjPath(doc, path, []);
  100. arr = utils.getObjPath(doc, path);
  101. }
  102. if(!Array.isArray(arr)){
  103. throw new Error('$push to non-array');
  104. }
  105. verifyDoc(param[path]);
  106. arr.push(param[path]);
  107. }
  108. return doc;
  109. };
  110. exports.$pushAll = function(doc, param){
  111. if(doc === null){
  112. throw new Error('doc not exist');
  113. }
  114. for(var path in param){
  115. var arr = utils.getObjPath(doc, path);
  116. if(arr === undefined){
  117. utils.setObjPath(doc, path, []);
  118. arr = utils.getObjPath(doc, path);
  119. }
  120. if(!Array.isArray(arr)){
  121. throw new Error('$push to non-array');
  122. }
  123. var items = param[path];
  124. if(!Array.isArray(items)){
  125. items = [items];
  126. }
  127. for(var i in items){
  128. verifyDoc(items[i]);
  129. arr.push(items[i]);
  130. }
  131. }
  132. return doc;
  133. };
  134. exports.$addToSet = function(doc, param){
  135. if(doc === null){
  136. throw new Error('doc not exist');
  137. }
  138. for(var path in param){
  139. var arr = utils.getObjPath(doc, path);
  140. if(arr === undefined){
  141. utils.setObjPath(doc, path, []);
  142. arr = utils.getObjPath(doc, path);
  143. }
  144. if(!Array.isArray(arr)){
  145. throw new Error('$addToSet to non-array');
  146. }
  147. var value = param[path];
  148. if(arr.indexOf(value) === -1){
  149. verifyDoc(value);
  150. arr.push(value);
  151. }
  152. }
  153. return doc;
  154. };
  155. exports.$pop = function(doc, param){
  156. if(doc === null){
  157. throw new Error('doc not exist');
  158. }
  159. for(var path in param){
  160. var arr = utils.getObjPath(doc, path);
  161. if(Array.isArray(arr)){
  162. arr.pop();
  163. }
  164. }
  165. return doc;
  166. };
  167. exports.$pull = function(doc, param){
  168. if(doc === null){
  169. throw new Error('doc not exist');
  170. }
  171. for(var path in param){
  172. var arr = utils.getObjPath(doc, path);
  173. if(Array.isArray(arr)){
  174. var value = param[path];
  175. var i = arr.indexOf(value);
  176. if(i !== -1){
  177. arr.splice(i, 1);
  178. }
  179. }
  180. }
  181. return doc;
  182. };
  183. exports.$pullAll = function(doc, param){
  184. if(doc === null){
  185. throw new Error('doc not exist');
  186. }
  187. for(var path in param){
  188. var arr = utils.getObjPath(doc, path);
  189. if(Array.isArray(arr)){
  190. var values = param[path];
  191. if(!Array.isArray(values)){
  192. values = [values];
  193. }
  194. values.forEach(function(value){
  195. var i = arr.indexOf(value);
  196. if(i !== -1){
  197. arr.splice(i, 1);
  198. }
  199. }); //jshint ignore:line
  200. }
  201. }
  202. return doc;
  203. };