IConnectionSettingsBaseSPtr IClusterSettingsBase::findSettingsByHost(const common::net::hostAndPort& host) const
    {
        for(int i = 0; i < clusters_nodes_.size(); ++i){
            IConnectionSettingsBaseSPtr cur = clusters_nodes_[i];
            if(cur->host() == host){
                return cur;
            }
        }

        return IConnectionSettingsBaseSPtr();
    }
    void SettingsManager::save()
    {
        QSettings settings(common::convertFromString<QString>(common::file_system::prepare_path(iniPath)), QSettings::IniFormat);
        DCHECK(settings.status() == QSettings::NoError);

        settings.setValue(STYLE, curStyle_);
        settings.setValue(FONT, curFontName_);
        settings.setValue(LANGUAGE, curLanguage_);
        settings.setValue(VIEW, views_);

        QList<QVariant> clusters;
        for(ClusterSettingsContainerType::const_iterator it = clusters_.begin(); it != clusters_.end(); ++it){
            IClusterSettingsBaseSPtr conn = *it;
            if(conn){
               std::string raw = conn->toString();
               std::string enc = common::utils::base64::encode64(raw);
               QString qdata = common::convertFromString<QString>(enc);
               clusters.push_back(qdata);
            }
        }
        settings.setValue(CLUSTERS, clusters);

        QList<QVariant> connections;
        for(ConnectionSettingsContainerType::const_iterator it = connections_.begin(); it != connections_.end(); ++it){
            IConnectionSettingsBaseSPtr conn = *it;
            if(conn){
               std::string raw = conn->toString();
               std::string enc = common::utils::base64::encode64(raw);
               QString qdata = common::convertFromString<QString>(enc);
               connections.push_back(qdata);
            }
        }
        settings.setValue(CONNECTIONS, connections);

        QStringList rconnections;
        for(QStringList::const_iterator it = recentConnections_.begin(); it != recentConnections_.end(); ++it){
            QString conn = *it;
            if(!conn.isEmpty()){
               std::string raw = common::convertToString(conn);
               std::string enc = common::utils::base64::encode64(raw);
               QString qdata = common::convertFromString<QString>(enc);
               rconnections.push_back(qdata);
            }
        }
        settings.setValue(RCONNECTIONS, rconnections);

        settings.setValue(SYNCTABS, syncTabs_);
        settings.setValue(LOGGINGDIR, loggingDir_);
        settings.setValue(CHECKUPDATES, autoCheckUpdate_);
        settings.setValue(AUTOCOMPLETION, autoCompletion_);
        settings.setValue(AUTOOPENCONSOLE, autoOpenConsole_);
        settings.setValue(FASTVIEWKEYS, fastViewKeys_);
    }
    std::string IClusterSettingsBase::toString() const
    {
        DCHECK(type_ != DBUNKNOWN);

        std::stringstream str;
        str << IConnectionSettings::toString() << ',';
        for(int i = 0; i < clusters_nodes_.size(); ++i){
           IConnectionSettingsBaseSPtr serv = clusters_nodes_[i];
           if(serv){
               str << magicNumber << serv->toString();
           }
        }

        std::string res = str.str();
        return res;
    }
    IServerSPtr ServersManager::createServer(IConnectionSettingsBaseSPtr settings)
    {
        DCHECK(settings);

        IServerSPtr result;
        connectionTypes conT = settings->connectionType();
        IServerSPtr ser = findServerBySetting(settings);
        if(conT == REDIS){
            RedisServer *newRed = NULL;
            if(!ser){
                IDriverSPtr dr(new RedisDriver(settings));
                dr->start();
                newRed = new RedisServer(dr, true);
            }
            else{
                newRed = new RedisServer(ser->driver(), false);
            }
            result.reset(newRed);
            servers_.push_back(result);
        }
        else if(conT == MEMCACHED){
            MemcachedServer *newMem = NULL;
            if(!ser){
                IDriverSPtr dr(new MemcachedDriver(settings));
                dr->start();
                newMem = new MemcachedServer(dr, true);
            }
            else{
                newMem = new MemcachedServer(ser->driver(), false);
            }
            result.reset(newMem);
            servers_.push_back(result);
        }
        else if(conT == SSDB){
            SsdbServer *newSsdb = NULL;
            if(!ser){
                IDriverSPtr dr(new SsdbDriver(settings));
                dr->start();
                newSsdb = new SsdbServer(dr, true);
            }
            else{
                newSsdb = new SsdbServer(ser->driver(), false);
            }
            result.reset(newSsdb);
            servers_.push_back(result);
        }

        DCHECK(result);
        if(ser && syncServers_){
            result->syncWithServer(ser.get());
        }

        return result;
    }
    void ConnectionsDialog::edit()
    {
        QTreeWidgetItem* qitem = listWidget_->currentItem();
        if(!qitem){
            return;
        }

        ConnectionListWidgetItem* currentItem = dynamic_cast<ConnectionListWidgetItem *>(qitem);
        if(currentItem){
            QTreeWidgetItem* qpitem = qitem->parent();
            if(!qpitem){
                IConnectionSettingsBaseSPtr con = currentItem->connection();
                ConnectionDialog dlg(this, dynamic_cast<IConnectionSettingsBase*>(con->clone()));
                int result = dlg.exec();
                IConnectionSettingsBaseSPtr newConnection = dlg.connection();
                if(result == QDialog::Accepted && newConnection){
                    currentItem->setConnection(newConnection);
                    SettingsManager::instance().removeConnection(con);
                    SettingsManager::instance().addConnection(newConnection);
                }
                return;
            }
            else{
                qitem = qpitem;
            }
        }


        ClusterConnectionListWidgetItem* clCurrentItem = dynamic_cast<ClusterConnectionListWidgetItem *>(qitem);
        if(clCurrentItem){
            IClusterSettingsBaseSPtr con = clCurrentItem->connection();
            ClusterDialog dlg(this, dynamic_cast<IClusterSettingsBase*>(con->clone()));
            int result = dlg.exec();
            IClusterSettingsBaseSPtr newConnection = dlg.connection();
            if(result == QDialog::Accepted && newConnection){
                clCurrentItem->setConnection(newConnection);
                SettingsManager::instance().removeCluster(con);
                SettingsManager::instance().addCluster(newConnection);
            }
        }
    }
