Преглед изворни кода

REFS DEVOPS-228 fixed whitespace/tab problems

David Aebersold пре 12 година
родитељ
комит
d8361cec8d
1 измењених фајлова са 151 додато и 130 уклоњено
  1. 151 130
      lib/pipeline/expressions/Expression.js

+ 151 - 130
lib/pipeline/expressions/Expression.js

@@ -13,12 +13,27 @@
  * @module mungedb-aggregate
  * @module mungedb-aggregate
  * @constructor
  * @constructor
  **/
  **/
-var Expression = module.exports = function Expression(){
-	if (arguments.length !== 0) throw new Error("zero args expected");
-}, klass = Expression, base = Object, proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
+var Expression = module.exports = function Expression() {
+		if (arguments.length !== 0) throw new Error("zero args expected");
+}, klass = Expression,
+		base = Object,
+		proto = klass.prototype = Object.create(base.prototype, {
+				constructor: {
+						value: klass
+				}
+		});
 
 
 // DEPENDENCIES
 // DEPENDENCIES
 var Document = require("../Document");
 var Document = require("../Document");
+var ObjectExpression;
+var FieldPathExpression;
+var ConstantExpression;
+var kinds;
+
+function fn(){
+	return;
+}
+
 
 
 // NESTED CLASSES
 // NESTED CLASSES
 /**
 /**
@@ -26,49 +41,54 @@ var Document = require("../Document");
  * @static
  * @static
  * @property ObjectCtx
  * @property ObjectCtx
  **/
  **/
-var ObjectCtx = Expression.ObjectCtx = (function(){
-	// CONSTRUCTOR
-	/**
-	 * Utility class for parseObject() below. isDocumentOk indicates that it is OK to use a Document in the current context.
-	 *
-	 * NOTE: deviation from Mongo code: accepts an `Object` of settings rather than a bitmask to help simplify the interface a little bit
-	 *
-	 * @class ObjectCtx
-	 * @namespace mungedb-aggregate.pipeline.expressions.Expression
-	 * @module mungedb-aggregate
-	 * @constructor
-	 * @param opts
-	 *	@param [opts.isDocumentOk]	{Boolean}
-	 *	@param [opts.isTopLevel]	{Boolean}
-	 *	@param [opts.isInclusionOk]	{Boolean}
-	 **/
-	var klass = function ObjectCtx(opts /*= {isDocumentOk:..., isTopLevel:..., isInclusionOk:...}*/){
-		if(!(opts instanceof Object && opts.constructor == Object)) throw new Error("opts is required and must be an Object containing named args");
-		for (var k in opts) { // assign all given opts to self so long as they were part of klass.prototype as undefined properties
-			if (opts.hasOwnProperty(k) && proto.hasOwnProperty(k) && proto[k] === undefined) this[k] = opts[k];
-		}
-	}, base = Object, proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
+var ObjectCtx = Expression.ObjectCtx = (function() {
+		// CONSTRUCTOR
+		/**
+		 * Utility class for parseObject() below. isDocumentOk indicates that it is OK to use a Document in the current context.
+		 *
+		 * NOTE: deviation from Mongo code: accepts an `Object` of settings rather than a bitmask to help simplify the interface a little bit
+		 *
+		 * @class ObjectCtx
+		 * @namespace mungedb-aggregate.pipeline.expressions.Expression
+		 * @module mungedb-aggregate
+		 * @constructor
+		 * @param opts
+		 *	@param [opts.isDocumentOk]	{Boolean}
+		 *	@param [opts.isTopLevel]	{Boolean}
+		 *	@param [opts.isInclusionOk]	{Boolean}
+		 **/
+		var klass = function ObjectCtx(opts /*= {isDocumentOk:..., isTopLevel:..., isInclusionOk:...}*/ ) {
+				if (!(opts instanceof Object && opts.constructor == Object)) throw new Error("opts is required and must be an Object containing named args");
+				for (var k in opts) { // assign all given opts to self so long as they were part of klass.prototype as undefined properties
+						if (opts.hasOwnProperty(k) && proto.hasOwnProperty(k) && proto[k] === undefined) this[k] = opts[k];
+				}
+		}, base = Object,
+				proto = klass.prototype = Object.create(base.prototype, {
+						constructor: {
+								value: klass
+						}
+				});
 
 
-	// PROTOTYPE MEMBERS
-	proto.isDocumentOk =
-	proto.isTopLevel =
-	proto.isInclusionOk = undefined;
+		// PROTOTYPE MEMBERS
+		proto.isDocumentOk =
+				proto.isTopLevel =
+				proto.isInclusionOk = undefined;
 
 
-	return klass;
+		return klass;
 })();
 })();
 
 
