Bladeren bron

Refs #3253. Partial conversion of matcher2 class.

Spencer Rathbun 12 jaren geleden
bovenliggende
commit
327a599fd9
1 gewijzigde bestanden met toevoegingen van 224 en 332 verwijderingen
  1. 224 332
      lib/pipeline/matcher/Matcher2.js

+ 224 - 332
lib/pipeline/matcher/Matcher2.js

@@ -1,448 +1,340 @@
-"use strict"
-
-
+"use strict";
 
 // Autogenerated by cport.py on 2013-09-17 14:37
 var Matcher2 = module.exports = function (){
 
 }, klass = Matcher2, base =  Object  , proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
 
-
 // File: matcher.h lines: 82-82
-//         boost::scoped_ptr<MatchExpression> _expression;
-
+//         boost.scoped_ptr<MatchExpression> _expression;
 proto._expression = undefined;
 
-
 // File: matcher.h lines: 80-80
 //         BSONObj _indexKey;
-
 proto._indexKey = undefined;
 
-
 // File: matcher.h lines: 79-79
 //         BSONObj _pattern;
-
 proto._pattern = undefined;
 
-
 // File: matcher.h lines: 84-84
 //         IndexSpliceInfo _spliceInfo;
-
 proto._spliceInfo = undefined;
 
-
 // File: matcher.h lines: 82-82
-//         boost::scoped_ptr<MatchExpression> _expression;
-
+//         boost.scoped_ptr<MatchExpression> _expression;
 proto._expression = undefined;
 
-
 // File: matcher.h lines: 80-80
 //         BSONObj _indexKey;
-
 proto._indexKey = undefined;
 
-
 // File: matcher.h lines: 79-79
 //         BSONObj _pattern;
-
 proto._pattern = undefined;
 
-
 // File: matcher.h lines: 84-84
 //         IndexSpliceInfo _spliceInfo;
-
 proto._spliceInfo = undefined;
 
-
-
-
-
 /**
- * 
+ *
  * This documentation was automatically generated. Please update when you touch this function.
  * @method Matcher2
  * @param
  *
  */
-proto.Matcher2 = function Matcher2( /*  const Matcher2 &docMatcher, const BSONObj &constrainIndexKey  */ ){
-
-// File: matcher.cpp lines: 94-102
-//     Matcher2::Matcher2( const Matcher2 &docMatcher, const BSONObj &constrainIndexKey )
-//         : _indexKey( constrainIndexKey ) {
-// 
-//         MatchExpression* indexExpression = spliceForIndex( constrainIndexKey,
-//                                                            docMatcher._expression.get(),
-//                                                            &_spliceInfo );
-//         if ( indexExpression ) {
-//             _expression.reset( indexExpression );
-//         }
-//     }
-
-
-
-}
-
+proto.Matcher2 = function Matcher2(docMatcher, constrainIndexKey){
+	// File: matcher.cpp lines: 94-102
+	var indexExpression = this.spliceForIndex(constrainIndexKey, docMatcher._expression.get(), this._spliceInfo);
+	if (indexExpression) {
+		this._expression.reset(indexExpression);
+	}
+};
 
 /**
- * 
+ *
  * This documentation was automatically generated. Please update when you touch this function.
  * @method _spliceForIndex
  * @param
  *
  */
