summaryrefslogtreecommitdiffstats
path: root/core/java/android/database
diff options
context:
space:
mode:
authorJean-Baptiste Queru <jbq@google.com>2009-03-18 11:33:14 -0700
committerJean-Baptiste Queru <jbq@google.com>2009-03-18 11:33:14 -0700
commit2a73de7b21a89aa2ba4c254d28658b49793425b2 (patch)
treeded5bcd581464b4174d81c373044b6d36eee58d2 /core/java/android/database
parent42e48026b21a962e5bf40344d738665ecbd9d74d (diff)
parentba87e3e6c985e7175152993b5efcc7dd2f0e1c93 (diff)
downloadframeworks_base-2a73de7b21a89aa2ba4c254d28658b49793425b2.zip
frameworks_base-2a73de7b21a89aa2ba4c254d28658b49793425b2.tar.gz
frameworks_base-2a73de7b21a89aa2ba4c254d28658b49793425b2.tar.bz2
Merge commit 'remotes/korg/cupcake' into merge
Conflicts: core/java/android/view/animation/TranslateAnimation.java core/jni/Android.mk core/res/res/values-en-rGB/strings.xml libs/audioflinger/AudioFlinger.cpp libs/surfaceflinger/LayerScreenshot.cpp packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
Diffstat (limited to 'core/java/android/database')
-rw-r--r--core/java/android/database/DatabaseUtils.java1
-rw-r--r--core/java/android/database/sqlite/SQLiteDatabase.java57
-rw-r--r--core/java/android/database/sqlite/SQLiteOpenHelper.java2
-rw-r--r--core/java/android/database/sqlite/SQLiteProgram.java2
-rw-r--r--core/java/android/database/sqlite/SQLiteQuery.java20
-rw-r--r--core/java/android/database/sqlite/SQLiteStatement.java56
-rw-r--r--core/java/android/database/sqlite/package.html2
7 files changed, 111 insertions, 29 deletions
diff --git a/core/java/android/database/DatabaseUtils.java b/core/java/android/database/DatabaseUtils.java
index 2ff7294..10f3806 100644
--- a/core/java/android/database/DatabaseUtils.java
+++ b/core/java/android/database/DatabaseUtils.java
@@ -84,6 +84,7 @@ public class DatabaseUtils {
code = 9;
} else {
reply.writeException(e);
+ Log.e(TAG, "Writing exception to parcel", e);
return;
}
reply.writeInt(code);
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index fa062c8..2af080a 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();
@@ -764,9 +778,9 @@ public class SQLiteDatabase extends SQLiteClosable {
}
/**
- * Returns the maximum size the database may grow to.
+ * Returns the current database page size, in bytes.
*
- * @return the new maximum database size
+ * @return the database page size, in bytes
*/
public long getPageSize() {
SQLiteStatement prog = null;
@@ -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/SQLiteProgram.java b/core/java/android/database/sqlite/SQLiteProgram.java
index f89c87d..9e85452 100644
--- a/core/java/android/database/sqlite/SQLiteProgram.java
+++ b/core/java/android/database/sqlite/SQLiteProgram.java
@@ -22,7 +22,7 @@ import android.util.Log;
* A base class for compiled SQLite programs.
*/
public abstract class SQLiteProgram extends SQLiteClosable {
- static final String TAG = "SQLiteProgram";
+ private static final String TAG = "SQLiteProgram";
/** The database this program is compiled against. */
protected SQLiteDatabase mDatabase;
diff --git a/core/java/android/database/sqlite/SQLiteQuery.java b/core/java/android/database/sqlite/SQLiteQuery.java
index 22c53ab..1386a0d 100644
--- a/core/java/android/database/sqlite/SQLiteQuery.java
+++ b/core/java/android/database/sqlite/SQLiteQuery.java
@@ -17,13 +17,15 @@
package android.database.sqlite;
import android.database.CursorWindow;
+import android.os.SystemClock;
+import android.util.Log;
/**
* A SQLite program that represents a query that reads the resulting rows into a CursorWindow.
* This class is used by SQLiteCursor and isn't useful itself.
*/
public class SQLiteQuery extends SQLiteProgram {
- //private static final String TAG = "Cursor";
+ private static final String TAG = "Cursor";
/** The index of the unbound OFFSET parameter */
private int mOffsetIndex;
@@ -55,12 +57,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 +72,18 @@ 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);
+
+ // Logging
+ if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
+ Log.d(TAG, "fillWindow(): " + mQuery);
+ }
+ 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..5889ad9 100644
--- a/core/java/android/database/sqlite/SQLiteStatement.java
+++ b/core/java/android/database/sqlite/SQLiteStatement.java
@@ -16,6 +16,9 @@
package android.database.sqlite;
+import android.os.SystemClock;
+import android.util.Log;
+
/**
* A pre-compiled statement against a {@link SQLiteDatabase} that can be reused.
* The statement cannot return multiple rows, but 1x1 result sets are allowed.
@@ -24,6 +27,10 @@ package android.database.sqlite;
*/
public class SQLiteStatement extends SQLiteProgram
{
+ private static final String TAG = "SQLiteStatement";
+
+ private final String mSql;
+
/**
* Don't use SQLiteStatement constructor directly, please use
* {@link SQLiteDatabase#compileStatement(String)}
@@ -32,6 +39,11 @@ public class SQLiteStatement extends SQLiteProgram
*/
/* package */ SQLiteStatement(SQLiteDatabase db, String sql) {
super(db, sql);
+ if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
+ mSql = sql;
+ } else {
+ mSql = null;
+ }
}
/**
@@ -43,10 +55,19 @@ public class SQLiteStatement extends SQLiteProgram
*/
public void execute() {
mDatabase.lock();
+ boolean logStats = mDatabase.mLogStats;
+ long startTime = logStats ? SystemClock.elapsedRealtime() : 0;
+
acquireReference();
try {
+ if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
+ Log.v(TAG, "execute() for [" + mSql + "]");
+ }
native_execute();
- } finally {
+ if (logStats) {
+ mDatabase.logTimeStat(false /* write */, startTime, SystemClock.elapsedRealtime());
+ }
+ } finally {
releaseReference();
mDatabase.unlock();
}
@@ -64,9 +85,18 @@ public class SQLiteStatement extends SQLiteProgram
*/
public long executeInsert() {
mDatabase.lock();
+ boolean logStats = mDatabase.mLogStats;
+ long startTime = logStats ? SystemClock.elapsedRealtime() : 0;
+
acquireReference();
try {
+ if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
+ Log.v(TAG, "executeInsert() for [" + mSql + "]");
+ }
native_execute();
+ if (logStats) {
+ mDatabase.logTimeStat(false /* write */, startTime, SystemClock.elapsedRealtime());
+ }
return mDatabase.lastInsertRow();
} finally {
releaseReference();
@@ -84,9 +114,19 @@ 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();
+ if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
+ Log.v(TAG, "simpleQueryForLong() for [" + mSql + "]");
+ }
+ long retValue = native_1x1_long();
+ if (logStats) {
+ mDatabase.logTimeStat(false /* write */, startTime, SystemClock.elapsedRealtime());
+ }
+ return retValue;
} finally {
releaseReference();
mDatabase.unlock();
@@ -103,9 +143,19 @@ 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();
+ if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
+ Log.v(TAG, "simpleQueryForString() for [" + mSql + "]");
+ }
+ 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