Skip to content

Commit 88aeff7

Browse files
author
zhuoxu
committed
Refactor logic by code review
1 parent a7daf53 commit 88aeff7

1 file changed

Lines changed: 31 additions & 21 deletions

File tree

src/main/java/com/j256/ormlite/android/AndroidCompiledStatement.java

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.j256.ormlite.android;
22

3-
import java.lang.reflect.Array;
3+
import java.lang.reflect.InvocationTargetException;
44
import java.lang.reflect.Method;
55
import java.sql.SQLException;
66
import java.util.ArrayList;
@@ -33,6 +33,8 @@ public class AndroidCompiledStatement implements CompiledStatement {
3333
private static final String[] NO_STRING_ARGS = new String[0];
3434
private static final ApiCompatibility apiCompatibility = ApiCompatibilityUtils.getCompatibility();
3535

36+
private static Method hiddenExecSqlMethod;
37+
3638
private final String sql;
3739
private final SQLiteDatabase db;
3840
private final StatementType type;
@@ -44,6 +46,10 @@ public class AndroidCompiledStatement implements CompiledStatement {
4446
private Integer max;
4547
private CancellationHook cancellationHook;
4648

49+
static {
50+
hiddenExecSqlMethod = hiddenExecSqlMethod();
51+
}
52+
4753
public AndroidCompiledStatement(String sql, SQLiteDatabase db, StatementType type, boolean cancelQueriesEnabled,
4854
boolean cacheStore) {
4955
this.sql = sql;
@@ -215,17 +221,18 @@ public String toString() {
215221
* Execute some SQL on the database and return the number of rows changed.
216222
*/
217223
static int execSql(SQLiteDatabase db, String label, String finalSql, Object[] argArray) throws SQLException {
218-
int result = -1;
219224
try {
220-
result = exeSqlCompatibly(db, finalSql, argArray);
225+
Integer result = execSqlCompatibly(db, finalSql, argArray);
226+
// reflection sql method returns will >= 0, public API will return null
227+
if (result != null && result >= 0) {
228+
logger.trace("executing statement using reflection {} changed {} rows: {}", label, result, finalSql);
229+
return result;
230+
}
221231
} catch (android.database.SQLException e) {
222232
throw new SQLException("Problems executing " + label + " Android statement: " + finalSql, e);
223233
}
224234

225-
// reflected sql method returns will >= 0
226-
if (result >= 0) {
227-
return result;
228-
}
235+
int result;
229236

230237
SQLiteStatement stmt = null;
231238
try {
@@ -248,32 +255,35 @@ static int execSql(SQLiteDatabase db, String label, String finalSql, Object[] ar
248255
* Use reflection first, when reflection error, use origin method without return code
249256
* @return modified rows count
250257
*/
251-
private static int exeSqlCompatibly(SQLiteDatabase db, String sql, Object[] bindArgs) {
258+
private static Integer execSqlCompatibly(SQLiteDatabase db, String sql, Object[] bindArgs) {
252259
try {
253-
int result = invokeExecSqlMethod(db, sql, bindArgs);
254-
return result;
260+
return invokeHiddenExecSqlMethod(db, sql, bindArgs);
255261
} catch (android.database.SQLException e) {
262+
logger.trace(e, "reflection failed, call origin method, sql {}", sql);
256263
db.execSQL(sql, bindArgs);
257-
return -1;
264+
return null;
258265
}
259266
}
260267

261-
private static int invokeExecSqlMethod(SQLiteDatabase db, String sql, Object[] bindArgs) throws android.database.SQLException {
268+
private static int invokeHiddenExecSqlMethod(SQLiteDatabase db, String sql, Object[] bindArgs) throws android.database.SQLException {
262269
try {
263-
Object result = hiddenExecSqlMethod().invoke(db, sql, bindArgs);
264-
logger.trace("invokeExecSqlMethod result: {}", result);
265-
return (int) result;
266-
} catch (Exception e) {
267-
throw new android.database.SQLException("reflect error", e);
270+
if (hiddenExecSqlMethod != null) {
271+
Object result = hiddenExecSqlMethod.invoke(db, sql, bindArgs);
272+
logger.trace("invoke hidden execSql method result: {}", result);
273+
return (int) result;
274+
} else {
275+
throw new android.database.SQLException("reflection get method error");
276+
}
277+
} catch (InvocationTargetException | IllegalAccessException e) {
278+
// reflection cannot work, set method null, no need invoke anymore
279+
hiddenExecSqlMethod = null;
280+
throw new android.database.SQLException("reflection invoke error", e);
268281
}
269282
}
270283

271284
private static Method hiddenExecSqlMethod() {
272-
Class<SQLiteDatabase> clz = SQLiteDatabase.class;
273-
Class<?> objArrClass = Array.newInstance(Object.class, 0).getClass();
274285
try {
275-
Method executeSqlMethod = clz.getMethod("executeSql", String.class, objArrClass);
276-
return executeSqlMethod;
286+
return SQLiteDatabase.class.getMethod("executeSql", String.class, Object[].class);
277287
} catch (NoSuchMethodException e) {
278288
return null;
279289
}

0 commit comments

Comments
 (0)