-proto._spliceForIndex = function _spliceForIndex( /*  const set<string>& keys,$/;" */ ){
-
-// File: matcher.cpp lines: 236-380
-//     MatchExpression* Matcher2::_spliceForIndex( const set<string>& keys,
-//                                                 const MatchExpression* full,
-//                                                 Matcher2::IndexSpliceInfo* spliceInfo  ) {
-// 
-//         switch ( full->matchType() ) {
-//         case MatchExpression::ALWAYS_FALSE:
-//             return new FalseMatchExpression();
-// 
-//         case MatchExpression::GEO_NEAR:
-//         case MatchExpression::NOT:
-//         case MatchExpression::NOR:
-//             // maybe?
-//             return NULL;
-// 
-//         case MatchExpression::OR:
-// 
-//         case MatchExpression::AND: {
-//             auto_ptr<ListOfMatchExpression> dup;
-//             for ( unsigned i = 0; i < full->numChildren(); i++ ) {
-//                 MatchExpression* sub = _spliceForIndex( keys, full->getChild( i ), spliceInfo );
-//                 if ( !sub )
-//                     continue;
-//                 if ( !dup.get() ) {
-//                     if ( full->matchType() == MatchExpression::AND )
-//                         dup.reset( new AndMatchExpression() );
-//                     else
-//                         dup.reset( new OrMatchExpression() );
-//                 }
-//                 dup->add( sub );
-//             }
-//             if ( dup.get() ) {
-//                 if ( full->matchType() == MatchExpression::OR &&
-//                      dup->numChildren() != full->numChildren() ) {
-//                     // TODO: I think this should actuall get a list of all the fields
-//                     // and make sure that's the same
-//                     // with an $or, have to make sure its all or nothing
-//                     return NULL;
-//                 }
-//                 return dup.release();
-//             }
-//             return NULL;
-//         }
-// 
-//         case MatchExpression::EQ: {
-//             const ComparisonMatchExpression* cmp =
-//                 static_cast<const ComparisonMatchExpression*>( full );
-// 
-//             if ( cmp->getRHS().type() == Array ) {
-//                 // need to convert array to an $in
-// 
-//                 if ( !keys.count( cmp->path().toString() ) )
-//                     return NULL;
-// 
-//                 auto_ptr<InMatchExpression> newIn( new InMatchExpression() );
-//                 newIn->init( cmp->path() );
-// 
-//                 if ( newIn->getArrayFilterEntries()->addEquality( cmp->getRHS() ).isOK() )
-//                     return NULL;
-// 
-//                 if ( cmp->getRHS().Obj().isEmpty() )
-//                     newIn->getArrayFilterEntries()->addEquality( myUndefinedElement );
-// 
-//                 BSONObjIterator i( cmp->getRHS().Obj() );
-//                 while ( i.more() ) {
-//                     Status s = newIn->getArrayFilterEntries()->addEquality( i.next() );
-//                     if ( !s.isOK() )
-//                         return NULL;
-//                 }
-// 
-//                 return newIn.release();
-//             }
-//             else if ( cmp->getRHS().type() == jstNULL ) {
-//                 //spliceInfo->hasNullEquality = true;
-//                 return NULL;
-//             }
-//         }
-// 
-//         case MatchExpression::LTE:
-//         case MatchExpression::LT:
-//         case MatchExpression::GT:
-//         case MatchExpression::GTE: {
-//             const ComparisonMatchExpression* cmp =
-//                 static_cast<const ComparisonMatchExpression*>( full );
-// 
-//             if ( cmp->getRHS().type() == jstNULL ) {
-//                 // null and indexes don't play nice
-//                 //spliceInfo->hasNullEquality = true;
-//                 return NULL;
-//             }
-//         }
-//         case MatchExpression::REGEX:
-//         case MatchExpression::MOD: {
-//             const LeafMatchExpression* lme = static_cast<const LeafMatchExpression*>( full );
-//             if ( !keys.count( lme->path().toString() ) )
-//                 return NULL;
-//             return lme->shallowClone();
-//         }
-// 
-//         case MatchExpression::MATCH_IN: {
-//             const LeafMatchExpression* lme = static_cast<const LeafMatchExpression*>( full );
-//             if ( !keys.count( lme->path().toString() ) )
-//                 return NULL;
-//             InMatchExpression* cloned = static_cast<InMatchExpression*>(lme->shallowClone());
-//             if ( cloned->getArrayFilterEntries()->hasEmptyArray() )
-//                 cloned->getArrayFilterEntries()->addEquality( myUndefinedElement );
-// 
-//             // since { $in : [[1]] } matches [1], need to explode
-//             for ( BSONElementSet::const_iterator i = cloned->getArrayFilterEntries()->equalities().begin();
-//                   i != cloned->getArrayFilterEntries()->equalities().end();
-//                   ++i ) {
-//                 const BSONElement& x = *i;
-//                 if ( x.type() == Array ) {
-//                     BSONObjIterator j( x.Obj() );
-//                     while ( j.more() ) {
-//                         cloned->getArrayFilterEntries()->addEquality( j.next() );
-//                     }
-//                 }
-//             }
-// 
-//             return cloned;
-//         }
-// 
-//         case MatchExpression::ALL:
-//             // TODO: conver to $in
-//             return NULL;
-// 
-//         case MatchExpression::ELEM_MATCH_OBJECT:
-//         case MatchExpression::ELEM_MATCH_VALUE:
-//             // future
-//             return NULL;
-// 
-//         case MatchExpression::GEO:
-//         case MatchExpression::SIZE:
-//         case MatchExpression::EXISTS:
-//         case MatchExpression::NIN:
-//         case MatchExpression::TYPE_OPERATOR:
-//         case MatchExpression::ATOMIC:
-//         case MatchExpression::WHERE:
-//             // no go
-//             return NULL;
-// 
-// 
-//         }
-// 
-//         return NULL;
-//     }
-
-
-
-}
-
+proto._spliceForIndex = function _spliceForIndex(keys, full, spliceInfo){
+	// File: matcher.cpp lines: 236-380
+	switch (full.matchType()) {
+		case MatchExpression.ALWAYS_FALSE:
+			return new FalseMatchExpression();
+
+		case MatchExpression.GEO_NEAR:
+		case MatchExpression.NOT:
+		case MatchExpression.NOR:
+			// maybe?
+			return NULL;
+
+		case MatchExpression.OR:
+
+		case MatchExpression.AND:
+			var dup = new ListOfMatchExpression();
+			for (var i = 0; i < full.numChildren(); i++) {
+				var sub = this._spliceForIndex(keys, full.getChild(i), spliceInfo);
+				if (!sub)
+					continue;
+				if (!dup.get()) {
+					if (full.matchType() == MatchExpression.AND)
+						dup.reset(new AndMatchExpression());
+					else
+						dup.reset(new OrMatchExpression());
+				}
+				dup.add(sub);
+			}
+			if (dup.get()) {
+				if (full.matchType() == MatchExpression.OR &&  dup.numChildren() != full.numChildren()) {
+					// TODO: I think this should actuall get a list of all the fields
+					// and make sure that's the same
+					// with an $or, have to make sure its all or nothing
+					return null;
+				}
+				return dup.release();
+			}
+			return null;
+
+		case MatchExpression.EQ:
+			var cmp = new ComparisonMatchExpression(full);
+
+			if (cmp.getRHS().type() == Array) {
+				// need to convert array to an $in
+
+				if (!keys.count(cmp.path().toString()))
+					return null;
+
+				var newIn = new InMatchExpression();
+				newIn.init(cmp.path());
+
+				if (newIn.getArrayFilterEntries().addEquality(cmp.getRHS()).isOK())
+					return null;
+
+				if (cmp.getRHS().Obj().isEmpty())
+					newIn.getArrayFilterEntries().addEquality(myUndefinedElement);
+
+				var obj = cmp.getRHS().Obj();
+				for(var i in obj) {
+					var s = newIn.getArrayFilterEntries().addEquality( obj[i].next() );
+					if (s.code != ErrorCode.OK)
+						return null;
+				}
+
+				return newIn.release();
+			}
+			else if (cmp.getRHS().type() === null) {
+				//spliceInfo.hasNullEquality = true;
+				return null;
+			}
+			break;
+
+		case MatchExpression.LTE:
+		case MatchExpression.LT:
+		case MatchExpression.GT:
+		case MatchExpression.GTE:
+			var cmp = new ComparisonMatchExpression(full);
+
+			if ( cmp.getRHS().type() === null) {
+				// null and indexes don't play nice
+				//spliceInfo.hasNullEquality = true;
+				return null;
+			}
+			break;
+
+		case MatchExpression.REGEX:
+		case MatchExpression.MOD:
+			var lme = new LeafMatchExpression(full);
+			if (!keys.count(lme.path().toString()))
+				return null;
+			return lme.shallowClone();
+
+		case MatchExpression.MATCH_IN:
+			var lme = new LeafMatchExpression(full);
+			if (!keys.count(lme.path().toString()))
+				return null;
+			var cloned = new InMatchExpression(lme.shallowClone());
+			if (cloned.getArrayFilterEntries().hasEmptyArray())
+				cloned.getArrayFilterEntries().addEquality(myUndefinedElement);
+
+			// since { $in : [[1]] } matches [1], need to explode
+			for (var i = cloned.getArrayFilterEntries().equalities().begin(); i != cloned.getArrayFilterEntries().equalities().end(); ++i) {
+				var x = *i;
+				if (x.type() == Array) {
+					BSONObjIterator j( x.Obj() );
+					while ( j.more() ) {
+						cloned.getArrayFilterEntries().addEquality( j.next() );
+					}
+				}
+			}
+
+			return cloned;
+
+		case MatchExpression.ALL:
+			// TODO: conver to $in
+			return null;
+
+		case MatchExpression.ELEM_MATCH_OBJECT:
+		case MatchExpression.ELEM_MATCH_VALUE:
+			// future
+			return null;
+
+		case MatchExpression.GEO:
+		case MatchExpression.SIZE:
+		case MatchExpression.EXISTS:
+		case MatchExpression.NIN:
+		case MatchExpression.TYPE_OPERATOR:
+		case MatchExpression.ATOMIC:
+		case MatchExpression.WHERE:
+			// no go
+			return null;
+	}
+
+	return null;
+};
 
 /**
- * 
+ *
  * This documentation was automatically generated. Please update when you touch this function.
  * @method atomic
  * @param
  *
  */
