Loading core/java/android/database/sqlite/SQLiteConnection.java +28 −1 Original line number Diff line number Diff line Loading @@ -176,6 +176,8 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen private static native void nativeCancel(long connectionPtr); private static native void nativeResetCancel(long connectionPtr, boolean cancelable); private static native int nativeLastInsertRowId(long connectionPtr); private static native long nativeChanges(long connectionPtr); private static native long nativeTotalChanges(long connectionPtr); private SQLiteConnection(SQLiteConnectionPool pool, SQLiteDatabaseConfiguration configuration, Loading Loading @@ -1823,11 +1825,36 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen * @return The ROWID of the last row to be inserted under this connection. * @hide */ long lastInsertRowId() { long getLastInsertRowId() { try { return nativeLastInsertRowId(mConnectionPtr); } finally { Reference.reachabilityFence(this); } } /** * Return the number of database changes on the current connection made by the last SQL * statement * @hide */ long getLastChangedRowsCount() { try { return nativeChanges(mConnectionPtr); } finally { Reference.reachabilityFence(this); } } /** * Return the total number of database changes made on the current connection. * @hide */ long getTotalChangedRowsCount() { try { return nativeTotalChanges(mConnectionPtr); } finally { Reference.reachabilityFence(this); } } } core/java/android/database/sqlite/SQLiteDatabase.java +43 −1 Original line number Diff line number Diff line Loading @@ -2197,7 +2197,49 @@ public final class SQLiteDatabase extends SQLiteClosable { * @throws IllegalStateException if there is no current transaction. */ public long getLastInsertRowId() { return getThreadSession().lastInsertRowId(); return getThreadSession().getLastInsertRowId(); } /** * Return the number of database rows that were inserted, updated, or deleted by the most recent * SQL statement within the current transaction. * * @see <a href="https://sqlite.org/c3ref/changes.html">sqlite3_changes64</a> * * @return The number of rows changed by the most recent sql statement * @throws IllegalStateException if there is no current transaction. * @hide */ public long getLastChangedRowsCount() { return getThreadSession().getLastChangedRowsCount(); } /** * Return the total number of database rows that have been inserted, updated, or deleted on * the current connection since it was created. Due to Android's internal management of * SQLite connections, the value may, or may not, include changes made in earlier * transactions. Best practice is to compare values returned within a single transaction. * * <code><pre> * database.beginTransaction(); * try { * long initialValue = database.getTotalChangedRowsCount(); * // Execute SQL statements * long changedRows = database.getTotalChangedRowsCount() - initialValue; * // changedRows counts the total number of rows updated in the transaction. * } finally { * database.endTransaction(); * } * </pre></code> * * @see <a href="https://sqlite.org/c3ref/changes.html">sqlite3_total_changes64</a> * * @return The number of rows changed on the current connection. * @throws IllegalStateException if there is no current transaction. * @hide */ public long getTotalChangedRowsCount() { return getThreadSession().getTotalChangedRowsCount(); } /** Loading core/java/android/database/sqlite/SQLiteSession.java +22 −2 Original line number Diff line number Diff line Loading @@ -988,9 +988,29 @@ public final class SQLiteSession { * necessary to acquire and release the connection: the connection has already been acquired. * @hide */ long lastInsertRowId() { long getLastInsertRowId() { throwIfNoTransaction(); return mConnection.lastInsertRowId(); return mConnection.getLastInsertRowId(); } /** * Return the number of database rows that were changed by the most recent SQL statement on * this connection. * @hide */ long getLastChangedRowsCount() { throwIfNoTransaction(); return mConnection.getLastChangedRowsCount(); } /** * Return the total number of database rows that were changed on the current connection, since * it was created. * @hide */ long getTotalChangedRowsCount() { throwIfNoTransaction(); return mConnection.getTotalChangedRowsCount(); } /** Loading core/jni/android_database_SQLiteConnection.cpp +13 −1 Original line number Diff line number Diff line Loading @@ -885,6 +885,16 @@ static jint nativeLastInsertRowId(JNIEnv* env, jclass, jlong connectionPtr) { return sqlite3_last_insert_rowid(connection->db); } static jlong nativeChanges(JNIEnv* env, jclass, jlong connectionPtr) { SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr); return sqlite3_changes64(connection->db); } static jlong nativeTotalChanges(JNIEnv* env, jclass, jlong connectionPtr) { SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr); return sqlite3_total_changes64(connection->db); } static const JNINativeMethod sMethods[] = { /* name, signature, funcPtr */ Loading Loading @@ -943,7 +953,9 @@ static const JNINativeMethod sMethods[] = { "nativeResetCancel", "(JZ)V", (void*)nativeResetCancel }, { "nativeLastInsertRowId", "(J)I", (void*) nativeLastInsertRowId } { "nativeLastInsertRowId", "(J)I", (void*) nativeLastInsertRowId }, { "nativeChanges", "(J)J", (void*) nativeChanges }, { "nativeTotalChanges", "(J)J", (void*) nativeTotalChanges }, }; int register_android_database_SQLiteConnection(JNIEnv *env) Loading core/tests/coretests/src/android/database/sqlite/SQLiteDatabaseTest.java +77 −0 Original line number Diff line number Diff line Loading @@ -137,4 +137,81 @@ public class SQLiteDatabaseTest { fail("Timed out"); } } /** * Create a database with one table with three columns. */ private void createComplexDatabase() { mDatabase.beginTransaction(); try { mDatabase.execSQL("CREATE TABLE t1 (i int, d double, t text);"); mDatabase.setTransactionSuccessful(); } finally { mDatabase.endTransaction(); } } /** * A three-value insert for the complex database. */ private String createComplexInsert() { return "INSERT INTO t1 (i, d, t) VALUES (?1, ?2, ?3)"; } @Test public void testAutomaticCounters() { final int size = 10; createComplexDatabase(); // Put 10 lines in the database. mDatabase.beginTransaction(); try { try (SQLiteRawStatement s = mDatabase.createRawStatement(createComplexInsert())) { for (int i = 0; i < size; i++) { int vi = i * 3; double vd = i * 2.5; String vt = String.format("text%02dvalue", i); s.bindInt(1, vi); s.bindDouble(2, vd); s.bindText(3, vt); boolean r = s.step(); // No row is returned by this query. assertFalse(r); s.reset(); assertEquals(i + 1, mDatabase.getLastInsertRowId()); assertEquals(1, mDatabase.getLastChangedRowsCount()); assertEquals(i + 2, mDatabase.getTotalChangedRowsCount()); } } mDatabase.setTransactionSuccessful(); } finally { mDatabase.endTransaction(); } // Put a second 10 lines in the database. mDatabase.beginTransaction(); try { try (SQLiteRawStatement s = mDatabase.createRawStatement(createComplexInsert())) { for (int i = 0; i < size; i++) { int vi = i * 3; double vd = i * 2.5; String vt = String.format("text%02dvalue", i); s.bindInt(1, vi); s.bindDouble(2, vd); s.bindText(3, vt); boolean r = s.step(); // No row is returned by this query. assertFalse(r); s.reset(); assertEquals(size + i + 1, mDatabase.getLastInsertRowId()); assertEquals(1, mDatabase.getLastChangedRowsCount()); assertEquals(size + i + 2, mDatabase.getTotalChangedRowsCount()); } } mDatabase.setTransactionSuccessful(); } finally { mDatabase.endTransaction(); } } } Loading
core/java/android/database/sqlite/SQLiteConnection.java +28 −1 Original line number Diff line number Diff line Loading @@ -176,6 +176,8 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen private static native void nativeCancel(long connectionPtr); private static native void nativeResetCancel(long connectionPtr, boolean cancelable); private static native int nativeLastInsertRowId(long connectionPtr); private static native long nativeChanges(long connectionPtr); private static native long nativeTotalChanges(long connectionPtr); private SQLiteConnection(SQLiteConnectionPool pool, SQLiteDatabaseConfiguration configuration, Loading Loading @@ -1823,11 +1825,36 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen * @return The ROWID of the last row to be inserted under this connection. * @hide */ long lastInsertRowId() { long getLastInsertRowId() { try { return nativeLastInsertRowId(mConnectionPtr); } finally { Reference.reachabilityFence(this); } } /** * Return the number of database changes on the current connection made by the last SQL * statement * @hide */ long getLastChangedRowsCount() { try { return nativeChanges(mConnectionPtr); } finally { Reference.reachabilityFence(this); } } /** * Return the total number of database changes made on the current connection. * @hide */ long getTotalChangedRowsCount() { try { return nativeTotalChanges(mConnectionPtr); } finally { Reference.reachabilityFence(this); } } }
core/java/android/database/sqlite/SQLiteDatabase.java +43 −1 Original line number Diff line number Diff line Loading @@ -2197,7 +2197,49 @@ public final class SQLiteDatabase extends SQLiteClosable { * @throws IllegalStateException if there is no current transaction. */ public long getLastInsertRowId() { return getThreadSession().lastInsertRowId(); return getThreadSession().getLastInsertRowId(); } /** * Return the number of database rows that were inserted, updated, or deleted by the most recent * SQL statement within the current transaction. * * @see <a href="https://sqlite.org/c3ref/changes.html">sqlite3_changes64</a> * * @return The number of rows changed by the most recent sql statement * @throws IllegalStateException if there is no current transaction. * @hide */ public long getLastChangedRowsCount() { return getThreadSession().getLastChangedRowsCount(); } /** * Return the total number of database rows that have been inserted, updated, or deleted on * the current connection since it was created. Due to Android's internal management of * SQLite connections, the value may, or may not, include changes made in earlier * transactions. Best practice is to compare values returned within a single transaction. * * <code><pre> * database.beginTransaction(); * try { * long initialValue = database.getTotalChangedRowsCount(); * // Execute SQL statements * long changedRows = database.getTotalChangedRowsCount() - initialValue; * // changedRows counts the total number of rows updated in the transaction. * } finally { * database.endTransaction(); * } * </pre></code> * * @see <a href="https://sqlite.org/c3ref/changes.html">sqlite3_total_changes64</a> * * @return The number of rows changed on the current connection. * @throws IllegalStateException if there is no current transaction. * @hide */ public long getTotalChangedRowsCount() { return getThreadSession().getTotalChangedRowsCount(); } /** Loading
core/java/android/database/sqlite/SQLiteSession.java +22 −2 Original line number Diff line number Diff line Loading @@ -988,9 +988,29 @@ public final class SQLiteSession { * necessary to acquire and release the connection: the connection has already been acquired. * @hide */ long lastInsertRowId() { long getLastInsertRowId() { throwIfNoTransaction(); return mConnection.lastInsertRowId(); return mConnection.getLastInsertRowId(); } /** * Return the number of database rows that were changed by the most recent SQL statement on * this connection. * @hide */ long getLastChangedRowsCount() { throwIfNoTransaction(); return mConnection.getLastChangedRowsCount(); } /** * Return the total number of database rows that were changed on the current connection, since * it was created. * @hide */ long getTotalChangedRowsCount() { throwIfNoTransaction(); return mConnection.getTotalChangedRowsCount(); } /** Loading
core/jni/android_database_SQLiteConnection.cpp +13 −1 Original line number Diff line number Diff line Loading @@ -885,6 +885,16 @@ static jint nativeLastInsertRowId(JNIEnv* env, jclass, jlong connectionPtr) { return sqlite3_last_insert_rowid(connection->db); } static jlong nativeChanges(JNIEnv* env, jclass, jlong connectionPtr) { SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr); return sqlite3_changes64(connection->db); } static jlong nativeTotalChanges(JNIEnv* env, jclass, jlong connectionPtr) { SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr); return sqlite3_total_changes64(connection->db); } static const JNINativeMethod sMethods[] = { /* name, signature, funcPtr */ Loading Loading @@ -943,7 +953,9 @@ static const JNINativeMethod sMethods[] = { "nativeResetCancel", "(JZ)V", (void*)nativeResetCancel }, { "nativeLastInsertRowId", "(J)I", (void*) nativeLastInsertRowId } { "nativeLastInsertRowId", "(J)I", (void*) nativeLastInsertRowId }, { "nativeChanges", "(J)J", (void*) nativeChanges }, { "nativeTotalChanges", "(J)J", (void*) nativeTotalChanges }, }; int register_android_database_SQLiteConnection(JNIEnv *env) Loading
core/tests/coretests/src/android/database/sqlite/SQLiteDatabaseTest.java +77 −0 Original line number Diff line number Diff line Loading @@ -137,4 +137,81 @@ public class SQLiteDatabaseTest { fail("Timed out"); } } /** * Create a database with one table with three columns. */ private void createComplexDatabase() { mDatabase.beginTransaction(); try { mDatabase.execSQL("CREATE TABLE t1 (i int, d double, t text);"); mDatabase.setTransactionSuccessful(); } finally { mDatabase.endTransaction(); } } /** * A three-value insert for the complex database. */ private String createComplexInsert() { return "INSERT INTO t1 (i, d, t) VALUES (?1, ?2, ?3)"; } @Test public void testAutomaticCounters() { final int size = 10; createComplexDatabase(); // Put 10 lines in the database. mDatabase.beginTransaction(); try { try (SQLiteRawStatement s = mDatabase.createRawStatement(createComplexInsert())) { for (int i = 0; i < size; i++) { int vi = i * 3; double vd = i * 2.5; String vt = String.format("text%02dvalue", i); s.bindInt(1, vi); s.bindDouble(2, vd); s.bindText(3, vt); boolean r = s.step(); // No row is returned by this query. assertFalse(r); s.reset(); assertEquals(i + 1, mDatabase.getLastInsertRowId()); assertEquals(1, mDatabase.getLastChangedRowsCount()); assertEquals(i + 2, mDatabase.getTotalChangedRowsCount()); } } mDatabase.setTransactionSuccessful(); } finally { mDatabase.endTransaction(); } // Put a second 10 lines in the database. mDatabase.beginTransaction(); try { try (SQLiteRawStatement s = mDatabase.createRawStatement(createComplexInsert())) { for (int i = 0; i < size; i++) { int vi = i * 3; double vd = i * 2.5; String vt = String.format("text%02dvalue", i); s.bindInt(1, vi); s.bindDouble(2, vd); s.bindText(3, vt); boolean r = s.step(); // No row is returned by this query. assertFalse(r); s.reset(); assertEquals(size + i + 1, mDatabase.getLastInsertRowId()); assertEquals(1, mDatabase.getLastChangedRowsCount()); assertEquals(size + i + 2, mDatabase.getTotalChangedRowsCount()); } } mDatabase.setTransactionSuccessful(); } finally { mDatabase.endTransaction(); } } }