Russian Qt Forum

Qt => Базы данных => Тема начата: deMax от Сентябрь 22, 2017, 11:01



Название: Готовые модули для просмотра и редактирования БД
Отправлено: deMax от Сентябрь 22, 2017, 11:01
Сабж? Вроде и писать не сложно, но может готовое что есть?
есть БД, есть списки с подробным описанием таблиц и полей на русском, нужна форма которая сделает окно просмотра таблицы.
Аналогично нужна форма редактирования таблицы, с возможностью отмены, контролем что данные в таблице не изменились перед внесением изменений... (если данные изменились то сделать слияние как в git)


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: vic57 от Сентябрь 22, 2017, 11:15
QSqlQueryModel, QSqlTableModel чем не подходят?


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: deMax от Сентябрь 27, 2017, 11:22
Для mssql изменения не сохраняются.
А вот такой вопрос: пользователь загрузил таблицу локально, отредактировал теперь он отсылает на сервер. Как проверить что на сервере таблица не изменилась?
Можно ли в запрос на изменения добавить запрос на проверку?  Например 2 пользователя одновременно проверили что таблица не изменилась, первый залил изменения, а второй испортил данные(так как думал что заливает на неизмененную таблицу).


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: vic57 от Сентябрь 27, 2017, 12:42
вставить можно все что угодно. я на изменение/удаление делал отдельный диалог с подтверждением действия. БД не будет думать за вас, бизнес-логику на клиенте самому надо делать.
например делать цепочку select/update - сначала видите то, что хотите изменить, потом меняеете

 


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: deMax от Сентябрь 27, 2017, 14:21
Меня вот какой вопрос смущает. Допустим в таблице есть 2 поля Scoda Touareg. Первый пользователь исправляет Scoda->Wolksvagen, а второй одновременно Touareg->Octavia, проверка у них произошла одновременно и получилось Wolksvagen Octavia или данные первого пользователя затрутся?
но тогда допустим есть еще поля в которые 2 пользователя вбивали технические характеристики и тогда теряются данные первого пользователя.

Можно ли считать таблицу, а записать только если таблица не изменилась с момента чтения?


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: vic57 от Сентябрь 27, 2017, 19:24
Меня вот какой вопрос смущает. Допустим в таблице есть 2 поля Scoda Touareg. Первый пользователь исправляет Scoda->Wolksvagen, а второй одновременно Touareg->Octavia, проверка у них произошла одновременно и получилось Wolksvagen Octavia или данные первого пользователя затрутся?
но тогда допустим есть еще поля в которые 2 пользователя вбивали технические характеристики и тогда теряются данные первого пользователя.
Можно ли считать таблицу, а записать только если таблица не изменилась с момента чтения?
ну это из серии - кто будет сторожить того кто будет сторожить
имхо я бы сделал поле user_id для каждого юзера, имеющего право на update например
http://webew.ru/articles/1383.webew


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: lit-uriy от Сентябрь 28, 2017, 06:13
deMax, если редактируют одну таблицу или несколько таблиц связанных ключами, то БД не позволит одновременный доступ.
Т.е. один из пользователей получит сообщение об ошибке, либо после попытке сохранить данные увидит всё в исходном состоянии.


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: deMax от Сентябрь 28, 2017, 08:11
deMax, если редактируют одну таблицу или несколько таблиц связанных ключами, то БД не позволит одновременный доступ.
Т.е. один из пользователей получит сообщение об ошибке, либо после попытке сохранить данные увидит всё в исходном состоянии.
А одновременно и не будет, считали что БД не изменилась, у второго лагнула сеть и он sql-запрос на изменения послал позже. Можно ли в одном запросе проверить что данные не изменились и только тогда вносить изменения? Потому что если запроса 2, между считал данные данные (локально проверил) и внес изменения кто то может эти данные изменить.


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: deMax от Сентябрь 28, 2017, 08:13
Запрос QSqlDatabase при соединении и запросе останавливает gui. Его в поток выносить отдельный? Каждый запрос в отдельном потоке? Есть готовые решения?


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: vic57 от Сентябрь 28, 2017, 09:04
http://doc.qt.io/Qt-5/examples-sql.html


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: deMax от Сентябрь 28, 2017, 09:24
http://doc.qt.io/Qt-5/examples-sql.html
И где там потоки(в папке примеров sql слово thread не найдено)? Виснущий GUI пока идет обращение к БД не очень актуально.


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: Bepec от Сентябрь 28, 2017, 10:53
В потоки шмалять. По другому никак не получается.


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: deMax от Сентябрь 28, 2017, 11:14
И какой класс потока выбрать для mssql? QtConcurrent, QThread...
Для каждого запроса создавать поток или в один поток запросы кидать(через очередь)?
В принципе бд не нагруженная, главное чтоб гуи при подключении и запросах не вис. Как отменить db->open() в потоке?


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: lit-uriy от Сентябрь 28, 2017, 13:47
>Для каждого запроса создавать поток
Надо не запрос, а соединение (QSqlDatabase) поместить в отдельный поток (moveToThread)


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: Old от Сентябрь 28, 2017, 13:49
Надо не запрос, а соединение (QSqlDatabase) поместить в отдельный поток (moveToThread)
QSqlDatabase не является наследником QObject, поэтому у него нет метода moveToThread.
А так да, для каждой нитки нужно создавать отдельное подключение.


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: deMax от Сентябрь 28, 2017, 13:56
А когда поток не работает останавливать его? Или в цикле со sleep гонять?
Может есть правильный пример?


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: deMax от Сентябрь 28, 2017, 14:37
Для каждого подключения к БД создать поток, когда приходят запросы выполнять их, когда запросов нет гонять пустой цикл со slepp, перед закрытием подключения отключаться от БД?
QThreadPool? QTHread? QtConcurent... что выбрать?


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: Bepec от Сентябрь 28, 2017, 15:08
Я решил проблему классом который держит объект соединения и дублирует функции слотами. Ну и собственно его и запуливаю в поток, сигналами и слотами шмалять.
Правда он крайне урезанный, поддерживает буквально exec, commit, ошибки.


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: deMax от Октябрь 04, 2017, 12:23
Я решил проблему классом который держит объект соединения и дублирует функции слотами. Ну и собственно его и запуливаю в поток, сигналами и слотами шмалять.
Правда он крайне урезанный, поддерживает буквально exec, commit, ошибки.
А можно пример? И что делать когда задач нет sleep в цикле гонять?


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: Bepec от Октябрь 04, 2017, 15:31
У меня он событийный поток. Т.е. там в run exec, а все задачи сигналами посылаются.


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: deMax от Октябрь 05, 2017, 11:59
QSqlDatabase не является наследником QObject, поэтому у него нет метода moveToThread.
А так да, для каждой нитки нужно создавать отдельное подключение.
А что выбрать: moveTothread, QtConcurrent, Qthread, QThreadPool?

