Russian Qt Forum

Qt => Базы данных => Тема начата: daimon от Декабрь 05, 2009, 16:47



Название: БД для новичка. Помогите, нужно быстро разобратся
Отправлено: daimon от Декабрь 05, 2009, 16:47
Как удалить файл базы данных?
Код:
#include <QtGui>
#include <QtSql>
#include <QMessageBox>

static bool createConnection()
{
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("addressbook");

    db.setUserName("elton");
    db.setHostName("epica");
    db.setPassword("password");
    
//
    if( db.open())
{
if(db.tables().isEmpty())
{ QMessageBox::critical(0,QObject::tr("Database Error"), QString(db.lastError().text()));
}
if(db.tables().isEmpty())
{db.close();db.removeDatabase("addressbook");}

        return false;
    }

    return true;
}

// ----------------------------------------------------------------------
int main(int argc, char** argv)
{
    QApplication app(argc, argv);

    if (!createConnection()) {
        return -1;
    }

  /*  QTableView     view;
    QSqlTableModel model;

    model.setTable("addressbook");
    model.select();
    model.setEditStrategy(QSqlTableModel::OnFieldChange);
    
    view.setModel(&model);
    view.show();*/
    
    return app.exec();
}
файл не удаляется. Что делать?


Название: Re: БД для новичка
Отправлено: Alp от Декабрь 05, 2009, 17:16
Не увидел в коде ни одной строчки удаляющей ФАЙЛ, так что не удивительно, что он остается на диске.
Почувствуй разницу: удаление базы данных и удаление файла базы данных =)


Название: Re: БД для новичка
Отправлено: daimon от Декабрь 05, 2009, 17:26
Не увидел в коде ни одной строчки удаляющей ФАЙЛ, так что не удивительно, что он остается на диске.
Почувствуй разницу: удаление базы данных и удаление файла базы данных =)
Какая функция удаления файла? (наверное надо использовать QFile)


Название: Re: БД для новичка
Отправлено: daimon от Декабрь 05, 2009, 18:03
Код:
#include <QtGui>
#include <QtSql>
#include <QMessageBox>

static bool createConnection()
{
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("addressbook");

    db.setUserName("elton");
    db.setHostName("epica");
    db.setPassword("password");
   

if( db.isOpenError())
{
QMessageBox::critical(0,QObject::tr("Database Error"), QString(db.lastError().text()));

        return false;
    }

    return true;
}

// ----------------------------------------------------------------------
int main(int argc, char** argv)
{
    QApplication app(argc, argv);

    if (!createConnection()) {
        return -1;
    }

    QTableView     view;
    QSqlTableModel model;

    model.setTable("addressbook");
    model.select();
// model.setEditStrategy(QSqlTableModel::OnManualSubmit);
    model.setEditStrategy(QSqlTableModel::OnFieldChange);
model.insertRow(0);
model.setData(model.index(0,0),223213123);
model.submitAll();
    view.setModel(&model);
    view.show();
   
    return app.exec();
}
работает неправильно. Как исправить?


Название: Re: БД для новичка
Отправлено: lit-uriy от Декабрь 05, 2009, 18:13
>>работает неправильно.
что значит это утверждение? Копает совковой лопатой, а не штыковой?


Название: Re: БД для новичка
Отправлено: daimon от Декабрь 05, 2009, 18:14
>>работает неправильно.
что значит это утверждение? Копает совковой лопатой, а не штыковой?
Данные не записываются в базу (в файл) и в представлении фокусы начинаются.
Файл БД открывается пустой.


Название: Re: БД для новичка
Отправлено: break от Декабрь 05, 2009, 18:51
Цитировать
Не увидел в коде ни одной строчки удаляющей ФАЙЛ, так что не удивительно, что он остается на диске.
Почувствуй разницу: удаление базы данных и удаление файла базы данных =)

Сначала убедитесь что сервер разрешает работать с файлами БД напрямую, например IB/FB это не расрешает - можно удалить файл БД после выключения сервера. Или используйте соответствующую утилиту из набора вашей БД для IB - isql которая умеет создавать/удалять Базы...


Название: Re: БД для новичка
Отправлено: daimon от Декабрь 05, 2009, 19:01
Как с помоью модели заполнить базу данных (файл)
Код:
#include <QtGui>
#include <QtSql>
#include <QMessageBox>

