• Home
  • History
  • Annotate
  • only in /frameworks/base/core/tests/coretests/src/android/database/sqlite/
History log of /frameworks/base/core/tests/coretests/src/android/database/sqlite/
Revision Date Author Comments (<<< Hide modified files) (Show modified files >>>)
e5360fbf3efe85427f7e7f59afe7bbeddb4949ac 01-Nov-2011 Jeff Brown <jeffbrown@google.com> Rewrite SQLite database wrappers.

The main theme of this change is encapsulation. This change
preserves all existing functionality but the implementation
is now much cleaner.

Instead of a "database lock", access to the database is treated
as a resource acquisition problem. If a thread's owns a database
connection, then it can access the database; otherwise, it must
acquire a database connection first, and potentially wait for other
threads to give up theirs. The SQLiteConnectionPool encapsulates
the details of how connections are created, configured, acquired,
released and disposed.

One new feature is that SQLiteConnectionPool can make scheduling
decisions about which thread should next acquire a database
connection when there is contention among threads. The factors
considered include wait queue ordering (fairness among peers),
whether the connection is needed for an interactive operation
(unfairness on behalf of the UI), and whether the primary connection
is needed or if any old connection will do. Thus one goal of the
new SQLiteConnectionPool is to improve the utilization of
database connections.

To emulate some quirks of the old "database lock," we introduce
the concept of the primary database connection. The primary
database connection is the one that is typically used to perform
write operations to the database. When a thread holds the primary
database connection, it effectively prevents other threads from
modifying the database (although they can still read). What's
more, those threads will block when they try to acquire the primary
connection, which provides the same kind of mutual exclusion
features that the old "database lock" had. (In truth, we
probably don't need to be requiring use of the primary database
connection in as many places as we do now, but we can seek to refine
that behavior in future patches.)

Another significant change is that native sqlite3_stmt objects
(prepared statements) are fully encapsulated by the SQLiteConnection
object that owns them. This ensures that the connection can
finalize (destroy) all extant statements that belong to a database
connection when the connection is closed. (In the original code,
this was very complicated because the sqlite3_stmt objects were
managed by SQLiteCompiledSql objects which had different lifetime
from the original SQLiteDatabase that created them. Worse, the
SQLiteCompiledSql finalizer method couldn't actually destroy the
sqlite3_stmt objects because it ran on the finalizer thread and
therefore could not guarantee that it could acquire the database
lock in order to do the work. This resulted in some rather
tortured logic involving a list of pending finalizable statements
and a high change of deadlocks or leaks.)

Because sqlite3_stmt objects never escape the confines of the
SQLiteConnection that owns them, we can also greatly simplify
the design of the SQLiteProgram, SQLiteQuery and SQLiteStatement
objects. They no longer have to wrangle a native sqlite3_stmt
object pointer and manage its lifecycle. So now all they do
is hold bind arguments and provide a fancy API.

All of the JNI glue related to managing database connections
and performing transactions is now bound to SQLiteConnection
(rather than being scattered everywhere). This makes sense because
SQLiteConnection owns the native sqlite3 object, so it is the
only class in the system that can interact with the native
SQLite database directly. Encapsulation for the win.

One particularly tricky part of this change is managing the
ownership of SQLiteConnection objects. At any given time,
a SQLiteConnection is either owned by a SQLiteConnectionPool
or by a SQLiteSession. SQLiteConnections should never be leaked,
but we handle that case too (and yell about it with CloseGuard).

A SQLiteSession object is responsible for acquiring and releasing
a SQLiteConnection object on behalf of a single thread as needed.
For example, the session acquires a connection when a transaction
begins and releases it when finished. If the session cannot
acquire a connection immediately, then the requested operation
blocks until a connection becomes available.

