Document.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. "use strict";
  2. /**
  3. * 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.
  4. * @class Document
  5. * @namespace mungedb-aggregate.pipeline
  6. * @module mungedb-aggregate
  7. * @constructor
  8. **/
  9. var Document = module.exports = function Document(){
  10. if(this.constructor == Document) throw new Error("Never create instances! Use static helpers only.");
  11. }, klass = Document, base = Object, proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
  12. var Value = require("./Value");
  13. /**
  14. * Shared "_id"
  15. * @static
  16. * @property ID_PROPERTY_NAME
  17. **/
  18. klass.ID_PROPERTY_NAME = "_id";
  19. //SKIPPED: DocumentStorage
  20. /**
  21. * Return JSON representation of this Document
  22. * @method toJson
  23. * @returns {Object} JSON representation of this Document
  24. **/
  25. klass.toJson = function toJson(doc) {
  26. return JSON.parse(JSON.stringify(doc));
  27. };
  28. //SKIPPED: metaFieldTextScore
  29. //SKIPPED: toBsonWithMetaData
  30. //SKIPPED: fromBsonWithMetaData
  31. //SKIPPED: MutableDocument
  32. //SKIPPED: getNestedFieldHelper
  33. //SKIPPED: getNestedField -- same as getNestedFieldHelper in our code
  34. //SKIPPED: getApproximateSize -- not implementing mem usage right now
  35. //SKIPPED: hash_combine
  36. /** Compare two documents.
  37. *
  38. * BSON document field order is significant, so this just goes through
  39. * the fields in order. The comparison is done in roughly the same way
  40. * as strings are compared, but comparing one field at a time instead
  41. * of one character at a time.
  42. *
  43. * Note: This does not consider metadata when comparing documents.
  44. *
  45. * @method compare
  46. * @static
  47. * @param l {Object} left document
  48. * @param r {Object} right document
  49. * @returns an integer less than zero, zero, or an integer greater than
  50. * zero, depending on whether lhs < rhs, lhs == rhs, or lhs > rhs
  51. * Warning: may return values other than -1, 0, or 1
  52. */
  53. klass.compare = function compare(l, r){ //TODO: might be able to replace this with a straight compare of docs using JSON.stringify()
  54. var lPropNames = Object.getOwnPropertyNames(l),
  55. lPropNamesLength = lPropNames.length,
  56. rPropNames = Object.getOwnPropertyNames(r),
  57. rPropNamesLength = rPropNames.length;
  58. for(var i = 0; true; ++i) {
  59. if (i >= lPropNamesLength) {
  60. if (i >= rPropNamesLength) return 0; // documents are the same length
  61. return -1; // left document is shorter
  62. }
  63. if (i >= rPropNamesLength) return 1; // right document is shorter
  64. var rField = rPropNames[i],
  65. lField = lPropNames[i];
  66. var nameCmp = Value.compare(lField, rField);
  67. if (nameCmp !== 0) return nameCmp; // field names are unequal
  68. var valueCmp = Value.compare(l[lPropNames[i]], r[rField]);
  69. if (valueCmp) return valueCmp; // fields are unequal
  70. }
  71. };
  72. //SKIPPED: toString
  73. klass.serializeForSorter = function serializeForSorter(doc) {
  74. //NOTE: DEVIATION FROM MONGO: they take a buffer to output the current instance into, ours is static and takes a doc and returns the serialized output
  75. return JSON.stringify(doc);
  76. };
  77. klass.deserializeForSorter = function deserializeForSorter(docStr, sorterDeserializeSettings) {
  78. JSON.parse(docStr);
  79. };
  80. //SKIPPED: swap
  81. //SKIPPED: []
  82. //SKIPPED: getField -- inline as: obj[key]
  83. //SKIPPED: getNestedField -- use fieldPath? might need to implement this...
  84. //SKIPPED: size -- need this? Number of fields in this document. O(n) -- recursive
  85. klass.empty = function(obj) {
  86. return Object.keys(obj).length === 0;
  87. };
  88. //SKIPPED: operator <<
  89. //SKIPPED: positionOf
  90. /**
  91. * Clone a document
  92. * @static
  93. * @method clone
  94. * @param doc
  95. */
  96. klass.clone = function clone(doc) {
  97. var obj = {};
  98. for (var key in doc) {
  99. if (doc.hasOwnProperty(key)) {
  100. var val = doc[key];
  101. if (val === undefined || val === null) { // necessary to handle null values without failing
  102. obj[key] = val;
  103. } else if (val instanceof Object && val.constructor === Object) {
  104. obj[key] = Document.clone(val);
  105. } else {
  106. obj[key] = val;
  107. }
  108. }
  109. }
  110. return obj;
  111. };
  112. //SKIPPED: hasTextScore
  113. //SKIPPED: getTextScore
  114. //SKIPPED: memUsageForSorter -- not implementing mem usage right now
  115. //SKIPPED: getOwned -- not implementing mem usage right now
  116. //SKIPPED: getPtr