-proto.removeFieldPrefix = function removeFieldPrefix( prefixedField ) {
-    if(prefixedField.indexOf("\0") !== -1 ) {
-        // field path must not contain embedded null characters - 16419
-    }
-    if(prefixedField[0] !== '$') {
-        // "field path references must be prefixed with a '$'"
-    }
-    return prefixedField.slice(1);
+proto.removeFieldPrefix = function removeFieldPrefix(prefixedField) {
+		if (prefixedField.indexOf("\0") !== -1) {
+				// field path must not contain embedded null characters - 16419
+		}
+		if (prefixedField[0] !== '$') {
+				// "field path references must be prefixed with a '$'"
+		}
+		return prefixedField.slice(1);
 };
 };
 var KIND_UNKNOWN = 0,
 var KIND_UNKNOWN = 0,
-    KIND_NOTOPERATOR = 1,
-    KIND_OPERATOR = 2;
+		KIND_NOTOPERATOR = 1,
+		KIND_OPERATOR = 2;
 /**
 /**
  * Parse an Object.  The object could represent a functional expression or a Document expression.
  * Parse an Object.  The object could represent a functional expression or a Document expression.
  *
  *
@@ -83,84 +103,84 @@ var KIND_UNKNOWN = 0,
  * @param ctx	a MiniCtx representing the options above
  * @param ctx	a MiniCtx representing the options above
  * @returns the parsed Expression
  * @returns the parsed Expression
  **/
  **/
