ФЭНДОМ


Статус: Черновик

Для взаимодействия с базами данных из Inferno вам понадобятся:

  1. Настроенная, работающая БД и пользовательский логин/пароль для доступа к ней;
  2. Установленное и настроенное ODBC;
  3. Запущенный в Inferno ODBC сервер dbsrv(7);
  4. Ваше 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/