LINUX.ORG.RU

Ответ на: комментарий от ANDI

Qt не катит. Основная проблема -- она "туго" понимает базу, нарезанную с charset-ами отличными от текущей locale, точнее вообще не понимает, то бишь напрочь отказывается читать данные, если база нарезана скажем с CHARSET=WINDOWS-1251. А в драйвере QIBASE опциональные настройки соединения, типа lc_ctype, просто в наглую заглушены :-(

anonymous
()
Ответ на: комментарий от anonymous

Скорее всего, Qt берет настройки драйвера IBASE.
У меня нет их исходников. Как определена isc_dpb_lc_ctype в ibase.h?
Что мешает изменить ее нужным образом самостоятельно?
Может быть, драйвер IBASE (не qt) имеет API для смены кодировки?

ANDI ★★
()
Ответ на: комментарий от ANDI

Вот кусочек из QT-шного драйвера qsql_ibase.cpp

...

bool QIBaseDriver::open(const QString & db,
const QString & user,
const QString & password,
const QString & host,
int /*port*/,
const QString & /* connOpts */)
{
if (isOpen())
close();

static const char enc[8] = "UTF_FSS";
...

QByteArray ba(usr.length() + pass.length() + sizeof(enc) + 6);

...

ba[i] = isc_dpb_lc_ctype;
ba[++i] = sizeof(enc) - 1;
...

QString ldb;
QString ldb;
if (!host.isEmpty())
ldb += host + ":";
ldb += db;
isc_attach_database(d->status, 0, (char*)ldb.latin1(), &d->ibase, i, ba.data());

...

Тут видно, что они принудительно используют кодировку UTF_FSS
(UNICODE_FSS). Все бы ничего, но у меня база нарезана с "DEFAULT
CHARACTER SET WIN1251" и она (Qt) напрочь отказывается читать данные.
Соединяется нормально, SQL-запрос вроде как исполняется (по крайней
мере ошибок не возникает), а вот данных в QSqlQuery нет -- 0 записей.
Если базу нарезать с "DEFAULT CHARACTER SET UTF_FSS", то, хоть и глюкаво (QDataTable отказывается отображать данные, хотя QSqlQuery эти
данные возвращает), но работает. По ряду причин я не могу установить
кодировку для базы в "UTF_FSS". В IBPP таких проблем нет, однако мне
не хотелось бы зацикливаться на чем-то одном, тем более, что пока
проект только в стадии "обмозгования". Вот и спросил - не знает ли
кто-нибудь еще что-то подобное IBPP, хотелось бы чуть-чуть больше
удобств, чем это предоставляет IBPP.

anonymous
()
Ответ на: комментарий от ANDI

Да... и еще

>Скорее всего, Qt берет настройки драйвера IBASE.

Ну нет такого драйвера, есть библиотека libfbclient.so с реализацией API

>У меня нет их исходников. Как определена isc_dpb_lc_ctype в ibase.h?

#define isc_dpb_lc_ctype 48

Но разве это что-то дает? Это же просто идентификатор параметра "CHARACTER SET" в буфере опциональных настроек соединения.

>Что мешает изменить ее нужным образом самостоятельно?

Изменить #define ? Ничто не мешает, но это не поможет, а только навредит.

>Может быть, драйвер IBASE (не qt) имеет API для смены кодировки?

Имеет, но тогда придется все делать на API, ибо эта "смена кодировки" не будет воздействовать на сессию, открываемую посредством Qt. А мне очень не хочется опускаться в API.

anonymous
()
Ответ на: комментарий от anonymous

> Ну нет такого драйвера, есть библиотека libfbclient.so с реализацией API

Не суть. Ничего не мешает драйверу быть реализованным в виде библиотеки.

>Но разве это что-то дает? Это же просто идентификатор параметра "CHARACTER SET" в буфере опциональных настроек соединения.

Понятно. Я надеялся, что это была переменная, хранящая кодировку (исходников IBASE у меня нет, повторюсь).

Функция QIBaseDriver::open() виртуальная.
Не желаете ее переопределить и добавить нужную поддержку для указания кодировки (или, в вашем случае, аналогичным образом зашить свою кодировку)?

ANDI ★★
()
Ответ на: комментарий от ANDI

>Функция QIBaseDriver::open() виртуальная.
>Не желаете ее переопределить и добавить нужную поддержку для указания
>кодировки (или, в вашем случае, аналогичным образом зашить свою
>кодировку)?

Угу... А проблема переносимости? QIBASE -- это плагин, который поставляется вместе с Qt и компилируется, если при configure задан флаг --plugin-sql-ibase. Тут две проблемы:

1. Изменить реализацию метода open() не сложно, там всего-то 10
строчек, но при этом я совершенно не уверен, что это положительно
скажется на всем остальном коде плагина (я полагаю что Тролли не
спроста жестко "зашили" кодировку, видимо были какие-то
{су}{о}бъективные причины). А ковырять весь драйвер, а может быть и
весь модуль SQL - мне как-то не улыбается.

2. Даже если проблема решится простым субклассингом, то у моего
заказчика, Qt может оказаться собранной без этого плагина и тогда вся
работа насмарку.

Вполне естественно напрашивается возражение на п.2 -- типа: "Дык, ты вместе с прогой распространяй и либу с плагином". Но я не слишком
опытный программёр в Qt, чтобы быть уверенным на все 100%, что Qt,
собранная без --plugin-sql-ibase, будет работать с этим плагином.
Честное слово, я не знаю, какие зависимости тут могут существовать.

Это еще одна причина, почему Qt, на мой взгляд, не самый лучший
вариант.

Впрочем я наверное попробую реализовать ваше предложение!
Хотя бы ради интереса. Кстати, вы натолкнули меня на одну идею, пусть
и не связанную с IBASE... ! ;-)))

