{"id":252899,"date":"2015-03-12T12:43:02","date_gmt":"2015-03-12T08:43:02","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=252899"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=252899","title":{"rendered":"\u041a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 SQLite Android \u0438\u043b\u0438 \u0441\u0432\u043e\u044f LOWER_FNC()"},"content":{"rendered":"<p>     \tSELECT * WHERE LOWER_FNC(name) like &#8216;%&quot; + filterText + &quot;%&#8217;&quot;<\/p>\n<p>  \u041f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 Android \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0441\u044f \u0441 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439 \u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 SQLite \u0444\u0438\u043b\u044c\u0442\u0440\u0430 \u0441 \u0440\u0443\u0441\u0441\u043a\u0438\u043c\u0438 \u0431\u0443\u043a\u0432\u0430\u043c\u0438. \u0414\u043b\u044f \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u0439 \u043b\u043e\u043a\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u043d\u0435\u0442. \u0414\u043b\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u0438\u043d\u0442\u0435\u0440\u043d\u0430\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0445 \u0440\u0430\u0441\u043a\u043b\u0430\u0434\u043e\u043a \u043d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043b\u0438\u0441\u044c \u0437\u0430\u0433\u043b\u0430\u0432\u043d\u044b\u0435 \u0431\u0443\u043a\u0432\u044b \u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0435.<br \/>  \u041d\u0435\u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0432\u0448\u0438\u0441\u044c \u044f \u043d\u0430\u0442\u043a\u043d\u0443\u043b\u0441\u044f \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435:<\/p>\n<p>  <i>(18) Case-insensitive matching of Unicode characters does not work.<\/p>\n<p>  The default configuration of SQLite only supports case-insensitive comparisons of ASCII characters. The reason for this is that doing full Unicode case-insensitive comparisons and case conversions requires tables and logic that would nearly double the size of the SQLite library. The SQLite developers reason that any application that needs full Unicode case support probably already has the necessary tables and functions and so SQLite should not take up space to duplicate this ability.<\/p>\n<p>  Instead of providing full Unicode case support by default, SQLite provides the ability to link against external Unicode comparison and conversion routines.<br \/>  <\/i><br \/>  \u0412\u0435\u0440\u043e\u044f\u0442\u043d\u043e \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f SQLite Android \u0438 \u0435\u0441\u0442\u044c <\/p>\n<blockquote><p>only supports case-insensitive comparisons of ASCII characters<\/p><\/blockquote>\n<p>  \u0412\u0438\u0434\u0435\u043b \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 <a href=\"https:\/\/gist.github.com\/ramzes642\/5400792\">CursorWrapper<\/a> \u043d\u043e \u0440\u0435\u0448\u0438\u043b \u0432\u0441\u0435 \u0442\u0430\u043a\u0438 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0441\u0432\u043e\u044e \u0432\u0435\u0440\u0441\u0438\u044e SQLite \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c addCustomFunction<\/p>\n<p>  \u0427\u0442\u043e \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0447\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434 \u043a\u0430\u0442\u043e\u043c<br \/>  <a name=\"habracut\"><\/a><\/p>\n<p>  \u0418\u0434\u0435\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u044f\u043c\u043e\u0439 \u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0439 \u043e\u0431\u043c\u0435\u043d \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0441 SQLite \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u043e\u0439 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 (custom) \u0441\u0431\u043e\u0440\u043a\u0438<br \/>  \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e <a href=\"http:\/\/www.sqlite.org\/android\/doc\/trunk\/www\/index.wiki\">SQLite Android Bindings<\/a><br \/>  \u042f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u0432\u0435\u0440\u0441\u0438\u044e Android API levels 15 (Android 4.0.3). \u041d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u0432 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0438\u043b\u0438 \u043f\u0430\u043a\u0435\u0442\u0435 package org.sqlite.os;<\/p>\n<p>  \u0414\u0430\u043b\u044c\u0448\u0435 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0447\u0435\u0440\u0435\u0437 NDK sqliteX \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443. \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043a \u043f\u0440\u043e\u0435\u043a\u0442\u0443. \u0418 \u0433\u0440\u0443\u0437\u0438\u043c \u043d\u0430\u0448\u0443 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443<\/p>\n<pre><code class=\"java\">System.loadLibrary(&quot;sqliteX&quot;); <\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043d\u0430\u0448\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0438\u0437 SQL \u0437\u0430\u043f\u0440\u043e\u0441\u0430<\/p>\n<pre><code class=\"java\">    private final SQLiteDatabase.CustomFunction mLowerFnc =                          new SQLiteDatabase.CustomFunction() {                  @Override                  public void callback(String[] args) {                      String text = args[0];                      text = text.toLowerCase();                      Log.d(LOG, &quot;LOWER_FNC : &quot; + text);                      return;                 }         }; <\/code><\/pre>\n<p>  \u0421\u0430\u043c\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c<\/p>\n<pre><code class=\"java\">public class DataBase extends SQLiteOpenHelper { ...     public DataBase(Context context) {         super(context, context.getDatabasePath(DATABASE_NAME).getPath(), null, DATABASE_VERSION);         context.openOrCreateDatabase(context.getDatabasePath(DATABASE_NAME).getPath(), context.MODE_PRIVATE, null);     }      public void open() throws SQLException {         database = getWritableDatabase();         database.addCustomFunction(&quot;LOWER_FNC&quot;, 1, mLowerFnc);     } <\/code><\/pre>\n<p>  \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b: \u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d\u0430 \u0438\u0437 SQLite \u0441\u0442\u0440\u043e\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430. \u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0432\u0445\u043e\u0434\u043d\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0441\u0430\u043c\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f-\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a<\/p>\n<p>  \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0431\u0430\u0437\u0443 \u043d\u0430\u0434\u043e \u043f\u043e \u043f\u043e\u043b\u043d\u043e\u043c\u0443 \u043f\u0443\u0442\u0438. \u0412\u0430\u0440\u0438\u0430\u043d\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u043d\u043e\u0433\u043e \u043f\u0443\u0442\u0438:<\/p>\n<pre><code class=\"java\">DB_PATH = getApplicationContext().getDatabasePath(&quot;test.db&quot;); DB_PATH.mkdirs(); <\/code><\/pre>\n<p>  \u0412 \u043b\u043e\u0433\u0430\u0445 \u0432\u0438\u0434\u0438\u043c \u0432\u044b\u0437\u043e\u0432 \u043d\u0430\u0448\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 LOWER_FNC \u0438 \u0441\u0442\u0440\u043e\u043a\u0438 \u0438\u0437 \u0437\u0430\u043f\u0440\u043e\u0441\u0430. \u041e\u0442\u043b\u0438\u0447\u043d\u043e!<br \/>  \u0410 \u0447\u0442\u043e \u0434\u0430\u043b\u044c\u0448\u0435? \u041a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u0441\u0442\u0440\u043e\u043a\u0438 \u0438 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0438\u0445 \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0432 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u043e\u043c \u0432\u0438\u0434\u0435?<\/p>\n<p>  \u0421\u043c\u043e\u0442\u0440\u0438\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 SQLite:<\/p>\n<pre><code class=\"cpp\">\/\/ Called each time a custom function is evaluated. static void sqliteCustomFunctionCallback(sqlite3_context *context,         int argc, sqlite3_value **argv) { ...         \/\/ TODO: Support functions that return values.         env-&gt;CallVoidMethod(functionObj,                 gSQLiteCustomFunctionClassInfo.dispatchCallback, argsArray); ... <\/code><\/pre>\n<p>  \u0412\u0438\u0434\u0438\u043c CallVoidMethod \u0438 \u0434\u0430\u043b\u0435\u0435 TODO: Support functions that return values<br \/>  \u0417\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e. \u0410\u0432\u0442\u043e\u0440\u044b \u043d\u0435 \u0434\u043e\u043f\u0438\u043b\u0438\u043b\u0438. \u041f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0441\u0430\u043c\u043e\u043c\u0443\u2026<br \/>  \u0421\u043a\u0430\u0436\u0443 \u0447\u0442\u043e \u043f\u043e\u0434\u0445\u043e\u0434 \u0431\u044b\u043b \u043d\u0430\u0439\u0434\u0435\u043d \u043d\u0435 \u0441\u0440\u0430\u0437\u0443. \u041f\u043e\u0442\u0440\u0430\u0447\u0435\u043d\u043e \u0434\u0432\u0430 \u0434\u043d\u044f, \u043d\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0431\u044b\u043b \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0443\u0442. \u0410 \u044d\u0442\u043e \u0433\u043b\u0430\u0432\u043d\u043e\u0435<\/p>\n<pre><code class=\"cpp\">\tresult = env-&gt;CallObjectMethod( functionObj, gSQLiteCustomFunctionClassInfo.dispatchCallback, argsArray); \tchar_result = env-&gt;GetStringUTFChars( (jstring) result, NULL); \tsqlite3_result_text(context, char_result, -1, SQLITE_TRANSIENT); <\/code><\/pre>\n<p>  \u0412\u043c\u0435\u0441\u0442\u043e CallVoidMethod \u0434\u0435\u043b\u0430\u0435\u043c CallObjectMethod \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0437\u0430\u0431\u0438\u0440\u0430\u0435\u043c \u0443 Android \u0441\u0442\u0440\u043e\u043a\u0443  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041f\u043e\u043b\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">\/\/ Called each time a custom function is evaluated. static void sqliteCustomFunctionCallback(sqlite3_context *context,         int argc, sqlite3_value **argv) {     jobject result;     JNIEnv* env = 0;     const char* char_result;      gpJavaVM-&gt;GetEnv((void**)&env, JNI_VERSION_1_4);      \/\/ Get the callback function object.     \/\/ Create a new local reference to it in case the callback tries to do something     \/\/ dumb like unregister the function (thereby destroying the global ref) while it is running.     jobject functionObjGlobal = reinterpret_cast&lt;jobject&gt;(sqlite3_user_data(context));     jobject functionObj = env-&gt;NewLocalRef(functionObjGlobal);      jobjectArray argsArray = env-&gt;NewObjectArray(argc, gStringClassInfo.clazz, NULL);     if (argsArray) {         for (int i = 0; i &lt; argc; i++) {             const jchar* arg = static_cast&lt;const jchar*&gt;(sqlite3_value_text16(argv[i]));             if (!arg) {                 ALOGW(&quot;NULL argument in custom_function_callback.  This should not happen.&quot;);             } else {                 size_t argLen = sqlite3_value_bytes16(argv[i]) \/ sizeof(jchar);                 jstring argStr = env-&gt;NewString(arg, argLen);                 if (!argStr) {                     goto error; \/\/ out of memory error                 }                 env-&gt;SetObjectArrayElement(argsArray, i, argStr);                 env-&gt;DeleteLocalRef(argStr);             }         }          \/\/ TODO: Support functions that return values.         \/\/env-&gt;CallVoidMethod(functionObj,         \/\/        gSQLiteCustomFunctionClassInfo.dispatchCallback, argsArray);  \tresult = env-&gt;CallObjectMethod( functionObj, gSQLiteCustomFunctionClassInfo.dispatchCallback, argsArray); \tchar_result = env-&gt;GetStringUTFChars( (jstring) result, NULL); \tsqlite3_result_text(context, char_result, -1, SQLITE_TRANSIENT);  error:         env-&gt;DeleteLocalRef(argsArray);     }      env-&gt;DeleteLocalRef(functionObj);     env-&gt;DeleteLocalRef(result);      if (env-&gt;ExceptionCheck()) {         ALOGE(&quot;An exception was thrown by custom SQLite function.&quot;);         \/* LOGE_EX(env); *\/         env-&gt;ExceptionClear();     } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0415\u0441\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u043c\u043e\u043c\u0435\u043d\u0442. \u041d\u0430\u0434\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c register_android_database_SQLiteConnection \u0434\u043e\u0431\u0430\u0432\u0438\u0432 Ljava\/lang\/String; \u042d\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u0435\u0440\u043d\u0435\u0442\u0441\u044f \u0438\u0437 Android \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0418\u043d\u0430\u0447\u0435 Android OS \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u0442 \u043d\u0430\u0448\u0443 \u043d\u043e\u0432\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">register_android_database_SQLiteConnection(JNIEnv *env)<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">int register_android_database_SQLiteConnection(JNIEnv *env) {     jclass clazz;     FIND_CLASS(clazz, &quot;org\/sqlite\/database\/sqlite\/SQLiteCustomFunction&quot;);      GET_FIELD_ID(gSQLiteCustomFunctionClassInfo.name, clazz,             &quot;name&quot;, &quot;Ljava\/lang\/String;&quot;);     GET_FIELD_ID(gSQLiteCustomFunctionClassInfo.numArgs, clazz,             &quot;numArgs&quot;, &quot;I&quot;);     GET_METHOD_ID(gSQLiteCustomFunctionClassInfo.dispatchCallback,             clazz, &quot;dispatchCallback&quot;, &quot;([Ljava\/lang\/String;)Ljava\/lang\/String;&quot;);      FIND_CLASS(clazz, &quot;java\/lang\/String&quot;);     gStringClassInfo.clazz = jclass(env-&gt;NewGlobalRef(clazz));      return jniRegisterNativeMethods(env,          &quot;org\/sqlite\/database\/sqlite\/SQLiteConnection&quot;,         sMethods, NELEM(sMethods)     ); } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0417\u0430\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u044d\u0442\u0430\u043f. \u0418\u0437\u043c\u0435\u043d\u044f\u0435\u043c callback \u0438 interface, \u0442\u0430\u043a \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u043b String  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0421\u043a\u0440\u044b\u0442\u044b\u0439 \u0442\u0435\u043a\u0441\u0442<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">    private final SQLiteDatabase.CustomFunction mLowerFnc =                          new SQLiteDatabase.CustomFunction() {                  @Override                  public String callback(String[] args) {                      String text = args[0];                      text = text.toLowerCase();                      Log.d(LOG, &quot;LOWER_FNC : &quot; + text);                      return text;                 }         };  ...      \/**      * A callback interface for a custom sqlite3 function.      * This can be used to create a function that can be called from      * sqlite3 database triggers.      * @hide      *\/     public interface CustomFunction {         public String callback(String[] args);     }  <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043b\u044e\u0431\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043d\u0430\u0434\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0438\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0432\u043e\u044e \u0441 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e. \u041f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0432\u0441\u0435 \u044d\u0442\u043e \u043d\u0430\u0448\u043b\u043e \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 <a href=\"https:\/\/play.google.com\/store\/apps\/details?id=net.appz.airtikets\">Air Tickets<\/a><br \/>  \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f feed Aviasales, \u043d\u043e \u044d\u0442\u043e \u0443\u0436\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0434\u0440\u0443\u0433\u0430\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u044f<\/p>\n<p>  \u041d\u0430\u0434\u0435\u044e\u0441\u044c \u0441\u0442\u0430\u0442\u044c\u044f \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0435\u0437\u043d\u0430. \u041f\u0438\u0448\u0438\u0442\u0435 SQLite \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0441\u043e \u0441\u0432\u043e\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e!<\/p>\n<p>  \u041c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u044b \u0441\u0442\u0430\u0442\u044c\u0438:<br \/>  <a href=\"http:\/\/www.sqlite.org\/android\/doc\/trunk\/www\/index.wiki\">SQLite Android Bindings<\/a><br \/>  <a href=\"https:\/\/developer.android.com\/tools\/sdk\/ndk\/index.html\">Android NDK<\/a>      \t<\/p>\n<div class=\"clear\"><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/252823\/\"> http:\/\/habrahabr.ru\/post\/252823\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>     \tSELECT * WHERE LOWER_FNC(name) like &#8216;%&quot; + filterText + &quot;%&#8217;&quot;<\/p>\n<p>  \u041f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 Android \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0441\u044f \u0441 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439 \u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 SQLite \u0444\u0438\u043b\u044c\u0442\u0440\u0430 \u0441 \u0440\u0443\u0441\u0441\u043a\u0438\u043c\u0438 \u0431\u0443\u043a\u0432\u0430\u043c\u0438. \u0414\u043b\u044f \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u0439 \u043b\u043e\u043a\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u043d\u0435\u0442. \u0414\u043b\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u0438\u043d\u0442\u0435\u0440\u043d\u0430\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0445 \u0440\u0430\u0441\u043a\u043b\u0430\u0434\u043e\u043a \u043d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043b\u0438\u0441\u044c \u0437\u0430\u0433\u043b\u0430\u0432\u043d\u044b\u0435 \u0431\u0443\u043a\u0432\u044b \u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0435.<br \/>  \u041d\u0435\u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0432\u0448\u0438\u0441\u044c \u044f \u043d\u0430\u0442\u043a\u043d\u0443\u043b\u0441\u044f \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435:<\/p>\n<p>  <i>(18) Case-insensitive matching of Unicode characters does not work.<\/p>\n<p>  The default configuration of SQLite only supports case-insensitive comparisons of ASCII characters. The reason for this is that doing full Unicode case-insensitive comparisons and case conversions requires tables and logic that would nearly double the size of the SQLite library. The SQLite developers reason that any application that needs full Unicode case support probably already has the necessary tables and functions and so SQLite should not take up space to duplicate this ability.<\/p>\n<p>  Instead of providing full Unicode case support by default, SQLite provides the ability to link against external Unicode comparison and conversion routines.<br \/>  <\/i><br \/>  \u0412\u0435\u0440\u043e\u044f\u0442\u043d\u043e \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f SQLite Android \u0438 \u0435\u0441\u0442\u044c <\/p>\n<blockquote><p>only supports case-insensitive comparisons of ASCII characters<\/p><\/blockquote>\n<p>  \u0412\u0438\u0434\u0435\u043b \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 <a href=\"https:\/\/gist.github.com\/ramzes642\/5400792\">CursorWrapper<\/a> \u043d\u043e \u0440\u0435\u0448\u0438\u043b \u0432\u0441\u0435 \u0442\u0430\u043a\u0438 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0441\u0432\u043e\u044e \u0432\u0435\u0440\u0441\u0438\u044e SQLite \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c addCustomFunction<\/p>\n<p>  \u0427\u0442\u043e \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0447\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434 \u043a\u0430\u0442\u043e\u043c  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-252899","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/252899","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=252899"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/252899\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=252899"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=252899"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=252899"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}