diff options
-rw-r--r-- | api/current.txt | 12 | ||||
-rw-r--r-- | core/java/android/database/Cursor.java | 4 | ||||
-rw-r--r-- | core/java/android/database/CursorWindow.java | 17 | ||||
-rw-r--r-- | core/java/android/database/DatabaseUtils.java | 97 | ||||
-rw-r--r-- | core/java/android/database/sqlite/SQLiteClosable.java | 55 | ||||
-rw-r--r-- | core/java/android/database/sqlite/SQLiteConnection.java | 65 | ||||
-rw-r--r-- | core/java/android/database/sqlite/SQLiteDatabase.java | 354 | ||||
-rw-r--r-- | core/java/android/database/sqlite/SQLiteProgram.java | 7 |
8 files changed, 355 insertions, 256 deletions
diff --git a/api/current.txt b/api/current.txt index c9be4cd..a4b9f97 100644 --- a/api/current.txt +++ b/api/current.txt @@ -6904,7 +6904,7 @@ package android.database { method public boolean onMove(int, int); } - public abstract interface Cursor { + public abstract interface Cursor implements java.io.Closeable { method public abstract void close(); method public abstract void copyStringToBuffer(int, android.database.CharArrayBuffer); method public abstract deprecated void deactivate(); @@ -6977,7 +6977,6 @@ package android.database { ctor public deprecated CursorWindow(boolean); method public boolean allocRow(); method public void clear(); - method public void close(); method public void copyStringToBuffer(int, int, android.database.CharArrayBuffer); method public int describeContents(); method public void freeLastRow(); @@ -7236,13 +7235,14 @@ package android.database.sqlite { ctor public SQLiteCantOpenDatabaseException(java.lang.String); } - public abstract class SQLiteClosable { + public abstract class SQLiteClosable implements java.io.Closeable { ctor public SQLiteClosable(); method public void acquireReference(); + method public void close(); method protected abstract void onAllReferencesReleased(); - method protected void onAllReferencesReleasedFromContainer(); + method protected deprecated void onAllReferencesReleasedFromContainer(); method public void releaseReference(); - method public void releaseReferenceFromContainer(); + method public deprecated void releaseReferenceFromContainer(); } public class SQLiteConstraintException extends android.database.sqlite.SQLiteException { @@ -7272,7 +7272,6 @@ package android.database.sqlite { method public void beginTransactionNonExclusive(); method public void beginTransactionWithListener(android.database.sqlite.SQLiteTransactionListener); method public void beginTransactionWithListenerNonExclusive(android.database.sqlite.SQLiteTransactionListener); - method public void close(); method public android.database.sqlite.SQLiteStatement compileStatement(java.lang.String) throws android.database.SQLException; method public static android.database.sqlite.SQLiteDatabase create(android.database.sqlite.SQLiteDatabase.CursorFactory); method public int delete(java.lang.String, java.lang.String, java.lang.String[]); @@ -7415,7 +7414,6 @@ package android.database.sqlite { method public void bindNull(int); method public void bindString(int, java.lang.String); method public void clearBindings(); - method public void close(); method public final deprecated int getUniqueId(); method protected void onAllReferencesReleased(); } diff --git a/core/java/android/database/Cursor.java b/core/java/android/database/Cursor.java index 59ec89d..907833d 100644 --- a/core/java/android/database/Cursor.java +++ b/core/java/android/database/Cursor.java @@ -20,6 +20,8 @@ import android.content.ContentResolver; import android.net.Uri; import android.os.Bundle; +import java.io.Closeable; + /** * This interface provides random read-write access to the result set returned * by a database query. @@ -27,7 +29,7 @@ import android.os.Bundle; * Cursor implementations are not required to be synchronized so code using a Cursor from multiple * threads should perform its own synchronization when using the Cursor. */ -public interface Cursor { +public interface Cursor extends Closeable { /* * Values returned by {@link #getType(int)}. * These should be consistent with the corresponding types defined in CursorWindow.h diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java index 85f570c..f1f3017 100644 --- a/core/java/android/database/CursorWindow.java +++ b/core/java/android/database/CursorWindow.java @@ -169,14 +169,6 @@ public class CursorWindow extends SQLiteClosable implements Parcelable { } /** - * Closes the cursor window and frees its underlying resources when all other - * remaining references have been released. - */ - public void close() { - releaseReference(); - } - - /** * Clears out the existing contents of the window, making it safe to reuse * for new data. * <p> @@ -703,8 +695,13 @@ public class CursorWindow extends SQLiteClosable implements Parcelable { } public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(mStartPos); - nativeWriteToParcel(mWindowPtr, dest); + acquireReference(); + try { + dest.writeInt(mStartPos); + nativeWriteToParcel(mWindowPtr, dest); + } finally { + releaseReference(); + } if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) { releaseReference(); diff --git a/core/java/android/database/DatabaseUtils.java b/core/java/android/database/DatabaseUtils.java index 0022118..99d260e 100644 --- a/core/java/android/database/DatabaseUtils.java +++ b/core/java/android/database/DatabaseUtils.java @@ -269,63 +269,56 @@ public class DatabaseUtils { if (position < 0 || position >= cursor.getCount()) { return; } - window.acquireReference(); - try { - final int oldPos = cursor.getPosition(); - final int numColumns = cursor.getColumnCount(); - window.clear(); - window.setStartPosition(position); - window.setNumColumns(numColumns); - if (cursor.moveToPosition(position)) { - do { - if (!window.allocRow()) { - break; - } - for (int i = 0; i < numColumns; i++) { - final int type = cursor.getType(i); - final boolean success; - switch (type) { - case Cursor.FIELD_TYPE_NULL: - success = window.putNull(position, i); - break; - - case Cursor.FIELD_TYPE_INTEGER: - success = window.putLong(cursor.getLong(i), position, i); - break; - - case Cursor.FIELD_TYPE_FLOAT: - success = window.putDouble(cursor.getDouble(i), position, i); - break; - - case Cursor.FIELD_TYPE_BLOB: { - final byte[] value = cursor.getBlob(i); - success = value != null ? window.putBlob(value, position, i) - : window.putNull(position, i); - break; - } - - default: // assume value is convertible to String - case Cursor.FIELD_TYPE_STRING: { - final String value = cursor.getString(i); - success = value != null ? window.putString(value, position, i) - : window.putNull(position, i); - break; - } + final int oldPos = cursor.getPosition(); + final int numColumns = cursor.getColumnCount(); + window.clear(); + window.setStartPosition(position); + window.setNumColumns(numColumns); + if (cursor.moveToPosition(position)) { + do { + if (!window.allocRow()) { + break; + } + for (int i = 0; i < numColumns; i++) { + final int type = cursor.getType(i); + final boolean success; + switch (type) { + case Cursor.FIELD_TYPE_NULL: + success = window.putNull(position, i); + break; + + case Cursor.FIELD_TYPE_INTEGER: + success = window.putLong(cursor.getLong(i), position, i); + break; + + case Cursor.FIELD_TYPE_FLOAT: + success = window.putDouble(cursor.getDouble(i), position, i); + break; + + case Cursor.FIELD_TYPE_BLOB: { + final byte[] value = cursor.getBlob(i); + success = value != null ? window.putBlob(value, position, i) + : window.putNull(position, i); + break; } - if (!success) { - window.freeLastRow(); + + default: // assume value is convertible to String + case Cursor.FIELD_TYPE_STRING: { + final String value = cursor.getString(i); + success = value != null ? window.putString(value, position, i) + : window.putNull(position, i); break; } } - position += 1; - } while (cursor.moveToNext()); - } - cursor.moveToPosition(oldPos); - } catch (IllegalStateException e){ - // simply ignore it - } finally { - window.releaseReference(); + if (!success) { + window.freeLastRow(); + break; + } + } + position += 1; + } while (cursor.moveToNext()); } + cursor.moveToPosition(oldPos); } /** diff --git a/core/java/android/database/sqlite/SQLiteClosable.java b/core/java/android/database/sqlite/SQLiteClosable.java index 7e91a7b..adfbc6e 100644 --- a/core/java/android/database/sqlite/SQLiteClosable.java +++ b/core/java/android/database/sqlite/SQLiteClosable.java @@ -16,15 +16,39 @@ package android.database.sqlite; +import java.io.Closeable; + /** * An object created from a SQLiteDatabase that can be closed. + * + * This class implements a primitive reference counting scheme for database objects. */ -public abstract class SQLiteClosable { +public abstract class SQLiteClosable implements Closeable { private int mReferenceCount = 1; + /** + * Called when the last reference to the object was released by + * a call to {@link #releaseReference()} or {@link #close()}. + */ protected abstract void onAllReferencesReleased(); - protected void onAllReferencesReleasedFromContainer() {} + /** + * Called when the last reference to the object was released by + * a call to {@link #releaseReferenceFromContainer()}. + * + * @deprecated Do not use. + */ + @Deprecated + protected void onAllReferencesReleasedFromContainer() { + onAllReferencesReleased(); + } + + /** + * Acquires a reference to the object. + * + * @throws IllegalStateException if the last reference to the object has already + * been released. + */ public void acquireReference() { synchronized(this) { if (mReferenceCount <= 0) { @@ -35,6 +59,12 @@ public abstract class SQLiteClosable { } } + /** + * Releases a reference to the object, closing the object if the last reference + * was released. + * + * @see #onAllReferencesReleased() + */ public void releaseReference() { boolean refCountIsZero = false; synchronized(this) { @@ -45,6 +75,14 @@ public abstract class SQLiteClosable { } } + /** + * Releases a reference to the object that was owned by the container of the object, + * closing the object if the last reference was released. + * + * @see #onAllReferencesReleasedFromContainer() + * @deprecated Do not use. + */ + @Deprecated public void releaseReferenceFromContainer() { boolean refCountIsZero = false; synchronized(this) { @@ -54,4 +92,17 @@ public abstract class SQLiteClosable { onAllReferencesReleasedFromContainer(); } } + + /** + * Releases a reference to the object, closing the object if the last reference + * was released. + * + * Calling this method is equivalent to calling {@link #releaseReference}. + * + * @see #releaseReference() + * @see #onAllReferencesReleased() + */ + public void close() { + releaseReference(); + } } diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java index d16f29f..0db3e4f 100644 --- a/core/java/android/database/sqlite/SQLiteConnection.java +++ b/core/java/android/database/sqlite/SQLiteConnection.java @@ -704,44 +704,49 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen throw new IllegalArgumentException("window must not be null."); } - int actualPos = -1; - int countedRows = -1; - int filledRows = -1; - final int cookie = mRecentOperations.beginOperation("executeForCursorWindow", - sql, bindArgs); + window.acquireReference(); try { - final PreparedStatement statement = acquirePreparedStatement(sql); + int actualPos = -1; + int countedRows = -1; + int filledRows = -1; + final int cookie = mRecentOperations.beginOperation("executeForCursorWindow", + sql, bindArgs); try { - throwIfStatementForbidden(statement); - bindArguments(statement, bindArgs); - applyBlockGuardPolicy(statement); - attachCancellationSignal(cancellationSignal); + final PreparedStatement statement = acquirePreparedStatement(sql); try { - final long result = nativeExecuteForCursorWindow( - mConnectionPtr, statement.mStatementPtr, window.mWindowPtr, - startPos, requiredPos, countAllRows); - actualPos = (int)(result >> 32); - countedRows = (int)result; - filledRows = window.getNumRows(); - window.setStartPosition(actualPos); - return countedRows; + throwIfStatementForbidden(statement); + bindArguments(statement, bindArgs); + applyBlockGuardPolicy(statement); + attachCancellationSignal(cancellationSignal); + try { + final long result = nativeExecuteForCursorWindow( + mConnectionPtr, statement.mStatementPtr, window.mWindowPtr, + startPos, requiredPos, countAllRows); + actualPos = (int)(result >> 32); + countedRows = (int)result; + filledRows = window.getNumRows(); + window.setStartPosition(actualPos); + return countedRows; + } finally { + detachCancellationSignal(cancellationSignal); + } } finally { - detachCancellationSignal(cancellationSignal); + releasePreparedStatement(statement); } + } catch (RuntimeException ex) { + mRecentOperations.failOperation(cookie, ex); + throw ex; } finally { - releasePreparedStatement(statement); + if (mRecentOperations.endOperationDeferLog(cookie)) { + mRecentOperations.logOperation(cookie, "window='" + window + + "', startPos=" + startPos + + ", actualPos=" + actualPos + + ", filledRows=" + filledRows + + ", countedRows=" + countedRows); + } } - } catch (RuntimeException ex) { - mRecentOperations.failOperation(cookie, ex); - throw ex; } finally { - if (mRecentOperations.endOperationDeferLog(cookie)) { - mRecentOperations.logOperation(cookie, "window='" + window - + "', startPos=" + startPos - + ", actualPos=" + actualPos - + ", filledRows=" + filledRows - + ", countedRows=" + countedRows); - } + window.releaseReference(); } } diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java index 604247e..d41b484 100644 --- a/core/java/android/database/sqlite/SQLiteDatabase.java +++ b/core/java/android/database/sqlite/SQLiteDatabase.java @@ -492,9 +492,16 @@ public final class SQLiteDatabase extends SQLiteClosable { private void beginTransaction(SQLiteTransactionListener transactionListener, boolean exclusive) { - getThreadSession().beginTransaction(exclusive ? SQLiteSession.TRANSACTION_MODE_EXCLUSIVE : - SQLiteSession.TRANSACTION_MODE_IMMEDIATE, transactionListener, - getThreadDefaultConnectionFlags(false /*readOnly*/), null); + acquireReference(); + try { + getThreadSession().beginTransaction( + exclusive ? SQLiteSession.TRANSACTION_MODE_EXCLUSIVE : + SQLiteSession.TRANSACTION_MODE_IMMEDIATE, + transactionListener, + getThreadDefaultConnectionFlags(false /*readOnly*/), null); + } finally { + releaseReference(); + } } /** @@ -502,7 +509,12 @@ public final class SQLiteDatabase extends SQLiteClosable { * are committed and rolled back. */ public void endTransaction() { - getThreadSession().endTransaction(null); + acquireReference(); + try { + getThreadSession().endTransaction(null); + } finally { + releaseReference(); + } } /** @@ -515,7 +527,12 @@ public final class SQLiteDatabase extends SQLiteClosable { * transaction is already marked as successful. */ public void setTransactionSuccessful() { - getThreadSession().setTransactionSuccessful(); + acquireReference(); + try { + getThreadSession().setTransactionSuccessful(); + } finally { + releaseReference(); + } } /** @@ -524,7 +541,12 @@ public final class SQLiteDatabase extends SQLiteClosable { * @return True if the current thread is in a transaction. */ public boolean inTransaction() { - return getThreadSession().hasTransaction(); + acquireReference(); + try { + return getThreadSession().hasTransaction(); + } finally { + releaseReference(); + } } /** @@ -540,7 +562,12 @@ public final class SQLiteDatabase extends SQLiteClosable { * @return True if the current thread is holding an active connection to the database. */ public boolean isDbLockedByCurrentThread() { - return getThreadSession().hasConnection(); + acquireReference(); + try { + return getThreadSession().hasConnection(); + } finally { + releaseReference(); + } } /** @@ -599,7 +626,12 @@ public final class SQLiteDatabase extends SQLiteClosable { } private boolean yieldIfContendedHelper(boolean throwIfUnsafe, long sleepAfterYieldDelay) { - return getThreadSession().yieldTransaction(sleepAfterYieldDelay, throwIfUnsafe, null); + acquireReference(); + try { + return getThreadSession().yieldTransaction(sleepAfterYieldDelay, throwIfUnsafe, null); + } finally { + releaseReference(); + } } /** @@ -788,13 +820,6 @@ public final class SQLiteDatabase extends SQLiteClosable { } /** - * Close the database. - */ - public void close() { - dispose(false); - } - - /** * Registers a CustomFunction callback as a function that can be called from * SQLite database triggers. * @@ -948,8 +973,12 @@ public final class SQLiteDatabase extends SQLiteClosable { * {@link SQLiteStatement}s are not synchronized, see the documentation for more details. */ public SQLiteStatement compileStatement(String sql) throws SQLException { - throwIfNotOpen(); // fail fast - return new SQLiteStatement(this, sql, null); + acquireReference(); + try { + return new SQLiteStatement(this, sql, null); + } finally { + releaseReference(); + } } /** @@ -1110,12 +1139,16 @@ public final class SQLiteDatabase extends SQLiteClosable { boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit, CancellationSignal cancellationSignal) { - throwIfNotOpen(); // fail fast - String sql = SQLiteQueryBuilder.buildQueryString( - distinct, table, columns, selection, groupBy, having, orderBy, limit); + acquireReference(); + try { + String sql = SQLiteQueryBuilder.buildQueryString( + distinct, table, columns, selection, groupBy, having, orderBy, limit); - return rawQueryWithFactory(cursorFactory, sql, selectionArgs, - findEditTable(table), cancellationSignal); + return rawQueryWithFactory(cursorFactory, sql, selectionArgs, + findEditTable(table), cancellationSignal); + } finally { + releaseReference(); + } } /** @@ -1260,12 +1293,15 @@ public final class SQLiteDatabase extends SQLiteClosable { public Cursor rawQueryWithFactory( CursorFactory cursorFactory, String sql, String[] selectionArgs, String editTable, CancellationSignal cancellationSignal) { - throwIfNotOpen(); // fail fast - - SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(this, sql, editTable, - cancellationSignal); - return driver.query(cursorFactory != null ? cursorFactory : mCursorFactory, - selectionArgs); + acquireReference(); + try { + SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(this, sql, editTable, + cancellationSignal); + return driver.query(cursorFactory != null ? cursorFactory : mCursorFactory, + selectionArgs); + } finally { + releaseReference(); + } } /** @@ -1384,38 +1420,44 @@ public final class SQLiteDatabase extends SQLiteClosable { */ public long insertWithOnConflict(String table, String nullColumnHack, ContentValues initialValues, int conflictAlgorithm) { - StringBuilder sql = new StringBuilder(); - sql.append("INSERT"); - sql.append(CONFLICT_VALUES[conflictAlgorithm]); - sql.append(" INTO "); - sql.append(table); - sql.append('('); - - Object[] bindArgs = null; - int size = (initialValues != null && initialValues.size() > 0) ? initialValues.size() : 0; - if (size > 0) { - bindArgs = new Object[size]; - int i = 0; - for (String colName : initialValues.keySet()) { - sql.append((i > 0) ? "," : ""); - sql.append(colName); - bindArgs[i++] = initialValues.get(colName); + acquireReference(); + try { + StringBuilder sql = new StringBuilder(); + sql.append("INSERT"); + sql.append(CONFLICT_VALUES[conflictAlgorithm]); + sql.append(" INTO "); + sql.append(table); + sql.append('('); + + Object[] bindArgs = null; + int size = (initialValues != null && initialValues.size() > 0) + ? initialValues.size() : 0; + if (size > 0) { + bindArgs = new Object[size]; + int i = 0; + for (String colName : initialValues.keySet()) { + sql.append((i > 0) ? "," : ""); + sql.append(colName); + bindArgs[i++] = initialValues.get(colName); + } + sql.append(')'); + sql.append(" VALUES ("); + for (i = 0; i < size; i++) { + sql.append((i > 0) ? ",?" : "?"); + } + } else { + sql.append(nullColumnHack + ") VALUES (NULL"); } sql.append(')'); - sql.append(" VALUES ("); - for (i = 0; i < size; i++) { - sql.append((i > 0) ? ",?" : "?"); - } - } else { - sql.append(nullColumnHack + ") VALUES (NULL"); - } - sql.append(')'); - SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs); - try { - return statement.executeInsert(); + SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs); + try { + return statement.executeInsert(); + } finally { + statement.close(); + } } finally { - statement.close(); + releaseReference(); } } @@ -1430,12 +1472,17 @@ public final class SQLiteDatabase extends SQLiteClosable { * whereClause. */ public int delete(String table, String whereClause, String[] whereArgs) { - SQLiteStatement statement = new SQLiteStatement(this, "DELETE FROM " + table + - (!TextUtils.isEmpty(whereClause) ? " WHERE " + whereClause : ""), whereArgs); + acquireReference(); try { - return statement.executeUpdateDelete(); + SQLiteStatement statement = new SQLiteStatement(this, "DELETE FROM " + table + + (!TextUtils.isEmpty(whereClause) ? " WHERE " + whereClause : ""), whereArgs); + try { + return statement.executeUpdateDelete(); + } finally { + statement.close(); + } } finally { - statement.close(); + releaseReference(); } } @@ -1470,38 +1517,43 @@ public final class SQLiteDatabase extends SQLiteClosable { throw new IllegalArgumentException("Empty values"); } - StringBuilder sql = new StringBuilder(120); - sql.append("UPDATE "); - sql.append(CONFLICT_VALUES[conflictAlgorithm]); - sql.append(table); - sql.append(" SET "); - - // move all bind args to one array - int setValuesSize = values.size(); - int bindArgsSize = (whereArgs == null) ? setValuesSize : (setValuesSize + whereArgs.length); - Object[] bindArgs = new Object[bindArgsSize]; - int i = 0; - for (String colName : values.keySet()) { - sql.append((i > 0) ? "," : ""); - sql.append(colName); - bindArgs[i++] = values.get(colName); - sql.append("=?"); - } - if (whereArgs != null) { - for (i = setValuesSize; i < bindArgsSize; i++) { - bindArgs[i] = whereArgs[i - setValuesSize]; + acquireReference(); + try { + StringBuilder sql = new StringBuilder(120); + sql.append("UPDATE "); + sql.append(CONFLICT_VALUES[conflictAlgorithm]); + sql.append(table); + sql.append(" SET "); + + // move all bind args to one array + int setValuesSize = values.size(); + int bindArgsSize = (whereArgs == null) ? setValuesSize : (setValuesSize + whereArgs.length); + Object[] bindArgs = new Object[bindArgsSize]; + int i = 0; + for (String colName : values.keySet()) { + sql.append((i > 0) ? "," : ""); + sql.append(colName); + bindArgs[i++] = values.get(colName); + sql.append("=?"); + } + if (whereArgs != null) { + for (i = setValuesSize; i < bindArgsSize; i++) { + bindArgs[i] = whereArgs[i - setValuesSize]; + } + } + if (!TextUtils.isEmpty(whereClause)) { + sql.append(" WHERE "); + sql.append(whereClause); } - } - if (!TextUtils.isEmpty(whereClause)) { - sql.append(" WHERE "); - sql.append(whereClause); - } - SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs); - try { - return statement.executeUpdateDelete(); + SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs); + try { + return statement.executeUpdateDelete(); + } finally { + statement.close(); + } } finally { - statement.close(); + releaseReference(); } } @@ -1579,24 +1631,29 @@ public final class SQLiteDatabase extends SQLiteClosable { } private int executeSql(String sql, Object[] bindArgs) throws SQLException { - if (DatabaseUtils.getSqlStatementType(sql) == DatabaseUtils.STATEMENT_ATTACH) { - boolean disableWal = false; - synchronized (mLock) { - if (!mHasAttachedDbsLocked) { - mHasAttachedDbsLocked = true; - disableWal = true; + acquireReference(); + try { + if (DatabaseUtils.getSqlStatementType(sql) == DatabaseUtils.STATEMENT_ATTACH) { + boolean disableWal = false; + synchronized (mLock) { + if (!mHasAttachedDbsLocked) { + mHasAttachedDbsLocked = true; + disableWal = true; + } + } + if (disableWal) { + disableWriteAheadLogging(); } } - if (disableWal) { - disableWriteAheadLogging(); - } - } - SQLiteStatement statement = new SQLiteStatement(this, sql, bindArgs); - try { - return statement.executeUpdateDelete(); + SQLiteStatement statement = new SQLiteStatement(this, sql, bindArgs); + try { + return statement.executeUpdateDelete(); + } finally { + statement.close(); + } } finally { - statement.close(); + releaseReference(); } } @@ -1881,26 +1938,32 @@ public final class SQLiteDatabase extends SQLiteClosable { attachedDbs.add(new Pair<String, String>("main", mConfigurationLocked.path)); return attachedDbs; } + + acquireReference(); } - // has attached databases. query sqlite to get the list of attached databases. - Cursor c = null; try { - c = rawQuery("pragma database_list;", null); - while (c.moveToNext()) { - // sqlite returns a row for each database in the returned list of databases. - // in each row, - // 1st column is the database name such as main, or the database - // name specified on the "ATTACH" command - // 2nd column is the database file path. - attachedDbs.add(new Pair<String, String>(c.getString(1), c.getString(2))); + // has attached databases. query sqlite to get the list of attached databases. + Cursor c = null; + try { + c = rawQuery("pragma database_list;", null); + while (c.moveToNext()) { + // sqlite returns a row for each database in the returned list of databases. + // in each row, + // 1st column is the database name such as main, or the database + // name specified on the "ATTACH" command + // 2nd column is the database file path. + attachedDbs.add(new Pair<String, String>(c.getString(1), c.getString(2))); + } + } finally { + if (c != null) { + c.close(); + } } + return attachedDbs; } finally { - if (c != null) { - c.close(); - } + releaseReference(); } - return attachedDbs; } /** @@ -1917,35 +1980,38 @@ public final class SQLiteDatabase extends SQLiteClosable { * false otherwise. */ public boolean isDatabaseIntegrityOk() { - throwIfNotOpen(); // fail fast - - List<Pair<String, String>> attachedDbs = null; + acquireReference(); try { - attachedDbs = getAttachedDbs(); - if (attachedDbs == null) { - throw new IllegalStateException("databaselist for: " + getPath() + " couldn't " + - "be retrieved. probably because the database is closed"); + List<Pair<String, String>> attachedDbs = null; + try { + attachedDbs = getAttachedDbs(); + if (attachedDbs == null) { + throw new IllegalStateException("databaselist for: " + getPath() + " couldn't " + + "be retrieved. probably because the database is closed"); + } + } catch (SQLiteException e) { + // can't get attachedDb list. do integrity check on the main database + attachedDbs = new ArrayList<Pair<String, String>>(); + attachedDbs.add(new Pair<String, String>("main", getPath())); } - } catch (SQLiteException e) { - // can't get attachedDb list. do integrity check on the main database - attachedDbs = new ArrayList<Pair<String, String>>(); - attachedDbs.add(new Pair<String, String>("main", getPath())); - } - for (int i = 0; i < attachedDbs.size(); i++) { - Pair<String, String> p = attachedDbs.get(i); - SQLiteStatement prog = null; - try { - prog = compileStatement("PRAGMA " + p.first + ".integrity_check(1);"); - String rslt = prog.simpleQueryForString(); - if (!rslt.equalsIgnoreCase("ok")) { - // integrity_checker failed on main or attached databases - Log.e(TAG, "PRAGMA integrity_check on " + p.second + " returned: " + rslt); - return false; + for (int i = 0; i < attachedDbs.size(); i++) { + Pair<String, String> p = attachedDbs.get(i); + SQLiteStatement prog = null; + try { + prog = compileStatement("PRAGMA " + p.first + ".integrity_check(1);"); + String rslt = prog.simpleQueryForString(); + if (!rslt.equalsIgnoreCase("ok")) { + // integrity_checker failed on main or attached databases + Log.e(TAG, "PRAGMA integrity_check on " + p.second + " returned: " + rslt); + return false; + } + } finally { + if (prog != null) prog.close(); } - } finally { - if (prog != null) prog.close(); } + } finally { + releaseReference(); } return true; } @@ -1955,12 +2021,6 @@ public final class SQLiteDatabase extends SQLiteClosable { return "SQLiteDatabase: " + getPath(); } - private void throwIfNotOpen() { - synchronized (mConnectionPoolLocked) { - throwIfNotOpenLocked(); - } - } - private void throwIfNotOpenLocked() { if (mConnectionPoolLocked == null) { throw new IllegalStateException("The database '" + mConfigurationLocked.label diff --git a/core/java/android/database/sqlite/SQLiteProgram.java b/core/java/android/database/sqlite/SQLiteProgram.java index 9f0edfb..94a23cb 100644 --- a/core/java/android/database/sqlite/SQLiteProgram.java +++ b/core/java/android/database/sqlite/SQLiteProgram.java @@ -190,13 +190,6 @@ public abstract class SQLiteProgram extends SQLiteClosable { } /** - * Release this program's resources, making it invalid. - */ - public void close() { - releaseReference(); - } - - /** * Given an array of String bindArgs, this method binds all of them in one single call. * * @param bindArgs the String array of bind args, none of which must be null. |