Merge "Allow PRAGMA statements that change and return a result in executeNonQuery()"

This commit is contained in:
TreeHugger Robot
2021-09-07 20:18:13 +00:00
committed by Android (Google) Code Review
2 changed files with 22 additions and 13 deletions

View File

@@ -153,7 +153,8 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
int index, byte[] value);
private static native void nativeResetStatementAndClearBindings(
long connectionPtr, long statementPtr);
private static native void nativeExecute(long connectionPtr, long statementPtr);
private static native void nativeExecute(long connectionPtr, long statementPtr,
boolean isPragmaStmt);
private static native long nativeExecuteForLong(long connectionPtr, long statementPtr);
private static native String nativeExecuteForString(long connectionPtr, long statementPtr);
private static native int nativeExecuteForBlobFileDescriptor(
@@ -699,6 +700,8 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
final int cookie = mRecentOperations.beginOperation("execute", sql, bindArgs);
try {
final boolean isPragmaStmt =
DatabaseUtils.getSqlStatementType(sql) == DatabaseUtils.STATEMENT_PRAGMA;
final PreparedStatement statement = acquirePreparedStatement(sql);
try {
throwIfStatementForbidden(statement);
@@ -706,7 +709,7 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
applyBlockGuardPolicy(statement);
attachCancellationSignal(cancellationSignal);
try {
nativeExecute(mConnectionPtr, statement.mStatementPtr);
nativeExecute(mConnectionPtr, statement.mStatementPtr, isPragmaStmt);
} finally {
detachCancellationSignal(cancellationSignal);
}

View File

@@ -518,23 +518,29 @@ static void nativeResetStatementAndClearBindings(JNIEnv* env, jclass clazz, jlon
}
}
static int executeNonQuery(JNIEnv* env, SQLiteConnection* connection, sqlite3_stmt* statement) {
int err = sqlite3_step(statement);
if (err == SQLITE_ROW) {
static int executeNonQuery(JNIEnv* env, SQLiteConnection* connection, sqlite3_stmt* statement,
bool isPragmaStmt) {
int rc = sqlite3_step(statement);
if (isPragmaStmt) {
while (rc == SQLITE_ROW) {
rc = sqlite3_step(statement);
}
}
if (rc == SQLITE_ROW) {
throw_sqlite3_exception(env,
"Queries can be performed using SQLiteDatabase query or rawQuery methods only.");
} else if (err != SQLITE_DONE) {
} else if (rc != SQLITE_DONE) {
throw_sqlite3_exception(env, connection->db);
}
return err;
return rc;
}
static void nativeExecute(JNIEnv* env, jclass clazz, jlong connectionPtr,
jlong statementPtr) {
static void nativeExecute(JNIEnv* env, jclass clazz, jlong connectionPtr, jlong statementPtr,
jboolean isPragmaStmt) {
SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
executeNonQuery(env, connection, statement);
executeNonQuery(env, connection, statement, isPragmaStmt);
}
static jint nativeExecuteForChangedRowCount(JNIEnv* env, jclass clazz,
@@ -542,7 +548,7 @@ static jint nativeExecuteForChangedRowCount(JNIEnv* env, jclass clazz,
SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
int err = executeNonQuery(env, connection, statement);
int err = executeNonQuery(env, connection, statement, false);
return err == SQLITE_DONE ? sqlite3_changes(connection->db) : -1;
}
@@ -551,7 +557,7 @@ static jlong nativeExecuteForLastInsertedRowId(JNIEnv* env, jclass clazz,
SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
int err = executeNonQuery(env, connection, statement);
int err = executeNonQuery(env, connection, statement, false);
return err == SQLITE_DONE && sqlite3_changes(connection->db) > 0
? sqlite3_last_insert_rowid(connection->db) : -1;
}
@@ -912,7 +918,7 @@ static const JNINativeMethod sMethods[] =
(void*)nativeBindBlob },
{ "nativeResetStatementAndClearBindings", "(JJ)V",
(void*)nativeResetStatementAndClearBindings },
{ "nativeExecute", "(JJ)V",
{ "nativeExecute", "(JJZ)V",
(void*)nativeExecute },
{ "nativeExecuteForLong", "(JJ)J",
(void*)nativeExecuteForLong },