Привет, ЛОР.
Столкнулся с тем, что в SQLite не работают upper()
и прочие регистрозависимые строковые функции для нелатинских символов. Долго искал, думал, я дурак, но оказывается, это поведение по умолчанию, давным-давно и много где описанное.
Почитал. В статье на Хабре предлагают либо пересобирать SQLite с включённым SQLITE_ENABLE_ICU, либо загрузить расширение. Ну, думаю, пересобрать и захламить систему я всегда успею, давай попробуем сначала второй путь.
Ссылка из статьи не работает, но в актуальных исходниках SQLite искомый icu.c находится без труда. Качаю. Собираю. Получаю libsqliteicu.so. Гружу его из SQLite CLI – LIKE
и upper()
начинают прекрасно работать.
Теперь пытаюсь подгрузить это в своей кутешной программе. Сначала вызываю sqlite3_enable_load_extension()
, потом sqlite3_load_extension()
. Первое проходит успешно, во втором получаю ошибку:
/usr/lib/libsqliteicu.so: undefined symbol: sqlite3_sqliteicu_init
Лезу в исходник: там вместо указанной присутствует функция sqlite3_icu_init()
. Ну, хитрожопый я, конечно же, попробовал её переименовать. Добился только того, что текст ошибки поменялся на «error during initialization:».
По совету utf8nowhere стал указывать другое имя точки входа третьим параметром
sqlite3_load_extension()
– тот же самый error during. Двоеточие намекает, конечно, что у ошибки должна быть дополнительная расшифровка, но где её искать, не очень понятно.
Подобного рода разночтения, конечно, первым делом наводят на мысль о несовместимости версий. Начинаю потрошить кутешный драйвер БД. Иду в /usr/lib/qt/plugins/sqldrivers
(у меня он соответствует Qt5) и делаю ldd libqsqlite.so
. Получаю, в числе прочего:
libsqlite3.so.0 => /usr/lib/libsqlite3.so.0 (0x0000728bea28f000)
В свою очередь, libsqlite3.so.0 является симлинком для libsqlite3.so.3.49.1. То есть «библиотечная» SQLite той же версии, что и sqlite3 CLI. Но во втором загрузка расширения работает, а в первой нет.
Куда копать? Можно, конечно, вернуться к варианту с пересборкой, но там свои вопросы будут…
P.S. Попробовал вариант с пересборкой, теперь кутешный драйвер верещит «Driver not loaded», а это может означать что угодно…
Обновление: как выяснил utf8nowhere, загрузка расширения не работает, если есть открытые запросы к БД. Необходимо либо вызвать у них метод
finish()
, либо проследить, чтобы соответствующие объекты завершили работу (вызван деструктор).