/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.database.sqlite;

import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.DatabaseErrorHandler;
import android.database.DatabaseUtils;
import android.database.DefaultDatabaseErrorHandler;
import android.database.SQLException;
import android.database.sqlite.SQLiteDebug.DbStats;
import android.os.CancellationSignal;
import android.os.Looper;
import android.os.OperationCanceledException;
import android.os.SystemProperties;
import android.text.TextUtils;
import android.util.EventLog;
import android.util.Log;
import android.util.Pair;
import android.util.Printer;

import com.android.internal.util.Preconditions;

import dalvik.system.CloseGuard;

import java.io.File;
import java.io.FileFilter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.WeakHashMap;

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.

/** * Exposes methods to manage a SQLite database. * * <p> * SQLiteDatabase has methods to create, delete, execute SQL commands, and * perform other common database management tasks. * </p><p> * See the Notepad sample application in the SDK for an example of creating * and managing a database. * </p><p> * Database names must be unique within an application, not across all applications. * </p> * * <h3>Localized Collation - ORDER BY</h3> * <p> * In addition to SQLite's default <code>BINARY</code> collator, Android supplies * two more, <code>LOCALIZED</code>, which changes with the system's current locale, * and <code>UNICODE</code>, which is the Unicode Collation Algorithm and not tailored * to the current locale. * </p> */
public final class SQLiteDatabase extends SQLiteClosable { private static final String TAG = "SQLiteDatabase"; private static final int EVENT_DB_CORRUPT = 75004; // By default idle connections are not closed private static final boolean DEBUG_CLOSE_IDLE_CONNECTIONS = SystemProperties .getBoolean("persist.debug.sqlite.close_idle_connections", false); // Stores reference to all databases opened in the current process. // (The referent Object is not used at this time.) // INVARIANT: Guarded by sActiveDatabases. private static WeakHashMap<SQLiteDatabase, Object> sActiveDatabases = new WeakHashMap<>(); // Thread-local for database sessions that belong to this database. // Each thread has its own database session. // INVARIANT: Immutable. private final ThreadLocal<SQLiteSession> mThreadSession = ThreadLocal .withInitial(this::createSession); // The optional factory to use when creating new Cursors. May be null. // INVARIANT: Immutable. private final CursorFactory mCursorFactory; // Error handler to be used when SQLite returns corruption errors. // INVARIANT: Immutable. private final DatabaseErrorHandler mErrorHandler; // Shared database state lock. // This lock guards all of the shared state of the database, such as its // configuration, whether it is open or closed, and so on. This lock should // be held for as little time as possible. // // The lock MUST NOT be held while attempting to acquire database connections or // while executing SQL statements on behalf of the client as it can lead to deadlock. // // It is ok to hold the lock while reconfiguring the connection pool or dumping // statistics because those operations are non-reentrant and do not try to acquire // connections that might be held by other threads. // // Basic rule: grab the lock, access or modify global state, release the lock, then // do the required SQL work. private final Object mLock = new Object(); // Warns if the database is finalized without being closed properly. // INVARIANT: Guarded by mLock. private final CloseGuard mCloseGuardLocked = CloseGuard.get(); // The database configuration. // INVARIANT: Guarded by mLock. private final SQLiteDatabaseConfiguration mConfigurationLocked; // The connection pool for the database, null when closed. // The pool itself is thread-safe, but the reference to it can only be acquired // when the lock is held. // INVARIANT: Guarded by mLock. private SQLiteConnectionPool mConnectionPoolLocked; // True if the database has attached databases. // INVARIANT: Guarded by mLock. private boolean mHasAttachedDbsLocked;
When 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.
/** * When 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_ROLLBACK = 1;
When a constraint violation occurs,no ROLLBACK is executed so changes from prior commands within the same transaction are preserved. This is the default behavior.
/** * When 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_ABORT = 2;
When 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.
/** * When 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_FAIL = 3;
When 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.
/** * When 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_IGNORE = 4;
When 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.
/** * When 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_REPLACE = 5;
Use the following when no conflict action is specified.
/** * Use the following when no conflict action is specified. */
public static final int CONFLICT_NONE = 0; private static final String[] CONFLICT_VALUES = new String[] {"", " OR ROLLBACK ", " OR ABORT ", " OR FAIL ", " OR IGNORE ", " OR REPLACE "};
Maximum 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.
/** * Maximum 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 SQLITE_MAX_LIKE_PATTERN_LENGTH = 50000;
Open flag: Flag for 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.
/** * Open 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_READWRITE = 0x00000000; // update native code if changing
Open flag: Flag for openDatabase to open the database for reading only. This is the only reliable way to open a database if the disk may be full.
/** * Open 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. */
public static final int OPEN_READONLY = 0x00000001; // update native code if changing private static final int OPEN_READ_MASK = 0x00000001; // update native code if changing
Open flag: Flag for 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, setLocale will do nothing.
/** * Open flag: Flag for {@link #openDatabase} to open the database without support for * localized collators. * * {@more} This causes the collator <code>LOCALIZED</code> 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 NO_LOCALIZED_COLLATORS = 0x00000010; // update native code if changing
Open flag: Flag for openDatabase to create the database file if it does not already exist.
/** * Open flag: Flag for {@link #openDatabase} to create the database file if it does not * already exist. */
public static final int CREATE_IF_NECESSARY = 0x10000000; // update native code if changing
Open flag: Flag for openDatabase to open the database file with write-ahead logging enabled by default. Using this flag is more efficient than calling 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.
See Also:
/** * Open 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. * * @see #enableWriteAheadLogging */
public static final int ENABLE_WRITE_AHEAD_LOGGING = 0x20000000;
Open flag: Flag for openDatabase to disable Compatibility WAL when opening database.
@hide
/** * Open flag: Flag for {@link #openDatabase} to disable Compatibility WAL when opening database. * * @hide */
public static final int DISABLE_COMPATIBILITY_WAL = 0x40000000;
Absolute max value that can be set by 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.
/** * Absolute 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. */
public static final int MAX_SQL_CACHE_SIZE = 100; private SQLiteDatabase(final String path, final int openFlags, CursorFactory cursorFactory, DatabaseErrorHandler errorHandler, int lookasideSlotSize, int lookasideSlotCount, long idleConnectionTimeoutMs, String journalMode, String syncMode) { mCursorFactory = cursorFactory; mErrorHandler = errorHandler != null ? errorHandler : new DefaultDatabaseErrorHandler(); mConfigurationLocked = new SQLiteDatabaseConfiguration(path, openFlags); mConfigurationLocked.lookasideSlotSize = lookasideSlotSize; mConfigurationLocked.lookasideSlotCount = lookasideSlotCount; // Disable lookaside allocator on low-RAM devices if (ActivityManager.isLowRamDeviceStatic()) { mConfigurationLocked.lookasideSlotCount = 0; mConfigurationLocked.lookasideSlotSize = 0; } long effectiveTimeoutMs = Long.MAX_VALUE; // Never close idle connections for in-memory databases if (!mConfigurationLocked.isInMemoryDb()) { // First, check app-specific value. Otherwise use defaults // -1 in idleConnectionTimeoutMs indicates unset value if (idleConnectionTimeoutMs >= 0) { effectiveTimeoutMs = idleConnectionTimeoutMs; } else if (DEBUG_CLOSE_IDLE_CONNECTIONS) { effectiveTimeoutMs = SQLiteGlobal.getIdleConnectionTimeout(); } } mConfigurationLocked.idleConnectionTimeoutMs = effectiveTimeoutMs; mConfigurationLocked.journalMode = journalMode; mConfigurationLocked.syncMode = syncMode; if (!SQLiteGlobal.isCompatibilityWalSupported() || ( SQLiteCompatibilityWalFlags.areFlagsSet() && !SQLiteCompatibilityWalFlags .isCompatibilityWalSupported())) { mConfigurationLocked.openFlags |= DISABLE_COMPATIBILITY_WAL; } } @Override protected void finalize() throws Throwable { try { dispose(true); } finally { super.finalize(); } } @Override protected void onAllReferencesReleased() { dispose(false); } 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(); } } }
Attempts to release memory that SQLite holds but does not require to operate properly. Typically this memory will come from the page cache.
Returns:the number of bytes actually released
/** * Attempts to release memory that SQLite holds but does not require to * operate properly. Typically this memory will come from the page cache. * * @return the number of bytes actually released */
public static int releaseMemory() { return SQLiteGlobal.releaseMemory(); }
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.
Params:
  • lockingEnabled – set to true to enable locks, false otherwise
Deprecated:This method now does nothing. Do not use.
/** * 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. * @param lockingEnabled set to true to enable locks, false otherwise * * @deprecated This method now does nothing. Do not use. */
@Deprecated public void setLockingEnabled(boolean lockingEnabled) { }
Gets a label to use when describing the database in log messages.
Returns:The label.
/** * Gets a label to use when describing the database in log messages. * @return The label. */
String getLabel() { synchronized (mLock) { return mConfigurationLocked.label; } }
Sends a corruption message to the database error handler.
/** * Sends a corruption message to the database error handler. */
void onCorruption() { EventLog.writeEvent(EVENT_DB_CORRUPT, getLabel()); mErrorHandler.onCorruption(this); }
Gets the 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 SQLiteClosable.close. Active database connections are not actually disposed until they are released by the threads that own them.
Throws:
Returns:The session, never null.
/** * 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 The session, never null. * * @throws IllegalStateException if the thread does not yet have a session and * the database is not open. */
SQLiteSession getThreadSession() { return mThreadSession.get(); // initialValue() throws if database closed } SQLiteSession createSession() { final SQLiteConnectionPool pool; synchronized (mLock) { throwIfNotOpenLocked(); pool = mConnectionPoolLocked; } return new SQLiteSession(pool); }
Gets default connection flags that are appropriate for this thread, taking into account whether the thread is acting on behalf of the UI.
Params:
  • readOnly – True if the connection should be read-only.
Returns:The connection flags.
/** * Gets default connection flags that are appropriate for this thread, taking into * account whether the thread is acting on behalf of the UI. * * @param readOnly True if the connection should be read-only. * @return The connection flags. */
int getThreadDefaultConnectionFlags(boolean readOnly) { int flags = readOnly ? SQLiteConnectionPool.CONNECTION_FLAG_READ_ONLY : SQLiteConnectionPool.CONNECTION_FLAG_PRIMARY_CONNECTION_AFFINITY; if (isMainThread()) { flags |= SQLiteConnectionPool.CONNECTION_FLAG_INTERACTIVE; } return flags; } 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(); }
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();
  }
/** * Begins a transaction in EXCLUSIVE mode. * <p> * 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. * </p> * <p>Here is the standard idiom for transactions: * * <pre> * db.beginTransaction(); * try { * ... * db.setTransactionSuccessful(); * } finally { * db.endTransaction(); * } * </pre> */
public void beginTransaction() { beginTransaction(null /* transactionStatusCallback */, true); }
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();
  }
/** * 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. * <p> * Here is the standard idiom for transactions: * * <pre> * db.beginTransactionNonExclusive(); * try { * ... * db.setTransactionSuccessful(); * } finally { * db.endTransaction(); * } * </pre> */
public void beginTransactionNonExclusive() { beginTransaction(null /* transactionStatusCallback */, false); }
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();
  }