-proto.atomic = function atomic( /*  */ ){
-
+proto.atomic = function atomic(){
 // File: matcher.cpp lines: 120-133
-//     bool Matcher2::atomic() const {
-//         if ( !_expression )
-//             return false;
-// 
-//         if ( _expression->matchType() == MatchExpression::ATOMIC )
-//             return true;
-// 
-//         // we only go down one level
-//         for ( unsigned i = 0; i < _expression->numChildren(); i++ ) {
-//             if ( _expression->getChild( i )->matchType() == MatchExpression::ATOMIC )
-//                 return true;
-//         }
-// 
-//         return false;
-//     }
+	if (!this._expression)
+		return false;
 
+	if (this._expression.matchType() == MatchExpression.ATOMIC)
+		return true;
 
+	// we only go down one level
+	for (var i = 0; i < this._expression.numChildren(); i++) {
+		if (this._expression.getChild(i).matchType() == MatchExpression.ATOMIC)
+			return true;
+	}
 
-}
-
+	return false;
+};
 
 /**
- * 
+ *
  * This documentation was automatically generated. Please update when you touch this function.
  * @method getQuery
  * @param
  *
  */
-proto.getQuery = function getQuery( /*  */ ){
-// File: matcher.h lines: 65-64
-//         const BSONObj* getQuery() const { return &_pattern; };
-
-
-
-
-}
-
+proto.getQuery = function getQuery(){
+	// File: matcher.h lines: 65-64
+	return this._pattern;
+};
 
 /**
- * 
+ *
  * This documentation was automatically generated. Please update when you touch this function.
  * @method hasExistsFalse
  * @param
  *
  */
