android change to handle Change-Id: Idbeed81b5b7349059e467b33a8641abf0b4aaeff
Change-Id: Icf221a8e8d4c281f7719875816835ad7dfe7f3d1
This commit is contained in:
@@ -144,6 +144,22 @@ import android.util.Log;
|
||||
}
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
synchronized(this) {
|
||||
StringBuilder buff = new StringBuilder();
|
||||
buff.append(" nStatement=");
|
||||
buff.append(nStatement);
|
||||
buff.append(", db=");
|
||||
buff.append(mDatabase.getPath());
|
||||
buff.append(", db_connectionNum=");
|
||||
buff.append(mDatabase.mConnectionNum);
|
||||
buff.append(", sql=");
|
||||
int len = mSqlStmt.length();
|
||||
buff.append(mSqlStmt.substring(0, (len > 100) ? 100 : len));
|
||||
return buff.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles SQL into a SQLite program.
|
||||
*
|
||||
|
||||
@@ -1066,7 +1066,7 @@ public class SQLiteDatabase extends SQLiteClosable {
|
||||
closePendingStatements();
|
||||
releaseCustomFunctions();
|
||||
// close this database instance - regardless of its reference count value
|
||||
dbclose();
|
||||
closeDatabase();
|
||||
if (mConnectionPool != null) {
|
||||
if (Log.isLoggable(TAG, Log.DEBUG)) {
|
||||
assert mConnectionPool != null;
|
||||
@@ -1075,7 +1075,7 @@ public class SQLiteDatabase extends SQLiteClosable {
|
||||
mConnectionPool.close();
|
||||
}
|
||||
} finally {
|
||||
unlock();
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1099,6 +1099,47 @@ public class SQLiteDatabase extends SQLiteClosable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* package level access for testing purposes
|
||||
*/
|
||||
/* package */ void closeDatabase() throws SQLiteException {
|
||||
try {
|
||||
dbclose();
|
||||
} catch (SQLiteUnfinalizedObjectsException e) {
|
||||
String msg = e.getMessage();
|
||||
String[] tokens = msg.split(",", 2);
|
||||
int stmtId = Integer.parseInt(tokens[0]);
|
||||
// get extra info about this statement, if it is still to be released by closeClosable()
|
||||
Iterator<Map.Entry<SQLiteClosable, Object>> iter = mPrograms.entrySet().iterator();
|
||||
boolean found = false;
|
||||
while (iter.hasNext()) {
|
||||
Map.Entry<SQLiteClosable, Object> entry = iter.next();
|
||||
SQLiteClosable program = entry.getKey();
|
||||
if (program != null && program instanceof SQLiteProgram) {
|
||||
SQLiteCompiledSql compiledSql = ((SQLiteProgram)program).mCompiledSql;
|
||||
if (compiledSql.nStatement == stmtId) {
|
||||
msg = compiledSql.toString();
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
// the statement is already released by closeClosable(). is it waiting to be
|
||||
// finalized?
|
||||
if (mClosedStatementIds.contains(stmtId)) {
|
||||
Log.w(TAG, "this shouldn't happen. finalizing the statement now: ");
|
||||
closePendingStatements();
|
||||
// try to close the database again
|
||||
closeDatabase();
|
||||
}
|
||||
} else {
|
||||
// the statement is not yet closed. most probably programming error in the app.
|
||||
Log.w(TAG, "dbclose failed due to un-close()d SQL statements: " + msg);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Native call to close the database.
|
||||
*/
|
||||
|
||||
@@ -52,7 +52,7 @@ public abstract class SQLiteProgram extends SQLiteClosable {
|
||||
/**
|
||||
* the SQLiteCompiledSql object for the given sql statement.
|
||||
*/
|
||||
private SQLiteCompiledSql mCompiledSql;
|
||||
/* package */ SQLiteCompiledSql mCompiledSql;
|
||||
|
||||
/**
|
||||
* SQLiteCompiledSql statement id is populated with the corresponding object from the above
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.database.sqlite;
|
||||
|
||||
/**
|
||||
* Thrown if the database can't be closed because of some un-closed
|
||||
* Cursor or SQLiteStatement objects. Could happen when a thread is trying to close
|
||||
* the database while another thread still hasn't closed a Cursor on that database.
|
||||
* @hide
|
||||
*/
|
||||
public class SQLiteUnfinalizedObjectsException extends SQLiteException {
|
||||
public SQLiteUnfinalizedObjectsException() {}
|
||||
|
||||
public SQLiteUnfinalizedObjectsException(String error) {
|
||||
super(error);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user