PDA

View Full Version : [QSQLITE] QT's database drivers having a strange affliction of tourettes



skruffynerherder
24th February 2013, 01:30
Alright, problems continuing from a previous thread, where I managed to solve the problem but now the driver is giving me headaches again (previous thread: http://www.qtcentre.org/threads/53421-SOLVED-QSQLLITE-Problem-retrieving-records).

So I have a bunch of functions doing some querying, mainly select statements. This function works fine:



QHash<QString, int> DataWhisperer::getShipTypeNumbers(QString reportKey) {
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(pathToApp+"/data/scanbuddy.s3db");

if (!db.open()) {
errorCode = 511;
error = true;
errorMessage = "Could not open database";
}



QStringList groups;
QHash<QString, int> shipGroups;
QSqlQuery groupQuery(db);
groupQuery.prepare("SELECT shiptypes.name FROM shiptypes "
"INNER JOIN ships ON shiptypes.id = ships.shiptype "
"INNER JOIN reports ON ships.id = reports.ship "
"INNER JOIN posts ON posts.id = reports.postid "
"WHERE posts.stamp = :thestamp");
groupQuery.bindValue(":thestamp",reportKey);
if (!groupQuery.exec() && !error) {
errorCode = 511;
error = true;
errorMessage = groupQuery.lastError().text();
} else {
while (groupQuery.next()) {
groups.append(groupQuery.value(0).toString());
}
}
db.close();

for (int i = 0; i < groups.count(); i++) {
shipGroups[groups.at(i)] = shipGroups[groups.at(i)] + 1;
}

return shipGroups;
}


While this function, almost identical, just different SQL select statement (the select statement works fine btw when ran directly on the database through SQlite administrator) fails horribly:



QHash<QString, int> DataWhisperer::getShips(QString reportKey) {
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(pathToApp+"/data/scanbuddy.s3db");

if (!db.open()) {
errorCode = 513;
error = true;
errorMessage = "Could not open database";
} else {
std::cout <<"<h2>FOR SOME WEIRD REASON THE DATABASE IS NOW OPEN FOR BUSINESS !! </h2>";
}


QHash<int, QString> shipList = getShipList();
QHash<QString, int> ships;
QHash<int, int> report;
bool prep2 = db.isOpen(); // Here it returns false, the database is no longer open
QSqlQuery groupQuery(db);
bool prep = groupQuery.prepare("SELECT ship, amount FROM reports "
"INNER JOIN posts ON posts.id = reports.postid "
"WHERE posts.stamp = :thestamp");
groupQuery.bindValue(":thestamp",reportKey);
if (!groupQuery.exec() && !error) {
errorCode = 513;
error = true;
errorMessage = groupQuery.lastError().text();
} else {
while (groupQuery.next()) {
report.insert(groupQuery.value(0).toInt(), groupQuery.value(1).toInt());
}
}
db.close();
if(error)
std::cout <<errorMessage.toStdString() <<" " <<std::boolalpha <<prep <<" " <<prep2 <<" " <<db.lastError().text().toStdString() <<"<br />"; //See output

std::cout <<reportKey.toStdString();
QHashIterator<int, int> x(report);
QHashIterator<int, QString> i(shipList);
while (i.hasNext()) {
i.next();
while(x.hasNext()) {
x.next();
if (i.key() == x.key()) {
ships.insert(i.value(), x.value());
}
}
}

return ships;
}


Output from DataWhisperer::getShipTypeNumbers():


FOR SOME WEIRD REASON THE DATABASE IS NOW OPEN FOR BUSINESS !!

No query Unable to fetch row false false Driver not loaded Driver not loaded

:confused: :confused: Can someone please, for the love of god shed some light on the situation :confused: :confused:

norobro
24th February 2013, 03:23
Are you closing the db in getShipList()?

skruffynerherder
24th February 2013, 03:52
Yes, db.close(); is called in getShipList

Added after 8 minutes:

Alright, you didn't provide a solution but you did put me on the right track it seems. getShipList() triggers the behaviour, if I comment that out the database driver doesn't throw the kitchen sink at me and behaves. It doesn't like to have two connections open at the same time, it seems. So I have to move/copy the code from getShipList() to getShips() and I think I am set. Going to update the thread if it resolves the issue.

norobro
24th February 2013, 04:20
Consider opening the database as the default connection. See the docs here (http://qt-project.org/doc/qt-5.0/qtsql/qsqldatabase.html#details). Also take a look at the Qt sql examples.

You can open your database once as the default connection, run all of your queries and close the database when you are finished.