Last active
May 17, 2017 09:19
-
-
Save ap-Codkelden/c5c0b8d1ed775238102eef6e2f482962 to your computer and use it in GitHub Desktop.
ICU How To
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Регистронезависимый LIKE в SQLite для кириллицы | |
Original is [here](https://medium.com/@eigenein/%D1%80%D0%B5%D0%B3%D0%B8%D1%81%D1%82%D1%80%D0%BE%D0%BD%D0%B5%D0%B7%D0%B0%D0%B2%D0%B8%D1%81%D0%B8%D0%BC%D1%8B%D0%B9-like-%D0%B2-sqlite-%D0%B4%D0%BB%D1%8F-%D0%BA%D0%B8%D1%80%D0%B8%D0%BB%D0%BB%D0%B8%D1%86%D1%8B-95e3e33e8ad) | |
При использовании `LIKE` или `ORDER BY` в SQLite с Unicode-символами может возникнуть проблема, связанная с неспособностью SQLite по умолчанию правильно воспринимать разные регистры одной и той же буквы: | |
sqlite> select "ы" like "ы"; | |
1 | |
sqlite> select "Ы" like "ы"; | |
0 | |
Поиск приводит к расширению ICU, которое переопределяет функции изменения регистра так, чтобы символы за пределами таблицы ASCII правильно приводились к заданному регистру. | |
Есть два варианта использования расширения: | |
* Скомпилировать SQLite вместе с расширением (и использовать вместо системной библиотеки). | |
* Скомпилировать расширение как Runtime Loadable Extension. | |
Мне хотелось использовать расширение через стандартный модуль `sqlite3` в Python, поэтому было решено пойти по второму пути. | |
Для начала установим необходимые пакеты с исходным кодом: | |
$ sudo apt-get install libicu-dev libsqlite3-dev | |
Скачаем исходный код самого расширения: | |
$ wget "https://www.sqlite.org/src/raw/ext/icu/icu.c?name=b2732aef0b076e4276d9b39b5a33cec7a05e1413" -O icu.c | |
А дальше — немного странный момент. Если мы сейчас скомпилируем расширение, то вероятно, получим следующую ошибку при попытке загрузить его (имя в вашей версии SQLite может быть другим): | |
sqlite> .load ./libsqliteicu.so | |
Error: ./libsqliteicu.so: undefined symbol: sqlite3_sqliteicu_init | |
Чтобы исправить ошибку, редактируем файл `icu.c`, заменяя в нем имя функции `sqlite3_icu_init` на `sqlite3_sqliteicu_init`. | |
Теперь собираем расширение: | |
$ gcc -shared icu.c -g -o libsqliteicu.so -fPIC `icu-config --cppflags --ldflags` | |
Загружаем расширение и проверяем, что все в порядке: | |
sqlite> .load ./libsqliteicu.so | |
sqlite> select "Ы" like "ы"; | |
1 | |
## Бонус | |
Для того, чтобы загрузить это расширение из Python, сначала разрешаем загрузку расширений из библиотек и затем загружаем саму библиотеку: | |
import sqlite3 | |
connection = sqlite3.connect(":memory:") | |
connection.enable_load_extension(True) | |
connection.load_extension("./libsqliteicu.so") | |
assert connection.execute("select 'ы' like 'Ы'").fetchone() == (1, ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment