|
|
@@ -0,0 +1,836 @@
|
|
|
+"use strict"
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+// Autogenerated by cport.py on 2013-09-17 14:37
|
|
|
+var MatchExpressionParser = module.exports = function (){
|
|
|
+
|
|
|
+}, klass = MatchExpressionParser, base = Object , proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * This documentation was automatically generated. Please update when you touch this function.
|
|
|
+ * @method _isExpressionDocument
|
|
|
+ * @param
|
|
|
+ *
|
|
|
+ */
|
|
|
+proto._isExpressionDocument = function _isExpressionDocument( /* const BSONElement& e */ ){
|
|
|
+
|
|
|
+// File: expression_parser.cpp lines: 340-355
|
|
|
+// bool MatchExpressionParser::_isExpressionDocument( const BSONElement& e ) {
|
|
|
+// if ( e.type() != Object )
|
|
|
+// return false;
|
|
|
+//
|
|
|
+// BSONObj o = e.Obj();
|
|
|
+// if ( o.isEmpty() )
|
|
|
+// return false;
|
|
|
+//
|
|
|
+// const char* name = o.firstElement().fieldName();
|
|
|
+// if ( name[0] != '$' )
|
|
|
+// return false;
|
|
|
+//
|
|
|
+// if ( mongoutils::str::equals( "$ref", name ) )
|
|
|
+// return false;
|
|
|
+//
|
|
|
+// return true;
|
|
|
+// }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * This documentation was automatically generated. Please update when you touch this function.
|
|
|
+ * @method _parse
|
|
|
+ * @param
|
|
|
+ *
|
|
|
+ */
|
|
|
+proto._parse = function _parse( /* const BSONObj& obj, bool topLevel */ ){
|
|
|
+
|
|
|
+// File: expression_parser.cpp lines: 217-319
|
|
|
+// StatusWithMatchExpression MatchExpressionParser::_parse( const BSONObj& obj, bool topLevel ) {
|
|
|
+//
|
|
|
+// std::auto_ptr<AndMatchExpression> root( new AndMatchExpression() );
|
|
|
+//
|
|
|
+// BSONObjIterator i( obj );
|
|
|
+// while ( i.more() ){
|
|
|
+//
|
|
|
+// BSONElement e = i.next();
|
|
|
+// if ( e.fieldName()[0] == '$' ) {
|
|
|
+// const char * rest = e.fieldName() + 1;
|
|
|
+//
|
|
|
+// // TODO: optimize if block?
|
|
|
+// if ( mongoutils::str::equals( "or", rest ) ) {
|
|
|
+// if ( e.type() != Array )
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue,
|
|
|
+// "$or needs an array" );
|
|
|
+// std::auto_ptr<OrMatchExpression> temp( new OrMatchExpression() );
|
|
|
+// Status s = _parseTreeList( e.Obj(), temp.get() );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return StatusWithMatchExpression( s );
|
|
|
+// root->add( temp.release() );
|
|
|
+// }
|
|
|
+// else if ( mongoutils::str::equals( "and", rest ) ) {
|
|
|
+// if ( e.type() != Array )
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue,
|
|
|
+// "and needs an array" );
|
|
|
+// std::auto_ptr<AndMatchExpression> temp( new AndMatchExpression() );
|
|
|
+// Status s = _parseTreeList( e.Obj(), temp.get() );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return StatusWithMatchExpression( s );
|
|
|
+// root->add( temp.release() );
|
|
|
+// }
|
|
|
+// else if ( mongoutils::str::equals( "nor", rest ) ) {
|
|
|
+// if ( e.type() != Array )
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue,
|
|
|
+// "and needs an array" );
|
|
|
+// std::auto_ptr<NorMatchExpression> temp( new NorMatchExpression() );
|
|
|
+// Status s = _parseTreeList( e.Obj(), temp.get() );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return StatusWithMatchExpression( s );
|
|
|
+// root->add( temp.release() );
|
|
|
+// }
|
|
|
+// else if ( mongoutils::str::equals( "atomic", rest ) ||
|
|
|
+// mongoutils::str::equals( "isolated", rest ) ) {
|
|
|
+// if ( !topLevel )
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue,
|
|
|
+// "$atomic/$isolated has to be at the top level" );
|
|
|
+// if ( e.trueValue() )
|
|
|
+// root->add( new AtomicMatchExpression() );
|
|
|
+// }
|
|
|
+// else if ( mongoutils::str::equals( "where", rest ) ) {
|
|
|
+// /*
|
|
|
+// if ( !topLevel )
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue,
|
|
|
+// "$where has to be at the top level" );
|
|
|
+// */
|
|
|
+// StatusWithMatchExpression s = expressionParserWhereCallback( e );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return s;
|
|
|
+// root->add( s.getValue() );
|
|
|
+// }
|
|
|
+// else if ( mongoutils::str::equals( "comment", rest ) ) {
|
|
|
+// }
|
|
|
+// else {
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue,
|
|
|
+// mongoutils::str::stream()
|
|
|
+// << "unknown top level operator: "
|
|
|
+// << e.fieldName() );
|
|
|
+// }
|
|
|
+//
|
|
|
+// continue;
|
|
|
+// }
|
|
|
+//
|
|
|
+// if ( _isExpressionDocument( e ) ) {
|
|
|
+// Status s = _parseSub( e.fieldName(), e.Obj(), root.get() );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return StatusWithMatchExpression( s );
|
|
|
+// continue;
|
|
|
+// }
|
|
|
+//
|
|
|
+// if ( e.type() == RegEx ) {
|
|
|
+// StatusWithMatchExpression result = _parseRegexElement( e.fieldName(), e );
|
|
|
+// if ( !result.isOK() )
|
|
|
+// return result;
|
|
|
+// root->add( result.getValue() );
|
|
|
+// continue;
|
|
|
+// }
|
|
|
+//
|
|
|
+// std::auto_ptr<ComparisonMatchExpression> eq( new EqualityMatchExpression() );
|
|
|
+// Status s = eq->init( e.fieldName(), e );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return StatusWithMatchExpression( s );
|
|
|
+//
|
|
|
+// root->add( eq.release() );
|
|
|
+// }
|
|
|
+//
|
|
|
+// if ( root->numChildren() == 1 ) {
|
|
|
+// const MatchExpression* real = root->getChild(0);
|
|
|
+// root->clearAndRelease();
|
|
|
+// return StatusWithMatchExpression( const_cast<MatchExpression*>(real) );
|
|
|
+// }
|
|
|
+//
|
|
|
+// return StatusWithMatchExpression( root.release() );
|
|
|
+// }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * This documentation was automatically generated. Please update when you touch this function.
|
|
|
+ * @method _parseAll
|
|
|
+ * @param
|
|
|
+ *
|
|
|
+ */
|
|
|
+proto._parseAll = function _parseAll( /* const char* name,$/;" */ ){
|
|
|
+
|
|
|
+// File: expression_parser.cpp lines: 512-583
|
|
|
+// StatusWithMatchExpression MatchExpressionParser::_parseAll( const char* name,
|
|
|
+// const BSONElement& e ) {
|
|
|
+// if ( e.type() != Array )
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue, "$all needs an array" );
|
|
|
+//
|
|
|
+// BSONObj arr = e.Obj();
|
|
|
+// if ( arr.firstElement().type() == Object &&
|
|
|
+// mongoutils::str::equals( "$elemMatch",
|
|
|
+// arr.firstElement().Obj().firstElement().fieldName() ) ) {
|
|
|
+// // $all : [ { $elemMatch : {} } ... ]
|
|
|
+//
|
|
|
+// std::auto_ptr<AllElemMatchOp> temp( new AllElemMatchOp() );
|
|
|
+// Status s = temp->init( name );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return StatusWithMatchExpression( s );
|
|
|
+//
|
|
|
+// BSONObjIterator i( arr );
|
|
|
+// while ( i.more() ) {
|
|
|
+// BSONElement hopefullyElemMatchElement = i.next();
|
|
|
+//
|
|
|
+// if ( hopefullyElemMatchElement.type() != Object ) {
|
|
|
+// // $all : [ { $elemMatch : ... }, 5 ]
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue,
|
|
|
+// "$all/$elemMatch has to be consistent" );
|
|
|
+// }
|
|
|
+//
|
|
|
+// BSONObj hopefullyElemMatchObj = hopefullyElemMatchElement.Obj();
|
|
|
+// if ( !mongoutils::str::equals( "$elemMatch",
|
|
|
+// hopefullyElemMatchObj.firstElement().fieldName() ) ) {
|
|
|
+// // $all : [ { $elemMatch : ... }, { x : 5 } ]
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue,
|
|
|
+// "$all/$elemMatch has to be consistent" );
|
|
|
+// }
|
|
|
+//
|
|
|
+// StatusWithMatchExpression inner = _parseElemMatch( "", hopefullyElemMatchObj.firstElement() );
|
|
|
+// if ( !inner.isOK() )
|
|
|
+// return inner;
|
|
|
+// temp->add( static_cast<ArrayMatchingMatchExpression*>( inner.getValue() ) );
|
|
|
+// }
|
|
|
+//
|
|
|
+// return StatusWithMatchExpression( temp.release() );
|
|
|
+// }
|
|
|
+//
|
|
|
+// std::auto_ptr<AndMatchExpression> myAnd( new AndMatchExpression() );
|
|
|
+// BSONObjIterator i( arr );
|
|
|
+// while ( i.more() ) {
|
|
|
+// BSONElement e = i.next();
|
|
|
+//
|
|
|
+// if ( e.type() == RegEx ) {
|
|
|
+// std::auto_ptr<RegexMatchExpression> r( new RegexMatchExpression() );
|
|
|
+// Status s = r->init( name, e );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return StatusWithMatchExpression( s );
|
|
|
+// myAnd->add( r.release() );
|
|
|
+// }
|
|
|
+// else if ( e.type() == Object && e.Obj().firstElement().getGtLtOp(-1) != -1 ) {
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue, "no $ expressions in $all" );
|
|
|
+// }
|
|
|
+// else {
|
|
|
+// std::auto_ptr<EqualityMatchExpression> x( new EqualityMatchExpression() );
|
|
|
+// Status s = x->init( name, e );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return StatusWithMatchExpression( s );
|
|
|
+// myAnd->add( x.release() );
|
|
|
+// }
|
|
|
+// }
|
|
|
+//
|
|
|
+// if ( myAnd->numChildren() == 0 ) {
|
|
|
+// return StatusWithMatchExpression( new FalseMatchExpression() );
|
|
|
+// }
|
|
|
+//
|
|
|
+// return StatusWithMatchExpression( myAnd.release() );
|
|
|
+// }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * This documentation was automatically generated. Please update when you touch this function.
|
|
|
+ * @method _parseArrayFilterEntries
|
|
|
+ * @param
|
|
|
+ *
|
|
|
+ */
|
|
|
+proto._parseArrayFilterEntries = function _parseArrayFilterEntries( /* ArrayFilterEntries* entries,$/;" */ ){
|
|
|
+
|
|
|
+// File: expression_parser.cpp lines: 445-468
|
|
|
+// Status MatchExpressionParser::_parseArrayFilterEntries( ArrayFilterEntries* entries,
|
|
|
+// const BSONObj& theArray ) {
|
|
|
+//
|
|
|
+// BSONObjIterator i( theArray );
|
|
|
+// while ( i.more() ) {
|
|
|
+// BSONElement e = i.next();
|
|
|
+//
|
|
|
+// if ( e.type() == RegEx ) {
|
|
|
+// std::auto_ptr<RegexMatchExpression> r( new RegexMatchExpression() );
|
|
|
+// Status s = r->init( "", e );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return s;
|
|
|
+// s = entries->addRegex( r.release() );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return s;
|
|
|
+// }
|
|
|
+// else {
|
|
|
+// Status s = entries->addEquality( e );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return s;
|
|
|
+// }
|
|
|
+// }
|
|
|
+// return Status::OK();
|
|
|
+//
|
|
|
+// }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * This documentation was automatically generated. Please update when you touch this function.
|
|
|
+ * @method _parseComparison
|
|
|
+ * @param
|
|
|
+ *
|
|
|
+ */
|
|
|
+proto._parseComparison = function _parseComparison( /* const char* name,$/;" */ ){
|
|
|
+
|
|
|
+// File: expression_parser.cpp lines: 34-43
|
|
|
+// StatusWithMatchExpression MatchExpressionParser::_parseComparison( const char* name,
|
|
|
+// ComparisonMatchExpression* cmp,
|
|
|
+// const BSONElement& e ) {
|
|
|
+// std::auto_ptr<ComparisonMatchExpression> temp( cmp );
|
|
|
+//
|
|
|
+// Status s = temp->init( name, e );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return StatusWithMatchExpression(s);
|
|
|
+//
|
|
|
+// return StatusWithMatchExpression( temp.release() );
|
|
|
+// }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * This documentation was automatically generated. Please update when you touch this function.
|
|
|
+ * @method _parseElemMatch
|
|
|
+ * @param
|
|
|
+ *
|
|
|
+ */
|
|
|
+proto._parseElemMatch = function _parseElemMatch( /* const char* name,$/;" */ ){
|
|
|
+
|
|
|
+// File: expression_parser.cpp lines: 471-509
|
|
|
+// StatusWithMatchExpression MatchExpressionParser::_parseElemMatch( const char* name,
|
|
|
+// const BSONElement& e ) {
|
|
|
+// if ( e.type() != Object )
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue, "$elemMatch needs an Object" );
|
|
|
+//
|
|
|
+// BSONObj obj = e.Obj();
|
|
|
+// if ( _isExpressionDocument( e ) ) {
|
|
|
+// // value case
|
|
|
+//
|
|
|
+// AndMatchExpression theAnd;
|
|
|
+// Status s = _parseSub( "", obj, &theAnd );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return StatusWithMatchExpression( s );
|
|
|
+//
|
|
|
+// std::auto_ptr<ElemMatchValueMatchExpression> temp( new ElemMatchValueMatchExpression() );
|
|
|
+// s = temp->init( name );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return StatusWithMatchExpression( s );
|
|
|
+//
|
|
|
+// for ( size_t i = 0; i < theAnd.numChildren(); i++ ) {
|
|
|
+// temp->add( theAnd.getChild( i ) );
|
|
|
+// }
|
|
|
+// theAnd.clearAndRelease();
|
|
|
+//
|
|
|
+// return StatusWithMatchExpression( temp.release() );
|
|
|
+// }
|
|
|
+//
|
|
|
+// // object case
|
|
|
+//
|
|
|
+// StatusWithMatchExpression sub = _parse( obj, false );
|
|
|
+// if ( !sub.isOK() )
|
|
|
+// return sub;
|
|
|
+//
|
|
|
+// std::auto_ptr<ElemMatchObjectMatchExpression> temp( new ElemMatchObjectMatchExpression() );
|
|
|
+// Status status = temp->init( name, sub.getValue() );
|
|
|
+// if ( !status.isOK() )
|
|
|
+// return StatusWithMatchExpression( status );
|
|
|
+//
|
|
|
+// return StatusWithMatchExpression( temp.release() );
|
|
|
+// }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * This documentation was automatically generated. Please update when you touch this function.
|
|
|
+ * @method _parseMOD
|
|
|
+ * @param
|
|
|
+ *
|
|
|
+ */
|
|
|
+proto._parseMOD = function _parseMOD( /* const char* name,$/;" */ ){
|
|
|
+
|
|
|
+// File: expression_parser.cpp lines: 360-387
|
|
|
+// StatusWithMatchExpression MatchExpressionParser::_parseMOD( const char* name,
|
|
|
+// const BSONElement& e ) {
|
|
|
+//
|
|
|
+// if ( e.type() != Array )
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue, "malformed mod, needs to be an array" );
|
|
|
+//
|
|
|
+// BSONObjIterator i( e.Obj() );
|
|
|
+//
|
|
|
+// if ( !i.more() )
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue, "malformed mod, not enough elements" );
|
|
|
+// BSONElement d = i.next();
|
|
|
+// if ( !d.isNumber() )
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue, "malformed mod, divisor not a number" );
|
|
|
+//
|
|
|
+// if ( !i.more() )
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue, "malformed mod, not enough elements" );
|
|
|
+// BSONElement r = i.next();
|
|
|
+// if ( !d.isNumber() )
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue, "malformed mod, remainder not a number" );
|
|
|
+//
|
|
|
+// if ( i.more() )
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue, "malformed mod, too many elements" );
|
|
|
+//
|
|
|
+// std::auto_ptr<ModMatchExpression> temp( new ModMatchExpression() );
|
|
|
+// Status s = temp->init( name, d.numberInt(), r.numberInt() );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return StatusWithMatchExpression( s );
|
|
|
+// return StatusWithMatchExpression( temp.release() );
|
|
|
+// }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * This documentation was automatically generated. Please update when you touch this function.
|
|
|
+ * @method _parseNot
|
|
|
+ * @param
|
|
|
+ *
|
|
|
+ */
|
|
|
+proto._parseNot = function _parseNot( /* const char* name,$/;" */ ){
|
|
|
+
|
|
|
+// File: expression_parser_tree.cpp lines: 55-91
|
|
|
+// StatusWithMatchExpression MatchExpressionParser::_parseNot( const char* name,
|
|
|
+// const BSONElement& e ) {
|
|
|
+// if ( e.type() == RegEx ) {
|
|
|
+// StatusWithMatchExpression s = _parseRegexElement( name, e );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return s;
|
|
|
+// std::auto_ptr<NotMatchExpression> n( new NotMatchExpression() );
|
|
|
+// Status s2 = n->init( s.getValue() );
|
|
|
+// if ( !s2.isOK() )
|
|
|
+// return StatusWithMatchExpression( s2 );
|
|
|
+// return StatusWithMatchExpression( n.release() );
|
|
|
+// }
|
|
|
+//
|
|
|
+// if ( e.type() != Object )
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue, "$not needs a regex or a document" );
|
|
|
+//
|
|
|
+// BSONObj notObject = e.Obj();
|
|
|
+// if ( notObject.isEmpty() )
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue, "$not cannot be empty" );
|
|
|
+//
|
|
|
+// std::auto_ptr<AndMatchExpression> theAnd( new AndMatchExpression() );
|
|
|
+// Status s = _parseSub( name, notObject, theAnd.get() );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return StatusWithMatchExpression( s );
|
|
|
+//
|
|
|
+// // TODO: this seems arbitrary?
|
|
|
+// // tested in jstests/not2.js
|
|
|
+// for ( unsigned i = 0; i < theAnd->numChildren(); i++ )
|
|
|
+// if ( theAnd->getChild(i)->matchType() == MatchExpression::REGEX )
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue, "$not cannot have a regex" );
|
|
|
+//
|
|
|
+// std::auto_ptr<NotMatchExpression> theNot( new NotMatchExpression() );
|
|
|
+// s = theNot->init( theAnd.release() );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return StatusWithMatchExpression( s );
|
|
|
+//
|
|
|
+// return StatusWithMatchExpression( theNot.release() );
|
|
|
+// }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * This documentation was automatically generated. Please update when you touch this function.
|
|
|
+ * @method _parseRegexDocument
|
|
|
+ * @param
|
|
|
+ *
|
|
|
+ */
|
|
|
+proto._parseRegexDocument = function _parseRegexDocument( /* const char* name,$/;" */ ){
|
|
|
+
|
|
|
+// File: expression_parser.cpp lines: 402-442
|
|
|
+// StatusWithMatchExpression MatchExpressionParser::_parseRegexDocument( const char* name,
|
|
|
+// const BSONObj& doc ) {
|
|
|
+// string regex;
|
|
|
+// string regexOptions;
|
|
|
+//
|
|
|
+// BSONObjIterator i( doc );
|
|
|
+// while ( i.more() ) {
|
|
|
+// BSONElement e = i.next();
|
|
|
+// switch ( e.getGtLtOp() ) {
|
|
|
+// case BSONObj::opREGEX:
|
|
|
+// if ( e.type() == String ) {
|
|
|
+// regex = e.String();
|
|
|
+// }
|
|
|
+// else if ( e.type() == RegEx ) {
|
|
|
+// regex = e.regex();
|
|
|
+// regexOptions = e.regexFlags();
|
|
|
+// }
|
|
|
+// else {
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue,
|
|
|
+// "$regex has to be a string" );
|
|
|
+// }
|
|
|
+//
|
|
|
+// break;
|
|
|
+// case BSONObj::opOPTIONS:
|
|
|
+// if ( e.type() != String )
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue,
|
|
|
+// "$options has to be a string" );
|
|
|
+// regexOptions = e.String();
|
|
|
+// break;
|
|
|
+// default:
|
|
|
+// break;
|
|
|
+// }
|
|
|
+//
|
|
|
+// }
|
|
|
+//
|
|
|
+// std::auto_ptr<RegexMatchExpression> temp( new RegexMatchExpression() );
|
|
|
+// Status s = temp->init( name, regex, regexOptions );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return StatusWithMatchExpression( s );
|
|
|
+// return StatusWithMatchExpression( temp.release() );
|
|
|
+//
|
|
|
+// }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * This documentation was automatically generated. Please update when you touch this function.
|
|
|
+ * @method _parseRegexElement
|
|
|
+ * @param
|
|
|
+ *
|
|
|
+ */
|
|
|
+proto._parseRegexElement = function _parseRegexElement( /* const char* name,$/;" */ ){
|
|
|
+
|
|
|
+// File: expression_parser.cpp lines: 390-399
|
|
|
+// StatusWithMatchExpression MatchExpressionParser::_parseRegexElement( const char* name,
|
|
|
+// const BSONElement& e ) {
|
|
|
+// if ( e.type() != RegEx )
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue, "not a regex" );
|
|
|
+//
|
|
|
+// std::auto_ptr<RegexMatchExpression> temp( new RegexMatchExpression() );
|
|
|
+// Status s = temp->init( name, e.regex(), e.regexFlags() );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return StatusWithMatchExpression( s );
|
|
|
+// return StatusWithMatchExpression( temp.release() );
|
|
|
+// }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * This documentation was automatically generated. Please update when you touch this function.
|
|
|
+ * @method _parseSub
|
|
|
+ * @param
|
|
|
+ *
|
|
|
+ */
|
|
|
+proto._parseSub = function _parseSub( /* const char* name,$/;" */ ){
|
|
|
+
|
|
|
+// File: expression_parser.cpp lines: 322-337
|
|
|
+// Status MatchExpressionParser::_parseSub( const char* name,
|
|
|
+// const BSONObj& sub,
|
|
|
+// AndMatchExpression* root ) {
|
|
|
+// BSONObjIterator j( sub );
|
|
|
+// while ( j.more() ) {
|
|
|
+// BSONElement deep = j.next();
|
|
|
+//
|
|
|
+// StatusWithMatchExpression s = _parseSubField( sub, root, name, deep );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return s.getStatus();
|
|
|
+//
|
|
|
+// if ( s.getValue() )
|
|
|
+// root->add( s.getValue() );
|
|
|
+// }
|
|
|
+//
|
|
|
+// return Status::OK();
|
|
|
+// }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * This documentation was automatically generated. Please update when you touch this function.
|
|
|
+ * @method _parseSubField
|
|
|
+ * @param
|
|
|
+ *
|
|
|
+ */
|
|
|
+proto._parseSubField = function _parseSubField( /* const BSONObj& context,$/;" */ ){
|
|
|
+
|
|
|
+// File: expression_parser.cpp lines: 46-214
|
|
|
+// StatusWithMatchExpression MatchExpressionParser::_parseSubField( const BSONObj& context,
|
|
|
+// const AndMatchExpression* andSoFar,
|
|
|
+// const char* name,
|
|
|
+// const BSONElement& e ) {
|
|
|
+//
|
|
|
+// // TODO: these should move to getGtLtOp, or its replacement
|
|
|
+//
|
|
|
+// if ( mongoutils::str::equals( "$eq", e.fieldName() ) )
|
|
|
+// return _parseComparison( name, new EqualityMatchExpression(), e );
|
|
|
+//
|
|
|
+// if ( mongoutils::str::equals( "$not", e.fieldName() ) ) {
|
|
|
+// return _parseNot( name, e );
|
|
|
+// }
|
|
|
+//
|
|
|
+// int x = e.getGtLtOp(-1);
|
|
|
+// switch ( x ) {
|
|
|
+// case -1:
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue,
|
|
|
+// mongoutils::str::stream() << "unknown operator: "
|
|
|
+// << e.fieldName() );
|
|
|
+// case BSONObj::LT:
|
|
|
+// return _parseComparison( name, new LTMatchExpression(), e );
|
|
|
+// case BSONObj::LTE:
|
|
|
+// return _parseComparison( name, new LTEMatchExpression(), e );
|
|
|
+// case BSONObj::GT:
|
|
|
+// return _parseComparison( name, new GTMatchExpression(), e );
|
|
|
+// case BSONObj::GTE:
|
|
|
+// return _parseComparison( name, new GTEMatchExpression(), e );
|
|
|
+// case BSONObj::NE: {
|
|
|
+// StatusWithMatchExpression s = _parseComparison( name, new EqualityMatchExpression(), e );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return s;
|
|
|
+// std::auto_ptr<NotMatchExpression> n( new NotMatchExpression() );
|
|
|
+// Status s2 = n->init( s.getValue() );
|
|
|
+// if ( !s2.isOK() )
|
|
|
+// return StatusWithMatchExpression( s2 );
|
|
|
+// return StatusWithMatchExpression( n.release() );
|
|
|
+// }
|
|
|
+// case BSONObj::Equality:
|
|
|
+// return _parseComparison( name, new EqualityMatchExpression(), e );
|
|
|
+//
|
|
|
+// case BSONObj::opIN: {
|
|
|
+// if ( e.type() != Array )
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue, "$in needs an array" );
|
|
|
+// std::auto_ptr<InMatchExpression> temp( new InMatchExpression() );
|
|
|
+// Status s = temp->init( name );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return StatusWithMatchExpression( s );
|
|
|
+// s = _parseArrayFilterEntries( temp->getArrayFilterEntries(), e.Obj() );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return StatusWithMatchExpression( s );
|
|
|
+// return StatusWithMatchExpression( temp.release() );
|
|
|
+// }
|
|
|
+//
|
|
|
+// case BSONObj::NIN: {
|
|
|
+// if ( e.type() != Array )
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue, "$nin needs an array" );
|
|
|
+// std::auto_ptr<InMatchExpression> temp( new InMatchExpression() );
|
|
|
+// Status s = temp->init( name );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return StatusWithMatchExpression( s );
|
|
|
+// s = _parseArrayFilterEntries( temp->getArrayFilterEntries(), e.Obj() );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return StatusWithMatchExpression( s );
|
|
|
+//
|
|
|
+// std::auto_ptr<NotMatchExpression> temp2( new NotMatchExpression() );
|
|
|
+// s = temp2->init( temp.release() );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return StatusWithMatchExpression( s );
|
|
|
+//
|
|
|
+// return StatusWithMatchExpression( temp2.release() );
|
|
|
+// }
|
|
|
+//
|
|
|
+// case BSONObj::opSIZE: {
|
|
|
+// int size = 0;
|
|
|
+// if ( e.type() == String ) {
|
|
|
+// // matching old odd semantics
|
|
|
+// size = 0;
|
|
|
+// }
|
|
|
+// else if ( e.type() == NumberInt || e.type() == NumberLong ) {
|
|
|
+// size = e.numberInt();
|
|
|
+// }
|
|
|
+// else if ( e.type() == NumberDouble ) {
|
|
|
+// if ( e.numberInt() == e.numberDouble() ) {
|
|
|
+// size = e.numberInt();
|
|
|
+// }
|
|
|
+// else {
|
|
|
+// // old semantcs require exact numeric match
|
|
|
+// // so [1,2] != 1 or 2
|
|
|
+// size = -1;
|
|
|
+// }
|
|
|
+// }
|
|
|
+// else {
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue, "$size needs a number" );
|
|
|
+// }
|
|
|
+//
|
|
|
+// std::auto_ptr<SizeMatchExpression> temp( new SizeMatchExpression() );
|
|
|
+// Status s = temp->init( name, size );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return StatusWithMatchExpression( s );
|
|
|
+// return StatusWithMatchExpression( temp.release() );
|
|
|
+// }
|
|
|
+//
|
|
|
+// case BSONObj::opEXISTS: {
|
|
|
+// if ( e.eoo() )
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue, "$exists can't be eoo" );
|
|
|
+// std::auto_ptr<ExistsMatchExpression> temp( new ExistsMatchExpression() );
|
|
|
+// Status s = temp->init( name );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return StatusWithMatchExpression( s );
|
|
|
+// if ( e.trueValue() )
|
|
|
+// return StatusWithMatchExpression( temp.release() );
|
|
|
+// std::auto_ptr<NotMatchExpression> temp2( new NotMatchExpression() );
|
|
|
+// s = temp2->init( temp.release() );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return StatusWithMatchExpression( s );
|
|
|
+// return StatusWithMatchExpression( temp2.release() );
|
|
|
+// }
|
|
|
+//
|
|
|
+// case BSONObj::opTYPE: {
|
|
|
+// if ( !e.isNumber() )
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue, "$type has to be a number" );
|
|
|
+// int type = e.numberInt();
|
|
|
+// if ( e.type() != NumberInt && type != e.number() )
|
|
|
+// type = -1;
|
|
|
+// std::auto_ptr<TypeMatchExpression> temp( new TypeMatchExpression() );
|
|
|
+// Status s = temp->init( name, type );
|
|
|
+// if ( !s.isOK() )
|
|
|
+// return StatusWithMatchExpression( s );
|
|
|
+// return StatusWithMatchExpression( temp.release() );
|
|
|
+// }
|
|
|
+//
|
|
|
+//
|
|
|
+// case BSONObj::opMOD:
|
|
|
+// return _parseMOD( name, e );
|
|
|
+//
|
|
|
+// case BSONObj::opOPTIONS: {
|
|
|
+// // TODO: try to optimize this
|
|
|
+// // we have to do this since $options can be before or after a $regex
|
|
|
+// // but we validate here
|
|
|
+// BSONObjIterator i( context );
|
|
|
+// while ( i.more() ) {
|
|
|
+// BSONElement temp = i.next();
|
|
|
+// if ( temp.getGtLtOp( -1 ) == BSONObj::opREGEX )
|
|
|
+// return StatusWithMatchExpression( NULL );
|
|
|
+// }
|
|
|
+//
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue, "$options needs a $regex" );
|
|
|
+// }
|
|
|
+//
|
|
|
+// case BSONObj::opREGEX: {
|
|
|
+// return _parseRegexDocument( name, context );
|
|
|
+// }
|
|
|
+//
|
|
|
+// case BSONObj::opELEM_MATCH:
|
|
|
+// return _parseElemMatch( name, e );
|
|
|
+//
|
|
|
+// case BSONObj::opALL:
|
|
|
+// return _parseAll( name, e );
|
|
|
+//
|
|
|
+// case BSONObj::opWITHIN:
|
|
|
+// case BSONObj::opGEO_INTERSECTS:
|
|
|
+// case BSONObj::opNEAR:
|
|
|
+// return expressionParserGeoCallback( name, x, context );
|
|
|
+//
|
|
|
+// }
|
|
|
+//
|
|
|
+// return StatusWithMatchExpression( ErrorCodes::BadValue,
|
|
|
+// mongoutils::str::stream() << "not handled: " << e.fieldName() );
|
|
|
+// }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * This documentation was automatically generated. Please update when you touch this function.
|
|
|
+ * @method _parseTreeList
|
|
|
+ * @param
|
|
|
+ *
|
|
|
+ */
|
|
|
+proto._parseTreeList = function _parseTreeList( /* const BSONObj& arr, ListOfMatchExpression* out */ ){
|
|
|
+
|
|
|
+// File: expression_parser_tree.cpp lines: 33-52
|
|
|
+// Status MatchExpressionParser::_parseTreeList( const BSONObj& arr, ListOfMatchExpression* out ) {
|
|
|
+// if ( arr.isEmpty() )
|
|
|
+// return Status( ErrorCodes::BadValue,
|
|
|
+// "$and/$or/$nor must be a nonempty array" );
|
|
|
+//
|
|
|
+// BSONObjIterator i( arr );
|
|
|
+// while ( i.more() ) {
|
|
|
+// BSONElement e = i.next();
|
|
|
+//
|
|
|
+// if ( e.type() != Object )
|
|
|
+// return Status( ErrorCodes::BadValue,
|
|
|
+// "$or/$and/$nor entries need to be full objects" );
|
|
|
+//
|
|
|
+// StatusWithMatchExpression sub = _parse( e.Obj(), false );
|
|
|
+// if ( !sub.isOK() )
|
|
|
+// return sub.getStatus();
|
|
|
+//
|
|
|
+// out->add( sub.getValue() );
|
|
|
+// }
|
|
|
+// return Status::OK();
|
|
|
+// }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * This documentation was automatically generated. Please update when you touch this function.
|
|
|
+ * @method parse
|
|
|
+ * @param
|
|
|
+ *
|
|
|
+ */
|
|
|
+proto.parse = function parse( /* const BSONObj& obj */ ){
|
|
|
+// File: expression_parser.h lines: 40-41
|
|
|
+// static StatusWithMatchExpression parse( const BSONObj& obj ) {
|
|
|
+// return _parse( obj, true );
|
|
|
+// }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+}
|