Форум » GUI » Еще раз о Sqlite3 » Ответить

Еще раз о Sqlite3

SADSTAR2: Задумал я написать полноценное десктопное приложение на базе SQLite3. Оказалось не все так просто как виделось изначально. А конкретно - не смог добиться безрегистрового (NOCASE) поиска/сравнения русских строковых полей. Например в LIKE "select...where FName LIKE '%"+mFnam+"%' ordered by ..." Поиск срабатывает но регистрозависимый. Если задано "Б" - найдет все строки с "Б", но не найдет с "б". И наоборот. Всякие хитрости и тонкости типа COLLATE NOCASE "select...where FName LIKE '%"+mFnam+"%' COLLATE NOCASE ordered by ..." или upper() "select...where upper(FName) LIKE '%"+upper(mFnam)+"%' ordered by ..." только ухудшают результат. Вычитал в документации что есть возможность создавать пользовательские функции (например - свою upper() или MyUpper()) и пользовательские колэйшины. Для этого используются функции API sqlite3_create_function(...) и ..._create_collation(...). Однако проверить этот вариант не удалось, т.к. в имеющейся библиотеке sqlite3.lib (судя по тексту sqlite3.c в исходниках) доступ к этим функциям не реализован. В связи с вышеизложенным вопросы. 1. решил ли кто из присутствующих описанную проблему? 2. не могли бы монстры Сишного программирования подсказать конкретно как реализовать вызов (и использование) вышеупомянутых функций?

Ответов - 10

Петр: Ясно, что вы ходите использовать движок SqLite3 для хранения данных, неясно только как. Вы приверженец "чистого Харбора" или plain C? Все что написано дальше подразумевает первый вариант. Какую библиотеку-обертку используете? Ту, что поставляется с MiniGUI? Но там по известной причине нет sqlite3.c в поставке ( по крайнем мере для версии 1.64 ). Или что-то другое (приложив усилия вы можете найти не менее 4 библиотек для Harbour, а еще использовать ADO или ODBC)? Я вам рекомендую hbsqlit3.lib из harbour\contrib (не путать с hbsqlite3.lib из МiniGUI), и совсем не потому, что я ее использую. Просто это наиболее полная реализация библиотеки функций-оберток для Harbour, находится в актуальном состоянии и вы можете использовать ее с последней версией sqlite3 3.6.12. К тому же не представляю полноценного приложение без использования callback функций. SADSTAR2 пишет: решил ли кто из присутствующих описанную проблему? Эта проблема решается именно так, как вы описали с использованием пользовательских функций и sqlite3_create_function, которая пока не реализована в публичной версии. Реализация каких-то титанических усилий не требует. Просто это немного небезопасно и работать с такими функциями нужно аккуратно.

gfilatov: Петр пишет: Я вам рекомендую hbsqlit3.lib из harbour\contrib (не путать с hbsqlite3.lib из МiniGUI), и совсем не потому, что я ее использую. Просто это наиболее полная реализация библиотеки функций-оберток для Harbour, находится в актуальном состоянии и вы можете использовать ее с последней версией sqlite3 3.6.12. Небольшой анонс: именно эта библиотека (со всеми примерами использования из harbour\contrib\hbsqlit3\tests) будет включена в состав следующей сборки расширенного релиза библиотеки МиниГуи. Петр, большое спасибо за Ваш вклад!

Петр: Спасибо, Григорий. Если кому-то будет интересно, через выходным я могу здесь опубликовать реализацию sqlite3_create_function, некоторые рекомендации по сборке sqlite3.lib и безопасном использовании callback функций hbsqlit3.lib


SADSTAR2: Петр пишет: Какую библиотеку-обертку используете? Ту, что поставляется с MiniGUI? Но там по известной причине нет sqlite3.c в поставке ( по крайнем мере для версии 1.64 ). Я смотрел здесь C:\MiniGUI63\SOURCE\HbSQLite3\hb_sqlite3.c Петр пишет: Если кому-то будет интересно, через выходным я могу здесь опубликовать реализацию sqlite3_create_function, некоторые рекомендации по сборке sqlite3.lib и безопасном использовании callback функций hbsqlit3.lib Не только интересно но и необходимо. По крайней мере мне.