Params:
  • transactionListener – listener that should be notified when the transaction begins, commits, or is rolled back, either explicitly or by a call to yieldIfContendedSafely.
/** * Begins a transaction in EXCLUSIVE mode. * <p> * 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. * </p> * <p>Here is the standard idiom for transactions: * * <pre> * db.beginTransactionWithListener(listener); * try { * ... * db.setTransactionSuccessful(); * } finally { * db.endTransaction(); * } * </pre> * * @param transactionListener listener that should be notified when the transaction begins, * commits, or is rolled back, either explicitly or by a call to * {@link #yieldIfContendedSafely}. */
public void beginTransactionWithListener(SQLiteTransactionListener transactionListener) { beginTransaction(transactionListener, true); }
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();
  }
Params:
  • transactionListener – listener that should be notified when the transaction begins, commits, or is rolled back, either explicitly or by a call to yieldIfContendedSafely.
/** * 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. * <p> * Here is the standard idiom for transactions: * * <pre> * db.beginTransactionWithListenerNonExclusive(listener); * try { * ... * db.setTransactionSuccessful(); * } finally { * db.endTransaction(); * } * </pre> * * @param transactionListener listener that should be notified when the * transaction begins, commits, or is rolled back, either * explicitly or by a call to {@link #yieldIfContendedSafely}. */
public void beginTransactionWithListenerNonExclusive( SQLiteTransactionListener transactionListener) { beginTransaction(transactionListener, false); } 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(); } }
End a transaction. See beginTransaction for notes about how to use this and when transactions are committed and rolled back.
/** * End a transaction. See beginTransaction for notes about how to use this and when transactions * are committed and rolled back. */
public void endTransaction() { acquireReference(); try { getThreadSession().endTransaction(null); } finally { releaseReference(); } }
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.
Throws:
  • IllegalStateException – if the current thread is not in a transaction or the transaction is already marked as successful.
/** * 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. * * @throws IllegalStateException if the current thread is not in a transaction or the * transaction is already marked as successful. */
public void setTransactionSuccessful() { acquireReference(); try { getThreadSession().setTransactionSuccessful(); } finally { releaseReference(); } }
Returns true if the current thread has a transaction pending.
Returns:True if the current thread is in a transaction.
/** * Returns true if the current thread has a transaction pending. * * @return True if the current thread is in a transaction. */
public boolean inTransaction() { acquireReference(); try { return getThreadSession().hasTransaction(); } finally { releaseReference(); } }
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.

Returns:True if the current thread is holding an active connection to the database.
/** * Returns true if the current thread is holding an active connection to the database. * <p> * 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. * </p> * * @return True if the current thread is holding an active connection to the database. */
public boolean isDbLockedByCurrentThread() { acquireReference(); try { return getThreadSession().hasConnection(); } finally { releaseReference(); } }
Always returns false.

There is no longer the concept of a database lock, so this method always returns false.

Returns:False.
Deprecated:Always returns false. Do not use this method.
/** * Always returns false. * <p> * There is no longer the concept of a database lock, so this method always returns false. * </p> * * @return False. * @deprecated Always returns false. Do not use this method. */
@Deprecated public boolean isDbLockedByOtherThreads() { return false; }
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.
Returns:true if the transaction was yielded
Deprecated:if the db is locked more than once (because of nested transactions) then the lock will not be yielded. Use yieldIfContendedSafely instead.
/** * 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 true if the transaction was yielded * @deprecated if the db is locked more than once (because of nested transactions) then the lock * will not be yielded. Use yieldIfContendedSafely instead. */
@Deprecated public boolean yieldIfContended() { return yieldIfContendedHelper(false /* do not check yielding */, -1 /* 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.
Returns:true if the transaction was yielded
/** * 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 true if the transaction was yielded */
public boolean yieldIfContendedSafely() { return yieldIfContendedHelper(true /* check yielding */, -1 /* 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.
Params:
  • sleepAfterYieldDelay – if > 0, sleep this long before starting a new transaction if the lock was actually yielded. This will allow other background threads to make some more progress than they would if we started the transaction immediately.
Returns:true if the transaction was yielded
/** * 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. * @param sleepAfterYieldDelay if > 0, sleep this long before starting a new transaction if * the lock was actually yielded. This will allow other background threads to make some * more progress than they would if we started the transaction immediately. * @return true if the transaction was yielded */
public boolean yieldIfContendedSafely(long sleepAfterYieldDelay) { return yieldIfContendedHelper(true /* check yielding */, sleepAfterYieldDelay); } private boolean yieldIfContendedHelper(boolean throwIfUnsafe, long sleepAfterYieldDelay) { acquireReference(); try { return getThreadSession().yieldTransaction(sleepAfterYieldDelay, throwIfUnsafe, null); } finally { releaseReference(); } }
Deprecated.
Deprecated:This method no longer serves any useful purpose and has been deprecated.
/** * Deprecated. * @deprecated This method no longer serves any useful purpose and has been deprecated. */
@Deprecated public Map<String, String> getSyncedTables() { return new HashMap<String, String>(0); }
Open the database according to the flags OPEN_READWRITE OPEN_READONLY CREATE_IF_NECESSARY and/or NO_LOCALIZED_COLLATORS.

Sets the locale of the database to the the system's current locale. Call setLocale if you would like something else.

Params:
  • path – to database file to open and/or create
  • factory – an optional factory class that is called to instantiate a cursor when query is called, or null for default
  • flags – to control database access mode
Throws:
Returns:the newly opened database
/** * Open the database according to the flags {@link #OPEN_READWRITE} * {@link #OPEN_READONLY} {@link #CREATE_IF_NECESSARY} and/or {@link #NO_LOCALIZED_COLLATORS}. * * <p>Sets the locale of the database to the the system's current locale. * Call {@link #setLocale} if you would like something else.</p> * * @param path to database file to open and/or create * @param factory an optional factory class that is called to instantiate a * cursor when query is called, or null for default * @param flags to control database access mode * @return the newly opened database * @throws SQLiteException if the database cannot be opened */
public static SQLiteDatabase openDatabase(@NonNull String path, @Nullable CursorFactory factory, @DatabaseOpenFlags int flags) { return openDatabase(path, factory, flags, null); }
Open the database according to the specified parameters
Params:
  • path – path to database file to open and/or create.

    Important: The file should be constructed either from an absolute path or by using Context.getDatabasePath(String).

  • openParams – configuration parameters that are used for opening SQLiteDatabase
Throws:
Returns:the newly opened database
/** * Open the database according to the specified {@link OpenParams parameters} * * @param path path to database file to open and/or create. * <p><strong>Important:</strong> The file should be constructed either from an absolute path or * by using {@link android.content.Context#getDatabasePath(String)}. * @param openParams configuration parameters that are used for opening {@link SQLiteDatabase} * @return the newly opened database * @throws SQLiteException if the database cannot be opened */
public static SQLiteDatabase openDatabase(@NonNull File path, @NonNull OpenParams openParams) { return openDatabase(path.getPath(), openParams); } private static SQLiteDatabase openDatabase(@NonNull String path, @NonNull OpenParams openParams) { Preconditions.checkArgument(openParams != null, "OpenParams cannot be null"); SQLiteDatabase db = new SQLiteDatabase(path, openParams.mOpenFlags, openParams.mCursorFactory, openParams.mErrorHandler, openParams.mLookasideSlotSize, openParams.mLookasideSlotCount, openParams.mIdleConnectionTimeout, openParams.mJournalMode, openParams.mSyncMode); db.open(); return db; }
Open the database according to the flags OPEN_READWRITE OPEN_READONLY CREATE_IF_NECESSARY and/or NO_LOCALIZED_COLLATORS.

Sets the locale of the database to the the system's current locale. Call setLocale if you would like something else.

Accepts input param: a concrete instance of DatabaseErrorHandler to be used to handle corruption when sqlite reports database corruption.

Params:
  • path – to database file to open and/or create
  • factory – an optional factory class that is called to instantiate a cursor when query is called, or null for default
  • flags – to control database access mode
  • errorHandler – the DatabaseErrorHandler obj to be used to handle corruption when sqlite reports database corruption
Throws:
Returns:the newly opened database
/** * Open the database according to the flags {@link #OPEN_READWRITE} * {@link #OPEN_READONLY} {@link #CREATE_IF_NECESSARY} and/or {@link #NO_LOCALIZED_COLLATORS}. * * <p>Sets the locale of the database to the the system's current locale. * Call {@link #setLocale} if you would like something else.</p> * * <p>Accepts input param: a concrete instance of {@link DatabaseErrorHandler} to be * used to handle corruption when sqlite reports database corruption.</p> * * @param path to database file to open and/or create * @param factory an optional factory class that is called to instantiate a * cursor when query is called, or null for default * @param flags to control database access mode * @param errorHandler the {@link DatabaseErrorHandler} obj to be used to handle corruption * when sqlite reports database corruption * @return the newly opened database * @throws SQLiteException if the database cannot be opened */
public static SQLiteDatabase openDatabase(@NonNull String path, @Nullable CursorFactory factory, @DatabaseOpenFlags int flags, @Nullable DatabaseErrorHandler errorHandler) { SQLiteDatabase db = new SQLiteDatabase(path, flags, factory, errorHandler, -1, -1, -1, null, null); db.open(); return db; }
Equivalent to openDatabase(file.getPath(), factory, CREATE_IF_NECESSARY).
/** * Equivalent to openDatabase(file.getPath(), factory, CREATE_IF_NECESSARY). */
public static SQLiteDatabase openOrCreateDatabase(@NonNull File file, @Nullable CursorFactory factory) { return openOrCreateDatabase(file.getPath(), factory); }
Equivalent to openDatabase(path, factory, CREATE_IF_NECESSARY).
/** * Equivalent to openDatabase(path, factory, CREATE_IF_NECESSARY). */
public static SQLiteDatabase openOrCreateDatabase(@NonNull String path, @Nullable CursorFactory factory) { return openDatabase(path, factory, CREATE_IF_NECESSARY, null); }
Equivalent to openDatabase(path, factory, CREATE_IF_NECESSARY, errorHandler).
/** * Equivalent to openDatabase(path, factory, CREATE_IF_NECESSARY, errorHandler). */
public static SQLiteDatabase openOrCreateDatabase(@NonNull String path, @Nullable CursorFactory factory, @Nullable DatabaseErrorHandler errorHandler) { return openDatabase(path, factory, CREATE_IF_NECESSARY, errorHandler); }
Deletes a database including its journal file and other auxiliary files that may have been created by the database engine.
Params:
  • file – The database file path.
Returns:True if the database was successfully deleted.
/** * Deletes a database including its journal file and other auxiliary files * that may have been created by the database engine. * * @param file The database file path. * @return True if the database was successfully deleted. */
public static boolean deleteDatabase(@NonNull File file) { 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; }
Reopens the database in read-write mode. If the database is already read-write, does nothing.
Throws:
  • SQLiteException – if the database could not be reopened as requested, in which case it remains open in read only mode.
  • IllegalStateException – if the database is not open.
See Also:
@hide
/** * Reopens the database in read-write mode. * If the database is already read-write, does nothing. * * @throws SQLiteException if the database could not be reopened as requested, in which * case it remains open in read only mode. * @throws IllegalStateException if the database is not open. * * @see #isReadOnly() * @hide */
public void reopenReadWrite() { 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; } } } 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; } } private void openInner() { synchronized (mLock) { assert mConnectionPoolLocked == null; mConnectionPoolLocked = SQLiteConnectionPool.open(mConfigurationLocked); mCloseGuardLocked.open("close"); } synchronized (sActiveDatabases) { sActiveDatabases.put(this, null); } }
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 setLocale if you would like something else.