-proto.hasExistsFalse = function hasExistsFalse( /*  */ ){
-
-// File: matcher.cpp lines: 172-180
-//     bool Matcher2::hasExistsFalse() const {
-//         if ( _spliceInfo.hasNullEquality ) {
-//             // { a : NULL } is very dangerous as it may not got indexed in some cases
-//             // so we just totally ignore
-//             return true;
-//         }
-// 
-//         return _isExistsFalse( _expression.get(), false,
-//                                _expression->matchType() == MatchExpression::AND ? -1 : 0 );
-//     }
-
-
-
-}
+proto.hasExistsFalse = function hasExistsFalse(){
+	// File: matcher.cpp lines: 172-180
+	if (this._spliceInfo.hasNullEquality) {
+		// { a : NULL } is very dangerous as it may not got indexed in some cases
+		// so we just totally ignore
+		return true;
+	}
 
+	return this._isExistsFalse(this._expression.get(), false, this._expression.matchType() == MatchExpression.AND ? -1 : 0);
+};
 
 /**
- * 
+ *
  * This documentation was automatically generated. Please update when you touch this function.
  * @method keyMatch
  * @param
  *
  */
-proto.keyMatch = function keyMatch( /*  const Matcher2 &docMatcher  */ ){
-
-// File: matcher.cpp lines: 199-206
-//     bool Matcher2::keyMatch( const Matcher2 &docMatcher ) const {
-//         if ( !_expression )
-//             return docMatcher._expression.get() == NULL;
-//         if ( !docMatcher._expression )
-//             return false;
-//         if ( _spliceInfo.hasNullEquality )
-//             return false;
-//         return _expression->equivalent( docMatcher._expression.get() );
-//     }
-
-
-
-}
-
+proto.keyMatch = function keyMatch(docMatcher){
+	// File: matcher.cpp lines: 199-206
+	if (!this._expression)
+		return docMatcher._expression.get() === null;
+	if (!docMatcher._expression)
+		return false;
+	if (this._spliceInfo.hasNullEquality)
+		return false;
+	return this._expression.equivalent(docMatcher._expression.get());
+};
 
 /**
- * 
+ *
  * This documentation was automatically generated. Please update when you touch this function.
  * @method matches
  * @param
  *
  */
