summaryrefslogtreecommitdiff
path: root/src/mongo/client/connection_string.cpp
diff options
context:
space:
mode:
authorSpencer T Brody <spencer@mongodb.com>2015-04-15 13:24:09 -0400
committerSpencer T Brody <spencer@mongodb.com>2015-04-16 16:02:48 -0400
commit492e26db0702abd8b44794fb718f76b26afecefd (patch)
tree8b1878dc5d8e2fe17b5d5ac34160cb639d7bab6e /src/mongo/client/connection_string.cpp
parentaa303eb3b5898842a0f5730472413d2b2fdc0930 (diff)
downloadmongo-492e26db0702abd8b44794fb718f76b26afecefd.tar.gz
SERVER-18070 Split ConnectionString out into its own library
Diffstat (limited to 'src/mongo/client/connection_string.cpp')
-rw-r--r--src/mongo/client/connection_string.cpp168
1 files changed, 168 insertions, 0 deletions
diff --git a/src/mongo/client/connection_string.cpp b/src/mongo/client/connection_string.cpp
new file mode 100644
index 00000000000..5e8d5a817cb
--- /dev/null
+++ b/src/mongo/client/connection_string.cpp
@@ -0,0 +1,168 @@
+/* Copyright 2009 10gen Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects
+ * for all of the code used other than as permitted herein. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you do not
+ * wish to do so, delete this exception statement from your version. If you
+ * delete this exception statement from all source files in the program,
+ * then also delete it in the license file.
+ */
+
+#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kNetwork
+
+#include "mongo/platform/basic.h"
+
+#include "mongo/client/connection_string.h"
+
+#include "mongo/util/mongoutils/str.h"
+
+namespace mongo {
+
+ void ConnectionString::_fillServers( std::string s ) {
+
+ //
+ // Custom-handled servers/replica sets start with '$'
+ // According to RFC-1123/952, this will not overlap with valid hostnames
+ // (also disallows $replicaSetName hosts)
+ //
+
+ if( s.find( '$' ) == 0 ) _type = CUSTOM;
+
+ {
+ std::string::size_type idx = s.find( '/' );
+ if ( idx != std::string::npos ) {
+ _setName = s.substr( 0 , idx );
+ s = s.substr( idx + 1 );
+ if( _type != CUSTOM ) _type = SET;
+ }
+ }
+
+ std::string::size_type idx;
+ while ( ( idx = s.find( ',' ) ) != std::string::npos ) {
+ _servers.push_back(HostAndPort(s.substr(0, idx)));
+ s = s.substr( idx + 1 );
+ }
+ _servers.push_back(HostAndPort(s));
+
+ }
+
+ void ConnectionString::_finishInit() {
+
+ // Needed here as well b/c the parsing logic isn't used in all constructors
+ // TODO: Refactor so that the parsing logic *is* used in all constructors
+ if ( _type == MASTER && _servers.size() > 0 ){
+ if( _servers[0].host().find( '$' ) == 0 ){
+ _type = CUSTOM;
+ }
+ }
+
+ std::stringstream ss;
+ if ( _type == SET )
+ ss << _setName << "/";
+ for ( unsigned i=0; i<_servers.size(); i++ ) {
+ if ( i > 0 )
+ ss << ",";
+ ss << _servers[i].toString();
+ }
+ _string = ss.str();
+ }
+
+ bool ConnectionString::sameLogicalEndpoint( const ConnectionString& other ) const {
+ if ( _type != other._type )
+ return false;
+
+ switch ( _type ) {
+ case INVALID:
+ return true;
+ case MASTER:
+ return _servers[0] == other._servers[0];
+ case PAIR:
+ if ( _servers[0] == other._servers[0] )
+ return _servers[1] == other._servers[1];
+ return
+ ( _servers[0] == other._servers[1] ) &&
+ ( _servers[1] == other._servers[0] );
+ case SET:
+ return _setName == other._setName;
+ case SYNC:
+ // The servers all have to be the same in each, but not in the same order.
+ if ( _servers.size() != other._servers.size() )
+ return false;
+ for ( unsigned i = 0; i < _servers.size(); i++ ) {
+ bool found = false;
+ for ( unsigned j = 0; j < other._servers.size(); j++ ) {
+ if ( _servers[i] == other._servers[j] ) {
+ found = true;
+ break;
+ }
+ }
+ if ( ! found )
+ return false;
+ }
+ return true;
+ case CUSTOM:
+ return _string == other._string;
+ }
+ verify( false );
+ }
+
+ ConnectionString ConnectionString::parse( const std::string& host , std::string& errmsg ) {
+
+ std::string::size_type i = host.find( '/' );
+ if ( i != std::string::npos && i != 0) {
+ // replica set
+ return ConnectionString( SET , host.substr( i + 1 ) , host.substr( 0 , i ) );
+ }
+
+ int numCommas = str::count( host , ',' );
+
+ if( numCommas == 0 )
+ return ConnectionString( HostAndPort( host ) );
+
+ if ( numCommas == 1 )
+ return ConnectionString( PAIR , host );
+
+ if ( numCommas == 2 )
+ return ConnectionString( SYNC , host );
+
+ errmsg = (std::string)"invalid hostname [" + host + "]";
+ return ConnectionString(); // INVALID
+ }
+
+ std::string ConnectionString::typeToString( ConnectionType type ) {
+ switch ( type ) {
+ case INVALID:
+ return "invalid";
+ case MASTER:
+ return "master";
+ case PAIR:
+ return "pair";
+ case SET:
+ return "set";
+ case SYNC:
+ return "sync";
+ case CUSTOM:
+ return "custom";
+ }
+ verify(0);
+ return "";
+ }
+
+} // namespace mongo