summaryrefslogtreecommitdiff
path: root/src/mongo/db/matcher/expression_where.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/matcher/expression_where.cpp')
-rw-r--r--src/mongo/db/matcher/expression_where.cpp249
1 files changed, 118 insertions, 131 deletions
diff --git a/src/mongo/db/matcher/expression_where.cpp b/src/mongo/db/matcher/expression_where.cpp
index 804ae7dc687..f3d99b79136 100644
--- a/src/mongo/db/matcher/expression_where.cpp
+++ b/src/mongo/db/matcher/expression_where.cpp
@@ -42,175 +42,162 @@
namespace mongo {
- using std::unique_ptr;
- using std::endl;
- using std::string;
- using std::stringstream;
+using std::unique_ptr;
+using std::endl;
+using std::string;
+using std::stringstream;
- class WhereMatchExpression : public MatchExpression {
- public:
- WhereMatchExpression(OperationContext* txn)
- : MatchExpression(WHERE),
- _txn(txn) {
+class WhereMatchExpression : public MatchExpression {
+public:
+ WhereMatchExpression(OperationContext* txn) : MatchExpression(WHERE), _txn(txn) {
+ invariant(_txn != NULL);
- invariant(_txn != NULL);
+ _func = 0;
+ }
- _func = 0;
- }
+ virtual ~WhereMatchExpression() {}
- virtual ~WhereMatchExpression(){}
+ Status init(StringData dbName, StringData theCode, const BSONObj& scope);
- Status init(StringData dbName, StringData theCode, const BSONObj& scope);
+ virtual bool matches(const MatchableDocument* doc, MatchDetails* details = 0) const;
- virtual bool matches( const MatchableDocument* doc, MatchDetails* details = 0 ) const;
+ virtual bool matchesSingleElement(const BSONElement& e) const {
+ return false;
+ }
- virtual bool matchesSingleElement( const BSONElement& e ) const {
- return false;
+ virtual MatchExpression* shallowClone() const {
+ WhereMatchExpression* e = new WhereMatchExpression(_txn);
+ e->init(_dbName, _code, _userScope);
+ if (getTag()) {
+ e->setTag(getTag()->clone());
}
+ return e;
+ }
- virtual MatchExpression* shallowClone() const {
- WhereMatchExpression* e = new WhereMatchExpression(_txn);
- e->init(_dbName, _code, _userScope);
- if (getTag()) {
- e->setTag(getTag()->clone());
- }
- return e;
- }
+ virtual void debugString(StringBuilder& debug, int level = 0) const;
- virtual void debugString( StringBuilder& debug, int level = 0 ) const;
+ virtual void toBSON(BSONObjBuilder* out) const;
- virtual void toBSON(BSONObjBuilder* out) const;
+ virtual bool equivalent(const MatchExpression* other) const;
- virtual bool equivalent( const MatchExpression* other ) const ;
+ virtual void resetTag() {
+ setTag(NULL);
+ }
- virtual void resetTag() { setTag(NULL); }
+private:
+ string _dbName;
+ string _code;
+ BSONObj _userScope;
- private:
+ unique_ptr<Scope> _scope;
+ ScriptingFunction _func;
- string _dbName;
- string _code;
- BSONObj _userScope;
+ // Not owned. See comments insde WhereCallbackReal for the lifetime of this pointer.
+ OperationContext* _txn;
+};
- unique_ptr<Scope> _scope;
- ScriptingFunction _func;
+Status WhereMatchExpression::init(StringData dbName, StringData theCode, const BSONObj& scope) {
+ if (dbName.size() == 0) {
+ return Status(ErrorCodes::BadValue, "ns for $where cannot be empty");
+ }
- // Not owned. See comments insde WhereCallbackReal for the lifetime of this pointer.
- OperationContext* _txn;
- };
+ if (theCode.size() == 0) {
+ return Status(ErrorCodes::BadValue, "code for $where cannot be empty");
+ }
- Status WhereMatchExpression::init( StringData dbName,
- StringData theCode,
- const BSONObj& scope ) {
+ _dbName = dbName.toString();
+ _code = theCode.toString();
+ _userScope = scope.getOwned();
- if (dbName.size() == 0) {
- return Status(ErrorCodes::BadValue, "ns for $where cannot be empty");
- }
+ const string userToken =
+ AuthorizationSession::get(ClientBasic::getCurrent())->getAuthenticatedUserNamesToken();
- if (theCode.size() == 0) {
- return Status(ErrorCodes::BadValue, "code for $where cannot be empty");
- }
-
- _dbName = dbName.toString();
- _code = theCode.toString();
- _userScope = scope.getOwned();
+ try {
+ _scope = globalScriptEngine->getPooledScope(_txn, _dbName, "where" + userToken);
+ _func = _scope->createFunction(_code.c_str());
+ } catch (...) {
+ return exceptionToStatus();
+ }
- const string userToken = AuthorizationSession::get(ClientBasic::getCurrent())
- ->getAuthenticatedUserNamesToken();
+ if (!_func)
+ return Status(ErrorCodes::BadValue, "$where compile error");
- try {
- _scope = globalScriptEngine->getPooledScope(_txn, _dbName, "where" + userToken);
- _func = _scope->createFunction(_code.c_str());
- } catch (...) {
- return exceptionToStatus();
- }
+ return Status::OK();
+}
- if ( !_func )
- return Status( ErrorCodes::BadValue, "$where compile error" );
+bool WhereMatchExpression::matches(const MatchableDocument* doc, MatchDetails* details) const {
+ uassert(28692, "$where compile error", _func);
+ BSONObj obj = doc->toBSON();
- return Status::OK();
+ if (!_userScope.isEmpty()) {
+ _scope->init(&_userScope);
}
- bool WhereMatchExpression::matches( const MatchableDocument* doc, MatchDetails* details ) const {
- uassert(28692, "$where compile error", _func);
- BSONObj obj = doc->toBSON();
-
- if ( ! _userScope.isEmpty() ) {
- _scope->init( &_userScope );
- }
-
- _scope->setObject( "obj", const_cast< BSONObj & >( obj ) );
- _scope->setBoolean( "fullObject" , true ); // this is a hack b/c fullObject used to be relevant
+ _scope->setObject("obj", const_cast<BSONObj&>(obj));
+ _scope->setBoolean("fullObject", true); // this is a hack b/c fullObject used to be relevant
- int err = _scope->invoke( _func, 0, &obj, 1000 * 60, false );
- if ( err == -3 ) { // INVOKE_ERROR
- stringstream ss;
- ss << "error on invocation of $where function:\n"
- << _scope->getError();
- uassert( 16812, ss.str(), false);
- }
- else if ( err != 0 ) { // ! INVOKE_SUCCESS
- uassert( 16813, "unknown error in invocation of $where function", false);
- }
-
- return _scope->getBoolean( "__returnValue" ) != 0;
+ int err = _scope->invoke(_func, 0, &obj, 1000 * 60, false);
+ if (err == -3) { // INVOKE_ERROR
+ stringstream ss;
+ ss << "error on invocation of $where function:\n" << _scope->getError();
+ uassert(16812, ss.str(), false);
+ } else if (err != 0) { // ! INVOKE_SUCCESS
+ uassert(16813, "unknown error in invocation of $where function", false);
}
- void WhereMatchExpression::debugString( StringBuilder& debug, int level ) const {
- _debugAddSpace( debug, level );
- debug << "$where\n";
+ return _scope->getBoolean("__returnValue") != 0;
+}
- _debugAddSpace( debug, level + 1 );
- debug << "dbName: " << _dbName << "\n";
+void WhereMatchExpression::debugString(StringBuilder& debug, int level) const {
+ _debugAddSpace(debug, level);
+ debug << "$where\n";
- _debugAddSpace( debug, level + 1 );
- debug << "code: " << _code << "\n";
+ _debugAddSpace(debug, level + 1);
+ debug << "dbName: " << _dbName << "\n";
- _debugAddSpace( debug, level + 1 );
- debug << "scope: " << _userScope << "\n";
- }
+ _debugAddSpace(debug, level + 1);
+ debug << "code: " << _code << "\n";
- void WhereMatchExpression::toBSON(BSONObjBuilder* out) const {
- out->append("$where", _code);
- }
+ _debugAddSpace(debug, level + 1);
+ debug << "scope: " << _userScope << "\n";
+}
- bool WhereMatchExpression::equivalent( const MatchExpression* other ) const {
- if ( matchType() != other->matchType() )
- return false;
- const WhereMatchExpression* realOther = static_cast<const WhereMatchExpression*>(other);
- return
- _dbName == realOther->_dbName &&
- _code == realOther->_code &&
- _userScope == realOther->_userScope;
- }
+void WhereMatchExpression::toBSON(BSONObjBuilder* out) const {
+ out->append("$where", _code);
+}
- WhereCallbackReal::WhereCallbackReal(OperationContext* txn, StringData dbName)
- : _txn(txn),
- _dbName(dbName) {
+bool WhereMatchExpression::equivalent(const MatchExpression* other) const {
+ if (matchType() != other->matchType())
+ return false;
+ const WhereMatchExpression* realOther = static_cast<const WhereMatchExpression*>(other);
+ return _dbName == realOther->_dbName && _code == realOther->_code &&
+ _userScope == realOther->_userScope;
+}
- }
+WhereCallbackReal::WhereCallbackReal(OperationContext* txn, StringData dbName)
+ : _txn(txn), _dbName(dbName) {}
- StatusWithMatchExpression WhereCallbackReal::parseWhere(const BSONElement& where) const {
- if (!globalScriptEngine)
- return StatusWithMatchExpression(ErrorCodes::BadValue,
- "no globalScriptEngine in $where parsing");
-
- unique_ptr<WhereMatchExpression> exp(new WhereMatchExpression(_txn));
- if (where.type() == String || where.type() == Code) {
- Status s = exp->init(_dbName, where.valuestr(), BSONObj());
- if (!s.isOK())
- return StatusWithMatchExpression(s);
- return StatusWithMatchExpression(exp.release());
- }
+StatusWithMatchExpression WhereCallbackReal::parseWhere(const BSONElement& where) const {
+ if (!globalScriptEngine)
+ return StatusWithMatchExpression(ErrorCodes::BadValue,
+ "no globalScriptEngine in $where parsing");
- if (where.type() == CodeWScope) {
- Status s = exp->init(_dbName,
- where.codeWScopeCode(),
- BSONObj(where.codeWScopeScopeDataUnsafe()));
- if (!s.isOK())
- return StatusWithMatchExpression(s);
- return StatusWithMatchExpression(exp.release());
- }
+ unique_ptr<WhereMatchExpression> exp(new WhereMatchExpression(_txn));
+ if (where.type() == String || where.type() == Code) {
+ Status s = exp->init(_dbName, where.valuestr(), BSONObj());
+ if (!s.isOK())
+ return StatusWithMatchExpression(s);
+ return StatusWithMatchExpression(exp.release());
+ }
- return StatusWithMatchExpression(ErrorCodes::BadValue, "$where got bad type");
+ if (where.type() == CodeWScope) {
+ Status s =
+ exp->init(_dbName, where.codeWScopeCode(), BSONObj(where.codeWScopeScopeDataUnsafe()));
+ if (!s.isOK())
+ return StatusWithMatchExpression(s);
+ return StatusWithMatchExpression(exp.release());
}
+
+ return StatusWithMatchExpression(ErrorCodes::BadValue, "$where got bad type");
+}
}