static bool createConnection()
{
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("addressbook");

    db.setUserName("elton");
    db.setHostName("epica");
    db.setPassword("password");
    

if( db.isOpenError())
{
QMessageBox::critical(0,QObject::tr("Database Error"), QString(db.lastError().text()));

        return false;
    }

    return true;
}

// ----------------------------------------------------------------------
int main(int argc, char** argv)
{
    QApplication app(argc, argv);

    if (!createConnection()) {
        return -1;
    }

    QTableView     view;
    QSqlTableModel model;

    model.setTable("addressbook");
   model.select();
// model.setEditStrategy(QSqlTableModel::OnManualSubmit);
    model.setEditStrategy(QSqlTableModel::OnFieldChange);
model.insertRow(3);
model.setData(model.index(0,0),223213123);
model.submitAll();
    view.setModel(&model);
    view.show();
    
    return app.exec();
}


Такой код не работает. Обязательно использовать QSqlQuery?


Название: Re: БД для новичка
Отправлено: lit-uriy от Декабрь 05, 2009, 19:08
daimon, ты для начал БД открой (QSqlDatabase::open())

О работе с базой данных (через модель) смотри примеры, например:
%QTDIR%\examples\sql\cachedtable

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


Название: Re: БД для новичка
Отправлено: daimon от Декабрь 05, 2009, 19:18
daimon, ты для начал БД открой (QSqlDatabase::open())

О работе с базой данных (через модель) смотри примеры, например:
%QTDIR%\examples\sql\cachedtable
По примеру видно, что модель нужна только для отображения, а с базой работает QSqlQuery (insertRow не вставляет новую строку именно в Бд файл)
Код:
 QSqlQuery query;
    query.exec("create table person (id int primary key, "
               "firstname varchar(20), lastname varchar(20))");
    query.exec("insert into person values(101, 'Danny', 'Young')");
    query.exec("insert into person values(102, 'Christine', 'Holand')");
    query.exec("insert into person values(103, 'Lars', 'Gordon')");
    query.exec("insert into person values(104, 'Roberto', 'Robitaille')");
    query.exec("insert into person values(105, 'Maria', 'Papadopoulos')");
Можно создать БД, только с помощью модели (insertRow, setHeaderData...)? Зачем тогда в QSqlTableModel есть insertColumn, insertRow? Будьте добры помогите


Название: Re: БД для новичка. Помогите, нужно быстро разобратся
Отправлено: gmorgunov от Декабрь 05, 2009, 22:27
daimon
Для OnManualSubmit ---> submitAll().
Для OnRowChange   ---->  submit() 
        OnFieldChange   ----> submit()
Слоты надо вызывать явно.Слоты срабатывают при переходе на другую строку, и сразу происходит сортировка.
Доработанный пример из книги Шлее:
Код:
#include <QtGui>
#include <QtSql>

static bool createConnection()
{
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("addressbook");

    db.setUserName("elton");
    db.setHostName("epica");
    db.setPassword("password");
    if (!db.open()) {
        qDebug() << "Cannot open database:" << db.lastError();
        return false;
    }
    return true;
}

int main(int argc, char** argv)
{
    QApplication app(argc, argv);

    if (!createConnection()) {
        return -1;
    }

    QTableView     view;
    QSqlTableModel model;

    model.setTable("addressbook");
    model.select();
    model.setEditStrategy(QSqlTableModel::OnFieldChange); 
//!!!!!!!!!!!!!!!
    model.submit();
//!!!!!!!!!!!!!!
    view.setModel(&model);
    view.show();
   
    return app.exec();
В ассистанте это прописано, а вот в примере Шлее была ошибка, он не вызывал слот submit(). Сам сидел полчаса, пока не разобрался. :)


Название: Re: БД для новичка. Помогите, нужно быстро разобратся
Отправлено: lit-uriy от Декабрь 05, 2009, 22:53
>insertRow не вставляет новую строку именно в Бд файл
Логика работы более или менее нормальной БД: Осуществляются манипуляции с таблицами, затем делается:
либо подтверждение (фиксация) изменений - commit
либо откат - rollback

>модель нужна только для отображения
не верно
Модель - интерфейс к хранилищу данных (может содержать их и в себе, например, QStandardItemModel)
Представление - представление (отображение) данных из модели.

конкретно по примеру cachedtable, троли, для упрощения, сделали один файлик для нескольких примеров, который намолачивает данные в БД, а затем полученная БД используется для демонстрации работы с модулем QSql


