Russian Qt Forum

Программирование => Базы данных => Тема начата: deMax от Июнь 29, 2010, 15:48



Название: SQLite удаление БД [РЕШЕНО]
Отправлено: deMax от Июнь 29, 2010, 15:48
Доброго времени суток, не могу удалить файл с базой данных, т.к. он блокируется программой несмотря на закрытие БД. Файл удаляю чтобы очистить БД. ос windows, qt creator 1.3.1.


Название: Re: SQLite удаление БД
Отправлено: ecspertiza от Июнь 29, 2010, 15:49
как закрываешь БД ?

попробуй так

Код:
QSqlDatabase::removeDatabase(QSqlDatabase::connectionName());
QSqlDatabase::close();


Название: Re: SQLite удаление БД
Отправлено: break от Июнь 29, 2010, 19:47
Почитайте внимательно документацию сервера БД - в IB/FB например вообще нельзя делать никакие файловые операции над файлом БД пока сервер запущен! То есть потребуется его остановить не то что для удаления БД но и для корректного копирования - иначе может повредиться и исходная БД и копия будет битой. Но это от сервера зависит...


Название: Re: SQLite удаление БД
Отправлено: lit-uriy от Июнь 29, 2010, 21:27
>>в IB/FB например вообще нельзя делать никакие файловые операции над файлом БД пока сервер запущен
если быть более точным, пока есть множество соединений. При монопольном доступе можно хоть что делать.

Но тут речь о SQLite


Название: Re: SQLite удаление БД
Отправлено: deMax от Июнь 30, 2010, 08:19
как закрываешь БД ?

попробуй так

Код:
QSqlDatabase::removeDatabase(QSqlDatabase::connectionName());
QSqlDatabase::close();

закрываю вначале close, потом removeDatabase - если поставить remove перед close то он ругнется, что соединение открыто.
После этого пытаюсь удалить файл, тотал командер тоже файл не удаляет если поставить breakpoint после сих операций.
ps. а под linux все великолепно работает, а нужно именно под виндуз  :(


Название: Re: SQLite удаление БД
Отправлено: asvil от Июнь 30, 2010, 09:07
Сами тролли вот так делают в примерах:
Код:
 {
     QSqlDatabase db = QSqlDatabase::database("sales");
     QSqlQuery query("SELECT NAME, DOB FROM EMPLOYEES", db);
 }
 // Both "db" and "query" are destroyed because they are out of scope
 QSqlDatabase::removeDatabase("sales"); // correct

Поэтому предалагаю, сам не успел протестировать:
Код:
QSqlDatabase::close();
QSqlDatabase::~QSqlDatabase();
QSqlDatabase::removeDatabase();


Название: Re: SQLite удаление БД
Отправлено: Sahab от Июнь 30, 2010, 09:15
Код:
QSqlDatabase::close();
QSqlDatabase::~QSqlDatabase();
QSqlDatabase::removeDatabase();
 :o


Название: Re: SQLite удаление БД
Отправлено: break от Июнь 30, 2010, 13:22
Цитировать
Поэтому предалагаю, сам не успел протестировать:
Код:
Код:
QSqlDatabase::close();
QSqlDatabase::~QSqlDatabase();
QSqlDatabase::removeDatabase();

А почему просто не делать так как предлагают тролли и не только в примерах но и в документации? Принудительный вызов деструктора класса который еще в области видимости - это круть... если он объявлен на стеке то деструктор вызовется и второй раз! А QSqlDatabase это value-based класс (как они его сами называют) - то есть его надо именно на стеке объявлять в каждой функции где потребуется работать с БД и не устроит соединение по умолчанию - все это сделано для удобства, чтобь не протягивать через многочисленные функции указатель на QSqlDatabase. QSqlDatabase по определению - все экземпляры в разных функциях созданные к одному подключению меняют настройки только этого одного подключения - то есть сам по себе QSqlDatabase не БД а только класс управляющий подключением!!! С этим многие путаются в начале работы...


Название: Re: SQLite удаление БД
Отправлено: deMax от Июнь 30, 2010, 15:54
Цитировать
Поэтому предалагаю, сам не успел протестировать:
Код:
Код:
QSqlDatabase::close();
QSqlDatabase::~QSqlDatabase();
QSqlDatabase::removeDatabase();
Кто нибудь проверил? У меня файл под виндой нельзя удалить, хотя все эти команды у меня делаются. (Программа уже написана)


Название: Re: SQLite удаление БД
Отправлено: asvil от Июнь 30, 2010, 20:40
Под линуксом файлы можно удалять и с открытыми дескрипторами, поэтому видимо и под линуксом и виндовсом файл остается открытым, пока приложение работает.
Заглядываем в исходники Qt. Без изучения исходников Qt, на мой взгляд, приложение написать невозможно.
Итак видим:
Код:
void QSQLite2Driver::close()
{
    if (isOpen()) {
        sqlite_close(d->access);
        d->access = 0;
        setOpen(false);
        setOpenError(false);
    }
}
Ищем поисковым средством sqlite_close delete file. Находим:
http://osdir.com/ml/db.sqlite.general/2004-02/msg00257.html
Дословно: "хотите удалить? используйте :memory:"



Название: Re: SQLite удаление БД
Отправлено: deMax от Июль 02, 2010, 10:02
Ищем поисковым средством sqlite_close delete file. Находим:
http://osdir.com/ml/db.sqlite.general/2004-02/msg00257.html
Дословно: "хотите удалить? используйте :memory:"

Не совсем то что нужно, все данные которые пишутся в базу обязательно сохраняются. Очистка базы должна происходить при нажатии на кнопку а не при выходе из программы.


Название: Re: SQLite удаление БД
Отправлено: Sahab от Июль 02, 2010, 13:30
Код:
#include <QtCore/QCoreApplication>
#include <QSqlDatabase>
#include <QtDebug>
#include <QFile>
#include <QStringList>

void init() {
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("custom.db");
Q_ASSERT_X(db.open(), "init()","Can't open db");
qDebug() << "[init]\tSUCCES";
qDebug() << "[init]\t" << db.tables();
}

void close() {
QSqlDatabase db = QSqlDatabase::database();
db.close();
qDebug() << "[close]\tclose Invoked";
}

void remove_db() {
if(QFile::remove("custom.db"))
qDebug() << "[remove_db]\tSUCCES";
else
qDebug() << "[remove_db]\tFAILURE";
}

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
init();
remove_db();
close();
remove_db();
return a.exec();
}

