ProjectDocumentSource.js 3.7 KB

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