15a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori/* 25a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori * Copyright (C) 2006-2008 The Android Open Source Project 35a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori * 45a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori * Licensed under the Apache License, Version 2.0 (the "License"); 55a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori * you may not use this file except in compliance with the License. 65a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori * You may obtain a copy of the License at 75a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori * 85a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori * http://www.apache.org/licenses/LICENSE-2.0 95a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori * 105a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori * Unless required by applicable law or agreed to in writing, software 115a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori * distributed under the License is distributed on an "AS IS" BASIS, 125a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori * See the License for the specific language governing permissions and 145a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori * limitations under the License. 155a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori */ 165a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori 175a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori#undef LOG_TAG 185a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori#define LOG_TAG "Cursor" 195a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori 205a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori#include <jni.h> 215a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori#include <JNIHelp.h> 225a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori#include <android_runtime/AndroidRuntime.h> 235a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori 245a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori#include <sqlite3.h> 255a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori 265a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori#include <utils/Log.h> 275a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori 285a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori#include <stdio.h> 295a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori#include <string.h> 305a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori#include <unistd.h> 315a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori 325a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori#include "sqlite3_exception.h" 335a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori 345a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori 355a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Norinamespace android { 365a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori 375a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Noristatic jfieldID gHandleField; 385a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Noristatic jfieldID gStatementField; 395a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori 405a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori 415a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori#define GET_STATEMENT(env, object) \ 425a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori (sqlite3_stmt *)env->GetIntField(object, gStatementField) 435a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori#define GET_HANDLE(env, object) \ 445a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori (sqlite3 *)env->GetIntField(object, gHandleField) 455a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori 465a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori 475a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Norisqlite3_stmt * compile(JNIEnv* env, jobject object, 485a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori sqlite3 * handle, jstring sqlString) 495a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori{ 505a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori int err; 515a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori jchar const * sql; 525a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori jsize sqlLen; 535a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori sqlite3_stmt * statement = GET_STATEMENT(env, object); 545a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori 555a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori // Make sure not to leak the statement if it already exists 565a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori if (statement != NULL) { 575a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori sqlite3_finalize(statement); 585a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori env->SetIntField(object, gStatementField, 0); 595a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori } 605a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori 615a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori // Compile the SQL 625a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori sql = env->GetStringChars(sqlString, NULL); 635a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori sqlLen = env->GetStringLength(sqlString); 645a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori err = sqlite3_prepare16_v2(handle, sql, sqlLen * 2, &statement, NULL); 655a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori env->ReleaseStringChars(sqlString, sql); 665a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori 675a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori if (err == SQLITE_OK) { 685a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori // Store the statement in the Java object for future calls 695a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori LOGV("Prepared statement %p on %p", statement, handle); 705a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori env->SetIntField(object, gStatementField, (int)statement); 715a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori return statement; 725a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori } else { 735a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori // Error messages like 'near ")": syntax error' are not 745a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori // always helpful enough, so construct an error string that 755a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori // includes the query itself. 765a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori const char *query = env->GetStringUTFChars(sqlString, NULL); 775a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori char *message = (char*) malloc(strlen(query) + 50); 785a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori if (message) { 795a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori strcpy(message, ", while compiling: "); // less than 50 chars 805a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori strcat(message, query); 815a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori } 825a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori env->ReleaseStringUTFChars(sqlString, query); 835a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori throw_sqlite3_exception(env, handle, message); 845a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori free(message); 855a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori return NULL; 865a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori } 875a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori} 885a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori 895a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Noristatic void native_compile(JNIEnv* env, jobject object, jstring sqlString) 905a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori{ 915a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori compile(env, object, GET_HANDLE(env, object), sqlString); 925a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori} 935a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori 945a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori 955a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Noristatic JNINativeMethod sMethods[] = 965a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori{ 975a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori /* name, signature, funcPtr */ 985a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori {"native_compile", "(Ljava/lang/String;)V", (void *)native_compile}, 995a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori}; 1005a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori 1015a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Noriint register_android_database_SQLiteCompiledSql(JNIEnv * env) 1025a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori{ 1035a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori jclass clazz; 1045a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori 1055a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori clazz = env->FindClass("android/database/sqlite/SQLiteCompiledSql"); 1065a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori if (clazz == NULL) { 1075a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori LOGE("Can't find android/database/sqlite/SQLiteCompiledSql"); 1085a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori return -1; 1095a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori } 1105a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori 1115a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori gHandleField = env->GetFieldID(clazz, "nHandle", "I"); 1125a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori gStatementField = env->GetFieldID(clazz, "nStatement", "I"); 1135a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori 1145a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori if (gHandleField == NULL || gStatementField == NULL) { 1155a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori LOGE("Error locating fields"); 1165a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori return -1; 1175a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori } 1185a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori 1195a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori return AndroidRuntime::registerNativeMethods(env, 1205a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori "android/database/sqlite/SQLiteCompiledSql", sMethods, NELEM(sMethods)); 1215a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori} 1225a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori 1235a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori} // namespace android 124