From d680fa07557feee2379dc6b9c1ffa5a20177c066 Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Tue, 5 Apr 2016 08:18:09 +0100 Subject: [PATCH] missing --- packages/myddas/pl/CMakeLists.txt | 39 + .../sqlite3/Android/AndroidManifest.xml | 15 + .../myddas/sqlite3/Android/ant.properties | 17 + packages/myddas/sqlite3/Android/build.xml | 92 + .../myddas/sqlite3/Android/jni/Android.mk | 4 + .../myddas/sqlite3/Android/jni/Application.mk | 1 + .../android_database_SQLiteConnection.cpp | 1014 + .../myddas/sqlite3/Android/local.properties | 10 + .../sqlite3/Android/proguard-project.txt | 20 + .../myddas/sqlite3/Android/project.properties | 14 + .../Android/res/drawable-hdpi/ic_launcher.png | Bin 0 -> 9397 bytes .../Android/res/drawable-ldpi/ic_launcher.png | Bin 0 -> 2729 bytes .../Android/res/drawable-mdpi/ic_launcher.png | Bin 0 -> 5237 bytes .../res/drawable-xhdpi/ic_launcher.png | Bin 0 -> 14383 bytes .../sqlite3/Android/res/layout/main.xml | 36 + .../sqlite3/Android/res/values/strings.xml | 4 + .../sqlite/app/customsqlite/CustomSqlite.java | 416 + .../myddas/sqlite3/Android/www/index.wiki | 215 + packages/myddas/sqlite3/sqlite3.c | 189270 +++++++++++++++ packages/myddas/sqlite3/sqlite3ext.h | 546 + 20 files changed, 191713 insertions(+) create mode 100644 packages/myddas/pl/CMakeLists.txt create mode 100644 packages/myddas/sqlite3/Android/AndroidManifest.xml create mode 100644 packages/myddas/sqlite3/Android/ant.properties create mode 100644 packages/myddas/sqlite3/Android/build.xml create mode 100644 packages/myddas/sqlite3/Android/jni/Android.mk create mode 100644 packages/myddas/sqlite3/Android/jni/Application.mk create mode 100644 packages/myddas/sqlite3/Android/jni/sqlite/android_database_SQLiteConnection.cpp create mode 100644 packages/myddas/sqlite3/Android/local.properties create mode 100644 packages/myddas/sqlite3/Android/proguard-project.txt create mode 100644 packages/myddas/sqlite3/Android/project.properties create mode 100644 packages/myddas/sqlite3/Android/res/drawable-hdpi/ic_launcher.png create mode 100644 packages/myddas/sqlite3/Android/res/drawable-ldpi/ic_launcher.png create mode 100644 packages/myddas/sqlite3/Android/res/drawable-mdpi/ic_launcher.png create mode 100644 packages/myddas/sqlite3/Android/res/drawable-xhdpi/ic_launcher.png create mode 100644 packages/myddas/sqlite3/Android/res/layout/main.xml create mode 100644 packages/myddas/sqlite3/Android/res/values/strings.xml create mode 100644 packages/myddas/sqlite3/Android/src/org/sqlite/app/customsqlite/CustomSqlite.java create mode 100644 packages/myddas/sqlite3/Android/www/index.wiki create mode 100644 packages/myddas/sqlite3/sqlite3.c create mode 100644 packages/myddas/sqlite3/sqlite3ext.h diff --git a/packages/myddas/pl/CMakeLists.txt b/packages/myddas/pl/CMakeLists.txt new file mode 100644 index 000000000..ac51da1a0 --- /dev/null +++ b/packages/myddas/pl/CMakeLists.txt @@ -0,0 +1,39 @@ +set( MYDDAS_YPP + myddas.ypp + myddas_assert_predicates.ypp + myddas_top_level.ypp + myddas_errors.ypp + myddas_prolog2sql.ypp + myddas_mysql.ypp + myddas_postgres.ypp + myddas_sqlite3.ypp + myddas_util_predicates.ypp + myddas_prolog2sql_optimizer.ypp ) + +set (MYDDAS_YAP "") +function(cpp_compile output filename) + set(header_extension "yap") +get_filename_component(base ${filename} NAME_WE) + set(base_abs ${CMAKE_CURRENT_BINARY_DIR}/${base}) + set(outfile ${base_abs}.yap) + set(${output} ${${output}} ${outfile} PARENT_SCOPE) + #message("outfile=${outfile}: ${CMAKE_C_COMPILER} -E -Xpreprocessor P ${CMAKE_CURRENT_SOURCE_DIR}/${filename}\n") + add_custom_command( + OUTPUT ${outfile} + COMMAND ${CMAKE_C_COMPILER} ${MYDDAS_FLAGS} -x c -E -P -w ${CMAKE_CURRENT_SOURCE_DIR}/${filename} -o ${outfile} +DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${filename}") +set_source_files_properties(${outfile} PROPERTIES GENERATED TRUE) +endfunction() + +foreach(file ${MYDDAS_YPP}) + message("infile=${file}\n") + cpp_compile( MYDDAS_YAP ${file}) + #message("outfiles=${MYDDAS_YAP}\n") + endforeach() + +Add_custom_target (plmyddas ALL DEPENDS ${MYDDAS_YPP} ${MYDDAS_YAP} ) # WORKING_DIRECTORY ${CMAKE_BINARY_DIR} ) + + +install(FILES ${MYDDAS_YAP} + DESTINATION ${libpl} +) diff --git a/packages/myddas/sqlite3/Android/AndroidManifest.xml b/packages/myddas/sqlite3/Android/AndroidManifest.xml new file mode 100644 index 000000000..31bf961a2 --- /dev/null +++ b/packages/myddas/sqlite3/Android/AndroidManifest.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + diff --git a/packages/myddas/sqlite3/Android/ant.properties b/packages/myddas/sqlite3/Android/ant.properties new file mode 100644 index 000000000..b0971e891 --- /dev/null +++ b/packages/myddas/sqlite3/Android/ant.properties @@ -0,0 +1,17 @@ +# This file is used to override default values used by the Ant build system. +# +# This file must be checked into Version Control Systems, as it is +# integral to the build system of your project. + +# This file is only used by the Ant script. + +# You can use this to override default values such as +# 'source.dir' for the location of your java source folder and +# 'out.dir' for the location of your output folder. + +# You can also use it define how the release builds are signed by declaring +# the following properties: +# 'key.store' for the location of your keystore and +# 'key.alias' for the name of the key to use. +# The password will be asked during the build when you use the 'release' target. + diff --git a/packages/myddas/sqlite3/Android/build.xml b/packages/myddas/sqlite3/Android/build.xml new file mode 100644 index 000000000..d88d541a4 --- /dev/null +++ b/packages/myddas/sqlite3/Android/build.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/myddas/sqlite3/Android/jni/Android.mk b/packages/myddas/sqlite3/Android/jni/Android.mk new file mode 100644 index 000000000..e372509cb --- /dev/null +++ b/packages/myddas/sqlite3/Android/jni/Android.mk @@ -0,0 +1,4 @@ + +LOCAL_PATH:= $(call my-dir) +include $(LOCAL_PATH)/sqlite/Android.mk + diff --git a/packages/myddas/sqlite3/Android/jni/Application.mk b/packages/myddas/sqlite3/Android/jni/Application.mk new file mode 100644 index 000000000..fe0d98a35 --- /dev/null +++ b/packages/myddas/sqlite3/Android/jni/Application.mk @@ -0,0 +1 @@ +APP_STL:=stlport_static diff --git a/packages/myddas/sqlite3/Android/jni/sqlite/android_database_SQLiteConnection.cpp b/packages/myddas/sqlite3/Android/jni/sqlite/android_database_SQLiteConnection.cpp new file mode 100644 index 000000000..cd9ddff84 --- /dev/null +++ b/packages/myddas/sqlite3/Android/jni/sqlite/android_database_SQLiteConnection.cpp @@ -0,0 +1,1014 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* +** Modified to support SQLite extensions by the SQLite developers: +** sqlite-dev@sqlite.org. +*/ + +#define LOG_TAG "SQLiteConnection" + +#include "ALog-priv.h" +#include +#include + +#include +#include +#include +#include + +#if 0 +#include +#endif + +#include +#if 0 +#include +#endif + +#include "android_database_SQLiteCommon.h" + +#include + +// Set to 1 to use UTF16 storage for localized indexes. +#define UTF16_STORAGE 0 + +namespace android { + +/* Busy timeout in milliseconds. + * If another connection (possibly in another process) has the database locked + * for + * longer than this amount of time then SQLite will generate a SQLITE_BUSY + * error. + * The SQLITE_BUSY error is then raised as a SQLiteDatabaseLockedException. + * + * In ordinary usage, busy timeouts are quite rare. Most databases only ever + * have a single open connection at a time unless they are using WAL. When + * using + * WAL, a timeout could occur if one connection is busy performing an + * auto-checkpoint + * operation. The busy timeout needs to be long enough to tolerate slow I/O + * write + * operations but not so long as to cause the application to hang indefinitely + * if + * there is a problem acquiring a database lock. + */ +static const int BUSY_TIMEOUT_MS = 2500; + +static JavaVM *gpJavaVM = 0; + +static struct { + jfieldID name; + jfieldID numArgs; + jmethodID dispatchCallback; +} gSQLiteCustomFunctionClassInfo; + +static struct { jclass clazz; } gStringClassInfo; + +struct SQLiteConnection { + // Open flags. + // Must be kept in sync with the constants defined in SQLiteDatabase.java. + enum { + OPEN_READWRITE = 0x00000000, + OPEN_READONLY = 0x00000001, + OPEN_READ_MASK = 0x00000001, + NO_LOCALIZED_COLLATORS = 0x00000010, + CREATE_IF_NECESSARY = 0x10000000, + }; + + sqlite3 *const db; + const int openFlags; + std::string path; + std::string label; + + volatile bool canceled; + + SQLiteConnection(sqlite3 *db, int openFlags, const std::string &path, + const std::string &label) + : db(db), openFlags(openFlags), path(path), label(label), + canceled(false) {} +}; + +// Called each time a statement begins execution, when tracing is enabled. +static void sqliteTraceCallback(void *data, const char *sql) { + SQLiteConnection *connection = static_cast(data); + ALOG(LOG_VERBOSE, SQLITE_TRACE_TAG, "%s: \"%s\"\n", connection->label.c_str(), + sql); +} + +// Called each time a statement finishes execution, when profiling is enabled. +static void sqliteProfileCallback(void *data, const char *sql, + sqlite3_uint64 tm) { + SQLiteConnection *connection = static_cast(data); + ALOG(LOG_VERBOSE, SQLITE_PROFILE_TAG, "%s: \"%s\" took %0.3f ms\n", + connection->label.c_str(), sql, tm * 0.000001f); +} + +// Called after each SQLite VM instruction when cancelation is enabled. +static int sqliteProgressHandlerCallback(void *data) { + SQLiteConnection *connection = static_cast(data); + return connection->canceled; +} + +/* +** This function is a collation sequence callback equivalent to the built-in +** BINARY sequence. +** +** Stock Android uses a modified version of sqlite3.c that calls out to a module +** named "sqlite3_android" to add extra built-in collations and functions to +** all database handles. Specifically, collation sequence "LOCALIZED". For now, +** this module does not include sqlite3_android (since it is difficult to build +** with the NDK only). Instead, this function is registered as "LOCALIZED" for +*all +** new database handles. +*/ +static int coll_localized(void *not_used, int nKey1, const void *pKey1, + int nKey2, const void *pKey2) { + int rc, n; + n = nKey1 < nKey2 ? nKey1 : nKey2; + rc = memcmp(pKey1, pKey2, n); + if (rc == 0) { + rc = nKey1 - nKey2; + } + return rc; +} + +static jlong nativeOpen(JNIEnv *env, jclass clazz, jstring pathStr, + jint openFlags, jstring labelStr, jboolean enableTrace, + jboolean enableProfile) { + int sqliteFlags; + if (openFlags & SQLiteConnection::CREATE_IF_NECESSARY) { + sqliteFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; + } else if (openFlags & SQLiteConnection::OPEN_READONLY) { + sqliteFlags = SQLITE_OPEN_READONLY; + } else { + sqliteFlags = SQLITE_OPEN_READWRITE; + } + + const char *pathChars = env->GetStringUTFChars(pathStr, NULL); + std::string path(pathChars); + env->ReleaseStringUTFChars(pathStr, pathChars); + + const char *labelChars = env->GetStringUTFChars(labelStr, NULL); + std::string label(labelChars); + env->ReleaseStringUTFChars(labelStr, labelChars); + + sqlite3 *db; + int err = sqlite3_open_v2(path.c_str(), &db, sqliteFlags, NULL); + if (err != SQLITE_OK) { + throw_sqlite3_exception_errcode(env, err, "Could not open database"); + return 0; + } + err = + sqlite3_create_collation(db, "localized", SQLITE_UTF8, 0, coll_localized); + if (err != SQLITE_OK) { + throw_sqlite3_exception_errcode(env, err, "Could not register collation"); + sqlite3_close(db); + return 0; + } + + // Check that the database is really read/write when that is what we asked + // for. + if ((sqliteFlags & SQLITE_OPEN_READWRITE) && sqlite3_db_readonly(db, NULL)) { + throw_sqlite3_exception(env, db, + "Could not open the database in read/write mode."); + sqlite3_close(db); + return 0; + } + + // Set the default busy handler to retry automatically before returning + // SQLITE_BUSY. + err = sqlite3_busy_timeout(db, BUSY_TIMEOUT_MS); + if (err != SQLITE_OK) { + throw_sqlite3_exception(env, db, "Could not set busy timeout"); + sqlite3_close(db); + return 0; + } + +// Register custom Android functions. +#if 0 + err = register_android_functions(db, UTF16_STORAGE); + if (err) { + throw_sqlite3_exception(env, db, "Could not register Android SQL functions."); + sqlite3_close(db); + return 0; + } +#endif + + // Create wrapper object. + SQLiteConnection *connection = + new SQLiteConnection(db, openFlags, path, label); + + // Enable tracing and profiling if requested. + if (enableTrace) { + sqlite3_trace(db, &sqliteTraceCallback, connection); + } + if (enableProfile) { + sqlite3_profile(db, &sqliteProfileCallback, connection); + } + + ALOGV("Opened connection %p with label '%s'", db, label.c_str()); + return reinterpret_cast(connection); +} + +static void nativeClose(JNIEnv *env, jclass clazz, jlong connectionPtr) { + SQLiteConnection *connection = + reinterpret_cast(connectionPtr); + + if (connection) { + ALOGV("Closing connection %p", connection->db); + int err = sqlite3_close(connection->db); + if (err != SQLITE_OK) { + // This can happen if sub-objects aren't closed first. Make sure the + // caller knows. + ALOGE("sqlite3_close(%p) failed: %d", connection->db, err); + throw_sqlite3_exception(env, connection->db, "Count not close db."); + return; + } + + delete connection; + } +} + +// Called each time a custom function is evaluated. +static void sqliteCustomFunctionCallback(sqlite3_context *context, int argc, + sqlite3_value **argv) { + + JNIEnv *env = 0; + 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(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(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); + + error: + env->DeleteLocalRef(argsArray); + } + + env->DeleteLocalRef(functionObj); + + if (env->ExceptionCheck()) { + ALOGE("An exception was thrown by custom SQLite function."); + /* LOGE_EX(env); */ + env->ExceptionClear(); + } +} + +// Called when a custom function is destroyed. +static void sqliteCustomFunctionDestructor(void *data) { + jobject functionObjGlobal = reinterpret_cast(data); + JNIEnv *env = 0; + gpJavaVM->GetEnv((void **)&env, JNI_VERSION_1_4); + env->DeleteGlobalRef(functionObjGlobal); +} + +static void nativeRegisterCustomFunction(JNIEnv *env, jclass clazz, + jlong connectionPtr, + jobject functionObj) { + SQLiteConnection *connection = + reinterpret_cast(connectionPtr); + + jstring nameStr = jstring( + env->GetObjectField(functionObj, gSQLiteCustomFunctionClassInfo.name)); + jint numArgs = + env->GetIntField(functionObj, gSQLiteCustomFunctionClassInfo.numArgs); + + jobject functionObjGlobal = env->NewGlobalRef(functionObj); + + const char *name = env->GetStringUTFChars(nameStr, NULL); + int err = + sqlite3_create_function_v2(connection->db, name, numArgs, SQLITE_UTF16, + reinterpret_cast(functionObjGlobal), + &sqliteCustomFunctionCallback, NULL, NULL, + &sqliteCustomFunctionDestructor); + env->ReleaseStringUTFChars(nameStr, name); + + if (err != SQLITE_OK) { + ALOGE("sqlite3_create_function returned %d", err); + env->DeleteGlobalRef(functionObjGlobal); + throw_sqlite3_exception(env, connection->db); + return; + } +} + +static void nativeRegisterLocalizedCollators(JNIEnv *env, jclass clazz, + jlong connectionPtr, + jstring localeStr) { +#if 0 + SQLiteConnection* connection = reinterpret_cast(connectionPtr); + + const char* locale = env->GetStringUTFChars(localeStr, NULL); + int err = register_localized_collators(connection->db, locale, UTF16_STORAGE); + env->ReleaseStringUTFChars(localeStr, locale); + + if (err != SQLITE_OK) { + throw_sqlite3_exception(env, connection->db); + } +#endif +} + +static jlong nativePrepareStatement(JNIEnv *env, jclass clazz, + jlong connectionPtr, jstring sqlString) { + SQLiteConnection *connection = + reinterpret_cast(connectionPtr); + + jsize sqlLength = env->GetStringLength(sqlString); + const jchar *sql = env->GetStringCritical(sqlString, NULL); + sqlite3_stmt *statement; + int err = sqlite3_prepare16_v2(connection->db, sql, sqlLength * sizeof(jchar), + &statement, NULL); + env->ReleaseStringCritical(sqlString, sql); + + if (err != SQLITE_OK) { + // Error messages like 'near ")": syntax error' are not + // always helpful enough, so construct an error string that + // includes the query itself. + const char *query = env->GetStringUTFChars(sqlString, NULL); + char *message = (char *)malloc(strlen(query) + 50); + if (message) { + strcpy(message, ", while compiling: "); // less than 50 chars + strcat(message, query); + } + env->ReleaseStringUTFChars(sqlString, query); + throw_sqlite3_exception(env, connection->db, message); + free(message); + return 0; + } + + ALOGV("Prepared statement %p on connection %p", statement, connection->db); + return reinterpret_cast(statement); +} + +static void nativeFinalizeStatement(JNIEnv *env, jclass clazz, + jlong connectionPtr, jlong statementPtr) { + SQLiteConnection *connection = + reinterpret_cast(connectionPtr); + sqlite3_stmt *statement = reinterpret_cast(statementPtr); + + // We ignore the result of sqlite3_finalize because it is really telling us + // about + // whether any errors occurred while executing the statement. The statement + // itself + // is always finalized regardless. + ALOGV("Finalized statement %p on connection %p", statement, connection->db); + sqlite3_finalize(statement); +} + +static jint nativeGetParameterCount(JNIEnv *env, jclass clazz, + jlong connectionPtr, jlong statementPtr) { + // SQLiteConnection *connection = + // reinterpret_cast(connectionPtr); + sqlite3_stmt *statement = reinterpret_cast(statementPtr); + + return sqlite3_bind_parameter_count(statement); +} + +static jboolean nativeIsReadOnly(JNIEnv *env, jclass clazz, jlong connectionPtr, + jlong statementPtr) { + // SQLiteConnection *connection = + // reinterpret_cast(connectionPtr); + sqlite3_stmt *statement = reinterpret_cast(statementPtr); + + return sqlite3_stmt_readonly(statement) != 0; +} + +static jint nativeGetColumnCount(JNIEnv *env, jclass clazz, jlong connectionPtr, + jlong statementPtr) { + // SQLiteConnection *connection = + // reinterpret_cast(connectionPtr); + sqlite3_stmt *statement = reinterpret_cast(statementPtr); + + return sqlite3_column_count(statement); +} + +static jstring nativeGetColumnName(JNIEnv *env, jclass clazz, + jlong connectionPtr, jlong statementPtr, + jint index) { + // SQLiteConnection *connection = + // reinterpret_cast(connectionPtr); + sqlite3_stmt *statement = reinterpret_cast(statementPtr); + + const jchar *name = + static_cast(sqlite3_column_name16(statement, index)); + if (name) { + size_t length = 0; + while (name[length]) { + length += 1; + } + return env->NewString(name, length); + } + return NULL; +} + +static void nativeBindNull(JNIEnv *env, jclass clazz, jlong connectionPtr, + jlong statementPtr, jint index) { + SQLiteConnection *connection = + reinterpret_cast(connectionPtr); + sqlite3_stmt *statement = reinterpret_cast(statementPtr); + + int err = sqlite3_bind_null(statement, index); + if (err != SQLITE_OK) { + throw_sqlite3_exception(env, connection->db, NULL); + } +} + +static void nativeBindLong(JNIEnv *env, jclass clazz, jlong connectionPtr, + jlong statementPtr, jint index, jlong value) { + SQLiteConnection *connection = + reinterpret_cast(connectionPtr); + sqlite3_stmt *statement = reinterpret_cast(statementPtr); + + int err = sqlite3_bind_int64(statement, index, value); + if (err != SQLITE_OK) { + throw_sqlite3_exception(env, connection->db, NULL); + } +} + +static void nativeBindDouble(JNIEnv *env, jclass clazz, jlong connectionPtr, + jlong statementPtr, jint index, jdouble value) { + SQLiteConnection *connection = + reinterpret_cast(connectionPtr); + sqlite3_stmt *statement = reinterpret_cast(statementPtr); + + int err = sqlite3_bind_double(statement, index, value); + if (err != SQLITE_OK) { + throw_sqlite3_exception(env, connection->db, NULL); + } +} + +static void nativeBindString(JNIEnv *env, jclass clazz, jlong connectionPtr, + jlong statementPtr, jint index, + jstring valueString) { + SQLiteConnection *connection = + reinterpret_cast(connectionPtr); + sqlite3_stmt *statement = reinterpret_cast(statementPtr); + + jsize valueLength = env->GetStringLength(valueString); + const jchar *value = env->GetStringCritical(valueString, NULL); + int err = sqlite3_bind_text16(statement, index, value, + valueLength * sizeof(jchar), SQLITE_TRANSIENT); + env->ReleaseStringCritical(valueString, value); + if (err != SQLITE_OK) { + throw_sqlite3_exception(env, connection->db, NULL); + } +} + +static void nativeBindBlob(JNIEnv *env, jclass clazz, jlong connectionPtr, + jlong statementPtr, jint index, + jbyteArray valueArray) { + SQLiteConnection *connection = + reinterpret_cast(connectionPtr); + sqlite3_stmt *statement = reinterpret_cast(statementPtr); + + jsize valueLength = env->GetArrayLength(valueArray); + jbyte *value = + static_cast(env->GetPrimitiveArrayCritical(valueArray, NULL)); + int err = + sqlite3_bind_blob(statement, index, value, valueLength, SQLITE_TRANSIENT); + env->ReleasePrimitiveArrayCritical(valueArray, value, JNI_ABORT); + if (err != SQLITE_OK) { + throw_sqlite3_exception(env, connection->db, NULL); + } +} + +static void nativeResetStatementAndClearBindings(JNIEnv *env, jclass clazz, + jlong connectionPtr, + jlong statementPtr) { + SQLiteConnection *connection = + reinterpret_cast(connectionPtr); + sqlite3_stmt *statement = reinterpret_cast(statementPtr); + + int err = sqlite3_reset(statement); + if (err == SQLITE_OK) { + err = sqlite3_clear_bindings(statement); + } + if (err != SQLITE_OK) { + throw_sqlite3_exception(env, connection->db, NULL); + } +} + +static int executeNonQuery(JNIEnv *env, SQLiteConnection *connection, + sqlite3_stmt *statement) { + int err = sqlite3_step(statement); + if (err == SQLITE_ROW) { + throw_sqlite3_exception(env, "Queries can be performed using " + "SQLiteDatabase query or rawQuery methods " + "only."); + } else if (err != SQLITE_DONE) { + throw_sqlite3_exception(env, connection->db); + } + return err; +} + +static void nativeExecute(JNIEnv *env, jclass clazz, jlong connectionPtr, + jlong statementPtr) { + SQLiteConnection *connection = + reinterpret_cast(connectionPtr); + sqlite3_stmt *statement = reinterpret_cast(statementPtr); + + executeNonQuery(env, connection, statement); +} + +static jint nativeExecuteForChangedRowCount(JNIEnv *env, jclass clazz, + jlong connectionPtr, + jlong statementPtr) { + SQLiteConnection *connection = + reinterpret_cast(connectionPtr); + sqlite3_stmt *statement = reinterpret_cast(statementPtr); + + int err = executeNonQuery(env, connection, statement); + return err == SQLITE_DONE ? sqlite3_changes(connection->db) : -1; +} + +static jlong nativeExecuteForLastInsertedRowId(JNIEnv *env, jclass clazz, + jlong connectionPtr, + jlong statementPtr) { + SQLiteConnection *connection = + reinterpret_cast(connectionPtr); + sqlite3_stmt *statement = reinterpret_cast(statementPtr); + + int err = executeNonQuery(env, connection, statement); + return err == SQLITE_DONE && sqlite3_changes(connection->db) > 0 + ? sqlite3_last_insert_rowid(connection->db) + : -1; +} + +static int executeOneRowQuery(JNIEnv *env, SQLiteConnection *connection, + sqlite3_stmt *statement) { + int err = sqlite3_step(statement); + if (err != SQLITE_ROW) { + throw_sqlite3_exception(env, connection->db); + } + return err; +} + +static jlong nativeExecuteForLong(JNIEnv *env, jclass clazz, + jlong connectionPtr, jlong statementPtr) { + SQLiteConnection *connection = + reinterpret_cast(connectionPtr); + sqlite3_stmt *statement = reinterpret_cast(statementPtr); + + int err = executeOneRowQuery(env, connection, statement); + if (err == SQLITE_ROW && sqlite3_column_count(statement) >= 1) { + return sqlite3_column_int64(statement, 0); + } + return -1; +} + +static jstring nativeExecuteForString(JNIEnv *env, jclass clazz, + jlong connectionPtr, jlong statementPtr) { + SQLiteConnection *connection = + reinterpret_cast(connectionPtr); + sqlite3_stmt *statement = reinterpret_cast(statementPtr); + + int err = executeOneRowQuery(env, connection, statement); + if (err == SQLITE_ROW && sqlite3_column_count(statement) >= 1) { + const jchar *text = + static_cast(sqlite3_column_text16(statement, 0)); + if (text) { + size_t length = sqlite3_column_bytes16(statement, 0) / sizeof(jchar); + return env->NewString(text, length); + } + } + return NULL; +} + +static int createAshmemRegionWithData(JNIEnv *env, const void *data, + size_t length) { +#if 0 + int error = 0; + int fd = ashmem_create_region(NULL, length); + if (fd < 0) { + error = errno; + ALOGE("ashmem_create_region failed: %s", strerror(error)); + } else { + if (length > 0) { + void* ptr = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (ptr == MAP_FAILED) { + error = errno; + ALOGE("mmap failed: %s", strerror(error)); + } else { + memcpy(ptr, data, length); + munmap(ptr, length); + } + } + + if (!error) { + if (ashmem_set_prot_region(fd, PROT_READ) < 0) { + error = errno; + ALOGE("ashmem_set_prot_region failed: %s", strerror(errno)); + } else { + return fd; + } + } + + close(fd); + } + +#endif + jniThrowIOException(env, -1); + return -1; +} + +static jint nativeExecuteForBlobFileDescriptor(JNIEnv *env, jclass clazz, + jlong connectionPtr, + jlong statementPtr) { + SQLiteConnection *connection = + reinterpret_cast(connectionPtr); + sqlite3_stmt *statement = reinterpret_cast(statementPtr); + + int err = executeOneRowQuery(env, connection, statement); + if (err == SQLITE_ROW && sqlite3_column_count(statement) >= 1) { + const void *blob = sqlite3_column_blob(statement, 0); + if (blob) { + int length = sqlite3_column_bytes(statement, 0); + if (length >= 0) { + return createAshmemRegionWithData(env, blob, length); + } + } + } + return -1; +} + +/* +** Note: The following symbols must be in the same order as the corresponding +** elements in the aMethod[] array in function nativeExecuteForCursorWindow(). +*/ +enum CWMethodNames { + CW_CLEAR = 0, + CW_SETNUMCOLUMNS = 1, + CW_ALLOCROW = 2, + CW_FREELASTROW = 3, + CW_PUTNULL = 4, + CW_PUTLONG = 5, + CW_PUTDOUBLE = 6, + CW_PUTSTRING = 7, + CW_PUTBLOB = 8 +}; + +/* +** An instance of this structure represents a single CursorWindow java method. +*/ +struct CWMethod { + jmethodID id; /* Method id */ + const char *zName; /* Method name */ + const char *zSig; /* Method JNI signature */ +}; + +/* +** Append the contents of the row that SQL statement pStmt currently points to +** to the CursorWindow object passed as the second argument. The CursorWindow +** currently contains iRow rows. Return true on success or false if an error +** occurs. +*/ +static jboolean copyRowToWindow(JNIEnv *pEnv, jobject win, int iRow, + sqlite3_stmt *pStmt, CWMethod *aMethod) { + int nCol = sqlite3_column_count(pStmt); + int i; + jboolean bOk; + + bOk = pEnv->CallBooleanMethod(win, aMethod[CW_ALLOCROW].id); + for (i = 0; bOk && i < nCol; i++) { + switch (sqlite3_column_type(pStmt, i)) { + case SQLITE_NULL: { + bOk = pEnv->CallBooleanMethod(win, aMethod[CW_PUTNULL].id, iRow, i); + break; + } + + case SQLITE_INTEGER: { + jlong val = sqlite3_column_int64(pStmt, i); + bOk = pEnv->CallBooleanMethod(win, aMethod[CW_PUTLONG].id, val, iRow, i); + break; + } + + case SQLITE_FLOAT: { + jdouble val = sqlite3_column_double(pStmt, i); + bOk = + pEnv->CallBooleanMethod(win, aMethod[CW_PUTDOUBLE].id, val, iRow, i); + break; + } + + case SQLITE_TEXT: { + jchar *pStr = (jchar *)sqlite3_column_text16(pStmt, i); + int nStr = sqlite3_column_bytes16(pStmt, i) / sizeof(jchar); + jstring val = pEnv->NewString(pStr, nStr); + bOk = + pEnv->CallBooleanMethod(win, aMethod[CW_PUTSTRING].id, val, iRow, i); + pEnv->DeleteLocalRef(val); + break; + } + + default: { + assert(sqlite3_column_type(pStmt, i) == SQLITE_BLOB); + const jbyte *p = (const jbyte *)sqlite3_column_blob(pStmt, i); + int n = sqlite3_column_bytes(pStmt, i); + jbyteArray val = pEnv->NewByteArray(n); + pEnv->SetByteArrayRegion(val, 0, n, p); + bOk = pEnv->CallBooleanMethod(win, aMethod[CW_PUTBLOB].id, val, iRow, i); + pEnv->DeleteLocalRef(val); + break; + } + } + + if (bOk == 0) { + pEnv->CallVoidMethod(win, aMethod[CW_FREELASTROW].id); + } + } + + return bOk; +} + +static jboolean setWindowNumColumns(JNIEnv *pEnv, jobject win, + sqlite3_stmt *pStmt, CWMethod *aMethod) { + int nCol; + + pEnv->CallVoidMethod(win, aMethod[CW_CLEAR].id); + nCol = sqlite3_column_count(pStmt); + return pEnv->CallBooleanMethod(win, aMethod[CW_SETNUMCOLUMNS].id, (jint)nCol); +} + +/* +** This method has been rewritten for org.sqlite.database.*. The original +** android implementation used the C++ interface to populate a CursorWindow +** object. Since the NDK does not export this interface, we invoke the Java +** interface using standard JNI methods to do the same thing. +** +** This function executes the SQLite statement object passed as the 4th +** argument and copies one or more returned rows into the CursorWindow +** object passed as the 5th argument. The set of rows copied into the +** CursorWindow is always contiguous. +** +** The only row that *must* be copied into the CursorWindow is row +** iRowRequired. Ideally, all rows from iRowStart through to the end +** of the query are copied into the CursorWindow. If this is not possible +** (CursorWindow objects have a finite capacity), some compromise position +** is found (see comments embedded in the code below for details). +** +** The return value is a 64-bit integer calculated as follows: +** +** (iStart << 32) | nRow +** +** where iStart is the index of the first row copied into the CursorWindow. +** If the countAllRows argument is true, nRow is the total number of rows +** returned by the query. Otherwise, nRow is one greater than the index of +** the last row copied into the CursorWindow. +*/ +static jlong nativeExecuteForCursorWindow( + JNIEnv *pEnv, jclass clazz, + jlong connectionPtr, /* Pointer to SQLiteConnection C++ object */ + jlong statementPtr, /* Pointer to sqlite3_stmt object */ + jobject win, /* The CursorWindow object to populate */ + jint startPos, /* First row to add (advisory) */ + jint iRowRequired, /* Required row */ + jboolean countAllRows) { + // SQLiteConnection *pConnection = + // reinterpret_cast(connectionPtr); + sqlite3_stmt *pStmt = reinterpret_cast(statementPtr); + + CWMethod aMethod[] = { + {0, "clear", "()V"}, {0, "setNumColumns", "(I)Z"}, + {0, "allocRow", "()Z"}, {0, "freeLastRow", "()V"}, + {0, "putNull", "(II)Z"}, {0, "putLong", "(JII)Z"}, + {0, "putDouble", "(DII)Z"}, {0, "putString", "(Ljava/lang/String;II)Z"}, + {0, "putBlob", "([BII)Z"}, + }; + jclass cls; /* Class android.database.CursorWindow */ + unsigned int i; /* Iterator variable */ + // int nCol; /* Number of columns returned by pStmt */ + int nRow; + jboolean bOk; + int iStart; /* First row copied to CursorWindow */ + + /* Locate all required CursorWindow methods. */ + cls = pEnv->FindClass("android/database/CursorWindow"); + for (i = 0; i < (sizeof(aMethod) / sizeof(struct CWMethod)); i++) { + aMethod[i].id = pEnv->GetMethodID(cls, aMethod[i].zName, aMethod[i].zSig); + if (aMethod[i].id == NULL) { + jniThrowExceptionFmt(pEnv, "java/lang/Exception", + "Failed to find method CursorWindow.%s()", + aMethod[i].zName); + return 0; + } + } + + /* Set the number of columns in the window */ + bOk = setWindowNumColumns(pEnv, win, pStmt, aMethod); + if (bOk == 0) + return 0; + + nRow = 0; + iStart = startPos; + while (sqlite3_step(pStmt) == SQLITE_ROW) { + /* Only copy in rows that occur at or after row index iStart. */ + if (nRow >= iStart && bOk) { + bOk = copyRowToWindow(pEnv, win, (nRow - iStart), pStmt, aMethod); + if (bOk == 0) { + /* The CursorWindow object ran out of memory. If row iRowRequired was + ** not successfully added before this happened, clear the CursorWindow + ** and try to add the current row again. */ + if (nRow <= iRowRequired) { + bOk = setWindowNumColumns(pEnv, win, pStmt, aMethod); + if (bOk == 0) { + sqlite3_reset(pStmt); + return 0; + } + iStart = nRow; + bOk = copyRowToWindow(pEnv, win, (nRow - iStart), pStmt, aMethod); + } + + /* If the CursorWindow is still full and the countAllRows flag is not + ** set, break out of the loop here. If countAllRows is set, continue + ** so as to set variable nRow correctly. */ + if (bOk == 0 && countAllRows == 0) + break; + } + } + + nRow++; + } + + /* Finalize the statement. If this indicates an error occurred, throw an + ** SQLiteException exception. */ + int rc = sqlite3_reset(pStmt); + if (rc != SQLITE_OK) { + throw_sqlite3_exception(pEnv, sqlite3_db_handle(pStmt)); + return 0; + } + + jlong lRet = jlong(iStart) << 32 | jlong(nRow); + return lRet; +} + +static jint nativeGetDbLookaside(JNIEnv *env, jobject clazz, + jlong connectionPtr) { + SQLiteConnection *connection = + reinterpret_cast(connectionPtr); + + int cur = -1; + int unused; + sqlite3_db_status(connection->db, SQLITE_DBSTATUS_LOOKASIDE_USED, &cur, + &unused, 0); + return cur; +} + +static void nativeCancel(JNIEnv *env, jobject clazz, jlong connectionPtr) { + SQLiteConnection *connection = + reinterpret_cast(connectionPtr); + connection->canceled = true; +} + +static void nativeResetCancel(JNIEnv *env, jobject clazz, jlong connectionPtr, + jboolean cancelable) { + SQLiteConnection *connection = + reinterpret_cast(connectionPtr); + connection->canceled = false; + + if (cancelable) { + sqlite3_progress_handler(connection->db, 4, sqliteProgressHandlerCallback, + connection); + } else { + sqlite3_progress_handler(connection->db, 0, NULL, NULL); + } +} + +static jboolean nativeHasCodec(JNIEnv *env, jobject clazz) { +#ifdef SQLITE_HAS_CODEC + return true; +#else + return false; +#endif +} + +static JNINativeMethod sMethods[] = { + /* name, signature, funcPtr */ + {"nativeOpen", "(Ljava/lang/String;ILjava/lang/String;ZZ)J", + (void *)nativeOpen}, + {"nativeClose", "(J)V", (void *)nativeClose}, + {"nativeRegisterCustomFunction", + "(JLorg/sqlite/database/sqlite/SQLiteCustomFunction;)V", + (void *)nativeRegisterCustomFunction}, + {"nativeRegisterLocalizedCollators", "(JLjava/lang/String;)V", + (void *)nativeRegisterLocalizedCollators}, + {"nativePrepareStatement", "(JLjava/lang/String;)J", + (void *)nativePrepareStatement}, + {"nativeFinalizeStatement", "(JJ)V", (void *)nativeFinalizeStatement}, + {"nativeGetParameterCount", "(JJ)I", (void *)nativeGetParameterCount}, + {"nativeIsReadOnly", "(JJ)Z", (void *)nativeIsReadOnly}, + {"nativeGetColumnCount", "(JJ)I", (void *)nativeGetColumnCount}, + {"nativeGetColumnName", "(JJI)Ljava/lang/String;", + (void *)nativeGetColumnName}, + {"nativeBindNull", "(JJI)V", (void *)nativeBindNull}, + {"nativeBindLong", "(JJIJ)V", (void *)nativeBindLong}, + {"nativeBindDouble", "(JJID)V", (void *)nativeBindDouble}, + {"nativeBindString", "(JJILjava/lang/String;)V", (void *)nativeBindString}, + {"nativeBindBlob", "(JJI[B)V", (void *)nativeBindBlob}, + {"nativeResetStatementAndClearBindings", "(JJ)V", + (void *)nativeResetStatementAndClearBindings}, + {"nativeExecute", "(JJ)V", (void *)nativeExecute}, + {"nativeExecuteForLong", "(JJ)J", (void *)nativeExecuteForLong}, + {"nativeExecuteForString", "(JJ)Ljava/lang/String;", + (void *)nativeExecuteForString}, + {"nativeExecuteForBlobFileDescriptor", "(JJ)I", + (void *)nativeExecuteForBlobFileDescriptor}, + {"nativeExecuteForChangedRowCount", "(JJ)I", + (void *)nativeExecuteForChangedRowCount}, + {"nativeExecuteForLastInsertedRowId", "(JJ)J", + (void *)nativeExecuteForLastInsertedRowId}, + {"nativeExecuteForCursorWindow", "(JJLandroid/database/CursorWindow;IIZ)J", + (void *)nativeExecuteForCursorWindow}, + {"nativeGetDbLookaside", "(J)I", (void *)nativeGetDbLookaside}, + {"nativeCancel", "(J)V", (void *)nativeCancel}, + {"nativeResetCancel", "(JZ)V", (void *)nativeResetCancel}, + + {"nativeHasCodec", "()Z", (void *)nativeHasCodec}, +}; + +#define FIND_CLASS(var, className) \ + var = env->FindClass(className); \ + LOG_FATAL_IF(!var, "Unable to find class " className); + +#define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \ + var = env->GetMethodID(clazz, methodName, fieldDescriptor); \ + LOG_FATAL_IF(!var, "Unable to find method" methodName); + +#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \ + var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \ + LOG_FATAL_IF(!var, "Unable to find field " fieldName); + +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;)V"); + + FIND_CLASS(clazz, "java/lang/String"); + gStringClassInfo.clazz = jclass(env->NewGlobalRef(clazz)); + + return jniRegisterNativeMethods(env, + "org/sqlite/database/sqlite/SQLiteConnection", + sMethods, NELEM(sMethods)); +} + +extern int register_android_database_SQLiteGlobal(JNIEnv *env); +extern int register_android_database_SQLiteDebug(JNIEnv *env); + +} // namespace android + +extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { + JNIEnv *env = 0; + + android::gpJavaVM = vm; + vm->GetEnv((void **)&env, JNI_VERSION_1_4); + + android::register_android_database_SQLiteConnection(env); + android::register_android_database_SQLiteDebug(env); + android::register_android_database_SQLiteGlobal(env); + + return JNI_VERSION_1_4; +} diff --git a/packages/myddas/sqlite3/Android/local.properties b/packages/myddas/sqlite3/Android/local.properties new file mode 100644 index 000000000..0bf9e3e43 --- /dev/null +++ b/packages/myddas/sqlite3/Android/local.properties @@ -0,0 +1,10 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must *NOT* be checked into Version Control Systems, +# as it contains information specific to your local configuration. + +# location of the SDK. This is only used by Ant +# For customization when using a Version Control System, please read the +# header note. +sdk.dir=/home/dan/adt-bundle-linux-x86-20131030/sdk/ diff --git a/packages/myddas/sqlite3/Android/proguard-project.txt b/packages/myddas/sqlite3/Android/proguard-project.txt new file mode 100644 index 000000000..f2fe1559a --- /dev/null +++ b/packages/myddas/sqlite3/Android/proguard-project.txt @@ -0,0 +1,20 @@ +# To enable ProGuard in your project, edit project.properties +# to define the proguard.config property as described in that file. +# +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in ${sdk.dir}/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the ProGuard +# include property in project.properties. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/packages/myddas/sqlite3/Android/project.properties b/packages/myddas/sqlite3/Android/project.properties new file mode 100644 index 000000000..4ab125693 --- /dev/null +++ b/packages/myddas/sqlite3/Android/project.properties @@ -0,0 +1,14 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system edit +# "ant.properties", and override values to adapt the script to your +# project structure. +# +# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): +#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt + +# Project target. +target=android-19 diff --git a/packages/myddas/sqlite3/Android/res/drawable-hdpi/ic_launcher.png b/packages/myddas/sqlite3/Android/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..96a442e5b8e9394ccf50bab9988cb2316026245d GIT binary patch literal 9397 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 literal 0 HcmV?d00001 diff --git a/packages/myddas/sqlite3/Android/res/drawable-mdpi/ic_launcher.png b/packages/myddas/sqlite3/Android/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..359047dfa4ed206e41e2354f9c6b307e713efe32 GIT binary patch literal 5237 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 literal 0 HcmV?d00001 diff --git a/packages/myddas/sqlite3/Android/res/drawable-xhdpi/ic_launcher.png b/packages/myddas/sqlite3/Android/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..71c6d760f05183ef8a47c614d8d13380c8528499 GIT binary patch literal 14383 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 literal 0 HcmV?d00001 diff --git a/packages/myddas/sqlite3/Android/res/layout/main.xml b/packages/myddas/sqlite3/Android/res/layout/main.xml new file mode 100644 index 000000000..a569727f5 --- /dev/null +++ b/packages/myddas/sqlite3/Android/res/layout/main.xml @@ -0,0 +1,36 @@ + + + + + + + +