only supports case-insensitive comparisons of ASCII characters
System.loadLibrary("sqliteX");
private final SQLiteDatabase.CustomFunction mLowerFnc = new SQLiteDatabase.CustomFunction() { @Override public void callback(String[] args) { String text = args[0]; text = text.toLowerCase(); Log.d(LOG, "LOWER_FNC : " + text); return; } };
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("LOWER_FNC", 1, mLowerFnc); }
DB_PATH = getApplicationContext().getDatabasePath("test.db"); DB_PATH.mkdirs();
// 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->CallVoidMethod(functionObj, gSQLiteCustomFunctionClassInfo.dispatchCallback, argsArray); ...
result = env->CallObjectMethod( functionObj, gSQLiteCustomFunctionClassInfo.dispatchCallback, argsArray); char_result = env->GetStringUTFChars( (jstring) result, NULL); sqlite3_result_text(context, char_result, -1, SQLITE_TRANSIENT);
// 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->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<jobject>(sqlite3_user_data(context)); jobject functionObj = env->NewLocalRef(functionObjGlobal); jobjectArray argsArray = env->NewObjectArray(argc, gStringClassInfo.clazz, NULL); if (argsArray) { for (int i = 0; i < argc; i++) { const jchar* arg = static_cast<const jchar*>(sqlite3_value_text16(argv[i])); if (!arg) { ALOGW("NULL argument in custom_function_callback. This should not happen."); } else { size_t argLen = sqlite3_value_bytes16(argv[i]) / sizeof(jchar); jstring argStr = env->NewString(arg, argLen); if (!argStr) { goto error; // out of memory error } env->SetObjectArrayElement(argsArray, i, argStr); env->DeleteLocalRef(argStr); } } // TODO: Support functions that return values. //env->CallVoidMethod(functionObj, // gSQLiteCustomFunctionClassInfo.dispatchCallback, argsArray); result = env->CallObjectMethod( functionObj, gSQLiteCustomFunctionClassInfo.dispatchCallback, argsArray); char_result = env->GetStringUTFChars( (jstring) result, NULL); sqlite3_result_text(context, char_result, -1, SQLITE_TRANSIENT); error: env->DeleteLocalRef(argsArray); } env->DeleteLocalRef(functionObj); env->DeleteLocalRef(result); if (env->ExceptionCheck()) { ALOGE("An exception was thrown by custom SQLite function."); /* LOGE_EX(env); */ env->ExceptionClear(); } }
GET_METHOD_ID(gSQLiteCustomFunctionClassInfo.dispatchCallback, clazz, "dispatchCallback", "([Ljava/lang/String;)Ljava/lang/String;");
int register_android_database_SQLiteConnection(JNIEnv *env) { jclass clazz; FIND_CLASS(clazz, "org/sqlite/database/sqlite/SQLiteCustomFunction"); GET_FIELD_ID(gSQLiteCustomFunctionClassInfo.name, clazz, "name", "Ljava/lang/String;"); GET_FIELD_ID(gSQLiteCustomFunctionClassInfo.numArgs, clazz, "numArgs", "I"); GET_METHOD_ID(gSQLiteCustomFunctionClassInfo.dispatchCallback, clazz, "dispatchCallback", "([Ljava/lang/String;)Ljava/lang/String;"); FIND_CLASS(clazz, "java/lang/String"); gStringClassInfo.clazz = jclass(env->NewGlobalRef(clazz)); return jniRegisterNativeMethods(env, "org/sqlite/database/sqlite/SQLiteConnection", sMethods, NELEM(sMethods) ); }
private final SQLiteDatabase.CustomFunction mLowerFnc = new SQLiteDatabase.CustomFunction() { @Override public String callback(String[] args) { String text = args[0]; text = text.toLowerCase(); Log.d(LOG, "LOWER_FNC : " + 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); }
Source: https://habr.com/ru/post/252823/
All Articles