crossplatform.ru

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

3 страниц V  < 1 2 3 >  
Ответить в данную темуНачать новую тему
> Некорректное закрытие QSqlDatabase, при использовании QSqlTableModel
acen83
  опции профиля:
сообщение 6.8.2008, 18:41
Сообщение #11


Студент
*

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

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




Репутация:   0  


Цитата(silver @ 6.8.2008, 15:43) *
Скорее всего, у тебя остаются висеть незакрытые запросы

Remove database у меня есть, но он закрывает только ругательства о незакрытых запросах, а сообщения о закрытии старой БД все равно остаются :unsure:

Плохо что нет какой-нибудь функции наподобие clear() и соответственно isNull(), для того чтобы определять была инициализирована база или нет. Так получить базу через QSqlDatabase::database() конечно можно, но как проверить была она уже настроена или нет :huh:
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 6.8.2008, 19:19
Сообщение #12


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

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




Репутация:   94  


во-первых, в программе работай по порядку, и давай имена соединениям. И по этим именам обращайся к соединению.
во-вторых, в Qt'ях работа идет с именоваными соединениями,
Цитата
Используйте contains(), чтобы видеть если заданное имя соединения в списке соединений

если нет то надо создать, а вообще удалять соединение, все-таки нужды нет.

Цитата(acen83 @ 6.8.2008, 22:41) *
функции наподобие clear() и соответственно isNull()

что должны были бы делать эти функции, еслиб они были?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
acen83
  опции профиля:
сообщение 6.8.2008, 19:51
Сообщение #13


Студент
*

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

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




Репутация:   0  


2 Litkevich Yuriy:

clear() - возвращало бы все в начальное состояние, как при запуске программы.

Дело в том что после QSqlDatabase::removeDatabase("qt_default_connection_что_то_типа_этого") в списке соединений ничего нет. Т.е. базу мы закрыли, удалили соединение, а при запуске новой базы ругательство все равно остается - непорядок.

У меня при нажатии на кнопку происходит инициализация БД, настройка БД, выполнение запросов, закрытие всего этого хозяйства. Получается в разных частях программы надо создавать именованные соединения, причем вынесенные в конструктор? че то некрасиво как то, тем более вероятность нажатия кнопки - 1 к 100.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 7.8.2008, 0:09
Сообщение #14


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

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




Репутация:   94  


у меня в классе главного окна создается экземпляр "одиночки", а внем соединение с БД настроек приложения (это я так решил вместо всяких ини-конфигов сделать). далее после конструктора, т.е. после того как окно программы отобразится создается соединение основной БД.
исходник

MainWindow::MainWindow()
{
    mdiArea = new QMdiArea;
    setCentralWidget(mdiArea);
    connect(mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow *)), this, SLOT(updateMenus()));
    
    windowMapper = new QSignalMapper(this);
    connect(windowMapper, SIGNAL(mapped(QWidget *)), this, SLOT(setActiveSubWindow(QWidget *)));

    createActions();    // Создаем действия
    createMenus();        // Создаем меню
    createToolBars();    // Создаем панель инструментов
    createStatusBar();    // Создаем панель статуса
    readWindowSettings();// Читаем настройки окна
    // Создаем экземпляр класса сесии
    auth = Session::InitInstance();    

    
    connect(this, SIGNAL(SigShow()), SLOT(SlotOnShow()));
    
    
}

MainWindow::~MainWindow()
{
    auth->FreeInstance();
}

bool MainWindow::event(QEvent *p_event)
{
    if( p_event->type() == QEvent::ShowToParent)
        emit SigShow();

    return QWidget::event(p_event);
}

/*=====================================================================
                Постинициализация
  ===================================================================*/
void MainWindow::SlotOnShow()
{
  QString    errmsg;
  QString    title = tr("Ошибка программы");

qDebug() << "SlotOnShow: " << QDateTime::currentDateTime() << "\n\r";
  
    // Вход от имени анонимного пользователя
    auth->LoginAnonymous();
    
    // Обновляем меню
    updateMenus();
    
    // Проверяем все ли хорошо с настройками
    if (!auth->isGood(errmsg))
    {
        QMessageBox::critical(this, title, tr("Ошибка настроек, обратитесь к специалисту. Сообщение: \n\r") + errmsg);
        return;
    }
    
    // Здесь проверяется и устанавливается соединение с БД.
  bool ok;
  QSqlDatabase app_db = QSqlDatabase::database("appdb");    // создано в Session::InitInstance();
  QSqlQuery query(app_db);
  QString    querystr;
  QString    qerr;
  
  QString    db_driver;
  QString    db_name;
  QString    db_user_name;
  QString    db_user_paswd;
  
  
    querystr="SELECT F_VALUE FROM APPSETTINGS \
    WHERE ((F_TYPE='db_driver') OR (F_TYPE='db_name') OR \
    (F_TYPE='db_user_name') OR (F_TYPE='db_user_paswd')) \
    ORDER BY F_TYPE ASC";
    ok = query.exec(querystr);
qDebug() << "select DB settings - " << ok << "\n\r";
    
    if (!ok)
    {
        qerr = query.lastError().text();
        QMessageBox::critical(0, title,
                                 tr("Невозможно прочитать настройки БД.\n\r Причина: ")+qerr,
                                QMessageBox::Ok);
    }
    
    query.first();
    if (!query.isValid())
    {
        qerr = query.lastError().text();
        QMessageBox::critical(0, title,
                                 tr("Невозможно прочитать настройки БД.\n\r Причина: ")+qerr,
                                QMessageBox::Ok);
    }
    
    db_driver = query.value(0).toString();
    query.next();
    db_name = query.value(0).toString();
    query.next();
    db_user_name = query.value(0).toString();
    query.next();
    db_user_paswd = query.value(0).toString();
    
    db_main = QSqlDatabase::addDatabase(db_driver,"maindb");
    db_main.setDatabaseName(db_name);
    db_main.setUserName(db_user_name);
    db_main.setPassword(db_user_paswd);
qDebug() << "db_main.open: " << QDateTime::currentDateTime() << "\n\r";
    ok = db_main.open();
    
    if (!ok)
    {
        qerr = db_main.lastError().text();
        QMessageBox::critical(0, title,
                                 QObject::tr("Невозможно установить соединение c БД.\n\r")+qerr,
                                QMessageBox::Ok);
    }
qDebug() << "db_main.open: " << QDateTime::currentDateTime() << "\n\r";
qDebug() << db_main << "\n\r";
}

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Tonal
  опции профиля:
сообщение 7.8.2008, 7:47
Сообщение #15


Активный участник
***

Группа: Участник
Сообщений: 452
Регистрация: 6.12.2007
Из: Новосибирск
Пользователь №: 34

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




Репутация:   17  


2 Litkevich Yuriy
Нет нужды делать соединение с БД одиночкой, т.к. оно само только удобный интерфейс к реальному соединению, которое уже одиночка.
Вроде с тобой же обсуждали в "переводах" значение value type в данном контексте. :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 7.8.2008, 8:33
Сообщение #16


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

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




Репутация:   94  


Цитата(Litkevich Yuriy @ 7.8.2008, 4:09) *
у меня в классе главного окна создается экземпляр "одиночки"

Да, надо было полнее прокоментировать. Это у меня для авторизации пользователей программы, но там же и соединение с БД хранящих настройки пользователей.

А соединение с основной БД так:
Цитата(Litkevich Yuriy @ 7.8.2008, 4:09) *
далее после конструктора, т.е. после того как окно программы отобразится создается соединение основной БД.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
silver
  опции профиля:
сообщение 7.8.2008, 16:01
Сообщение #17


Новичок


Группа: Новичок
Сообщений: 8
Регистрация: 4.8.2008
Из: Харьков
Пользователь №: 250

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




Репутация:   0  


Цитата(acen83 @ 6.8.2008, 18:41) *
Remove database у меня есть, но он закрывает только ругательства о незакрытых запросах, а сообщения о закрытии старой БД все равно остаются :unsure:

Может я чего-то пропустил? Что ещё за сообщение о закрытии старой БД? В первом посте ты указал только одно сообщение: о том, что на момент закрытия соединения остались запросы, которые это соединение используют.

Цитата(acen83 @ 6.8.2008, 18:41) *
Плохо что нет какой-нибудь функции наподобие clear() и соответственно isNull(), для того чтобы определять была инициализирована база или нет. Так получить базу через QSqlDatabase::database() конечно можно, но как проверить была она уже настроена или нет :huh:


Есть функции QSqlDatabase::isOpen() и QSqlDatabase::isValid(), которые именно это и делают.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 7.8.2008, 16:23
Сообщение #18


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

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




Репутация:   94  


Цитата(silver @ 7.8.2008, 20:01) *
Что ещё за сообщение о закрытии старой БД?

да он дважды одно и тоже соединение создает:
Цитата(acen83 @ 6.8.2008, 12:28) *
QSqlDataBase* bd=QSqlDataBase::addConnection("QMYSQL");
// настройка базы, логина и т.п.
bd->open();
// запросы
bd->close();

затем в другом месте программы повторяя этот код появляется предупреждение

QSqlDatabasePrivate::removeDatabase: connection 'qt_sql_default_connection' is still in use, all queries will cease to work.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
acen83
  опции профиля:
сообщение 7.8.2008, 18:45
Сообщение #19


Студент
*

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

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




Репутация:   0  


Цитата(silver @ 7.8.2008, 17:01) *
Есть функции QSqlDatabase::isOpen() и QSqlDatabase::isValid(), которые именно это и делают.


Так чтоли?

QSqlDatabase db=QSqlDatabase::database();
if (!db.isValid())
{
db.addConnection("QMYSQL");
// добавление логинов, пассов и т.п.
}
return db;

Сообщение отредактировал acen83 - 7.8.2008, 18:47
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
silver
  опции профиля:
сообщение 8.8.2008, 22:33
Сообщение #20


Новичок


Группа: Новичок
Сообщений: 8
Регистрация: 4.8.2008
Из: Харьков
Пользователь №: 250

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




Репутация:   0  


Цитата(acen83 @ 7.8.2008, 18:45) *
Так чтоли?


Ну, как один из вариантов:
    QSqlDatabase db = QSqlDatabase::database("my_very_rarely_used_db");
    if (!db.isValid()) {
            // выполнится только в первый раз, когда соединения ещё нет
        db = QSqlDatabase::addDatabase("QMYSQL", "my_very_rarely_used_db");
        // Заполняем параметры соединения
    }
    db.open();
    // работаем
    db.close();
    // всё, никаких removeDatabase() делать не надо


Хотя я бы всё-таки создал именованное соединение в конструкторе, и не открывал его. Эта операция практически не займёт ни времени, ни ресурсов. Зато когда БД понадобится, можно сразу открывать её и работать, без всяких дополнительных проверок.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

3 страниц V  < 1 2 3 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


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




RSS Текстовая версия Сейчас: 23.4.2024, 13:00