FilterBaseDocumentSource.js 3.8 KB

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