SQLiteおよび完全なUNICODE

おそらく多くの人が、 SQLiteデータベースの埋め込みを知っています。 SQLiteは、UTF-8およびUTF-16エンコーディングを完全にサポートしています。 ただし、1つの注意点があります。文字がASCIIテーブルの外にある文字列フィールドとテキストフィールドでは、大文字と小文字を区別しないLIKEとORDER BYは機能しません。

例:

 sqlite> SELECT "s" LIKE "s";
 0
しながら

 sqlite> SELECT "s" LIKE "S";
 1
修正方法を見てみましょう。



長時間のグーグルは、SQLiteのICU拡張機能につながります。 readmeからわかるように、ICU拡張機能は、大文字と小文字の変換を行うupper()およびlower()関数を置き換えます。 さらに、この拡張機能は、正規表現でテキストフィールドを選択するためのREGEXP演算子の実装を追加します(SQLiteは言語レベルでREGEXP演算子をサポートしますが、それを実装する関数は実装なしで配信され、カスタム実装が期待されます)。



ICU拡張機能の使用を開始するには、最初にそれを動的ライブラリにコンパイルする必要があります。

これを行うには、icu unicodeサポートライブラリとICU拡張コード自体が必要です。

Mac OSの場合(macportsがインストールされていると仮定):

 $ sudo port install icu
 $ wget http://www.sqlite.org/cvstrac/getfile?f=sqlite/ext/icu/icu.c
 $ gcc -dynamiclib icu.c -o libsqliteicu.dylib `icu-config --cppflags`` icu-config --ldflags`
またはDebian:

 $ sudo apt-get install libicu-dev
 $ wget http://www.sqlite.org/cvstrac/getfile?f=sqlite/ext/icu/icu.c
 $ gcc -shared icu.c -o libsqliteicu.so `icu-config --cppflags`` icu-config --ldflags`


SQLite3 CLIを実行し、結果を楽しんでください:)

 $ sqlite3
負荷延長
 sqlite> .load libsqliteicu.dylib
ロシア語の照合をインストールする
 sqlite> SELECT icu_load_collat​​ion( 'ru_RU'、 'RUSSIAN');
 sqlite> SELECT "s" LIKE "s";
 1


しかし、結局のところ、すべてがそれほど単純ではありません。 CLI経由ではなくAPI経由で拡張機能をロードするには、 sqlite3_enable_load_extension関数を呼び出す必要があります。 ご使用の言語のSQLiteドライバーにこの関数のラッパーがある場合、またはC / C ++で記述している場合は、すべて正常です。 しかし、ここにRuby用のRubyドライバーであるruby-sqlite3があり、この関数はサポートしていません...



最初の考えは、この機能をドライバーに追加することです:)しかし、オプションはより簡単な方法で見つかりました。 ICU拡張機能をSQLiteに組み込むことができることがわかりました。

 $ wget http://www.sqlite.org/sqlite-amalgamation-3.6.13.tar.gz
 $ tar xzfv sqlite *
 $ cd sqlite *
 $ CFLAGS = '-Os -DSQLITE_ENABLE_ICU' CPPFLAGS = `icu-config --cppflags` LDFLAGS =` icu-config --ldflags` ./configure
 $ make && sudo make install


その後、Rubyのアダプターを再インストールして(再構築するため)、問題の解決を喜んでください:)



しかし、もちろん、いくつかの短所がありました。 ICUに依存しているため、ライブラリの重量は数メガバイトになりますが、これは組み込みデータベースにはあまり適していません。 (私の場合のように)サイトにsqliteが使用されている場合、これは心配する必要はありません。

解決策は、 sqlite3_create_collat​​ionを使用して独自の照合を作成することです



UPD: Sequel Rubyライブラリを使用する人向け。 上で言ったように、ICU拡張機能はREGEXPステートメントも追加します。 ただし、Sequelで、たとえば次のような正規表現を使用してクエリを実行しようとすると
 p DB [:アーティスト] .filter(:名前=> /^a.*/i).all
実行すると、SQLiteが正規表現をサポートしていないことがスローされます。

これを回避するために、私は小さな猿パッチを書きました。




All Articles