IServerSPtr ServersManager::createServer(IConnectionSettingsBaseSPtr settings) {
  if (!settings) {
    NOTREACHED();
    return IServerSPtr();
  }

  connectionTypes conT = settings->type();
  IServer* server = nullptr;
#ifdef BUILD_WITH_REDIS
  if (conT == REDIS) {
    server = new redis::RedisServer(settings);
  }
#endif
#ifdef BUILD_WITH_MEMCACHED
  if (conT == MEMCACHED) {
    server = new memcached::MemcachedServer(settings);
  }
#endif
#ifdef BUILD_WITH_SSDB
  if (conT == SSDB) {
    server = new ssdb::SsdbServer(settings);
  }
#endif
#ifdef BUILD_WITH_LEVELDB
  if (conT == LEVELDB) {
    server = new leveldb::LeveldbServer(settings);
  }
#endif
#ifdef BUILD_WITH_ROCKSDB
  if (conT == ROCKSDB) {
    server = new rocksdb::RocksdbServer(settings);
  }
#endif
#ifdef BUILD_WITH_UNQLITE
  if (conT == UNQLITE) {
    server = new unqlite::UnqliteServer(settings);
  }
#endif
#ifdef BUILD_WITH_LMDB
  if (conT == LMDB) {
    server = new lmdb::LmdbServer(settings);
  }
#endif

  if (!server) {
    NOTREACHED();
    return IServerSPtr();
  }

  IServerSPtr sh(server);
  servers_.push_back(sh);
  return sh;
}
common::Error ServersManager::discoveryConnection(IConnectionSettingsBaseSPtr connection,
                                                  std::vector<ServerDiscoveryInfoSPtr>* inf) {
  if (!connection || !inf) {
    return common::make_error_value("Invalid input argument", common::ErrorValue::E_ERROR);
  }

  connectionTypes type = connection->type();
#ifdef BUILD_WITH_REDIS
  if (type == REDIS) {
    return fastonosql::redis::discoveryConnection(dynamic_cast<redis::RedisConnectionSettings*>(connection.get()), inf);
  }
#endif
#ifdef BUILD_WITH_MEMCACHED
  if (type == MEMCACHED) {
    return common::make_error_value("Not supported setting type", common::ErrorValue::E_ERROR);
  }
#endif
#ifdef BUILD_WITH_SSDB
  if (type == SSDB) {
    return common::make_error_value("Not supported setting type", common::ErrorValue::E_ERROR);
  }
#endif
#ifdef BUILD_WITH_LEVELDB
  if (type == LEVELDB) {
    return common::make_error_value("Not supported setting type", common::ErrorValue::E_ERROR);
  }
#endif
#ifdef BUILD_WITH_ROCKSDB
  if (type == ROCKSDB) {
    return common::make_error_value("Not supported setting type", common::ErrorValue::E_ERROR);
  }
#endif
#ifdef BUILD_WITH_UNQLITE
  if (type == UNQLITE) {
    return common::make_error_value("Not supported setting type", common::ErrorValue::E_ERROR);
  }
#endif
#ifdef BUILD_WITH_LMDB
  if (type == LMDB) {
    return common::make_error_value("Not supported setting type", common::ErrorValue::E_ERROR);
  }
#endif
  return common::make_error_value("Invalid setting type", common::ErrorValue::E_ERROR);
}
common::Error ServersManager::testConnection(IConnectionSettingsBaseSPtr connection) {
  if (!connection) {
    NOTREACHED();
    return common::make_error_value("Invalid input argument", common::ErrorValue::E_ERROR);
  }

  connectionTypes type = connection->type();
#ifdef BUILD_WITH_REDIS
  if (type == REDIS) {
    return fastonosql::redis::testConnection(dynamic_cast<redis::RedisConnectionSettings*>(connection.get()));
  }
#endif
#ifdef BUILD_WITH_MEMCACHED
  if (type == MEMCACHED) {
    return fastonosql::memcached::testConnection(dynamic_cast<memcached::MemcachedConnectionSettings*>(connection.get()));
  }
#endif
#ifdef BUILD_WITH_SSDB
  if (type == SSDB) {
    return fastonosql::ssdb::testConnection(dynamic_cast<ssdb::SsdbConnectionSettings*>(connection.get()));
  }
#endif
#ifdef BUILD_WITH_LEVELDB
  if (type == LEVELDB) {
    return fastonosql::leveldb::testConnection(dynamic_cast<leveldb::LeveldbConnectionSettings*>(connection.get()));
  }
#endif
#ifdef BUILD_WITH_ROCKSDB
  if (type == ROCKSDB) {
    return fastonosql::rocksdb::testConnection(dynamic_cast<rocksdb::RocksdbConnectionSettings*>(connection.get()));
  }
#endif
#ifdef BUILD_WITH_UNQLITE
  if (type == UNQLITE) {
    return fastonosql::unqlite::testConnection(dynamic_cast<unqlite::UnqliteConnectionSettings*>(connection.get()));
  }
#endif
#ifdef BUILD_WITH_LMDB
  if (type == LMDB) {
    return fastonosql::lmdb::testConnection(dynamic_cast<lmdb::LmdbConnectionSettings*>(connection.get()));
  }
#endif
  return common::make_error_value("Invalid setting type", common::ErrorValue::E_ERROR);
}
    IServerSPtr ServersManager::createServer(IConnectionSettingsBaseSPtr settings)
    {
        DCHECK(settings);

        IServerSPtr result;
        connectionTypes conT = settings->connectionType();
        IServerSPtr ser = findServerBySetting(settings);
#ifdef BUILD_WITH_REDIS
        if(conT == REDIS){
            result.reset(make_server<RedisServer, RedisDriver>(ser, settings));
        }
#endif
#ifdef BUILD_WITH_MEMCACHED
        if(conT == MEMCACHED){
            result.reset(make_server<MemcachedServer, MemcachedDriver>(ser, settings));
        }
#endif
#ifdef BUILD_WITH_SSDB
        if(conT == SSDB){
            result.reset(make_server<SsdbServer, SsdbDriver>(ser, settings));
        }
#endif
#ifdef BUILD_WITH_LEVELDB
        if(conT == LEVELDB){
            result.reset(make_server<LeveldbServer, LeveldbDriver>(ser, settings));
        }
#endif

        DCHECK(result);
        if(result){
            servers_.push_back(result);
            if(ser && syncServers_){
                result->syncWithServer(ser.get());
            }
        }

        return result;
    }
    ConnectionDiagnosticDialog::ConnectionDiagnosticDialog(QWidget* parent, IConnectionSettingsBaseSPtr connection)
        : QDialog(parent)
    {
        using namespace translations;

        setWindowTitle(trConnectionDiagnostic);
        setWindowIcon(GuiFactory::instance().icon(connection->connectionType()));
        setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); // Remove help button (?)

        QVBoxLayout* mainLayout = new QVBoxLayout;

        executeTimeLabel_ = new QLabel;
        executeTimeLabel_->setText(connectionStatusTemplate.arg("execute..."));
        mainLayout->addWidget(executeTimeLabel_);

        statusLabel_ = new QLabel(timeTemplate.arg("calculate..."));
        iconLabel_ = new QLabel;
        QIcon icon = GuiFactory::instance().failIcon();
        const QPixmap pm = icon.pixmap(stateIconSize);
        iconLabel_->setPixmap(pm);

        mainLayout->addWidget(statusLabel_);
        mainLayout->addWidget(iconLabel_, 1, Qt::AlignCenter);

        QDialogButtonBox* buttonBox = new QDialogButtonBox;
        buttonBox->setOrientation(Qt::Horizontal);
        buttonBox->setStandardButtons(QDialogButtonBox::Ok);
        VERIFY(connect(buttonBox, &QDialogButtonBox::accepted, this, &ConnectionDiagnosticDialog::accept));

        mainLayout->addWidget(buttonBox);
        setFixedSize(QSize(fix_width, fix_height));
        setLayout(mainLayout);

        glassWidget_ = new fasto::qt::gui::GlassWidget(GuiFactory::instance().pathToLoadingGif(), trTryToConnect, 0.5, QColor(111, 111, 100), this);
        testConnection(connection);
    }