Петр: Не прошло и 3 года.. С учетом моего сегодняшнего опыта использования SQLite3, я бы рекомендовал использовать библиотеку ICU - International Components for Unicode. Далее я опишу как собрать sqlite3i.dll с поддержкой ICU. Исходные данные Windows XP SP3, mingw 4.5.1, sqlite 3.7.3, ICU 4.4.2 SQLite берем с страницы закачки http://sqlite.org/download.html Нам нужен sqlite-amalgamation-3_7_3.zip Страница для скачки ICU http://icu-project.org/download/4.4.html#ICU4C Прямая ссылка И еще нужна утилита pexports.exe. Взять можно здесь или поискать более свежую версию на SF Распаковываем бинарники ICU. Допустим на диск C: Распаковываем sqlite3, например в папку C:\sqlite373 Собственно нам нужны только sqlite3.c, sqlite3.h, sqlite3ext.h, остальное можно удалить. Туда же помещаем pexports.exe В этой же папке создаем make_dll.bat сл. содержания [pre2]@ECHO OFF SETLOCAL IF NOT "%1"=="/b" GOTO :clear REM ---------------------------------------------------------- SET PATH=h:/mingw32/bin;./ SET ICU_PATH=c:/icu SET _CC_OPT=-DSQLITE_CORE=1 ^ -DSQLITE_ENABLE_COLUMN_METADATA ^ -DSQLITE_ENABLE_STAT2 ^ -DSQLITE_DEFAULT_RECURSIVE_TRIGGERS=1 ^ -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_PARENTHESIS ^ -DSQLITE_ENABLE_ICU ^ -DSQLITE_DEFAULT_PAGE_SIZE=8192 ^ -DSQLITE_DEFAULT_CACHE_SIZE=8000 ^ -DSQLITE_DEFAULT_TEMP_CACHE_SIZE=2000 ^ -DSQLITE_DEFAULT_FILE_FORMAT=4 ^ -DSQLITE_DEFAULT_JOURNAL_SIZE_LIMIT=1048576 ^ -DSQLITE_THREADSAFE=1 ^ -DSQLITE_ENABLE_LOAD_EXTENSION=1 REM -DSQLITE_ENABLE_RTREE ^ REM ---------------------------------------------------------- CALL :if_exist "gcc.exe" IF ERRORLEVEL 1 ( ECHO Error : Please install MinGW! GOTO end ) CALL :if_exist "pexports.exe" IF ERRORLEVEL 1 ( ECHO Error : PExports utility not found! GOTO end ) ECHO. FOR %%d IN (icuin44 icuuc44) DO CALL :implib %ICU_PATH%/bin/%%d ECHO BUILD Sqlite3i.dll gcc %_CC_OPT% -O3 -shared -o sqlite3i.dll sqlite3.c -I%ICU_PATH%/include ^ -L. -licuin44 -licuuc44 CALL :if_exist "strip.exe" IF NOT ERRORLEVEL 1 ( ECHO STRIP Sqlite3i.dll strip -d sqlite3i.dll ) ECHO Sqlite3i.dll was created successfully. IF EXIST libsqlite3i.a DEL /q libsqlite3i.a CALL :implib sqlite3i CALL :if_exist "upx.exe" IF NOT ERRORLEVEL 1 ( upx --best -q sqlite3i.dll ) ELSE ( ECHO WARNING: UPX not found! Sqlite3i.dll not packing ) GOTO clear REM ---------------------------------------------------------- REM | LOCAL PSEUDOFUNCTIONS | REM ---------------------------------------------------------- :if_exist FOR /f %%i IN (%1) DO IF "%%~$PATH:i" == "" EXIT /b 1 EXIT /b 0 REM ---------------------------------------------------------- :implib IF NOT EXIST lib%~n1.a ( pexports %~1.dll > %~n1.def dlltool --input-def %~n1.def --dllname %~n1.dll --output-lib lib%~n1.a ranlib lib%~n1.a ECHO Created import library: lib%~n1.a ^<= %~1.dll ) EXIT /b REM ---------------------------------------------------------- REM ---------------------------------------------------------- :clear @DEL /q *.def FOR %%d IN (icuin44 icuuc44) DO @DEL /q lib%%d.a :end PAUSE ENDLOCAL [/pre2] Не забываем указать правильный путь доступа к mingw и ICU, и запускаем его на выполнение с параметром /b Если вы просто скопировали вышеуказанный текст через буфер обмена - не забудьте удалить концевые пробелы, если ваш редактор добавляет их. В случае если вы все сделали правильно, в папке появятся sqlite3i.dll и библиотека импорта libsqlite3i.a. Далее любым приемлемым для вас методом перекомпилируете библиотеку hbsqlit3 (последнюю версию -из Harbour SVN или Harbour MiniGUI 1.8 Extended Edition (Build 89), объявив предварительно SQLITE_ENABLE_COLUMN_METADATA. Проще всего это сделать добавив в начало файла hbsqlit3.c #define SQLITE_ENABLE_COLUMN_METADATA 1 Или передавая соответствующий параметр утилите hbmk2 или C компилятору. Ну и тестовая программка [pre2]#include "common.ch" #include "hbsqlit3.ch" #define _DB_FLAGS_ (SQLITE_OPEN_CREATE + SQLITE_OPEN_READWRITE + SQLITE_OPEN_EXCLUSIVE) /** */ FUNCTION main() LOCAL cSQLTEXT, pDb // QOut( "SQLite ver.", sqlite3_libversion() ) QOut( "~~~~~~~~~~~~~~~~~~~" ) // IF ! sqlite3_compileoption_used( "SQLITE_ENABLE_ICU" ) QOut( "Oops.. ICU is not enabled, isn't it?" ) RETURN 1 ENDIF // pDb := sqlite3_open_v2( ":memory:", _DB_FLAGS_ ) IF Empty( pDb ) QOut( "Can't open database : ':memory:'" ) RETURN 1 ENDIF // load and show avaible collation list QOut( (cSQLTEXT := "SELECT icu_load_collation('uk_UA', 'ukrainian')") ) sqlite3_exec(pDb, cSQLTEXT) QOut( (cSQLTEXT := "SELECT icu_load_collation('ru_RU', 'russian')") ) sqlite3_exec(pDb, cSQLTEXT) QOut( (cSQLTEXT := "SELECT icu_load_collation('pl_PL', 'polish')") ) sqlite3_exec(pDb, cSQLTEXT) QOut( "~~~~~~~~~~~~~~~~~~~" ) cSQLTEXT := "PRAGMA collation_list" QOut( cSQLTEXT ) sqlite3_exec( pDb, cSQLTEXT, @ShowCollationList() ) sqlite3_sleep( 3000 ) pDb := NIL RETURN 0 /** */ FUNCTION ShowCollationList( nColCount, aValue, aColName ) LOCAL cStr := hb_StrFormat( "%1$s || %2$s", aValue[1], aValue[2]) HB_SYMBOL_UNUSED( nColCount ) HB_SYMBOL_UNUSED( aColName ) QOut( cStr ) // RETURN 0 [/pre2] Не забудьте при построении программы подключать библиотеки hbsqlit3 и sqlite3i. А также сделать доступными для ваших приложений динамические библиотеки sqlite3i.dll, icuuc44.dll, icuin44.dll, icudt44.dll Общим весом около 18 Mb, из них icudt44.dll - около 14 Mb. Но для теперешних времен - это не проблема. Во первых - это все хорошо "ужимается" всем известной утилитой UPX, где-то до 5-6 Mb в зависимости от использованных опций; во вторых - когда нибудь вы сможете научиться собирать icudt44.dll только с нужными вам Charset и прочими прибамбасами ( см. ) UPX рекомендую брать 3.07w и выше, он уже с mingw 4.5 научился корректно работать и даже (!) harbour-xx.dll корректно упаковывает.

