summaryrefslogtreecommitdiff
path: root/scripting
diff options
context:
space:
mode:
authorEliot Horowitz <eliot@10gen.com>2009-09-29 16:54:31 -0400
committerEliot Horowitz <eliot@10gen.com>2009-09-29 16:54:31 -0400
commitae3d49d718ac6778f7abdc133263121971f64569 (patch)
treec8eec1cd64667e56ccc69b645ff280cdc9fc0abd /scripting
parent966e13e27f875a863bea62e02c7425b77dab39c6 (diff)
downloadmongo-ae3d49d718ac6778f7abdc133263121971f64569.tar.gz
allow you to store js functions in the server SERVER-157
Diffstat (limited to 'scripting')
-rw-r--r--scripting/engine.cpp43
-rw-r--r--scripting/engine.h14
-rw-r--r--scripting/engine_spidermonkey.cpp12
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;