Название: Re: БД для новичка. Помогите, нужно быстро разобратся
Отправлено: lit-uriy от Декабрь 05, 2009, 22:58
>>а вот в примере Шлее была ошибка, он не вызывал слот submit()
Чушь

>>model.submit();
что ты зафиксировал в БД этой строчкой?


Название: Re: БД для новичка. Помогите, нужно быстро разобратся
Отправлено: lit-uriy от Декабрь 05, 2009, 23:05
>>Зачем тогда в QSqlTableModel есть insertColumn, insertRow?
Чтобы вставить в модель строку/колонку, эти методы УНАСЛЕДОВАНЫ от QAbstractItemModel а она универсальна.

Скорее всего операция insertColumn/removeColumn не увенчается успехом при работе с БД.

Для insertRow: позволяет вставить строку в модель, но эти изменения висят в модели, затем нужно
либо их фиксировать (QSqlTableModel::submit (), QSqlTableModel::submitAll ())
либо откатывать (QSqlTableModel::revert (), QSqlTableModel::revertAll ())


Название: Re: БД для новичка. Помогите, нужно быстро разобратся
Отправлено: daimon от Декабрь 05, 2009, 23:52
Как удалять данные из БД?


Название: Re: БД для новичка. Помогите, нужно быстро разобратся
Отправлено: niXman от Декабрь 05, 2009, 23:56
Код
SQL
DROP TABLE *
 


Название: Re: БД для новичка. Помогите, нужно быстро разобратся
Отправлено: daimon от Декабрь 05, 2009, 23:59
Код
SQL
DROP TABLE *
 
Это вроде удалить таблицу, а как одну ячеку (0,0)?


Название: Re: БД для новичка. Помогите, нужно быстро разобратся
Отправлено: lit-uriy от Декабрь 06, 2009, 00:04
из таблицы в БД, нельзя удалить ячейку. В БД есть понятие "запись" (подобна строке), и манипуляции происходят с записями.

Я взял пример cachedtable и перенёс из демки sqlbrowser (плюс файл connection) несколько методов.
Смотри во вложении (через контекстное меню можешь вставлять и удалять записи)

В коде сделал пометки, куда внесены изменения:
Код
C++ (Qt)
//--->>>-----
так помечено начало изменения
Код
C++ (Qt)
//---<<<-----
так помечено завершение изменения


Название: Re: БД для новичка. Помогите, нужно быстро разобратся
Отправлено: daimon от Декабрь 06, 2009, 00:12
из таблицы в БД, нельзя удалить ячейку. В БД есть понятие "запись" (подобна строке), и манипуляции происходят с записями.

Я взял пример cachedtable и перенёс из демки sqlbrowser (плюс файл connection) несколько методов.
Смотри во вложении (через контекстное меню можешь вставлять и удалять записи)

В коде сделал пометки, куда внесены изменения:
Код
C++ (Qt)
//--->>>-----
так помечено начало изменения
Код
C++ (Qt)
//---<<<-----
так помечено завершение изменения
Почему в БД нельзя вставлять строки в середину (новые строки добавляются в конец)?


Название: Re: БД для новичка. Помогите, нужно быстро разобратся
Отправлено: lit-uriy от Декабрь 06, 2009, 00:14
>>Почему в БД нельзя вставлять строки в середину (новые строки добавляются в конец)?
так устроены все БД.

Записи всегда добавляются в конец. Ещё раз напомню: БД это не эксель. БД - БАЗА ДАННЫХ!


Название: Re: БД для новичка. Помогите, нужно быстро разобратся
Отправлено: daimon от Декабрь 06, 2009, 00:20
С помощью чего можна реализовать что-то похожее на ексель
-QTableWidget - сделал (много оперативы жрёт  и тормозит)
-QAbstractTableModel QTableView - (много оперативы жрёт) Вопрос: какой создать вектор для данных 2 ролей
-БД - не поддерживает вставку в середину
Может в БД добавить id integer и сортировать БД по нём (при вставке в модель фиксирую новый id, а старые сдвинаю).

Что посоветуете сделать?


Название: Re: БД для новичка. Помогите, нужно быстро разобратся
Отправлено: gmorgunov от Декабрь 06, 2009, 00:28
Еще раз проверил пример без model.submit(). Работает точно так же, как и с model.submit().
Lit-uriy - признаю, ошибся я.


