Russian Qt Forum
Ноябрь 26, 2024, 20:01 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 ... 10 11 [12] 13 14   Вниз
  Печать  
Автор Тема: Транзакции Interbase  (Прочитано 150762 раз)
sarbash
Гость
« Ответ #165 : Декабрь 19, 2010, 00:58 »

Попробовал сегодня поработать (Qt 4.7 /MinGW/ + FB2.5) со "стандартным" драйвером QIBASE: нормально возвращает значение returning, только next() выполнить нужно, а с QFIREBIRD - фиквам, с ошибкой.
Цитировать
QSqlQuery::value: not positioned on a valid record

Недопилено еще...Грустный
Фикс есть у меня, если нужен патч, могу поделиться. Работает по тому же принципу, что и QIBASE. Однако, до этого времени никто не проявил интерес к этому функционалу, из чего я решил, что никому, кроме меня он и не нужен. Улыбающийся

P.S. На всякий случай...
« Последнее редактирование: Декабрь 19, 2010, 01:08 от sarbash » Записан
vlad-mal
Гость
« Ответ #166 : Декабрь 21, 2010, 19:25 »

1. Да вы что, как так "нет интереса"? Все "Qt-интербейзники" везде только на эту ветку и ссылаются. Улыбающийся

2. Распреспасибищще!
Записан
sne
Гость
« Ответ #167 : Декабрь 22, 2011, 07:15 »

Собственно, до автора смог кто до автора достучаться? Просто если он не поддерживает проект, может добавит мемберов, или остается форкнуть, да потихонечку дописывать??
Записан
Whiplash
Гость
« Ответ #168 : Апрель 10, 2012, 15:41 »

Озадачился тут намедни работой с guid из Firebird... Долго рассказывать, но для комфортной работы пришлось слегка модифицировать драйвер QFIREBIRD. Давно этим драйвером пользуюсь, выражаю своё почтение автору Улыбающийся
GUID'ы в FB принято хранить в виде CHAR(16) OCTETS. Попытка работы с таким "сырым" гуидом с помощью этого драйвера провалилась - в нём все строки преобразовываются в QString и использованием текстового кодека. А в случае гуидов это не строка, а фиксированный набор байт, который с сервера приходит как строка. Да ещё и 0x00 в середине легко попасться может.
В общем, в модифицированном драйвере:
1. Зарегистрирован и декларирован тип QUuid, чтобы можно было им пользоваться в QVariant.
2. Проводится автоматическое распознавание столбца GUID по следующим условиям:
    - домен называется UUID
    - это CHAR (16) OCTETS
3. Фактически, при открытии соединения с базой делается служебный запрос по метаданным и заполняется хэш, где каждому столбцу каждой таблицы присваивается признак true или false. В дальнейшем для доопределения типа столбца с гуид этот столбец сверяется с хэшем.
4. При помещении в запрос (bindValue) тип QUuid сериализуется в 16-байтный std::string.
5. К сожалению, для комфортного использования нужно в своём приложении не забыть написать Q_DECLARE_METATYPE(QUuid). В каком-нибудь хидере.

Примерно так можно пользоваться:
В запросе
Код
SQL
SELECT id, name FROM dir d
id - это UUID
Выполняем запрос, получаем данные:
Код:
    QSqlQuery q(db);
    q.exec("select id, name from dir d");
    q.next();
    QUuid uid=q.value(0).value<QUuid>();

Передаём данные в запрос:
Код:
    QUuid id;
    QSqlQuery q(db);
    db.transaction();
    q.prepare("select dscr from dir where id=?");
    q.bindValue(0,QVariant::fromValue(id));

Так как QUuid нестандартный для QVariant тип данных, то приходится делать всякие QVariant::fromValue(id) и value<QUuid>().
Для удобства я оперделил макрос
Код:
#define VUUID(variant) variant.value<QUuid>()
Так-что могу делать вот так:
Код:
QUuid uid=VUUID(q.value(0));
вместо
Код:
QUuid uid=q.value(0).value<QUuid>();

Даёшь GUID!

*** Блин, забыл в начале про селективные процедуры Улыбающийся Сейчас поправил - гуиды работают и из селективных процедур.
« Последнее редактирование: Апрель 10, 2012, 16:21 от Whiplash » Записан
Tonal
Гость
« Ответ #169 : Апрель 11, 2012, 08:37 »

Для справки про uid-ы: в версии 2.1 появилась функция GEN_UUID() - генерация uuid-ов, а в 2.5 UUID_TO_CHAR и CHAR_TO_UUID - конвертаця uid-ов в строку и обратно. Улыбающийся
Код:
CHAR_TO_UUID
Function:
    Converts the CHAR(32) ASCII representation of an UUID
    (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX) to the CHAR(16) OCTETS
    representation (optimized for storage).
Format:
    CHAR_TO_UUID( <string> )
Example:
    select char_to_uuid('93519227-8D50-4E47-81AA-8F6678C096A1') from rdb$database;

Ну и по хорошему, нужно для любого столбца с символьным типом и кодировками OCTETS или NONE возвращать QByteArray вместо QString - иначе, с большой вероятностью, получится каша...
Записан
Whiplash
Гость
« Ответ #170 : Апрель 11, 2012, 15:55 »

Ну так потому и озаботился, что сейчас в ФБ появилась номальная поддержка UID.
Насчёт того, что для любого столбца с OCTETS или NONE возвращать ByteArray вместо строки - просто отличная идея. Время будет - так и сделаю. Чего уж, расковырял малёха драйвер так не останавливаться же.
Может, автор драйвера сделает какой-нить официальный билд с этими изменениями?
Записан
Tonal
Гость
« Ответ #171 : Апрель 12, 2012, 09:04 »

Может на githab склонировать?
Там как-то попроще с управление проектом и форканьем. Улыбающийся
Записан
eJinn
Гость
« Ответ #172 : Май 13, 2013, 22:43 »

Всем привет.

Версия Qt:
qt-windows-opensource-5.0.2-mingw47_32-x86-offline

Драйвер QFIREBIRD не собирается.
Выдает ошибку
D:\Qt Projects\AxQtFbIbppSqlDriver\src\main.cpp:62: ошибка: expected constructor, destructor, or type conversion before 'enum'
на строчку
Q_EXPORT_PLUGIN2(qsqlfb, QFBDriverPlugin)

qsqlfirebird.dll + переименованный в qsqlfirebirdd.dll, , положенные к [Qt-dir]\5.0.2\mingw47_32\plugins\sqldrivers не подцепляется.

Win7 x64, Firebird-2.5.2.26540-0_Win32

Какие будут идеи?
Записан
Whiplash
Гость
« Ответ #173 : Май 14, 2013, 00:28 »

Не соберётся драйвер для 4 версии под 5. Надо переписывать.
Записан
eJinn
Гость
« Ответ #174 : Май 14, 2013, 07:01 »

Версия Qt:
qt-windows-opensource-5.0.2-mingw47_32-x86-offline

qsqlfirebird.dll + переименованный в qsqlfirebirdd.dll, , положенные к [Qt-dir]\5.0.2\mingw47_32\plugins\sqldrivers не подцепляется.
И не подцепится Грустный((
Цитировать
Подключаемые модули, слинкованные с библиотекой Qt, имеющей меньший главный номер версии, не будут загружены библиотекой имеющей больший главный номер версии.
Пример: Qt 4.3.1 не будет загружать подключаемый модуль, собранный с Qt 3.3.1.
http://doc.crossplatform.ru/qt/4.7.x/deployment-plugins.html

Пичалька...
Upd: написал Issue на эту проблему на страничке Ах`а. Может он откликнется.
« Последнее редактирование: Май 14, 2013, 07:17 от eJinn » Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #175 : Май 23, 2014, 17:41 »

Вот модифицированный main.cpp

Код:
#include <qsqldriverplugin.h>
#include <qstringlist.h>
#include "qsql_ibpp.h"

#include <QDebug>

class QFBDriverPlugin : public QSqlDriverPlugin
{
Q_PLUGIN_METADATA( IID "org.qt-project.Qt.QSqlDriverFactoryInterface" )
public:
QFBDriverPlugin();

QSqlDriver* create(const QString &);
QStringList keys() const;
};

QFBDriverPlugin::QFBDriverPlugin()
: QSqlDriverPlugin()
{
qDebug() << "111";
}

QSqlDriver* QFBDriverPlugin::create(const QString &name)
{
qDebug() << "222";

if (name == QLatin1String("QFIREBIRD")) {
        QFBDriver* driver = new QFBDriver();
        return driver;
    }
    return 0;
}

QStringList QFBDriverPlugin::keys() const
{
qDebug() << "333";

QStringList l;
l  << QLatin1String("QFIREBIRD");
    return l;
}

Драйвер компилится под QT 5  - но мне никак не удается его заставить работать - и в релизе и в дебаге собирал и его и программу пытающуюся его использовать, вообще не хочет загружаться в QT.

Прилагаю так же проект драйвера - может не хватает каких-то опций в pro-шнике.

Проблема пока не решена, буду рад помощи!
« Последнее редактирование: Май 23, 2014, 17:43 от break » Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #176 : Май 27, 2014, 14:08 »

Починил - компилится под QT5 и работает !

Причина в том, что в QT5 теперь вместо виртуальной ф-ци keys возвращающей имя идентификатор плагина есть файл json. Но чтобы он увиделся надо, чтобы класс был описан в h-нике, т.к. макрос Q_PLUGIN_METADATA обрабатывается MOC-ом, который натравливается только на h-ники.

Подправленный проект прилагаю!
« Последнее редактирование: Май 27, 2014, 14:10 от break » Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #177 : Май 27, 2014, 14:42 »

Кто мне подскажет как автор предполагал использовать несколько транзакций внутри одного соединения QSqlDatabase ?

Я не вижу как это возможно - мпакрос TRANSACTION это всего лишь установка свойства драйвера, QSqlDatabase::database().driver()->setProperty("Transaction",(x)) и оно применится к застартованной после транзакции. Внутри одного QSqlDatabase мы вроде можем иметь только одну запущенную транзакцию....

Все таки прийдется создавать разные подключения к БД через QSqlDatabase с разным connectionName - чтобы создать изолированную транзакцию?

Простейший пример - БД - основная программа главное окно - дересья, таблички - все в одной основной транзакции. Открываем конкретный документ - хочется естественно иметь изолированную транзакцию для работы с ним - отдельное диалоговое окно с его свойствами, и две кнопки ОК (Commit), Cancel (Rollback).

 Я правильно понял, что архитектура интерфейса Qt сегодня не позволяет это сделать через один QSqlDatabase - точнее один connectionName?
Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #178 : Май 28, 2014, 16:49 »

Прикольно, но лучше собирать драйвер из консоли, а не из креатора - а то как результат MOC может и не натравиться - и опять не работает...

https://github.com/qreal/qreal/issues/209
Записан
break
Гипер активный житель
*****
Offline Offline

Сообщений: 846


Просмотр профиля
« Ответ #179 : Май 28, 2014, 17:21 »

Разобрался с транзакциями в этом драйвере - вызов функции transaction() стартует новую транзакцию и кладет ее в стек, штатный драйвер не делал этого. Далее commit или rollback могут работать с последней транзакцией из стека. В принцепе это удобно при вызове диалоговых окон и частично решает проблему, но в более сложном интерфейсе где все равно нужно управление отдельными параллельно живущими транзакциями прийдется делать несколько коннекшенов QSqlDatabase - ф-ция cloneDatabase  в помощь...

Все же маловат апи Qt - транзакции должны быть именованными (ф-я transaction() должна возвращать ID транзакции, с которым потом можно работать) внутри одного QSqlDatabase, а сам QSqlDatabse должен использовать разные коннекшены только для доступа к разным БД.
Записан
Страниц: 1 ... 10 11 [12] 13 14   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.266 секунд. Запросов: 23.