Params:
  • factory – an optional factory class that is called to instantiate a cursor when query is called
Throws:
Returns:a SQLiteDatabase instance
/** * Create a memory backed SQLite database. Its contents will be destroyed * when the database is closed. * * <p>Sets the locale of the database to the the system's current locale. * Call {@link #setLocale} if you would like something else.</p> * * @param factory an optional factory class that is called to instantiate a * cursor when query is called * @return a SQLiteDatabase instance * @throws SQLiteException if the database cannot be created */
@NonNull public static SQLiteDatabase create(@Nullable CursorFactory factory) { // This is a magic string with special meaning for SQLite. return openDatabase(SQLiteDatabaseConfiguration.MEMORY_DB_PATH, factory, CREATE_IF_NECESSARY); }
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 setLocale if you would like something else.

Params:
  • openParams – configuration parameters that are used for opening SQLiteDatabase
Throws:
Returns:a SQLiteDatabase instance
/** * Create a memory backed SQLite database. Its contents will be destroyed * when the database is closed. * * <p>Sets the locale of the database to the the system's current locale. * Call {@link #setLocale} if you would like something else.</p> * @param openParams configuration parameters that are used for opening SQLiteDatabase * @return a SQLiteDatabase instance * @throws SQLException if the database cannot be created */
@NonNull public static SQLiteDatabase createInMemory(@NonNull OpenParams openParams) { return openDatabase(SQLiteDatabaseConfiguration.MEMORY_DB_PATH, openParams.toBuilder().addOpenFlags(CREATE_IF_NECESSARY).build()); }
Registers a CustomFunction callback as a function that can be called from SQLite database triggers.
Params:
  • name – the name of the sqlite3 function
  • numArgs – the number of arguments for the function
  • function – callback to call when the function is executed
@hide
/** * Registers a CustomFunction callback as a function that can be called from * SQLite database triggers. * * @param name the name of the sqlite3 function * @param numArgs the number of arguments for the function * @param function callback to call when the function is executed * @hide */
public void addCustomFunction(String name, int numArgs, CustomFunction function) { // 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; } } }
Gets the database version.
Returns:the database version
/** * Gets the database version. * * @return the database version */
public int getVersion() { return ((Long) DatabaseUtils.longForQuery(this, "PRAGMA user_version;", null)).intValue(); }
Sets the database version.
Params:
  • version – the new database version
/** * Sets the database version. * * @param version the new database version */
public void setVersion(int version) { execSQL("PRAGMA user_version = " + version); }
Returns the maximum size the database may grow to.
Returns:the new maximum database size
/** * Returns the maximum size the database may grow to. * * @return the new maximum database size */
public long getMaximumSize() { long pageCount = DatabaseUtils.longForQuery(this, "PRAGMA max_page_count;", null); return pageCount * getPageSize(); }
Sets the maximum size the database will grow to. The maximum size cannot be set below the current size.
Params:
  • numBytes – the maximum database size, in bytes
Returns:the new maximum database size
/** * Sets the maximum size the database will grow to. The maximum size cannot * be set below the current size. * * @param numBytes the maximum database size, in bytes * @return the new maximum database size */
public long setMaximumSize(long numBytes) { 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; }
Returns the current database page size, in bytes.
Returns:the database page size, in bytes
/** * Returns the current database page size, in bytes. * * @return the database page size, in bytes */
public long getPageSize() { return DatabaseUtils.longForQuery(this, "PRAGMA page_size;", null); }
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.
Params:
  • numBytes – the database page size, in bytes
/** * 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. * * @param numBytes the database page size, in bytes */
public void setPageSize(long numBytes) { execSQL("PRAGMA page_size = " + numBytes); }
Mark this table as syncable. When an update occurs in this table the _sync_dirty field will be set to ensure proper syncing operation.
Params:
  • table – the table to mark as syncable
  • deletedTable – The deleted table that corresponds to the syncable table
Deprecated:This method no longer serves any useful purpose and has been deprecated.
/** * Mark this table as syncable. When an update occurs in this table the * _sync_dirty field will be set to ensure proper syncing operation. * * @param table the table to mark as syncable * @param deletedTable The deleted table that corresponds to the * syncable table * @deprecated This method no longer serves any useful purpose and has been deprecated. */
@Deprecated public void markTableSyncable(String table, String deletedTable) { }
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.
Params:
  • table – an update on this table will trigger a sync time removal
  • foreignKey – this is the column in table whose value is an _id in updateTable
  • updateTable – this is the table that will have its _sync_dirty
Deprecated:This method no longer serves any useful purpose and has been deprecated.
/** * 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. * * @param table an update on this table will trigger a sync time removal * @param foreignKey this is the column in table whose value is an _id in * updateTable * @param updateTable this is the table that will have its _sync_dirty * @deprecated This method no longer serves any useful purpose and has been deprecated. */
@Deprecated public void markTableSyncable(String table, String foreignKey, String updateTable) { }
Finds the name of the first table, which is editable.
Params:
  • tables – a list of tables
Returns:the first table listed
/** * Finds the name of the first table, which is editable. * * @param tables a list of tables * @return the first table listed */
public static String findEditTable(String tables) { 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"); } }
Compiles an SQL statement into a reusable pre-compiled statement object. The parameters are identical to execSQL(String). You may put ?s in the statement and fill in those values with SQLiteProgram.bindString and 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 SQLiteStatement at the same time.

Params:
  • sql – The raw SQL statement, may contain ? for unknown values to be bound later.
Returns:A pre-compiled SQLiteStatement object. Note that SQLiteStatements are not synchronized, see the documentation for more details.
/** * 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. *<p> * No two threads should be using the same {@link SQLiteStatement} at the same time. * * @param sql The raw SQL statement, may contain ? for unknown values to be * bound later. * @return A pre-compiled {@link SQLiteStatement} object. Note that * {@link SQLiteStatement}s are not synchronized, see the documentation for more details. */
public SQLiteStatement compileStatement(String sql) throws SQLException { acquireReference(); try { return new SQLiteStatement(this, sql, null); } finally { releaseReference(); } }
Query the given URL, returning a Cursor over the result set.
Params:
  • distinct – true if you want each row to be unique, false otherwise.
  • table – The table name to compile the query against.
  • columns – A list of which columns to return. Passing null will return all columns, which is discouraged to prevent reading data from storage that isn't going to be used.
  • selection – A filter declaring which rows to return, formatted as an SQL WHERE clause (excluding the WHERE itself). Passing null will return all rows for the given table.
  • selectionArgs – You may include ?s in selection, which will be replaced by the values from selectionArgs, in order that they appear in the selection. The values will be bound as Strings.
  • groupBy – A filter declaring how to group rows, formatted as an SQL GROUP BY clause (excluding the GROUP BY itself). Passing null will cause the rows to not be grouped.
  • having – A filter declare which row groups to include in the cursor, if row grouping is being used, formatted as an SQL HAVING clause (excluding the HAVING itself). Passing null will cause all row groups to be included, and is required when row grouping is not being used.
  • orderBy – How to order the rows, formatted as an SQL ORDER BY clause (excluding the ORDER BY itself). Passing null will use the default sort order, which may be unordered.
  • limit – Limits the number of rows returned by the query, formatted as LIMIT clause. Passing null denotes no LIMIT clause.
See Also:
Returns:A Cursor object, which is positioned before the first entry. Note that Cursors are not synchronized, see the documentation for more details.
/** * Query the given URL, returning a {@link Cursor} over the result set. * * @param distinct true if you want each row to be unique, false otherwise. * @param table The table name to compile the query against. * @param columns A list of which columns to return. Passing null will * return all columns, which is discouraged to prevent reading * data from storage that isn't going to be used. * @param selection A filter declaring which rows to return, formatted as an * SQL WHERE clause (excluding the WHERE itself). Passing null * will return all rows for the given table. * @param selectionArgs You may include ?s in selection, which will be * replaced by the values from selectionArgs, in order that they * appear in the selection. The values will be bound as Strings. * @param groupBy A filter declaring how to group rows, formatted as an SQL * GROUP BY clause (excluding the GROUP BY itself). Passing null * will cause the rows to not be grouped. * @param having A filter declare which row groups to include in the cursor, * if row grouping is being used, formatted as an SQL HAVING * clause (excluding the HAVING itself). Passing null will cause * all row groups to be included, and is required when row * grouping is not being used. * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause * (excluding the ORDER BY itself). Passing null will use the * default sort order, which may be unordered. * @param limit Limits the number of rows returned by the query, * formatted as LIMIT clause. Passing null denotes no LIMIT clause. * @return A {@link Cursor} object, which is positioned before the first entry. Note that * {@link Cursor}s are not synchronized, see the documentation for more details. * @see Cursor */
public Cursor query(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit) { return queryWithFactory(null, distinct, table, columns, selection, selectionArgs, groupBy, having, orderBy, limit, null); }
Query the given URL, returning a Cursor over the result set.
Params:
  • distinct – true if you want each row to be unique, false otherwise.
  • table – The table name to compile the query against.
  • columns – A list of which columns to return. Passing null will return all columns, which is discouraged to prevent reading data from storage that isn't going to be used.
  • selection – A filter declaring which rows to return, formatted as an SQL WHERE clause (excluding the WHERE itself). Passing null will return all rows for the given table.
  • selectionArgs – You may include ?s in selection, which will be replaced by the values from selectionArgs, in order that they appear in the selection. The values will be bound as Strings.
  • groupBy – A filter declaring how to group rows, formatted as an SQL GROUP BY clause (excluding the GROUP BY itself). Passing null will cause the rows to not be grouped.
  • having – A filter declare which row groups to include in the cursor, if row grouping is being used, formatted as an SQL HAVING clause (excluding the HAVING itself). Passing null will cause all row groups to be included, and is required when row grouping is not being used.
  • orderBy – How to order the rows, formatted as an SQL ORDER BY clause (excluding the ORDER BY itself). Passing null will use the default sort order, which may be unordered.
  • limit – Limits the number of rows returned by the query, formatted as LIMIT clause. Passing null denotes no LIMIT clause.
  • cancellationSignal – A signal to cancel the operation in progress, or null if none. If the operation is canceled, then OperationCanceledException will be thrown when the query is executed.
See Also:
Returns:A Cursor object, which is positioned before the first entry. Note that Cursors are not synchronized, see the documentation for more details.
/** * Query the given URL, returning a {@link Cursor} over the result set. * * @param distinct true if you want each row to be unique, false otherwise. * @param table The table name to compile the query against. * @param columns A list of which columns to return. Passing null will * return all columns, which is discouraged to prevent reading * data from storage that isn't going to be used. * @param selection A filter declaring which rows to return, formatted as an * SQL WHERE clause (excluding the WHERE itself). Passing null * will return all rows for the given table. * @param selectionArgs You may include ?s in selection, which will be * replaced by the values from selectionArgs, in order that they * appear in the selection. The values will be bound as Strings. * @param groupBy A filter declaring how to group rows, formatted as an SQL * GROUP BY clause (excluding the GROUP BY itself). Passing null * will cause the rows to not be grouped. * @param having A filter declare which row groups to include in the cursor, * if row grouping is being used, formatted as an SQL HAVING * clause (excluding the HAVING itself). Passing null will cause * all row groups to be included, and is required when row * grouping is not being used. * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause * (excluding the ORDER BY itself). Passing null will use the * default sort order, which may be unordered. * @param limit Limits the number of rows returned by the query, * formatted as LIMIT clause. Passing null denotes no LIMIT clause. * @param cancellationSignal A signal to cancel the operation in progress, or null if none. * If the operation is canceled, then {@link OperationCanceledException} will be thrown * when the query is executed. * @return A {@link Cursor} object, which is positioned before the first entry. Note that * {@link Cursor}s are not synchronized, see the documentation for more details. * @see Cursor */
public Cursor query(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit, CancellationSignal cancellationSignal) { return queryWithFactory(null, distinct, table, columns, selection, selectionArgs, groupBy, having, orderBy, limit, cancellationSignal); }
Query the given URL, returning a Cursor over the result set.
Params:
  • cursorFactory – the cursor factory to use, or null for the default factory
  • distinct – true if you want each row to be unique, false otherwise.
  • table – The table name to compile the query against.
  • columns – A list of which columns to return. Passing null will return all columns, which is discouraged to prevent reading data from storage that isn't going to be used.
  • selection – A filter declaring which rows to return, formatted as an SQL WHERE clause (excluding the WHERE itself). Passing null will return all rows for the given table.
  • selectionArgs – You may include ?s in selection, which will be replaced by the values from selectionArgs, in order that they appear in the selection. The values will be bound as Strings.
  • groupBy – A filter declaring how to group rows, formatted as an SQL GROUP BY clause (excluding the GROUP BY itself). Passing null will cause the rows to not be grouped.
  • having – A filter declare which row groups to include in the cursor, if row grouping is being used, formatted as an SQL HAVING clause (excluding the HAVING itself). Passing null will cause all row groups to be included, and is required when row grouping is not being used.
  • orderBy – How to order the rows, formatted as an SQL ORDER BY clause (excluding the ORDER BY itself). Passing null will use the default sort order, which may be unordered.
  • limit – Limits the number of rows returned by the query, formatted as LIMIT clause. Passing null denotes no LIMIT clause.
See Also:
Returns:A Cursor object, which is positioned before the first entry. Note that Cursors are not synchronized, see the documentation for more details.
/** * Query the given URL, returning a {@link Cursor} over the result set. * * @param cursorFactory the cursor factory to use, or null for the default factory * @param distinct true if you want each row to be unique, false otherwise. * @param table The table name to compile the query against. * @param columns A list of which columns to return. Passing null will * return all columns, which is discouraged to prevent reading * data from storage that isn't going to be used. * @param selection A filter declaring which rows to return, formatted as an * SQL WHERE clause (excluding the WHERE itself). Passing null * will return all rows for the given table. * @param selectionArgs You may include ?s in selection, which will be * replaced by the values from selectionArgs, in order that they * appear in the selection. The values will be bound as Strings. * @param groupBy A filter declaring how to group rows, formatted as an SQL * GROUP BY clause (excluding the GROUP BY itself). Passing null * will cause the rows to not be grouped. * @param having A filter declare which row groups to include in the cursor, * if row grouping is being used, formatted as an SQL HAVING * clause (excluding the HAVING itself). Passing null will cause * all row groups to be included, and is required when row * grouping is not being used. * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause * (excluding the ORDER BY itself). Passing null will use the * default sort order, which may be unordered. * @param limit Limits the number of rows returned by the query, * formatted as LIMIT clause. Passing null denotes no LIMIT clause. * @return A {@link Cursor} object, which is positioned before the first entry. Note that * {@link Cursor}s are not synchronized, see the documentation for more details. * @see Cursor */
public Cursor queryWithFactory(CursorFactory cursorFactory, boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit) { return queryWithFactory(cursorFactory, distinct, table, columns, selection, selectionArgs, groupBy, having, orderBy, limit, null); }
Query the given URL, returning a Cursor over the result set.
Params:
  • cursorFactory – the cursor factory to use, or null for the default factory
  • distinct – true if you want each row to be unique, false otherwise.
  • table – The table name to compile the query against.
  • columns – A list of which columns to return. Passing null will return all columns, which is discouraged to prevent reading data from storage that isn't going to be used.
  • selection – A filter declaring which rows to return, formatted as an SQL WHERE clause (excluding the WHERE itself). Passing null will return all rows for the given table.
  • selectionArgs – You may include ?s in selection, which will be replaced by the values from selectionArgs, in order that they appear in the selection. The values will be bound as Strings.
  • groupBy – A filter declaring how to group rows, formatted as an SQL GROUP BY clause (excluding the GROUP BY itself). Passing null will cause the rows to not be grouped.
  • having – A filter declare which row groups to include in the cursor, if row grouping is being used, formatted as an SQL HAVING clause (excluding the HAVING itself). Passing null will cause all row groups to be included, and is required when row grouping is not being used.
  • orderBy – How to order the rows, formatted as an SQL ORDER BY clause (excluding the ORDER BY itself). Passing null will use the default sort order, which may be unordered.
  • limit – Limits the number of rows returned by the query, formatted as LIMIT clause. Passing null denotes no LIMIT clause.
  • cancellationSignal – A signal to cancel the operation in progress, or null if none. If the operation is canceled, then OperationCanceledException will be thrown when the query is executed.
See Also:
Returns:A Cursor object, which is positioned before the first entry. Note that Cursors are not synchronized, see the documentation for more details.
/** * Query the given URL, returning a {@link Cursor} over the result set. * * @param cursorFactory the cursor factory to use, or null for the default factory * @param distinct true if you want each row to be unique, false otherwise. * @param table The table name to compile the query against. * @param columns A list of which columns to return. Passing null will * return all columns, which is discouraged to prevent reading * data from storage that isn't going to be used. * @param selection A filter declaring which rows to return, formatted as an * SQL WHERE clause (excluding the WHERE itself). Passing null * will return all rows for the given table. * @param selectionArgs You may include ?s in selection, which will be * replaced by the values from selectionArgs, in order that they * appear in the selection. The values will be bound as Strings. * @param groupBy A filter declaring how to group rows, formatted as an SQL * GROUP BY clause (excluding the GROUP BY itself). Passing null * will cause the rows to not be grouped. * @param having A filter declare which row groups to include in the cursor, * if row grouping is being used, formatted as an SQL HAVING * clause (excluding the HAVING itself). Passing null will cause * all row groups to be included, and is required when row * grouping is not being used. * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause * (excluding the ORDER BY itself). Passing null will use the * default sort order, which may be unordered. * @param limit Limits the number of rows returned by the query, * formatted as LIMIT clause. Passing null denotes no LIMIT clause. * @param cancellationSignal A signal to cancel the operation in progress, or null if none. * If the operation is canceled, then {@link OperationCanceledException} will be thrown * when the query is executed. * @return A {@link Cursor} object, which is positioned before the first entry. Note that * {@link Cursor}s are not synchronized, see the documentation for more details. * @see Cursor */
public Cursor queryWithFactory(CursorFactory cursorFactory, boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit, CancellationSignal cancellationSignal) { acquireReference(); try { String sql = SQLiteQueryBuilder.buildQueryString( distinct, table, columns, selection, groupBy, having, orderBy, limit); return rawQueryWithFactory(cursorFactory, sql, selectionArgs, findEditTable(table), cancellationSignal); } finally { releaseReference(); } }
Query the given table, returning a Cursor over the result set.
Params:
  • table – The table name to compile the query against.
  • columns – A list of which columns to return. Passing null will return all columns, which is discouraged to prevent reading data from storage that isn't going to be used.
  • selection – A filter declaring which rows to return, formatted as an SQL WHERE clause (excluding the WHERE itself). Passing null will return all rows for the given table.
  • selectionArgs – You may include ?s in selection, which will be replaced by the values from selectionArgs, in order that they appear in the selection. The values will be bound as Strings.
  • groupBy – A filter declaring how to group rows, formatted as an SQL GROUP BY clause (excluding the GROUP BY itself). Passing null will cause the rows to not be grouped.
  • having – A filter declare which row groups to include in the cursor, if row grouping is being used, formatted as an SQL HAVING clause (excluding the HAVING itself). Passing null will cause all row groups to be included, and is required when row grouping is not being used.
  • orderBy – How to order the rows, formatted as an SQL ORDER BY clause (excluding the ORDER BY itself). Passing null will use the default sort order, which may be unordered.
See Also:
Returns:A Cursor object, which is positioned before the first entry. Note that Cursors are not synchronized, see the documentation for more details.
/** * Query the given table, returning a {@link Cursor} over the result set. * * @param table The table name to compile the query against. * @param columns A list of which columns to return. Passing null will * return all columns, which is discouraged to prevent reading * data from storage that isn't going to be used. * @param selection A filter declaring which rows to return, formatted as an * SQL WHERE clause (excluding the WHERE itself). Passing null * will return all rows for the given table. * @param selectionArgs You may include ?s in selection, which will be * replaced by the values from selectionArgs, in order that they * appear in the selection. The values will be bound as Strings. * @param groupBy A filter declaring how to group rows, formatted as an SQL * GROUP BY clause (excluding the GROUP BY itself). Passing null * will cause the rows to not be grouped. * @param having A filter declare which row groups to include in the cursor, * if row grouping is being used, formatted as an SQL HAVING * clause (excluding the HAVING itself). Passing null will cause * all row groups to be included, and is required when row * grouping is not being used. * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause * (excluding the ORDER BY itself). Passing null will use the * default sort order, which may be unordered. * @return A {@link Cursor} object, which is positioned before the first entry. Note that * {@link Cursor}s are not synchronized, see the documentation for more details. * @see Cursor */
public Cursor query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy) { return query(false, table, columns, selection, selectionArgs, groupBy, having, orderBy, null /* limit */); }
Query the given table, returning a Cursor over the result set.
Params:
  • table – The table name to compile the query against.
  • columns – A list of which columns to return. Passing null will return all columns, which is discouraged to prevent reading data from storage that isn't going to be used.
  • selection – A filter declaring which rows to return, formatted as an SQL WHERE clause (excluding the WHERE itself). Passing null will return all rows for the given table.
  • selectionArgs – You may include ?s in selection, which will be replaced by the values from selectionArgs, in order that they appear in the selection. The values will be bound as Strings.
  • groupBy – A filter declaring how to group rows, formatted as an SQL GROUP BY clause (excluding the GROUP BY itself). Passing null will cause the rows to not be grouped.
  • having – A filter declare which row groups to include in the cursor, if row grouping is being used, formatted as an SQL HAVING clause (excluding the HAVING itself). Passing null will cause all row groups to be included, and is required when row grouping is not being used.
  • orderBy – How to order the rows, formatted as an SQL ORDER BY clause (excluding the ORDER BY itself). Passing null will use the default sort order, which may be unordered.
  • limit – Limits the number of rows returned by the query, formatted as LIMIT clause. Passing null denotes no LIMIT clause.
See Also:
Returns:A Cursor object, which is positioned before the first entry. Note that Cursors are not synchronized, see the documentation for more details.
/** * Query the given table, returning a {@link Cursor} over the result set. * * @param table The table name to compile the query against. * @param columns A list of which columns to return. Passing null will * return all columns, which is discouraged to prevent reading * data from storage that isn't going to be used. * @param selection A filter declaring which rows to return, formatted as an * SQL WHERE clause (excluding the WHERE itself). Passing null * will return all rows for the given table. * @param selectionArgs You may include ?s in selection, which will be * replaced by the values from selectionArgs, in order that they * appear in the selection. The values will be bound as Strings. * @param groupBy A filter declaring how to group rows, formatted as an SQL * GROUP BY clause (excluding the GROUP BY itself). Passing null * will cause the rows to not be grouped. * @param having A filter declare which row groups to include in the cursor, * if row grouping is being used, formatted as an SQL HAVING * clause (excluding the HAVING itself). Passing null will cause * all row groups to be included, and is required when row * grouping is not being used. * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause * (excluding the ORDER BY itself). Passing null will use the * default sort order, which may be unordered. * @param limit Limits the number of rows returned by the query, * formatted as LIMIT clause. Passing null denotes no LIMIT clause. * @return A {@link Cursor} object, which is positioned before the first entry. Note that * {@link Cursor}s are not synchronized, see the documentation for more details. * @see Cursor */
public Cursor query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit) { return query(false, table, columns, selection, selectionArgs, groupBy, having, orderBy, limit); }
Runs the provided SQL and returns a Cursor over the result set.
Params:
  • sql – the SQL query. The SQL string must not be ; terminated
  • selectionArgs – You may include ?s in where clause in the query, which will be replaced by the values from selectionArgs. The values will be bound as Strings.
Returns:A Cursor object, which is positioned before the first entry. Note that Cursors are not synchronized, see the documentation for more details.
/** * Runs the provided SQL and returns a {@link Cursor} over the result set. * * @param sql the SQL query. The SQL string must not be ; terminated * @param selectionArgs You may include ?s in where clause in the query, * which will be replaced by the values from selectionArgs. The * values will be bound as Strings. * @return A {@link Cursor} object, which is positioned before the first entry. Note that * {@link Cursor}s are not synchronized, see the documentation for more details. */
public Cursor rawQuery(String sql, String[] selectionArgs) { return rawQueryWithFactory(null, sql, selectionArgs, null, null); }
Runs the provided SQL and returns a Cursor over the result set.
Params:
  • sql – the SQL query. The SQL string must not be ; terminated
  • selectionArgs – You may include ?s in where clause in the query, which will be replaced by the values from selectionArgs. The values will be bound as Strings.
  • cancellationSignal – A signal to cancel the operation in progress, or null if none. If the operation is canceled, then OperationCanceledException will be thrown when the query is executed.
Returns:A Cursor object, which is positioned before the first entry. Note that Cursors are not synchronized, see the documentation for more details.
/** * Runs the provided SQL and returns a {@link Cursor} over the result set. * * @param sql the SQL query. The SQL string must not be ; terminated * @param selectionArgs You may include ?s in where clause in the query, * which will be replaced by the values from selectionArgs. The * values will be bound as Strings. * @param cancellationSignal A signal to cancel the operation in progress, or null if none. * If the operation is canceled, then {@link OperationCanceledException} will be thrown * when the query is executed. * @return A {@link Cursor} object, which is positioned before the first entry. Note that * {@link Cursor}s are not synchronized, see the documentation for more details. */
public Cursor rawQuery(String sql, String[] selectionArgs, CancellationSignal cancellationSignal) { return rawQueryWithFactory(null, sql, selectionArgs, null, cancellationSignal); }
Runs the provided SQL and returns a cursor over the result set.
Params:
  • cursorFactory – the cursor factory to use, or null for the default factory
  • sql – the SQL query. The SQL string must not be ; terminated
  • selectionArgs – You may include ?s in where clause in the query, which will be replaced by the values from selectionArgs. The values will be bound as Strings.
  • editTable – the name of the first table, which is editable
Returns:A Cursor object, which is positioned before the first entry. Note that Cursors are not synchronized, see the documentation for more details.
/** * Runs the provided SQL and returns a cursor over the result set. * * @param cursorFactory the cursor factory to use, or null for the default factory * @param sql the SQL query. The SQL string must not be ; terminated * @param selectionArgs You may include ?s in where clause in the query, * which will be replaced by the values from selectionArgs. The * values will be bound as Strings. * @param editTable the name of the first table, which is editable * @return A {@link Cursor} object, which is positioned before the first entry. Note that * {@link Cursor}s are not synchronized, see the documentation for more details. */
public Cursor rawQueryWithFactory( CursorFactory cursorFactory, String sql, String[] selectionArgs, String editTable) { return rawQueryWithFactory(cursorFactory, sql, selectionArgs, editTable, null); }
Runs the provided SQL and returns a cursor over the result set.
Params:
  • cursorFactory – the cursor factory to use, or null for the default factory
  • sql – the SQL query. The SQL string must not be ; terminated
  • selectionArgs – You may include ?s in where clause in the query, which will be replaced by the values from selectionArgs. The values will be bound as Strings.
  • editTable – the name of the first table, which is editable
  • cancellationSignal – A signal to cancel the operation in progress, or null if none. If the operation is canceled, then OperationCanceledException will be thrown when the query is executed.
Returns:A Cursor object, which is positioned before the first entry. Note that Cursors are not synchronized, see the documentation for more details.
/** * Runs the provided SQL and returns a cursor over the result set. * * @param cursorFactory the cursor factory to use, or null for the default factory * @param sql the SQL query. The SQL string must not be ; terminated * @param selectionArgs You may include ?s in where clause in the query, * which will be replaced by the values from selectionArgs. The * values will be bound as Strings. * @param editTable the name of the first table, which is editable * @param cancellationSignal A signal to cancel the operation in progress, or null if none. * If the operation is canceled, then {@link OperationCanceledException} will be thrown * when the query is executed. * @return A {@link Cursor} object, which is positioned before the first entry. Note that * {@link Cursor}s are not synchronized, see the documentation for more details. */
public Cursor rawQueryWithFactory( CursorFactory cursorFactory, String sql, String[] selectionArgs, String editTable, CancellationSignal cancellationSignal) { acquireReference(); try { SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(this, sql, editTable, cancellationSignal); return driver.query(cursorFactory != null ? cursorFactory : mCursorFactory, selectionArgs); } finally { releaseReference(); } }
Convenience method for inserting a row into the database.
Params:
  • table – the table to insert the row into
  • nullColumnHack – optional; may be null. SQL doesn't allow inserting a completely empty row without naming at least one column name. If your provided values is empty, no column names are known and an empty row can't be inserted. If not set to null, the nullColumnHack parameter provides the name of nullable column name to explicitly insert a NULL into in the case where your values is empty.
  • values – this map contains the initial column values for the row. The keys should be the column names and the values the column values
Returns:the row ID of the newly inserted row, or -1 if an error occurred
/** * Convenience method for inserting a row into the database. * * @param table the table to insert the row into * @param nullColumnHack optional; may be <code>null</code>. * SQL doesn't allow inserting a completely empty row without * naming at least one column name. If your provided <code>values</code> is * empty, no column names are known and an empty row can't be inserted. * If not set to null, the <code>nullColumnHack</code> parameter * provides the name of nullable column name to explicitly insert a NULL into * in the case where your <code>values</code> is empty. * @param values this map contains the initial column values for the * row. The keys should be the column names and the values the * column values * @return the row ID of the newly inserted row, or -1 if an error occurred */
public long insert(String table, String nullColumnHack, ContentValues values) { try { return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE); } catch (SQLException e) { Log.e(TAG, "Error inserting " + values, e); return -1; } }
Convenience method for inserting a row into the database.
Params:
  • table – the table to insert the row into
  • nullColumnHack – optional; may be null. SQL doesn't allow inserting a completely empty row without naming at least one column name. If your provided values is empty, no column names are known and an empty row can't be inserted. If not set to null, the nullColumnHack parameter provides the name of nullable column name to explicitly insert a NULL into in the case where your values is empty.
  • values – this map contains the initial column values for the row. The keys should be the column names and the values the column values
