Russian Qt Forum
Ноябрь 23, 2024, 11:59 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: query.lastError().isValid() не работает  (Прочитано 11275 раз)
GraninDm
Гость
« : Август 29, 2012, 14:55 »

Добрый день!

Решил я проверить что будет с программой, если во время ее работы погасить postgresql, с которым она работает.

Код банальный
Код:
query.exec("select ...");
queryError = query.lastError().isValid();
далее проверяется queryError


Запустил программу, погасил сервер, и получил queryError = false
Удивился, и переделал код

Код:
queryError = !query.exec("select ...");
queryError = queryError || query.lastError().isValid();

exec() установил queryError в true, а query.lastError().isValid() вернула false;

Хотя при подключенном сервере query.lastError().isValid() работало.

Я что-то упустил?
Записан
GraninDm
Гость
« Ответ #1 : Сентябрь 03, 2012, 14:54 »

Решил еще проверить...

qqqwwa = db->isValid();
qqqwwa = db->isOpen();

Вываливается Seg fault то на первой строке, то на второй.

Объясните мне, что я не так делаю?

Qt 4.7.4 32bit WinXP
Записан
andrew.k
Гость
« Ответ #2 : Сентябрь 03, 2012, 15:24 »

Решил еще проверить...

qqqwwa = db->isValid();
qqqwwa = db->isOpen();

Вываливается Seg fault то на первой строке, то на второй.

Объясните мне, что я не так делаю?
Решил проверить то же самое.
То на первой, то на второй строке Seg fault не вываливается.

Объясните мне, что я не так делаю?
Записан
GraninDm
Гость
« Ответ #3 : Сентябрь 03, 2012, 15:56 »

Ок.

Нашел http://www.sql.ru/forum/actualthread.aspx?tid=426962 вот это
Вот этот момент мне в QT очень не нравится, но увы. При объявлении объекта типа QSqlDatabase в любом месте кроме стека появлется большое количество очень странных глюков.

Объясните, почему нельзя ее создавать в куче?
Записан
andrew.k
Гость
« Ответ #4 : Сентябрь 03, 2012, 15:58 »

Объясните, почему нельзя ее создавать в куче?
А зачем её создавать в куче?
Записан
GraninDm
Гость
« Ответ #5 : Сентябрь 03, 2012, 16:03 »

Т.е. вот так в классе нельзя делать?

private:
    QSqlDatabase    *db;
Записан
andrew.k
Гость
« Ответ #6 : Сентябрь 03, 2012, 17:30 »

Т.е. вот так в классе нельзя делать?

private:
    QSqlDatabase    *db;
еще раз, зачем так делать?
Ты в любой момент можешь получить нужный экземпляр класса QSqlDataBase
Записан
andrew.k
Гость
« Ответ #7 : Сентябрь 03, 2012, 17:35 »

Нигде в QtSql не используется динамический экземпляр, зачем тебе это нужно?
Записан
GraninDm
Гость
« Ответ #8 : Сентябрь 03, 2012, 21:21 »

Спасибо, натолкнули на правильный путь.
Понял, что с самого начала неправильно сделал.

Буду переделывать.
Записан
GraninDm
Гость
« Ответ #9 : Сентябрь 04, 2012, 09:40 »

А по первому сообщению, может кто подскажет, как в моем случае получить код и текст ошибки?

сервер postgres погашен, но подключение к базе было установлено ранее
Код:
        QSqlDatabase db = QSqlDatabase::database();
        qqqwwa = db.isValid();                         qqqwwa = true;
        qqqwwa = db.isOpen();                        qqqwwa = true;  
        QSqlQuery query;
        query...
        queryError = !query.exec();                   queryError = true;
        queryError = query.lastError().isValid();    queryError = false;
        qDebug() <<  query.lastError();              QSqlError(-1, "", "")
        qqqwwa = db.isValid();                         qqqwwa = true;
        qqqwwa = db.isOpen();                         qqqwwa = true;


Посмотрел в исходниках qsqlquery и qsql_psql
Код:
  Note that the last error for this query is reset when exec() is
  called.

bool QSqlQuery::exec(const QString& query)
{
    if (d->ref != 1) {
        bool fo = isForwardOnly();
        *this = QSqlQuery(driver()->createResult());
        d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy());
        setForwardOnly(fo);
    } else {
        d->sqlResult->clear();
        d->sqlResult->setActive(false);
        d->sqlResult->setLastError(QSqlError());
        d->sqlResult->setAt(QSql::BeforeFirstRow);
        d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy());
    }
    d->sqlResult->setQuery(query.trimmed());
    if (!driver()->isOpen() || driver()->isOpenError()) {
        qWarning("QSqlQuery::exec: database not open");
        return false;
    }
    if (query.isEmpty()) {
        qWarning("QSqlQuery::exec: empty query");
        return false;
    }
