Поиск в SQLite без учета регистра, для русского языка
August 14th, 2010 Begemot Posted in Использование
Не смотрю на всю свою юникодность, SQLite все-таки юникодна не до конца:( При поиске типа WHERE description LIKE “%STRING%” поиск идет без учета регистра для латинских букв, но к сожалению, он регистрозависимый для всех остальных символов. Корни этого уходят в виндовую функцию tolower(), которая правильно обрабатывает символы только текущей локали. И это весьма плохо, для целого ряда задач, например для поиска ранее скопированного текста в истории буфера обмена (извините, не удержался:))
Но к счастию способ есть. Оригинал и файлы для загрузки тут – SQLite and native UNICODE LIKE support in C/C++ . А я раскажу о том как это интегрировать и скрестить с wxDatabaselayer’om.
- Берем файлы sqlite3_unicode.h/c с архива по ссылке выше и добавляем в проект.
- Вызываем свойства sqlite3_unicode.c и добавляем SQLITE_ENABLE_UNICODE; SQLITE_CORE в определения препроцессора c++/preprocessor/preprocessor definitions
- Если используете precompiled header в проекте, надо в свойствах обоих файлов отключить его использование.
- в с файле есть строчка #include “sqlite3.h” заменить ее на свой путь к sqlite3.h, если он у вас отличается
- Включить sqlite3.h в sqlite3_unicode.h, без этого у меня не компилилось.
- Дальше вызываете sqlite3_unicode_load(); \ sqlite3_unicode_free(); – в начале/конце программы
- После открытия базы данных вызываем для нее sqlite3_unicode_init(db);
Проблема тут в том что sqlite3_unicode_init(db); хочет db типа sqlite3 *, а у нас есть только указатель на обьект датабайслаера. Тут придется править код самого wxDatabaselayer’a и заново компилить. Идем в databaselayer\include\SqliteDatabaseLayer.h, пишем:
// Added by Begemot – for using with sqlite3_unicode
void * GetSQLiteDatabase() { return m_pDatabase; }
компиляем, и в нашей программе вместо строчки sqlite3_unicode_init(db); используем вот такую вот страшную конструкцию
sqlite3_unicode_init(static_cast<sqlite3*>(static_cast<SqliteDatabaseLayer*>(db)->GetSQLiteDatabase()));
Все. Теперь Like % прекрасно ищет по русским или любым другим символам без учета регистра.
August 16th, 2010 at 4:33 pm
Я правда не знаком с SQLite но в других БД можно выкрутиться конструкцией типа WHERE UPPER(description) LIKE ‘%STRING%’
August 16th, 2010 at 4:35 pm
дык UPPER(description) наверняка же будет делатся той же виндовой toupper, зависящей от локали…
August 17th, 2010 at 3:05 pm
с ICU люди еще собирают я слышал, но там и с апи тогда нужно добавлять sqlite3_enable_load_extension
вот обсуждение
http://habrahabr.ru/blogs/sql/57915/
я лично FireBird пользую
August 18th, 2010 at 1:31 pm
Спасибо, полезная ссылка буду иметь ввиду. Вдруг я полезну под другие платформы все-таки 🙂
Хотя вроде бы ICU сильно утяжеляет библиотеку…
September 12th, 2010 at 6:35 pm
Извините, а скомпилированную sqlite3_unicode (win) могли бы выложить?
September 13th, 2010 at 12:36 am
Это просто файлы добавляемые в ваш проект…
September 13th, 2010 at 12:31 pm
Ай, а если проект на другом языке? 🙂 А превратить это в dll есть возможность? (Если не сложно конечно, если нет, буду сам разбираться).
September 13th, 2010 at 5:31 pm
нет, незнаю, тут к сожалению ничем не помогу 🙂