mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 09:32:32 +01:00
Spider Monkey: framework mostly done now
This commit is contained in:
parent
77c36b8c37
commit
c9d8450389
@ -105,6 +105,7 @@ namespace mongo {
|
||||
}
|
||||
|
||||
jsval getProperty( JSObject * o , const char * field ){
|
||||
uassert( "object passed to getPropery is null" , o );
|
||||
jsval v;
|
||||
assert( JS_GetProperty( _context , o , field , &v ) );
|
||||
return v;
|
||||
@ -114,6 +115,11 @@ namespace mongo {
|
||||
assert( JS_SetProperty( _context , o , field , &v ) );
|
||||
}
|
||||
|
||||
string typeString( jsval v ){
|
||||
JSType t = JS_TypeOfValue( _context , v );
|
||||
return JS_GetTypeName( _context , t );
|
||||
}
|
||||
|
||||
private:
|
||||
JSContext * _context;
|
||||
};
|
||||
@ -140,7 +146,6 @@ namespace mongo {
|
||||
|
||||
JSFunctionSpec globalHelpers[] = {
|
||||
{ "print" , &native_print , 0 , 0 , 0 } ,
|
||||
{ "createDB" , &native_db_create , 0 , 0 , 0 } ,
|
||||
{ 0 , 0 , 0 , 0 , 0 }
|
||||
};
|
||||
|
||||
@ -250,6 +255,8 @@ namespace mongo {
|
||||
void localConnect( const char * dbName ){
|
||||
assert( JS_InitClass( _context , _global , 0 , &mongo_local_class , mongo_local_constructor , 0 , 0 , mongo_functions , 0 , 0 ) );
|
||||
assert( JS_InitClass( _context , _global , 0 , &object_id_class , 0 , 0 , 0 , 0 , 0 , 0 ) );
|
||||
assert( JS_InitClass( _context , _global , 0 , &db_class , db_constructor , 2 , 0 , 0 , 0 , 0 ) );
|
||||
assert( JS_InitClass( _context , _global , 0 , &db_collection_class , db_collection_constructor , 4 , 0 , 0 , 0 , 0 ) );
|
||||
|
||||
exec( jsconcatcode );
|
||||
|
||||
@ -443,10 +450,21 @@ namespace mongo {
|
||||
SMScope s;
|
||||
|
||||
s.localConnect( "foo" );
|
||||
s.exec( "print( '_mongo:' + _mongo );" );
|
||||
|
||||
s.exec( "assert( db.getMongo() )" );
|
||||
s.exec( "assert( db.bar , 'collection getting does not work' ); " );
|
||||
s.exec( "assert.eq( db._name , 'foo' );" );
|
||||
s.exec( "assert( _mongo == db.getMongo() ); " );
|
||||
s.exec( "assert( _mongo == db._mongo ); " );
|
||||
s.exec( "assert( typeof DB.bar == 'undefined' ); " );
|
||||
s.exec( "assert( typeof DB.prototype.bar == 'undefined' , 'resolution is happening on prototype, not object' ); " );
|
||||
|
||||
s.exec( "assert( db.bar ); " );
|
||||
s.exec( "assert( typeof db.addUser == 'function' )" );
|
||||
s.exec( "assert( db.addUser == DB.prototype.addUser )" );
|
||||
s.exec( "assert.eq( 'foo.bar' , db.bar._fullName ); " );
|
||||
s.exec( "db.bar.verify();" );
|
||||
|
||||
s.exec( "db.bar.silly.verify();" );
|
||||
s.exec( "assert.eq( 'foo.bar.silly' , db.bar.silly._fullName )" );
|
||||
s.exec( "assert.eq( 'function' , typeof _mongo.find , 'mongo.find is not a function' )" );
|
||||
|
@ -31,10 +31,17 @@ namespace mongo {
|
||||
|
||||
|
||||
// mongo
|
||||
JSBool mongo_local_constructor( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval );
|
||||
JSBool native_db_create( JSContext * cx , JSObject * obj , uintN argc, jsval *argv, jsval *rval );
|
||||
JSObject * doCreateCollection( JSContext * cx , JSObject * db , const string& shortName );
|
||||
extern JSClass mongo_local_class;
|
||||
JSBool mongo_local_constructor( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval );
|
||||
|
||||
extern JSClass db_class;
|
||||
JSBool db_constructor( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval );
|
||||
|
||||
extern JSClass db_collection_class;
|
||||
JSBool db_collection_constructor( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval );
|
||||
|
||||
JSObject * doCreateCollection( JSContext * cx , JSObject * db , const string& shortName );
|
||||
|
||||
extern JSClass object_id_class;
|
||||
|
||||
extern JSFunctionSpec mongo_functions[];
|
||||
|
@ -4,6 +4,18 @@
|
||||
|
||||
namespace mongo {
|
||||
|
||||
bool isSpecialName( const string& name ){
|
||||
static set<string> names;
|
||||
if ( names.size() == 0 ){
|
||||
names.insert( "_mongo" );
|
||||
names.insert( "_db" );
|
||||
names.insert( "_name" );
|
||||
names.insert( "_fullName" );
|
||||
names.insert( "_shortName" );
|
||||
}
|
||||
return names.count( name ) > 0;
|
||||
}
|
||||
|
||||
// ------ mongo stuff ------
|
||||
|
||||
JSBool mongo_constructor( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval ){
|
||||
@ -72,51 +84,60 @@ namespace mongo {
|
||||
}
|
||||
|
||||
JSBool db_collection_resolve( JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp ){
|
||||
if ( flags & JSRESOLVE_ASSIGNING || flags & JSRESOLVE_DETECTING )
|
||||
return JS_TRUE;
|
||||
|
||||
Convertor c( cx );
|
||||
string collname = c.toString( id );
|
||||
|
||||
if ( collname == "_mongo" || collname == "_db" || collname == "_shortName" || collname == "_fullName" )
|
||||
if ( isSpecialName( collname ) )
|
||||
return JS_TRUE;
|
||||
|
||||
if ( obj == c.getGlobalPrototype( "DBCollection" ) )
|
||||
return JS_TRUE;
|
||||
|
||||
JSObject * proto = JS_GetPrototype( cx , obj );
|
||||
if ( proto && c.hasProperty( proto , collname.c_str() ) )
|
||||
if ( c.hasProperty( obj , collname.c_str() ) || ( proto && c.hasProperty( proto , collname.c_str() ) ) )
|
||||
return JS_TRUE;
|
||||
|
||||
string name = c.toString( c.getProperty( obj , "_shortName" ) );
|
||||
name += ".";
|
||||
name += collname;
|
||||
|
||||
JSObject * coll = doCreateCollection( cx , JSVAL_TO_OBJECT( c.getProperty( obj , "_db" ) ) , name );
|
||||
jsval db = c.getProperty( obj , "_db" );
|
||||
if ( ! JSVAL_IS_OBJECT( db ) )
|
||||
return JS_TRUE;
|
||||
|
||||
JSObject * coll = doCreateCollection( cx , JSVAL_TO_OBJECT( db ) , name );
|
||||
c.setProperty( obj , collname.c_str() , OBJECT_TO_JSVAL( coll ) );
|
||||
*objp = obj;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSClass db_collection_class = {
|
||||
"DB" , JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE ,
|
||||
JSClass db_collection_class = {
|
||||
"DBCollection" , JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE ,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, (JSResolveOp)(&db_collection_resolve) , JS_ConvertStub, JS_FinalizeStub,
|
||||
0 , 0 , 0 ,
|
||||
db_collection_constructor ,
|
||||
0 , 0 , 0 , 0
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
};
|
||||
|
||||
|
||||
JSObject * doCreateCollection( JSContext * cx , JSObject * db , const string& shortName ){
|
||||
Convertor c(cx);
|
||||
|
||||
|
||||
assert( c.hasProperty( db , "_mongo" ) );
|
||||
assert( c.hasProperty( db , "_name" ) );
|
||||
|
||||
JSObject * coll = JS_NewObject( cx , &db_collection_class , 0 , 0 );
|
||||
c.setProperty( coll , "_mongo" , c.getProperty( db , "_mongo" ) );
|
||||
c.setProperty( coll , "_db" , OBJECT_TO_JSVAL( db ) );
|
||||
c.setProperty( coll , "_shortName" , c.toval( shortName.c_str() ) );
|
||||
|
||||
|
||||
string name = c.toString( c.getProperty( db , "_name" ) );
|
||||
name += "." + shortName;
|
||||
c.setProperty( coll , "_fullName" , c.toval( name.c_str() ) );
|
||||
|
||||
assert( JS_SetPrototype( cx , coll , c.getGlobalPrototype( "DBCollection" ) ) );
|
||||
|
||||
return coll;
|
||||
|
||||
return coll;
|
||||
}
|
||||
|
||||
// -------------- DB ---------------
|
||||
@ -126,21 +147,28 @@ namespace mongo {
|
||||
uassert( "wrong number of arguments to DB" , argc == 2 );
|
||||
assert( JS_SetProperty( cx , obj , "_mongo" , &(argv[0]) ) );
|
||||
assert( JS_SetProperty( cx , obj , "_name" , &(argv[1]) ) );
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool db_resolve( JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp ){
|
||||
Convertor c( cx );
|
||||
string collname = c.toString( id );
|
||||
|
||||
if ( collname == "prototype" || collname.find( "__" ) == 0 ||
|
||||
collname == "_mongo" || collname == "_name" )
|
||||
if ( flags & JSRESOLVE_ASSIGNING || flags & JSRESOLVE_DETECTING )
|
||||
return JS_TRUE;
|
||||
|
||||
Convertor c( cx );
|
||||
|
||||
if ( obj == c.getGlobalPrototype( "DB" ) )
|
||||
return JS_TRUE;
|
||||
|
||||
string collname = c.toString( id );
|
||||
|
||||
if ( isSpecialName( collname ) )
|
||||
return JS_TRUE;
|
||||
|
||||
JSObject * proto = JS_GetPrototype( cx , obj );
|
||||
if ( proto && c.hasProperty( proto , collname.c_str() ) )
|
||||
return JS_TRUE;
|
||||
|
||||
|
||||
JSObject * coll = doCreateCollection( cx , obj , collname );
|
||||
c.setProperty( obj , collname.c_str() , OBJECT_TO_JSVAL( coll ) );
|
||||
|
||||
@ -148,52 +176,13 @@ namespace mongo {
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSClass db_class = {
|
||||
JSClass db_class = {
|
||||
"DB" , JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE ,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, (JSResolveOp)(&db_resolve) , JS_ConvertStub, JS_FinalizeStub,
|
||||
0 , 0 , 0 ,
|
||||
db_constructor ,
|
||||
0 , 0 , 0 , 0
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
};
|
||||
|
||||
JSBool native_db_create( JSContext * cx , JSObject * obj , uintN argc, jsval *argv, jsval *rval ){
|
||||
Convertor c( cx );
|
||||
uassert( "dbCreate needs 2 args" , argc == 2 );
|
||||
|
||||
JSObject * proto = c.getGlobalPrototype( "DB" );
|
||||
uassert( "can't find DB prototype" , proto );
|
||||
|
||||
JSObject * db = JS_NewObject( cx , &db_class , 0 , 0 );
|
||||
assert( JS_SetProperty( cx , db , "_mongo" , &(argv[0]) ) );
|
||||
assert( JS_SetProperty( cx , db , "_name" , &(argv[1]) ) );
|
||||
assert( JS_SetPrototype( cx , db , proto ) );
|
||||
|
||||
*rval = OBJECT_TO_JSVAL( db );
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
JSBool native_db_collection_create( JSContext * cx , JSObject * obj , uintN argc, jsval *argv, jsval *rval ){
|
||||
Convertor c( cx );
|
||||
uassert( "native_db_collection_create needs 4 args" , argc == 4 );
|
||||
|
||||
JSObject * proto = c.getGlobalPrototype( "DBCollection" );
|
||||
uassert( "can't find DBCollection prototype" , proto );
|
||||
|
||||
JSObject * db = JS_NewObject( cx , &db_collection_class , 0 , 0 );
|
||||
assert( JS_SetProperty( cx , obj , "_mongo" , &(argv[0]) ) );
|
||||
assert( JS_SetProperty( cx , obj , "_db" , &(argv[1]) ) );
|
||||
assert( JS_SetProperty( cx , obj , "_shortName" , &(argv[2]) ) );
|
||||
assert( JS_SetProperty( cx , obj , "_fullName" , &(argv[3]) ) );
|
||||
|
||||
assert( JS_SetPrototype( cx , db , proto ) );
|
||||
|
||||
*rval = OBJECT_TO_JSVAL( db );
|
||||
return JS_TRUE;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// -------------- object id -------------
|
||||
|
||||
|
@ -13,12 +13,13 @@ if ( ( typeof DBCollection ) == "undefined" ){
|
||||
}
|
||||
|
||||
DBCollection.prototype.verify = function(){
|
||||
assert( this._mongo , "no mongo" );
|
||||
assert( this._db , "no db" );
|
||||
assert( this._shortName , "no shortName" );
|
||||
assert( this._fullName , "no fullName" );
|
||||
assert( this._shortName , "no shortName" );
|
||||
assert( this._db , "no db" );
|
||||
|
||||
assert.eq( this._fullName , this._db._name + "." + this._shortName , "name mismatch" );
|
||||
|
||||
assert( this._mongo , "no mongo in DBCollection" );
|
||||
}
|
||||
|
||||
DBCollection.prototype.getName = function(){
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
if ( typeof DB == "undefined" ){
|
||||
DB = function( mongo , name ){
|
||||
assert( typeof createDB != "function" , "createDB defined, so shouldn't do this" );
|
||||
this._mongo = mongo;
|
||||
this._name = name;
|
||||
}
|
||||
|
@ -30,12 +30,6 @@ Mongo.prototype.setSlaveOk = function() {
|
||||
}
|
||||
|
||||
Mongo.prototype.getDB = function( name ){
|
||||
if ( typeof createDB == "function" ){
|
||||
var newdb = createDB( this , name );
|
||||
assert( this == newdb.getMongo() , "createDB sanity check 1" );
|
||||
assert( this == newdb._mongo , "createDB sanity check 2" );
|
||||
return newdb;
|
||||
}
|
||||
return new DB( this , name );
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user