Informix GLS

Коротко

Для тех, кто торопится, не хочет разбираться в тонкостях и стремится лишь к тому, чтобы избавиться от ошибок, связанных с доступом к локализованным базам данных, можно сказать следующее:

Кодировки, заданные этими двумя переменными, должны быть либо одинаковыми, либо совместимыми.

Пример: база данных создана в кодировке CP866 (DOS), а клиентская программа должна работать в кодировке Windows-1251. На стороне клиента до его запуска следует установить окружение:

	DB_LOCALE=ru_ru.866
	CLIENT_LOCALE=ru_ru.1251

Кодировки русского языка, поддерживаемые в Informix

Обозначение кодировки в переменной окружения задается в виде ru_ru.имя_кодировки

Для самых распространенных кодировок можно использовать следующие имена:

Название кодировкиВозможные имена кодировок
DOS866, PC866, pc-cyrillic, CIS-1
Windows1251, pc-slavic, CP1251
koi-857382, KOI-8
ISO 8859-5915, Cyrillic-8bit, 8859-5, Latin-Cyrillic

Теперь - подробнее.

Документация IBM

Все, что здесь описано, на самом деле можно найти на странице GLS User's Guide в онлайн-архиве документации. Ссылка указывает на документ, относящийся к версии 12.10.

Структура GLS

Предупреждение: здесь описаны правила именования и форматы некоторых файлов, используемых в подсистеме поддержки национальных языков Informix. Эти описания в ряде случаев могут помочь при самостоятельном решении проблем, возникающих при работе с локализованными базами данных. Не пытайтесь редактировать файлы - последствия могут быть непредсказуемы.

GLS - аббревиатура, означающая "Global Language Support"

Большинство файлов, отвечающих за поддержку GLS, располагаются в каталоге $INFORMIXDIR/gls, в пяти подкаталогах:

Содержимое подкаталогов dll и etc нас пока не интересует.

Кроме того, имеется также каталог $INFORMIXDIR/msg, где размещаются тексты сообщений СУБД, в том числе и локализованные.

Каталоги gls и msg всегда присутствуют на стороне сервера. Если на клиентской стороне установлен Informix-Connect, они также имеются и на стороне клиента.

Реестр кодировок - подкаталог gls/cm3

Список всех известных Informix кодировок находится в файле registry. Назначение и формат файла весьма подробно описаны в комментариях, приведенных в начале этого файла. Если коротко - это простой текстовый файл, каждая строка которого описывает одно имя кодировки. Строки выглядят примерно так:

	pc-slavic       1251    # 0x04e3 (Microsoft Code Page 1251)
	CP1251          1251    # 0x04e3 (Microsoft Code Page 1251)
	utf8            57372   # 0xe01c

