FilterBaseDocumentSource.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. "use strict";
  2. var FilterBaseDocumentSource = module.exports = (function(){
  3. // CONSTRUCTOR
  4. /**
  5. * A base class for filter document sources
  6. *
  7. * @class FilterBaseDocumentSource
  8. * @namespace munge.pipeline.documentsource
  9. * @module munge
  10. * @constructor
  11. * @param {ExpressionContext}
  12. **/
  13. var klass = module.exports = FilterBaseDocumentSource = function FilterBaseDocumentSource(/*pCtx*/){
  14. if(arguments.length !== 0) throw new Error("zero args expected");
  15. base.call(this);
  16. this.unstarted = true;
  17. this.hasNext = false;
  18. this.pCurrent = null;
  19. }, base = require('./DocumentSource'), proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
  20. /**
  21. * Find the next acceptable source document, if there are any left.
  22. *
  23. * @method findNext
  24. **/
  25. proto.findNext = function findNext() {
  26. /* only do this the first time */
  27. if (this.unstarted) {
  28. this.hasNext = !this.pSource.eof();
  29. this.unstarted = false;
  30. }
  31. while(this.hasNext) {
  32. var pDocument = this.pSource.getCurrent();
  33. this.hasNext = this.pSource.advance();
  34. if (this.accept(pDocument)) {
  35. this.pCurrent = pDocument;
  36. return;
  37. }
  38. }
  39. this.pCurrent = null;
  40. };
  41. /**
  42. * Is the source at EOF?
  43. *
  44. * @method eof
  45. **/
  46. proto.eof = function eof() {
  47. if (this.unstarted)
  48. this.findNext();
  49. return (this.pCurrent === null);
  50. };
  51. /**
  52. * Advance the state of the DocumentSource so that it will return the next Document.
  53. * The default implementation returns false, after checking for interrupts.
  54. * Derived classes can call the default implementation in their own implementations in order to check for interrupts.
  55. *
  56. * @method advance
  57. * @returns {Boolean} whether there is another document to fetch, i.e., whether or not getCurrent() will succeed. This default implementation always returns false.
  58. **/
  59. proto.advance = function advance() {
  60. base.prototype.advance.call(this); // check for interrupts
  61. if (this.unstarted)
  62. this.findNext();
  63. /**
  64. * This looks weird after the above, but is correct. Note that calling
  65. * getCurrent() when first starting already yields the first document
  66. * in the collection. Calling advance() without using getCurrent()
  67. * first will skip over the first item.
  68. **/
  69. this.findNext();
  70. return (this.pCurrent !== null);
  71. };
  72. /**
  73. * some implementations do the equivalent of verify(!eof()) so check eof() first
  74. *
  75. * @method getCurrent
  76. * @returns {Document} the current Document without advancing
  77. **/
  78. proto.getCurrent = function getCurrent() {
  79. if (this.unstarted)
  80. this.findNext();
  81. if (this.pCurrent === null) throw new Error("This should never happen");
  82. return this.pCurrent;
  83. };
  84. /**
  85. * Test the given document against the predicate and report if it
  86. * should be accepted or not.
  87. *
  88. * @param {object} pDocument the document to test
  89. * @returns {bool} true if the document matches the filter, false otherwise
  90. **/
  91. proto.accept = function accept(pDocument) {
  92. throw new Error("not implemented");
  93. };
  94. /**
  95. * Create a JSONObj suitable for Matcher construction.
  96. *
  97. * This is used after filter analysis has moved as many filters to
  98. * as early a point as possible in the document processing pipeline.
  99. * See db/Matcher.h and the associated wiki documentation for the
  100. * format. This conversion is used to move back to the low-level
  101. * find() Cursor mechanism.
  102. *
  103. * @param pBuilder the builder to write to
  104. **/
  105. proto.toMatcherJson = function toMatcherJson(pBuilder) {
  106. throw new Error("not implemented");
  107. };
  108. /**
  109. * Reset the document source so that it is ready for a new stream of data.
  110. * Note that this is a deviation from the mongo implementation.
  111. *
  112. * @method reset
  113. **/
  114. proto.reset = function reset(){
  115. this.unstarted = true;
  116. };
  117. return klass;
  118. })();