ProjectDocumentSource.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. "use strict";
  2. var ProjectDocumentSource = module.exports = (function(){
  3. // CONSTRUCTOR
  4. /**
  5. * A base class for filter document sources
  6. *
  7. * @class ProjectDocumentSource
  8. * @namespace munge.pipeline.documentsource
  9. * @module munge
  10. * @constructor
  11. * @param {ExpressionContext}
  12. **/
  13. var klass = module.exports = ProjectDocumentSource = function ProjectDocumentSource(/*pCtx*/){
  14. if(arguments.length !== 0) throw new Error("zero args expected");
  15. base.call(this);
  16. this.EO = new ObjectExpression();
  17. this._raw = undefined;
  18. }, base = require('./DocumentSource'), proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
  19. // DEPENDENCIES
  20. var Expression = require('../expressions/Expression');
  21. var ObjectExpression = require('../expressions/ObjectExpression');
  22. var Value = require('../Value');
  23. /**
  24. * Returns the name of project
  25. *
  26. * @return {string} the name of project
  27. **/
  28. klass.projectName = "$project";
  29. proto.getSourceName = function getSourceName() {
  30. return klass.projectName;
  31. };
  32. /**
  33. * Returns the object that was used to construct the ProjectDocumentSource
  34. *
  35. * @return {object} the object that was used to construct the ProjectDocumentSource
  36. **/
  37. proto.getRaw = function getRaw() {
  38. return this._raw;
  39. };
  40. /**
  41. * Calls base document source eof()
  42. *
  43. * @return {bool} The result of base.pSource.eof()
  44. **/
  45. proto.eof = function eof() {
  46. return this.pSource.eof();
  47. };
  48. /**
  49. * Calls base document source advance()
  50. *
  51. * @return {bool} The result of base.pSource.advance()
  52. **/
  53. proto.advance = function advance() {
  54. return this.pSource.advance();
  55. };
  56. /**
  57. * Builds a new document(object) that represents this base document
  58. *
  59. * @return {object} A document that represents this base document
  60. **/
  61. proto.getCurrent = function getCurrent() {
  62. var inDocument = this.pSource.getCurrent();
  63. if (!inDocument) {
  64. throw new Error('inDocument must be an object');
  65. }
  66. var resultDocument = {};
  67. this.EO.addToDocument(resultDocument, inDocument, /*root=*/inDocument);
  68. return resultDocument;
  69. };
  70. /**
  71. * Optimizes the internal ObjectExpression
  72. *
  73. * @return
  74. **/
  75. proto.optimize = function optimize() {
  76. this.EO.optimize();
  77. };
  78. proto.toJSON = function toJSON(){
  79. var obj = {};
  80. this.sourceToJson(obj);
  81. return obj;
  82. };
  83. /**
  84. * Places a $project key inside the builder object with value of this.EO
  85. *
  86. * @method sourceToJson
  87. * @param {builder} An object (was ported from BsonBuilder)
  88. * @return
  89. **/
  90. proto.sourceToJson = function sourceToJson(builder, explain) {
  91. var insides = this.EO.toJson(true);
  92. builder[this.getSourceName()] = insides;
  93. };
  94. /**
  95. * Builds a new ProjectDocumentSource from an object
  96. *
  97. * @method createFromJson
  98. * @return {ProjectDocmentSource} a ProjectDocumentSource instance
  99. **/
  100. klass.createFromJson = function(jsonElement, expCtx) {
  101. if(!(jsonElement instanceof Object) || jsonElement.constructor !== Object) {
  102. throw new Error('Error 15969. Specification must be an object but was ' + typeof jsonElement);
  103. }
  104. var objectContext = new Expression.ObjectCtx({
  105. isDocumentOk:true,
  106. isTopLevel:true,
  107. isInclusionOk:true
  108. });
  109. var project = new ProjectDocumentSource();
  110. project._raw = jsonElement;
  111. var parsed = Expression.parseObject(jsonElement, objectContext);
  112. var exprObj = parsed;
  113. if(! exprObj instanceof ObjectExpression) {
  114. throw new Error("16402, parseObject() returned wrong type of Expression");
  115. }
  116. if(!exprObj.getFieldCount()) {
  117. throw new Error("16403, $projection requires at least one output field");
  118. }
  119. project.EO = exprObj;
  120. return project;
  121. };
  122. /**
  123. * Adds dependencies to the contained ObjectExpression
  124. *
  125. * @param {deps} An object that is treated as a set of strings
  126. * @return A string that is part of the GetDepsReturn enum
  127. **/
  128. proto.getDependencies = function getDependencies(deps) {
  129. var path = [];
  130. this.EO.addDependencies(deps, path);
  131. return base.GetDepsReturn.EXHAUSTIVE;
  132. };
  133. /**
  134. * Reset the document source so that it is ready for a new stream of data.
  135. * Note that this is a deviation from the mongo implementation.
  136. *
  137. * @method reset
  138. **/
  139. proto.reset = function reset(){
  140. };
  141. return klass;
  142. })();