Document.js 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. var Document = module.exports = (function(){
  2. // CONSTRUCTOR
  3. /**
  4. * Represents a `Document` (i.e., an `Object`) in `mongo` but in `munge` this is only a set of static helpers since we treat all `Object`s like `Document`s.
  5. *
  6. * @class Document
  7. * @namespace munge.pipeline
  8. * @module munge
  9. * @constructor
  10. **/
  11. var klass = function Document(){
  12. if(this.constructor == Document) throw new Error("Never create instances! Use static helpers only.");
  13. }, base = Object, proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
  14. // DEPENDENCIES
  15. var Value = require("./Value");
  16. // STATIC MEMBERS
  17. /**
  18. * Shared "_id"
  19. *
  20. * @static
  21. * @property ID_PROPERTY_NAME
  22. **/
  23. klass.ID_PROPERTY_NAME = "_id";
  24. /**
  25. * Compare two documents.
  26. * BSON document field order is significant, so this just goes through the fields in order.
  27. * The comparison is done in roughly the same way as strings are compared, but comparing one field at a time instead of one character at a time.
  28. *
  29. * @static
  30. * @method compare
  31. * @param rL left document
  32. * @param rR right document
  33. * @returns an integer less than zero, zero, or an integer greater than zero, depending on whether rL < rR, rL == rR, or rL > rR
  34. **/
  35. klass.compare = function compare(l, r){ //TODO: might be able to replace this with a straight compare of docs using JSON.stringify()
  36. var lPropNames = Object.getOwnPropertyNames(l),
  37. lPropNamesLength = lPropNames.length,
  38. rPropNames = Object.getOwnPropertyNames(r),
  39. rPropNamesLength = rPropNames.length;
  40. for(var i = 0; true; ++i) {
  41. if (i >= lPropNamesLength) {
  42. if (i >= rPropNamesLength) return 0; // documents are the same length
  43. return -1; // left document is shorter
  44. }
  45. if (i >= rPropNamesLength) return 1; // right document is shorter
  46. var nameCmp = Value.compare(lPropNames[i], rPropNames[i]);
  47. if (nameCmp !== 0) return nameCmp; // field names are unequal
  48. var valueCmp = Value.compare(l[lPropNames[i]], r[rPropNames[i]]);
  49. if (valueCmp) return valueCmp; // fields are unequal
  50. }
  51. /* NOTREACHED */
  52. throw new Error("This should never happen"); //verify(false)
  53. // return 0;
  54. };
  55. // proto.addField = function addField(){ throw new Error("Instead of `Document#addField(key,val)` you should just use `obj[key] = val`"); }
  56. // proto.setField = function addField(){ throw new Error("Instead of `Document#setField(key,val)` you should just use `obj[key] = val`"); }
  57. // proto.getField = function getField(){ throw new Error("Instead of `Document#getField(key)` you should just use `var val = obj[key];`"); }
  58. return klass;
  59. })();