From 42122bfecfc5efba843726f88ecc8e24adf3eabc Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Thu, 26 Jul 2018 09:39:18 -0600 Subject: [PATCH] Bind update() args as Object[] for performance. It's wasteful to convert them to String when SQLite already knows how to bind specific data types, including funky types like byte[]. Also promote to public API, since they're generally useful. Bug: 111085900 Test: atest packages/providers/DownloadProvider/tests/ Test: atest cts/tests/app/src/android/app/cts/DownloadManagerTest.java Test: atest cts/tests/tests/database/src/android/database/sqlite/cts/SQLiteQueryBuilderTest.java Change-Id: I5b418bca1204773fd2795156a2f47906ca1e1a6b --- api/current.txt | 2 ++ .../database/sqlite/SQLiteQueryBuilder.java | 23 +++++++++++-------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/api/current.txt b/api/current.txt index 9a47a66fd73eb..d6b6ad4e089e5 100644 --- a/api/current.txt +++ b/api/current.txt @@ -12677,6 +12677,7 @@ package android.database.sqlite { method public java.lang.String buildUnionQuery(java.lang.String[], java.lang.String, java.lang.String); method public java.lang.String buildUnionSubQuery(java.lang.String, java.lang.String[], java.util.Set, int, java.lang.String, java.lang.String, java.lang.String, java.lang.String); method public deprecated java.lang.String buildUnionSubQuery(java.lang.String, java.lang.String[], java.util.Set, int, java.lang.String, java.lang.String, java.lang.String[], java.lang.String, java.lang.String); + method public int delete(android.database.sqlite.SQLiteDatabase, java.lang.String, java.lang.String[]); method public java.lang.String getTables(); method public android.database.Cursor query(android.database.sqlite.SQLiteDatabase, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String); method public android.database.Cursor query(android.database.sqlite.SQLiteDatabase, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String); @@ -12686,6 +12687,7 @@ package android.database.sqlite { method public void setProjectionMap(java.util.Map); method public void setStrict(boolean); method public void setTables(java.lang.String); + method public int update(android.database.sqlite.SQLiteDatabase, android.content.ContentValues, java.lang.String, java.lang.String[]); } public class SQLiteReadOnlyDatabaseException extends android.database.sqlite.SQLiteException { diff --git a/core/java/android/database/sqlite/SQLiteQueryBuilder.java b/core/java/android/database/sqlite/SQLiteQueryBuilder.java index 2d45b14146fce..3298140b4a9b7 100644 --- a/core/java/android/database/sqlite/SQLiteQueryBuilder.java +++ b/core/java/android/database/sqlite/SQLiteQueryBuilder.java @@ -29,7 +29,7 @@ import android.text.TextUtils; import android.util.ArrayMap; import android.util.Log; -import com.android.internal.util.ArrayUtils; +import libcore.util.EmptyArray; import java.util.Arrays; import java.util.Iterator; @@ -436,7 +436,6 @@ public class SQLiteQueryBuilder * that they appear in the selection. The values will be bound * as Strings. * @return the number of rows updated - * @hide */ public int update(@NonNull SQLiteDatabase db, @NonNull ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) { @@ -471,14 +470,19 @@ public class SQLiteQueryBuilder sql = unwrappedSql; } - final ArrayMap rawValues = values.getValues(); - final String[] updateArgs = new String[rawValues.size()]; - for (int i = 0; i < updateArgs.length; i++) { - final Object arg = rawValues.valueAt(i); - updateArgs[i] = (arg != null) ? arg.toString() : null; + if (selectionArgs == null) { + selectionArgs = EmptyArray.STRING; + } + final ArrayMap rawValues = values.getValues(); + final int valuesLength = rawValues.size(); + final Object[] sqlArgs = new Object[valuesLength + selectionArgs.length]; + for (int i = 0; i < sqlArgs.length; i++) { + if (i < valuesLength) { + sqlArgs[i] = rawValues.valueAt(i); + } else { + sqlArgs[i] = selectionArgs[i - valuesLength]; + } } - - final String[] sqlArgs = ArrayUtils.concat(String.class, updateArgs, selectionArgs); if (Log.isLoggable(TAG, Log.DEBUG)) { if (Build.IS_DEBUGGABLE) { Log.d(TAG, sql + " with args " + Arrays.toString(sqlArgs)); @@ -502,7 +506,6 @@ public class SQLiteQueryBuilder * that they appear in the selection. The values will be bound * as Strings. * @return the number of rows deleted - * @hide */ public int delete(@NonNull SQLiteDatabase db, @Nullable String selection, @Nullable String[] selectionArgs) {