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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: QODBC и кодировки  (Прочитано 8677 раз)
carrygun
Гость
« : Февраль 19, 2014, 05:43 »

Доброго времени суток.
В общем возникла неприятная проблема. Есть старая база (Informix) и нужно к ней подцепиться. Проблема в том, что данные в базе хранятся в досовской кодировке (866), а DSN локаль клиента настроена на 1251 (так сделано потому что не я один туда цепляюсь). В общем суть проблемы в кодировках, мне от одбц приходят кракозябры такие, что никаким тексткодеком их не исправить. Установка в DSN локали клиента utf8 не помогает. На 4й версии Qt все работало, а на 5й такая беда. Есть у кого идеи как побороть?
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #1 : Февраль 19, 2014, 06:00 »

Приведите примеры кракозябр и правилльной их расшифровки, что б посмотреть обратима ошибка или нет.
Записан
carrygun
Гость
« Ответ #2 : Февраль 19, 2014, 06:19 »

Текст в базе: "Акнет"
Выхлоп:
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #3 : Февраль 19, 2014, 07:32 »

На 4й версии Qt все работало, а на 5й такая беда.
А на 4-ой как оно работало? Просто в вашей программе 1251 стояло или в чём разница?
Записан
carrygun
Гость
« Ответ #4 : Февраль 19, 2014, 08:27 »

Уже и не вспомню, мне просто надо было по-быстрому запросы адекватно погонять, вот я на коленке и написал тут приблуду, в 4ке тоже писал на коленке и по-быстрому, так что найти не могу.
Ну и интересно то, что запросы туда уходят нормально с русским текстом, и, судя по всему, выполняются там тоже адекватно. Именно отображение на стороне клиента так себя ведет
Записан
OKTA
Гость
« Ответ #5 : Февраль 19, 2014, 09:10 »

А пробовали принимать данные в чистом виде, без перекодирования и смотреть, что приходит? По одним кодам символов можно выяснить, что за кодировка, если все так запутано.
Записан
Johnik
Крякер
****
Offline Offline

Сообщений: 339


Просмотр профиля
« Ответ #6 : Февраль 19, 2014, 10:26 »

Код
C++ (Qt)
QTextCodec::setCodecForLocale(QTextCodec::codecForName("CP866"));
не пробовали?

еще вариант настроить локали в строке подключения ODBC:
параметры: client_locale=;db_locale=;

какая у вас строка подключения?
Записан
kai666_73
Крякер
****
Offline Offline

Сообщений: 319


Просмотр профиля
« Ответ #7 : Февраль 19, 2014, 11:01 »

