crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> незакрывается подключение к БД после запросов
zloyGamer
  опции профиля:
сообщение 6.12.2009, 22:02
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 22
Регистрация: 18.7.2009
Пользователь №: 917

Спасибо сказали: 0 раз(а)




Репутация:   0  


подскажите как поправить, или что тут может быть не так, к примеру есть простая форма с вьюхой QSqlQueryModel m_model;

  QSqlDatabase::removeDatabase( "test" );
  QSqlDatabase db = QSqlDatabase::addDatabase( "QIBASE"  , "test" );
  db.setHostName( "127.0.0.1" );
  db.setPort( 3050 );
  db.setDatabaseName( "D:\\test.FDB" );
  db.setConnectOptions( "" );
  db.setUserName( "SYSDBA" );
  db.setPassword( "masterkey" );


далее если выполнить:
  db.open();  
  //...
  db.close();

то FB вначале выдает что было 1 соединение а потом 0

а если выполнить какието операции с бд:
  db.open();  
  QSqlQuery q("SELECT * FROM ui_table",db);
  m_model.setQuery(q);
  ui->view->setModel(&m_model);
  db.close();

то FB вначале выдает что было 1 соединение а после db.close(); всеравно остается 1 соединение, но из приложения уже нельзя выполнять запросы
а если далее опять вызвать db.open(); то FB выдает что уже установлено 2 соединения, и т.д.
все соединения обрываются тока после закрытия приложения, как это можно исправить?
что можно сделать чтобы соединение корректно закрывалось?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Kagami
  опции профиля:
сообщение 6.12.2009, 22:33
Сообщение #2


Старейший участник
****

Группа: Участник
Сообщений: 601
Регистрация: 2.2.2009
Пользователь №: 523

Спасибо сказали: 101 раз(а)




Репутация:   9  


У QSqlQuery есть метод finish(), у QSqlQueryModel есть метод query(), который возвращает хранящийся в этой модели объект QSqlQuery. Если у тебя есть запросы, которые не уничтожаются после выхода из функции (т.е. создаются динамически), то для них было бы неплохо вызывать метод finish().
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zloyGamer
  опции профиля:
сообщение 7.12.2009, 21:54
Сообщение #3


Студент
*

Группа: Участник
Сообщений: 22
Регистрация: 18.7.2009
Пользователь №: 917

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Kagami @ 6.12.2009, 22:33) *
У QSqlQuery есть метод finish(), у QSqlQueryModel есть метод query(), который возвращает хранящийся в этой модели объект QSqlQuery. Если у тебя есть запросы, которые не уничтожаются после выхода из функции (т.е. создаются динамически), то для них было бы неплохо вызывать метод finish().

ща проверил:
m_model.query().finish();
db.close();
db.removeDatabase("test");
тож самое получается, подключение(я) незакрываются, т.е. закрываются тока при закрытии самого приложения или в случае если небыло запросов после открытия бд.
что еще можно попробывать?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
MoPDoBoPoT
  опции профиля:
сообщение 7.12.2009, 22:19
Сообщение #4


Участник
**

Группа: Участник
Сообщений: 172
Регистрация: 7.5.2009
Из: Москва
Пользователь №: 738

Спасибо сказали: 44 раз(а)




Репутация:   9  


Попробовать сделать также, как в доке:
{
     QSqlDatabase db = QSqlDatabase::addDatabase( "QIBASE"  , "test" );
     db.setHostName( "127.0.0.1" );
     db.setPort( 3050 );
     db.setDatabaseName( "D:\\test.FDB" );
     db.setUserName( "SYSDBA" );
     db.setPassword( "masterkey" );
     db.open();  

     QSqlQuery q("SELECT * FROM ui_table",db);
     m_model.setQuery(q);
     ui->view->setModel(&m_model);
     db.close();
}
// "db" и "q" уничтожаются при выходе из блока
QSqlDatabase::removeDatabase("test");
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zloyGamer
  опции профиля:
сообщение 8.12.2009, 15:24
Сообщение #5


Студент
*

