LimitDocumentSource.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. var LimitDocumentSource = module.exports = (function(){
  2. // CONSTRUCTOR
  3. /**
  4. * A document source limiter
  5. *
  6. * @class LimitDocumentSource
  7. * @namespace munge.pipepline.documentsource
  8. * @module munge
  9. * @constructor
  10. * @param {Object} query the match query to use
  11. **/
  12. var klass = module.exports = LimitDocumentSource = function LimitDocumentSource(/* pCtx*/){
  13. if(arguments.length !== 0) throw new Error("zero args expected");
  14. base.call(this);
  15. this.limit = 0;
  16. this.count = 0;
  17. }, base = require('./DocumentSource'), proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
  18. proto.getSourceName = function getSourceName(){
  19. return "$limit";
  20. };
  21. proto.getFactory = function getFactory(){
  22. return klass; // using the ctor rather than a separate .create() method
  23. };
  24. klass.GetDepsReturn = {
  25. SEE_NEXT:"SEE_NEXT", // Add the next Source's deps to the set
  26. };
  27. /**
  28. * Coalesce limits together
  29. *
  30. * @param {Object} nextSource the next source
  31. * @return {bool} return whether we can coalese together
  32. **/
  33. proto.coalesce = function coalesce(nextSource) {
  34. nextLimit = nextSource.get();
  35. /* if it's not another $skip, we can't coalesce */
  36. if (!nextLimit)
  37. return false;
  38. /* we need to limit by the minimum of the two limits */
  39. if (nextLimit.limit < this.limit)
  40. this.limit = nextLimit.limit;
  41. return true;
  42. };
  43. /**
  44. * Is the source at EOF?
  45. *
  46. * @method eof
  47. **/
  48. proto.eof = function eof() {
  49. return this.pSource.eof() || this.count >= this.limit;
  50. };
  51. /**
  52. * some implementations do the equivalent of verify(!eof()) so check eof() first
  53. *
  54. * @method getCurrent
  55. * @returns {Document} the current Document without advancing
  56. **/
  57. proto.getCurrent = function getCurrent() {
  58. return this.pSource.getCurrent();
  59. };
  60. /**
  61. * Advance the state of the DocumentSource so that it will return the next Document.
  62. * The default implementation returns false, after checking for interrupts.
  63. * Derived classes can call the default implementation in their own implementations in order to check for interrupts.
  64. *
  65. * @method advance
  66. * @returns {Boolean} whether there is another document to fetch, i.e., whether or not getCurrent() will succeed. This default implementation always returns false.
  67. **/
  68. proto.advance = function advance() {
  69. base.prototype.advance.call(this); // check for interrupts
  70. ++this.count;
  71. if (this.count >= this.limit) {
  72. return false;
  73. }
  74. this.pCurrent = this.pSource.getCurrent();
  75. return this.pSource.advance();
  76. };
  77. /**
  78. * Create an object that represents the document source. The object
  79. * will have a single field whose name is the source's name. This
  80. * will be used by the default implementation of addToJsonArray()
  81. * to add this object to a pipeline being represented in JSON.
  82. *
  83. * @method sourceToJson
  84. * @param {Object} builder JSONObjBuilder: a blank object builder to write to
  85. * @param {Boolean} explain create explain output
  86. **/
  87. proto.sourceToJson = function sourceToJson(builder, explain) {
  88. builder.$limit = this.limit;
  89. };
  90. /**
  91. * Creates a new LimitDocumentSource with the input number as the limit
  92. *
  93. * @param {Number} JsonElement this thing is *called* Json, but it expects a number
  94. **/
  95. proto.createFromJson = function createFromJson(JsonElement) {
  96. //if (!(JsonElement instanceof Number)) throw new Error("code 15957; the limit must be specified as a number");
  97. var nextLimit = proto.getFactory();
  98. nextLimit.limit = JsonElement;
  99. if ((nextLimit.limit <= 0) || isNaN(nextLimit.limit)) throw new Error("code 15958; the limit must be positive");
  100. return nextLimit;
  101. };
  102. return klass;
  103. })();