- Статус: Черновик
Для взаимодействия с базами данных из Inferno вам понадобятся:
- Настроенная, работающая БД и пользовательский логин/пароль для доступа к ней;
- Установленное и настроенное ODBC;
- Запущенный в Inferno ODBC сервер dbsrv(7);
- Ваше Limbo-приложение должно подключить модуль db(7);
Давайте подробнее остановимся на каждом из перечисленных пунктов.
База данных[]
- Рассказ о том, как устанавливать и настраивать конкретную БД, выходит за пределы этой заметки. Следует упомянуть лишь о том, что если машина с запущенной БД и запущенная служба ODBC находятся на разных машинах, то вам необходимо настроить БД, так чтобы она прослушивала реальный сетевой интерфейс такой как "10.0.0.15", и конечно не следует забывать о файерволе. Это будет легко проверить, инициировав соединение от машины с ODBC к машине с БД при помощи telnet server_address DB_port.
username$ telnet 192.168.0.33 5432 Trying 192.168.0.33... Connected to 192.168.0.33. Escape character is '^]'.
Соединение установлено, сервер готов принимать запросы.
Настройка ODBC[]
- Предполагается, что мы делаем доступ к серверу с Unix-машины (вариант с Windows оставим на потом/не будем рассматривать).
- Первое что нам понадобится, это остановить свой выбор на одном из двух кандидатов unixODBC или iODBC. После того, как вы установите одного из них, вам потребуются ODBC-драйвера к вашей конкретной базе данных. Надеюсь, что их сборка/установка не доставят вам хлопот.
- Следующее действие, файл-конфигурация ODBC. Вы можете воспользоваться для его генерации GUI-приложением, либо создать его вручную. В результате, ваш файл /etc/odbcinst.ini примерно должен выглядеть следующим образом:
[PostgreSQL] Description = PostgreSQL driver for Linux & Win32 Driver = /usr/lib/psqlodbcw.so Setup = /usr/lib/libodbcpsqlS.so FileUsage = 1 UsageCount = 1
А файл с /etc/odbc.ini содержащий записи DSN так:
[itemname] Driver = /usr/lib/psqlodbcw.so Database = dbname Servername = 192.168.0.33 USER = dbuser PASSWORD = dbpassword Port = 5432 ReadOnly = No Trace = 1 TraceFile = /tmp/sql.log Debug = 1 DebugFile = /tmp/odbcdebug.log
Запуск dbsrv в Inferno[]
- Нам нужен откомпилированный файл infdb из tools/db/. (Он уже скомпилирован для Windows-версии Inferno и расположен в Nt/386/bin/infdb.exe). (Обратите внимание! Если вы установили unixODBC, в файле tools/db/mkfile исправьте строку "SYSLIBS= -liodbc" на "SYSLIBS= -lodbc")
После того, как вы выполните его компиляцию вам понадобится переписать его в системный каталог:
export PATH=/usr/local/inferno/`uname`/386/bin:$PATH cd /usr/local/inferno/tools/db mk # теперь скопируем infdb в каталог содержащийся в PATH cp infdb.o /usr/bin/infdb chmod 755 /usr/bin/infdb chown root /usr/bin/infdb chgrp root /usr/bin/infdb
В Inferno, нам нужно сделать доступным командный интерпретатор хост-ОС:
bind -b '#C' /
убедимся, что в каталоге /cmd есть файлы:
% ls /cmd /cmd/clone
Теперь запустим службу на Inferno-машине выступающей шлюзом к ODBC, которая будет прослушивать порт 6669:
listen -A tcp!192.168.0.55!6669 lib/dbsrv none
Мы не задали никакой авторизации для нее (параметр -A и опция none)
Limbo-приложение и модуль db(7)[]
- Общие положения даны в Поддержка баз данных.
Возникшие нюансы[]
- Бинарная сборка драйверов ODBC для MySQL распространяется без поддержки unicode-кодировки. Собирать из исходников из-за кучи ошибок не стал, и желания разбираться с этим не возникло. (Гугль говорит о том, что для китайско-японского сегмента интернета это является проблемой уже многие годы и ситуация не меняется.) Выбор, таким образом был сделан в пользу PostgresSQL у которой с поддержкой национальных кодировок все намного лучше (если не совсем хорошо).
- Все ниже приведенное относится исключительно к БД PostgreSQL.
- Соединение устанавливаем к машине с запущенной службой dbsrv:
(dh, errs) := db->open("192.168.0.55", "dbuser", "dbpassword", "itemname");
С оператором SELECT проблем не возникло:
sql := "SELECT * FROM test;"; (status, errmsg) := dh.SQL(sql);
Зато с INSERT оказалось не все так просто. Для того, чтобы запись добавилась в базу, необходимо запрос оформить как транзакцию. Хотя в документации и написано, что по-умолчанию клиентские библиотеки PostgreSQL каждый запрос оформляет как транзакцию, мне не удалось воспроизвести, и каждый запрос на добавление/обновление записей я записывал как классическую транзакцию.
BEGIN; INSERT INTO test (uid, firstname, lastname) VALUES ('007', 'James', 'Bond'); -- .... что-то еще .... COMMIT;
Ссылки на проекты интерфейсов к PostgreSQL:
http://code.google.com/p/limbo-machine/
http://www.maht0x0r.net/inferno/