Throws:
Returns:the row ID of the newly inserted row, or -1 if an error occurred
/** * Convenience method for inserting a row into the database. * * @param table the table to insert the row into * @param nullColumnHack optional; may be <code>null</code>. * SQL doesn't allow inserting a completely empty row without * naming at least one column name. If your provided <code>values</code> is * empty, no column names are known and an empty row can't be inserted. * If not set to null, the <code>nullColumnHack</code> parameter * provides the name of nullable column name to explicitly insert a NULL into * in the case where your <code>values</code> is empty. * @param values this map contains the initial column values for the * row. The keys should be the column names and the values the * column values * @throws SQLException * @return the row ID of the newly inserted row, or -1 if an error occurred */
public long insertOrThrow(String table, String nullColumnHack, ContentValues values) throws SQLException { return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE); }
Convenience method for replacing a row in the database. Inserts a new row if a row does not already exist.
Params:
  • table – the table in which to replace the row
  • nullColumnHack – optional; may be null. SQL doesn't allow inserting a completely empty row without naming at least one column name. If your provided initialValues is empty, no column names are known and an empty row can't be inserted. If not set to null, the nullColumnHack parameter provides the name of nullable column name to explicitly insert a NULL into in the case where your initialValues is empty.
  • initialValues – this map contains the initial column values for the row. The keys should be the column names and the values the column values.
