Transactd での文字コード

文字コードを正しく扱うには、データベースに定義された文字コードとクライアントプログラム実行環境で使用する文字コードを正しく指定する必要があります。

Transactdで日本語を扱うには、MySQL/MariaDBのcharacter-set-serverutf8utf8mb4またはcp932でなければなりません。

Transactdで扱うデータベースの文字コード

Transactdで扱うデータベースの文字コードには、以下の3つがあります。

  1. フィールドの値の文字コード
  2. テーブル名、フィールド名の文字コード
  3. 2以外のメタ情報の文字コード(データベース名など)

(1) フィールドの値の文字コード

SQLのSHOW CREATE TABLE文で確認できる、文字列フィールドの値の文字コードです。Transactdではfielddef::charsetIndex()で確認できます。

この文字コードはテーブルの設計で決まります。

(2) テーブル名、フィールド名の文字コード

Transactdのスキーマテーブルの文字コードです。tabledef::schemaCodePageで確認できます。スキーマテーブルを自動生成した場合はutf8が使用されます。

スキーマテーブルを自分で作成した場合は、tabledef::schemaCodePageで指定した任意の文字コードです。

(3) 2以外のメタ情報の文字コード

(2)以外のメタ情報文字コードはutf8が使用されます。

クライアントプログラム実行環境で使用するデフォルトの文字コード

データベースの文字コードは上記の3つに分類できますが、クライアントプログラムで使用している文字コードがわからないと、APIは結果を正しくエンコードできません。そのため、nsdatabase::setExecCodePage(unsigned int codepage)を使用して、クライアントプログラムで使用する文字コードのコードページを指定します。

何も指定していない状態のデフォルトでは、WindowsではCP_ACP、その他の環境ではCP_UTF8です。

WindowsのUNICODE版のライブラリの場合は、クライアントプログラムの文字コードはutf16で固定であるため、nsdatabase::setExecCodePageで指定した値は無視されます。

APIの使用

(1) フィールドの値のセットと読取

フィールドの値のセット・読取は、自動でnsdatabase::execCodePage()からfielddef::charsetIndex()またはその逆に変換されます。table::setFV(short index, const char* data)dataパラメータなどが該当します。

2つの文字コードが一致した場合は変換は起こりません。

WindowsのUNICODE版のライブラリの場合は、utf16を使用してください。セット・読取ともに、自動でutf16からfielddef::charsetIndex()またはその逆に変換されます。

(2) テーブル名、フィールド名のセットと読取

テーブル名とフィールド名は、Transactd専用のスキーマテーブルに保存されいる値から検索や照合が行われます。table::setFV(const char* name, const char* data)nameパラメータなどが該当します。

スキーマテーブルを自動生成した場合は、utf8でエンコードされた文字列で指定してください。

スキーマテーブルを自分で作成した場合は、tabledef::schemaCodePage()で任意のコードページを指定することができます。この場合、テーブル名とフィールド名はschemaCodePage()で指定したコードページの文字列で指定します。

WindowsのUNICODE版のライブラリの場合は、utf16を使用してください。セット・読取ともに、自動でutf16からtabledef::schemaCodePage()またはその逆に変換されます。

(3) (2)以外のメタ情報(データベース名など)のセットと読取

データベース名など、テーブル名とフィールド名以外のメタ情報は、常にutf8を使用してください。database::open()uriパラメータなどが該当します。

これらの情報はTransactd Pluginを通じてMySQL/MariaDB内部の関数に渡されます。それらは常にutf8で処理されます。

WindowsのUNICODE版のライブラリの場合はutf16を使用してください。自動でutf16からutf8またはその逆に変換されます。

パターン別簡単設定

(a) Linux、Mac OS Xでの C++ / PHP / Ruby

(1) プログラムの記述はutf8で行ってください。nsdatabase::execCodePage()はデフォルトでutf8なので何も設定は必要ありません。

(2) スキーマを自分で作成する場合も、すべてutf8で記述してください。tabledef::schemaCodePageはデフォルトでutf8なので何も設定は必要ありません。

