/* ** Implementation of the scalar function icu_load_collation(). ** ** This scalar function is used to add ICU collation based collation ** types to an SQLite database connection. It is intended to be called ** as follows: ** ** SELECT icu_load_collation(<locale>, <collation-name>); ** ** Where <locale> is a string containing an ICU locale identifier (i.e. ** "en_AU", "tr_TR" etc.) and <collation-name> is the name of the ** collation sequence to create. */ static void icuLoadCollation( sqlite3_context *p, int nArg, sqlite3_value **apArg ){ sqlite3 *db = (sqlite3 *)sqlite3_user_data(p); UErrorCode status = U_ZERO_ERROR; const char *zLocale; /* Locale identifier - (eg. "jp_JP") */ const char *zName; /* SQL Collation sequence name (eg. "japanese") */ UCollator *pUCollator; /* ICU library collation object */ int rc; /* Return code from sqlite3_create_collation_x() */ assert(nArg==2); zLocale = (const char *)sqlite3_value_text(apArg[0]); zName = (const char *)sqlite3_value_text(apArg[1]); if( !zLocale || !zName ){ return; } pUCollator = ucol_open(zLocale, &status); if( !U_SUCCESS(status) ){ icuFunctionError(p, "ucol_open", status); return; } assert(p); rc = sqlite3_create_collation_v2(db, zName, SQLITE_UTF16, (void *)pUCollator, icuCollationColl, icuCollationDel ); if( rc!=SQLITE_OK ){ ucol_close(pUCollator); sqlite3_result_error(p, "Error registering collation function", -1); } }
extern "C" int register_android_functions(sqlite3 * handle, int utf16Storage) { int err; UErrorCode status = U_ZERO_ERROR; UCollator * collator = ucol_open(NULL, &status); if (U_FAILURE(status)) { return -1; } if (utf16Storage) { // Note that text should be stored as UTF-16 err = sqlite3_exec(handle, "PRAGMA encoding = 'UTF-16'", 0, 0, 0); if (err != SQLITE_OK) { return err; } // Register the UNICODE collation err = sqlite3_create_collation_v2(handle, "UNICODE", SQLITE_UTF16, collator, collate16, (void(*)(void*))localized_collator_dtor); } else { err = sqlite3_create_collation_v2(handle, "UNICODE", SQLITE_UTF8, collator, collate8, (void(*)(void*))localized_collator_dtor); } if (err != SQLITE_OK) { return err; } // Register the PHONE_NUM_EQUALS function err = sqlite3_create_function( handle, "PHONE_NUMBERS_EQUAL", 2, SQLITE_UTF8, NULL, phone_numbers_equal, NULL, NULL); if (err != SQLITE_OK) { return err; } // Register the PHONE_NUM_EQUALS function with an additional argument "use_strict" err = sqlite3_create_function( handle, "PHONE_NUMBERS_EQUAL", 3, SQLITE_UTF8, NULL, phone_numbers_equal, NULL, NULL); if (err != SQLITE_OK) { return err; } // Register the _DELETE_FILE function err = sqlite3_create_function(handle, "_DELETE_FILE", 1, SQLITE_UTF8, NULL, delete_file, NULL, NULL); if (err != SQLITE_OK) { return err; } #if ENABLE_ANDROID_LOG // Register the _LOG function err = sqlite3_create_function(handle, "_LOG", 1, SQLITE_UTF8, NULL, android_log, NULL, NULL); if (err != SQLITE_OK) { return err; } #endif // Register the GET_PHONEBOOK_INDEX function err = sqlite3_create_function(handle, "GET_PHONEBOOK_INDEX", 2, SQLITE_UTF8, NULL, get_phonebook_index, NULL, NULL); if (err != SQLITE_OK) { return err; } // Register the _PHONE_NUMBER_STRIPPED_REVERSED function, which imitates // PhoneNumberUtils.getStrippedReversed. This function is not public API, // it is only used for compatibility with Android 1.6 and earlier. err = sqlite3_create_function(handle, "_PHONE_NUMBER_STRIPPED_REVERSED", 1, SQLITE_UTF8, NULL, phone_number_stripped_reversed, NULL, NULL); if (err != SQLITE_OK) { return err; } return SQLITE_OK; }
extern "C" int register_localized_collators(sqlite3* handle, const char* systemLocale, int utf16Storage) { int err; UErrorCode status = U_ZERO_ERROR; void* icudata; UCollator* collator = ucol_open(systemLocale, &status); if (U_FAILURE(status)) { return -1; } ucol_setAttribute(collator, UCOL_STRENGTH, UCOL_PRIMARY, &status); if (U_FAILURE(status)) { return -1; } status = U_ZERO_ERROR; char buf[1024]; ucol_getShortDefinitionString(collator, NULL, buf, 1024, &status); if (utf16Storage) { err = sqlite3_create_collation_v2(handle, LOCALIZED_COLLATOR_NAME, SQLITE_UTF16, collator, collate16, (void(*)(void*))localized_collator_dtor); } else { err = sqlite3_create_collation_v2(handle, LOCALIZED_COLLATOR_NAME, SQLITE_UTF8, collator, collate8, (void(*)(void*))localized_collator_dtor); } if (err != SQLITE_OK) { return err; } // Register the _TOKENIZE function err = sqlite3_create_function(handle, "_TOKENIZE", 4, SQLITE_UTF16, collator, tokenize, NULL, NULL); if (err != SQLITE_OK) { return err; } err = sqlite3_create_function(handle, "_TOKENIZE", 5, SQLITE_UTF16, collator, tokenize, NULL, NULL); if (err != SQLITE_OK) { return err; } err = sqlite3_create_function(handle, "_TOKENIZE", 6, SQLITE_UTF16, collator, tokenize, NULL, NULL); if (err != SQLITE_OK) { return err; } //// PHONEBOOK_COLLATOR // The collator may be removed in the near future. Do not depend on it. // TODO: it might be better to have another function for registering phonebook collator. status = U_ZERO_ERROR; if (strcmp(systemLocale, "ja") == 0 || strcmp(systemLocale, "ja_JP") == 0) { collator = ucol_open("ja@collation=phonebook", &status); } else { collator = ucol_open(systemLocale, &status); } if (U_FAILURE(status)) { return -1; } status = U_ZERO_ERROR; ucol_setAttribute(collator, UCOL_STRENGTH, UCOL_PRIMARY, &status); if (U_FAILURE(status)) { return -1; } status = U_ZERO_ERROR; // ucol_getShortDefinitionString(collator, NULL, buf, 1024, &status); if (utf16Storage) { err = sqlite3_create_collation_v2(handle, PHONEBOOK_COLLATOR_NAME, SQLITE_UTF16, collator, collate16, (void(*)(void*))localized_collator_dtor); } else { err = sqlite3_create_collation_v2(handle, PHONEBOOK_COLLATOR_NAME, SQLITE_UTF8, collator, collate8, (void(*)(void*))localized_collator_dtor); } if (err != SQLITE_OK) { return err; } //// PHONEBOOK_COLLATOR return SQLITE_OK; }
void SQLiteDatabase::removeCollationFunction(const String& collationName) { sqlite3_create_collation_v2(m_db, collationName.utf8().data(), SQLITE_UTF8, nullptr, nullptr, nullptr); }
void SQLiteDatabase::setCollationFunction(const String& collationName, std::function<int(int, const void*, int, const void*)> collationFunction) { auto functionObject = new std::function<int(int, const void*, int, const void*)>(collationFunction); sqlite3_create_collation_v2(m_db, collationName.utf8().data(), SQLITE_UTF8, functionObject, callCollationFunction, destroyCollationFunction); }
extern "C" int register_localized_collators(sqlite3* handle, const char* systemLocale, int utf16Storage) { int err; UErrorCode status = U_ZERO_ERROR; void* icudata; UCollator* collator = ucol_open(systemLocale, &status); if (U_FAILURE(status)) { return -1; } ucol_setAttribute(collator, UCOL_STRENGTH, UCOL_PRIMARY, &status); if (U_FAILURE(status)) { return -1; } status = U_ZERO_ERROR; char buf[1024]; ucol_getShortDefinitionString(collator, NULL, buf, 1024, &status); if (utf16Storage) { err = sqlite3_create_collation_v2(handle, LOCALIZED_COLLATOR_NAME, SQLITE_UTF16, collator, collate16, (void(*)(void*))localized_collator_dtor); } else { err = sqlite3_create_collation_v2(handle, LOCALIZED_COLLATOR_NAME, SQLITE_UTF8, collator, collate8, (void(*)(void*))localized_collator_dtor); } if (err != SQLITE_OK) { return err; } // Register the _TOKENIZE function err = sqlite3_create_function(handle, "_TOKENIZE", 4, SQLITE_UTF16, collator, tokenize, NULL, NULL); if (err != SQLITE_OK) { return err; } err = sqlite3_create_function(handle, "_TOKENIZE", 5, SQLITE_UTF16, collator, tokenize, NULL, NULL); if (err != SQLITE_OK) { return err; } err = sqlite3_create_function(handle, "_TOKENIZE", 6, SQLITE_UTF16, collator, tokenize, NULL, NULL); if (err != SQLITE_OK) { return err; } //// PHONEBOOK_COLLATOR status = U_ZERO_ERROR; collator = ucol_open(systemLocale, &status); if (U_FAILURE(status)) { return -1; } status = U_ZERO_ERROR; ucol_setAttribute(collator, UCOL_STRENGTH, UCOL_PRIMARY, &status); if (U_FAILURE(status)) { return -1; } status = U_ZERO_ERROR; // ucol_getShortDefinitionString(collator, NULL, buf, 1024, &status); if (utf16Storage) { err = sqlite3_create_collation_v2(handle, PHONEBOOK_COLLATOR_NAME, SQLITE_UTF16, collator, collate16, (void(*)(void*))localized_collator_dtor); } else { err = sqlite3_create_collation_v2(handle, PHONEBOOK_COLLATOR_NAME, SQLITE_UTF8, collator, collate8, (void(*)(void*))localized_collator_dtor); } if (err != SQLITE_OK) { return err; } //// PHONEBOOK_COLLATOR return SQLITE_OK; }