Returns:the row ID of the newly inserted row, or -1 if an error occurred
/** * Convenience method for replacing a row in the database. * Inserts a new row if a row does not already exist. * * @param table the table in which to replace the row * @param nullColumnHack optional; may be <code>null</code>. * SQL doesn't allow inserting a completely empty row without * naming at least one column name. If your provided <code>initialValues</code> is * empty, no column names are known and an empty row can't be inserted. * If not set to null, the <code>nullColumnHack</code> parameter * provides the name of nullable column name to explicitly insert a NULL into * in the case where your <code>initialValues</code> is empty. * @param initialValues this map contains the initial column values for * the row. The keys should be the column names and the values the column values. * @return the row ID of the newly inserted row, or -1 if an error occurred */
public long replace(String table, String nullColumnHack, ContentValues initialValues) { try { return insertWithOnConflict(table, nullColumnHack, initialValues, CONFLICT_REPLACE); } catch (SQLException e) { Log.e(TAG, "Error inserting " + initialValues, e); return -1; } }
Convenience method for replacing a row in the database. Inserts a new row if a row does not already exist.
Params:
  • table – the table in which to replace the row
  • nullColumnHack – optional; may be null. SQL doesn't allow inserting a completely empty row without naming at least one column name. If your provided initialValues is empty, no column names are known and an empty row can't be inserted. If not set to null, the nullColumnHack parameter provides the name of nullable column name to explicitly insert a NULL into in the case where your initialValues is empty.
  • initialValues – this map contains the initial column values for the row. The keys should be the column names and the values the column values.