Группа: Участник
Сообщений: 22
Регистрация: 18.7.2009
Пользователь №: 917

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(MoPDoBoPoT @ 7.12.2009, 22:19) *
Попробовать сделать также, как в доке:
{
     QSqlDatabase db = QSqlDatabase::addDatabase( "QIBASE"  , "test" );
     db.setHostName( "127.0.0.1" );
     db.setPort( 3050 );
     db.setDatabaseName( "D:\\test.FDB" );
     db.setUserName( "SYSDBA" );
     db.setPassword( "masterkey" );
     db.open();  

     QSqlQuery q("SELECT * FROM ui_table",db);
     m_model.setQuery(q);
     ui->view->setModel(&m_model);
     db.close();
}
// "db" и "q" уничтожаются при выходе из блока
QSqlDatabase::removeDatabase("test");


пробывал, даже более, уничтожалась сама форма с m_model, но коннект всеравно оставался пока незакровалось само приложение
видимо дело гдето в статических функциях и переменных QSqlDatabas'а
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
MoPDoBoPoT
  опции профиля:
сообщение 8.12.2009, 15:54
Сообщение #6


Участник
**

Группа: Участник
Сообщений: 172
Регистрация: 7.5.2009
Из: Москва
Пользователь №: 738

Спасибо сказали: 44 раз(а)




Репутация:   9  


Дело скорей всего в драйвере, ибо у меня с Oracle закрывается соединение.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zloyGamer
  опции профиля:
сообщение 8.12.2009, 16:44
Сообщение #7


Студент
*

Группа: Участник
Сообщений: 22
Регистрация: 18.7.2009
Пользователь №: 917

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(MoPDoBoPoT @ 8.12.2009, 15:54) *
Дело скорей всего в драйвере, ибо у меня с Oracle закрывается соединение.

я тож так подумал, потому несколько раз пробывал пересобирать длл'ки qsqlibase4.dll и qsqlibased4.dll для FB2.0 и FB2.1 всеравно результат тотже,
ща думаю что дело в статических функциях и переменных QSqlDatabase, QSqlQuery или QSqlQueryModel, думаю что гдето там собака зарыта ))
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 8.12.2009, 17:25
Сообщение #8


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Можно посмотреть отладчиком, что тут происходит:

void QIBaseDriver::close()
{
    if (isOpen()) {

        if (d->eventBuffers.size()) {
            ISC_STATUS status[20];
            QMap<QString, QIBaseEventBuffer *>::const_iterator i;
            for (i = d->eventBuffers.constBegin(); i != d->eventBuffers.constEnd(); ++i) {
                QIBaseEventBuffer *eBuffer = i.value();
                eBuffer->subscriptionState = QIBaseEventBuffer::Finished;
                isc_cancel_events(status, &d->ibase, &eBuffer->eventId);
                qFreeEventBuffer(eBuffer);
            }
            d->eventBuffers.clear();

#if defined(FB_API_VER)
            // Workaround for Firebird crash
            QTime timer;
            timer.start();
            while (timer.elapsed() < 500)
                QCoreApplication::processEvents();
#endif
        }

        isc_detach_database(d->status, &d->ibase);
        d->ibase = 0;
        setOpen(false);
        setOpenError(false);
    }
}


Сообщение отредактировал SABROG - 8.12.2009, 17:27
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
zloyGamer
  опции профиля:
сообщение 9.12.2009, 20:06
Сообщение #9


Студент
*

Группа: Участник
Сообщений: 22
Регистрация: 18.7.2009
Пользователь №: 917

Спасибо сказали: 0 раз(а)




Репутация:   0  


да дествительно видимо что то не так идет в функции isc_detach_database,
ща проверил,
вот с этим вариантом нормально работает:
if(m_model!=0)
{
delete m_model; //раньше модель была не динамическая и ДОЛЖНА была уничтожаться вместе с классом формы, но видимо этого не происходило!
m_model = 0;
}

QSqlDatabase db = QSqlDatabase::database( "test" );
db.close();
db.removeDatabase("test");
_on__connect_refresh();

тоесть если явно вызывать delete или m_model->clear(); ДО закрытия бд - то все ок и закрывается,
иначе isc_detach_database возвращает значение != 0 ( уменя было ==335544357, я пока ненашел что это за ошибка но над будет както проверить передаваемые параметры)

получается надо уничтожить все модели перед тем как закрывать подключение..., хотя в доке явно прописано:
void QSqlDatabase::close ()
Closes the database connection, freeing any resources acquired, and invalidating any existing QSqlQuery objects that are used with the database.
This will also affect copies of this QSqlDatabase object.

и на основе этого я уже успел нагородить кучу говнокода,
оно так и должно работать(необходимо обязательно уничтожать или чистить все модели) или нет?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 19.4.2024, 8:54