QSqlQuery PostgreSqlStorage::prepareAndExecuteQuery(const QString &queryname, const QString &paramstring, const QSqlDatabase &db)
{
    // Query preparing is done lazily. That means that instead of always checking if the query is already prepared
    // we just EXECUTE and catch the error
    QSqlQuery query;

    db.exec("SAVEPOINT quassel_prepare_query");
    if (paramstring.isNull()) {
        query = db.exec(QString("EXECUTE quassel_%1").arg(queryname));
    }
    else {
        query = db.exec(QString("EXECUTE quassel_%1 (%2)").arg(queryname).arg(paramstring));
    }

    if (db.lastError().isValid()) {
        // and once again: Qt leaves us without error codes so we either parse (language dependant(!)) strings
        // or we just guess the error. As we're only interested in unprepared queries, this will be our guess. :)
        db.exec("ROLLBACK TO SAVEPOINT quassel_prepare_query");
        QSqlQuery checkQuery = db.exec(QString("SELECT count(name) FROM pg_prepared_statements WHERE name = 'quassel_%1' AND from_sql = TRUE").arg(queryname.toLower()));
        checkQuery.first();
        if (checkQuery.value(0).toInt() == 0) {
            db.exec(QString("PREPARE quassel_%1 AS %2").arg(queryname).arg(queryString(queryname)));
            if (db.lastError().isValid()) {
                qWarning() << "PostgreSqlStorage::prepareQuery(): unable to prepare query:" << queryname << "AS" << queryString(queryname);
                qWarning() << "  Error:" << db.lastError().text();
                return QSqlQuery(db);
            }
        }
        // we alwas execute the query again, even if the query was already prepared.
        // this ensures, that the error is properly propagated to the calling function
        // (otherwise the last call would be the testing select to pg_prepared_statements
        // which always gives a proper result and the error would be lost)
        if (paramstring.isNull()) {
            query = db.exec(QString("EXECUTE quassel_%1").arg(queryname));
        }
        else {
            query = db.exec(QString("EXECUTE quassel_%1 (%2)").arg(queryname).arg(paramstring));
        }
    }
    else {
        // only release the SAVEPOINT
        db.exec("RELEASE SAVEPOINT quassel_prepare_query");
    }
    return query;
}
QSqlQuery PostgreSqlStorage::prepareAndExecuteQuery(const QString &queryname, const QString &paramstring, const QSqlDatabase &db)
{
     
     
    QSqlQuery query;

    db.exec("SAVEPOINT quassel_prepare_query");
    if (paramstring.isNull()) {
        query = db.exec(QString("EXECUTE quassel_%1").arg(queryname));
    }
    else {
        query = db.exec(QString("EXECUTE quassel_%1 (%2)").arg(queryname).arg(paramstring));
    }

    if (db.lastError().isValid()) {
         
         
        db.exec("ROLLBACK TO SAVEPOINT quassel_prepare_query");
        QSqlQuery checkQuery = db.exec(QString("SELECT count(name) FROM pg_prepared_statements WHERE name = 'quassel_%1' AND from_sql = TRUE").arg(queryname.toLower()));
        checkQuery.first();
        if (checkQuery.value(0).toInt() == 0) {
            db.exec(QString("PREPARE quassel_%1 AS %2").arg(queryname).arg(queryString(queryname)));
            if (db.lastError().isValid()) {
                qWarning() << "PostgreSqlStorage::prepareQuery(): unable to prepare query:" << queryname << "AS" << queryString(queryname);
                qWarning() << "  Error:" << db.lastError().text();
                return QSqlQuery(db);
            }
        }
         
         
         
         
        if (paramstring.isNull()) {
            query = db.exec(QString("EXECUTE quassel_%1").arg(queryname));
        }
        else {
            query = db.exec(QString("EXECUTE quassel_%1 (%2)").arg(queryname).arg(paramstring));
        }
    }
    else {
         
        db.exec("RELEASE SAVEPOINT quassel_prepare_query");
    }
    return query;
}