Регистронезависимый поиск руских слов в trac

Последнее время все чаще и чаще начали пользовать для внутренних нужд на работе trac. Причем если на первых порах у нас был отдельный движек под wiki и отдельно под исходники и тикеты трак, то в последствии плавно переехали на один единый движек, ибо удобно. Но недавно обнаружили досадный баг, если в поиске трака искать слова из не латинских букв, то поиск получается регистрозависимый.

Вся беда в sqlite, и если перетащить базу в pgsql, то проблема решиться сама собой (сам не пробовал), подробнее про эту проблему можно почитать тут:

http://trac.edgewall.org/ticket/7902
http://trac.edgewall.org/ticket/10327
http://trac.edgewall.org/ticket/5720

Сперва хотел перевести базу в MySQL, но обнаружились проблемы с конвертированием дампа (у sqlite и mysql несколько отличается синтаксис), а так же проблемы с совместимостью с MySQL. Поэтому было принято решение допиливать SqLite.

Решение в общем то есть, вот тут (ссылка) лежит исходник плагина для sqlite реализующего нужный функционал, но по пути были встречены разнообразные грабли, и вот как их обойти.

Кратко

1. Получаем исходники;

2. Компилируем плагин;

3. Подключаем плагин к траку;

Решение

1. Сперва качаем с сайта исходники (sqliteicu.h и icu.c), что бы скомпилять потребуется поставить dev либы: libsqlite3-dev и libicu-dev (названия пакетов для Ubuntu 12.04, в вашей системе могут называться иначе).

2. Далее, т.к. sqlite моей версии отказался хавать скомпиленный бинарник, то sqlite3_extension_init найти не мог, то load_extension fail, выдавал, а под конец и вовсе охренел и заявил, что enable_load_extension не вызвали. В общем пришлось чуток покурить маны. Почему это происходило опишу в конце, сперва решение. Открываем icu.c и переименовываем функцию “int sqlite3_icu_init(” в “int sqlite3_extension_init(“. После чего компиляем:
gcc -shared icu.c `icu-config --ldflags` -o libSqliteIcu.so

далее копируем файл libSqliteIcu.so в /usr/local/lib, теперь можно проверить загрузится ли оно в sqlite. Для этого запускаем в консоли sqlite указав ему где искать либы:

 /lib/ld-linux.so.2 --library-path /usr/local/lib/ /usr/bin/sqlite3

далее загружаем либу и делаем проверочный запрос:

SQLite version 3.7.9 2011-11-01 00:52:41
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .load libSqliteIcu.so
sqlite> SELECT "ы" like "Ы";
1
sqlite>

если на в результате выполнения такого селекта получили 1, значит все ок.

3. Теперь нужно заставить trac подключать данный плагин и использовать его, для этого во первых проверяем что установлен python-pysqlite2, т.к. данный плагин будет работать только с этим бэкендом. Далее в /var/trac/conf/trac.ini (или где у вас трак установлен) пишем:

[sqlite]
extensions = /usr/local/lib/libSqliteIcu.so

после этого нужно ребутнуть апач (у меня трак через него запускается), и попробовать воспользоваться поиском в траке, по идее должно работать.

И немного теории

Сперва, при загрузке плагина в sqlite я получал sqlite3_extension_init, в последствии выяснилось, что API sqlite при загрузке либы пытается вызвать функцию sqlite3_extension_init, а если ее не находит, то sqlite3_X_init, где Х это имя файла плагина в нижнем регистре без приставки lib в начале. Т.к. в официальном ридми к плагину приводилась именно такая строка для компиляции, то у меня естесственно ничего не работало, т.к. в исходниках функций sqlite3_extension_init и sqlite3_sqliteicu_init не было. Видимо это неточность в описании, и пожзе попробую отправить им баг репорт.

Когда эта проблема была решена, и я уже подключил плагин к траку, начал получать “enable_load_extension“. Как выяснилось, это была проблема бэкенда, поэтому нужно убедиться, что установлена python-pysqlite2, т.к. в отличие от консольного клиента sqlite, что бы подгрузить плагин из стороннего софта, нужно вызвать функцию enable_load_extension, после чего уже подгружать плагин, и тот бэкенод который стоял у меня, этого не делал.

UPD: Исправил ссылку на исходники

ВНИМАНИЕ! Если при выполнении команд сыпятся ошибки, то:

  1. Проверьте, что перед gnu style длинными опциями идет два минуса — а не длинное тире – (возможна автозамена)
  2. Проверьте, что кавычки у вас обычные, а не “елочки” (при копипасте могут приключиться)
  3. Если при компиляции получаете ошибку  error: ‘SQLITE_DETERMINISTIC’ undeclared (first use in this function). Добавте в файл icu.c строку  “#define SQLITE_DETERMINISTIC    0x800” без кавычек. Добавлять следует вверху файла, после пачки include.
  4. Если при компиляции получается вот такая беда:
    /usr/bin/ld: /tmp/ccHpLbWp.o: relocation R_X86_64_32S against `.rodata’ can not be used when making a shared object; recompile with -fPIC
    Тогда компилять надо командой: gcc -shared icu.c -fPIC `icu-config –ldflags` -o libSqliteIcu.so
  5. для проверки подключения плагина на 64битных процессорах sqlite запускать следует так:
    /lib64/ld-linux-x86-64.so.2 –library-path ./ /usr/bin/sqlite3

Добавить комментарий

Войти с помощью: