Russian Qt Forum

Qt => Базы данных => Тема начата: QuAzI от Ноябрь 28, 2011, 00:29



Название: Старый баян про закрытие базы
Отправлено: QuAzI от Ноябрь 28, 2011, 00:29
Нужно работать с базой MySQL, использую генератор отчётов ncReport2 (почему-то пока не задал имя подключения отличное от дефолтного, ncReport отказывался нормально выборку данных делать), соответственно надо указывать базу данных в параметрах каждого создаваемого QSqlQuery. Так же есть пачка дочерних окон, куда надо будет так же передавать db, чтобы в созданных там запросах вертеть отдельные таблицы. Нужно было сделать возможность перенастройки приложения (да и при закрытии этот варнинг бесит), получился такой вот код
Код:
        query->finish();
        delete query;
        db.close();

        qDebug() << "BeforeDelete" << db.connectionNames();
        db.removeDatabase(db.connectionName());
        qDebug() << "AfterDelete" << db.connectionNames();
в лог падает
Код:
BeforeDelete ("MYBASE") 
QSqlDatabasePrivate::removeDatabase: connection 'MYBASE' is still in use, all queries will cease to work.
AfterDelete ()
Т.е. видно, что подключение удалилось, но варнинг при этом всё равно вываливается. Почему? Как правильно его удалить?
Пробовал через QSqlDatabase::removeDatabase("MYBASE"), так при повторном подключении к базе (после перенастройки) пишет что одноименная база уже есть и будет заменена (т.е. удаление не происходит).


Название: Re: Старый баян про закрытие базы
Отправлено: LisandreL от Ноябрь 28, 2011, 06:23
Как-то так:
Код
C++ (Qt)
       query->finish();
       delete query;
       db.close();
       QString connectionName = db.connectionName();
       db = QSqlDatabase();
       qDebug() << "BeforeDelete" << db.connectionNames();
       db.removeDatabase(connectionName);
       qDebug() << "AfterDelete" << db.connectionNames();


Название: Re: Старый баян про закрытие базы
Отправлено: QuAzI от Ноябрь 28, 2011, 14:46
В таком варианте при повторном добавлении пишет, что будет заменено уже существующее подключение. Т.е. реально база не освободилась и это чревато косяками.


Название: Re: Старый баян про закрытие базы
Отправлено: LisandreL от Ноябрь 28, 2011, 15:11
Новый код покажите. И вывод куДебагов.


Название: Re: Старый баян про закрытие базы
Отправлено: QuAzI от Ноябрь 28, 2011, 16:16
Я уже изуродовал код по хэндбуку:
Удалил QSqlDatabase db и вообще все QSql* из основной формы, теперь везде инициализирую так:
Код:
QSqlQuery query(QSqlDatabase::database("MYBASE"));
К счастью на главной форме нет таблиц постоянно работающих с базой и теперь удаление работает
Код:
    if (db_isOpened)
    {
        QSqlDatabase::removeDatabase("MYBASE");
        db_isOpened = false;
    }
Где переменная db_isOpened устанавливается в true если удалось подключиться к базе, типа глобальный флаг.
Не совсем красиво, больше писать при каждом вызове, но зато без лишней ругани.


Название: Re: Старый баян про закрытие базы
Отправлено: arhohryakov от Ноябрь 29, 2011, 03:11
Если интересно, у себя делал так. База является членом класса и создаётся в конструкторе. Есть две QSqlTableModel и два QSqlTableView. Сделал себе вот такой деструктор, чтобы база закрывалась без ругательств.

Код:

  delete modelView_2;
  delete modelView_1;
  delete model_2;
  delete model_1;

  db_.close();

  QSqlDatabase::removeDatabase(QString());
}

Т.к. база одна, то используется соединение по умолчанию, но не думаю, что с именованным соединением будет какая-то великая разница ;)