diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-02-10 15:44:00 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-02-10 15:44:00 -0800 |
commit | d24b8183b93e781080b2c16c487e60d51c12da31 (patch) | |
tree | fbb89154858984eb8e41556da7e9433040d55cd4 /core/java/android/database | |
parent | f1e484acb594a726fb57ad0ae4cfe902c7f35858 (diff) | |
download | frameworks_base-d24b8183b93e781080b2c16c487e60d51c12da31.zip frameworks_base-d24b8183b93e781080b2c16c487e60d51c12da31.tar.gz frameworks_base-d24b8183b93e781080b2c16c487e60d51c12da31.tar.bz2 |
auto import from //branches/cupcake/...@130745
Diffstat (limited to 'core/java/android/database')
5 files changed, 78 insertions, 25 deletions
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java index fa062c8..87bb277 100644 --- a/core/java/android/database/sqlite/SQLiteDatabase.java +++ b/core/java/android/database/sqlite/SQLiteDatabase.java @@ -25,6 +25,7 @@ import android.os.SystemClock; import android.text.TextUtils; import android.util.Config; import android.util.Log; +import android.util.EventLog; import java.io.File; import java.util.HashMap; @@ -51,7 +52,8 @@ import java.util.concurrent.locks.ReentrantLock; * is the Unicode Collation Algorithm and not tailored to the current locale. */ public class SQLiteDatabase extends SQLiteClosable { - private final static String TAG = "Database"; + private static final String TAG = "Database"; + private static final int DB_OPERATION_EVENT = 52000; /** * Algorithms used in ON CONFLICT clause @@ -207,6 +209,11 @@ public class SQLiteDatabase extends SQLiteClosable { private WeakHashMap<SQLiteClosable, Object> mPrograms; private final RuntimeException mLeakedException; + + // package visible, since callers will access directly to minimize overhead in the case + // that logging is not enabled. + /* package */ final boolean mLogStats; + /** * @param closable */ @@ -436,7 +443,14 @@ public class SQLiteDatabase extends SQLiteClosable { if (mTransactionIsSuccessful) { execSQL("COMMIT;"); } else { - execSQL("ROLLBACK;"); + try { + execSQL("ROLLBACK;"); + } catch (SQLException e) { + if (Config.LOGD) { + Log.d(TAG, "exception during rollback, maybe the DB previously " + + "performed an auto-rollback"); + } + } } } finally { unlockForced(); @@ -1472,10 +1486,8 @@ public class SQLiteDatabase extends SQLiteClosable { * @throws SQLException If the SQL string is invalid for some reason */ public void execSQL(String sql) throws SQLException { - long timeStart = 0; - if (Config.LOGV) { - timeStart = System.currentTimeMillis(); - } + boolean logStats = mLogStats; + long timeStart = logStats ? SystemClock.elapsedRealtime() : 0; lock(); try { native_execSQL(sql); @@ -1485,9 +1497,8 @@ public class SQLiteDatabase extends SQLiteClosable { } finally { unlock(); } - if (Config.LOGV) { - long timeEnd = System.currentTimeMillis(); - Log.v(TAG, "Executed (" + (timeEnd - timeStart) + " ms):" + sql); + if (logStats) { + logTimeStat(false /* not a read */, timeStart, SystemClock.elapsedRealtime()); } } @@ -1504,10 +1515,9 @@ public class SQLiteDatabase extends SQLiteClosable { if (bindArgs == null) { throw new IllegalArgumentException("Empty bindArgs"); } - long timeStart = 0; - if (Config.LOGV) { - timeStart = System.currentTimeMillis(); - } + + boolean logStats = mLogStats; + long timeStart = logStats ? SystemClock.elapsedRealtime() : 0; lock(); SQLiteStatement statement = null; try { @@ -1528,9 +1538,8 @@ public class SQLiteDatabase extends SQLiteClosable { } unlock(); } - if (Config.LOGV) { - long timeEnd = System.currentTimeMillis(); - Log.v(TAG, "Executed (" + (timeEnd - timeStart) + " ms):" + sql); + if (logStats) { + logTimeStat(false /* not a read */, timeStart, SystemClock.elapsedRealtime()); } } @@ -1550,7 +1559,7 @@ public class SQLiteDatabase extends SQLiteClosable { } /** - * Private constructor. See {@link createDatabase} and {@link openDatabase}. + * Private constructor. See {@link #create} and {@link #openDatabase}. * * @param path The full path to the database * @param factory The factory to use when creating cursors, may be NULL. @@ -1563,6 +1572,8 @@ public class SQLiteDatabase extends SQLiteClosable { } mFlags = flags; mPath = path; + mLogStats = "1".equals(android.os.SystemProperties.get("db.logstats")); + mLeakedException = new IllegalStateException(path + " SQLiteDatabase created and never closed"); mFactory = factory; @@ -1605,6 +1616,10 @@ public class SQLiteDatabase extends SQLiteClosable { return mPath; } + /* package */ void logTimeStat(boolean read, long begin, long end) { + EventLog.writeEvent(DB_OPERATION_EVENT, mPath, read ? 0 : 1, end - begin); + } + /** * Sets the locale for this database. Does nothing if this database has * the NO_LOCALIZED_COLLATORS flag set or was opened read only. @@ -1629,7 +1644,7 @@ public class SQLiteDatabase extends SQLiteClosable { private native void dbopen(String path, int flags); /** - * Native call to execute a raw SQL statement. {@link mLock} must be held + * Native call to execute a raw SQL statement. {@link #lock} must be held * when calling this method. * * @param sql The raw SQL string @@ -1638,7 +1653,7 @@ public class SQLiteDatabase extends SQLiteClosable { /* package */ native void native_execSQL(String sql) throws SQLException; /** - * Native call to set the locale. {@link mLock} must be held when calling + * Native call to set the locale. {@link #lock} must be held when calling * this method. * @throws SQLException */ diff --git a/core/java/android/database/sqlite/SQLiteOpenHelper.java b/core/java/android/database/sqlite/SQLiteOpenHelper.java index 35bf645..52aac3a 100644 --- a/core/java/android/database/sqlite/SQLiteOpenHelper.java +++ b/core/java/android/database/sqlite/SQLiteOpenHelper.java @@ -26,6 +26,8 @@ import android.util.Log; * optionally {@link #onOpen}, and this class takes care of opening the database * if it exists, creating it if it does not, and upgrading it as necessary. * Transactions are used to make sure the database is always in a sensible state. + * <p>For an example, see the NotePadProvider class in the NotePad sample application, + * in the <em>samples/</em> directory of the SDK.</p> */ public abstract class SQLiteOpenHelper { private static final String TAG = SQLiteOpenHelper.class.getSimpleName(); diff --git a/core/java/android/database/sqlite/SQLiteQuery.java b/core/java/android/database/sqlite/SQLiteQuery.java index 22c53ab..5bfa0e8 100644 --- a/core/java/android/database/sqlite/SQLiteQuery.java +++ b/core/java/android/database/sqlite/SQLiteQuery.java @@ -17,6 +17,7 @@ package android.database.sqlite; import android.database.CursorWindow; +import android.os.SystemClock; /** * A SQLite program that represents a query that reads the resulting rows into a CursorWindow. @@ -55,12 +56,14 @@ public class SQLiteQuery extends SQLiteProgram { * Reads rows into a buffer. This method acquires the database lock. * * @param window The window to fill into - * @param startPos The position to start reading rows from * @return number of total rows in the query */ /* package */ int fillWindow(CursorWindow window, int maxRead, int lastPos) { mDatabase.lock(); + + boolean logStats = mDatabase.mLogStats; + long startTime = logStats ? SystemClock.elapsedRealtime() : 0; try { acquireReference(); try { @@ -68,8 +71,13 @@ public class SQLiteQuery extends SQLiteProgram { // if the start pos is not equal to 0, then most likely window is // too small for the data set, loading by another thread // is not safe in this situation. the native code will ignore maxRead - return native_fill_window(window, window.getStartPosition(), mOffsetIndex, + int numRows = native_fill_window(window, window.getStartPosition(), mOffsetIndex, maxRead, lastPos); + if (logStats) { + mDatabase.logTimeStat(true /* read */, startTime, + SystemClock.elapsedRealtime()); + } + return numRows; } catch (IllegalStateException e){ // simply ignore it return 0; diff --git a/core/java/android/database/sqlite/SQLiteStatement.java b/core/java/android/database/sqlite/SQLiteStatement.java index bf9361d..d169259 100644 --- a/core/java/android/database/sqlite/SQLiteStatement.java +++ b/core/java/android/database/sqlite/SQLiteStatement.java @@ -16,6 +16,8 @@ package android.database.sqlite; +import android.os.SystemClock; + /** * A pre-compiled statement against a {@link SQLiteDatabase} that can be reused. * The statement cannot return multiple rows, but 1x1 result sets are allowed. @@ -43,10 +45,16 @@ public class SQLiteStatement extends SQLiteProgram */ public void execute() { mDatabase.lock(); + boolean logStats = mDatabase.mLogStats; + long startTime = logStats ? SystemClock.elapsedRealtime() : 0; + acquireReference(); try { native_execute(); - } finally { + if (logStats) { + mDatabase.logTimeStat(false /* write */, startTime, SystemClock.elapsedRealtime()); + } + } finally { releaseReference(); mDatabase.unlock(); } @@ -64,9 +72,15 @@ public class SQLiteStatement extends SQLiteProgram */ public long executeInsert() { mDatabase.lock(); + boolean logStats = mDatabase.mLogStats; + long startTime = logStats ? SystemClock.elapsedRealtime() : 0; + acquireReference(); try { native_execute(); + if (logStats) { + mDatabase.logTimeStat(false /* write */, startTime, SystemClock.elapsedRealtime()); + } return mDatabase.lastInsertRow(); } finally { releaseReference(); @@ -84,9 +98,16 @@ public class SQLiteStatement extends SQLiteProgram */ public long simpleQueryForLong() { mDatabase.lock(); + boolean logStats = mDatabase.mLogStats; + long startTime = logStats ? SystemClock.elapsedRealtime() : 0; + acquireReference(); try { - return native_1x1_long(); + long retValue = native_1x1_long(); + if (logStats) { + mDatabase.logTimeStat(false /* write */, startTime, SystemClock.elapsedRealtime()); + } + return retValue; } finally { releaseReference(); mDatabase.unlock(); @@ -103,9 +124,16 @@ public class SQLiteStatement extends SQLiteProgram */ public String simpleQueryForString() { mDatabase.lock(); + boolean logStats = mDatabase.mLogStats; + long startTime = logStats ? SystemClock.elapsedRealtime() : 0; + acquireReference(); try { - return native_1x1_string(); + String retValue = native_1x1_string(); + if (logStats) { + mDatabase.logTimeStat(false /* write */, startTime, SystemClock.elapsedRealtime()); + } + return retValue; } finally { releaseReference(); mDatabase.unlock(); diff --git a/core/java/android/database/sqlite/package.html b/core/java/android/database/sqlite/package.html index c03a8dc..ff0f9f5 100644 --- a/core/java/android/database/sqlite/package.html +++ b/core/java/android/database/sqlite/package.html @@ -6,7 +6,7 @@ classes that an application would use to manage its own private database. Applications use these classes to maange private databases. If creating a content provider, you will probably have to use these classes to create and manage your own database to store content. See <a -href="{@docRoot}devel/data.html">Storing, Retrieving and Exposing Data</a> to learn +href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a> to learn the conventions for implementing a content provider. See the NotePadProvider class in the NotePad sample application in the SDK for an example of a content provider. Android ships with SQLite version 3.4.0 |