Последнее время все чаще и чаще начали пользовать для внутренних нужд на работе 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: Исправил ссылку на исходники
ВНИМАНИЕ! Если при выполнении команд сыпятся ошибки, то:
- Проверьте, что перед gnu style длинными опциями идет два минуса — а не длинное тире – (возможна автозамена)
- Проверьте, что кавычки у вас обычные, а не “елочки” (при копипасте могут приключиться)
- Если при компиляции получаете ошибку error: ‘SQLITE_DETERMINISTIC’ undeclared (first use in this function). Добавте в файл icu.c строку “#define SQLITE_DETERMINISTIC 0x800” без кавычек. Добавлять следует вверху файла, после пачки include.
-
Если при компиляции получается вот такая беда:
/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 -
для проверки подключения плагина на 64битных процессорах sqlite запускать следует так:
/lib64/ld-linux-x86-64.so.2 –library-path ./ /usr/bin/sqlite3