Russian Qt Forum

Qt => Базы данных => Тема начата: CroCIV от Ноябрь 01, 2010, 15:17



Название: [РЕШ] Как записать в БД в поле типа BLOB или varbinary любой стандарный класс Qt
Отправлено: CroCIV от Ноябрь 01, 2010, 15:17
Примерно вот так:

Код:
	QSqlQuery q(QSqlDatabase::database());
QByteArray ba;
QDataStream ds(&ba,QIODevice::WriteOnly);
QЛюбойКласс qkl(...);
ds<<qkl;
q.prepare("Update Таблица set поле = ? where ...");
q.addBindValue(QVariant(ba.toHex()));
q.exec();


Название: Re: Как записать в БД в поле типа BLOB или varbinary любой стандарный класс Qt
Отправлено: CroCIV от Ноябрь 01, 2010, 15:21
А вот так почитать:

Код:
	QSqlQuery sql(QSqlDatabase::database()); 
sql.exec("select id, поле from Таблица");

while (sql.next())
{
QByteArray ba = QByteArray::fromHex(sql.value(1).toByteArray());
QDataStream ds(ba);
QЛюбойКласс kls;
ds>>kls;
эземпляр_QMap[sql.value(0).toInt()]=kls;
}


Название: Re: [РЕШ] Как записать в БД в поле типа BLOB или varbinary любой стандарный класс Qt
Отправлено: Denjs от Ноябрь 01, 2010, 17:21
Т.е. вы про "сериализацию" нам расказываете? супер! спасибо.

и чо? работает? на чем проверяли? что будет если сунуть туда какой объект завязанный на рантайм (ну скажем Qhttp и иже с ними?

класс объекта должен быть наследован от QObject?

Если я хочу свой класс таким образом сериализировать - что будет? мне нуджно перед этим его регстрировать в системе метаданных или дописывать какой свой метод для сохранения восстановления?

(да - исправьте заголовок ? - вы не "стандартный класс" сериализируете - а "объект стандартного класса")
а топик по данной фиче думаю надо перенести в "готовые решения" думаю. )))


Название: Re: [РЕШ] Как записать в БД в поле типа BLOB или varbinary любой стандарный класс Qt
Отправлено: RedDog от Ноябрь 01, 2010, 17:48
А вложенные члены в виде указателей тоже потом после десериализации восстановятся?
т.е. если примерно такой объект взять:

Код:
class MyQtClass : public QWiget
{
public:
// some public
private:
    QTableWiget *m_table;
};

MyQtClass::MyQtClass (QWiget *parent = 0):
QWiget(parent)
{
     m_table = new QTableWiget(this);
}

после восстановления (в совсем другой сессии) m_table куда будет указывать?


Название: Re: [РЕШ] Как записать в БД в поле типа BLOB или varbinary любой стандарный класс Qt
Отправлено: Denjs от Ноябрь 01, 2010, 17:51
ну, думаю по такому указателю после десериализации вы сегфолт схватите)))
Вот агрегированная переменная - не ссылка - она может и сериализуется...

кого назначим эксперементатором?

PS: вообше - этакий доморощенный мини-ORM получается)))) конечно примерно так сериализация и ORM и соотносятся)))


Название: Re: [РЕШ] Как записать в БД в поле типа BLOB или varbinary любой стандарный класс Qt
Отправлено: RedDog от Ноябрь 01, 2010, 23:01
Ну собственно, тогда вопрос - смысл тогда в этой серелизации? Дамп куска памяти, который не является статичным?


Название: Re: [РЕШ] Как записать в БД в поле типа BLOB или varbinary любой стандарный класс Qt
Отправлено: CroCIV от Ноябрь 02, 2010, 08:58
Ой спасибо за обьективную критику, это так мило... Если у меня будет плохое настроение, обязательно попрошу, чтоб Вы прокоментировали какой-нибудь кусок моего кода. Я рад, что с матчастью у Вас все впорядке, но речь шла не о сериализации. К сожалению я не смог сформулировать правильно тему топика, увы.

Суть в том, что я потратил некоторое время на форуме, и некоторое время на самостоятельный поиск решения, почему вот так:
QSqlQuery1.prepare(..);
QSqlQuery1.addBindValue(QVariant(например_QPixmap).toByteArray());
QSqlQuery1.exec();
не работает, и как это на самом деле должно реализовываться.... Вот и решил поделиться опытом, мб кто предложит более грамотный способ.

Всякие классы с обьяленными в них Q_OBJECT я и не подразумевал, если чо.


Название: Re: [РЕШ] Как записать в БД в поле типа BLOB или varbinary любой стандарный класс Qt
Отправлено: RedDog от Ноябрь 02, 2010, 09:45
Всякие классы с обьяленными в них Q_OBJECT я и не подразумевал, если чо.
как то не вяжется :)
Цитата: CroCIV
любой стандарный класс Qt


Название: Re: [РЕШ] Как записать в БД в поле типа BLOB или varbinary любой стандарный класс Qt
Отправлено: CroCIV от Ноябрь 02, 2010, 09:52
К сожалению я не смог сформулировать правильно тему топика, увы.

Да согласен, не любой. Но, при желании все решается, по крайней мере указатели сразу не проблема.

