mirror of https://github.com/mongodb/mongo
SREVER-357 NumberLong support in v8 engine
This commit is contained in:
parent
37d6be1908
commit
fb093990ac
|
|
@ -521,7 +521,7 @@ namespace JSTests {
|
|||
Scope * s = globalScriptEngine->newScope();
|
||||
s->localConnect( "blah" );
|
||||
BSONObjBuilder b;
|
||||
long long val = (long long)( 0xdeadbeefbaddULL );
|
||||
long long val = (long long)( 0xbabadeadbeefbaddULL );
|
||||
b.append( "a", val );
|
||||
BSONObj in = b.obj();
|
||||
s->setObject( "a", in );
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ namespace mongo {
|
|||
long long toNumberLongUnsafe( JSObject *o ) {
|
||||
unsigned long long val =
|
||||
( (unsigned long long)( getNumber( o , "top" ) ) << 32 ) +
|
||||
( unsigned long long )( getNumber( o , "bottom" ) );
|
||||
( unsigned )( getNumber( o , "bottom" ) );
|
||||
return val;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,17 @@ namespace mongo {
|
|||
return mongo;
|
||||
}
|
||||
|
||||
v8::Handle<v8::FunctionTemplate> getNumberLongFunctionTemplate() {
|
||||
v8::Local<v8::FunctionTemplate> numberLong = FunctionTemplate::New( numberLongInit );
|
||||
v8::Local<v8::Template> proto = numberLong->PrototypeTemplate();
|
||||
|
||||
proto->Set( v8::String::New( "toString" ) , FunctionTemplate::New( numberLongToString ) );
|
||||
proto->Set( v8::String::New( "toNumber" ) , FunctionTemplate::New( numberLongToNumber ) );
|
||||
|
||||
return numberLong;
|
||||
}
|
||||
|
||||
|
||||
void installDBTypes( Handle<ObjectTemplate>& global ){
|
||||
v8::Local<v8::FunctionTemplate> db = FunctionTemplate::New( dbInit );
|
||||
db->InstanceTemplate()->SetNamedPropertyHandler( collectionFallback );
|
||||
|
|
@ -71,6 +82,8 @@ namespace mongo {
|
|||
|
||||
global->Set( v8::String::New("BinData") , FunctionTemplate::New( binDataInit ) );
|
||||
|
||||
global->Set( v8::String::New("NumberLong") , getNumberLongFunctionTemplate() );
|
||||
|
||||
}
|
||||
|
||||
void installDBTypes( Handle<v8::Object>& global ){
|
||||
|
|
@ -95,6 +108,8 @@ namespace mongo {
|
|||
|
||||
global->Set( v8::String::New("BinData") , FunctionTemplate::New( binDataInit )->GetFunction() );
|
||||
|
||||
global->Set( v8::String::New("NumberLong") , getNumberLongFunctionTemplate()->GetFunction() );
|
||||
|
||||
BSONObjBuilder b;
|
||||
b.appendMaxKey( "" );
|
||||
b.appendMinKey( "" );
|
||||
|
|
@ -531,6 +546,59 @@ namespace mongo {
|
|||
return it;
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> numberLongInit( const v8::Arguments& args ) {
|
||||
|
||||
if (args.Length() != 2) {
|
||||
return v8::ThrowException( v8::String::New( "NumberLong needs 2 arguments" ) );
|
||||
}
|
||||
|
||||
v8::Handle<v8::Object> it = args.This();
|
||||
|
||||
if ( it->IsUndefined() || it == v8::Context::GetCurrent()->Global() ){
|
||||
v8::Function* f = getNamedCons( "NumberLong" );
|
||||
it = f->NewInstance();
|
||||
}
|
||||
|
||||
it->Set( v8::String::New( "top" ) , args[0] );
|
||||
it->Set( v8::String::New( "bottom" ) , args[1] );
|
||||
it->SetHiddenValue( v8::String::New( "__NumberLong" ), v8::Number::New( 1 ) );
|
||||
|
||||
return it;
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> numberLongToString( const v8::Arguments& args ) {
|
||||
|
||||
if (args.Length() != 0) {
|
||||
return v8::ThrowException( v8::String::New( "toString needs 0 arguments" ) );
|
||||
}
|
||||
|
||||
v8::Handle<v8::Object> it = args.This();
|
||||
|
||||
unsigned long long val =
|
||||
( (unsigned long long)( it->Get( v8::String::New( "top" ) )->ToInt32()->Value() ) << 32 ) +
|
||||
(unsigned)( it->Get( v8::String::New( "bottom" ) )->ToInt32()->Value() );
|
||||
|
||||
stringstream ss;
|
||||
ss << (long long)val;
|
||||
string ret = ss.str();
|
||||
return v8::String::New( ret.c_str() );
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> numberLongToNumber( const v8::Arguments& args ) {
|
||||
|
||||
if (args.Length() != 0) {
|
||||
return v8::ThrowException( v8::String::New( "toNumber needs 0 arguments" ) );
|
||||
}
|
||||
|
||||
v8::Handle<v8::Object> it = args.This();
|
||||
|
||||
unsigned long long val =
|
||||
( (unsigned long long)( it->Get( v8::String::New( "top" ) )->ToInt32()->Value() ) << 32 ) +
|
||||
(unsigned)( it->Get( v8::String::New( "bottom" ) )->ToInt32()->Value() );
|
||||
|
||||
return v8::Number::New( double( (long long)val ) );
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> bsonsize( const v8::Arguments& args ) {
|
||||
|
||||
if (args.Length() != 1 || !args[ 0 ]->IsObject()) {
|
||||
|
|
|
|||
|
|
@ -60,6 +60,9 @@ namespace mongo {
|
|||
v8::Handle<v8::Value> dbPointerInit( const v8::Arguments& args );
|
||||
|
||||
v8::Handle<v8::Value> binDataInit( const v8::Arguments& args );
|
||||
v8::Handle<v8::Value> numberLongInit( const v8::Arguments& args );
|
||||
v8::Handle<v8::Value> numberLongToString(const v8::Arguments& args);
|
||||
v8::Handle<v8::Value> numberLongToNumber(const v8::Arguments& args);
|
||||
|
||||
v8::Handle<v8::Value> dbQueryInit( const v8::Arguments& args );
|
||||
v8::Handle<v8::Value> dbQueryIndexAccess( uint32_t index , const v8::AccessorInfo& info );
|
||||
|
|
|
|||
|
|
@ -149,7 +149,6 @@ namespace mongo {
|
|||
|
||||
case mongo::NumberDouble:
|
||||
case mongo::NumberInt:
|
||||
case mongo::NumberLong: // may lose information here - just copying sm engine behavior
|
||||
o->Set( v8::String::New( f.fieldName() ) , v8::Number::New( f.number() ) );
|
||||
break;
|
||||
|
||||
|
|
@ -208,6 +207,17 @@ namespace mongo {
|
|||
break;
|
||||
}
|
||||
|
||||
case mongo::NumberLong: {
|
||||
Local<v8::Object> sub = readOnly ? readOnlyObjects->NewInstance() : internalFieldObjects->NewInstance();
|
||||
unsigned long long val = f.numberLong();
|
||||
v8::Function* numberLong = getNamedCons( "NumberLong" );
|
||||
v8::Handle<v8::Value> argv[2];
|
||||
argv[0] = v8::Integer::New( val >> 32 );
|
||||
argv[1] = v8::Integer::New( (unsigned long)(val & 0x00000000ffffffff) );
|
||||
o->Set( v8::String::New( f.fieldName() ), numberLong->NewInstance(2, argv) );
|
||||
break;
|
||||
}
|
||||
|
||||
case mongo::MinKey: {
|
||||
Local<v8::Object> sub = readOnly ? readOnlyObjects->NewInstance() : internalFieldObjects->NewInstance();
|
||||
sub->Set( v8::String::New( "$MinKey" ), v8::Boolean::New( true ) );
|
||||
|
|
@ -325,6 +335,16 @@ namespace mongo {
|
|||
|
||||
return sub;
|
||||
}
|
||||
|
||||
case mongo::NumberLong: {
|
||||
Local<v8::Object> sub = internalFieldObjects->NewInstance();
|
||||
unsigned long long val = f.numberLong();
|
||||
v8::Function* numberLong = getNamedCons( "NumberLong" );
|
||||
v8::Handle<v8::Value> argv[2];
|
||||
argv[0] = v8::Integer::New( val >> 32 );
|
||||
argv[1] = v8::Integer::New( (unsigned long)(val & 0x00000000ffffffff) );
|
||||
return numberLong->NewInstance( 2, argv );
|
||||
}
|
||||
|
||||
case mongo::MinKey: {
|
||||
Local<v8::Object> sub = internalFieldObjects->NewInstance();
|
||||
|
|
@ -431,10 +451,16 @@ namespace mongo {
|
|||
oid.init( toSTLString( value ) );
|
||||
b.appendOID( sname.c_str() , &oid );
|
||||
}
|
||||
else if ( !value->ToObject()->GetHiddenValue( v8::String::New( "__DBPointer" ) ).IsEmpty() ) {
|
||||
else if ( !value->ToObject()->GetHiddenValue( v8::String::New( "__NumberLong" ) ).IsEmpty() ) {
|
||||
// TODO might be nice to potentially speed this up with an indexed internal
|
||||
// field, but I don't yet know how to use an ObjectTemplate with a
|
||||
// constructor.
|
||||
unsigned long long val =
|
||||
( (unsigned long long)( value->ToObject()->Get( v8::String::New( "top" ) )->ToInt32()->Value() ) << 32 ) +
|
||||
(unsigned)( value->ToObject()->Get( v8::String::New( "bottom" ) )->ToInt32()->Value() );
|
||||
b.append( sname.c_str(), (long long)val );
|
||||
}
|
||||
else if ( !value->ToObject()->GetHiddenValue( v8::String::New( "__DBPointer" ) ).IsEmpty() ) {
|
||||
OID oid;
|
||||
oid.init( toSTLString( value->ToObject()->Get( v8::String::New( "id" ) ) ) );
|
||||
string ns = toSTLString( value->ToObject()->Get( v8::String::New( "ns" ) ) );
|
||||
|
|
|
|||
Loading…
Reference in New Issue