Document.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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. // DEPENDENCIES
  13. var Value = require("./Value");
  14. // STATIC MEMBERS
  15. /**
  16. * Shared "_id"
  17. * @static
  18. * @property ID_PROPERTY_NAME
  19. **/
  20. klass.ID_PROPERTY_NAME = "_id";
  21. /**
  22. * Return JSON representation of this Document
  23. *
  24. * @method toJson
  25. * @returns JSON representation of this Document
  26. **/
  27. klass.toJson = function toJson(document){
  28. return JSON.stringify(document);
  29. };
  30. /**
  31. * Return JSON representation of this Document
  32. *
  33. * @method toJsonWithMetaData
  34. * @returns JSON representation of this Document, with MetaData
  35. **/
  36. klass.toJsonWithMetaData = function toJsonWithMetaData(document){
  37. //NOTE: DEVIATION FROM MONGO: Not sure how we are handling metadata
  38. return JSON.stringify(document);
  39. };
  40. /**
  41. * Return Document with MetaData from its JSON representation
  42. *
  43. * @method fromJsonWithMetaData
  44. * @returns Document with MetaData
  45. **/
  46. klass.fromJsonWithMetaData = function fromJsonWithMetaData(json){
  47. return JSON.parse(json);
  48. };
  49. /**
  50. * Compare two documents.
  51. *
  52. * BSON document field order is significant, so this just goes through the fields in order.
  53. * 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.
  54. *
  55. * @static
  56. * @method compare
  57. * @param rL left document
  58. * @param rR right document
  59. * @returns an integer less than zero, zero, or an integer greater than zero, depending on whether rL < rR, rL == rR, or rL > rR
  60. **/
  61. klass.compare = function compare(l, r){ //TODO: might be able to replace this with a straight compare of docs using JSON.stringify()
  62. var lPropNames = Object.getOwnPropertyNames(l),
  63. lPropNamesLength = lPropNames.length,
  64. rPropNames = Object.getOwnPropertyNames(r),
  65. rPropNamesLength = rPropNames.length;
  66. for(var i = 0; true; ++i) {
  67. if (i >= lPropNamesLength) {
  68. if (i >= rPropNamesLength) return 0; // documents are the same length
  69. return -1; // left document is shorter
  70. }
  71. if (i >= rPropNamesLength) return 1; // right document is shorter
  72. var nameCmp = Value.compare(lPropNames[i], rPropNames[i]);
  73. if (nameCmp !== 0) return nameCmp; // field names are unequal
  74. var valueCmp = Value.compare(l[lPropNames[i]], r[rPropNames[i]]);
  75. if (valueCmp) return valueCmp; // fields are unequal
  76. }
  77. /* NOTREACHED */
  78. throw new Error("This should never happen"); //verify(false)
  79. // return 0;
  80. };
  81. /**
  82. * Clone a document
  83. * @static
  84. * @method clone
  85. * @param document
  86. **/
  87. klass.clone = function(document){
  88. var obj = {};
  89. for(var key in document){
  90. if(document.hasOwnProperty(key)){
  91. var withObjVal = document[key];
  92. if(withObjVal === null) { // necessary to handle null values without failing
  93. obj[key] = withObjVal;
  94. }
  95. else if(withObjVal.constructor === Object){
  96. obj[key] = Document.clone(withObjVal);
  97. }else{
  98. obj[key] = withObjVal;
  99. }
  100. }
  101. }
  102. return obj;
  103. };
  104. //NOTE: not implementing the sorter functions until we understand sorter needs better
  105. var _waitingOnSorter = function() {
  106. //TODO: When working on sorter, decide if this is needed
  107. throw new Error("Not implemented.");
  108. };
  109. klass.serializeForSorter = function(document) {
  110. var buffer, size = 0, key;
  111. //determine size for sorter??
  112. //for (key in document) {
  113. // if (document.hasOwnProperty(key)) size++;
  114. //};
  115. //add size to buffer (don't count size field)
  116. //buffer = (size-1).toString();
  117. //add each field
  118. //for (key in document) {
  119. // buffer += document[key]);
  120. //};
  121. //append text score?
  122. //return buffer;
  123. return JSON.stringify(document);
  124. };
  125. klass.deserializeForSorter = function(stringifiedDocument) {
  126. //_waitingOnSorter();
  127. //var document, size;
  128. //size = int.parse(stringifiedDocument.split(",")[0]);
  129. //document["size"] = size;
  130. //document = JSON.parse(stringifiedDocument);
  131. return JSON.parse(stringifiedDocument);
  132. };
  133. klass.memUsageForSorter = function(value) {
  134. _waitingOnSorter();
  135. };
  136. klass.getOwned = function() {
  137. return proto;
  138. };
  139. // proto.addField = function addField(){ throw new Error("Instead of `Document#addField(key,val)` you should just use `obj[key] = val`"); }
  140. // proto.setField = function addField(){ throw new Error("Instead of `Document#setField(key,val)` you should just use `obj[key] = val`"); }
  141. // proto.getField = function getField(){ throw new Error("Instead of `Document#getField(key)` you should just use `var val = obj[key];`"); }