Throws:
Returns:the row ID of the newly inserted row, or -1 if an error occurred
/** * Convenience method for replacing a row in the database. * Inserts a new row if a row does not already exist. * * @param table the table in which to replace the row * @param nullColumnHack optional; may be <code>null</code>. * SQL doesn't allow inserting a completely empty row without * naming at least one column name. If your provided <code>initialValues</code> is * empty, no column names are known and an empty row can't be inserted. * If not set to null, the <code>nullColumnHack</code> parameter * provides the name of nullable column name to explicitly insert a NULL into * in the case where your <code>initialValues</code> is empty. * @param initialValues this map contains the initial column values for * the row. The keys should be the column names and the values the column values. * @throws SQLException * @return the row ID of the newly inserted row, or -1 if an error occurred */
public long replaceOrThrow(String table, String nullColumnHack, ContentValues initialValues) throws SQLException { return insertWithOnConflict(table, nullColumnHack, initialValues, CONFLICT_REPLACE); }
General method for inserting a row into the database.
Params:
  • table – the table to insert the row into
  • nullColumnHack – optional; may be null. SQL doesn't allow inserting a completely empty row without naming at least one column name. If your provided initialValues is empty, no column names are known and an empty row can't be inserted. If not set to null, the nullColumnHack parameter provides the name of nullable column name to explicitly insert a NULL into in the case where your initialValues is empty.
  • initialValues – this map contains the initial column values for the row. The keys should be the column names and the values the column values
  • conflictAlgorithm – for insert conflict resolver
Returns:the row ID of the newly inserted row OR -1 if either the input parameter conflictAlgorithm = CONFLICT_IGNORE or an error occurred.
/** * General method for inserting a row into the database. * * @param table the table to insert the row into * @param nullColumnHack optional; may be <code>null</code>. * SQL doesn't allow inserting a completely empty row without * naming at least one column name. If your provided <code>initialValues</code> is * empty, no column names are known and an empty row can't be inserted. * If not set to null, the <code>nullColumnHack</code> parameter * provides the name of nullable column name to explicitly insert a NULL into * in the case where your <code>initialValues</code> is empty. * @param initialValues this map contains the initial column values for the * row. The keys should be the column names and the values the * column values * @param conflictAlgorithm for insert conflict resolver * @return the row ID of the newly inserted row OR <code>-1</code> if either the * input parameter <code>conflictAlgorithm</code> = {@link #CONFLICT_IGNORE} * or an error occurred. */
public long insertWithOnConflict(String table, String nullColumnHack, ContentValues initialValues, int conflictAlgorithm) { 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.isEmpty()) ? 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(); } }
Convenience method for deleting rows in the database.
Params:
  • table – the table to delete from
  • whereClause – the optional WHERE clause to apply when deleting. Passing null will delete all rows.
  • whereArgs – You may include ?s in the where clause, which will be replaced by the values from whereArgs. The values will be bound as Strings.
Returns:the number of rows affected if a whereClause is passed in, 0 otherwise. To remove all rows and get a count pass "1" as the whereClause.
/** * Convenience method for deleting rows in the database. * * @param table the table to delete from * @param whereClause the optional WHERE clause to apply when deleting. * Passing null will delete all rows. * @param whereArgs You may include ?s in the where clause, which * will be replaced by the values from whereArgs. The values * will be bound as Strings. * @return the number of rows affected if a whereClause is passed in, 0 * otherwise. To remove all rows and get a count pass "1" as the * whereClause. */
public int delete(String table, String whereClause, String[] whereArgs) { 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(); } }
Convenience method for updating rows in the database.
Params:
  • table – the table to update in
  • values – a map from column names to new column values. null is a valid value that will be translated to NULL.
  • whereClause – the optional WHERE clause to apply when updating. Passing null will update all rows.
  • whereArgs – You may include ?s in the where clause, which will be replaced by the values from whereArgs. The values will be bound as Strings.
Returns:the number of rows affected
/** * Convenience method for updating rows in the database. * * @param table the table to update in * @param values a map from column names to new column values. null is a * valid value that will be translated to NULL. * @param whereClause the optional WHERE clause to apply when updating. * Passing null will update all rows. * @param whereArgs You may include ?s in the where clause, which * will be replaced by the values from whereArgs. The values * will be bound as Strings. * @return the number of rows affected */
public int update(String table, ContentValues values, String whereClause, String[] whereArgs) { return updateWithOnConflict(table, values, whereClause, whereArgs, CONFLICT_NONE); }
Convenience method for updating rows in the database.
Params:
  • table – the table to update in
  • values – a map from column names to new column values. null is a valid value that will be translated to NULL.
  • whereClause – the optional WHERE clause to apply when updating. Passing null will update all rows.
  • whereArgs – You may include ?s in the where clause, which will be replaced by the values from whereArgs. The values will be bound as Strings.
  • conflictAlgorithm – for update conflict resolver
Returns:the number of rows affected
/** * Convenience method for updating rows in the database. * * @param table the table to update in * @param values a map from column names to new column values. null is a * valid value that will be translated to NULL. * @param whereClause the optional WHERE clause to apply when updating. * Passing null will update all rows. * @param whereArgs You may include ?s in the where clause, which * will be replaced by the values from whereArgs. The values * will be bound as Strings. * @param conflictAlgorithm for update conflict resolver * @return the number of rows affected */
public int updateWithOnConflict(String table, ContentValues values, String whereClause, String[] whereArgs, int conflictAlgorithm) { if (values == null || values.isEmpty()) { 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(); } }
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 insert(String, String, ContentValues), update(String, ContentValues, String, String[]), et al, when possible.

When using 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 enableWriteAheadLogging()

Params:
  • sql – the SQL statement to be executed. Multiple statements separated by semicolons are not supported.
Throws:
/** * Execute a single SQL statement that is NOT a SELECT * or any other SQL statement that returns data. * <p> * 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. * </p> * <p> * When using {@link #enableWriteAheadLogging()}, journal_mode is * automatically managed by this class. So, do not set journal_mode * using "PRAGMA journal_mode'<value>" statement if your app is using * {@link #enableWriteAheadLogging()} * </p> * * @param sql the SQL statement to be executed. Multiple statements separated by semicolons are * not supported. * @throws SQLException if the SQL string is invalid */
public void execSQL(String sql) throws SQLException { executeSql(sql, null); }
Execute a single SQL statement that is NOT a SELECT/INSERT/UPDATE/DELETE.

For INSERT statements, use any of the following instead.

For UPDATE statements, use any of the following instead.

For DELETE statements, use any of the following instead.

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 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 enableWriteAheadLogging()

Params:
  • sql – the SQL statement to be executed. Multiple statements separated by semicolons are not supported.
  • bindArgs – only byte[], String, Long and Double are supported in bindArgs.
Throws:
/** * Execute a single SQL statement that is NOT a SELECT/INSERT/UPDATE/DELETE. * <p> * For INSERT statements, use any of the following instead. * <ul> * <li>{@link #insert(String, String, ContentValues)}</li> * <li>{@link #insertOrThrow(String, String, ContentValues)}</li> * <li>{@link #insertWithOnConflict(String, String, ContentValues, int)}</li> * </ul> * <p> * For UPDATE statements, use any of the following instead. * <ul> * <li>{@link #update(String, ContentValues, String, String[])}</li> * <li>{@link #updateWithOnConflict(String, ContentValues, String, String[], int)}</li> * </ul> * <p> * For DELETE statements, use any of the following instead. * <ul> * <li>{@link #delete(String, String, String[])}</li> * </ul> * <p> * For example, the following are good candidates for using this method: * <ul> * <li>ALTER TABLE</li> * <li>CREATE or DROP table / trigger / view / index / virtual table</li> * <li>REINDEX</li> * <li>RELEASE</li> * <li>SAVEPOINT</li> * <li>PRAGMA that returns no data</li> * </ul> * </p> * <p> * When using {@link #enableWriteAheadLogging()}, journal_mode is * automatically managed by this class. So, do not set journal_mode * using "PRAGMA journal_mode'<value>" statement if your app is using * {@link #enableWriteAheadLogging()} * </p> * * @param sql the SQL statement to be executed. Multiple statements separated by semicolons are * not supported. * @param bindArgs only byte[], String, Long and Double are supported in bindArgs. * @throws SQLException if the SQL string is invalid */
public void execSQL(String sql, Object[] bindArgs) throws SQLException { if (bindArgs == null) { throw new IllegalArgumentException("Empty bindArgs"); } executeSql(sql, bindArgs); }
{@hide}
/** {@hide} */
public int executeSql(String sql, Object[] bindArgs) throws SQLException { acquireReference(); try { final int statementType = DatabaseUtils.getSqlStatementType(sql); if (statementType == DatabaseUtils.STATEMENT_ATTACH) { boolean disableWal = false; synchronized (mLock) { if (!mHasAttachedDbsLocked) { mHasAttachedDbsLocked = true; disableWal = true; mConnectionPoolLocked.disableIdleConnectionHandler(); } } if (disableWal) { disableWriteAheadLogging(); } } try (SQLiteStatement statement = new SQLiteStatement(this, sql, bindArgs)) { return statement.executeUpdateDelete(); } finally { // If schema was updated, close non-primary connections, otherwise they might // have outdated schema information if (statementType == DatabaseUtils.STATEMENT_DDL) { mConnectionPoolLocked.closeAvailableNonPrimaryConnectionsAndLogExceptions(); } } } finally { releaseReference(); } }
Verifies that a SQL SELECT statement is valid by compiling it. If the SQL statement is not valid, this method will throw a SQLiteException.
Params:
  • sql – SQL to be validated
  • cancellationSignal – A signal to cancel the operation in progress, or null if none. If the operation is canceled, then OperationCanceledException will be thrown when the query is executed.
Throws:
/** * Verifies that a SQL SELECT statement is valid by compiling it. * If the SQL statement is not valid, this method will throw a {@link SQLiteException}. * * @param sql SQL to be validated * @param cancellationSignal A signal to cancel the operation in progress, or null if none. * If the operation is canceled, then {@link OperationCanceledException} will be thrown * when the query is executed. * @throws SQLiteException if {@code sql} is invalid */
public void validateSql(@NonNull String sql, @Nullable CancellationSignal cancellationSignal) { getThreadSession().prepare(sql, getThreadDefaultConnectionFlags(/* readOnly =*/ true), cancellationSignal, null); }
Returns true if the database is opened as read only.
Returns:True if database is opened as read only.
/** * Returns true if the database is opened as read only. * * @return True if database is opened as read only. */
public boolean isReadOnly() { synchronized (mLock) { return isReadOnlyLocked(); } } private boolean isReadOnlyLocked() { return (mConfigurationLocked.openFlags & OPEN_READ_MASK) == OPEN_READONLY; }
Returns true if the database is in-memory db.
Returns:True if the database is in-memory.
@hide
/** * Returns true if the database is in-memory db. * * @return True if the database is in-memory. * @hide */
public boolean isInMemoryDatabase() { synchronized (mLock) { return mConfigurationLocked.isInMemoryDb(); } }
Returns true if the database is currently open.
Returns:True if the database is currently open (has not been closed).
/** * Returns true if the database is currently open. * * @return True if the database is currently open (has not been closed). */
public boolean isOpen() { synchronized (mLock) { return mConnectionPoolLocked != null; } }
Returns true if the new version code is greater than the current database version.
Params:
  • newVersion – The new version code.
Returns:True if the new version code is greater than the current database version.
/** * Returns true if the new version code is greater than the current database version. * * @param newVersion The new version code. * @return True if the new version code is greater than the current database version. */
public boolean needUpgrade(int newVersion) { return newVersion > getVersion(); }
Gets the path to the database file.
Returns:The path to the database file.
/** * Gets the path to the database file. * * @return The path to the database file. */
public final String getPath() { synchronized (mLock) { return mConfigurationLocked.path; } }
Sets the locale for this database. Does nothing if this database has the NO_LOCALIZED_COLLATORS flag set or was opened read only.
Params:
  • locale – The new locale.
Throws:
  • SQLException – if the locale could not be set. The most common reason for this is that there is no collator available for the locale you requested. In this case the database remains unchanged.
/** * Sets the locale for this database. Does nothing if this database has * the {@link #NO_LOCALIZED_COLLATORS} flag set or was opened read only. * * @param locale The new locale. * * @throws SQLException if the locale could not be set. The most common reason * for this is that there is no collator available for the locale you requested. * In this case the database remains unchanged. */
public void setLocale(Locale locale) { 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; } } }
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.

Params:
Throws:
/** * 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). *<p> * 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. *<p> * This method is thread-safe. * * @param cacheSize the size of the cache. can be (0 to {@link #MAX_SQL_CACHE_SIZE}) * @throws IllegalStateException if input cacheSize > {@link #MAX_SQL_CACHE_SIZE}. */
public void setMaxSqlCacheSize(int cacheSize) { 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; } } }
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 openOrCreateDatabase or in the 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 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.

