void SyncClusterConnection::update( const string &ns , Query query , BSONObj obj , bool upsert , bool multi ){ if ( upsert ){ uassert( 13120 , "SyncClusterConnection::update upsert query needs _id" , query.obj["_id"].type() ); } if ( _writeConcern ){ string errmsg; if ( ! prepare( errmsg ) ) throw UserException( 8005 , (string)"SyncClusterConnection::udpate prepare failed: " + errmsg ); } for ( size_t i=0; i<_conns.size(); i++ ){ try { _conns[i]->update( ns , query , obj , upsert , multi ); } catch ( std::exception& e ){ if ( _writeConcern ) throw e; } } if ( _writeConcern ){ _checkLast(); } }
void SyncClusterConnection::insert( const string &ns, const vector< BSONObj >& v , int flags) { if (v.size() == 1){ insert(ns, v[0], flags); return; } for (vector<BSONObj>::const_iterator it = v.begin(); it != v.end(); ++it ) { BSONObj obj = *it; if ( obj["_id"].type() == EOO ) { string assertMsg = "SyncClusterConnection::insert (batched) obj misses an _id: "; uasserted( 16743, assertMsg + obj.jsonString() ); } } // fsync all connections before starting the batch. string errmsg; if ( ! prepare( errmsg ) ) { string assertMsg = "SyncClusterConnection::insert (batched) prepare failed: "; throw UserException( 16744, assertMsg + errmsg ); } // We still want one getlasterror per document, even if they're batched. for ( size_t i=0; i<_conns.size(); i++ ) { for ( vector<BSONObj>::const_iterator it = v.begin(); it != v.end(); ++it ) { _conns[i]->insert( ns, *it, flags ); _conns[i]->getLastErrorDetailed(); } } // We issue a final getlasterror, but this time with an fsync. _checkLast(); }
BSONObj SyncClusterConnection::findOne(const string &ns, Query query, const BSONObj *fieldsToReturn, int queryOptions) { if ( ns.find( ".$cmd" ) != string::npos ){ string cmdName = query.obj.firstElement().fieldName(); int lockType = _lockType( cmdName ); if ( lockType > 0 ){ // write $cmd string errmsg; if ( ! prepare( errmsg ) ) throw UserException( 13104 , (string)"SyncClusterConnection::insert prepare failed: " + errmsg ); vector<BSONObj> all; for ( size_t i=0; i<_conns.size(); i++ ){ all.push_back( _conns[i]->findOne( ns , query , 0 , queryOptions ).getOwned() ); } _checkLast(); for ( size_t i=0; i<all.size(); i++ ){ BSONObj temp = all[i]; if ( isOk( temp ) ) continue; stringstream ss; ss << "write $cmd failed on a shard: " << temp.jsonString(); ss << " " << _conns[i]->toString(); throw UserException( 13105 , ss.str() ); } return all[0]; } } return DBClientBase::findOne( ns , query , fieldsToReturn , queryOptions ); }
void SyncClusterConnection::remove( const string &ns , Query query, int flags ) { string errmsg; if ( ! prepare( errmsg ) ) throw UserException( 8020 , (string)"SyncClusterConnection::remove prepare failed: " + errmsg ); for ( size_t i=0; i<_conns.size(); i++ ) { _conns[i]->remove( ns , query , flags ); } _checkLast(); }
void SyncClusterConnection::say( Message &toSend ) { string errmsg; if ( ! prepare( errmsg ) ) throw UserException( 13397 , (string)"SyncClusterConnection::say prepare failed: " + errmsg ); for ( size_t i=0; i<_conns.size(); i++ ) { _conns[i]->say( toSend ); } _checkLast(); }
void SyncClusterConnection::say( Message &toSend, bool isRetry , string * actualServer ) { string errmsg; if ( ! prepare( errmsg ) ) throw UserException( 13397 , (string)"SyncClusterConnection::say prepare failed: " + errmsg ); for ( size_t i=0; i<_conns.size(); i++ ) { _conns[i]->say( toSend ); } // TODO: should we set actualServer?? _checkLast(); }
void SyncClusterConnection::insert( const string &ns, BSONObj obj ){ uassert( 13119 , (string)"SyncClusterConnection::insert obj has to have an _id: " + obj.jsonString() , ns.find( ".system.indexes" ) != string::npos || obj["_id"].type() ); string errmsg; if ( ! prepare( errmsg ) ) throw UserException( 8003 , (string)"SyncClusterConnection::insert prepare failed: " + errmsg ); for ( size_t i=0; i<_conns.size(); i++ ){ _conns[i]->insert( ns , obj ); } _checkLast(); }
void SyncClusterConnection::insert( const string &ns, BSONObj obj , int flags) { uassert(13119, (string)"SyncClusterConnection::insert obj has to have an _id: " + obj.jsonString(), NamespaceString(ns).coll == "system.indexes" || obj["_id"].type()); string errmsg; if ( ! prepare( errmsg ) ) throw UserException( 8003 , (string)"SyncClusterConnection::insert prepare failed: " + errmsg ); for ( size_t i=0; i<_conns.size(); i++ ) { _conns[i]->insert( ns , obj , flags); } _checkLast(); }
void SyncClusterConnection::update( const string &ns , Query query , BSONObj obj , int flags ) { if ( flags & UpdateOption_Upsert ) { uassert( 13120 , "SyncClusterConnection::update upsert query needs _id" , query.obj["_id"].type() ); } if ( _writeConcern ) { string errmsg; if ( ! prepare( errmsg ) ) throw UserException( 8005 , (string)"SyncClusterConnection::udpate prepare failed: " + errmsg ); } for ( size_t i = 0; i < _conns.size(); i++ ) { try { _conns[i]->update( ns , query , obj , flags ); } catch ( std::exception& e ) { if ( _writeConcern ) throw e; } } if ( _writeConcern ) { _checkLast(); verify( _lastErrors.size() > 1 ); int a = _lastErrors[0]["n"].numberInt(); for ( unsigned i=1; i<_lastErrors.size(); i++ ) { int b = _lastErrors[i]["n"].numberInt(); if ( a == b ) continue; throw UpdateNotTheSame( 8017 , str::stream() << "update not consistent " << " ns: " << ns << " query: " << query.toString() << " update: " << obj << " gle1: " << _lastErrors[0] << " gle2: " << _lastErrors[i] , _connAddresses , _lastErrors ); } } }
void SyncClusterConnection::update( const string &ns , Query query , BSONObj obj , bool upsert , bool multi ) { if ( upsert ) { uassert( 13120 , "SyncClusterConnection::update upsert query needs _id" , query.obj["_id"].type() ); } if ( _writeConcern ) { string errmsg; if ( ! prepare( errmsg ) ) throw UserException( 8005 , (string)"SyncClusterConnection::udpate prepare failed: " + errmsg ); } for ( size_t i=0; i<_conns.size(); i++ ) { try { _conns[i]->update( ns , query , obj , upsert , multi ); } catch ( std::exception& e ) { if ( _writeConcern ) throw e; } } if ( _writeConcern ) { _checkLast(); assert( _lastErrors.size() > 1 ); int a = _lastErrors[0]["n"].numberInt(); for ( unsigned i=1; i<_lastErrors.size(); i++ ) { int b = _lastErrors[i]["n"].numberInt(); if ( a == b ) continue; throw UpdateNotTheSame( 8017 , "update not consistent" , _connAddresses , _lastErrors ); } } }