1/* //device/libs/android_runtime/android_database_SQLiteCursor.cpp
2**
3** Copyright 2006, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9**     http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18#undef LOG_TAG
19#define LOG_TAG "Cursor"
20
21#include <jni.h>
22#include <JNIHelp.h>
23#include <android_runtime/AndroidRuntime.h>
24
25#include <sqlite3.h>
26
27#include <utils/Log.h>
28
29#include <stdio.h>
30#include <string.h>
31#include <unistd.h>
32
33#include "sqlite3_exception.h"
34
35namespace android {
36
37
38sqlite3_stmt * compile(JNIEnv* env, jobject object,
39                       sqlite3 * handle, jstring sqlString);
40
41static jfieldID gHandleField;
42static jfieldID gStatementField;
43
44
45#define GET_STATEMENT(env, object) \
46        (sqlite3_stmt *)env->GetIntField(object, gStatementField)
47#define GET_HANDLE(env, object) \
48        (sqlite3 *)env->GetIntField(object, gHandleField)
49
50
51static void native_execute(JNIEnv* env, jobject object)
52{
53    int err;
54    sqlite3 * handle = GET_HANDLE(env, object);
55    sqlite3_stmt * statement = GET_STATEMENT(env, object);
56
57    // Execute the statement
58    err = sqlite3_step(statement);
59
60    // Throw an exception if an error occured
61    if (err != SQLITE_DONE) {
62        throw_sqlite3_exception_errcode(env, err, sqlite3_errmsg(handle));
63    }
64
65    // Reset the statment so it's ready to use again
66    sqlite3_reset(statement);
67}
68
69static jlong native_1x1_long(JNIEnv* env, jobject object)
70{
71    int err;
72    sqlite3 * handle = GET_HANDLE(env, object);
73    sqlite3_stmt * statement = GET_STATEMENT(env, object);
74    jlong value = -1;
75
76    // Execute the statement
77    err = sqlite3_step(statement);
78
79    // Handle the result
80    if (err == SQLITE_ROW) {
81        // No errors, read the data and return it
82        value = sqlite3_column_int64(statement, 0);
83    } else {
84        throw_sqlite3_exception_errcode(env, err, sqlite3_errmsg(handle));
85    }
86
87    // Reset the statment so it's ready to use again
88    sqlite3_reset(statement);
89
90    return value;
91}
92
93static jstring native_1x1_string(JNIEnv* env, jobject object)
94{
95    int err;
96    sqlite3 * handle = GET_HANDLE(env, object);
97    sqlite3_stmt * statement = GET_STATEMENT(env, object);
98    jstring value = NULL;
99
100    // Execute the statement
101    err = sqlite3_step(statement);
102
103    // Handle the result
104    if (err == SQLITE_ROW) {
105        // No errors, read the data and return it
106        char const * text = (char const *)sqlite3_column_text(statement, 0);
107        value = env->NewStringUTF(text);
108    } else {
109        throw_sqlite3_exception_errcode(env, err, sqlite3_errmsg(handle));
110    }
111
112    // Reset the statment so it's ready to use again
113    sqlite3_reset(statement);
114
115    return value;
116}
117
118
119static JNINativeMethod sMethods[] =
120{
121     /* name, signature, funcPtr */
122    {"native_execute", "()V", (void *)native_execute},
123    {"native_1x1_long", "()J", (void *)native_1x1_long},
124    {"native_1x1_string", "()Ljava/lang/String;", (void *)native_1x1_string},
125};
126
127int register_android_database_SQLiteStatement(JNIEnv * env)
128{
129    jclass clazz;
130
131    clazz = env->FindClass("android/database/sqlite/SQLiteStatement");
132    if (clazz == NULL) {
133        LOGE("Can't find android/database/sqlite/SQLiteStatement");
134        return -1;
135    }
136
137    gHandleField = env->GetFieldID(clazz, "nHandle", "I");
138    gStatementField = env->GetFieldID(clazz, "nStatement", "I");
139
140    if (gHandleField == NULL || gStatementField == NULL) {
141        LOGE("Error locating fields");
142        return -1;
143    }
144
145    return AndroidRuntime::registerNativeMethods(env,
146        "android/database/sqlite/SQLiteStatement", sMethods, NELEM(sMethods));
147}
148
149} // namespace android
150