Transactd での文字コード
文字コードを正しく扱うには、データベースに定義された文字コードとクライアントプログラム実行環境で使用する文字コードを正しく指定する必要があります。
Transactdで日本語を扱うには、MySQL/MariaDBのcharacter-set-server
がutf8
、utf8mb4
またはcp932
でなければなりません。
Transactdで扱うデータベースの文字コード
Transactdで扱うデータベースの文字コードには、以下の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です。
ただし、フィールドの値がマルチバイト文字を使用しcp932
utf16
utf8
以外でエンコードされている場合は、後述の文字コード変換の詳細とDDL処理の詳細を参照して対応を行ってください。
(b) Windowsでの C++ / COM(JScript, C#)
C++の場合は、UNICODE版のバイナリを使用してください。COMはデフォルトでUNICODE版のバイナリです。
プログラムの記述はcp932
utf16
どちらでも構いません。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-server
はcp932
を指定します。プログラムではnsdatabase::setExecCodePage(CHARSET_CP932)
を設定します。PHP/Rubyなどから使用する場合は、cp932
でプログラムを記述し保存します。
(2) テーブル名、フィールド名に日本語がある場合は、Transactdのスキーマテーブルのtabledef::schemaCodePage
にcp932
を指定して、TransactdのAPIを使用してテーブルを生成します。あるいは、自動生成されたスキーマテーブルを開き、tabledef::schemaCodePage
にcp932
を指定して、テーブル名とフィールド名の値をcp932
に変換して設定した後に、updateTableDef
で保存してください。
(3) データベース名は必ずプログラムコード上でutf8
の文字列に変換してから指定してください。
文字コード変換の詳細
Transactdの文字コード変換は、すべてクライアントサイドで行われます。サーバー内で文字コード変換がされることはありません。
Windowsでの変換には、OSのMultiByteToWideChar
とWideCharToMultiByte
が使用されます。
Linuxではiconv
を使って変換します。変換を高速に行うために、文字コードの組み合わせごとに変換ライブラリをオープンしてキャッシュしています。デフォルトのキャッシュはmbcs
utf16
utf8
の3つの文字コードのすべての組み合わせの6つです。
mbcs
の文字コードは、デフォルトのSHIFT-JIS
が、mbcswchrLinux.h
のMBC_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-server
はiconv
キャッシュにキャッシュされたmbcs
(デフォルトでSHIFT-JIS
)utf16
utf8
のいずれかでないと正しくエンコードできません。
コードページ一覧
execCodePage
やschemaCodePage
として指定するコードページは、ソースコードのcharacterset.cppを参照してください。