ProjectDocumentSource.js 4.1 KB

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