(3) (2)以外のメタ情報もすべてutf8で記述してください。

フィールドの値や名前、テーブル名、データベース名などすべてをutf8で指定すればOKです。

ただし、フィールドの値がマルチバイト文字を使用しcp932utf16utf8以外でエンコードされている場合は、後述の文字コード変換の詳細DDL処理の詳細を参照して対応を行ってください。

(b) Windowsでの C++ / COM(JScript, C#)

C++の場合は、UNICODE版のバイナリを使用してください。COMはデフォルトでUNICODE版のバイナリです。

プログラムの記述はcp932utf16どちらでも構いません。C++の場合は、コンパイラの設定をUNICODE文字コードセットを使う設定にしてください。

UNICODE版は、(1)(2)(3)のすべてで、自動で必要な文字コード変換が行われます。最も簡単な選択肢です。

(c) Windowsでの PHP / Ruby

(1) プログラムの記述はutf8で行ってください。PHP/Ruby用ライブラリ内部のdatabaseオブジェクトのコンストラクタで、自動でnsdatabase::setExecCodePage(CP_UTF8)が呼び出されているため、明示的な設定は不要です。

(2) スキーマを自分で作成する場合も、すべてutf8で記述してください。tabledef::schemaCodePageはデフォルトでutf8なので何も設定は必要ありません。

(3) (2)以外のメタ情報もすべてutf8で記述してください。

フィールドの値や名前、テーブル名、データベース名などすべてをutf8で指定すればOKです。

(d) cp932でプログラムを記述したい場合

※処理が煩雑になるため、推奨されません。既存のデータベースがすべてcp932であるなどの特別な都合がない場合は、他の設定を使ってください。

(1) MySQL/MariaDBのcharacter-set-servercp932を指定します。プログラムではnsdatabase::setExecCodePage(CHARSET_CP932)を設定します。PHP/Rubyなどから使用する場合は、cp932でプログラムを記述し保存します。

(2) テーブル名、フィールド名に日本語がある場合は、Transactdのスキーマテーブルのtabledef::schemaCodePagecp932を指定して、TransactdのAPIを使用してテーブルを生成します。あるいは、自動生成されたスキーマテーブルを開き、tabledef::schemaCodePagecp932を指定して、テーブル名とフィールド名の値をcp932に変換して設定した後に、updateTableDefで保存してください。

(3) データベース名は必ずプログラムコード上でutf8の文字列に変換してから指定してください。

文字コード変換の詳細

Transactdの文字コード変換は、すべてクライアントサイドで行われます。サーバー内で文字コード変換がされることはありません。

Windowsでの変換には、OSのMultiByteToWideCharWideCharToMultiByteが使用されます。

Linuxではiconvを使って変換します。変換を高速に行うために、文字コードの組み合わせごとに変換ライブラリをオープンしてキャッシュしています。デフォルトのキャッシュはmbcsutf16utf8の3つの文字コードのすべての組み合わせの6つです。

mbcsの文字コードは、デフォルトのSHIFT-JISが、mbcswchrLinux.hMBC_CHARSETNAMEマクロで指定されています。 デフォルトのmbcsを変更する場合は、MBC_CHARSETNAMEを変更してコンパイルし直す必要があります。

また、複数のmbcsを同時に使用する場合は、mbcswchrLinux.hおよびmbcswchrLinux.cppのコードに変更を加える必要があります。

DDL処理の詳細

TransactdのDDL処理には、SQLレイヤーを使用して行っているものがあります。MySQL/MariaDBの内部処理はすべてutf8ですが、SQLレイヤーに渡す文字列はMySQL/MariaDBのcharacter-set-serverで指定された文字コードで渡さなければなりません。

通常プログラマはSQLレイヤーに渡す文字コードを意識する必要はありませんが、Linuxの場合、character-set-servericonvキャッシュにキャッシュされたmbcs(デフォルトでSHIFT-JISutf16utf8のいずれかでないと正しくエンコードできません。

コードページ一覧

execCodePageschemaCodePageとして指定するコードページは、ソースコードのcharacterset.cppを参照してください。