-klass.parseObject = function parseObject(obj, ctx, vps){
-	if(!(ctx instanceof ObjectCtx)) throw new Error("ctx must be ObjectCtx");
-	var kind = KIND_UNKNOWN,
-	    pExpression, // the result
-	    pExpressionObject; // the alt result
-	if (obj === undefined || obj == {}) return new ObjectExpression();
-	var fieldNames = Object.keys(obj);
-	if(fieldNames.length === 0) { //NOTE: Added this for mongo 2.5 port of document sources. Should reconsider when porting the expressions themselves
-		return new ObjectExpression();
-	}
-	for (var fieldCount = 0, n = fieldNames.length; fieldCount < n; ++fieldCount) {
-	    var pFieldName = fieldNames[fieldCount];
-
-	    if (pFieldName[0] === "$") {
-		if (fieldCount !== 0)
-                    throw new Error("the operator must be the only field in a pipeline object (at '" + pFieldName + "'.; code 16410");
+klass.parseObject = function parseObject(obj, ctx, vps) {
+		if (!(ctx instanceof ObjectCtx)) throw new Error("ctx must be ObjectCtx");
+		var kind = KIND_UNKNOWN,
+				pExpression, // the result
+				pExpressionObject; // the alt result
+		if (obj === undefined || obj == {}) return new ObjectExpression();
+		var fieldNames = Object.keys(obj);
+		if (fieldNames.length === 0) { //NOTE: Added this for mongo 2.5 port of document sources. Should reconsider when porting the expressions themselves
+				return new ObjectExpression();
+		}
+		for (var fieldCount = 0, n = fieldNames.length; fieldCount < n; ++fieldCount) {
+				var pFieldName = fieldNames[fieldCount];
 
 
-		if(ctx.isTopLevel)
-                    throw new Error("$expressions are not allowed at the top-level of $project; code 16404");
-		kind = KIND_OPERATOR;	//we've determined this "object" is an operator expression
-		pExpression = Expression.parseExpression(pFieldName, obj[pFieldName], vps);
-		} else {
-		    if (kind === KIND_OPERATOR)
-                        throw new Error("this object is already an operator expression, and can't be used as a document expression (at '" + pFieldName + "'.; code 15990");
+				if (pFieldName[0] === "$") {
+						if (fieldCount !== 0)
+								throw new Error("the operator must be the only field in a pipeline object (at '" + pFieldName + "'.; code 16410");
 
 
-                    if (!ctx.isTopLevel && pFieldName.indexOf(".") != -1)
-                        throw new Error("dotted field names are only allowed at the top level; code 16405");
-		    if (pExpression === undefined) { // if it's our first time, create the document expression
-			if (!ctx.isDocumentOk)
-                            throw new Error("document not allowed in this context"); // CW TODO error: document not allowed in this context
-				pExpression = pExpressionObject = new ObjectExpression(); //check for top level?
-				kind = kinds.NOT_OPERATOR;	//this "object" is not an operator expression
-			}
-			var fieldValue = obj[pFieldName];
-			switch (typeof(fieldValue)) {
-			case "object":
-				// it's a nested document
-				var subCtx = new ObjectCtx({
-					isDocumentOk: ctx.isDocumentOk,
-					isInclusionOk: ctx.isInclusionOk
-				});
-				pExpressionObject.addField(pFieldName, Expression.parseObject(fieldValue, subCtx, vps));
-				break;
-			case "string":
-				// it's a renamed field		// CW TODO could also be a constant
-				var pathExpr = new FieldPathExpression.parse(fieldValue);
-				pExpressionObject.addField(pFieldName, pathExpr);
-				break;
-			case "boolean":
-			case "number":
-				// it's an inclusion specification
-				if (fieldValue) {
-				    if (!ctx.isInclusionOk)
-                                        throw new Error("field inclusion is not allowed inside of $expressions; code 16420");
-					pExpressionObject.includePath(pFieldName);
+						if (ctx.isTopLevel)
+								throw new Error("$expressions are not allowed at the top-level of $project; code 16404");
+						kind = KIND_OPERATOR; //we've determined this "object" is an operator expression
+						pExpression = Expression.parseExpression(pFieldName, obj[pFieldName], vps);
 				} else {
 				} else {
-					if (!(ctx.isTopLevel && fn == Document.ID_PROPERTY_NAME))
-                                            throw new Error("The top-level " + Document.ID_PROPERTY_NAME + " field is the only field currently supported for exclusion; code 16406");
-					pExpressionObject.excludeId = true;
+						if (kind === KIND_OPERATOR)
+								throw new Error("this object is already an operator expression, and can't be used as a document expression (at '" + pFieldName + "'.; code 15990");
+
+						if (!ctx.isTopLevel && pFieldName.indexOf(".") != -1)
+								throw new Error("dotted field names are only allowed at the top level; code 16405");
+						if (pExpression === undefined) { // if it's our first time, create the document expression
+								if (!ctx.isDocumentOk)
+										throw new Error("document not allowed in this context"); // CW TODO error: document not allowed in this context
+								pExpression = pExpressionObject = new ObjectExpression(); //check for top level?
+								kind = kinds.NOT_OPERATOR; //this "object" is not an operator expression
+						}
+						var fieldValue = obj[pFieldName];
+						switch (typeof(fieldValue)) {
+								case "object":
+										// it's a nested document
+										var subCtx = new ObjectCtx({
+												isDocumentOk: ctx.isDocumentOk,
+												isInclusionOk: ctx.isInclusionOk
+										});
+										pExpressionObject.addField(pFieldName, Expression.parseObject(fieldValue, subCtx, vps));
+										break;
+								case "string":
+										// it's a renamed field		// CW TODO could also be a constant
+										var pathExpr = new FieldPathExpression.parse(fieldValue);
+										pExpressionObject.addField(pFieldName, pathExpr);
+										break;
+								case "boolean":
+								case "number":
+										// it's an inclusion specification
+										if (fieldValue) {
+												if (!ctx.isInclusionOk)
+														throw new Error("field inclusion is not allowed inside of $expressions; code 16420");
+												pExpressionObject.includePath(pFieldName);
+										} else {
+												if (!(ctx.isTopLevel && fn == Document.ID_PROPERTY_NAME))
+														throw new Error("The top-level " + Document.ID_PROPERTY_NAME + " field is the only field currently supported for exclusion; code 16406");
+												pExpressionObject.excludeId = true;
+										}
+										break;
+								default:
+										throw new Error("disallowed field type " + (fieldValue ? fieldValue.constructor.name + ":" : "") + typeof(fieldValue) + " in object expression (at '" + pFieldName + "')");
+						}
 				}
 				}
-				break;
-			default:
-				throw new Error("disallowed field type " + (fieldValue ? fieldValue.constructor.name + ":" : "") + typeof(fieldValue) + " in object expression (at '" + pFieldName + "')");
-			}
 		}
 		}
-	}
-	return pExpression;
+		return pExpression;
 };
 };
 
 
 
 
 klass.expressionParserMap = {};
 klass.expressionParserMap = {};
 
 
 klass.registerExpression = function registerExpression(key, parserFunc) {
 klass.registerExpression = function registerExpression(key, parserFunc) {
-    if( key in klass.expressionParserMap ) {
-        throw new Error("Duplicate expression registrarion for " + key);
-    }
-    klass.expressionParserMap[key] = parserFunc;
-    return 0; // Should
+		if (key in klass.expressionParserMap) {
+				throw new Error("Duplicate expression registrarion for " + key);
+		}
+		klass.expressionParserMap[key] = parserFunc;
+		return 0; // Should
 };
 };
 
 
 /**
 /**
@@ -173,10 +193,10 @@ klass.registerExpression = function registerExpression(key, parserFunc) {
  * @returns the parsed Expression
  * @returns the parsed Expression
  **/
  **/
 klass.parseExpression = function parseExpression(exprKey, exprValue, vps) {
 klass.parseExpression = function parseExpression(exprKey, exprValue, vps) {
-    if( !(exprKey in Expression.expressionParserMap) ) {
-        throw new Error("Invalid operator : " + exprKey);
-    }
-    return Expression.expressionParserMap[exprKey](exprValue, vps);
+		if (!(exprKey in Expression.expressionParserMap)) {
+				throw new Error("Invalid operator : " + exprKey);
+		}
+		return Expression.expressionParserMap[exprKey](exprValue, vps);
 };
 };
 
 
 /**
 /**
@@ -186,15 +206,16 @@ klass.parseExpression = function parseExpression(exprKey, exprValue, vps) {
  * @param pBsonElement the expected operand's BSONElement
  * @param pBsonElement the expected operand's BSONElement
  * @returns the parsed operand, as an Expression
  * @returns the parsed operand, as an Expression
  **/
  **/