Петр: Ну и еще один пример. Обратите внимание текстовые данные должны хранится в базе SQLite в формате UTF-8. Для этого мы используем связку hb_strToUTF8/hb_UTF8ToStr. Конечно это увеличивает время доступа к данным, но, надеюсь когда-нибудь Harbour получит нативную поддержку Unicode. [pre2]REQUEST HB_CODEPAGE_RU866 REQUEST HB_CODEPAGE_RU1251 #include "common.ch" #include "hbsqlit3.ch" #define _DB_FLAGS_ (SQLITE_OPEN_CREATE + SQLITE_OPEN_READWRITE + SQLITE_OPEN_EXCLUSIVE) INIT PROCEDURE _cp_init hb_cdpSelect( "RU1251" ) hb_setTermCP( "RU866", "RU1251", .F. ) RETURN /** */ FUNCTION main() LOCAL cSQLTEXT LOCAL pDb, cb // IF ! sqlite3_compileoption_used( "SQLITE_ENABLE_ICU" ) QOut( "Oops.. ICU is not enabled, isn't it?" ) RETURN 1 ENDIF // pDb := sqlite3_open_v2( "test.db", _DB_FLAGS_ ) IF Empty( pDb ) QOut( "Can't open database : 'test.db'" ) RETURN 1 ENDIF //sqlite3_trace( pDb, .T., "acc.log" ) QOut( (cSQLTEXT := "SELECT icu_load_collation('ru_RU', 'russian')") ) sqlite3_exec(pDb, cSQLTEXT) // drop and re- create table main.test & main.test_r sqlite3_exec( pDb, "DROP TABLE IF EXISTS test" ) sqlite3_exec( pDb, "DROP TABLE IF EXISTS test_r" ) // -------------------------------- cSQLTEXT := "CREATE TABLE IF NOT EXISTS test ( name TEXT )" ? cSQLTEXT sqlite3_exec(pDb, cSQLTEXT) PopulateDB ( pDb, "test" ) cSQLTEXT := "SELECT name, lower(name), upper(name) FROM test ORDER by name" ? cSQLTEXT, hb_osNewLine() cb := @CallBack() // "CallBack" sqlite3_exec(pDb, cSQLTEXT, cb) cSQLTEXT := "SELECT name, lower(name), upper(name) FROM test ORDER by name COLLATE russian" ? cSQLTEXT, hb_osNewLine() cb := @CallBack() sqlite3_exec(pDb, cSQLTEXT, cb) // -------------------------------- cSQLTEXT := "CREATE TABLE IF NOT EXISTS test_r ( name TEXT COLLATE russian )" ? cSQLTEXT sqlite3_exec(pDb, cSQLTEXT) PopulateDB ( pDb, "test_r" ) cSQLTEXT := "SELECT name, lower(name), upper(name) FROM test_r ORDER by name" ? cSQLTEXT, hb_osNewLine() cb := @CallBack() sqlite3_exec(pDb, cSQLTEXT, cb) // -------------------------------- cSQLTEXT := "SELECT * FROM test_r WHERE name LIKE '%мо%' ORDER by name" ? cSQLTEXT, hb_osNewLine() cb := @CallBack2() sqlite3_exec(pDb, hb_strToUTF8(cSQLTEXT), cb) sqlite3_sleep( 3000 ) // pDb := Nil // close database // RETURN 0 /** */ FUNCTION PopulateDB ( pDb, table ) LOCAL cSQLTEXT cSQLTEXT := "INSERT INTO " + table + " VALUES ('Привет!')" sqlite3_exec(pDb, hb_strToUTF8(cSQLTEXT)) cSQLTEXT := "INSERT INTO " + table + " VALUES ('Ё-моё')" sqlite3_exec(pDb, hb_strToUTF8(cSQLTEXT)) cSQLTEXT := "INSERT INTO " + table + " VALUES ('привет!')" sqlite3_exec(pDb, hb_strToUTF8(cSQLTEXT)) cSQLTEXT := "INSERT INTO " + table + " VALUES ('ё-прст')" sqlite3_exec(pDb, hb_strToUTF8(cSQLTEXT)) cSQLTEXT := "INSERT INTO " + table + " VALUES ('ага!')" sqlite3_exec(pDb, hb_strToUTF8(cSQLTEXT)) cSQLTEXT := "INSERT INTO " + table + " VALUES ('ё-моё')" sqlite3_exec(pDb, hb_strToUTF8(cSQLTEXT)) cSQLTEXT := "INSERT INTO " + table + " VALUES ('ё-Моё')" sqlite3_exec(pDb, hb_strToUTF8(cSQLTEXT)) // RETURN Nil /** */ #translate UTF8_CP1251( <utf8> ) => ( padr( hb_UTF8ToStr( <utf8> ), 12 ) ) FUNCTION CallBack( nColCount, aValue, aColName ) LOCAL cStr := hb_StrFormat( "%1$s => %2$s => %3$s",; UTF8_CP1251(aValue[1]), UTF8_CP1251(aValue[2]), UTF8_CP1251(aValue[3]) ) HB_SYMBOL_UNUSED( nColCount ) HB_SYMBOL_UNUSED( aColName ) OutStd( cStr, hb_OsNewLine() ) // RETURN 0 /** */ FUNCTION CallBack2( nColCount, aValue, aColName ) LOCAL cStr := hb_StrFormat( "%1$s", UTF8_CP1251(aValue[1]) ) HB_SYMBOL_UNUSED( nColCount ) HB_SYMBOL_UNUSED( aColName ) OutStd( cStr, hb_OsNewLine() ) // RETURN 0 [/pre2]

