Home | History | Annotate | Download | only in jni
      1 /*
      2  * Copyright (C) 2006-2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #undef LOG_TAG
     18 #define LOG_TAG "Cursor"
     19 
     20 #include <jni.h>
     21 #include <JNIHelp.h>
     22 #include <android_runtime/AndroidRuntime.h>
     23 
     24 #include <sqlite3.h>
     25 
     26 #include <utils/Log.h>
     27 
     28 #include <stdio.h>
     29 #include <string.h>
     30 #include <unistd.h>
     31 
     32 #include "sqlite3_exception.h"
     33 
     34 
     35 namespace android {
     36 
     37 static jfieldID gHandleField;
     38 static jfieldID gStatementField;
     39 
     40 
     41 #define GET_STATEMENT(env, object) \
     42         (sqlite3_stmt *)env->GetIntField(object, gStatementField)
     43 #define GET_HANDLE(env, object) \
     44         (sqlite3 *)env->GetIntField(object, gHandleField)
     45 
     46 static void native_compile(JNIEnv* env, jobject object, jstring sqlString)
     47 {
     48     char buf[65];
     49     strcpy(buf, "android_database_SQLiteProgram->native_compile() not implemented");
     50     throw_sqlite3_exception(env, GET_HANDLE(env, object), buf);
     51     return;
     52 }
     53 
     54 static void native_bind_null(JNIEnv* env, jobject object,
     55                              jint index)
     56 {
     57     int err;
     58     sqlite3_stmt * statement = GET_STATEMENT(env, object);
     59 
     60     err = sqlite3_bind_null(statement, index);
     61     if (err != SQLITE_OK) {
     62         char buf[32];
     63         sprintf(buf, "handle %p", statement);
     64         throw_sqlite3_exception(env, GET_HANDLE(env, object), buf);
     65         return;
     66     }
     67 }
     68 
     69 static void native_bind_long(JNIEnv* env, jobject object,
     70                              jint index, jlong value)
     71 {
     72     int err;
     73     sqlite3_stmt * statement = GET_STATEMENT(env, object);
     74 
     75     err = sqlite3_bind_int64(statement, index, value);
     76     if (err != SQLITE_OK) {
     77         char buf[32];
     78         sprintf(buf, "handle %p", statement);
     79         throw_sqlite3_exception(env, GET_HANDLE(env, object), buf);
     80         return;
     81     }
     82 }
     83 
     84 static void native_bind_double(JNIEnv* env, jobject object,
     85                              jint index, jdouble value)
     86 {
     87     int err;
     88     sqlite3_stmt * statement = GET_STATEMENT(env, object);
     89 
     90     err = sqlite3_bind_double(statement, index, value);
     91     if (err != SQLITE_OK) {
     92         char buf[32];
     93         sprintf(buf, "handle %p", statement);
     94         throw_sqlite3_exception(env, GET_HANDLE(env, object), buf);
     95         return;
     96     }
     97 }
     98 
     99 static void native_bind_string(JNIEnv* env, jobject object,
    100                                jint index, jstring sqlString)
    101 {
    102     int err;
    103     jchar const * sql;
    104     jsize sqlLen;
    105     sqlite3_stmt * statement= GET_STATEMENT(env, object);
    106 
    107     sql = env->GetStringChars(sqlString, NULL);
    108     sqlLen = env->GetStringLength(sqlString);
    109     err = sqlite3_bind_text16(statement, index, sql, sqlLen * 2, SQLITE_TRANSIENT);
    110     env->ReleaseStringChars(sqlString, sql);
    111     if (err != SQLITE_OK) {
    112         char buf[32];
    113         sprintf(buf, "handle %p", statement);
    114         throw_sqlite3_exception(env, GET_HANDLE(env, object), buf);
    115         return;
    116     }
    117 }
    118 
    119 static void native_bind_blob(JNIEnv* env, jobject object,
    120                                jint index, jbyteArray value)
    121 {
    122     int err;
    123     jchar const * sql;
    124     jsize sqlLen;
    125     sqlite3_stmt * statement= GET_STATEMENT(env, object);
    126 
    127     jint len = env->GetArrayLength(value);
    128     jbyte * bytes = env->GetByteArrayElements(value, NULL);
    129 
    130     err = sqlite3_bind_blob(statement, index, bytes, len, SQLITE_TRANSIENT);
    131     env->ReleaseByteArrayElements(value, bytes, JNI_ABORT);
    132 
    133     if (err != SQLITE_OK) {
    134         char buf[32];
    135         sprintf(buf, "statement %p", statement);
    136         throw_sqlite3_exception(env, GET_HANDLE(env, object), buf);
    137         return;
    138     }
    139 }
    140 
    141 static void native_clear_bindings(JNIEnv* env, jobject object)
    142 {
    143     int err;
    144     sqlite3_stmt * statement = GET_STATEMENT(env, object);
    145 
    146     err = sqlite3_clear_bindings(statement);
    147     if (err != SQLITE_OK) {
    148         throw_sqlite3_exception(env, GET_HANDLE(env, object));
    149         return;
    150     }
    151 }
    152 
    153 static void native_finalize(JNIEnv* env, jobject object)
    154 {
    155     char buf[66];
    156     strcpy(buf, "android_database_SQLiteProgram->native_finalize() not implemented");
    157     throw_sqlite3_exception(env, GET_HANDLE(env, object), buf);
    158     return;
    159 }
    160 
    161 
    162 static JNINativeMethod sMethods[] =
    163 {
    164      /* name, signature, funcPtr */
    165     {"native_bind_null", "(I)V", (void *)native_bind_null},
    166     {"native_bind_long", "(IJ)V", (void *)native_bind_long},
    167     {"native_bind_double", "(ID)V", (void *)native_bind_double},
    168     {"native_bind_string", "(ILjava/lang/String;)V", (void *)native_bind_string},
    169     {"native_bind_blob", "(I[B)V", (void *)native_bind_blob},
    170     {"native_clear_bindings", "()V", (void *)native_clear_bindings},
    171 };
    172 
    173 int register_android_database_SQLiteProgram(JNIEnv * env)
    174 {
    175     jclass clazz;
    176 
    177     clazz = env->FindClass("android/database/sqlite/SQLiteProgram");
    178     if (clazz == NULL) {
    179         LOGE("Can't find android/database/sqlite/SQLiteProgram");
    180         return -1;
    181     }
    182 
    183     gHandleField = env->GetFieldID(clazz, "nHandle", "I");
    184     gStatementField = env->GetFieldID(clazz, "nStatement", "I");
    185 
    186     if (gHandleField == NULL || gStatementField == NULL) {
    187         LOGE("Error locating fields");
    188         return -1;
    189     }
    190 
    191     return AndroidRuntime::registerNativeMethods(env,
    192         "android/database/sqlite/SQLiteProgram", sMethods, NELEM(sMethods));
    193 }
    194 
    195 } // namespace android
    196