Connection::Connection(const QString& ident, const QString& driver, const QString& dbHost, const QString& dbName, const QString& dbUser, const QString& dbPassword, int dbPort) : _threadId(0), _countRef(0), _countBegins(0), _retryCount(0),_invalid(false) { _conn = QSqlDatabase::addDatabase(driver, ident); _conn.setHostName(dbHost); _conn.setDatabaseName(dbName); _conn.setUserName(dbUser); _conn.setPassword(dbPassword); _conn.setPort(dbPort), open(); }
void exec(QSqlQuery& sql); void exec(const char* sql); void exec(const QString& sql); /** * , */ template <typename T> void fetchCol(QSqlQuery& sql,QList<T>& result)... template <typename T> QList<T> fetchCol(QSqlQuery& sql) ... template <typename T> QList<T> fetchCol(const char* sql) ... template <typename T> QList<T> fetchCol(const QString& sql) ... /* * */ template <typename T> T fetchOne(QSqlQuery& sql, bool* ok = 0) ... template <typename T> T fetchOne(const QString& sql, bool* ok = 0) ... template <typename T> T fetchOne(const char* sql, bool* ok = 0) ... /* * */ void fetchRow(QSqlQuery& sql,QVariantMap& res); QVariantMap fetchRow(const QString& sql); QVariantMap fetchRow(const char* sql); QVariantMap fetchRow(QSqlQuery& sql); /** * */ void query(QSqlQuery& sql,QList<QVariant>& result); QList<QVariant> query(const char* sql); QList<QVariant> query(QSqlQuery& sql); QList<QVariant> query(const QString& sql); /* query */ void fetchAll(QSqlQuery& sql,QList<QVariant>& result); QList<QVariant> fetchAll(const char* sql); QList<QVariant> fetchAll(QSqlQuery& sql); QList<QVariant> fetchAll(const QString& sql);
QSqlQuery createQuery() const { return QSqlQuery(_conn);} QSqlQuery createQuery(const QString& sql) { return QSqlQuery(sql, _conn); }
DB::DConn conn; // DB::ManagedConnection conn("default'); // DB::ManagedConnection c1("db1conn); DB::ManagedConnection c2("db2conn);
Order : save(){ DB::DBConn conn; // . countRef = 1 conn->query('INSERT INTO order...'); item->save(); Item:save() { DB::DBConn conn;// . countRef = 2 conn->query('INSERT INTO item...'); data->save(); Data:save() { DB::DBConn conn;// . countRef = 3 conn->query('INSERT INTO data...'); // , ~ManagedConnection countRef = 2 } // , ~ManagedConnection countRef = 1 } // , ~ManagedConnection countRef = 0 } } }
[database] size = 2 ; 1\ident=db1conn ; , MySQL 1\driver=QMYSQL ; 1\host=localhost ; 1\name=db1 ; 1\user=db1_user ; 1\password=lol ; 1\port=3306 ; - 1\max_count = 30 2\ident=db2conn 2\driver=QPSQL 2\host=localhost 2\name=test 2\user=postgres 2\password= 2\port=5432 2\max_count = 30
Application::Application(int& argc, char** argv): QCoreApplication(argc, argv) { ... QVariantMap stgs = settings(); DB::ConnectionManager::init(stgs); ... }
void ConnectionManager::init(const QVariantMap& settings) { const int size = settings.value("database/size").toInt(); for (int i = 1; i <= size; ++i) { const QString ident = settings.value(QString("database/%1/ident").arg(i), "default").toString(); ConnectionManager* inst = new ConnectionManager( ident, settings.value(QString("database/%1/driver").arg(i)).toString(), ... ); _instances[ident] = inst; Log::info(QString("ConnectionManager::init: [%1] [%2@%3:%4] ").arg(inst->_driver).arg(inst->_dbUser).arg(inst->_dbHost).arg(inst->_dbPort)); } }
Connection* ConnectionManager::getConnection() { Connection* conn = 0; int count = 0; while(count++ < MAX_RETRY_GET_CONN_COUNT) { pthread_t thread_id = pthread_self(); // , { QMutexLocker mlocker(&_mutex); for (int i = 0; i < _pool.size(); ++i) { conn = _pool.at(i); // if (conn && conn->threadID() == thread_id && conn->isValid()) { // conn->lock(); //Log::debug(QString("ConnectionManager::getConnection thread [%1])").arg(conn->name())); return conn; } } } // , { QMutexLocker mlocker(&_mutex); for (int i = 0; i < _pool.size(); ++i) { conn = _pool.at(i); if (conn && !conn->isLocked() && conn->isValid() ) { //Log::debug(QString("ConnectionManager::getConnection [%1])").arg(conn->name())); // conn->lock(); return conn; } } } // { QMutexLocker mlocker(&_mutex); if(_currentCount < _maxCount) { // // //try { conn = new Connection( QString("%1_%2").arg(_ident).arg(_currentCount), _driver, _dbHost, _dbName, _dbUser, _dbPassword,_dbPort ); _currentCount++; conn->lock(); _pool.append(conn); return conn; /*} catch(exc::Message& ex) { delete conn; throw ex; }*/ } else { // //Log::warn(" - [%d] DB [%d]",_maxCount,count); /*for (int i = 0; i < _pool.size(); ++i) { conn = _pool.at(i); if (!conn->isValid() && !conn->isLocked() ) { removeConnection(conn); break; } }*/ } } // , // sleep(2); } Log::crit(" %d ",MAX_RETRY_GET_CONN_COUNT); { QMutexLocker mlocker(&_mutex); for (int i = 0; i < _pool.size(); ++i) { conn = _pool.at(i); if (!conn->isValid() && !conn->isLocked()) { removeConnection(conn); break; } } } throw exc::Message(" "); //return 0; }
QList<QVariant> Bank::banksByAccountNumber(const QString& accountNumber) { QList<QVariant> res; DB::ManagedConnection conn; foreach(const QVariant& row, conn->fetchAll( "SELECT `real` as state ,namen as name,namep as full_name," "newnum as bik,ksnp as korr_acc,okpo as okpo,nnp as city," "ind as zip, adr as address,regn as regnum, telef as phones FROM `bankdinfo` WHERE `real` = '' ORDER BY RAND()" )) { if(isBelongToBank((row.toMap()["bik"]).toString(),accountNumber)) { res.append(row); } } Log::debug("Banks found %d",res.size()); return res; }
bool Connection::tryRetry(const QSqlError& err) { // bool needRecon = false; QRegExp mrx("MySQL server has gone away"); if (err.type() == QSqlError::NoError && qstrcmp(_conn.driver()->handle().typeName(), "PGconn*") == 0) { needRecon = true; } else if ( /*(qstrcmp(_conn.driver()->handle().typeName(), "MYSQL*") == 0)*/ err.text().contains(mrx)) { needRecon = true; } bool ok = false; if (needRecon) { Log::err( " - GONE AWAY. ..."); bool lol = true; while(lol) { if (_retryCount >= MAX_RETRY_COUNT) { _retryCount = 0; _invalid = true; Log::crit( " ."); throw exc::Message(" "); } lol = !reconnect(); if(!lol) { ok = true; _retryCount = 0; break; } _retryCount++; sleep(2); } } //_retryCount return ok; } void Connection::query(QSqlQuery& sql, QList<QVariant>& result) { if (!sql.exec()) { if (tryRetry(sql.lastError())) { if(isValid()) { QSqlQuery qs = createQuery(); cpQuery(sql, qs); Log::warn(" ..."); return query(qs, result); } else { throw exc::Message(" ");; } } else throw exc::Sql(sql); } ... }
Source: https://habr.com/ru/post/164377/
All Articles