diff options
author | Eliot Horowitz <eliot@10gen.com> | 2009-09-29 16:54:31 -0400 |
---|---|---|
committer | Eliot Horowitz <eliot@10gen.com> | 2009-09-29 16:54:31 -0400 |
commit | ae3d49d718ac6778f7abdc133263121971f64569 (patch) | |
tree | c8eec1cd64667e56ccc69b645ff280cdc9fc0abd /scripting | |
parent | 966e13e27f875a863bea62e02c7425b77dab39c6 (diff) | |
download | mongo-ae3d49d718ac6778f7abdc133263121971f64569.tar.gz |
allow you to store js functions in the server SERVER-157
Diffstat (limited to 'scripting')
-rw-r--r-- | scripting/engine.cpp | 43 | ||||
-rw-r--r-- | scripting/engine.h | 14 | ||||
-rw-r--r-- | scripting/engine_spidermonkey.cpp | 12 |
3 files changed, 64 insertions, 5 deletions
diff --git a/scripting/engine.cpp b/scripting/engine.cpp index 5c53cdd1f65..c82f5961563 100644 --- a/scripting/engine.cpp +++ b/scripting/engine.cpp @@ -3,10 +3,13 @@ #include "stdafx.h" #include "engine.h" #include "../util/file.h" +#include "../client/dbclient.h" namespace mongo { + + long long Scope::_lastVersion = 1; - Scope::Scope(){ + Scope::Scope() : _localDBName("") , _loadedVersion(0){ } Scope::~Scope(){ @@ -88,6 +91,37 @@ namespace mongo { return exec( data , filename , printResult , reportError , assertOnError, timeoutMs ); } + + void Scope::storedFuncMod(){ + _lastVersion++; + } + + void Scope::loadStored( bool ignoreNotConnected ){ + if ( _localDBName.size() == 0 ){ + if ( ignoreNotConnected ) + return; + uassert( "need to have locallyConnected already" , _localDBName.size() ); + } + if ( _loadedVersion == _lastVersion ) + return; + + _loadedVersion = _lastVersion; + + static DBClientBase * db = createDirectClient(); + + auto_ptr<DBClientCursor> c = db->query( _localDBName + ".system.js" , Query() ); + while ( c->more() ){ + BSONObj o = c->next(); + + BSONElement n = o["_id"]; + BSONElement v = o["value"]; + + uassert( "name has to be a string" , n.type() == String ); + uassert( "value has to be set" , v.type() != EOO ); + + setElement( n.valuestr() , v ); + } + } typedef map< string , list<Scope*> > PoolToScopes; @@ -157,7 +191,9 @@ namespace mongo { class PooledScope : public Scope { public: - PooledScope( const string pool , Scope * real ) : _pool( pool ) , _real( real ){}; + PooledScope( const string pool , Scope * real ) : _pool( pool ) , _real( real ){ + _real->loadStored( true ); + }; virtual ~PooledScope(){ ScopeCache * sc = scopeCache.get(); if ( sc ){ @@ -202,6 +238,9 @@ namespace mongo { return _real->type( field ); } + void setElement( const char *field , const BSONElement& val ){ + _real->setElement( field , val ); + } void setNumber( const char *field , double val ){ _real->setNumber( field , val ); } diff --git a/scripting/engine.h b/scripting/engine.h index 50b0dee6dea..fb9aa48dbc2 100644 --- a/scripting/engine.h +++ b/scripting/engine.h @@ -36,6 +36,7 @@ namespace mongo { void append( BSONObjBuilder & builder , const char * fieldName , const char * scopeName ); + virtual void setElement( const char *field , const BSONElement& e ) = 0; virtual void setNumber( const char *field , double val ) = 0; virtual void setString( const char *field , const char * val ) = 0; virtual void setObject( const char *field , const BSONObj& obj , bool readOnly=true ) = 0; @@ -67,6 +68,19 @@ namespace mongo { virtual void injectNative( const char *field, NativeFunction func ) = 0; virtual void gc() = 0; + + void loadStored( bool ignoreNotConnected = false ); + + /** + if any changes are made to .system.js, call this + right now its just global - slightly inefficient, but a lot simpler + */ + static void storedFuncMod(); + + protected: + string _localDBName; + long long _loadedVersion; + static long long _lastVersion; }; class ScriptEngine : boost::noncopyable { diff --git a/scripting/engine_spidermonkey.cpp b/scripting/engine_spidermonkey.cpp index 0fbeb0bb3db..88a410544a1 100644 --- a/scripting/engine_spidermonkey.cpp +++ b/scripting/engine_spidermonkey.cpp @@ -1008,7 +1008,7 @@ namespace mongo { smlock; uassert( "already setup for external db" , ! _externalSetup ); if ( _localConnect ){ - uassert( "connected to different db" , _dbName == dbName ); + uassert( "connected to different db" , _localDBName == dbName ); return; } @@ -1018,7 +1018,8 @@ namespace mongo { exec( ((string)"db = _mongo.getDB( \"" + dbName + "\" ); ").c_str() ); _localConnect = true; - _dbName = dbName; + _localDBName = dbName; + loadStored(); } // ----- getters ------ @@ -1082,6 +1083,12 @@ namespace mongo { // ----- setters ------ + void setElement( const char *field , const BSONElement& val ){ + smlock; + jsval v = _convertor->toval( val ); + assert( JS_SetProperty( _context , _global , field , &v ) ); + } + void setNumber( const char *field , double val ){ smlock; jsval v = _convertor->toval( val ); @@ -1301,7 +1308,6 @@ namespace mongo { bool _externalSetup; bool _localConnect; - string _dbName; set<string> _initFieldNames; |