Перейти до основного вмісту

Розрив з'єднання з віддаленою базою MySQL

У мене є проект treeShop, який працює з базами даних електронних магазинів. У цьому проекті спочатку я вирішив використовувати постійне подлюченіе, і тільки потім, коли мені знадобилося зберігати інші дані я вирішив зробити модуль синхронізації. Як і багато web-майстрів, роботу програми я тестую на локальному веб сервері. Я прихильник Linux'а тому використовую збірку сервера XAMPP. Версія мого qt 5.2.1. Насправді версія не важлива, саме цю я взяв тому, що мені потрібен був webkit.

Підключення до бази просте:

QSqlDatabase db;
db = QSqlDatabase :: addDatabase ( "QMYSQL");
db.setHostName ( "hostName");
db.setDatabaseName ( "databaseName");
db.setPort (3306);
db.setUserName ( "userName");
db.setPassword ( "userPass");
db.open ();

За великим рахунком цього достатньо, і в тестах прога працює стабільно. Але ж я націлений на віддалене підключення. Крім власне самих налаштувань для з'єднання і користувача з відповідними правами, хостер повинен надавати послуги віддаленого підключення. Для її відкриття служба підтримки зазвичай просить ваш зовнішній ip, для внесення його до списку довірених.

Перші враження від роботи з віддаленою БД - ніякої різниці з локальною. Невеличкі гальма при додаванні записів, але це цілком очікувано. Однак при роботі з програмою, паузи неминучі (на введення даних, на аналіз виводу, на "відійти налити кави" і т.д.) і в цей момент відбувається розрив. Ви повертаєтеся до роботи, натискаєте оновити дані, а з'єднання немає (.

В налаштуваннях БД є параметри Timeout Setting.

На локальному все це діло було відключено, тому в тестах таких проблем не виникало (навіть коли я їх повключав, розриви виникали через раз). Як варіант вирішення проблеми - можна збільшити період, скажімо поставити не 10 сек, а 300 або більше. Я цей метод не прийняв зразу, так як націлений на роботу з "чужою" базою, настройки якої мені не доступні.

Я вирішив, що перемогти це потрібно засобами qt. Цікаво, якщо запитати у qt, чи є в момент розриву з'єднання:

qDebug () << db.isOpen ();

він бреше у відповість:

true

Перше рішення, було абсолютно тупе, але працювало. Фактично, я примусово робив reconnect при кожному зверненні до БД.

void myClass :: reconnect () {
db.close ();
db.open ();
}

І цю функцію довелося натикати по всьому коду - тупе рішення.

"Не тупе" рішення прийшло після прочитання доків qt по драйверам для баз даних. Виявляється для різних баз є корисні опції. Мені допомогла MYSQL_OPT_RECONNECT.

Прописавши одного разу ось таке:

db.setConnectOptions ( "MYSQL_OPT_RECONNECT = TRUE;");

перед стрічкою

db.open ();

цілком достатньо, і не потрібна купа безглуздих функцій.

Коментарі

Популярні дописи з цього блогу

Qt та Excel. Робота з ячейками.

Для доступу до всіх властивостей і вмісту ячійок у Excel використовуються два об'єкти Range і Cells. Між ними є тільки одна відмінність (крім назви) - перший об'єкт забезпечує доступ до області ячійок та його аргументом є строка. QAxObject *myRange; myRange = sheetAct->querySubObject("Range (QVariant)", "A1:D3"); myRange->dynamicCall("Select()"); / / виділяємо діапазон ячійок Cells забезпечує доступ тільки до однієї ячійки і аргументом є номер рядка і стовпця. Таким чином запис виду: QAxObject *myRange; myRange = sheetAct->querySubObject("Range(QVariant)", "A2"); і QAxObject *myCells; myCells = sheetAct->querySubObject("Cells (Int, Int)", 1, 2); є рівнозначною. Щоб визначити реальну адресу ячійки або діапазону ячійок можна скористатися властивістю Address, яке має наступні параметри: RowAbsolute, ColumnAbsolute, ReferenceStyle, External, RelativeTo. myRange = sheetAct->querySubObject(...

QString в HEX и обратно

Спочатку з QString робимо QByteArray. Зауважимо, якщо у вас по тексту тільки латинські букви цілком підійде варіант з .toUtf8(). Якщо ж присутня і кирилиця - обов'язково використовуємо .toLocal8Bit(). QString strA = "Some text"; QByteArray bA = strA.toLocal8Bit().toHex(); Перетворення QByteArray в початковий текст має такий вигляд: QString strB = QString::fromLocal8Bit(QByteArray::fromHex(bA))); Цікаво, що якщо ми для зберігання записали отриманий Нех куди-небудь, наприклад, в файл або базу даних у вигляді текстового рядка, то для зворотного перетворення цей рядок потрібно додатково перетворити в QByteArray. QString strA2 = QString::fromUtf8(bA); QByteArray bB = strA2.toUtf8(); QString strB = QString::fromLocal8Bit(QByteArray::fromHex(bB)));

Qt Округлення до певного розряду

Округлення - тривіальна задача в математиці, але в Qt немає функції округлення до певного розряду. Проте в QtMath є такі функції як qFloor (qreal) і QCeil (qreal), в результаті яких int. А також можна використовуючи round (double), отримати double. Дуже швидко я знайшов ось цей ресурс звідки взяв вихідну формулу. Вона без сумніву працює, але дає результати, які не відповідаю моїм очікуванням: toRound(187.156, 2); //187.15 toRound(187.156, 1); //187.1 toRound(187.156, 0); //187 toRound(187.156, -1); //180 toRound(187.156, -2); //100 Після невеликої корекції самої функції, її підсумковий варіант виглядає так: double wcsv::toRound(double val, int r) {   double outpValue;   double tempVal;   tempVal=val*pow(10,r);   if (double(int(tempVal))+0.5==tempVal){     int(tempVal)%2 == 0       ? outpValue=double(qFloor(tempVal))/pow(10,r)       :outpValue=d...