все нормально работает...


Название: Re: SQLite удаление БД
Отправлено: asvil от Июль 02, 2010, 17:25
Не совсем то что нужно, все данные которые пишутся в базу обязательно сохраняются. Очистка базы должна происходить при нажатии на кнопку а не при выходе из программы.
Тогда:
Код:
QSqlQuery query(database);
foreach (QString table, QSqlDatabase::tables())
  query.exec(QString("TRUNCATE TABLE %1").arg(table));

foreach (QString table, QSqlDatabase::tables())
  query.exec(QString("DROP TABLE %1").arg(table));


Название: Re: SQLite удаление БД
Отправлено: niXman от Июль 02, 2010, 17:25
Цитировать
Под линуксом файлы можно удалять и с открытыми дескрипторами
пруфлинк пожалуйста.

Цитировать
Заглядываем в исходники Qt. Без изучения исходников Qt, на мой взгляд, приложение написать невозможно.
странно... "БД только для динамической памяти." ох негодные тролли, такую "каку" написали ;D

и вообще, нафига удалять файл БД?!


Название: Re: SQLite удаление БД
Отправлено: asvil от Июль 02, 2010, 20:01
пруфлинк пожалуйста.
Открываю видео файл в totem'е, удаляю его, totem проигрывает файл до конца. А я наверно неправильно выразился, файл помечается как удаляемый, а удаляется при закрытии последнего дескриптора, так?
и вообще, нафига удалять файл БД?!
deMax очистку решил произвести данным способом.


Название: Re: SQLite удаление БД
Отправлено: niXman от Июль 02, 2010, 22:00
Цитировать
Открываю видео файл в totem'е, удаляю его, totem проигрывает файл до конца
а я отключаю интернет, но в браузере страница прогорга продолжает торчать ;)


Название: Re: SQLite удаление БД
Отправлено: asvil от Июль 02, 2010, 22:11
Цитировать
Открываю видео файл в totem'е, удаляю его, totem проигрывает файл до конца
а я отключаю интернет, но в браузере страница прогорга продолжает торчать ;)
А я совсем не подумал о том, что можно загрузить весь файл в память.


Название: Re: SQLite удаление БД
Отправлено: deMax от Июль 05, 2010, 08:33
все нормально работает...


Спасибо, вопрос решил. просто query забыл удалить, в результате закрытия БД , файл все равно оставался блокированным.

ps. последний вопрос, что нажать по решенной теме? "заблокировать тему"?


Название: Re: SQLite удаление БД
Отправлено: Пантер от Июль 06, 2010, 06:40
Ничего нажимать не нужно. Отредактируй первый пост, дописав в теме "[РЕШЕНО]".