Params:
  • enable – True to enable foreign key constraints, false to disable them.
Throws:
/** * Sets whether foreign key constraints are enabled for the database. * <p> * 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. * </p><p> * A good time to call this method is right after calling {@link #openOrCreateDatabase} * or in the {@link SQLiteOpenHelper#onConfigure} callback. * </p><p> * 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}. * </p><p> * This method must not be called while a transaction is in progress. * </p><p> * See also <a href="http://sqlite.org/foreignkeys.html">SQLite Foreign Key Constraints</a> * for more details about foreign key constraint support. * </p> * * @param enable True to enable foreign key constraints, false to disable them. * * @throws IllegalStateException if the are transactions is in progress * when this method is called. */
public void setForeignKeyConstraintsEnabled(boolean enable) { synchronized (mLock) { throwIfNotOpenLocked(); if (mConfigurationLocked.foreignKeyConstraintsEnabled == enable) { return; } mConfigurationLocked.foreignKeyConstraintsEnabled = enable; try { mConnectionPoolLocked.reconfigure(mConfigurationLocked); } catch (RuntimeException ex) { mConfigurationLocked.foreignKeyConstraintsEnabled = !enable; throw ex; } } }
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 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 beginTransactionNonExclusive() or 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, enableWriteAheadLogging returns false.

The best way to enable write-ahead logging is to pass the ENABLE_WRITE_AHEAD_LOGGING flag to openDatabase. This is more efficient than calling enableWriteAheadLogging.

    SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory,
            SQLiteDatabase.CREATE_IF_NECESSARY | SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING,
            myDatabaseErrorHandler);

Another way to enable write-ahead logging is to call 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.

Throws:
  • IllegalStateException – if there are transactions in progress at the time this method is called. WAL mode can only be changed when there are no transactions in progress.
See Also:
Returns:True if write-ahead logging is enabled.
/** * 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. * <p> * 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. * </p><p> * 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. * </p><p> * 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. * </p><p> * 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. * </p><p> * The maximum number of connections used to execute queries in parallel is * dependent upon the device memory and possibly other properties. * </p><p> * If a query is part of a transaction, then it is executed on the same database handle the * transaction was begun. * </p><p> * 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. * </p><p> * 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. * </p><p> * 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}. * <code><pre> * SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory, * SQLiteDatabase.CREATE_IF_NECESSARY | SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING, * myDatabaseErrorHandler); * </pre></code> * </p><p> * Another way to enable write-ahead logging is to call {@link #enableWriteAheadLogging} * after opening the database. * <code><pre> * SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory, * SQLiteDatabase.CREATE_IF_NECESSARY, myDatabaseErrorHandler); * db.enableWriteAheadLogging(); * </pre></code> * </p><p> * See also <a href="http://sqlite.org/wal.html">SQLite Write-Ahead Logging</a> for * more details about how write-ahead logging works. * </p> * * @return True if write-ahead logging is enabled. * * @throws IllegalStateException if there are transactions in progress at the * time this method is called. WAL mode can only be changed when there are no * transactions in progress. * * @see #ENABLE_WRITE_AHEAD_LOGGING * @see #disableWriteAheadLogging */
public boolean enableWriteAheadLogging() { 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; }
This method disables the features enabled by enableWriteAheadLogging().
Throws:
  • IllegalStateException – if there are transactions in progress at the time this method is called. WAL mode can only be changed when there are no transactions in progress.
