ProjectDocumentSource.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  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 mungedb-aggregate.pipeline.documentSources
  9. * @module mungedb-aggregate
  10. * @constructor
  11. * @param [ctx] {ExpressionContext}
  12. **/
  13. var klass = module.exports = ProjectDocumentSource = function ProjectDocumentSource(ctx){
  14. if(arguments.length > 1) throw new Error("up to one arg expected");
  15. base.call(this, ctx);
  16. this.OE = 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. klass.projectName = "$project";
  24. /**
  25. * Returns the name of project
  26. * @return {string} the name of project
  27. **/
  28. proto.getSourceName = function getSourceName() {
  29. return klass.projectName;
  30. };
  31. /**
  32. * Returns the object that was used to construct the ProjectDocumentSource
  33. * @return {object} the object that was used to construct the ProjectDocumentSource
  34. **/
  35. proto.getRaw = function getRaw() {
  36. return this._raw;
  37. };
  38. /**
  39. * Calls base document source eof()
  40. * @return {bool} The result of base.source.eof()
  41. **/
  42. proto.eof = function eof() {
  43. return this.source.eof();
  44. };
  45. /**
  46. * Calls base document source advance()
  47. * @return {bool} The result of base.source.advance()
  48. **/
  49. proto.advance = function advance() {
  50. return this.source.advance();
  51. };
  52. /**
  53. * Builds a new document(object) that represents this base document
  54. * @return {object} A document that represents this base document
  55. **/
  56. proto.getCurrent = function getCurrent() {
  57. var inDocument = this.source.getCurrent();
  58. if (!inDocument) throw new Error('inDocument must be an object');
  59. var resultDocument = {};
  60. this.OE.addToDocument(resultDocument, inDocument, /*root=*/inDocument);
  61. return resultDocument;
  62. };
  63. /**
  64. * Optimizes the internal ObjectExpression
  65. * @return
  66. **/
  67. proto.optimize = function optimize() {
  68. this.OE.optimize();
  69. };
  70. proto.toJSON = function toJSON(){
  71. var obj = {};
  72. this.sourceToJson(obj);
  73. return obj;
  74. };
  75. /**
  76. * Places a $project key inside the builder object with value of this.OE
  77. * @method sourceToJson
  78. * @param {builder} An object (was ported from BsonBuilder)
  79. * @return
  80. **/
  81. proto.sourceToJson = function sourceToJson(builder, explain) {
  82. var insides = this.OE.toJSON(true);
  83. builder[this.getSourceName()] = insides;
  84. };
  85. /**
  86. * Builds a new ProjectDocumentSource from an object
  87. * @method createFromJson
  88. * @return {ProjectDocmentSource} a ProjectDocumentSource instance
  89. **/
  90. klass.createFromJson = function(jsonElement, expCtx) {
  91. if(!(jsonElement instanceof Object) || jsonElement.constructor !== Object) {
  92. throw new Error('Error 15969. Specification must be an object but was ' + typeof jsonElement);
  93. }
  94. var objectContext = new Expression.ObjectCtx({
  95. isDocumentOk: true,
  96. isTopLevel: true,
  97. isInclusionOk: true
  98. });
  99. var project = new ProjectDocumentSource(expCtx);
  100. project._raw = jsonElement;
  101. var parsed = Expression.parseObject(jsonElement, objectContext);
  102. var exprObj = parsed;
  103. if(! exprObj instanceof ObjectExpression) {
  104. throw new Error("16402, parseObject() returned wrong type of Expression");
  105. }
  106. if(!exprObj.getFieldCount()) {
  107. throw new Error("16403, $projection requires at least one output field");
  108. }
  109. project.OE = exprObj;
  110. return project;
  111. };
  112. /**
  113. * Adds dependencies to the contained ObjectExpression
  114. * @param {deps} An object that is treated as a set of strings
  115. * @return A string that is part of the GetDepsReturn enum
  116. **/
  117. proto.getDependencies = function getDependencies(deps) {
  118. var path = [];
  119. this.OE.addDependencies(deps, path);
  120. return base.GetDepsReturn.EXHAUSTIVE;
  121. };
  122. return klass;
  123. })();