[pgsql-jp: 37700] 透過的に翻訳メッセージを返す方法

EBIHARA, Yuichiro ebihara @ iplocks.co.jp
2006年 11月 20日 (月) 23:27:59 JST


こんにちは、海老原です。
透過的なi18nの実現方法に関する質問です。

同一のSELECT文に対して、クライアントの言語設定に依存する翻訳
メッセージを返す方法を思案しています。
環境はPostgreSQL 8.1.4(WindowsとLinux両方)で、データベースキャラ
クタセットはUTF-8に設定されているものとします。

例えば、都市の名前と国と人口を管理するとします。
都市名を翻訳の対象とすると、以下のようなスキーマが考えられます。

-- 都市コード、国コード、人口
CREATE TABLE cities (
  city_id VARCHAR(10) NOT NULL,
  country VARCHAR(2) NOT NULL,
  population INTEGER,
  CONSTRAINT messages_pk PRIMARY KEY (city_id)
);

INSERT INTO cities VALUES ('TKY', 'JP', 12640000);
INSERT INTO cities VALUES ('NYK', 'US', 8210000);

-- 都市名(各国語に翻訳)
CREATE TABLE cities_tr (
  city_id VARCHAR(10) NOT NULL,
  lang VARCHAR(2) NOT NULL,
  city_name VARCHAR(100),
  CONSTRAINT cities_tr_pk PRIMARY KEY (city_id, lang),
  CONSTRAINT cities_tr_fk FOREIGN KEY (city_id) REFERENCES cities (city_id)
);

INSERT INTO cities_tr VALUES ('TKY', 'en', 'Tokyo');
INSERT INTO cities_tr VALUES ('TKY', 'ja', '東京');

INSERT INTO cities_tr VALUES ('NYK', 'en', 'New York');
INSERT INTO cities_tr VALUES ('NYK', 'ja', 'ニューヨーク');

ここで、cities_trのlang列にはISO言語コード(ISO-639)を使用します。
つまり、小文字アルファベットで2文字です。

で、例えば次のようなビューを作成すると、セッションのlc_messages
設定に応じて、自動的に適切な翻訳が出てくるわけです。

CREATE VIEW cities_v AS
  SELECT a.city_id, b.city_name, a.population
  FROM cities a, cities_tr b
  WHERE b.city_id = a.city_id
    AND b.lang = substr(current_setting('lc_messages'), 1, 2);

testdb=# set lc_messages to 'ja_JP.utf8';
SET
testdb=# SELECT * FROM cities_v;
 city_id |  city_name   | population
---------+--------------+------------
     100 | 東京         |   12640000
     200 | ニューヨーク |    8210000
(2 rows)

testdb=# set lc_messages to 'en_US.utf8';
SET
testdb=# SELECT * FROM cities_v;
 city_id | city_name | population
---------+-----------+------------
     100 | Tokyo     |   12640000
     200 | New York  |    8210000
(2 rows)


これはOracleのセッション言語を返す関数 sys_context('USERENV', 'LANG')
を使った常套手段にヒントを得ているのですが、PostgreSQLにおいて
current_setting('lc_messages')の上記のような使用は妥当だと思いますか?
Java+JDBCのアプリなら、システムプロパティuser.languageとかを透過的に
使えるととてもうれしいのですが。

また、それしかないとして、lc_messagesの設定はやはりSETコマンドか、
環境変数PGOPTIONSでしょうか?
libpqアプリケーションであれば環境変数LANGやLC_MESSAGESが自動的に
反映されるとよいのですが。

マニュアルは一通り見ていますが、何か見落としているかもしれません。
色々なご意見を聞くことができればうれしいです。

--
海老原 雄一郎 / EBIHARA, Yuichiro
  Email: ebihara @ iplocks.co.jp





pgsql-jp メーリングリストの案内