Поставили задачу на работе, перевести приложения с PostgreSQL под СУБД Informix. Ничто не поделаешь... Взял доки, подключил инет и начал шаманить :) Что из этого вышло читаем в статье.
Задачи:
1. Установить Informix clientSDK в Ubuntu
2. Настроить clientSDK + unixODBC
3. Связать Qt4 и Informix через unixODBC
Что имеем, клиент:
Linux serge-noutebook 2.6.38-8-generic-pae #42-Ubuntu SMP Mon Apr 11 05:17:09 UTC 2011 i686 i686 i386 GNU/Linux |
Сервак:
# uname -a Linux rhel.local 2.6.18-194.el5 #1 SMP Tue Mar 16 21:52:43 EDT 2010 i686 i686 i386 GNU/Linux # /etc/init.d/informix status IBM Informix Dynamic Server Version 11.50.UC4DE -- On-Line -- Up 00:11:13 -- 745072 Kbytes |
onconfig - дефолтен
sqlhosts:
#demo_on onipcshm on_hostname on_servername |
Переменные окружения на сервере:
export INFORMIXDIR=/usr/informix/ export CLIENT_LOCALE=ru_RU.UTF8 |
Строка с номером порта в /etc/service :
port_alias 8201/tcp # informix |
Итак начнемс :)
Ставим unixODBC
sudo apt-get install unixodbc* |
Далее скачиваем для нужного дистрибутива clientsdk с сайта Informix client SDK. Но в связи с багнотостью регистрации, выложу файлик у себя на сервере(если IBM не понравится, думаю они сообщат:))(мне например на работе так и не удалось зарегаться на сайте IBM, в связи с "замечательном" фаерволом на моей работе). Для моего дистрибутива подходит clientsdk.3.70.UC2.LINUX.tar, что и качаем, можно и у меня.
Ставится клиент просто, распаковываем, запускаем installclientsdk. Я выбрал директорию установки /opt/IBM/informix/ и выбрал полную установку:
И так, после завершения установки, нужно задать некоторые переменные окружения. Я забил их в $HOME/.bashrc:
export ODBCINI=/etc/odbc.ini |
Тут только одно замечание, переменные DB_LOCALE и CLIENT_LOCALE выставляете свои, в соответсвии с настойками сервера Informix.
Ecли пропустить переменную LD_LIBRARY_PATH, то будем получать в дальнейшем ошибки вида:
QODBC3: Unable to connect [unixODBC][Driver Manager]Can't open lib '/opt/IBM/informix/lib/cli/iclit09b.so' : file not found |
Или например от iodbctest
$ iodbctest Enter ODBC connect string (? shows list): ? DSN | Driver Enter ODBC connect string (? shows list): bgd |
Смотрим ради интереса, с какими либами залинкована библиотечка /opt/IBM/informix/lib/cli/iclit09b.so, и видим, что ей что то не хватает :) Для этого и вводим LD_LIBRARY_PATH:
$ ldd /opt/IBM/informix/lib/cli/iclit09b.so |
И так, с переменными окружения все(как мне кажется). Приступим теперь к настойке ODBC. В директории $INFORMIXDIR/etc/ есть два примерных файла с настройками для ODBC, это - odbc.ini и odbcinst.ini. Первый это список серверов, и настроек для подключения, второй это настройка самого драйвера для подключения к Infrmix. Можно просто скопировать их в /etc/ и потом поправить. Я привожу в пример свои файлы настроек:
odbc.ini
$ cat /etc/odbc.ini |
Хочется отметить переменную ENABLESCROLLABLECURSORS, говорят, что без нее QODBC работать не будет.
odbcinst.ini
$ cat /etc/odbcinst.ini |
Так же, необходимо прописать номер порта, который слушает сервер Informix, и обозвать его так же, как назвали его в /opt/IBM/informix/etc/sqlhosts. Строку добавляем в /etc/services
informix_sql 8201/tcp # Infromix SQL |
Настройки unixODBC завершены. Проверяем как работают утилы isql и iodbctest:
$ isql bgd $ iodbctest "DSN=bgd;UID=informix;PWD=infM INFORMIX ODBC DRIVER};" SQL>quit Have a nice day. |
Маленькое замечание. Если! если у вас сервер в ru_RU.UTF8 и клиент ru_RU.UTF8б необходимо скопировать след файлик - $INFORMIXDIR/gls/lc11/en_us/e01c.lco в $INFORMIXDIR/gls/lc11/ru_ru/e01c.lco как на клиентах, так и на сервере.
Как видим все работает.
Переходим к Qt. Версия Qt у меня:
$ qmake-qt4 --version |
Ставим пакет для поддержки ODBC:
sudo apt-get install libqt4-sql-odbc |
Впринцыпе все. Но есть костыли, с которым я разбираюсь.
Код:
QSqlDatabase database = QSqlDatabase::addDatabase("QODBC"); |
И получаю загадочную ошибку при открытии БД:
QODBC3: Unable to connect [unixODBC][ |
Так что последний пункт повестки открыт :(
Добавил 16:44 18.05.2011
Итак салют найде. Второй день рыская по инету, нашел баг репорт: http://bugreports.qt.nokia.com/browse/QTBUG-14808
И теперь пишу салют.
Нам понадобятся исходники qt, или исходники драйвера ODBC для Qt. Сами исходники библиотеки скачать можно у тролей, у себя выложу только исходники QODBC поправленные мной.
1. Распаковываем исходники qt(я скачал qt-everywhere-opensource-src-4.7.3.tar.gz
2. Идем в папку qt-everywhere-opensource-src-4.7.3/src/plugins/sqldrivers/odbc/ и правим файл odbc.pro. Добавляем строчку DEFINES += Q_ODBC_VERSION_2
3. делаем qmake(qmake-qt4 "INCLUDEPATH+="куда_ставили/unixODBC-2.3.0/include/" "LIBS+=-L/usr/lib -lodbc")
4. Кидаем патч в qt-everywhere-opensource-src-4.7.3 и накладываем его patch -p1 < bug-14808.patch
5. make
6. sudo make install
Все :)
Пример кода для работы с ODBC + Informix
QSqlDatabase database = QSqlDatabase::addDatabase("QODBC"); database.setDatabaseName("DSN=bgd;DRIVER=IBM"); if(!database.open()){ QMessageBox::critical(this, "Ошибка", QString("%1\n%2\n%3\n(%4:%5)") .arg(database.lastError().driverText()) .arg(database.lastError().databaseText()) .arg("Обратитесь к системному администратору.") .arg(FILE) .arg(__LINE__)); } |
Приложу так же уже пропатченный и отредактированный мной odbc driver для qt. Он включает в себя уже патч и готов к сборке. Распаковываем, даем команду
qmake-qt4 "INCLUDEPATH+="куда_ставили/unixODBC-2.3.0/include/" "LIBS+=-L/usr/lib -lodbc" и потом sudo cp libqsqlodbc.so* /usr/lib/qt4/plugins/sqldrivers/
И все :)
P.S. Я упустил один момент. Допустим у вас базы в UTF8, ну и допустим клиент тоже в UTF8... Все описанное выше работать не будет... Если не сделать следующие... :) Всего нада скопировать $INFORMIXDIR/gls/lc11/en_us/e01c.lco в папку $INFORMIXDIR/gls/lc11/ru_ru/