-proto.matches = function matches( /* const BSONObj& doc, MatchDetails* details  */ ){
+proto.matches = function matches(doc, details){
+	// File: matcher.cpp lines: 105-116
+	if (!this._expression)
+		return true;
 
-// File: matcher.cpp lines: 105-116
-//     bool Matcher2::matches(const BSONObj& doc, MatchDetails* details ) const {
-//         if ( !_expression )
-//             return true;
-// 
-//         if ( _indexKey.isEmpty() )
-//             return _expression->matchesBSON( doc, details );
-// 
-//         if ( !doc.isEmpty() && doc.firstElement().fieldName()[0] )
-//             return _expression->matchesBSON( doc, details );
-// 
-//         IndexKeyMatchableDocument mydoc( _indexKey, doc );
-//         return _expression->matches( &mydoc, details );
-//     }
+	if (this._indexKey.isEmpty())
+		return this._expression.matchesBSON(doc, details);
 
+	if (!doc.isEmpty() && doc.firstElement().fieldName()[0])
+		return this._expression.matchesBSON(doc, details);
 
-
-}
-
+	mydoc = new IndexKeyMatchableDocument(this._indexKey, doc);
+	return this._expression.matches(mydoc, details);
+};
 
 /**
- * 
+ *
  * This documentation was automatically generated. Please update when you touch this function.
  * @method singleSimpleCriterion
  * @param
  *
  */
-proto.singleSimpleCriterion = function singleSimpleCriterion( /*  */ ){
-
-// File: matcher.cpp lines: 184-196
-//     bool Matcher2::singleSimpleCriterion() const {
-//         if ( !_expression )
-//             return false;
-// 
-//         if ( _expression->matchType() == MatchExpression::EQ )
-//             return true;
-// 
-//         if ( _expression->matchType() == MatchExpression::AND &&
-//              _expression->numChildren() == 1 &&
-//              _expression->getChild(0)->matchType() == MatchExpression::EQ )
-//             return true;
-// 
-//         return false;
-//     }
+proto.singleSimpleCriterion = function singleSimpleCriterion(){
+	// File: matcher.cpp lines: 184-196
+	if (!this._expression)
+		return false;
 
+	if (this._expression.matchType() == MatchExpression.EQ)
+		return true;
 
+	if (this._expression.matchType() == MatchExpression.AND && this._expression.numChildren() == 1 && this._expression.getChild(0).matchType() == MatchExpression.EQ)
+		return true;
 
-}
-
+	return false;
+};
 
 /**
- * 
+ *
  * This documentation was automatically generated. Please update when you touch this function.
  * @method spliceForIndex
  * @param
  *
  */
-proto.spliceForIndex = function spliceForIndex( /*  const BSONObj& key,$/;" */ ){
-
-// File: matcher.cpp lines: 209-217
-//     MatchExpression* Matcher2::spliceForIndex( const BSONObj& key,
-//                                                const MatchExpression* full,
-//                                                Matcher2::IndexSpliceInfo* spliceInfo ) {
-//         set<string> keys;
-//         for ( BSONObjIterator i(key); i.more(); ) {
-//             BSONElement e = i.next();
-//             keys.insert( e.fieldName() );
-//         }
-//         return _spliceForIndex( keys, full, spliceInfo );
-//     }
-
-
-
-}
-
+proto.spliceForIndex = function spliceForIndex(key, full, spliceInfo){
+	// File: matcher.cpp lines: 209-217
+	var keys = [];
+	for (var i in key) {
+		e = key[i];
+		keys.insert(e.fieldName());
+	}
+	return this._spliceForIndex(keys, full, spliceInfo);
+};
 
 /**
- * 
+ *
  * This documentation was automatically generated. Please update when you touch this function.
  * @method toString
  * @param
  *
  */
-proto.toString = function toString( /*  */ ){
-// File: matcher.h lines: 66-65
-//         std::string toString() const { return _pattern.toString(); }
-
-
-
-
-}
+proto.toString = function toString(){
+	// File: matcher.h lines: 66-65
+	return this._pattern.toString();
+};