Название: Re: БД для новичка. Помогите, нужно быстро разобратся
Отправлено: lit-uriy от Декабрь 06, 2009, 01:03
>>Что делать?
вариантов море.

Если тебе нужно некое подобие электронных таблиц, возьми готовый - QSimpleSheet (http://www.qt-apps.org/content/show.php/QSimpleSheet?content=75343), и переделай его, если в этом есть нужда


Название: Re: БД для новичка. Помогите, нужно быстро разобратся
Отправлено: daimon от Декабрь 06, 2009, 01:49
>>Что делать?
вариантов море.

Если тебе нужно некое подобие электронных таблиц, возьми готовый - QSimpleSheet (http://www.qt-apps.org/content/show.php/QSimpleSheet?content=75343), и переделай его, если в этом есть нужда
Код:
void Table::sort(TableSort tableSort)
{
   QTableWidgetSelectionRange range = tableSort.getRange();
   QList<int> rowsOrColumns; //TODO: can we do it without QList to get higher speed?
   
   if (tableSort.getSortDirection() == TableSort::SortRows)
      for (int i=range.topRow(); i<=range.bottomRow(); i++)
         rowsOrColumns.append(i);
   else
      for (int j=range.leftColumn(); j<=range.rightColumn(); j++)
         rowsOrColumns.append(j);
   
   tableSort.setTable(this);
   qStableSort(rowsOrColumns.begin(), rowsOrColumns.end(), tableSort);
   
   QTableWidgetItem *cells[range.rowCount()][range.columnCount()];
   for (int i=0; i<range.rowCount(); i++)
      for (int j=0; j<range.columnCount(); j++)
         cells[i][j] = takeItem(i+range.topRow(), j+range.leftColumn());
   
   if (tableSort.getSortDirection() == TableSort::SortRows)
   {
      for (int i=0; i<range.rowCount(); i++)
         for (int j=0; j<range.columnCount(); j++)
            setItem(i+range.topRow(), j+range.leftColumn(),
                    cells[ rowsOrColumns[i]-range.topRow() ][j]);
   }
   else
   {
      for (int i=0; i<range.rowCount(); i++)
         for (int j=0; j<range.columnCount(); j++)
            setItem(i+range.topRow(), j+range.leftColumn(),
                   cells[i][rowsOrColumns[j]-range.leftColumn()]);
   }
}
ошибка в  QTableWidgetItem *cells[range.rowCount()][range.columnCount()]
Как исправить?


Название: Re: БД для новичка. Помогите, нужно быстро разобратся
Отправлено: lit-uriy от Декабрь 06, 2009, 02:02
>>QTableWidgetItem *cells[range.rowCount()][range.columnCount()]
А что это значит?


Название: Re: БД для новичка. Помогите, нужно быстро разобратся
Отправлено: daimon от Декабрь 06, 2009, 02:04
>>QTableWidgetItem *cells[range.rowCount()][range.columnCount()]
А что это значит?
Нашел в проге http://www.qt-apps.org/content/show.php/QSimpleSheet?content=75343 (http://www.qt-apps.org/content/show.php/QSimpleSheet?content=75343), которую вы посоветовали


Название: Re: БД для новичка. Помогите, нужно быстро разобратся
Отправлено: lit-uriy от Декабрь 06, 2009, 02:15
ошибка при компиляции? что пишет?


Название: Re: БД для новичка. Помогите, нужно быстро разобратся
Отправлено: daimon от Декабрь 06, 2009, 02:17
ошибка при компиляции? что пишет?
1>------ Build started: Project: QSimplesheet, Configuration: Release Win32 ------
1>Compiling...
1>Table.cpp
1>.\Table.cpp(472) : error C2057: expected constant expression
1>.\Table.cpp(472) : error C2466: cannot allocate an array of constant size 0
1>.\Table.cpp(472) : error C2057: expected constant expression
1>.\Table.cpp(472) : error C2466: cannot allocate an array of constant size 0
1>.\Table.cpp(472) : error C2087: 'cells' : missing subscript
1>.\Table.cpp(472) : error C2133: 'cells' : unknown size
1>Build log was saved at "file://c:\Documents and Settings\Dima\Мои документы\Visual Studio 2008\Projects\QSimplesheet\QSimplesheet\Release\BuildLog.htm"
1>QSimplesheet - 6 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========


Название: Re: БД для новичка. Помогите, нужно быстро разобратся
Отправлено: daimon от Декабрь 06, 2009, 02:25
>>QTableWidgetItem *cells[range.rowCount()][range.columnCount()]
А что это значит?
Нашел в проге http://www.qt-apps.org/content/show.php/QSimpleSheet?content=75343 (http://www.qt-apps.org/content/show.php/QSimpleSheet?content=75343), которую вы посоветовали
надо заменить на  
Код:
QVector<QVector< QTableWidgetItem *>> cells;
 cells.resize(range.rowCount());
 for(int i=0;i<range.rowCount();i++)
 cells[i].resize(range.columnCount());
Вот у меня тогда вопрос: упадёт ли быстродействие и расход памяти в таком случае?
С сортировка есть неточность - она сортирует строки, а не числа 2 20 3 4 не сортирует


Название: Re: БД для новичка. Помогите, нужно быстро разобратся
Отправлено: lit-uriy от Декабрь 06, 2009, 02:29
скачал сырцы, собрал, запустил  - всё работает, никаких ошибок.


Название: Re: БД для новичка. Помогите, нужно быстро разобратся
Отправлено: daimon от Декабрь 06, 2009, 02:30
скачал сырцы, собрал, запустил  - всё работает, никаких ошибок.
Вы попробывали мой вариан исправления?


Название: Re: БД для новичка. Помогите, нужно быстро разобратся
Отправлено: lit-uriy от Декабрь 06, 2009, 06:19
нет не пробовал, а для чего эти исправления? Что они дают?


Название: Re: БД для новичка. Помогите, нужно быстро разобратся
Отправлено: daimon от Декабрь 06, 2009, 12:54
нет не пробовал, а для чего эти исправления? Что они дают?
QTableWidgetItem *cells[range.rowCount()][range.columnCount()] у меня на это компилятор выдает ошибку, поэтому я создал двухмерный вектор. А увас что нет ошибки?


Название: Re: БД для новичка. Помогите, нужно быстро разобратся
Отправлено: daimon от Декабрь 06, 2009, 13:06
Что можна использовать для создания программы типа spreadsheet только для больших данных 5000*5000?
Какой класс для реализации таблицы?


Название: Re: БД для новичка. Помогите, нужно быстро разобратся
Отправлено: lit-uriy от Декабрь 06, 2009, 15:33
>>А увас что нет ошибки?
нет (у меня MinGW32), хотя действительно странно, по идее полностью динамический массив в С++ невозможен.

>>Что можна использовать для создания программы типа spreadsheet только для больших данных 5000*5000?
Возможно наследник QAbstractItemModel + QTableView. Есть ещё проект табличного отчётника, вроде как на большой объём данных расчитан: Скрин (http://www.forum.crossplatform.ru/index.php?showtopic=1169&view=findpost&p=24358)
Можно глянуть, как он устроен, или вовсе у его автора спросить


Название: Re: БД для новичка. Помогите, нужно быстро разобратся
Отправлено: daimon от Декабрь 06, 2009, 16:12
>>А увас что нет ошибки?
нет (у меня MinGW32), хотя действительно странно, по идее полностью динамический массив в С++ невозможен.

>>Что можна использовать для создания программы типа spreadsheet только для больших данных 5000*5000?
Возможно наследник QAbstractItemModel + QTableView. Есть ещё проект табличного отчётника, вроде как на большой объём данных расчитан: Скрин (http://www.forum.crossplatform.ru/index.php?showtopic=1169&view=findpost&p=24358)
Можно глянуть, как он устроен, или вовсе у его автора спросить
Пример рабочий, но сложен


Название: Re: БД для новичка. Помогите, нужно быстро разобратся
Отправлено: daimon от Декабрь 06, 2009, 16:44
>>А увас что нет ошибки?
нет (у меня MinGW32), хотя действительно странно, по идее полностью динамический массив в С++ невозможен.

>>Что можна использовать для создания программы типа spreadsheet только для больших данных 5000*5000?
Возможно наследник QAbstractItemModel + QTableView. Есть ещё проект табличного отчётника, вроде как на большой объём данных расчитан: Скрин (http://www.forum.crossplatform.ru/index.php?showtopic=1169&view=findpost&p=24358)
Можно глянуть, как он устроен, или вовсе у его автора спросить
Провёл эксперимент 1000*1000 цифры: QTableWidget 167 метров, ваш пример 397 метров (вставляю из буфера обмена)