SQLiteSessions are thread-local. A SQLiteDatabase assigns a
distinct session to each thread that performs database operations.
This is very very important. First, it prevents two threads
from trying to use the same SQLiteConnection at the same time
(because two threads can't share the same session).
Second, it prevents a single thread from trying to acquire two
SQLiteConnections simultaneously from the same database (because
a single thread can't have two sessions for the same database which,
in addition to being greedy, could result in a deadlock).

There is strict layering between the various database objects,
objects at lower layers are not aware of objects at higher layers.
Moreover, objects at higher layers generally own objects at lower
layers and are responsible for ensuring they are properly disposed
when no longer needed (good for the environment).

API layer: SQLiteDatabase, SQLiteProgram, SQLiteQuery, SQLiteStatement.
Session layer: SQLiteSession.
Connection layer: SQLiteConnectionPool, SQLiteConnection.
Native layer: JNI glue.

By avoiding cyclic dependencies between layers, we make the
architecture much more intelligible, maintainable and robust.

Finally, this change adds a great deal of new debugging information.
It is now possible to view a list of the most recent database
operations including how long they took to run using
"adb shell dumpsys dbinfo". (Because most of the interesting
work happens in SQLiteConnection, it is easy to add debugging
instrumentation to track all database operations in one place.)

Change-Id: Iffb4ce72d8bcf20b4e087d911da6aa84d2f15297
atabaseConnectionPoolTest.java
QLiteCursorTest.java
QLiteDatabaseTest.java
QLiteStatementTest.java
QLiteUnfinalizedExceptionTest.java
cc1eaf6f7b81eaae21c01cbf4cf6f27dc3970774 15-Mar-2011 Vasu Nori <vnori@google.com> bug:4090903 allow bindargs on attach database statement

code incorrectly assumed that certain statements (like ATTACH DATABASE)
will never have bindargs.

Change-Id: I62eddbdf8e15947e8debf5052c7248113a3b9b57
QLiteDatabaseTest.java
12669b6c8073defcfae369e9f7b6f879b1ac218e 18-Feb-2011 Vasu Nori <vnori@google.com> bring back sqlite WAL tests now that the feature is in.

Change-Id: I92103915845b7cf3f41f95e909051b6669c63ec4
QLiteCursorTest.java
QLiteDatabaseTest.java
e7dea4ec2479002f5ee15bc6fc98d8c8acd123a6 10-Feb-2011 Vasu Nori <vnori@google.com> bug:3443154 fix database tests after disabling sqlite wal

sqlite wal is disabled in Change-Id: I283ad26ba7e1793772a372aa8e24df0cb96ce2ef

Change-Id: I2b370c65390a9293e4a82f650c9cee8023b861d7
QLiteCursorTest.java
QLiteDatabaseTest.java
c2ce721fcf684189b7251a5ecbf386426490d68e 06-Oct-2010 Vasu Nori <vnori@google.com> fix broken build

Change-Id: Ic00e8b98780d48928e05ee27f855e8211fb1ec47
QLiteCursorTest.java
790762ca8f4fa458b87f75e7e8cde965c9efe3e5 06-Oct-2010 Vasu Nori <vnori@google.com> annotate some tests large - just in case they take longer. bug:3066136

Change-Id: I89ab0454f592748f971b678a3ae23724eb6fc2e5
QLiteCursorTest.java
QLiteStatementTest.java
ffe06127f6ea4e9ea8e797f8ba0365d1f47fe297 27-Sep-2010 Vasu Nori <vnori@google.com> remove public API setConnectionPoolSize()

because connection pool size is now settable by modifying config.xml
of the device.

Change-Id: I973cc11d7dc10c8d95ab83e2f691068f6019fa33
QLiteDatabaseTest.java
b729dcc8a94bc2c2a1ecda47d791be0d6f1d160a 14-Sep-2010 Vasu Nori <vnori@google.com> Revert "caching code retooled to reduce locking + handle SMP"

This reverts commit 992f7d52fad590d90edc166cd74380e96d627605.

Change-Id: Ia5b789d1b2195d6ce43baffe24296c857f9b30f6
QLiteCacheTest.java
QLiteCompiledSqlTest.java
QLiteDatabaseTest.java
QLiteStatementTest.java
992f7d52fad590d90edc166cd74380e96d627605 03-Sep-2010 Vasu Nori <vnori@google.com> caching code retooled to reduce locking + handle SMP

1. Moved all code related to compiled-sql statement cache to SQLiteCache.java
Removed all caching related code from everywhere else.
2. Moved all code related to compiling a sql statement and caching it to
SQLiteCompiledSql.java. There was some code in SQLiteProgram.java
releated to this. moved it out.
3. Added state to SQLiteCompiledSql. This is to help in debugging.
Change-Id: I63ab0c9c4419e964eb9796d284dd389985763d83
QLiteCacheTest.java
QLiteCompiledSqlTest.java
QLiteDatabaseTest.java
QLiteStatementTest.java
b18f27dbf43ee9028a11cafbca23d3fa318e278b 13-Aug-2010 Vasu Nori <vnori@google.com> Return count of rows in a resultset only once (when startPos = 0)

If a query returns 100 rows and say only 10 rows fit in 1MB, then client
receiving the cursor from the ContentProvider needs to paginate.
ContentProvider returns count of total data everytime it returns a page
(= 1MB) of data to the client.
Returning total count causes reading (and skipping unwanted) data
from sqlite.
Instead, it should be sufficient to get total count once
and re-use the count value during the life of the cursor
until a requery is performed on the cursor.
(Count won't change unless data is changed - in which case
the cursor is asked to perform requery anyway. So doing count
once and reusing it should work)
Change-Id: I3520d94524dda07be9bcff56b6fbae5276af1d3b
QLiteCursorTest.java
422dad0f5069a96c002faf31540bf471a7052585 04-Sep-2010 Vasu Nori <vnori@google.com> android change to handle Change-Id: Idbeed81b5b7349059e467b33a8641abf0b4aaeff

Change-Id: Icf221a8e8d4c281f7719875816835ad7dfe7f3d1
QLiteUnfinalizedExceptionTest.java
cc6f54910d2431e31af176163f61b34d50a33647 24-Aug-2010 Vasu Nori <vnori@google.com> SQLiteOpenHelper should discard closed singleton database objects

bug:2943028
Change-Id: I4b6263cc25413995363158c976d3c723231cc050
QLiteDatabaseTest.java
ce38b98feb1e7c9c1799eb270c40798d833aa9ae 22-Jul-2010 Vasu Nori <vnori@google.com> do begin-end transaction before standalone insert/update/delete sql

also fix bug# 2871037
Change-Id: I13325f8eabff4f218d3206905010803b61d8e2cd
QLiteDatabaseTest.java
65a8883f0e605bb8a73a692987b47ce5da632e72 17-Jul-2010 Vasu Nori <vnori@google.com> don't store mDatabase in SQLiteCursor as it is already in SQLiteQuery

SQLiteCursor has two members: mQuery, mDatabase
but mQuery already has mDatabase.
there is no need for SQLiteCursor.mDatabase.
and everytime SQLiteQuery.mDatabase is to be used, try to use a pooled database
connection handle, if possible.
Change-Id: I42b2376d714a1a4091c843e245a45b882bb7fee6
atabaseConnectionPoolTest.java
QLiteCursorTest.java
QLiteDatabaseTest.java
e25539fdfdf884eee55107efbcc893f44e82e00e 09-Jul-2010 Vasu Nori <vnori@google.com> reduce locking when using SQLiteStatement

Do compiling of sql, binding of args and execution of the SQL
statement within one single database lock period.
This reduces the number of times the database lock
needs to be acquired during the course of compilation, binding
and execution of a SQLiteStatement.

Change-Id: I22b090ec9e10fc0aa2532a93bafe610af2546b58
QLiteDatabaseTest.java
QLiteStatementTest.java
57feb5d9a7fd5329c2ae5daeca0ce8f10a7372a7 22-Jun-2010 Vasu Nori <vnori@google.com> STOPSHIP CL in master - make sqlite WAL default for all apps

for testing the sqlite WAL feature in the next few weeks.

Change-Id: I07234647b5e90d9e3bb0a5310b6cc449d58db428
QLiteDatabaseTest.java
2827d6d974beabb12344040a002dcb52dd7106b5 04-Jul-2010 Vasu Nori <vnori@google.com> for WAL to work, can't keep prepared SQL stmt_id in SQLiteStatement

Some (including the Contacts app) do the following:
1. Open database
2. As part of database_connection.onCreate(),
Create some SQLiteStatement objects to cache them in the process
3. attach databases
WAL doesn't work with attached databases. so, apps doing the above
should enable WAL only if there are no attached databases.

But we would like to enable WAL automatically for all apps after step #1 above
and disable WAL if the app subsequently does 'attach database' SQL.

this works only if there are no SQLiteStatement objects created in step # 2,
because SQLiteStatements cwmaintain a hard-reference to the database connection
for life and also to the prepared SQL statement id.
It is quite difficult to disable WAL in step # 3
if it is enabled in step # 1
and then a connection pool gets used by step # 2

would make WAL disabling easier if SQLiteStatement refers to prepared SQL
statement id only when it is needed (during binding and execute calls)
and thus NOT tied to a spacific database conenction.

also, from the standpoint of not blocking readers, it helps NOT to have
SQLiteStatement be married to a database connection and prepared SQL statement
id for life.

Change-Id: I464d57042965a28d2bde88e0f44b66ec119b40dc
QLiteDatabaseTest.java
QLiteStatementTest.java
6ac21d30be06c1c6d5ef04a88cf5171a446633f1 07-Jul-2010 Vasu Nori <vnori@google.com> unittests for DatabaseConnectionPool (and fix bugs)

Change-Id: I6f251b4bdd472bd840ea1be6497660f8c31cd3e3
atabaseConnectionPoolTest.java
59d60420ba9246eee152852b6a597a0aba7f704d 04-Jul-2010 Vasu Nori <vnori@google.com> deprecate method returning prepared sql statement id

this method causes sql statement in a SQLiteProgram object to be never
re-compiled. thats not desirable, is it?
there should be no need for this method.

Change-Id: I207fad6415c1e2ef4097ee65a3ff347b5435b994
QLiteDatabaseTest.java
QLiteStatementTest.java
2776d57403f08e4ffcc05d476d11d58861823f08 04-Jul-2010 Vasu Nori <vnori@google.com> Merge "fix broken build: renaming a testfile"
7af57126b557bfe08a21952134a8712f29009aaa 04-Jul-2010 Vasu Nori <vnori@google.com> fix broken build: renaming a testfile

Change-Id: I973f604f4f87792b3f8734a6aea4a73d29e0b34b
QLiteStatementTest.java
d960ef8469b385124fe1a83c28c60ddaef5099ec 04-Jul-2010 Vasu Nori <vnori@google.com> Merge "change name of a test to be more accurate"
709493707c22d8794a0f82b07caae96addeff460 04-Jul-2010 Vasu Nori <vnori@google.com> change name of a test to be more accurate

Change-Id: Ie8c7d6ab4b80ae0446f9d67c8a04cef436948692
QLiteGeneralTest.java
QLiteStatementTest.java
150daa1ae1cf81b676349a7dedef61767c5a68a9 02-Jul-2010 Vasu Nori <vnori@google.com> Merge "remove broken, unused and unwanted tests"
ed57af9e89f1d27ae544ccebb88e2728c2ab379d 02-Jul-2010 Vasu Nori <vnori@google.com> remove broken, unused and unwanted tests

Change-Id: I804b777b7c434c8a190d70d6a2556e1f157abe70
bstractJDBCDriverTest.java
QLiteJDBCDriverTest.java
7501010b71d57264a06f82937f5fb29cb9f4b509 02-Jul-2010 Vasu Nori <vnori@google.com> some refactoring and multi-threading fixes

Change-Id: I7a0497dc2ed7b1e21471d71532558ef243eb9f73
QLiteDatabaseTest.java
e8bf6dbc4025f5e3973f2902af7dfdb501e5d6ff 18-Jun-2010 Vasu Nori <vnori@google.com> fix broken test similar to I32c30f7d05e5bec7c6b2776ce9a80c8be61d856f

Change-Id: Idf075ea888dfab35afba0a28a838e3a15b7de545
QLiteDatabaseTest.java
0bcd289b99786567931b56658e37c8fcb965b513 17-Jun-2010 Vasu Nori <vnori@google.com> move a sqlite test from framework-tests to coretests

Change-Id: Ic8d42a3c477e4ea0ad8eaa4e1869ae221b95ba46
QLiteDatabaseTest.java
e8de28415b4362824a52c180adf10dd882d12eaf 18-Feb-2010 Vasu Nori <vnori@google.com> bug fix for 2419869. also included 2 unittests.

bug fix for 2419869 is the following
1. only one object can use the prepared statement object
(SQLiteCompiledSql in SQLIteProgram)
2. if two objects are requesting to use it, then create a new prepared
statement object for exclusive use by the newcomer and let it be
be finalized by the newcomer.
3. add mInUse flag to SQLiteCompiledSql - to be set when SQLiteProgram
requests it and to be released when that SQLiteProgram is done with it
a couple more changes included are
1. unitests to simulate bug # 2419869 (and the fix's repair to it)
2. better logging in SQLiteCloseable when it prints log messages
QLiteGeneralTest.java
3ef94e25b4c896ecaa85aa2c12b8863ecdf98df0 05-Feb-2010 Vasu Nori <vnori@google.com> use sqlite 3.6.22 to print and profile the sql statetements

instead of rolling our own trace/profile code in java, lets use
sqlite 3.6.22 features. turns out sqlite does a good job of
printing the sql statements - including the ones from the triggers.
QLiteDebugTest.java
4dd4ab4cc322e82401f380aeb877daa4a20d7069 30-Jan-2010 Vasu Nori <vnori@google.com> add instrumentation to log the sql statement + bindargs + databasename

capture the sql statement along with the bindargs passed in. this will help
one to see the sql statements being executed and hopefully will help
debug incorrect-sql bugs.
QLiteDebugTest.java
1d3165f10b12165f02b7015ac1a817c5f60e6399 12-Jan-2010 Neal Nguyen <tommyn@google.com> Phase 2 of test file cleanup: relocating test files from FrameworkTest closer to their sources in core.

In addition to the file moves, the package names of the tests have been updated and adjusted to match their new locations.
bstractJDBCDriverTest.java
QLiteJDBCDriverTest.java
22e31e5b609136d5bf7d77b1dccd6b042b83ebdf 07-Jan-2010 Neal Nguyen <tommyn@google.com> Moving framework core tests closer to their source files.

Phase 2 of test case cleanup; distributing CoreTests files closer to their respective sources under frameworks.
bstractJDBCDriverTest.java
QLiteJDBCDriverTest.java