bool run(const string& , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool) { BSONElement e = cmdObj.firstElement(); if ( e.type() != jstOID ) { errmsg = "need oid as first value"; return 0; } // get the command issuer's (a mongos) serverID const OID id = e.__oid(); // the command issuer is blocked awaiting a response // we want to do return at least at every 5 minutes so sockets don't timeout BSONObj z; if ( writeBackManager.getWritebackQueue(id.str())->queue.blockingPop( z, 5 * 60 /* 5 minutes */ ) ) { MONGO_LOG(1) << "WriteBackCommand got : " << z << endl; result.append( "data" , z ); } else { result.appendBool( "noop" , true ); } #ifdef _DEBUG // Sleep a short amount of time usually int sleepFor = rand() % 10; sleepmillis( sleepFor ); // Sleep a longer amount of time every once and awhile int sleepLong = rand() % 50; if( sleepLong == 0 ) sleepsecs( 2 ); #endif return true; }
bool run(const string& , BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool){ BSONElement e = cmdObj.firstElement(); if ( e.type() != jstOID ){ errmsg = "need oid as first value"; return 0; } const OID id = e.__oid(); BSONObj z = getWritebackQueue(id.str())->blockingPop(); log(1) << "WriteBackCommand got : " << z << endl; result.append( "data" , z ); return true; }
string SavePaymentJson(int amount) { //BSONObj paymentBSON = mongo::fromjson(newPyamentJson); BSONObj paymentBSON = BSON(GENOID << "PayedToUserId" << 8888 << "PayedDate" << "2015-01-25 12:00:00" << "PayedPeriodStartDate" << "2015-01-01 00:00:00" << "PayedPeriodEndDate" << "2015-01-29 23:59:59" << "Amount" << amount); db.insert(PAYMENTS_COLLECTION_NAMESPASE, paymentBSON); BSONElement oi; paymentBSON.getObjectID(oi); OID oid = oi.__oid(); return oid.toString(); }
bool run(const char *cmdns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool){ BSONElement e = cmdObj.firstElement(); if ( e.type() != jstOID ){ errmsg = "need oid as first value"; return 0; } const OID id = e.__oid(); if ( ! clientQueues[id.str()] ) clientQueues[id.str()] = new BlockingQueue<BSONObj>(); BSONObj z = clientQueues[id.str()]->blockingPop(); log(1) << "WriteBackCommand got : " << z << endl; result.append( "data" , z ); return true; }
bool checkMongosID( ShardedConnectionInfo* info, const BSONElement& id, string errmsg ) { if ( id.type() != jstOID ) { // TODO: fix this //errmsg = "need serverID to be an OID"; //return 0; return true; } OID clientId = id.__oid(); if ( ! info->hasID() ) { info->setID( clientId ); return true; } if ( clientId != info->getID() ) { errmsg = "server id has changed!"; return false; } return true; }
FieldParser::FieldState FieldParser::extract(BSONElement elem, const BSONField<OID>& field, OID* out, string* errMsg) { if (elem.eoo()) { if (field.hasDefault()) { *out = field.getDefault(); return FIELD_DEFAULT; } else { return FIELD_NONE; } } if (elem.type() == jstOID) { *out = elem.__oid(); return FIELD_SET; } _genFieldErrMsg(elem, field, "OID", errMsg); return FIELD_INVALID; }
bool run(const string& , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool) { cc().curop()->suppressFromCurop(); cc().curop()->setExpectedLatencyMs( 30000 ); BSONElement e = cmdObj.firstElement(); if ( e.type() != jstOID ) { errmsg = "need oid as first value"; return 0; } // get the command issuer's (a mongos) serverID const OID id = e.__oid(); // the command issuer is blocked awaiting a response // we want to do return at least at every 5 minutes so sockets don't timeout BSONObj z; if ( writeBackManager.getWritebackQueue(id.str())->queue.blockingPop( z, 5 * 60 /* 5 minutes */ ) ) { LOG(1) << "WriteBackCommand got : " << z << endl; result.append( "data" , z ); } else { result.appendBool( "noop" , true ); } #ifdef _DEBUG PseudoRandom r(static_cast<int64_t>(time(0))); // Sleep a short amount of time usually int sleepFor = r.nextInt32( 10 ); sleepmillis( sleepFor ); // Sleep a longer amount of time every once and awhile int sleepLong = r.nextInt32( 50 ); if( sleepLong == 0 ) sleepsecs( 2 ); #endif return true; }
bool run(const string& , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool) { BSONElement e = cmdObj.firstElement(); if ( e.type() != jstOID ) { errmsg = "need oid as first value"; return 0; } // get the command issuer's (a mongos) serverID const OID id = e.__oid(); // the command issuer is blocked awaiting a response // we want to do return at least at every 5 minutes so sockets don't timeout BSONObj z; if ( writeBackManager.getWritebackQueue(id.str())->queue.blockingPop( z, 5 * 60 /* 5 minutes */ ) ) { log(1) << "WriteBackCommand got : " << z << endl; result.append( "data" , z ); } else { result.appendBool( "noop" , true ); } return true; }
bool checkMongosID( ShardedConnectionInfo* info, const BSONElement& id, string& errmsg ) { if ( id.type() != jstOID ) { if ( ! info->hasID() ) { warning() << "bad serverID set in setShardVersion and none in info: " << id << endl; } // TODO: fix this //errmsg = "need serverID to be an OID"; //return 0; return true; } OID clientId = id.__oid(); if ( ! info->hasID() ) { info->setID( clientId ); return true; } if ( clientId != info->getID() ) { errmsg = "server id has changed!"; return false; } return true; }
Local<v8::Object> mongoToV8( BSONObj & m , bool array ){ Local<v8::Object> o; if ( array ) o = v8::Array::New(); else o = v8::Object::New(); mongo::BSONObj sub; for ( BSONObjIterator i(m); i.more(); ) { BSONElement f = i.next(); if ( f.eoo() ) break; Local<Value> v; switch ( f.type() ){ case mongo::Code: cout << "warning, code saved in database just turned into string right now" << endl; case mongo::String: o->Set( v8::String::New( f.fieldName() ) , v8::String::New( f.valuestr() ) ); break; case mongo::jstOID: { v8::Function * idCons = getObjectIdCons(); v8::Handle<v8::Value> argv[1]; argv[0] = v8::String::New( f.__oid().str().c_str() ); o->Set( v8::String::New( f.fieldName() ) , idCons->NewInstance( 1 , argv ) ); break; } case mongo::NumberDouble: case mongo::NumberInt: o->Set( v8::String::New( f.fieldName() ) , v8::Number::New( f.number() ) ); break; case mongo::Array: case mongo::Object: sub = f.embeddedObject(); o->Set( v8::String::New( f.fieldName() ) , mongoToV8( sub , f.type() == mongo::Array ) ); break; case mongo::Date: o->Set( v8::String::New( f.fieldName() ) , v8::Date::New( f.date() ) ); break; case mongo::Bool: o->Set( v8::String::New( f.fieldName() ) , v8::Boolean::New( f.boolean() ) ); break; case mongo::jstNULL: o->Set( v8::String::New( f.fieldName() ) , v8::Null() ); break; case mongo::RegEx: { v8::Function * regex = getNamedCons( "RegExp" ); v8::Handle<v8::Value> argv[2]; argv[0] = v8::String::New( f.regex() ); argv[1] = v8::String::New( f.regexFlags() ); o->Set( v8::String::New( f.fieldName() ) , regex->NewInstance( 2 , argv ) ); break; } case mongo::BinData: { Local<v8::Object> b = v8::Object::New(); int len; f.binData( len ); b->Set( v8::String::New( "subtype" ) , v8::Number::New( f.binDataType() ) ); b->Set( v8::String::New( "length" ) , v8::Number::New( len ) ); o->Set( v8::String::New( f.fieldName() ) , b ); break; }; case mongo::Timestamp: { Local<v8::Object> sub = v8::Object::New(); sub->Set( v8::String::New( "time" ) , v8::Date::New( f.timestampTime() ) ); sub->Set( v8::String::New( "i" ) , v8::Number::New( f.timestampInc() ) ); o->Set( v8::String::New( f.fieldName() ) , sub ); break; } default: cout << "can't handle type: "; cout << f.type() << " "; cout << f.toString(); cout << endl; break; } } return o; }
string StorageEngine::getoid(BSONObj post) { BSONElement el; post.getObjectID(el); return el.__oid().str(); }
Handle<v8::Value> mongoToV8Element( const BSONElement &f ) { assert( !f.eoo() ); switch ( f.type() ){ case mongo::Code: cout << "warning, code saved in database just turned into string right now" << endl; case mongo::String: return v8::String::New( f.valuestr() ); case mongo::jstOID: { v8::Function * idCons = getObjectIdCons(); v8::Handle<v8::Value> argv[1]; argv[0] = v8::String::New( f.__oid().str().c_str() ); return idCons->NewInstance( 1 , argv ); } case mongo::NumberDouble: case mongo::NumberInt: return v8::Number::New( f.number() ); case mongo::Array: case mongo::Object: return mongoToV8( f.embeddedObject() , f.type() == mongo::Array ); case mongo::Date: return v8::Date::New( f.date() ); case mongo::Bool: return v8::Boolean::New( f.boolean() ); case mongo::jstNULL: return v8::Null(); case mongo::RegEx: { v8::Function * regex = getNamedCons( "RegExp" ); v8::Handle<v8::Value> argv[2]; argv[0] = v8::String::New( f.regex() ); argv[1] = v8::String::New( f.regexFlags() ); return regex->NewInstance( 2 , argv ); break; } case mongo::BinData: { Local<v8::Object> b = v8::Object::New(); int len; f.binData( len ); b->Set( v8::String::New( "subtype" ) , v8::Number::New( f.binDataType() ) ); b->Set( v8::String::New( "length" ) , v8::Number::New( len ) ); return b; }; case mongo::Timestamp: { Local<v8::Object> sub = v8::Object::New(); sub->Set( v8::String::New( "time" ) , v8::Date::New( f.timestampTime() ) ); sub->Set( v8::String::New( "i" ) , v8::Number::New( f.timestampInc() ) ); return sub; } case mongo::MinKey: // TODO: make a special type return v8::String::New( "MinKey" ); case mongo::MaxKey: // TODO: make a special type return v8::String::New( "MaxKey" ); case mongo::Undefined: return v8::Undefined(); default: cout << "can't handle type: "; cout << f.type() << " "; cout << f.toString(); cout << endl; break; } return v8::Undefined(); }
void BSONComparatorInterfaceBase<T>::hashCombineBSONElement( size_t& hash, BSONElement elemToHash, bool considerFieldName, const StringData::ComparatorInterface* stringComparator) { boost::hash_combine(hash, elemToHash.canonicalType()); const StringData fieldName = elemToHash.fieldNameStringData(); if (considerFieldName && !fieldName.empty()) { SimpleStringDataComparator::kInstance.hash_combine(hash, fieldName); } switch (elemToHash.type()) { // Order of types is the same as in compareElementValues(). case mongo::EOO: case mongo::Undefined: case mongo::jstNULL: case mongo::MaxKey: case mongo::MinKey: // These are valueless types break; case mongo::Bool: boost::hash_combine(hash, elemToHash.boolean()); break; case mongo::bsonTimestamp: boost::hash_combine(hash, elemToHash.timestamp().asULL()); break; case mongo::Date: boost::hash_combine(hash, elemToHash.date().asInt64()); break; case mongo::NumberDecimal: { const Decimal128 dcml = elemToHash.numberDecimal(); if (dcml.toAbs().isGreater(Decimal128(std::numeric_limits<double>::max(), Decimal128::kRoundTo34Digits, Decimal128::kRoundTowardZero)) && !dcml.isInfinite() && !dcml.isNaN()) { // Normalize our decimal to force equivalent decimals // in the same cohort to hash to the same value Decimal128 dcmlNorm(dcml.normalize()); boost::hash_combine(hash, dcmlNorm.getValue().low64); boost::hash_combine(hash, dcmlNorm.getValue().high64); break; } // Else, fall through and convert the decimal to a double and hash. // At this point the decimal fits into the range of doubles, is infinity, or is NaN, // which doubles have a cheaper representation for. } case mongo::NumberDouble: case mongo::NumberLong: case mongo::NumberInt: { // This converts all numbers to doubles, which ignores the low-order bits of // NumberLongs > 2**53 and precise decimal numbers without double representations, // but that is ok since the hash will still be the same for equal numbers and is // still likely to be different for different numbers. (Note: this issue only // applies for decimals when they are outside of the valid double range. See // the above case.) // SERVER-16851 const double dbl = elemToHash.numberDouble(); if (std::isnan(dbl)) { boost::hash_combine(hash, std::numeric_limits<double>::quiet_NaN()); } else { boost::hash_combine(hash, dbl); } break; } case mongo::jstOID: elemToHash.__oid().hash_combine(hash); break; case mongo::String: { if (stringComparator) { stringComparator->hash_combine(hash, elemToHash.valueStringData()); } else { SimpleStringDataComparator::kInstance.hash_combine(hash, elemToHash.valueStringData()); } break; } case mongo::Code: case mongo::Symbol: SimpleStringDataComparator::kInstance.hash_combine(hash, elemToHash.valueStringData()); break; case mongo::Object: case mongo::Array: hashCombineBSONObj(hash, elemToHash.embeddedObject(), true, // considerFieldName stringComparator); break; case mongo::DBRef: case mongo::BinData: // All bytes of the value are required to be identical. SimpleStringDataComparator::kInstance.hash_combine( hash, StringData(elemToHash.value(), elemToHash.valuesize())); break; case mongo::RegEx: SimpleStringDataComparator::kInstance.hash_combine(hash, elemToHash.regex()); SimpleStringDataComparator::kInstance.hash_combine(hash, elemToHash.regexFlags()); break; case mongo::CodeWScope: { SimpleStringDataComparator::kInstance.hash_combine( hash, StringData(elemToHash.codeWScopeCode(), elemToHash.codeWScopeCodeLen())); hashCombineBSONObj(hash, elemToHash.codeWScopeObject(), true, // considerFieldName &SimpleStringDataComparator::kInstance); break; } } }
std::string jsonString(BSONElement &elem, JsonStringFormat format, bool includeFieldNames, int pretty, UUIDEncoding uuidEncoding) { BSONType t = elem.type(); int sign; if ( t == Undefined ) return "undefined"; stringstream s; if ( includeFieldNames ) s << '"' << escape( elem.fieldName() ) << "\" : "; switch ( elem.type() ) { case mongo::String: case Symbol: s << '"' << escape( string(elem.valuestr(), elem.valuestrsize()-1) ) << '"'; break; case NumberLong: s << "NumberLong(" << elem._numberLong() << ")"; break; case NumberInt: case NumberDouble: if ( elem.number() >= -numeric_limits< double >::max() && elem.number() <= numeric_limits< double >::max() ) { s.precision( 16 ); s << elem.number(); } else if ( mongo::isNaN(elem.number()) ) { s << "NaN"; } else if ( mongo::isInf(elem.number(), &sign) ) { s << ( sign == 1 ? "Infinity" : "-Infinity"); } else { StringBuilder ss; ss << "Number " << elem.number() << " cannot be represented in JSON"; string message = ss.str(); //massert( 10311 , message.c_str(), false ); } break; case mongo::Bool: s << ( elem.boolean() ? "true" : "false" ); break; case jstNULL: s << "null"; break; case Object: { BSONObj obj = elem.embeddedObject(); s << jsonString(obj, format, pretty, uuidEncoding); } break; case mongo::Array: { if ( elem.embeddedObject().isEmpty() ) { s << "[]"; break; } s << "[ "; BSONObjIterator i( elem.embeddedObject() ); BSONElement e = i.next(); if ( !e.eoo() ) { int count = 0; while ( 1 ) { if( pretty ) { s << '\n'; for( int x = 0; x < pretty; x++ ) s << " "; } if (strtol(e.fieldName(), 0, 10) > count) { s << "undefined"; } else { s << jsonString(e, format, false, pretty?pretty+1:0, uuidEncoding); e = i.next(); } count++; if ( e.eoo() ) { s << '\n'; for( int x = 0; x < pretty - 1; x++ ) s << " "; s << "]"; break; } s << ", "; } } //s << " ]"; break; } case DBRef: { mongo::OID *x = (mongo::OID *) (elem.valuestr() + elem.valuestrsize()); if ( format == TenGen ) s << "Dbref( "; else s << "{ \"$ref\" : "; s << '"' << elem.valuestr() << "\", "; if ( format != TenGen ) s << "\"$id\" : "; s << '"' << *x << "\" "; if ( format == TenGen ) s << ')'; else s << '}'; break; } case jstOID: if ( format == TenGen ) { s << "ObjectId("; } else { s << "{ \"$oid\" : "; } s << '"' << elem.__oid() << '"'; if ( format == TenGen ) { s << ")"; } else { s << " }"; } break; case BinData: { int len = *(int *)( elem.value() ); BinDataType type = BinDataType( *(char *)( (int *)( elem.value() ) + 1 ) ); if (type == mongo::bdtUUID || type == mongo::newUUID) { s << HexUtils::formatUuid(elem, uuidEncoding); break; } s << "{ \"$binary\" : \""; char *start = ( char * )( elem.value() ) + sizeof( int ) + 1; base64::encode( s , start , len ); s << "\", \"$type\" : \"" << hex; s.width( 2 ); s.fill( '0' ); s << type << dec; s << "\" }"; break; } case mongo::Date: if ( format == Strict ) s << "{ \"$date\" : "; else s << "ISODate("; if( pretty ) { Date_t d = elem.date(); long long ms = (long long) d.millis; boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1)); boost::posix_time::time_duration diff = boost::posix_time::millisec(ms); boost::posix_time::ptime time = epoch + diff; std::string timestr = miutil::isotimeString(time, true, true); s << '"' << timestr << '"'; /* if( d == 0 ) s << '0'; else //P s << '"' << elem.date().toString() << '"'; s << '"' << elem.date().millis << '"';*/ } else s << elem.date(); if ( format == Strict ) s << " }"; else s << ")"; break; case RegEx: if ( format == Strict ) { s << "{ \"$regex\" : \"" << escape( elem.regex() ); s << "\", \"$options\" : \"" << elem.regexFlags() << "\" }"; } else { s << "/" << escape( elem.regex() , true ) << "/"; // FIXME Worry about alpha order? for ( const char *f = elem.regexFlags(); *f; ++f ) { switch ( *f ) { case 'g': case 'i': case 'm': s << *f; default: break; } } } break; case CodeWScope: { BSONObj scope = elem.codeWScopeObject(); if ( ! scope.isEmpty() ) { s << "{ \"$code\" : " << elem._asCode() << " , " << " \"$scope\" : " << scope.jsonString() << " }"; break; } } case Code: s << elem._asCode(); break; case Timestamp: if ( format == TenGen ) { s << "Timestamp(" << ( elem.timestampTime() / 1000 ) << ", " << elem.timestampInc() << ")"; } else { s << "{ \"$timestamp\" : { \"t\" : " << ( elem.timestampTime() / 1000 ) << ", \"i\" : " << elem.timestampInc() << " } }"; } break; case MinKey: s << "{ \"$minKey\" : 1 }"; break; case MaxKey: s << "{ \"$maxKey\" : 1 }"; break; default: StringBuilder ss; ss << "Cannot create a properly formatted JSON string with " << "element: " << elem.toString() << " of type: " << elem.type(); string message = ss.str(); //massert( 10312 , message.c_str(), false ); } return s.str(); }
void lua_push_value(lua_State *L, const BSONElement &elem) { int type = elem.type(); switch(type) { case mongo::Undefined: lua_pushnil(L); break; case mongo::NumberInt: lua_pushinteger(L, elem.numberInt()); break; case mongo::NumberLong: case mongo::NumberDouble: lua_pushnumber(L, elem.number()); break; case mongo::Bool: lua_pushboolean(L, elem.boolean()); break; case mongo::String: lua_pushstring(L, elem.valuestr()); break; case mongo::Array: bson_to_array(L, elem.embeddedObject()); break; case mongo::Object: bson_to_table(L, elem.embeddedObject()); break; case mongo::Date: push_bsontype_table(L, mongo::Date); lua_pushnumber(L, elem.date()); lua_rawseti(L, -2, 1); break; case mongo::Timestamp: push_bsontype_table(L, mongo::Date); lua_pushnumber(L, elem.timestampTime()); lua_rawseti(L, -2, 1); break; case mongo::Symbol: push_bsontype_table(L, mongo::Symbol); lua_pushstring(L, elem.valuestr()); lua_rawseti(L, -2, 1); break; case mongo::RegEx: push_bsontype_table(L, mongo::RegEx); lua_pushstring(L, elem.regex()); lua_rawseti(L, -2, 1); lua_pushstring(L, elem.regexFlags()); lua_rawseti(L, -2, 2); break; case mongo::jstOID: push_bsontype_table(L, mongo::jstOID); lua_pushstring(L, elem.__oid().str().c_str()); lua_rawseti(L, -2, 1); break; case mongo::jstNULL: push_bsontype_table(L, mongo::jstNULL); break; case mongo::EOO: break; default: luaL_error(L, LUAMONGO_UNSUPPORTED_BSON_TYPE, bson_name(type)); } }
// fromBSON to Key format KeyV1Owned::KeyV1Owned(const BSONObj& obj) { BSONObj::iterator i(obj); assert( i.more() ); unsigned char bits = 0; while( 1 ) { BSONElement e = i.next(); if( i.more() ) bits |= cHASMORE; switch( e.type() ) { case MinKey: b.appendUChar(cminkey|bits); break; case jstNULL: b.appendUChar(cnull|bits); break; case MaxKey: b.appendUChar(cmaxkey|bits); break; case Bool: b.appendUChar( (e.boolean()?ctrue:cfalse) | bits ); break; case jstOID: b.appendUChar(coid|bits); b.appendBuf(&e.__oid(), sizeof(OID)); break; case BinData: { int t = e.binDataType(); // 0-7 and 0x80 to 0x87 are supported by Key if( (t & 0x78) == 0 && t != ByteArrayDeprecated ) { int len; const char * d = e.binData(len); int code = BinDataLengthToCode[len]; if( code >= 0 ) { if( t >= 128 ) t = (t-128) | 0x08; dassert( (code&t) == 0 ); b.appendUChar( cbindata|bits ); b.appendUChar( code | t ); b.appendBuf(d, len); break; } } traditional(obj); return; } case Date: b.appendUChar(cdate|bits); b.appendStruct(e.date()); break; case String: { b.appendUChar(cstring|bits); // note we do not store the terminating null, to save space. unsigned x = (unsigned) e.valuestrsize() - 1; if( x > 255 ) { traditional(obj); return; } b.appendUChar(x); b.appendBuf(e.valuestr(), x); break; } case NumberInt: b.appendUChar(cint|bits); b.appendNum((double) e._numberInt()); break; case NumberLong: { long long n = e._numberLong(); double d = (double) n; if( d != n ) { traditional(obj); return; } b.appendUChar(clong|bits); b.appendNum(d); break; } case NumberDouble: { double d = e._numberDouble(); bool nan = !( d <= numeric_limits< double >::max() && d >= -numeric_limits< double >::max() ); if( !nan ) { b.appendUChar(cdouble|bits); b.appendNum(d); break; } // else fall through and return a traditional BSON obj so our compressed keys need not check for nan } default: // if other types involved, store as traditional BSON traditional(obj); return; } if( !i.more() ) break; bits = 0; } _keyData = (const unsigned char *) b.buf(); dassert( b.len() == dataSize() ); // check datasize method is correct dassert( (*_keyData & cNOTUSED) == 0 ); }
Handle<v8::Value> mongoToV8Element( const BSONElement &f ) { Local< v8::ObjectTemplate > internalFieldObjects = v8::ObjectTemplate::New(); internalFieldObjects->SetInternalFieldCount( 1 ); switch ( f.type() ){ case mongo::Code: return newFunction( f.valuestr() ); case CodeWScope: if ( f.codeWScopeObject().isEmpty() ) log() << "warning: CodeWScope doesn't transfer to db.eval" << endl; return newFunction( f.codeWScopeCode() ); case mongo::String: return v8::String::New( f.valuestr() ); case mongo::jstOID: return newId( f.__oid() ); case mongo::NumberDouble: case mongo::NumberInt: return v8::Number::New( f.number() ); case mongo::Array: case mongo::Object: return mongoToV8( f.embeddedObject() , f.type() == mongo::Array ); case mongo::Date: return v8::Date::New( f.date() ); case mongo::Bool: return v8::Boolean::New( f.boolean() ); case mongo::EOO: case mongo::jstNULL: case mongo::Undefined: // duplicate sm behavior return v8::Null(); case mongo::RegEx: { v8::Function * regex = getNamedCons( "RegExp" ); v8::Handle<v8::Value> argv[2]; argv[0] = v8::String::New( f.regex() ); argv[1] = v8::String::New( f.regexFlags() ); return regex->NewInstance( 2 , argv ); break; } case mongo::BinData: { int len; const char *data = f.binData( len ); v8::Function* binData = getNamedCons( "BinData" ); v8::Handle<v8::Value> argv[3]; argv[0] = v8::Number::New( len ); argv[1] = v8::Number::New( f.binDataType() ); argv[2] = v8::String::New( data, len ); return binData->NewInstance( 3, argv ); }; case mongo::Timestamp: { Local<v8::Object> sub = internalFieldObjects->NewInstance(); sub->Set( v8::String::New( "time" ) , v8::Date::New( f.timestampTime() ) ); sub->Set( v8::String::New( "i" ) , v8::Number::New( f.timestampInc() ) ); sub->SetInternalField( 0, v8::Uint32::New( f.type() ) ); 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(); sub->Set( v8::String::New( "$MinKey" ), v8::Boolean::New( true ) ); sub->SetInternalField( 0, v8::Uint32::New( f.type() ) ); return sub; } case mongo::MaxKey: { Local<v8::Object> sub = internalFieldObjects->NewInstance(); sub->Set( v8::String::New( "$MaxKey" ), v8::Boolean::New( true ) ); sub->SetInternalField( 0, v8::Uint32::New( f.type() ) ); return sub; } case mongo::DBRef: { v8::Function* dbPointer = getNamedCons( "DBPointer" ); v8::Handle<v8::Value> argv[2]; argv[0] = v8::String::New( f.dbrefNS() ); argv[1] = newId( f.dbrefOID() ); return dbPointer->NewInstance(2, argv); } default: cout << "can't handle type: "; cout << f.type() << " "; cout << f.toString(); cout << endl; break; } return v8::Undefined(); }
// fromBSON to Key format KeyV1Owned::KeyV1Owned(const BSONObj& obj) { BSONObj::iterator i(obj); unsigned char bits = 0; while( 1 ) { BSONElement e = i.next(); if( i.more() ) bits |= cHASMORE; switch( e.type() ) { case MinKey: b.appendUChar(cminkey|bits); break; case jstNULL: b.appendUChar(cnull|bits); break; case MaxKey: b.appendUChar(cmaxkey|bits); break; case Bool: b.appendUChar( (e.boolean()?ctrue:cfalse) | bits ); break; case jstOID: b.appendUChar(coid|bits); b.appendBuf(&e.__oid(), sizeof(OID)); break; case BinData: { int t = e.binDataType(); // 0-7 and 0x80 to 0x87 are supported by Key if( (t & 0x78) == 0 && t != ByteArrayDeprecated ) { int len; const char * d = e.binData(len); if( len <= BinDataLenMax ) { int code = BinDataLengthToCode[len]; if( code >= 0 ) { if( t >= 128 ) t = (t-128) | 0x08; dassert( (code&t) == 0 ); b.appendUChar( cbindata|bits ); b.appendUChar( code | t ); b.appendBuf(d, len); break; } } } traditional(obj); return; } case Date: b.appendUChar(cdate|bits); b.appendStruct(e.date()); break; case String: { b.appendUChar(cstring|bits); // note we do not store the terminating null, to save space. unsigned x = (unsigned) e.valuestrsize() - 1; if( x > 255 ) { traditional(obj); return; } b.appendUChar(x); b.appendBuf(e.valuestr(), x); break; } case NumberInt: b.appendUChar(cint|bits); b.appendNum((double) e._numberInt()); break; case NumberLong: { long long n = e._numberLong(); long long m = 2LL << 52; DEV { long long d = m-1; verify( ((long long) ((double) -d)) == -d ); } if( n >= m || n <= -m ) { // can't represent exactly as a double traditional(obj); return; } b.appendUChar(clong|bits); b.appendNum((double) n); break; } case NumberDouble: { double d = e._numberDouble(); if( isNaN(d) ) { traditional(obj); return; } b.appendUChar(cdouble|bits); b.appendNum(d); break; } default: // if other types involved, store as traditional BSON traditional(obj); return; } if( !i.more() ) break; bits = 0; } _keyData = (const unsigned char *) b.buf(); dassert( b.len() == dataSize() ); // check datasize method is correct dassert( (*_keyData & cNOTUSED) == 0 ); }
// PD_TRACE_DECLARE_FUNCTION ( SDB_RTNCOORDREMOVELOB_EXECUTE, "rtnCoordRemoveLob::execute" ) INT32 rtnCoordRemoveLob::execute( CHAR *pReceiveBuffer, SINT32 packSize, CHAR **ppResultBuffer, pmdEDUCB *cb, MsgOpReply &replyHeader, BSONObj** ppErrorObj ) { INT32 rc = SDB_OK ; PD_TRACE_ENTRY( SDB_RTNCOORDREMOVELOB_EXECUTE ) ; const MsgOpLob *header = NULL ; const MsgHeader *baseHeader = ( const MsgHeader * )pReceiveBuffer ; BSONObj obj ; BSONElement ele ; const CHAR *fullName = NULL ; _rtnCoordLobStream stream ; replyHeader.header.messageLength = sizeof( MsgOpReply ) ; replyHeader.header.opCode = MSG_BS_LOB_CLOSE_RES ; replyHeader.header.requestID = baseHeader->requestID ; replyHeader.header.routeID.value = 0 ; replyHeader.header.TID = baseHeader->TID ; replyHeader.contextID = -1 ; replyHeader.flags = SDB_OK ; replyHeader.numReturned = 0 ; replyHeader.startFrom = 0 ; rc = msgExtractRemoveLobRequest( pReceiveBuffer, &header, obj ) ; if ( SDB_OK != rc ) { PD_LOG( PDERROR, "failed to extract remove msg:%d", rc ) ; goto error ; } ele = obj.getField( FIELD_NAME_COLLECTION ) ; if ( String != ele.type() ) { PD_LOG( PDERROR, "invalid type of field \"collection\":%s", obj.toString( FALSE, TRUE ).c_str() ) ; rc = SDB_SYS ; goto error ; } fullName = ele.valuestr() ; ele = obj.getField( FIELD_NAME_LOB_OID ) ; if ( jstOID != ele.type() ) { PD_LOG( PDERROR, "invalid type of field \"oid\":%s", obj.toString( FALSE, TRUE ).c_str() ) ; rc = SDB_SYS ; goto error ; } rc = stream.open( fullName, ele.__oid(), SDB_LOB_MODE_REMOVE, cb ) ; if ( SDB_OK != rc ) { PD_LOG( PDERROR, "failed to remove lob:%s, rc:%d", ele.__oid().str().c_str(), rc ) ; goto error ; } else { } rc = stream.truncate( 0, cb ) ; if ( SDB_OK != rc ) { PD_LOG( PDERROR, "faield to truncate lob:%d", rc ) ; goto error ; } done: { INT32 rcTmp = SDB_OK ; rcTmp = stream.close( cb ) ; if ( SDB_OK != rcTmp ) { PD_LOG( PDERROR, "failed to remove lob:%d", rcTmp ) ; rc = rc == SDB_OK ? rcTmp : rc ; replyHeader.flags = rc ; } } PD_TRACE_EXITRC( SDB_RTNCOORDREMOVELOB_EXECUTE, rc ) ; return rc ; error: replyHeader.flags = rc ; goto done ; }
jsval toval( const BSONElement& e ) { switch( e.type() ) { case EOO: case jstNULL: case Undefined: return JSVAL_NULL; case NumberDouble: case NumberInt: return toval( e.number() ); case Symbol: // TODO: should we make a special class for this case String: return toval( e.valuestr() ); case Bool: return e.boolean() ? JSVAL_TRUE : JSVAL_FALSE; case Object: { BSONObj embed = e.embeddedObject().getOwned(); return toval( &embed ); } case Array: { BSONObj embed = e.embeddedObject().getOwned(); if ( embed.isEmpty() ) { return OBJECT_TO_JSVAL( JS_NewArrayObject( _context , 0 , 0 ) ); } int n = embed.nFields(); JSObject * array = JS_NewArrayObject( _context , n , 0 ); assert( array ); jsval myarray = OBJECT_TO_JSVAL( array ); for ( int i=0; i<n; i++ ) { jsval v = toval( embed[i] ); assert( JS_SetElement( _context , array , i , &v ) ); } return myarray; } case jstOID: { OID oid = e.__oid(); JSObject * o = JS_NewObject( _context , &object_id_class , 0 , 0 ); setProperty( o , "str" , toval( oid.str().c_str() ) ); return OBJECT_TO_JSVAL( o ); } case RegEx: { const char * flags = e.regexFlags(); uintN flagNumber = 0; while ( *flags ) { switch ( *flags ) { case 'g': flagNumber |= JSREG_GLOB; break; case 'i': flagNumber |= JSREG_FOLD; break; case 'm': flagNumber |= JSREG_MULTILINE; break; //case 'y': flagNumber |= JSREG_STICKY; break; default: log() << "warning: unknown regex flag:" << *flags << endl; } flags++; } JSObject * r = JS_NewRegExpObject( _context , (char*)e.regex() , strlen( e.regex() ) , flagNumber ); assert( r ); return OBJECT_TO_JSVAL( r ); } case Code: { JSFunction * func = compileFunction( e.valuestr() ); return OBJECT_TO_JSVAL( JS_GetFunctionObject( func ) ); } case CodeWScope: { JSFunction * func = compileFunction( e.codeWScopeCode() ); BSONObj extraScope = e.codeWScopeObject(); if ( ! extraScope.isEmpty() ) { log() << "warning: CodeWScope doesn't transfer to db.eval" << endl; } return OBJECT_TO_JSVAL( JS_GetFunctionObject( func ) ); } case Date: return OBJECT_TO_JSVAL( js_NewDateObjectMsec( _context , (jsdouble) e.date().millis ) ); case MinKey: return OBJECT_TO_JSVAL( JS_NewObject( _context , &minkey_class , 0 , 0 ) ); case MaxKey: return OBJECT_TO_JSVAL( JS_NewObject( _context , &maxkey_class , 0 , 0 ) ); case Timestamp: { JSObject * o = JS_NewObject( _context , ×tamp_class , 0 , 0 ); setProperty( o , "t" , toval( (double)(e.timestampTime()) ) ); setProperty( o , "i" , toval( (double)(e.timestampInc()) ) ); return OBJECT_TO_JSVAL( o ); } case NumberLong: { boost::uint64_t val = (boost::uint64_t)e.numberLong(); JSObject * o = JS_NewObject( _context , &numberlong_class , 0 , 0 ); setProperty( o , "floatApprox" , toval( (double)(boost::int64_t)( val ) ) ); if ( (boost::int64_t)val != (boost::int64_t)(double)(boost::int64_t)( val ) ) { // using 2 doubles here instead of a single double because certain double // bit patterns represent undefined values and sm might trash them setProperty( o , "top" , toval( (double)(boost::uint32_t)( val >> 32 ) ) ); setProperty( o , "bottom" , toval( (double)(boost::uint32_t)( val & 0x00000000ffffffff ) ) ); } return OBJECT_TO_JSVAL( o ); } case DBRef: { JSObject * o = JS_NewObject( _context , &dbpointer_class , 0 , 0 ); setProperty( o , "ns" , toval( e.dbrefNS() ) ); JSObject * oid = JS_NewObject( _context , &object_id_class , 0 , 0 ); setProperty( oid , "str" , toval( e.dbrefOID().str().c_str() ) ); setProperty( o , "id" , OBJECT_TO_JSVAL( oid ) ); return OBJECT_TO_JSVAL( o ); } case BinData: { JSObject * o = JS_NewObject( _context , &bindata_class , 0 , 0 ); int len; const char * data = e.binData( len ); assert( JS_SetPrivate( _context , o , new BinDataHolder( data ) ) ); setProperty( o , "len" , toval( len ) ); setProperty( o , "type" , toval( (int)e.binDataType() ) ); return OBJECT_TO_JSVAL( o ); } }