-klass.parseOperand = function parseOperand(exprElement, vps){
-	var t = typeof(exprElement);
-	if (t === "string" && exprElement[0] == "$") { //if we got here, this is a field path expression
-		return new FieldPathExpression.parse(exprElement, vps);
-	}
-	else
-            if (t === "object" && exprElement && exprElement.constructor === Object)
-                return Expression.parseObject(exprElement, new ObjectCtx({isDocumentOk: true}), vps);
-	else return ConstantExpression.parse(exprElement, vps);
+klass.parseOperand = function parseOperand(exprElement, vps) {
+		var t = typeof(exprElement);
+		if (t === "string" && exprElement[0] == "$") { //if we got here, this is a field path expression
+				return new FieldPathExpression.parse(exprElement, vps);
+		} else
+		if (t === "object" && exprElement && exprElement.constructor === Object)
+				return Expression.parseObject(exprElement, new ObjectCtx({
+						isDocumentOk: true
+				}), vps);
+		else return ConstantExpression.parse(exprElement, vps);
 };
 };
 
 
 /**
 /**
@@ -206,9 +227,9 @@ klass.parseOperand = function parseOperand(exprElement, vps){
  * @returns the field path with the prefix removed
  * @returns the field path with the prefix removed
  **/
  **/
 klass.removeFieldPrefix = function removeFieldPrefix(prefixedField) {
 klass.removeFieldPrefix = function removeFieldPrefix(prefixedField) {
-	if (prefixedField.indexOf("\0") != -1) throw new Error("field path must not contain embedded null characters; code 16419");
-	if (prefixedField[0] !== "$") throw new Error("field path references must be prefixed with a '$' ('" + prefixedField + "'); code 15982");
-	return prefixedField.substr(1);
+		if (prefixedField.indexOf("\0") != -1) throw new Error("field path must not contain embedded null characters; code 16419");
+		if (prefixedField[0] !== "$") throw new Error("field path references must be prefixed with a '$' ('" + prefixedField + "'); code 15982");
+		return prefixedField.substr(1);
 };
 };
 
 
 
 
