SQLiteDatabasepublic final class SQLiteDatabase extends SQLiteClosable Exposes methods to manage a SQLite database.
SQLiteDatabase has methods to create, delete, execute SQL commands, and
perform other common database management tasks.
See the Notepad sample application in the SDK for an example of creating
and managing a database.
Database names must be unique within an application, not across all applications.
Localized Collation - ORDER BY
In addition to SQLite's default BINARY collator, Android supplies
two more, LOCALIZED , which changes with the system's current locale,
and UNICODE , which is the Unicode Collation Algorithm and not tailored
to the current locale.
|
Fields Summary |
---|
private static final String | TAG | private static final int | EVENT_DB_CORRUPT | private static WeakHashMap | sActiveDatabases | private final ThreadLocal | mThreadSession | private final CursorFactory | mCursorFactory | private final android.database.DatabaseErrorHandler | mErrorHandler | private final Object | mLock | private final dalvik.system.CloseGuard | mCloseGuardLocked | private final SQLiteDatabaseConfiguration | mConfigurationLocked | private SQLiteConnectionPool | mConnectionPoolLocked | private boolean | mHasAttachedDbsLocked | public static final int | CONFLICT_ROLLBACKWhen a constraint violation occurs, an immediate ROLLBACK occurs,
thus ending the current transaction, and the command aborts with a
return code of SQLITE_CONSTRAINT. If no transaction is active
(other than the implied transaction that is created on every command)
then this algorithm works the same as ABORT. | public static final int | CONFLICT_ABORTWhen a constraint violation occurs,no ROLLBACK is executed
so changes from prior commands within the same transaction
are preserved. This is the default behavior. | public static final int | CONFLICT_FAILWhen a constraint violation occurs, the command aborts with a return
code SQLITE_CONSTRAINT. But any changes to the database that
the command made prior to encountering the constraint violation
are preserved and are not backed out. | public static final int | CONFLICT_IGNOREWhen a constraint violation occurs, the one row that contains
the constraint violation is not inserted or changed.
But the command continues executing normally. Other rows before and
after the row that contained the constraint violation continue to be
inserted or updated normally. No error is returned. | public static final int | CONFLICT_REPLACEWhen a UNIQUE constraint violation occurs, the pre-existing rows that
are causing the constraint violation are removed prior to inserting
or updating the current row. Thus the insert or update always occurs.
The command continues executing normally. No error is returned.
If a NOT NULL constraint violation occurs, the NULL value is replaced
by the default value for that column. If the column has no default
value, then the ABORT algorithm is used. If a CHECK constraint
violation occurs then the IGNORE algorithm is used. When this conflict
resolution strategy deletes rows in order to satisfy a constraint,
it does not invoke delete triggers on those rows.
This behavior might change in a future release. | public static final int | CONFLICT_NONEUse the following when no conflict action is specified. | private static final String[] | CONFLICT_VALUES | public static final int | SQLITE_MAX_LIKE_PATTERN_LENGTHMaximum Length Of A LIKE Or GLOB Pattern
The pattern matching algorithm used in the default LIKE and GLOB implementation
of SQLite can exhibit O(N^2) performance (where N is the number of characters in
the pattern) for certain pathological cases. To avoid denial-of-service attacks
the length of the LIKE or GLOB pattern is limited to SQLITE_MAX_LIKE_PATTERN_LENGTH bytes.
The default value of this limit is 50000. A modern workstation can evaluate
even a pathological LIKE or GLOB pattern of 50000 bytes relatively quickly.
The denial of service problem only comes into play when the pattern length gets
into millions of bytes. Nevertheless, since most useful LIKE or GLOB patterns
are at most a few dozen bytes in length, paranoid application developers may
want to reduce this parameter to something in the range of a few hundred
if they know that external users are able to generate arbitrary patterns. | public static final int | OPEN_READWRITEOpen flag: Flag for {@link #openDatabase} to open the database for reading and writing.
If the disk is full, this may fail even before you actually write anything.
{@more} Note that the value of this flag is 0, so it is the default. | public static final int | OPEN_READONLYOpen flag: Flag for {@link #openDatabase} to open the database for reading only.
This is the only reliable way to open a database if the disk may be full. | private static final int | OPEN_READ_MASK | public static final int | NO_LOCALIZED_COLLATORSOpen flag: Flag for {@link #openDatabase} to open the database without support for
localized collators.
{@more} This causes the collator LOCALIZED not to be created.
You must be consistent when using this flag to use the setting the database was
created with. If this is set, {@link #setLocale} will do nothing. | public static final int | CREATE_IF_NECESSARYOpen flag: Flag for {@link #openDatabase} to create the database file if it does not
already exist. | public static final int | ENABLE_WRITE_AHEAD_LOGGINGOpen flag: Flag for {@link #openDatabase} to open the database file with
write-ahead logging enabled by default. Using this flag is more efficient
than calling {@link #enableWriteAheadLogging}.
Write-ahead logging cannot be used with read-only databases so the value of
this flag is ignored if the database is opened read-only. | public static final int | MAX_SQL_CACHE_SIZEAbsolute max value that can be set by {@link #setMaxSqlCacheSize(int)}.
Each prepared-statement is between 1K - 6K, depending on the complexity of the
SQL statement & schema. A large SQL cache may use a significant amount of memory. |
Constructors Summary |
---|
private SQLiteDatabase(String path, int openFlags, CursorFactory cursorFactory, android.database.DatabaseErrorHandler errorHandler)
mCursorFactory = cursorFactory;
mErrorHandler = errorHandler != null ? errorHandler : new DefaultDatabaseErrorHandler();
mConfigurationLocked = new SQLiteDatabaseConfiguration(path, openFlags);
|
Methods Summary |
---|
public void | addCustomFunction(java.lang.String name, int numArgs, android.database.sqlite.SQLiteDatabase$CustomFunction function)Registers a CustomFunction callback as a function that can be called from
SQLite database triggers.
// Create wrapper (also validates arguments).
SQLiteCustomFunction wrapper = new SQLiteCustomFunction(name, numArgs, function);
synchronized (mLock) {
throwIfNotOpenLocked();
mConfigurationLocked.customFunctions.add(wrapper);
try {
mConnectionPoolLocked.reconfigure(mConfigurationLocked);
} catch (RuntimeException ex) {
mConfigurationLocked.customFunctions.remove(wrapper);
throw ex;
}
}
| public void | beginTransaction()Begins a transaction in EXCLUSIVE mode.
Transactions can be nested.
When the outer transaction is ended all of
the work done in that transaction and all of the nested transactions will be committed or
rolled back. The changes will be rolled back if any transaction is ended without being
marked as clean (by calling setTransactionSuccessful). Otherwise they will be committed.
Here is the standard idiom for transactions:
db.beginTransaction();
try {
...
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
beginTransaction(null /* transactionStatusCallback */, true);
| private void | beginTransaction(SQLiteTransactionListener transactionListener, boolean exclusive)
acquireReference();
try {
getThreadSession().beginTransaction(
exclusive ? SQLiteSession.TRANSACTION_MODE_EXCLUSIVE :
SQLiteSession.TRANSACTION_MODE_IMMEDIATE,
transactionListener,
getThreadDefaultConnectionFlags(false /*readOnly*/), null);
} finally {
releaseReference();
}
| public void | beginTransactionNonExclusive()Begins a transaction in IMMEDIATE mode. Transactions can be nested. When
the outer transaction is ended all of the work done in that transaction
and all of the nested transactions will be committed or rolled back. The
changes will be rolled back if any transaction is ended without being
marked as clean (by calling setTransactionSuccessful). Otherwise they
will be committed.
Here is the standard idiom for transactions:
db.beginTransactionNonExclusive();
try {
...
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
beginTransaction(null /* transactionStatusCallback */, false);
| public void | beginTransactionWithListener(SQLiteTransactionListener transactionListener)Begins a transaction in EXCLUSIVE mode.
Transactions can be nested.
When the outer transaction is ended all of
the work done in that transaction and all of the nested transactions will be committed or
rolled back. The changes will be rolled back if any transaction is ended without being
marked as clean (by calling setTransactionSuccessful). Otherwise they will be committed.
Here is the standard idiom for transactions:
db.beginTransactionWithListener(listener);
try {
...
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
beginTransaction(transactionListener, true);
| public void | beginTransactionWithListenerNonExclusive(SQLiteTransactionListener transactionListener)Begins a transaction in IMMEDIATE mode. Transactions can be nested. When
the outer transaction is ended all of the work done in that transaction
and all of the nested transactions will be committed or rolled back. The
changes will be rolled back if any transaction is ended without being
marked as clean (by calling setTransactionSuccessful). Otherwise they
will be committed.
Here is the standard idiom for transactions:
db.beginTransactionWithListenerNonExclusive(listener);
try {
...
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
beginTransaction(transactionListener, false);
| private void | collectDbStats(java.util.ArrayList dbStatsList)
synchronized (mLock) {
if (mConnectionPoolLocked != null) {
mConnectionPoolLocked.collectDbStats(dbStatsList);
}
}
| public SQLiteStatement | compileStatement(java.lang.String sql)Compiles an SQL statement into a reusable pre-compiled statement object.
The parameters are identical to {@link #execSQL(String)}. You may put ?s in the
statement and fill in those values with {@link SQLiteProgram#bindString}
and {@link SQLiteProgram#bindLong} each time you want to run the
statement. Statements may not return result sets larger than 1x1.
No two threads should be using the same {@link SQLiteStatement} at the same time.
acquireReference();
try {
return new SQLiteStatement(this, sql, null);
} finally {
releaseReference();
}
| public static android.database.sqlite.SQLiteDatabase | create(android.database.sqlite.SQLiteDatabase$CursorFactory factory)Create a memory backed SQLite database. Its contents will be destroyed
when the database is closed.
Sets the locale of the database to the the system's current locale.
Call {@link #setLocale} if you would like something else.
// This is a magic string with special meaning for SQLite.
return openDatabase(SQLiteDatabaseConfiguration.MEMORY_DB_PATH,
factory, CREATE_IF_NECESSARY);
| SQLiteSession | createSession()
final SQLiteConnectionPool pool;
synchronized (mLock) {
throwIfNotOpenLocked();
pool = mConnectionPoolLocked;
}
return new SQLiteSession(pool);
| public int | delete(java.lang.String table, java.lang.String whereClause, java.lang.String[] whereArgs)Convenience method for deleting rows in the database.
acquireReference();
try {
SQLiteStatement statement = new SQLiteStatement(this, "DELETE FROM " + table +
(!TextUtils.isEmpty(whereClause) ? " WHERE " + whereClause : ""), whereArgs);
try {
return statement.executeUpdateDelete();
} finally {
statement.close();
}
} finally {
releaseReference();
}
| public static boolean | deleteDatabase(java.io.File file)Deletes a database including its journal file and other auxiliary files
that may have been created by the database engine.
if (file == null) {
throw new IllegalArgumentException("file must not be null");
}
boolean deleted = false;
deleted |= file.delete();
deleted |= new File(file.getPath() + "-journal").delete();
deleted |= new File(file.getPath() + "-shm").delete();
deleted |= new File(file.getPath() + "-wal").delete();
File dir = file.getParentFile();
if (dir != null) {
final String prefix = file.getName() + "-mj";
File[] files = dir.listFiles(new FileFilter() {
@Override
public boolean accept(File candidate) {
return candidate.getName().startsWith(prefix);
}
});
if (files != null) {
for (File masterJournal : files) {
deleted |= masterJournal.delete();
}
}
}
return deleted;
| public void | disableWriteAheadLogging()This method disables the features enabled by {@link #enableWriteAheadLogging()}.
synchronized (mLock) {
throwIfNotOpenLocked();
if ((mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) == 0) {
return;
}
mConfigurationLocked.openFlags &= ~ENABLE_WRITE_AHEAD_LOGGING;
try {
mConnectionPoolLocked.reconfigure(mConfigurationLocked);
} catch (RuntimeException ex) {
mConfigurationLocked.openFlags |= ENABLE_WRITE_AHEAD_LOGGING;
throw ex;
}
}
| private void | dispose(boolean finalized)
final SQLiteConnectionPool pool;
synchronized (mLock) {
if (mCloseGuardLocked != null) {
if (finalized) {
mCloseGuardLocked.warnIfOpen();
}
mCloseGuardLocked.close();
}
pool = mConnectionPoolLocked;
mConnectionPoolLocked = null;
}
if (!finalized) {
synchronized (sActiveDatabases) {
sActiveDatabases.remove(this);
}
if (pool != null) {
pool.close();
}
}
| private void | dump(android.util.Printer printer, boolean verbose)
synchronized (mLock) {
if (mConnectionPoolLocked != null) {
printer.println("");
mConnectionPoolLocked.dump(printer, verbose);
}
}
| static void | dumpAll(android.util.Printer printer, boolean verbose)Dump detailed information about all open databases in the current process.
Used by bug report.
for (SQLiteDatabase db : getActiveDatabases()) {
db.dump(printer, verbose);
}
| public boolean | enableWriteAheadLogging()This method enables parallel execution of queries from multiple threads on the
same database. It does this by opening multiple connections to the database
and using a different database connection for each query. The database
journal mode is also changed to enable writes to proceed concurrently with reads.
When write-ahead logging is not enabled (the default), it is not possible for
reads and writes to occur on the database at the same time. Before modifying the
database, the writer implicitly acquires an exclusive lock on the database which
prevents readers from accessing the database until the write is completed.
In contrast, when write-ahead logging is enabled (by calling this method), write
operations occur in a separate log file which allows reads to proceed concurrently.
While a write is in progress, readers on other threads will perceive the state
of the database as it was before the write began. When the write completes, readers
on other threads will then perceive the new state of the database.
It is a good idea to enable write-ahead logging whenever a database will be
concurrently accessed and modified by multiple threads at the same time.
However, write-ahead logging uses significantly more memory than ordinary
journaling because there are multiple connections to the same database.
So if a database will only be used by a single thread, or if optimizing
concurrency is not very important, then write-ahead logging should be disabled.
After calling this method, execution of queries in parallel is enabled as long as
the database remains open. To disable execution of queries in parallel, either
call {@link #disableWriteAheadLogging} or close the database and reopen it.
The maximum number of connections used to execute queries in parallel is
dependent upon the device memory and possibly other properties.
If a query is part of a transaction, then it is executed on the same database handle the
transaction was begun.
Writers should use {@link #beginTransactionNonExclusive()} or
{@link #beginTransactionWithListenerNonExclusive(SQLiteTransactionListener)}
to start a transaction. Non-exclusive mode allows database file to be in readable
by other threads executing queries.
If the database has any attached databases, then execution of queries in parallel is NOT
possible. Likewise, write-ahead logging is not supported for read-only databases
or memory databases. In such cases, {@link #enableWriteAheadLogging} returns false.
The best way to enable write-ahead logging is to pass the
{@link #ENABLE_WRITE_AHEAD_LOGGING} flag to {@link #openDatabase}. This is
more efficient than calling {@link #enableWriteAheadLogging}.
SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory,
SQLiteDatabase.CREATE_IF_NECESSARY | SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING,
myDatabaseErrorHandler);
db.enableWriteAheadLogging();
Another way to enable write-ahead logging is to call {@link #enableWriteAheadLogging}
after opening the database.
SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory,
SQLiteDatabase.CREATE_IF_NECESSARY, myDatabaseErrorHandler);
db.enableWriteAheadLogging();
See also SQLite Write-Ahead Logging for
more details about how write-ahead logging works.
synchronized (mLock) {
throwIfNotOpenLocked();
if ((mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) != 0) {
return true;
}
if (isReadOnlyLocked()) {
// WAL doesn't make sense for readonly-databases.
// TODO: True, but connection pooling does still make sense...
return false;
}
if (mConfigurationLocked.isInMemoryDb()) {
Log.i(TAG, "can't enable WAL for memory databases.");
return false;
}
// make sure this database has NO attached databases because sqlite's write-ahead-logging
// doesn't work for databases with attached databases
if (mHasAttachedDbsLocked) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "this database: " + mConfigurationLocked.label
+ " has attached databases. can't enable WAL.");
}
return false;
}
mConfigurationLocked.openFlags |= ENABLE_WRITE_AHEAD_LOGGING;
try {
mConnectionPoolLocked.reconfigure(mConfigurationLocked);
} catch (RuntimeException ex) {
mConfigurationLocked.openFlags &= ~ENABLE_WRITE_AHEAD_LOGGING;
throw ex;
}
}
return true;
| public void | endTransaction()End a transaction. See beginTransaction for notes about how to use this and when transactions
are committed and rolled back.
acquireReference();
try {
getThreadSession().endTransaction(null);
} finally {
releaseReference();
}
| public void | execSQL(java.lang.String sql)Execute a single SQL statement that is NOT a SELECT
or any other SQL statement that returns data.
It has no means to return any data (such as the number of affected rows).
Instead, you're encouraged to use {@link #insert(String, String, ContentValues)},
{@link #update(String, ContentValues, String, String[])}, et al, when possible.
When using {@link #enableWriteAheadLogging()}, journal_mode is
automatically managed by this class. So, do not set journal_mode
using "PRAGMA journal_mode'" statement if your app is using
{@link #enableWriteAheadLogging()}
executeSql(sql, null);
| public void | execSQL(java.lang.String sql, java.lang.Object[] bindArgs)Execute a single SQL statement that is NOT a SELECT/INSERT/UPDATE/DELETE.
For INSERT statements, use any of the following instead.
- {@link #insert(String, String, ContentValues)}
- {@link #insertOrThrow(String, String, ContentValues)}
- {@link #insertWithOnConflict(String, String, ContentValues, int)}
For UPDATE statements, use any of the following instead.
- {@link #update(String, ContentValues, String, String[])}
- {@link #updateWithOnConflict(String, ContentValues, String, String[], int)}
For DELETE statements, use any of the following instead.
- {@link #delete(String, String, String[])}
For example, the following are good candidates for using this method:
- ALTER TABLE
- CREATE or DROP table / trigger / view / index / virtual table
- REINDEX
- RELEASE
- SAVEPOINT
- PRAGMA that returns no data
When using {@link #enableWriteAheadLogging()}, journal_mode is
automatically managed by this class. So, do not set journal_mode
using "PRAGMA journal_mode'" statement if your app is using
{@link #enableWriteAheadLogging()}
if (bindArgs == null) {
throw new IllegalArgumentException("Empty bindArgs");
}
executeSql(sql, bindArgs);
| private int | executeSql(java.lang.String sql, java.lang.Object[] bindArgs)
acquireReference();
try {
if (DatabaseUtils.getSqlStatementType(sql) == DatabaseUtils.STATEMENT_ATTACH) {
boolean disableWal = false;
synchronized (mLock) {
if (!mHasAttachedDbsLocked) {
mHasAttachedDbsLocked = true;
disableWal = true;
}
}
if (disableWal) {
disableWriteAheadLogging();
}
}
SQLiteStatement statement = new SQLiteStatement(this, sql, bindArgs);
try {
return statement.executeUpdateDelete();
} finally {
statement.close();
}
} finally {
releaseReference();
}
| protected void | finalize()
try {
dispose(true);
} finally {
super.finalize();
}
| public static java.lang.String | findEditTable(java.lang.String tables)Finds the name of the first table, which is editable.
if (!TextUtils.isEmpty(tables)) {
// find the first word terminated by either a space or a comma
int spacepos = tables.indexOf(' ");
int commapos = tables.indexOf(',");
if (spacepos > 0 && (spacepos < commapos || commapos < 0)) {
return tables.substring(0, spacepos);
} else if (commapos > 0 && (commapos < spacepos || spacepos < 0) ) {
return tables.substring(0, commapos);
}
return tables;
} else {
throw new IllegalStateException("Invalid tables");
}
| private static java.util.ArrayList | getActiveDatabases()
ArrayList<SQLiteDatabase> databases = new ArrayList<SQLiteDatabase>();
synchronized (sActiveDatabases) {
databases.addAll(sActiveDatabases.keySet());
}
return databases;
| public java.util.List | getAttachedDbs()Returns list of full pathnames of all attached databases including the main database
by executing 'pragma database_list' on the database.
ArrayList<Pair<String, String>> attachedDbs = new ArrayList<Pair<String, String>>();
synchronized (mLock) {
if (mConnectionPoolLocked == null) {
return null; // not open
}
if (!mHasAttachedDbsLocked) {
// No attached databases.
// There is a small window where attached databases exist but this flag is not
// set yet. This can occur when this thread is in a race condition with another
// thread that is executing the SQL statement: "attach database <blah> as <foo>"
// If this thread is NOT ok with such a race condition (and thus possibly not
// receivethe entire list of attached databases), then the caller should ensure
// that no thread is executing any SQL statements while a thread is calling this
// method. Typically, this method is called when 'adb bugreport' is done or the
// caller wants to collect stats on the database and all its attached databases.
attachedDbs.add(new Pair<String, String>("main", mConfigurationLocked.path));
return attachedDbs;
}
acquireReference();
}
try {
// 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 {
releaseReference();
}
| static java.util.ArrayList | getDbStats()Collect statistics about all open databases in the current process.
Used by bug report.
ArrayList<DbStats> dbStatsList = new ArrayList<DbStats>();
for (SQLiteDatabase db : getActiveDatabases()) {
db.collectDbStats(dbStatsList);
}
return dbStatsList;
| java.lang.String | getLabel()Gets a label to use when describing the database in log messages.
synchronized (mLock) {
return mConfigurationLocked.label;
}
| public long | getMaximumSize()Returns the maximum size the database may grow to.
long pageCount = DatabaseUtils.longForQuery(this, "PRAGMA max_page_count;", null);
return pageCount * getPageSize();
| public long | getPageSize()Returns the current database page size, in bytes.
return DatabaseUtils.longForQuery(this, "PRAGMA page_size;", null);
| public final java.lang.String | getPath()Gets the path to the database file.
synchronized (mLock) {
return mConfigurationLocked.path;
}
| public java.util.Map | getSyncedTables()Deprecated.
return new HashMap<String, String>(0);
| int | getThreadDefaultConnectionFlags(boolean readOnly)Gets default connection flags that are appropriate for this thread, taking into
account whether the thread is acting on behalf of the UI.
int flags = readOnly ? SQLiteConnectionPool.CONNECTION_FLAG_READ_ONLY :
SQLiteConnectionPool.CONNECTION_FLAG_PRIMARY_CONNECTION_AFFINITY;
if (isMainThread()) {
flags |= SQLiteConnectionPool.CONNECTION_FLAG_INTERACTIVE;
}
return flags;
| SQLiteSession | getThreadSession()Gets the {@link SQLiteSession} that belongs to this thread for this database.
Once a thread has obtained a session, it will continue to obtain the same
session even after the database has been closed (although the session will not
be usable). However, a thread that does not already have a session cannot
obtain one after the database has been closed.
The idea is that threads that have active connections to the database may still
have work to complete even after the call to {@link #close}. Active database
connections are not actually disposed until they are released by the threads
that own them.
return mThreadSession.get(); // initialValue() throws if database closed
| public int | getVersion()Gets the database version.
return ((Long) DatabaseUtils.longForQuery(this, "PRAGMA user_version;", null)).intValue();
| public boolean | inTransaction()Returns true if the current thread has a transaction pending.
acquireReference();
try {
return getThreadSession().hasTransaction();
} finally {
releaseReference();
}
| public long | insert(java.lang.String table, java.lang.String nullColumnHack, android.content.ContentValues values)Convenience method for inserting a row into the database.
try {
return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE);
} catch (SQLException e) {
Log.e(TAG, "Error inserting " + values, e);
return -1;
}
| public long | insertOrThrow(java.lang.String table, java.lang.String nullColumnHack, android.content.ContentValues values)Convenience method for inserting a row into the database.
return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE);
| public long | insertWithOnConflict(java.lang.String table, java.lang.String nullColumnHack, android.content.ContentValues initialValues, int conflictAlgorithm)General method for inserting a row into the database.
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(')");
SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs);
try {
return statement.executeInsert();
} finally {
statement.close();
}
} finally {
releaseReference();
}
| public boolean | isDatabaseIntegrityOk()Runs 'pragma integrity_check' on the given database (and all the attached databases)
and returns true if the given database (and all its attached databases) pass integrity_check,
false otherwise.
If the result is false, then this method logs the errors reported by the integrity_check
command execution.
Note that 'pragma integrity_check' on a database can take a long time.
acquireReference();
try {
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()));
}
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 {
releaseReference();
}
return true;
| public boolean | isDbLockedByCurrentThread()Returns true if the current thread is holding an active connection to the database.
The name of this method comes from a time when having an active connection
to the database meant that the thread was holding an actual lock on the
database. Nowadays, there is no longer a true "database lock" although threads
may block if they cannot acquire a database connection to perform a
particular operation.
acquireReference();
try {
return getThreadSession().hasConnection();
} finally {
releaseReference();
}
| public boolean | isDbLockedByOtherThreads()Always returns false.
There is no longer the concept of a database lock, so this method always returns false.
return false;
| public boolean | isInMemoryDatabase()Returns true if the database is in-memory db.
synchronized (mLock) {
return mConfigurationLocked.isInMemoryDb();
}
| private static boolean | isMainThread()
// FIXME: There should be a better way to do this.
// Would also be nice to have something that would work across Binder calls.
Looper looper = Looper.myLooper();
return looper != null && looper == Looper.getMainLooper();
| public boolean | isOpen()Returns true if the database is currently open.
synchronized (mLock) {
return mConnectionPoolLocked != null;
}
| public boolean | isReadOnly()Returns true if the database is opened as read only.
synchronized (mLock) {
return isReadOnlyLocked();
}
| private boolean | isReadOnlyLocked()
return (mConfigurationLocked.openFlags & OPEN_READ_MASK) == OPEN_READONLY;
| public boolean | isWriteAheadLoggingEnabled()Returns true if write-ahead logging has been enabled for this database.
synchronized (mLock) {
throwIfNotOpenLocked();
return (mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) != 0;
}
| public void | markTableSyncable(java.lang.String table, java.lang.String deletedTable)Mark this table as syncable. When an update occurs in this table the
_sync_dirty field will be set to ensure proper syncing operation.
| public void | markTableSyncable(java.lang.String table, java.lang.String foreignKey, java.lang.String updateTable)Mark this table as syncable, with the _sync_dirty residing in another
table. When an update occurs in this table the _sync_dirty field of the
row in updateTable with the _id in foreignKey will be set to
ensure proper syncing operation.
| public boolean | needUpgrade(int newVersion)Returns true if the new version code is greater than the current database version.
return newVersion > getVersion();
| protected void | onAllReferencesReleased()
dispose(false);
| void | onCorruption()Sends a corruption message to the database error handler.
EventLog.writeEvent(EVENT_DB_CORRUPT, getLabel());
mErrorHandler.onCorruption(this);
| private void | open()
try {
try {
openInner();
} catch (SQLiteDatabaseCorruptException ex) {
onCorruption();
openInner();
}
} catch (SQLiteException ex) {
Log.e(TAG, "Failed to open database '" + getLabel() + "'.", ex);
close();
throw ex;
}
| public static android.database.sqlite.SQLiteDatabase | openDatabase(java.lang.String path, android.database.sqlite.SQLiteDatabase$CursorFactory factory, int flags)Open the database according to the flags {@link #OPEN_READWRITE}
{@link #OPEN_READONLY} {@link #CREATE_IF_NECESSARY} and/or {@link #NO_LOCALIZED_COLLATORS}.
Sets the locale of the database to the the system's current locale.
Call {@link #setLocale} if you would like something else.
return openDatabase(path, factory, flags, null);
| public static android.database.sqlite.SQLiteDatabase | openDatabase(java.lang.String path, android.database.sqlite.SQLiteDatabase$CursorFactory factory, int flags, android.database.DatabaseErrorHandler errorHandler)Open the database according to the flags {@link #OPEN_READWRITE}
{@link #OPEN_READONLY} {@link #CREATE_IF_NECESSARY} and/or {@link #NO_LOCALIZED_COLLATORS}.
Sets the locale of the database to the the system's current locale.
Call {@link #setLocale} if you would like something else.
Accepts input param: a concrete instance of {@link DatabaseErrorHandler} to be
used to handle corruption when sqlite reports database corruption.
SQLiteDatabase db = new SQLiteDatabase(path, flags, factory, errorHandler);
db.open();
return db;
| private void | openInner()
synchronized (mLock) {
assert mConnectionPoolLocked == null;
mConnectionPoolLocked = SQLiteConnectionPool.open(mConfigurationLocked);
mCloseGuardLocked.open("close");
}
synchronized (sActiveDatabases) {
sActiveDatabases.put(this, null);
}
| public static android.database.sqlite.SQLiteDatabase | openOrCreateDatabase(java.io.File file, android.database.sqlite.SQLiteDatabase$CursorFactory factory)Equivalent to openDatabase(file.getPath(), factory, CREATE_IF_NECESSARY).
return openOrCreateDatabase(file.getPath(), factory);
| public static android.database.sqlite.SQLiteDatabase | openOrCreateDatabase(java.lang.String path, android.database.sqlite.SQLiteDatabase$CursorFactory factory)Equivalent to openDatabase(path, factory, CREATE_IF_NECESSARY).
return openDatabase(path, factory, CREATE_IF_NECESSARY, null);
| public static android.database.sqlite.SQLiteDatabase | openOrCreateDatabase(java.lang.String path, android.database.sqlite.SQLiteDatabase$CursorFactory factory, android.database.DatabaseErrorHandler errorHandler)Equivalent to openDatabase(path, factory, CREATE_IF_NECESSARY, errorHandler).
return openDatabase(path, factory, CREATE_IF_NECESSARY, errorHandler);
| public android.database.Cursor | query(boolean distinct, java.lang.String table, java.lang.String[] columns, java.lang.String selection, java.lang.String[] selectionArgs, java.lang.String groupBy, java.lang.String having, java.lang.String orderBy, java.lang.String limit)Query the given URL, returning a {@link Cursor} over the result set.
return queryWithFactory(null, distinct, table, columns, selection, selectionArgs,
groupBy, having, orderBy, limit, null);
| public android.database.Cursor | query(boolean distinct, java.lang.String table, java.lang.String[] columns, java.lang.String selection, java.lang.String[] selectionArgs, java.lang.String groupBy, java.lang.String having, java.lang.String orderBy, java.lang.String limit, android.os.CancellationSignal cancellationSignal)Query the given URL, returning a {@link Cursor} over the result set.
return queryWithFactory(null, distinct, table, columns, selection, selectionArgs,
groupBy, having, orderBy, limit, cancellationSignal);
| public android.database.Cursor | query(java.lang.String table, java.lang.String[] columns, java.lang.String selection, java.lang.String[] selectionArgs, java.lang.String groupBy, java.lang.String having, java.lang.String orderBy)Query the given table, returning a {@link Cursor} over the result set.
return query(false, table, columns, selection, selectionArgs, groupBy,
having, orderBy, null /* limit */);
| public android.database.Cursor | query(java.lang.String table, java.lang.String[] columns, java.lang.String selection, java.lang.String[] selectionArgs, java.lang.String groupBy, java.lang.String having, java.lang.String orderBy, java.lang.String limit)Query the given table, returning a {@link Cursor} over the result set.
return query(false, table, columns, selection, selectionArgs, groupBy,
having, orderBy, limit);
| public android.database.Cursor | queryWithFactory(android.database.sqlite.SQLiteDatabase$CursorFactory cursorFactory, boolean distinct, java.lang.String table, java.lang.String[] columns, java.lang.String selection, java.lang.String[] selectionArgs, java.lang.String groupBy, java.lang.String having, java.lang.String orderBy, java.lang.String limit)Query the given URL, returning a {@link Cursor} over the result set.
return queryWithFactory(cursorFactory, distinct, table, columns, selection,
selectionArgs, groupBy, having, orderBy, limit, null);
| public android.database.Cursor | queryWithFactory(android.database.sqlite.SQLiteDatabase$CursorFactory cursorFactory, boolean distinct, java.lang.String table, java.lang.String[] columns, java.lang.String selection, java.lang.String[] selectionArgs, java.lang.String groupBy, java.lang.String having, java.lang.String orderBy, java.lang.String limit, android.os.CancellationSignal cancellationSignal)Query the given URL, returning a {@link Cursor} over the result set.
acquireReference();
try {
String sql = SQLiteQueryBuilder.buildQueryString(
distinct, table, columns, selection, groupBy, having, orderBy, limit);
return rawQueryWithFactory(cursorFactory, sql, selectionArgs,
findEditTable(table), cancellationSignal);
} finally {
releaseReference();
}
| public android.database.Cursor | rawQuery(java.lang.String sql, java.lang.String[] selectionArgs)Runs the provided SQL and returns a {@link Cursor} over the result set.
return rawQueryWithFactory(null, sql, selectionArgs, null, null);
| public android.database.Cursor | rawQuery(java.lang.String sql, java.lang.String[] selectionArgs, android.os.CancellationSignal cancellationSignal)Runs the provided SQL and returns a {@link Cursor} over the result set.
return rawQueryWithFactory(null, sql, selectionArgs, null, cancellationSignal);
| public android.database.Cursor | rawQueryWithFactory(android.database.sqlite.SQLiteDatabase$CursorFactory cursorFactory, java.lang.String sql, java.lang.String[] selectionArgs, java.lang.String editTable)Runs the provided SQL and returns a cursor over the result set.
return rawQueryWithFactory(cursorFactory, sql, selectionArgs, editTable, null);
| public android.database.Cursor | rawQueryWithFactory(android.database.sqlite.SQLiteDatabase$CursorFactory cursorFactory, java.lang.String sql, java.lang.String[] selectionArgs, java.lang.String editTable, android.os.CancellationSignal cancellationSignal)Runs the provided SQL and returns a cursor over the result set.
acquireReference();
try {
SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(this, sql, editTable,
cancellationSignal);
return driver.query(cursorFactory != null ? cursorFactory : mCursorFactory,
selectionArgs);
} finally {
releaseReference();
}
| public static int | releaseMemory()Attempts to release memory that SQLite holds but does not require to
operate properly. Typically this memory will come from the page cache.
return SQLiteGlobal.releaseMemory();
| public void | reopenReadWrite()Reopens the database in read-write mode.
If the database is already read-write, does nothing.
synchronized (mLock) {
throwIfNotOpenLocked();
if (!isReadOnlyLocked()) {
return; // nothing to do
}
// Reopen the database in read-write mode.
final int oldOpenFlags = mConfigurationLocked.openFlags;
mConfigurationLocked.openFlags = (mConfigurationLocked.openFlags & ~OPEN_READ_MASK)
| OPEN_READWRITE;
try {
mConnectionPoolLocked.reconfigure(mConfigurationLocked);
} catch (RuntimeException ex) {
mConfigurationLocked.openFlags = oldOpenFlags;
throw ex;
}
}
| public long | replace(java.lang.String table, java.lang.String nullColumnHack, android.content.ContentValues initialValues)Convenience method for replacing a row in the database.
try {
return insertWithOnConflict(table, nullColumnHack, initialValues,
CONFLICT_REPLACE);
} catch (SQLException e) {
Log.e(TAG, "Error inserting " + initialValues, e);
return -1;
}
| public long | replaceOrThrow(java.lang.String table, java.lang.String nullColumnHack, android.content.ContentValues initialValues)Convenience method for replacing a row in the database.
return insertWithOnConflict(table, nullColumnHack, initialValues,
CONFLICT_REPLACE);
| public void | setForeignKeyConstraintsEnabled(boolean enable)Sets whether foreign key constraints are enabled for the database.
By default, foreign key constraints are not enforced by the database.
This method allows an application to enable foreign key constraints.
It must be called each time the database is opened to ensure that foreign
key constraints are enabled for the session.
A good time to call this method is right after calling {@link #openOrCreateDatabase}
or in the {@link SQLiteOpenHelper#onConfigure} callback.
When foreign key constraints are disabled, the database does not check whether
changes to the database will violate foreign key constraints. Likewise, when
foreign key constraints are disabled, the database will not execute cascade
delete or update triggers. As a result, it is possible for the database
state to become inconsistent. To perform a database integrity check,
call {@link #isDatabaseIntegrityOk}.
This method must not be called while a transaction is in progress.
See also SQLite Foreign Key Constraints
for more details about foreign key constraint support.
synchronized (mLock) {
throwIfNotOpenLocked();
if (mConfigurationLocked.foreignKeyConstraintsEnabled == enable) {
return;
}
mConfigurationLocked.foreignKeyConstraintsEnabled = enable;
try {
mConnectionPoolLocked.reconfigure(mConfigurationLocked);
} catch (RuntimeException ex) {
mConfigurationLocked.foreignKeyConstraintsEnabled = !enable;
throw ex;
}
}
| public void | setLocale(java.util.Locale locale)Sets the locale for this database. Does nothing if this database has
the {@link #NO_LOCALIZED_COLLATORS} flag set or was opened read only.
if (locale == null) {
throw new IllegalArgumentException("locale must not be null.");
}
synchronized (mLock) {
throwIfNotOpenLocked();
final Locale oldLocale = mConfigurationLocked.locale;
mConfigurationLocked.locale = locale;
try {
mConnectionPoolLocked.reconfigure(mConfigurationLocked);
} catch (RuntimeException ex) {
mConfigurationLocked.locale = oldLocale;
throw ex;
}
}
| public void | setLockingEnabled(boolean lockingEnabled)Control whether or not the SQLiteDatabase is made thread-safe by using locks
around critical sections. This is pretty expensive, so if you know that your
DB will only be used by a single thread then you should set this to false.
The default is true.
| public void | setMaxSqlCacheSize(int cacheSize)Sets the maximum size of the prepared-statement cache for this database.
(size of the cache = number of compiled-sql-statements stored in the cache).
Maximum cache size can ONLY be increased from its current size (default = 10).
If this method is called with smaller size than the current maximum value,
then IllegalStateException is thrown.
This method is thread-safe.
if (cacheSize > MAX_SQL_CACHE_SIZE || cacheSize < 0) {
throw new IllegalStateException(
"expected value between 0 and " + MAX_SQL_CACHE_SIZE);
}
synchronized (mLock) {
throwIfNotOpenLocked();
final int oldMaxSqlCacheSize = mConfigurationLocked.maxSqlCacheSize;
mConfigurationLocked.maxSqlCacheSize = cacheSize;
try {
mConnectionPoolLocked.reconfigure(mConfigurationLocked);
} catch (RuntimeException ex) {
mConfigurationLocked.maxSqlCacheSize = oldMaxSqlCacheSize;
throw ex;
}
}
| public long | setMaximumSize(long numBytes)Sets the maximum size the database will grow to. The maximum size cannot
be set below the current size.
long pageSize = getPageSize();
long numPages = numBytes / pageSize;
// If numBytes isn't a multiple of pageSize, bump up a page
if ((numBytes % pageSize) != 0) {
numPages++;
}
long newPageCount = DatabaseUtils.longForQuery(this, "PRAGMA max_page_count = " + numPages,
null);
return newPageCount * pageSize;
| public void | setPageSize(long numBytes)Sets the database page size. The page size must be a power of two. This
method does not work if any data has been written to the database file,
and must be called right after the database has been created.
execSQL("PRAGMA page_size = " + numBytes);
| public void | setTransactionSuccessful()Marks the current transaction as successful. Do not do any more database work between
calling this and calling endTransaction. Do as little non-database work as possible in that
situation too. If any errors are encountered between this and endTransaction the transaction
will still be committed.
acquireReference();
try {
getThreadSession().setTransactionSuccessful();
} finally {
releaseReference();
}
| public void | setVersion(int version)Sets the database version.
execSQL("PRAGMA user_version = " + version);
| private void | throwIfNotOpenLocked()
if (mConnectionPoolLocked == null) {
throw new IllegalStateException("The database '" + mConfigurationLocked.label
+ "' is not open.");
}
| public java.lang.String | toString()
return "SQLiteDatabase: " + getPath();
| public int | update(java.lang.String table, android.content.ContentValues values, java.lang.String whereClause, java.lang.String[] whereArgs)Convenience method for updating rows in the database.
return updateWithOnConflict(table, values, whereClause, whereArgs, CONFLICT_NONE);
| public int | updateWithOnConflict(java.lang.String table, android.content.ContentValues values, java.lang.String whereClause, java.lang.String[] whereArgs, int conflictAlgorithm)Convenience method for updating rows in the database.
if (values == null || values.size() == 0) {
throw new IllegalArgumentException("Empty values");
}
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);
}
SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs);
try {
return statement.executeUpdateDelete();
} finally {
statement.close();
}
} finally {
releaseReference();
}
| public boolean | yieldIfContended()Temporarily end the transaction to let other threads run. The transaction is assumed to be
successful so far. Do not call setTransactionSuccessful before calling this. When this
returns a new transaction will have been created but not marked as successful.
return yieldIfContendedHelper(false /* do not check yielding */,
-1 /* sleepAfterYieldDelay */);
| private boolean | yieldIfContendedHelper(boolean throwIfUnsafe, long sleepAfterYieldDelay)
acquireReference();
try {
return getThreadSession().yieldTransaction(sleepAfterYieldDelay, throwIfUnsafe, null);
} finally {
releaseReference();
}
| public boolean | yieldIfContendedSafely()Temporarily end the transaction to let other threads run. The transaction is assumed to be
successful so far. Do not call setTransactionSuccessful before calling this. When this
returns a new transaction will have been created but not marked as successful. This assumes
that there are no nested transactions (beginTransaction has only been called once) and will
throw an exception if that is not the case.
return yieldIfContendedHelper(true /* check yielding */, -1 /* sleepAfterYieldDelay*/);
| public boolean | yieldIfContendedSafely(long sleepAfterYieldDelay)Temporarily end the transaction to let other threads run. The transaction is assumed to be
successful so far. Do not call setTransactionSuccessful before calling this. When this
returns a new transaction will have been created but not marked as successful. This assumes
that there are no nested transactions (beginTransaction has only been called once) and will
throw an exception if that is not the case.
return yieldIfContendedHelper(true /* check yielding */, sleepAfterYieldDelay);
|
|