мне нужно class LibDB {public slots: setConfig(Config); int query(Qstring); signals void data(int id, QVariantList);}


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: Bepec от Октябрь 05, 2017, 12:51
Я плохой советчик по потокам, т.к. я просто создаю класс наследуемый от QThread и делаю moveToThread в конструктор :D С другой стороны этот подход работает, не имеет никаких отрицательных сторон, кроме слабой переносимости :D


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: deMax от Октябрь 05, 2017, 14:09
Создать несколько потоков(например 4), в конструкторе каждого потока:
db = QSqlDatabase::addDatabase()
db.open()
В деструкторе:
db.close()
?


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: Bepec от Октябрь 05, 2017, 15:07
Не, у меня приложение не ресурсоёмкое, потому запросы выполняются последовательно. Т.е. 1 поток, одно соединение.
Хотя при частых запросах, создать несколько соединений... Хз, на мой неискушенный взгляд такое не особо сильно прибавит быстродействия.


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: deMax от Октябрь 05, 2017, 16:31
А как из потока структуру вернуть?
прописал:
typedef QList<QVariantList> ResultFromDB;
Q_DECLARE_METATYPE(ResultFromDB)

консоль:
QObject::connect: Cannot queue arguments of type 'ResultFromDB'
(Make sure 'ResultFromDB' is registered using qRegisterMetaType().)


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: MrDron от Октябрь 05, 2017, 17:33
А как из потока структуру вернуть?
прописал:
typedef QList<QVariantList> ResultFromDB;
Q_DECLARE_METATYPE(ResultFromDB)

консоль:
QObject::connect: Cannot queue arguments of type 'ResultFromDB'
(Make sure 'ResultFromDB' is registered using qRegisterMetaType().)

qRegisterMetaType<ResultFromDB>("ResultFromDB");

http://doc.qt.io/qt-5/qmetatype.html#qRegisterMetaType


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: deMax от Октябрь 05, 2017, 23:36
Спасибо, заработало.
Как лучше результат из базы возвращать? ссылка/unique_ptr/по значению...?
qRegisterMetaType<My>("My") - это функция, вне кода(под структурой её не написать) где её лучше вызвать?


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: lit-uriy от Октябрь 06, 2017, 06:56
>>qRegisterMetaType<My>("My") - это функция, вне кода(под структурой её не написать) где её лучше вызвать?
можно в конструкторе где у тебя соединение создаётся


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: deMax от Октябрь 06, 2017, 10:31
У меня N потоков с QThread, как посылать сигнал DB::queryWork только одному? Вызвать слот напрямую в другом потоке вряд ли получиться, добавить идентификатор потока чтобы поток если это не ему не выполнял запрос?

Код:
    for(QThread *&threadDB: threadsDB) {
        threadDB = new QThread;
        Worker *worker = new Worker;
        worker->moveToThread(threadDB);

        connect(threadDB, &QThread::finished, worker, &QObject::deleteLater);
        connect(this, &DB::queryWork, worker, &Worker::queryWork);
        connect(this, &DB::workerConnectDB, worker, &Worker::connectDB);
        connect(this, &DB::workerDisconnectDB, worker, &Worker::disconnectDB);
        connect(worker, &Worker::queryResult, this, &DB::queryResult);
        threadDB->start(); }


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: MrDron от Октябрь 06, 2017, 10:44
Вызвать слот напрямую в другом потоке вряд ли получиться
Слот, чтобы он выполнился в нужном потоке, можно написать:
Код
C++ (Qt)
QMetaObject::invokeMethod(worker, "queryWork");


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: deMax от Октябрь 06, 2017, 11:56
Спасибо.
Объекты через сигналы-слоты обращаются к классу БД. Как вернуть данные объекту, который их запросил, от БД?


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: MrDron от Октябрь 06, 2017, 15:23
Спасибо.
Объекты через сигналы-слоты обращаются к классу БД. Как вернуть данные объекту, который их запросил, от БД?
так sender() же имеется


Название: Re: Готовые модули для просмотра и редактирования БД
Отправлено: deMax от Октябрь 31, 2017, 16:11
А как отменить запрос на подключение и SQL запрос?
Запрос на подключение висит 30 секунд(пока не выдаст ошибку что пользователь ошибся, пользователь увидел ошибку, как ему отменить подключение?)
Аналогично с sql запросом, подключаюсь к другой БД, все активные выполнения запросов можно удалить.