#ifdef QT_DEBUG_SQL
    qDebug("\n QSqlQuery: %s", query.toLocal8Bit().constData());
#endif
    return d->sqlResult->reset(query);
}

bool QPSQLResult::reset (const QString& query)
{
    cleanup();
    if (!driver())
        return false;
    if (!driver()->isOpen() || driver()->isOpenError())
        return false;
    d->result = PQexec(d->driver->connection,
                       d->driver->isUtf8 ? query.toUtf8().constData()
                                         : query.toLocal8Bit().constData());
    return d->processResults();
}


bool QPSQLResultPrivate::processResults()
{
    if (!result)
        return false; Вот тут ошибка не обрабатывается?????

    int status = PQresultStatus(result);
    if (status == PGRES_TUPLES_OK) {
        q->setSelect(true);
        q->setActive(true);
        currentSize = PQntuples(result);
        return true;
    } else if (status == PGRES_COMMAND_OK) {
        q->setSelect(false);
        q->setActive(true);
        currentSize = -1;
        return true;
    }
    q->setLastError(qMakeError(QCoreApplication::translate("QPSQLResult",
                    "Unable to create query"), QSqlError::StatementError, driver));
    return false;
}
Т.е. получается, что проверяется только открыт драйвер и была ли при открытии ошибка
В противном случае ошибка сбрасывается
Так получается?
« Последнее редактирование: Сентябрь 04, 2012, 10:56 от GraninDm » Записан
GraninDm
Гость
« Ответ #10 : Сентябрь 04, 2012, 12:40 »

Короче, подправил драйвер psql

Код:
bool QPSQLResultPrivate::processResults()
{
    if (!result){
        q->setLastError(qMakeError(QCoreApplication::translate("QPSQLResult",
                        "Unable to execute query"), QSqlError::StatementError, driver));
       return false;
    }
...

Мой код
Код:
        queryError = !query.exec();
        queryError = query.lastError().isValid();
        qDebug() << queryError;
        qDebug() << query.lastError();

Так работает
Код:
Подключение установлено, сервер работает
false
QSqlError(-1, "", "")
Подключение установлено, сервер не работает
true
QSqlError(-1, "QPSQL: Unable to execute query", "no connection to the server
")

Может я не прав?

Добавил
Оказывается для mysql зарегистрирован bug
https://bugreports.qt-project.org/browse/QTBUG-4926
Для psql похоже то же самое.
« Последнее редактирование: Сентябрь 04, 2012, 14:07 от GraninDm » Записан
fte
Гость
« Ответ #11 : Сентябрь 04, 2012, 14:05 »

А что будет?
query("select 1 where 0!=0")
qDebug() << query.lastError().text();
Записан
GraninDm
Гость
« Ответ #12 : Сентябрь 04, 2012, 14:19 »

А что будет?
query("select 1 where 0!=0")
qDebug() << query.lastError().text();

Код:
QSqlQuery queryTemp("select 1 where 0!=0");
        qDebug() << queryTemp.lastError().isValid();
        qDebug() << queryTemp.lastError().text();

Драйвер с моими исправлениями

При работающем сервере
false
" "
При неработающем
true
"server closed the connection unexpectedly
   This probably means the server terminated abnormally
   before or while processing the request.

А вот так с родным соответственно
false
" "
false
" "
« Последнее редактирование: Сентябрь 04, 2012, 14:30 от GraninDm » Записан
andrew.k
Гость
« Ответ #13 : Сентябрь 04, 2012, 14:25 »

Выложил бы, что исправил в драйвере.
Вдруг кому пригодится.
Записан
GraninDm
Гость
« Ответ #14 : Сентябрь 04, 2012, 14:35 »

Так я же выложил
Было
Код:
bool QPSQLResultPrivate::processResults()
{
    if (!result)
       return false;
...

Стало
Код:
bool QPSQLResultPrivate::processResults()
{
    if (!result){
        q->setLastError(qMakeError(QCoreApplication::translate("QPSQLResult",
                        "Unable to execute query"), QSqlError::StatementError, driver));
       return false;
    }
...

Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.16 секунд. Запросов: 21.