Просмотр исходного кода

ref #3253: Fill out ElementPath and BSONElement

Brennan Chesley 12 лет назад
Родитель
Сommit
0259db5e3e

+ 117 - 240
lib/pipeline/matcher/BSONElementIterator.js

@@ -1,10 +1,14 @@
-"use strict"
-
-
+"use strict";
 
+ElementPath = require('ElementPath');
+BSONElement = require('BSONElemtn');
 // Autogenerated by cport.py on 2013-09-17 14:37
-var BSONElementIterator = module.exports = function (){
-
+var BSONElementIterator = module.exports = function ( path, context ){
+	// File: path.cpp lines: 77-80 
+	this._path = path;
+	this._context = context;
+	this._state = 'BEGIN';
+	//console.debug( 'path: ' + path.fieldRef().dottedField() + ' context: ' + context + '\n');
 }, klass = BSONElementIterator, base =  Object  , proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
 
 
@@ -13,31 +17,11 @@ var BSONElementIterator = module.exports = function (){
 
 proto._arrayIterationState = undefined;
 
-
-// File: path.h lines: 114-114
-//         BSONObj _context;
-
-proto._context = undefined;
-
-
 // File: path.h lines: 117-117
 //         Context _next;
 
 proto._next = undefined;
 
-
-// File: path.h lines: 113-113
-//         const ElementPath& _path;
-
-proto._path = undefined;
-
-
-// File: path.h lines: 116-115
-//         enum State { BEGIN, IN_ARRAY, DONE } _state;
-
-proto._state = undefined;
-
-
 // File: path.h lines: 142-142
 //         boost::scoped_ptr<ElementIterator> _subCursor;
 
@@ -50,72 +34,6 @@ proto._subCursor = undefined;
 proto._subCursorPath = undefined;
 
 
-// File: path.h lines: 140-140
-//         ArrayIterationState _arrayIterationState;
-
-proto._arrayIterationState = undefined;
-
-
-// File: path.h lines: 114-114
-//         BSONObj _context;
-
-proto._context = undefined;
-
-
-// File: path.h lines: 117-117
-//         Context _next;
-
-proto._next = undefined;
-
-
-// File: path.h lines: 113-113
-//         const ElementPath& _path;
-
-proto._path = undefined;
-
-
-// File: path.h lines: 116-115
-//         enum State { BEGIN, IN_ARRAY, DONE } _state;
-
-proto._state = undefined;
-
-
-// File: path.h lines: 142-142
-//         boost::scoped_ptr<ElementIterator> _subCursor;
-
-proto._subCursor = undefined;
-
-
-// File: path.h lines: 143-143
-//         boost::scoped_ptr<ElementPath> _subCursorPath;
-
-proto._subCursorPath = undefined;
-
-
-
-
-
-/**
- * 
- * This documentation was automatically generated. Please update when you touch this function.
- * @method BSONElementIterator
- * @param
- *
- */
-proto.BSONElementIterator = function BSONElementIterator( /*  const ElementPath& path, const BSONObj& context  */ ){
-
-// File: path.cpp lines: 77-80
-//     BSONElementIterator::BSONElementIterator( const ElementPath& path, const BSONObj& context )
-//         : _path( path ), _context( context ) {
-//         _state = BEGIN;
-//         //log() << "path: " << path.fieldRef().dottedField() << " context: " << context << endl;
-//     }
-
-
-
-}
-
-
 /**
  * 
  * This documentation was automatically generated. Please update when you touch this function.
@@ -124,124 +42,105 @@ proto.BSONElementIterator = function BSONElementIterator( /*  const ElementPath&
  *
  */
 proto.more = function more( /*  */ ){
-
 // File: path.cpp lines: 120-230
-//     bool BSONElementIterator::more() {
-//         if ( _subCursor ) {
-// 
-//             if ( _subCursor->more() )
-//                 return true;
-// 
-//             _subCursor.reset();
-// 
-//             if ( _arrayIterationState.isArrayOffsetMatch( _arrayIterationState._current.fieldName() ) ) {
-//                 if ( _arrayIterationState.nextEntireRest() ) {
-//                     _next.reset( _arrayIterationState._current, _arrayIterationState._current, true );
-//                     _arrayIterationState._current = BSONElement();
-//                     return true;
-//                 }
-// 
-//                 _subCursorPath.reset( new ElementPath() );
-//                 _subCursorPath->init( _arrayIterationState.restOfPath.substr( _arrayIterationState.nextPieceOfPath.size() + 1 ) );
-//                 _subCursorPath->setTraverseLeafArray( _path.shouldTraverseLeafArray() );
-//                 _subCursor.reset( new BSONElementIterator( *_subCursorPath, _arrayIterationState._current.Obj() ) );
-//                 _arrayIterationState._current = BSONElement();
-//                 return more();
-//             }
-// 
-//         }
-// 
-//         if ( !_next.element().eoo() )
-//             return true;
-// 
-//         if ( _state == DONE ){
-//             return false;
-//         }
-// 
-//         if ( _state == BEGIN ) {
-//             size_t idxPath = 0;
-//             BSONElement e = getFieldDottedOrArray( _context, _path.fieldRef(), &idxPath );
-// 
-//             if ( e.type() != Array ) {
-//                 _next.reset( e, BSONElement(), false );
-//                 _state = DONE;
-//                 return true;
-//             }
-// 
-//             // its an array
-// 
-//             _arrayIterationState.reset( _path.fieldRef(), idxPath + 1 );
-// 
-//             if ( !_arrayIterationState.hasMore && !_path.shouldTraverseLeafArray() ) {
-//                 _next.reset( e, BSONElement(), true );
-//                 _state = DONE;
-//                 return true;
-//             }
-// 
-//             _arrayIterationState.startIterator( e );
-//             _state = IN_ARRAY;
-//             return more();
-//         }
-// 
-//         if ( _state == IN_ARRAY ) {
-// 
-//             while ( _arrayIterationState.more() ) {
-// 
-//                 BSONElement x = _arrayIterationState.next();
-//                 if ( !_arrayIterationState.hasMore ) {
-//                     _next.reset( x, x, false );
-//                     return true;
-//                 }
-// 
-//                 // i have deeper to go
-// 
-//                 if ( x.type() == Object ) {
-//                     _subCursorPath.reset( new ElementPath() );
-//                     _subCursorPath->init( _arrayIterationState.restOfPath );
-//                     _subCursorPath->setTraverseLeafArray( _path.shouldTraverseLeafArray() );
-// 
-//                     _subCursor.reset( new BSONElementIterator( *_subCursorPath, x.Obj() ) );
-//                     return more();
-//                 }
-// 
-// 
-//                 if ( _arrayIterationState.isArrayOffsetMatch( x.fieldName() ) ) {
-// 
-//                     if ( _arrayIterationState.nextEntireRest() ) {
-//                         _next.reset( x, x, false );
-//                         return true;
-//                     }
-// 
-//                     if ( x.isABSONObj() ) {
-//                         _subCursorPath.reset( new ElementPath() );
-//                         _subCursorPath->init( _arrayIterationState.restOfPath.substr( _arrayIterationState.nextPieceOfPath.size() + 1 ) );
-//                         _subCursorPath->setTraverseLeafArray( _path.shouldTraverseLeafArray() );
-//                         BSONElementIterator* real = new BSONElementIterator( *_subCursorPath, _arrayIterationState._current.Obj() );
-//                         _subCursor.reset( real );
-//                         real->_arrayIterationState.reset( _subCursorPath->fieldRef(), 0 );
-//                         real->_arrayIterationState.startIterator( x );
-//                         real->_state = IN_ARRAY;
-//                         _arrayIterationState._current = BSONElement();
-//                         return more();
-//                     }
-//                 }
-// 
-//             }
-// 
-//             if ( _arrayIterationState.hasMore )
-//                 return false;
-// 
-//             _next.reset( _arrayIterationState._theArray, BSONElement(), true );
-//             _state = DONE;
-//             return true;
-//         }
-// 
-//         return false;
-//     }
-
-
-
-}
+	if( this._subCursor ){
+		if( this._subCursor.more() ) {return true;}
+		this._subCursor.reset();
+ 
+		if ( this._arrayIterationState.isArrayOffsetMatch( this._arrayIterationState._current.fieldName() ) ) {
+			if ( this._arrayIterationState.nextEntireRest() ) {
+				this._next.reset( this._arrayIterationState._current, this._arrayIterationState._current, true );
+				this._arrayIterationState._current = new BSONElement(); //BSON
+				return true;
+			}
+
+			this._subCursorPath.reset( new ElementPath() );
+			this._subCursorPath.init( this._arrayIterationState.restOfPath.substr( this._arrayIterationState.nextPieceOfPath.size() + 1 ) );
+			this._subCursorPath.setTraverseLeafArray( this._path.shouldTraverseLeafArray() );
+			this._subCursor.reset( new BSONElementIterator( this._subCursorPath, this._arrayIterationState._current.Obj() ) );
+			this._arrayIterationState._current = BSONElement();
+			return this.more();
+		}
+ 
+	}
+
+	if ( !this._next.element().eoo() ) {return true;}
+
+	if ( this._state == 'DONE' ){ return false; }
+
+	if ( this._state == 'BEGIN' ) {
+		var idxPath = {pathID:0};
+		var e = ElementPath.getFieldDottedOrArray( this._context, this._path.fieldRef(), idxPath ); //BSONElement
+		if ( e.type() != Array ) {
+			this._next.reset( e, new BSONElement(), false );
+			this._state = 'DONE';
+			return true;
+		}
+		// its an array
+
+		this._arrayIterationState.reset( this._path.fieldRef(), idxPath.pathID + 1 );
+
+		if ( !this._arrayIterationState.hasMore && this._path.shouldTraverseLeafArray() ) {
+			this._next.reset( e, new BSONElement(), true );
+			this._state = 'DONE';
+			return true;
+		}
+
+		this._arrayIterationState.startIterator( e );
+		this._state = IN_ARRAY;
+		return more();
+	}
+
+	if ( this._state == 'IN_ARRAY' ) {
+
+		while ( this._arrayIterationState.more() ) {
+			var x = this._arrayIterationState.next(); //BSONElement
+			if ( !this._arrayIterationState.hasMore() ) {
+				this._next.reset( x, x, false );
+				return true;
+			}
+
+			// i have deeper to go
+
+			if ( x.type() == Object ) {
+				this._subCursorPath.reset( new ElementPath() );
+				this._subCursorPath.init( this._arrayIterationState.restOfPath );
+				this._subCursorPath.setTraverseLeafArray( this._path.shouldTraverseLeafArray() );
+
+				this._subCursor.reset( new BSONElementIterator( this._subCursorPath, x.Obj() ) );
+				return more();
+			}
+
+			if ( this._arrayIterationState.isArrayOffsetMatch( x.fieldName() ) ) {
+
+				if ( this._arrayIterationState.nextEntireRest() ) {
+					this._next.reset( x, x, false );
+					return true;
+				}
+	
+				if ( x.isABSONObj() ) {
+					this._subCursorPath.reset( new ElementPath() );
+					this._subCursorPath.init( this._arrayIterationState.restOfPath.substr( this._arrayIterationState.nextPieceOfPath.size() + 1 ) );
+					this._subCursorPath.setTraverseLeafArray( this._path.shouldTraverseLeafArray() );
+					var real = new BSONElementIterator( this._subCursorPath, this._arrayIterationState._current.Obj() );
+					this._subCursor.reset( real );
+					real._arrayIterationState.reset( this._subCursorPath.fieldRef(), 0 );
+					real._arrayIterationState.startIterator( x );
+					real._state = 'IN_ARRAY';
+					this._arrayIterationState._current = new BSONElement();
+					return more();
+				}
+			}
+
+		}
+		if ( this._arrayIterationState.hasMore() ) { return false; }
+		
+		this._next.reset( this._arrayIterationState._theArray, new BSONElement(), true );
+		this._state = 'DONE';
+		return true;
+	}
+	return false;
+};
 
 
 /**
@@ -251,38 +150,16 @@ proto.more = function more( /*  */ ){
  * @param
  *
  */
-proto.next = function next( /*  */ ){
-
+proto.next = function next(){
 // File: path.cpp lines: 233-241
-//     ElementIterator::Context BSONElementIterator::next() {
-//         if ( _subCursor ) {
-//             Context e = _subCursor->next();
-//             e.setArrayOffset( _arrayIterationState._current );
-//             return e;
-//         }
-//         Context x = _next;
-//         _next.reset();
-//         return x;
-//     }
-
-
-
-}
-
-
-/**
- * 
- * This documentation was automatically generated. Please update when you touch this function.
- * @method ~BSONElementIterator
- * @param
- *
- */
-proto.~BSONElementIterator = function ~BSONElementIterator( /*  */ ){
-
-// File: path.cpp lines: 83-83
-//     BSONElementIterator::~BSONElementIterator() {
-//     }
-
 
+	if ( this._subCursor ) {
+		var e = this._subCursor.next(); //Context
+		e.setArrayOffset( this._arrayIterationState._current );
+		return e;
+	}
+	var x = _next; //Context
+	this._next.reset();
+	return x;
+};
 
-}

+ 8 - 0
lib/pipeline/matcher/CLUDGES

@@ -0,0 +1,8 @@
+Things that have been moved around or changed.
+
+
+getFieldDottedOrArray -> ElementPath.getFieldDottedOrArray (was unattached function, now static function on ElementPath class)
+isAllDigits -> ElementPath.isAllDigits ( now static function )
+
+
+

+ 76 - 31
lib/pipeline/matcher/ElementPath.js

@@ -1,6 +1,7 @@
-"use strict"
-
+"use strict";
 
+FieldRef = require('FieldRef');
+BSONElement = require('BSONElement');
 
 // Autogenerated by cport.py on 2013-09-17 14:37
 var ElementPath = module.exports = function (){
@@ -32,6 +33,67 @@ proto._fieldRef = undefined;
 proto._shouldTraverseLeafArray = undefined;
 
 
+// File: path_internal.cpp
+
+/**
+ * getFieldDottedOrArray 
+ *
+ * @method getFieldDottedArray
+ * @param doc
+ * @param path
+ * @param idxPathObj This is an object with a pathID element. This allows for pass by ref in calling function.
+ * */
+klass.getFieldDottedOrArray = function getFieldDottedOrArray(doc, path, idxPathObj){
+	// File path_internal.cpp lines 31-72
+	if (path.numParts() === 0 ) { return doc.getField(""); }
+	
+	var res,curr = doc,
+	    stop = false,
+	    partNum = 0;
+	while (partNum < path.numParts() && !stop) {
+		res = curr.getField( path.getPart( partNum) );
+		switch (res.type() ) {
+			case 'EOO':
+				stop = true;
+				break;
+
+			case 'Object':
+				curr = res.Obj();
+				partNum++;
+				break;
+
+			case 'Array':
+				stop = true;
+				break;
+
+			default:
+				if (partNum + 1 < path.numParts() ) {
+					res = new BSONELEMENT();
+				}
+				stope = true;
+				break;
+		}
+	}
+
+	idxPath.pathID = partNum;
+	return res;
+};
+
+/**
+ * isAllDigits does what it says on the tin.
+ *
+ * @method isAllDigits
+ * @param str
+ */
+
+klass.isAllDigits = function isAllDigits ( str ){
+	// File path_internal.cpp lines 23-29
+	digitCheck = /\D/g;
+	if (digitCheck.exec(str) === null){ return true; }
+	return false;
+};
+	
+
 
 
 
@@ -44,12 +106,8 @@ proto._shouldTraverseLeafArray = undefined;
  */
 proto.fieldRef = function fieldRef( /*  */ ){
 // File: path.h lines: 37-36
-//         const FieldRef& fieldRef() const { return _fieldRef; }
-
-
-
-
-}
+	return this._fieldRef;
+};
 
 
 /**
@@ -59,18 +117,12 @@ proto.fieldRef = function fieldRef( /*  */ ){
  * @param
  *
  */
-proto.init = function init( /*  const StringData& path  */ ){
-
+proto.init = function init( path ){  //  const StringData& path 
 // File: path.cpp lines: 26-29
-//     Status ElementPath::init( const StringData& path ) {
-//         _shouldTraverseLeafArray = true;
-//         _fieldRef.parse( path );
-//         return Status::OK();
-//     }
-
-
-
-}
+	this._shouldTraverseLeafArray = true;
+	this._fieldRef.parse( path );
+	return Status.OK;
+};
 
 
 /**
@@ -80,14 +132,10 @@ proto.init = function init( /*  const StringData& path  */ ){
  * @param
  *
  */
-proto.setTraverseLeafArray = function setTraverseLeafArray( /*  bool b  */ ){
+proto.setTraverseLeafArray = function setTraverseLeafArray( b ){ //  bool b
 // File: path.h lines: 35-34
-//         void setTraverseLeafArray( bool b ) { _shouldTraverseLeafArray = b; }
-
-
-
-
-}
+	this._shouldTraverseLeafArray = b;
+};
 
 
 /**
@@ -99,9 +147,6 @@ proto.setTraverseLeafArray = function setTraverseLeafArray( /*  bool b  */ ){
  */
 proto.shouldTraverseLeafArray = function shouldTraverseLeafArray( /*  */ ){
 // File: path.h lines: 38-37
-//         bool shouldTraverseLeafArray() const { return _shouldTraverseLeafArray; }
-
-
-
+	return this._shouldTraverseLeafArray;
+};
 
-}

+ 3 - 3
lib/pipeline/matcher/OrMatchExpression.js

@@ -1,9 +1,9 @@
-"use strict"
+"use strict";
 
 
 
 // Autogenerated by cport.py on 2013-09-17 14:37
-var OrMatchExpression = module.exports = function (){
+var OrMatchExpression = module.exports = function OrMatchExpression (){
 
 }, klass = OrMatchExpression, base =  Object  , proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
 
@@ -134,4 +134,4 @@ proto.~OrMatchExpression = function ~OrMatchExpression( /*  */ ){
 
 
 
-}
+}