Все, что указано после символа решетки (#), как обычно, считается комментарием. С учетом этого каждая строка состоит из двух полей:

В комментарии для удобства обычно указывается еще и номер кодировки в шестнадцатеричном виде - далее будем называть его идентификатором кодировки. Номер и идентификатор - это одно и то же число, просто они записаны в разных форматах. Номер указывается в десятичной системе - для удобства чтения - и обычно используется только в названиях локализаций (кодировок), указываемых в переменных окружения. Идентификатор указан в шестнадцатеричном виде и используется повсеместно в GLS в именах файлов и каталогов.

В файле registry перечислены все мыслимые кодировки, поддерживаемые Informix в принципе. При этом, скорее всего, далеко не все из них поддерживаются именно в вашей инсталляции.

В этом же каталоге располагаются списки символов, включенных в каждую кодировку - файлы .cmo (charmap object). Эти списки в общем случае предназначены для контроля корректности символьных данных, передаваемых от клиента на сервер, и позволяют исключить обработку строк, содержащих символы, отсутствующие в той или иной кодировке.

Список для каждой кодировки находится в отдельном файле. Имя файла - это идентификатор кодировки, к которому добавлен суффикс .cmo. Например, файл 04e3.cmo описывает набор символов кодировки Windows-1251, а файл e01c.cmo - набор символов кодировки UTF-8. Файлы эти - текстовые, так что при необходимости можно посмотреть, какие именно символы входят в ту или иную кодировку.

Описание каждого символа состоит из пяти полей:

Если для какой-то кодировки файл .cmo отсутствует - соответствующая кодировка не поддерживается в вашей инсталляции

Таблицы перекодировки - подкаталог gls/cv9

Каталог содержит набор таблиц перекодировки, используемых для трансляции текстов из одной кодировки в другую. Каждая таблица размещена в файле .cvo (codeset conversion object). Имя файла составлено из идентификаторов исходной и целевой кодировок, к полученной строке добавлен суффикс .cvo. Например, правила перекодировки из Windows-1251 в UTF-8 описаны в файле 04e3e01c.cvo, а правила перекодировки в другую сторону - в файле e01c04e3.cvo.

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

Файлы .cvo - также текстовые, и их можно просмотреть, но интерес могут представлять только заголовки. Сама таблица перекодировки хоть и представлена в виде текста, но для познавательного чтения, скорее всего, непригодна.

Описания локализаций - подкаталог gls/lc11

Здесь располагаются описания локализаций, разбитые по группам язык-территория. Каждая группа размещена в подкаталоге, имя которого образовано из обозначения языка и обозначения территории в соответствии со стандартом ISO. Например, для русского языка имеется одна группа с именем ru_ru - язык "ru" (русский) и территория "ru" (Россия). Для португальского языка присутствуют две группы - pt_pt (португальский - Португалия) и pt_br (португальский - Бразилия). Полный список можете посмотреть в вашей инсталляции.

В подкаталоге каждой группы размещены описания локализаций для соответствующих языка и территории. Имя файла локализации - это идентификатор кодировки, к которому добавлен суффикс .lco (locale object). Сама локализация состоит из нескольких секций:

В чем-то этот механизм дублирует набор локализаций, стандартно присутствующих, скажем, в UNIX. Включение в СУБД собственного механизма поддержки локалей, по-видимому, вызвано стремлением обеспечить независимость работы СУБД от текущей конфигурации операционной системы. Помимо этого, так как поддержка локалей обеспечивается только собственными средствами Informix, она по идее должна работать одинаково и в UNIX, и в Windows.

Ergo, описание локализации для кодировки Windows-1251 для русского языка находится в файле

	$INFORMIXDIR/gls/lc11/ru_ru/04e3.lco

Как это все работает

Перед подключением клиентской программы к локализованной базе данных необходимо установить значения двух переменных окружения:

Имя локализации записывается в виде

	язык_территория.кодировка

Что такое язык и территория - описано в предыдущем пункте. В качестве имени кодировки можно указать либо ее номер (не идентификатор!), либо одно из имен, поставленных в соответствие этому номеру в файле cm3/registry. Так, для базы, созданной в кодировке MS-DOS (CP866), переменная DB_LOCALE может содержать любое из значений

	ru_ru.866
	ru_ru.pc-cyrillic
	ru_ru.CIS-1
	ru_ru.PC866

В момент попытки подключения к базе значение каждой переменной разбивается по точке на две части - язык+территория и кодировка. Далее просматривается файл registry, и для каждой кодировки по имени определяется ее идентификатор. Затем проверяется наличие в системе всех необходимых для работы файлов:

Если какие-либо из этих файлов не обнаружены, подключение невозможно. Текст сообщения об ошибке зависит от того, какие именно из перечисленных файлов не обнаружены.

Если все необходимые файлы есть в наличии, проверяется соответствие значения переменной DB_LOCALE реальной локализации нужной базы данных. Если при этом обнаруживается несоответствие, подключение также невозможно - вы получите сообщение Database locale information mismatch

Сортировка и перекодировка

Сортировка данных всегда выполняется на стороне сервера. С учетом локализации (LC_COLLATE) сортируются данные, размещенные в полях типа NCHAR и NVARCHAR. Данные всех прочих символьных типов сортируются независимо от установленной локали - то есть только с учетом двоичных кодов символов.

Перекодировка данных, как правило, выполняется на стороне клиента. Перекодировке подвергаются данные, размещенные в полях типа CHAR, VARCHAR, LVARCHAR, NCHAR, NVARCHAR и TEXT.

Если локали клиента и базы совпадают

Особый случай - если клиент должен работать в той же локали, в которой создана база данных. В такой ситуации значения переменных DB_LOCALE и CLIENT_LOCALE будут одинаковы (или по крайней мере обозначать одну и ту же локаль). Все остается по-прежнему, за исключением двух моментов:

  1. перекодировка данных не происходит - поэтому поиска таблиц перекодировки нет
  2. не выполняется контроль корректности символьных данных - строки, передаваемые клиентом на сервер, могут содержать любые символы, в том числе и отсутствующие в выбранной кодировке, и они будут сохраняться в базе "как есть"

Как определить, в какой локализации создана база данных

Чтобы подключиться к локализованной базе данных, нужно заранее знать, в какой именно локализации она создана. Чтобы выяснить это, достаточно выполнить запрос в базе sysmaster

	echo 'select dbs_collate from sysdbslocale where dbs_dbsname = "имя_базы"' | dbaccess sysmaster

Результат может выглядеть так:

	Database selected.

	dbs_collate                      

	ru_RU.866                       

	1 row(s) retrieved.

	Database closed.

База создана в кодировке CP866.

Служебная база sysmaster не считается локализованной, поэтому подключение к ней будет успешным независимо от того, какие значения DB_LOCALE и CLIENT_LOCALE при этом установлены (и установлены ли вообще).

Если нужной кодировки (локализации) нет

В стандартной поставке Informix Server и Informix Connect присутствует ограниченное число наиболее популярных кодировок и локализаций. Если оказалось, что нужной кодировки (локализации) в вашем варианте нет, можно попытаться доставить недостающие компоненты из пакета International Language Supplement (входит в Informix Client SDK или доступен отдельно через техподдержку).

Java-клиенты

Все изложенное выше относится к клиентам, подключающимся к СУБД Informix через Informix-Connect. Java-клиенты работают с базами через драйверы JDBC и не требуют наличия Informix-Connect на клиентской стороне, так как весь необходимый функционал встроен непосредственно в драйвер.

Так как Java-программы всегда работают в кодировке Unicode, указывать CLIENT_LOCALE нет смысла. В URL подключения к базе указывается только DB_LOCALE - например, так:

	jdbc:informix-sqli://хост:порт/имя_базы:DB_LOCALE=ru_ru.866;INFORMIXSERVER=имя_сервера;

Обязательно указывать только DB_LOCALE и INFORMIXSERVER; при необходимости можно задать и другие переменные окружения.