Петр: Ну и последний штрих. Почему MinGW? Потому, что я его использую. Можно сказать, что он мне нравится А с другой стороны - это самый "сложный" случай. Если вы используете MS VC то какие могут быть проблемы - библиотеки импорта все в поставке ICU - бери и используй. По идее и MinGW 4.5 может использовать библиотеки от VC, а вот на практике.. А для BCC есть утилита implib и никаких особых трудностей я не вижу.. OW с ICU работать пока не может, а PellesC, DM и прочие я не рассматривал вообще (и не хочу ).

Петр: Сбросил в Harbour SVN сл. изменения Revision: 15721 http://harbour-project.svn.sourceforge.net/harbour-project/?rev=15721&view=rev Author: petr_ch Date: 2010-10-31 22:06:54 +0000 (Sun, 31 Oct 2010) Log Message: ----------- 2010-11-01 00:05 UTC+0200 Petr Chornyj (myorg63 at mail.ru) * harbour/contrib/hbsqlit3/hbsqlit3.c * Changed syntax of sqlite3_exec() to sqlite3_exec( db, cSQLTEXT, [pCallbackFunc]|[cCallbackFunc], [lConvertSQLTextToUTF8], "cCDP" ) -> nResultCode From now we can replace cSQLTEXT := hb_strToUTF8( cSQLTEXT, "RU1251" ) sqlite3_exec( db, cSQLTEXT ) with sqlite3_exec( db, cSQLTEXT, , .t., "RU1251" ) * Changed syntax of sqlite3_bind_text(), sqlite3_column_text() in such way * Changed sqlite3_bind_blob() according to sqlite3 docs. Modified Paths: -------------- trunk/harbour/ChangeLog trunk/harbour/contrib/hbsqlit3/hbsqlit3.c Теперь пример из поста №983 можно переписать вот так [pre2]REQUEST HB_CODEPAGE_RU866 REQUEST HB_CODEPAGE_RU1251 #include "common.ch" #include "hbsqlit3.ch" #define _DB_FLAGS_ (SQLITE_OPEN_CREATE + SQLITE_OPEN_READWRITE + SQLITE_OPEN_EXCLUSIVE) INIT PROCEDURE _cp_init hb_cdpSelect( "RU1251" ) hb_setTermCP( "RU866", "RU1251", .F. ) RETURN /** */ FUNCTION main() LOCAL cSQLTEXT LOCAL pDb, cb LOCAL pStmt // IF ! sqlite3_compileoption_used( "SQLITE_ENABLE_ICU" ) QOut( "Oops.. ICU is not enabled, isn't it?" ) RETURN 1 ENDIF // pDb := sqlite3_open_v2( "test.db", _DB_FLAGS_ ) IF Empty( pDb ) QOut( "Can't open database : 'test.db'" ) RETURN 1 ENDIF //sqlite3_trace( pDb, .T., "acc.log" ) QOut( (cSQLTEXT := "SELECT icu_load_collation('ru_RU', 'russian')") ) sqlite3_exec(pDb, cSQLTEXT) // drop and re- create table main.test & main.test_r sqlite3_exec( pDb, "DROP TABLE IF EXISTS test" ) sqlite3_exec( pDb, "DROP TABLE IF EXISTS test_r" ) // -------------------------------- cSQLTEXT := "CREATE TABLE IF NOT EXISTS test ( name TEXT )" ? cSQLTEXT sqlite3_exec(pDb, cSQLTEXT) PopulateDB ( pDb, "test" ) cSQLTEXT := "SELECT name, lower(name), upper(name) FROM test ORDER by name" ? cSQLTEXT, hb_osNewLine() cb := "CallBack" sqlite3_exec(pDb, cSQLTEXT, cb) cSQLTEXT := "SELECT name, lower(name), upper(name) FROM test ORDER by name COLLATE russian" ? cSQLTEXT, hb_osNewLine() cb := @CallBack() sqlite3_exec(pDb, cSQLTEXT, cb) // -------------------------------- cSQLTEXT := "CREATE TABLE IF NOT EXISTS test_r ( name TEXT COLLATE russian )" ? cSQLTEXT sqlite3_exec(pDb, cSQLTEXT) PopulateDB ( pDb, "test_r" ) cSQLTEXT := "SELECT name, lower(name), upper(name) FROM test_r ORDER by name" ? cSQLTEXT, hb_osNewLine() cb := @CallBack() sqlite3_exec(pDb, cSQLTEXT, cb) // -------------------------------- cSQLTEXT := "SELECT * FROM test_r WHERE name LIKE :name ORDER by name" ? cSQLTEXT pStmt := sqlite3_prepare( pDb, cSQLTEXT ) sqlite3_bind_text( pStmt, 1, '%мо%', .t. ) DO WHILE sqlite3_step( pStmt ) == SQLITE_ROW ? sqlite3_column_text( pStmt, 1, .t., "RU1251" ) ENDDO sqlite3_clear_bindings( pStmt ) sqlite3_finalize( pStmt ) sqlite3_sleep( 3000 ) // pDb := Nil // close database // RETURN 0 /** */ FUNCTION PopulateDB ( pDb, table ) LOCAL cSQLTEXT LOCAL pStmt LOCAL aStrings := { 'Ё-моё', 'привет!', 'ё-прст', 'ага!', 'ё-моё', 'ё-Моё', "Ъ-ГЫ" } LOCAL cString cSQLTEXT := "INSERT INTO " + table + " VALUES ('Привет!')" sqlite3_exec(pDb, cSQLTEXT, NIL, .t.) cSQLTEXT := "INSERT INTO " + table + " VALUES (:value)" pStmt := sqlite3_prepare( pDb, cSQLTEXT ) FOR EACH cString IN aStrings sqlite3_reset( pStmt ) sqlite3_bind_text( pStmt, 1, cString, .t., "RU1251" ) sqlite3_step( pStmt ) NEXT sqlite3_clear_bindings( pStmt ) sqlite3_finalize( pStmt ) // RETURN Nil /** */ #translate UTF8_CP1251( <utf8> ) => ( padr( hb_UTF8ToStr( <utf8> ), 12 ) ) FUNCTION CallBack( nColCount, aValue, aColName ) LOCAL cStr := hb_StrFormat( "%1$s => %2$s => %3$s",; UTF8_CP1251(aValue[1]), UTF8_CP1251(aValue[2]), UTF8_CP1251(aValue[3]) ) HB_SYMBOL_UNUSED( nColCount ) HB_SYMBOL_UNUSED( aColName ) OutStd( cStr, hb_OsNewLine() ) // RETURN 0[/pre2]

