PDA

View Full Version : bad mySQL host freezes app on connection



Frozenjim
12th October 2008, 20:38
My little test app connects just fine to a valid database.

If I change the variables so that I am connecting to "microsoft.com" (for example), I get the expected error message.

If I connect to a valid host with invalid credentials, I get the expected error.

But when I connect to some mySQL databases, my app just freezes while waiting for the connection. No message is ever returned because the app just freezes entirely - forever.

Is there any way to timeout the db.open() or db.isvalid()? Or is there some way to use processevents() to decide that it's time to terminate the attempt?


bool MainWindowImpl::createConnection()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("microsoft.com");
db.setDatabaseName("thedata");
db.setUserName("bill");
db.setPassword("billybob");

if (!db.isValid()){
QMessageBox::critical(0,QObject::tr("Database is not valid"),"I can't open the damned thing.");
return false;
}
else{
if (!db.open()) {
QMessageBox::critical(0, QObject::tr("Database Error"),db.lastError().text());
return false;
}
QMessageBox::information(0, QObject::tr("Database Opened Just Fine"),"apparently the username/password was valid");
return true;
}
}

vfernandez
13th October 2008, 00:13
It's better to perform database operations in another thread so that the GUI doesn't freeze while connecting or performing queries. That also gives you the chance to abort the thread if the user wants to abort the operation and the server doesn't answer.

If you do so, just remember one very important thing: don't use QtSql classes in different threads but only in the same thread. Otherwise you might get unexpected crashes due to some database engines not being thread-safe.

Anyway, answering your question, some database engines allow you to specify the timeout. Take a look at QSqlDatabase::setConnectOptions() (http://doc.trolltech.com/4.4/qsqldatabase.html#setConnectOptions):


ODBC: QL_ATTR_CONNECTION_TIMEOUT
PostgreSQL: connect_timeout
DB2: SQL_ATTR_LOGIN_TIMEOUT

Frozenjim
13th October 2008, 02:22
Yeah, I was sort of afraid that the answer was threads. I am not an inexperienced developer, but I am brand new to C++ and QT in particular.

OK. I'll make threads my next priority. I knew I'd have to go there sometime - might as well be tonight.

I am quite surprised to see that mySQL doesn't have a connection_timeout option like Postgress.

vfernandez
13th October 2008, 08:37
I am quite surprised to see that mySQL doesn't have a connection_timeout option like Postgress.

Well, it's not the only thing it doesn't have, that's why we switched to PostgreSQL as our main DBMS. What I miss the most are notifications. They are very useful to let your application be aware of database changes without needing to poll. Qt supports them very well since 4.4.

vfernandez
13th October 2008, 08:39
About using threads for the database I suggest you to run the Qt loop in a thread using exec() and just create slots that perform the different queries, using queued connections. That way you don't need to use wait conditions, you can connect signals to slots in your thread and you can receive database notifications if the database driver supports them.