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
native_compile(JNIEnv * env,jobject object,jstring sqlString)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
native_bind_null(JNIEnv * env,jobject object,jint index)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
native_bind_long(JNIEnv * env,jobject object,jint index,jlong value)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
native_bind_double(JNIEnv * env,jobject object,jint index,jdouble value)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
native_bind_string(JNIEnv * env,jobject object,jint index,jstring sqlString)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
native_bind_blob(JNIEnv * env,jobject object,jint index,jbyteArray value)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
native_clear_bindings(JNIEnv * env,jobject object)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
native_finalize(JNIEnv * env,jobject object)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
register_android_database_SQLiteProgram(JNIEnv * env)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