Есть такая беда:
в 4.7 помогала ф-я setCodecForCStrings
в 4.8 и далее уже никак (

Код
C++ (Qt)
QTextCodec::setCodecForLocale(QTextCodec::codecForName("CP866"));
не пробовали?

еще вариант настроить локали в строке подключения ODBC:
параметры: client_locale=;db_locale=;

какая у вас строка подключения?


В стандартном ODBC-драйвере от Qt нет обработки таких параметров...
Так что, придется писать свой драйвер, либо патчить Qt-шный (что не комильфо)
Записан
Bepec
Гость
« Ответ #8 : Февраль 19, 2014, 11:03 »

Так тупо кодировать строки в Cp866 и отправлять. Хотя тут непонятно что у вас на приёме.
Записан
Johnik
Крякер
****
Offline Offline

Сообщений: 339


Просмотр профиля
« Ответ #9 : Февраль 19, 2014, 11:42 »


еще вариант настроить локали в строке подключения ODBC:
параметры: client_locale=;db_locale=;

В стандартном ODBC-драйвере от Qt нет обработки таких параметров...
Так что, придется писать свой драйвер, либо патчить Qt-шный (что не комильфо)
не поленился, посмотрел драйвер ODBC в исходниках Qt.
QODBC обрабатывает всего несколько параметров:
DRIVER=; SERVER=; FILEDSN=; DSN=; UID=; PWD=
остальные транслирует напрямую вышестоящему драйверу

так что все ж можно попробовать параметры: client_locale=;db_locale=;


carrygun, какая у вас строка подключения к базе?
Записан
kai666_73
Крякер
****
Offline Offline

Сообщений: 319


Просмотр профиля
« Ответ #10 : Февраль 19, 2014, 12:07 »

не поленился, посмотрел драйвер ODBC в исходниках Qt.
QODBC обрабатывает всего несколько параметров:
DRIVER=; SERVER=; FILEDSN=; DSN=; UID=; PWD=
остальные транслирует напрямую вышестоящему драйверу

так что все ж можно попробовать параметры: client_locale=;db_locale=;


Сорри, попутал databaseName и connectOptions.
Записан
carrygun
Гость
« Ответ #11 : Февраль 20, 2014, 04:29 »


так что все ж можно попробовать параметры: client_locale=;db_locale=;


carrygun, какая у вас строка подключения к базе?

Я подключаюсь простым добавлением QODBC в QSqlDatabase, устанавливаю имя DSN и подключаюсь. Локаль базы и клиента установлены в odbcad'е 1251 и 866 соответственно. Смена локали на утф8 не помогает, потому что Informix драйвер просто не умеет такую кодировку.

А кракозябры приходят уже от одбц плагина, так что наверное его надо в сорцах ковырять.
Записан
carrygun
Гость
« Ответ #12 : Февраль 20, 2014, 05:11 »

Так, есть успехи, но нужен ваш совет.

Сегодня дошли руки до сорцов плагина и, собственно, до ковыряния в них. Русский текст достать мне удалось., для этого я завел тексткодек следующим образом:

Код
C++ (Qt)
QTextCodec *RU_Locale = QTextCodec::codecForName("CP1251");

Далее в функции qGetStringData, в условии где unicode == false изменил строку
Код
C++ (Qt)
fieldVal += QString::fromUtf8((const char *)buf.constData(), rSize);
на
Код
C++ (Qt)
fieldVal += RU_Locale->toUnicode((const char *)buf.constData(), rSize);

Это конечно сработало, но как уже говорили - это не комильфо. Поэтому такой вопрос можно ли както на ходу в плагине узнавать клиент локаль?
Записан
Johnik
Крякер
****
Offline Offline

Сообщений: 339


Просмотр профиля
« Ответ #13 : Февраль 20, 2014, 08:05 »

Как вариант, написать собственную реализацию драйвера ODBC для informix, на основе QODBC.
Записан
kai666_73
Крякер
****
Offline Offline

Сообщений: 319


Просмотр профиля
« Ответ #14 : Февраль 20, 2014, 12:18 »

Поэтому такой вопрос можно ли както на ходу в плагине узнавать клиент локаль?

Оо, это исходник драйвера, а не плагина, но не суть...
Использовать setConnectOptions
Код:
    QSqlDatabase db = QSqlDatabase::addDatabase("QODBC", connName);
    db.setConnectOptions("SQL_ATTR_CODEC=Windows-1251");
а на стороне драйвера подкорректировать
Код:
bool QODBCDriverPrivate::setConnectionOptions(const QString& connOpts)
{
    ...
        } else if ( opt.toUpper() == QLatin1String("SQL_ATTR_CODEC") ) {
            m_codec = QTextCodec::codecForName(val.toLatin1());
        } else {
                qWarning() << "QODBCDriver::open: Unknown connection attribute '" << opt << '\'';
        }
    ...
    return true;
}

как-то так

Upd: ну еще сам кодек протащить через дебри пимпла, но это уже дело техники.
А насчет не комильфо, это да... сам пользуюсь правленным QODBC-драйвером, а надо бы реквестить...
« Последнее редактирование: Февраль 20, 2014, 12:29 от kai666_73 » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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