See Also:
/** * This method disables the features enabled by {@link #enableWriteAheadLogging()}. * * @throws IllegalStateException if there are transactions in progress at the * time this method is called. WAL mode can only be changed when there are no * transactions in progress. * * @see #enableWriteAheadLogging */
public void disableWriteAheadLogging() { synchronized (mLock) { throwIfNotOpenLocked(); final int oldFlags = mConfigurationLocked.openFlags; final boolean walDisabled = (oldFlags & ENABLE_WRITE_AHEAD_LOGGING) == 0; final boolean compatibilityWalDisabled = (oldFlags & DISABLE_COMPATIBILITY_WAL) != 0; if (walDisabled && compatibilityWalDisabled) { return; } mConfigurationLocked.openFlags &= ~ENABLE_WRITE_AHEAD_LOGGING; // If an app explicitly disables WAL, compatibility mode should be disabled too mConfigurationLocked.openFlags |= DISABLE_COMPATIBILITY_WAL; try { mConnectionPoolLocked.reconfigure(mConfigurationLocked); } catch (RuntimeException ex) { mConfigurationLocked.openFlags = oldFlags; throw ex; } } }
Returns true if write-ahead logging has been enabled for this database.
See Also:
Returns:True if write-ahead logging has been enabled for this database.
/** * Returns true if write-ahead logging has been enabled for this database. * * @return True if write-ahead logging has been enabled for this database. * * @see #enableWriteAheadLogging * @see #ENABLE_WRITE_AHEAD_LOGGING */
public boolean isWriteAheadLoggingEnabled() { synchronized (mLock) { throwIfNotOpenLocked(); return (mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) != 0; } }
Collect statistics about all open databases in the current process. Used by bug report.
/** * Collect statistics about all open databases in the current process. * Used by bug report. */
static ArrayList<DbStats> getDbStats() { ArrayList<DbStats> dbStatsList = new ArrayList<DbStats>(); for (SQLiteDatabase db : getActiveDatabases()) { db.collectDbStats(dbStatsList); } return dbStatsList; } private void collectDbStats(ArrayList<DbStats> dbStatsList) { synchronized (mLock) { if (mConnectionPoolLocked != null) { mConnectionPoolLocked.collectDbStats(dbStatsList); } } } private static ArrayList<SQLiteDatabase> getActiveDatabases() { ArrayList<SQLiteDatabase> databases = new ArrayList<SQLiteDatabase>(); synchronized (sActiveDatabases) { databases.addAll(sActiveDatabases.keySet()); } return databases; }
Dump detailed information about all open databases in the current process. Used by bug report.
/** * Dump detailed information about all open databases in the current process. * Used by bug report. */
static void dumpAll(Printer printer, boolean verbose) { for (SQLiteDatabase db : getActiveDatabases()) { db.dump(printer, verbose); } } private void dump(Printer printer, boolean verbose) { synchronized (mLock) { if (mConnectionPoolLocked != null) { printer.println(""); mConnectionPoolLocked.dump(printer, verbose); } } }
Returns list of full pathnames of all attached databases including the main database by executing 'pragma database_list' on the database.
Returns:ArrayList of pairs of (database name, database file path) or null if the database is not open.
/** * Returns list of full pathnames of all attached databases including the main database * by executing 'pragma database_list' on the database. * * @return ArrayList of pairs of (database name, database file path) or null if the database * is not open. */
public List<Pair<String, String>> getAttachedDbs() { 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(); } }
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.

Returns:true if the given database (and all its attached databases) pass integrity_check, false otherwise.
/** * 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. *<p> * If the result is false, then this method logs the errors reported by the integrity_check * command execution. *<p> * Note that 'pragma integrity_check' on a database can take a long time. * * @return true if the given database (and all its attached databases) pass integrity_check, * false otherwise. */
public boolean isDatabaseIntegrityOk() { 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; } @Override public String toString() { return "SQLiteDatabase: " + getPath(); } private void throwIfNotOpenLocked() { if (mConnectionPoolLocked == null) { throw new IllegalStateException("The database '" + mConfigurationLocked.label + "' is not open."); } }
Used to allow returning sub-classes of Cursor when calling query.
/** * Used to allow returning sub-classes of {@link Cursor} when calling query. */
public interface CursorFactory { /** * See {@link SQLiteCursor#SQLiteCursor(SQLiteCursorDriver, String, SQLiteQuery)}. */ public Cursor newCursor(SQLiteDatabase db, SQLiteCursorDriver masterQuery, String editTable, SQLiteQuery query); }
A callback interface for a custom sqlite3 function. This can be used to create a function that can be called from sqlite3 database triggers.
@hide
/** * A callback interface for a custom sqlite3 function. * This can be used to create a function that can be called from * sqlite3 database triggers. * @hide */
public interface CustomFunction { public void callback(String[] args); }
Wrapper for configuration parameters that are used for opening SQLiteDatabase
/** * Wrapper for configuration parameters that are used for opening {@link SQLiteDatabase} */
public static final class OpenParams { private final int mOpenFlags; private final CursorFactory mCursorFactory; private final DatabaseErrorHandler mErrorHandler; private final int mLookasideSlotSize; private final int mLookasideSlotCount; private final long mIdleConnectionTimeout; private final String mJournalMode; private final String mSyncMode; private OpenParams(int openFlags, CursorFactory cursorFactory, DatabaseErrorHandler errorHandler, int lookasideSlotSize, int lookasideSlotCount, long idleConnectionTimeout, String journalMode, String syncMode) { mOpenFlags = openFlags; mCursorFactory = cursorFactory; mErrorHandler = errorHandler; mLookasideSlotSize = lookasideSlotSize; mLookasideSlotCount = lookasideSlotCount; mIdleConnectionTimeout = idleConnectionTimeout; mJournalMode = journalMode; mSyncMode = syncMode; }
Returns size in bytes of each lookaside slot or -1 if not set.
See Also:
  • setLookasideConfig.setLookasideConfig(int, int)
/** * Returns size in bytes of each lookaside slot or -1 if not set. * * @see Builder#setLookasideConfig(int, int) */
@IntRange(from = -1) public int getLookasideSlotSize() { return mLookasideSlotSize; }
Returns total number of lookaside memory slots per database connection or -1 if not set.
See Also:
  • setLookasideConfig.setLookasideConfig(int, int)
/** * Returns total number of lookaside memory slots per database connection or -1 if not * set. * * @see Builder#setLookasideConfig(int, int) */
@IntRange(from = -1) public int getLookasideSlotCount() { return mLookasideSlotCount; }
Returns flags to control database access mode. Default value is 0.
See Also:
  • setOpenFlags.setOpenFlags(int)
/** * Returns flags to control database access mode. Default value is 0. * * @see Builder#setOpenFlags(int) */
@DatabaseOpenFlags public int getOpenFlags() { return mOpenFlags; }
Returns an optional factory class that is called to instantiate a cursor when query is called
See Also:
  • setCursorFactory.setCursorFactory(CursorFactory)
/** * Returns an optional factory class that is called to instantiate a cursor when query * is called * * @see Builder#setCursorFactory(CursorFactory) */
@Nullable public CursorFactory getCursorFactory() { return mCursorFactory; }
Returns handler for database corruption errors
See Also:
  • setErrorHandler.setErrorHandler(DatabaseErrorHandler)
/** * Returns handler for database corruption errors * * @see Builder#setErrorHandler(DatabaseErrorHandler) */
@Nullable public DatabaseErrorHandler getErrorHandler() { return mErrorHandler; }
Returns maximum number of milliseconds that SQLite connection is allowed to be idle before it is closed and removed from the pool.

If the value isn't set, the timeout defaults to the system wide timeout

Returns:timeout in milliseconds or -1 if the value wasn't set.
/** * Returns maximum number of milliseconds that SQLite connection is allowed to be idle * before it is closed and removed from the pool. * <p>If the value isn't set, the timeout defaults to the system wide timeout * * @return timeout in milliseconds or -1 if the value wasn't set. */
public long getIdleConnectionTimeout() { return mIdleConnectionTimeout; }
Returns journal mode. This journal mode will only be used if SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING flag is not set, otherwise a platform will use "WAL" journal mode.
See Also:
/** * Returns <a href="https://sqlite.org/pragma.html#pragma_journal_mode">journal mode</a>. * This journal mode will only be used if {@link SQLiteDatabase#ENABLE_WRITE_AHEAD_LOGGING} * flag is not set, otherwise a platform will use "WAL" journal mode. * @see Builder#setJournalMode(String) */
@Nullable public String getJournalMode() { return mJournalMode; }
Returns synchronous mode. If not set, a system wide default will be used.
See Also:
  • setSynchronousMode.setSynchronousMode(String)
/** * Returns <a href="https://sqlite.org/pragma.html#pragma_synchronous">synchronous mode</a>. * If not set, a system wide default will be used. * @see Builder#setSynchronousMode(String) */
@Nullable public String getSynchronousMode() { return mSyncMode; }
Creates a new instance of builder initialized with this parameters.
@hide
/** * Creates a new instance of builder {@link Builder#Builder(OpenParams) initialized} with * {@code this} parameters. * @hide */
@NonNull public Builder toBuilder() { return new Builder(this); }
Builder for OpenParams.
/** * Builder for {@link OpenParams}. */
public static final class Builder { private int mLookasideSlotSize = -1; private int mLookasideSlotCount = -1; private long mIdleConnectionTimeout = -1; private int mOpenFlags; private CursorFactory mCursorFactory; private DatabaseErrorHandler mErrorHandler; private String mJournalMode; private String mSyncMode; public Builder() { } public Builder(OpenParams params) { mLookasideSlotSize = params.mLookasideSlotSize; mLookasideSlotCount = params.mLookasideSlotCount; mOpenFlags = params.mOpenFlags; mCursorFactory = params.mCursorFactory; mErrorHandler = params.mErrorHandler; mJournalMode = params.mJournalMode; mSyncMode = params.mSyncMode; }
Configures lookaside memory allocator

SQLite default settings will be used, if this method isn't called. Use setLookasideConfig(0,0) to disable lookaside

Note: Provided slotSize/slotCount configuration is just a recommendation. The system may choose different values depending on a device, e.g. lookaside allocations can be disabled on low-RAM devices

Params:
  • slotSize – The size in bytes of each lookaside slot.
  • slotCount – The total number of lookaside memory slots per database connection.
/** * Configures * <a href="https://sqlite.org/malloc.html#lookaside">lookaside memory allocator</a> * * <p>SQLite default settings will be used, if this method isn't called. * Use {@code setLookasideConfig(0,0)} to disable lookaside * * <p><strong>Note:</strong> Provided slotSize/slotCount configuration is just a * recommendation. The system may choose different values depending on a device, e.g. * lookaside allocations can be disabled on low-RAM devices * * @param slotSize The size in bytes of each lookaside slot. * @param slotCount The total number of lookaside memory slots per database connection. */
public Builder setLookasideConfig(@IntRange(from = 0) final int slotSize, @IntRange(from = 0) final int slotCount) { Preconditions.checkArgument(slotSize >= 0, "lookasideSlotCount cannot be negative"); Preconditions.checkArgument(slotCount >= 0, "lookasideSlotSize cannot be negative"); Preconditions.checkArgument( (slotSize > 0 && slotCount > 0) || (slotCount == 0 && slotSize == 0), "Invalid configuration: " + slotSize + ", " + slotCount); mLookasideSlotSize = slotSize; mLookasideSlotCount = slotCount; return this; }
Returns true if SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING flag is set
@hide
/** * Returns true if {@link #ENABLE_WRITE_AHEAD_LOGGING} flag is set * @hide */
public boolean isWriteAheadLoggingEnabled() { return (mOpenFlags & ENABLE_WRITE_AHEAD_LOGGING) != 0; }
Sets flags to control database access mode
Params:
  • openFlags – The new flags to set
See Also:
Returns:same builder instance for chaining multiple calls into a single statement
/** * Sets flags to control database access mode * @param openFlags The new flags to set * @see #OPEN_READWRITE * @see #OPEN_READONLY * @see #CREATE_IF_NECESSARY * @see #NO_LOCALIZED_COLLATORS * @see #ENABLE_WRITE_AHEAD_LOGGING * @return same builder instance for chaining multiple calls into a single statement */
@NonNull public Builder setOpenFlags(@DatabaseOpenFlags int openFlags) { mOpenFlags = openFlags; return this; }
Adds flags to control database access mode
Params:
  • openFlags – The new flags to add
Returns:same builder instance for chaining multiple calls into a single statement
/** * Adds flags to control database access mode * * @param openFlags The new flags to add * @return same builder instance for chaining multiple calls into a single statement */
@NonNull public Builder addOpenFlags(@DatabaseOpenFlags int openFlags) { mOpenFlags |= openFlags; return this; }
Removes database access mode flags
Params:
  • openFlags – Flags to remove
Returns:same builder instance for chaining multiple calls into a single statement
/** * Removes database access mode flags * * @param openFlags Flags to remove * @return same builder instance for chaining multiple calls into a single statement */
@NonNull public Builder removeOpenFlags(@DatabaseOpenFlags int openFlags) { mOpenFlags &= ~openFlags; return this; }
Sets SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING flag if enabled is true, unsets otherwise
@hide
/** * Sets {@link #ENABLE_WRITE_AHEAD_LOGGING} flag if {@code enabled} is {@code true}, * unsets otherwise * @hide */
public void setWriteAheadLoggingEnabled(boolean enabled) { if (enabled) { addOpenFlags(ENABLE_WRITE_AHEAD_LOGGING); } else { removeOpenFlags(ENABLE_WRITE_AHEAD_LOGGING); } }
Set an optional factory class that is called to instantiate a cursor when query is called.
Params:
  • cursorFactory – instance
Returns:same builder instance for chaining multiple calls into a single statement
/** * Set an optional factory class that is called to instantiate a cursor when query * is called. * * @param cursorFactory instance * @return same builder instance for chaining multiple calls into a single statement */
@NonNull public Builder setCursorFactory(@Nullable CursorFactory cursorFactory) { mCursorFactory = cursorFactory; return this; }
Sets DatabaseErrorHandler object to handle db corruption errors
/** * Sets {@link DatabaseErrorHandler} object to handle db corruption errors */
@NonNull public Builder setErrorHandler(@Nullable DatabaseErrorHandler errorHandler) { mErrorHandler = errorHandler; return this; }
Sets the maximum number of milliseconds that SQLite connection is allowed to be idle before it is closed and removed from the pool.
Params:
  • idleConnectionTimeoutMs – timeout in milliseconds. Use Long.MAX_VALUE to allow unlimited idle connections.
/** * Sets the maximum number of milliseconds that SQLite connection is allowed to be idle * before it is closed and removed from the pool. * * @param idleConnectionTimeoutMs timeout in milliseconds. Use {@link Long#MAX_VALUE} * to allow unlimited idle connections. */
@NonNull public Builder setIdleConnectionTimeout( @IntRange(from = 0) long idleConnectionTimeoutMs) { Preconditions.checkArgument(idleConnectionTimeoutMs >= 0, "idle connection timeout cannot be negative"); mIdleConnectionTimeout = idleConnectionTimeoutMs; return this; }
Sets journal mode to use when SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING flag is not set.
/** * Sets <a href="https://sqlite.org/pragma.html#pragma_journal_mode">journal mode</a> * to use when {@link SQLiteDatabase#ENABLE_WRITE_AHEAD_LOGGING} flag is not set. */
@NonNull public Builder setJournalMode(@NonNull String journalMode) { Preconditions.checkNotNull(journalMode); mJournalMode = journalMode; return this; }
Returns:
/** * Sets <a href="https://sqlite.org/pragma.html#pragma_synchronous">synchronous mode</a> * . * @return */
@NonNull public Builder setSynchronousMode(@NonNull String syncMode) { Preconditions.checkNotNull(syncMode); mSyncMode = syncMode; return this; }
Creates an instance of OpenParams with the options that were previously set on this builder
/** * Creates an instance of {@link OpenParams} with the options that were previously set * on this builder */
@NonNull public OpenParams build() { return new OpenParams(mOpenFlags, mCursorFactory, mErrorHandler, mLookasideSlotSize, mLookasideSlotCount, mIdleConnectionTimeout, mJournalMode, mSyncMode); } } }
@hide
/** @hide */
@IntDef(flag = true, prefix = {"OPEN_", "CREATE_", "NO_", "ENABLE_"}, value = { OPEN_READWRITE, OPEN_READONLY, CREATE_IF_NECESSARY, NO_LOCALIZED_COLLATORS, ENABLE_WRITE_AHEAD_LOGGING }) @Retention(RetentionPolicy.SOURCE) public @interface DatabaseOpenFlags {} }