Ну вот у меня не хватило таланта уложить проблему в 250 символов  :-\
готов переименовать тему грамотно, жду варианты :)


Название: Re: [РЕШ] Как записать в БД в поле типа BLOB или varbinary любой стандарный класс Qt
Отправлено: crossly от Ноябрь 02, 2010, 20:57
к примеру для QPixmap есть метод save(...)


Название: Re: [РЕШ] Как записать в БД в поле типа BLOB или varbinary любой стандарный класс Qt
Отправлено: TemaTre от Апрель 27, 2012, 13:51
Не понимаю что вы все так понаехали на него, лично мне этой информации хватило. Зачем сохранять всякие там QWidget? Когда вы пишете код у вас данные должны быть отделены от GUI, так вот в первом посте и шла речь о том, как сохранить эти самые данные. И код вполне адекватный, перегрузили операторы ввода-вывода для вашего класса и будет вам счастье. А если вы не додумались, при перегрузке оператора, учесть, что у вас указатели есть, то это ваша проблема.


Название: Re: [РЕШ] Как записать в БД в поле типа BLOB или varbinary любой стандарный класс Qt
Отправлено: PavelVX от Июнь 25, 2012, 10:11
Qt + psql, хочется вставить маленькую картинку:

Код:
CREATE TABLE "public"."tst6" (
  "ind" INTEGER NOT NULL,
  "pict" BYTEA,
  CONSTRAINT "tst6_pkey" PRIMARY KEY("ind")
) WITHOUT OIDS;
Код:

    QSqlQuery query;
    QLabel * tstLabel = new QLabel("label", this);
    tstLabel->setPixmap(QPixmap(":/db/resources/delete_record.jpg"));

    query.prepare("update public.tst6 set pict = ?");
    query.addBindValue(QVariant(tstLabel->pixmap()).toByteArray());
    query.exec();


QODBCResult::exec: Unable to execute statement: "ERROR: тип "lo" не существует; Error while executing the query"
Что же я делаю не так? :(


Название: Re: [РЕШ] Как записать в БД в поле типа BLOB или varbinary любой стандарный класс Qt
Отправлено: shirushizo от Июнь 25, 2012, 11:00
Используй это:
Код:
bool 	save(QIODevice * device, const char * format = 0, int quality = -1) const

что-то типа такого:
Код:
    QSqlQuery query;
    QLabel * tstLabel = new QLabel("label", this);
    tstLabel->setPixmap(QPixmap(":/db/resources/delete_record.jpg"));

    QByteArray imgBuffer;
    tstLabel->pixmap().save(imgBuffer, "PNG");
    query.prepare("update public.tst6 set pict = ?");
    query.addBindValue(imgBuffer);
    query.exec();


Название: Re: [РЕШ] Как записать в БД в поле типа BLOB или varbinary любой стандарный класс Qt
Отправлено: PavelVX от Июнь 25, 2012, 11:53
Так точно не прокатит.
tstLabel->pixmap()->save - нет такого метода с параметрами QByteArray

Есть такое подозрение, что дело где-то в дровах, типа как передается сам массив байт
PS а может такое быть, что можно впихнуть не больше сколькито байт за один заход?
Просто
//    query.bindValue("picdata", QVariant(bytes.toHex())); //не работает
    query.bindValue("picdata", QVariant("000")); //работает


Название: Re: [РЕШ] Как записать в БД в поле типа BLOB или varbinary любой стандарный класс Qt
Отправлено: shirushizo от Июль 02, 2012, 11:05
Ну блин опечатался:
Код:
tstLabel->pixmap().save(&imgBuffer, "PNG");

Можно еще через QBuffer засунуть


Название: Re: [РЕШ] Как записать в БД в поле типа BLOB или varbinary любой стандарный класс Qt
Отправлено: atischenko77 от Июль 28, 2012, 16:27
Я заганяю в BLOB файл так:
Есть процедура для считывания файла.
Код:
QVariant setFileVBlob(QString qsFile)
{
    QVariant qvFileVBlob;

    if (!qsFile.isEmpty())
    {
        QFile fFile(qsFile);
        if (fFile.open(QIODevice::ReadOnly))
        {
            QByteArray baFile = fFile.readAll();
            QVariant qvF(baFile.toBase64());
            qvFileVBlob = qvF;
            fFile.close();
        }
        else
        {
            QVariant qvF(QByteArray("").toBase64());
            qvFileVBlob = qvF;
        }
    }

    return qvFileVBlob;
}

а потом использую процедуру так

Код:
QVariant qvFileFotografiyiAversa = setFileVBlob(qsFileFotografiyiAversa);

где qsFileFotografiyiAversa это переменная типа QString которая содержит путь и имя файла который нужно загнать в BLOB.

Код:
QString qsZapros = "INSERT INTO mytable (avers) VALUES (?)";

QSqlQuery qsqQuery(DB);
qsqQuery.prepare(qsZapros);
qsqQuery.bindValue(0, qvFileFotografiyiAversa);

qsqQuery.exec();

DB - это открытая база данных.

Код рабочий 100%. Применяю у себя в программе. Проверено на СУБД PostgreSQL.