@@ -220,7 +241,7 @@ klass.removeFieldPrefix = function removeFieldPrefix(prefixedField) {
  * @returns the computed value
  * @returns the computed value
  **/
  **/
 proto.evaluate = function evaluate(obj) {
 proto.evaluate = function evaluate(obj) {
-	throw new Error("WAS NOT IMPLEMENTED BY INHERITOR!");
+		throw new Error("WAS NOT IMPLEMENTED BY INHERITOR!");
 };
 };
 
 
 /**
 /**
@@ -237,7 +258,7 @@ proto.evaluate = function evaluate(obj) {
  * @returns the optimized Expression
  * @returns the optimized Expression
  **/
  **/
 proto.optimize = function optimize() {
 proto.optimize = function optimize() {
-	throw new Error("WAS NOT IMPLEMENTED BY INHERITOR!");
+		throw new Error("WAS NOT IMPLEMENTED BY INHERITOR!");
 };
 };
 
 
 /**
 /**
@@ -251,7 +272,7 @@ proto.optimize = function optimize() {
  * @param path	path to self if all ancestors are ExpressionObjects.
  * @param path	path to self if all ancestors are ExpressionObjects.
  **/
  **/
 proto.addDependencies = function addDependencies(deps, path) {
 proto.addDependencies = function addDependencies(deps, path) {
-	throw new Error("WAS NOT IMPLEMENTED BY INHERITOR!");
+		throw new Error("WAS NOT IMPLEMENTED BY INHERITOR!");
 };
 };
 
 
 /**
 /**
@@ -259,9 +280,9 @@ proto.addDependencies = function addDependencies(deps, path) {
  * @method getIsSimple
  * @method getIsSimple
  **/
  **/
 proto.getIsSimple = function getIsSimple() {
 proto.getIsSimple = function getIsSimple() {
-	return false;
+		return false;
 };
 };
 
 
-proto.toMatcherBson = function toMatcherBson(){
-	throw new Error("WAS NOT IMPLEMENTED BY INHERITOR!");	//verify(false && "Expression::toMatcherBson()");
-};
+proto.toMatcherBson = function toMatcherBson() {
+		throw new Error("WAS NOT IMPLEMENTED BY INHERITOR!"); //verify(false && "Expression::toMatcherBson()");
+};