소스 검색

Implemented base DocumentSource munge class. fixes #997

http://source.rd.rcg.local/trac/eagle6/changeset/1294/Eagle6_SVN
Philip Murray 12 년 전
부모
커밋
1379b05b76
1개의 변경된 파일258개의 추가작업 그리고 0개의 파일을 삭제
  1. 258 0
      lib/pipeline/documentsource/DocumentSource.js

+ 258 - 0
lib/pipeline/documentsource/DocumentSource.js

@@ -0,0 +1,258 @@
+var DocumentSource = module.exports = (function(){
+	// CONSTRUCTOR
+	/**
+	 * A base class for all document sources
+	 * @param	{ExpressionContext}	
+	**/
+	var klass = module.exports = DocumentSource = function DocumentSource(/*pCtx*/){
+		if(arguments.length !== 0) throw new Error("zero args expected");
+		
+        /*
+          Most DocumentSources have an underlying source they get their data
+          from.  This is a convenience for them.
+          The default implementation of setSource() sets this; if you don't
+          need a source, override that to verify().  The default is to
+          verify() if this has already been set.
+        */
+        this.pSource = null;
+
+        /*
+          The zero-based user-specified pipeline step.  Used for diagnostics.
+          Will be set to -1 for artificial pipeline steps that were not part
+          of the original user specification.
+         */
+        this.step = -1;
+
+		//we dont need this because we are not sharding
+        //intrusive_ptr<ExpressionContext> pExpCtx;
+		//this.pExpCtx = pCtx;
+
+        /*
+          for explain: # of rows returned by this source
+          This is *not* unsigned so it can be passed to BSONObjBuilder.append().
+         */
+        this.nRowsOut = 0;
+		
+	}, base = Object, proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
+
+/*
+class DocumentSource :
+    public IntrusiveCounterUnsigned,
+    public StringWriter {
+public:
+    virtual ~DocumentSource();
+
+    // virtuals from StringWriter
+    virtual void writeString(stringstream &ss) const;
+*/
+
+    /**
+     * Set the step for a user-specified pipeline step.
+     * 
+     * @method	setPipelineStep
+     * @param	{Number}	step	number 0 to n.
+    **/
+    proto.setPipelineStep = function setPipelineStep(step) {
+		this.step = step;
+    };
+
+    /**
+     * Get the user-specified pipeline step.
+     * 
+     * @method	getPipelineStep
+     * @returns	{Number}	step
+    **/
+    proto.getPipelineStep = function getPipelineStep() {
+		return this.step;
+    };
+    
+    /**
+     * Is the source at EOF?
+     * 
+     * @method	eof
+    **/
+    proto.eof = function eof() {
+		throw new Error("not implemented");
+    };
+    
+    /**
+     * Advance the state of the DocumentSource so that it will return the next Document.  
+     * The default implementation returns false, after checking for interrupts. 
+     * Derived classes can call the default implementation in their own implementations in order to check for interrupts.
+     * 
+     * @method	advance
+     * @returns	{Boolean}	whether there is another document to fetch, i.e., whether or not getCurrent() will succeed.  This default implementation always returns false.
+    **/
+    proto.advance = function advance() {
+        //pExpCtx->checkForInterrupt(); // might not return
+        return false;
+    };
+    
+    /**
+     * some implementations do the equivalent of verify(!eof()) so check eof() first
+     * 
+     * @method	getCurrent
+     * @returns	{Document}	the current Document without advancing
+    **/
+    proto.getCurrent = function getCurrent() {
+		throw new Error("not implemented");
+    };
+
+    /**
+     * Inform the source that it is no longer needed and may release its resources.  After
+     * dispose() is called the source must still be able to handle iteration requests, but may
+     * become eof().
+     * NOTE: For proper mutex yielding, dispose() must be called on any DocumentSource that will
+     * not be advanced until eof(), see SERVER-6123.
+     * 
+     * @method	dispose
+    **/
+    proto.dispose = function dispose() {
+        if ( this.pSource ) {
+            // This is required for the DocumentSourceCursor to release its read lock, see
+            // SERVER-6123.
+            this.pSource.dispose();
+        }
+    };
+    
+    /**
+     * Get the source's name.
+     * 
+     * @method	getSourceName
+     * @returns	{String}	the string name of the source as a constant string; this is static, and there's no need to worry about adopting it
+    **/
+    proto.getSourceName = function getSourceName() {
+		return "[UNKNOWN]";
+    };
+    
+    /**
+     * Set the underlying source this source should use to get Documents
+     * from.
+     * It is an error to set the source more than once.  This is to
+     * prevent changing sources once the original source has been started;
+     * this could break the state maintained by the DocumentSource.
+     * This pointer is not reference counted because that has led to
+     * some circular references.  As a result, this doesn't keep
+     * sources alive, and is only intended to be used temporarily for
+     * the lifetime of a Pipeline::run().
+     * 
+     * @method	setSource
+     * @param	{DocumentSource}	pSource	the underlying source to use
+    **/
+    proto.setSource = function setSource(pTheSource) {
+		if(this.pSource){
+			throw new Error("It is an error to set the source more than once");
+		}
+        this.pSource = pTheSource;
+    };
+    
+    
+    /**
+     * Attempt to coalesce this DocumentSource with its successor in the
+     * document processing pipeline.  If successful, the successor
+     * DocumentSource should be removed from the pipeline and discarded.
+     * If successful, this operation can be applied repeatedly, in an
+     * attempt to coalesce several sources together.
+     * The default implementation is to do nothing, and return false.
+     * 
+     * @method	coalesce
+     * @param	{DocumentSource}	pNextSource	the next source in the document processing chain.
+     * @returns	{Boolean}	whether or not the attempt to coalesce was successful or not; if the attempt was not successful, nothing has been changed
+    **/
+    proto.coalesce = function coalesce(pNextSource) {
+		return false;
+    };
+    
+    /**
+     * Optimize the pipeline operation, if possible.  This is a local
+     * optimization that only looks within this DocumentSource.  For best
+     * results, first coalesce compatible sources using coalesce().
+     * This is intended for any operations that include expressions, and
+     * provides a hook for those to optimize those operations.
+     * The default implementation is to do nothing.
+     * 
+     * @method	optimize
+    **/
+    proto.optimize = function optimize(pNextSource) {
+    };
+
+	klass.GetDepsReturn = {
+        NOT_SUPPORTED:"NOT_SUPPORTED", // This means the set should be ignored
+        EXHAUSTIVE:"EXHAUSTIVE", // This means that everything needed should be in the set
+        SEE_NEXT:"SEE_NEXT", // Add the next Source's deps to the set
+	};
+
+    /**
+     * Get the fields this operation needs to do its job.
+     * Deps should be in "a.b.c" notation
+     * 
+     * @method	getDependencies
+     * @param	{Object} deps	set (unique array) of strings
+     * @returns	DocumentSource.GetDepsReturn
+    **/
+    proto.getDependencies = function getDependencies(deps) {
+		return klass.GetDepsReturn.NOT_SUPPORTED;
+    };
+    
+  
+    /**
+     * This takes dependencies from getDependencies and
+     * returns a projection that includes all of them
+     * 
+     * @method	depsToProjection
+     * @param	{Object} deps	set (unique array) of strings
+     * @returns	{Object}	BSONObj
+    **/
+    proto.depsToProjection = function depsToProjection(deps) {
+        var bb = {};
+        if (deps._id === undefined)
+            bb._id = 0;
+
+        var last = "";
+        Object.keys(deps).forEach(function(it){
+            if (last !== "" && it.slice(0, last.length) === last){
+                // we are including a parent of *it so we don't need to
+                // include this field explicitly. In fact, due to
+                // SERVER-6527 if we included this field, the parent
+                // wouldn't be fully included.
+                return;
+            }
+            last = it + ".";
+            bb[it] = 1;
+        });
+        
+        return bb;
+    };
+
+
+    /**
+     * Add the DocumentSource to the array builder.
+     * The default implementation calls sourceToBson() in order to
+     * convert the inner part of the object which will be added to the
+     * array being built here.
+     * 
+     * @method	addToBsonArray
+     * @param	{Array} pBuilder	BSONArrayBuilder: the array builder to add the operation to.
+     * @param	{Boolean}	explain	create explain output
+     * @returns	{Object}
+    **/
+    proto.addToBsonArray = function addToBsonArray(pBuilder, explain) {
+		pBuilder.push(this.sourceToBson({}, explain));
+    };
+
+    /**
+     * Create an object that represents the document source.  The object
+     * will have a single field whose name is the source's name.  This
+     * will be used by the default implementation of addToBsonArray()
+     * to add this object to a pipeline being represented in BSON.
+     * 
+     * @method	sourceToBson
+     * @param	{Array} pBuilder	BSONObjBuilder: a blank object builder to write to
+     * @param	{Boolean}	explain	create explain output
+    **/
+    proto.sourceToBson = function sourceToBson(pBuilder, explain) {
+		throw new Error("not implemented");
+    };
+
+	return klass;
+})();