Петр: Петр пишет: Сбросил в Harbour SVN сл. изменения 2010-11-01 13:53 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) * contrib/hbsqlit3/hbsqlit3.c - Reverted UTF8 patch in 2010-11-01 00:05 UTC+0200. + Replaced above solution with transparent one, using Str API usage and extended it for all places where UTF8 strings are expected or returned by sqlite3 API. Please test. This clears an old TOFIX. 2010-11-02 18:55 UTC+0200 Petr Chornyj (myorg63 at mail.ru) * harbour/contrib/hbsqlit3/hbsqlit3.c * Changed to use STR API for UTF8 conversions in few places. Lightly tested - seems now it's works as expected. + Added sqlite_sourceid() Объясняю суть изменений. Теперь все данные (текстовые естественно) автоматически транслируются библиотекой hbsqlit3 в UTF8 при сохранении в БД и соответственно в ANSI при чтении из базы. Никаких дополнительных ухищрений делать не нужно. Честно мне не очень нравится обязательность такой процедуры. Здесь и вопросы по сопровождению уже существующих баз могут возникнуть, и отрезали поддержку старых версий Harbour (до 12/2009), как раньше поддержку xHarbour, и китайцев фактически обидели. Но в таком подходе и достоинств достаточно много. Да и с Viktor- ом препираться не хочется

Vladimir: Вариант решения из статьи SQLite и UNICODE. Оформлено в виде библиотеки HbSQLite3u для MinGW и MSVC10 с тестовым примером. Библиотека включает sqlite3_unicode.c и функции инициализации/выгрузки. Подключение выполняется функцией SQLite3_Unicode_Load() перед открытием базы SQLite3_Open(), после чего для кирилицы в SQLite заработают lower(), upper() и регистронезависимый LIKE. Из замеченного, в запросе LIKE буквы со сходным начертанием считаются одинаковыми (Ё(ё) = Е(е), Ї(ї) = І(і), Ґ(ґ) = Г(г)). Т.е., LIKE "%ё%" выдаст слова и с "Ё", и с "Е" (LIKE "Петр" - покажет "Петр" и "Пётр").



полная версия страницы