anonymous
()
Ответ на: комментарий от anonymous

>1. Изменить реализацию метода open() не сложно, там всего-то 10
строчек, но при этом я совершенно не уверен, что это положительно
скажется на всем остальном коде плагина (я полагаю что Тролли не
спроста жестко "зашили" кодировку, видимо были какие-то
{су}{о}бъективные причины).

Может быть. Но это легко выяснить, подставив вместо UTF_FSS то, что требуется.
Благо, исходники Qt доступны...
Если не заработает с cp1251, значит уникод зашит архитектурно, и тут уже действительно ничего не поделаешь.
Возможно, придется делать перекодировку на стороне клиента, если сервер ее не делает.
Кстати, ни один из qt-sql-драйверов при открытии не требует указания кодировки (что объясняет зашитие уникода). Может, эта проблема должна решаться в Qt как-то по другому?


>2. Даже если проблема решится простым субклассингом, то у моего
заказчика, Qt может оказаться собранной без этого плагина и тогда вся
работа насмарку.

Плагины могут идти с программой. А в main(), соответственно, надо вызвать:
QApplication::addLibraryPath() с указанием пути к нужному драйверу. Дальше - как обычно, qt его уже сама загрузит.

>Вполне естественно напрашивается возражение на п.2 -- типа: "Дык, ты вместе с прогой распространяй и либу с плагином".

Нет, либу не придется таскать. Только скомпилированный sql-драйвер.

> Но я не слишком опытный программёр в Qt, чтобы быть уверенным на все 100%, что Qt,
собранная без --plugin-sql-ibase, будет работать с этим плагином.

Можно просто взять файлы qt-sql-ibase, переименовать, исправить и сделать самостоятельным плагином.
В общем, тут вариантов - море.

>Это еще одна причина, почему Qt, на мой взгляд, не самый лучший вариант.
Возможно. Поддержка ibase в Qt появилась недавно (3.3). Еще полгода не прошло.

ANDI ★★
()
Ответ на: комментарий от ANDI


Попробовал... Точнее чуть не попробовал! В пылу обсуждения как-то
упустил из виду, что open() не виртуальный, а значит объем кодирования
значительно увеличивается, поэтому "выбросил" такую мысль.

>...подставив вместо UTF_FSS то, что требуется.
>Благо, исходники Qt доступны...

Это не есть выход, поскольку реально имеется 4 базы, одна построена на
ISO8859-5 (CYRL), а три других на WIN1251. Модификация этих баз
выходит за рамки моей компетенции. Так что любое hardcoded-решение
изначально неприемлемо

>Кстати, ни один из qt-sql-драйверов при открытии не требует указания
>кодировки (что объясняет зашитие уникода). Может, эта проблема должна
>решаться в Qt как-то по другому?

К сожалению -- не требуют и это явно недостаток драйвера, поскольку он
ограничивает область применений, а драйвер с недостатками, хмммм...

>Плагины могут идти с программой. А в main(), соответственно, надо
>вызвать: QApplication::addLibraryPath() с указанием пути к нужному
>драйверу. Дальше - как обычно, qt его уже сама загрузит.

А как быть, если приложение переносится в систему с другой версией qt?
Или еще какая закавыка?

>Нет, либу не придется таскать. Только скомпилированный sql-драйвер.

Так это и есть либа -- libqsqlibase.so

>Можно просто взять файлы qt-sql-ibase, переименовать, исправить и
>сделать самостоятельным плагином. В общем, тут вариантов - море.

С этим готов согласиться, но лишь частично, поскольку, как я уже
упоминал, любое hardcoded-решение для моей специфики не совсем
подходит, а кроме того, на фоне этих "неурядиц" IBPP выглядит более
привлекательно, поскольку не требует внесения исправлений. Если вы не
забыли тему вопроса -- я не задаюсь целью нарисовать "морду"
основываясь исключительно на средствах Qt, я пытаюсь найти возможные
альтернативы, потому что перспектива вырисовывается довольно широкая и
хотелось бы подобрать инструментарий, что называется "по руке".


anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.