Home | History | Annotate | Download | only in sqlite
      1 /*
      2  * Copyright (C) 2006 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.database.sqlite;
     18 
     19 import android.content.ContentValues;
     20 import android.database.Cursor;
     21 import android.database.DatabaseErrorHandler;
     22 import android.database.DatabaseUtils;
     23 import android.database.DefaultDatabaseErrorHandler;
     24 import android.database.SQLException;
     25 import android.database.sqlite.SQLiteDebug.DbStats;
     26 import android.os.CancellationSignal;
     27 import android.os.Looper;
     28 import android.os.OperationCanceledException;
     29 import android.text.TextUtils;
     30 import android.util.EventLog;
     31 import android.util.Log;
     32 import android.util.Pair;
     33 import android.util.Printer;
     34 
     35 import dalvik.system.CloseGuard;
     36 
     37 import java.io.File;
     38 import java.io.FileFilter;
     39 import java.util.ArrayList;
     40 import java.util.HashMap;
     41 import java.util.List;
     42 import java.util.Locale;
     43 import java.util.Map;
     44 import java.util.WeakHashMap;
     45 
     46 /**
     47  * Exposes methods to manage a SQLite database.
     48  *
     49  * <p>
     50  * SQLiteDatabase has methods to create, delete, execute SQL commands, and
     51  * perform other common database management tasks.
     52  * </p><p>
     53  * See the Notepad sample application in the SDK for an example of creating
     54  * and managing a database.
     55  * </p><p>
     56  * Database names must be unique within an application, not across all applications.
     57  * </p>
     58  *
     59  * <h3>Localized Collation - ORDER BY</h3>
     60  * <p>
     61  * In addition to SQLite's default <code>BINARY</code> collator, Android supplies
     62  * two more, <code>LOCALIZED</code>, which changes with the system's current locale,
     63  * and <code>UNICODE</code>, which is the Unicode Collation Algorithm and not tailored
     64  * to the current locale.
     65  * </p>
     66  */
     67 public final class SQLiteDatabase extends SQLiteClosable {
     68     private static final String TAG = "SQLiteDatabase";
     69 
     70     private static final int EVENT_DB_CORRUPT = 75004;
     71 
     72     // Stores reference to all databases opened in the current process.
     73     // (The referent Object is not used at this time.)
     74     // INVARIANT: Guarded by sActiveDatabases.
     75     private static WeakHashMap<SQLiteDatabase, Object> sActiveDatabases =
     76             new WeakHashMap<SQLiteDatabase, Object>();
     77 
     78     // Thread-local for database sessions that belong to this database.
     79     // Each thread has its own database session.
     80     // INVARIANT: Immutable.
     81     private final ThreadLocal<SQLiteSession> mThreadSession = new ThreadLocal<SQLiteSession>() {
     82         @Override
     83         protected SQLiteSession initialValue() {
     84             return createSession();
     85         }
     86     };
     87 
     88     // The optional factory to use when creating new Cursors.  May be null.
     89     // INVARIANT: Immutable.
     90     private final CursorFactory mCursorFactory;
     91 
     92     // Error handler to be used when SQLite returns corruption errors.
     93     // INVARIANT: Immutable.
     94     private final DatabaseErrorHandler mErrorHandler;
     95 
     96     // Shared database state lock.
     97     // This lock guards all of the shared state of the database, such as its
     98     // configuration, whether it is open or closed, and so on.  This lock should
     99     // be held for as little time as possible.
    100     //
    101     // The lock MUST NOT be held while attempting to acquire database connections or
    102     // while executing SQL statements on behalf of the client as it can lead to deadlock.
    103     //
    104     // It is ok to hold the lock while reconfiguring the connection pool or dumping
    105     // statistics because those operations are non-reentrant and do not try to acquire
    106     // connections that might be held by other threads.
    107     //
    108     // Basic rule: grab the lock, access or modify global state, release the lock, then
    109     // do the required SQL work.
    110     private final Object mLock = new Object();
    111 
    112     // Warns if the database is finalized without being closed properly.
    113     // INVARIANT: Guarded by mLock.
    114     private final CloseGuard mCloseGuardLocked = CloseGuard.get();
    115 
    116     // The database configuration.
    117     // INVARIANT: Guarded by mLock.
    118     private final SQLiteDatabaseConfiguration mConfigurationLocked;
    119 
    120     // The connection pool for the database, null when closed.
    121     // The pool itself is thread-safe, but the reference to it can only be acquired
    122     // when the lock is held.
    123     // INVARIANT: Guarded by mLock.
    124     private SQLiteConnectionPool mConnectionPoolLocked;
    125 
    126     // True if the database has attached databases.
    127     // INVARIANT: Guarded by mLock.
    128     private boolean mHasAttachedDbsLocked;
    129 
    130     /**
    131      * When a constraint violation occurs, an immediate ROLLBACK occurs,
    132      * thus ending the current transaction, and the command aborts with a
    133      * return code of SQLITE_CONSTRAINT. If no transaction is active
    134      * (other than the implied transaction that is created on every command)
    135      * then this algorithm works the same as ABORT.
    136      */
    137     public static final int CONFLICT_ROLLBACK = 1;
    138 
    139     /**
    140      * When a constraint violation occurs,no ROLLBACK is executed
    141      * so changes from prior commands within the same transaction
    142      * are preserved. This is the default behavior.
    143      */
    144     public static final int CONFLICT_ABORT = 2;
    145 
    146     /**
    147      * When a constraint violation occurs, the command aborts with a return
    148      * code SQLITE_CONSTRAINT. But any changes to the database that
    149      * the command made prior to encountering the constraint violation
    150      * are preserved and are not backed out.
    151      */
    152     public static final int CONFLICT_FAIL = 3;
    153 
    154     /**
    155      * When a constraint violation occurs, the one row that contains
    156      * the constraint violation is not inserted or changed.
    157      * But the command continues executing normally. Other rows before and
    158      * after the row that contained the constraint violation continue to be
    159      * inserted or updated normally. No error is returned.
    160      */
    161     public static final int CONFLICT_IGNORE = 4;
    162 
    163     /**
    164      * When a UNIQUE constraint violation occurs, the pre-existing rows that
    165      * are causing the constraint violation are removed prior to inserting
    166      * or updating the current row. Thus the insert or update always occurs.
    167      * The command continues executing normally. No error is returned.
    168      * If a NOT NULL constraint violation occurs, the NULL value is replaced
    169      * by the default value for that column. If the column has no default
    170      * value, then the ABORT algorithm is used. If a CHECK constraint
    171      * violation occurs then the IGNORE algorithm is used. When this conflict
    172      * resolution strategy deletes rows in order to satisfy a constraint,
    173      * it does not invoke delete triggers on those rows.
    174      * This behavior might change in a future release.
    175      */
    176     public static final int CONFLICT_REPLACE = 5;
    177 
    178     /**
    179      * Use the following when no conflict action is specified.
    180      */
    181     public static final int CONFLICT_NONE = 0;
    182 
    183     private static final String[] CONFLICT_VALUES = new String[]
    184             {"", " OR ROLLBACK ", " OR ABORT ", " OR FAIL ", " OR IGNORE ", " OR REPLACE "};
    185 
    186     /**
    187      * Maximum Length Of A LIKE Or GLOB Pattern
    188      * The pattern matching algorithm used in the default LIKE and GLOB implementation
    189      * of SQLite can exhibit O(N^2) performance (where N is the number of characters in
    190      * the pattern) for certain pathological cases. To avoid denial-of-service attacks
    191      * the length of the LIKE or GLOB pattern is limited to SQLITE_MAX_LIKE_PATTERN_LENGTH bytes.
    192      * The default value of this limit is 50000. A modern workstation can evaluate
    193      * even a pathological LIKE or GLOB pattern of 50000 bytes relatively quickly.
    194      * The denial of service problem only comes into play when the pattern length gets
    195      * into millions of bytes. Nevertheless, since most useful LIKE or GLOB patterns
    196      * are at most a few dozen bytes in length, paranoid application developers may
    197      * want to reduce this parameter to something in the range of a few hundred
    198      * if they know that external users are able to generate arbitrary patterns.
    199      */
    200     public static final int SQLITE_MAX_LIKE_PATTERN_LENGTH = 50000;
    201 
    202     /**
    203      * Open flag: Flag for {@link #openDatabase} to open the database for reading and writing.
    204      * If the disk is full, this may fail even before you actually write anything.
    205      *
    206      * {@more} Note that the value of this flag is 0, so it is the default.
    207      */
    208     public static final int OPEN_READWRITE = 0x00000000;          // update native code if changing
    209 
    210     /**
    211      * Open flag: Flag for {@link #openDatabase} to open the database for reading only.
    212      * This is the only reliable way to open a database if the disk may be full.
    213      */
    214     public static final int OPEN_READONLY = 0x00000001;           // update native code if changing
    215 
    216     private static final int OPEN_READ_MASK = 0x00000001;         // update native code if changing
    217 
    218     /**
    219      * Open flag: Flag for {@link #openDatabase} to open the database without support for
    220      * localized collators.
    221      *
    222      * {@more} This causes the collator <code>LOCALIZED</code> not to be created.
    223      * You must be consistent when using this flag to use the setting the database was
    224      * created with.  If this is set, {@link #setLocale} will do nothing.
    225      */
    226     public static final int NO_LOCALIZED_COLLATORS = 0x00000010;  // update native code if changing
    227 
    228     /**
    229      * Open flag: Flag for {@link #openDatabase} to create the database file if it does not
    230      * already exist.
    231      */
    232     public static final int CREATE_IF_NECESSARY = 0x10000000;     // update native code if changing
    233 
    234     /**
    235      * Open flag: Flag for {@link #openDatabase} to open the database file with
    236      * write-ahead logging enabled by default.  Using this flag is more efficient
    237      * than calling {@link #enableWriteAheadLogging}.
    238      *
    239      * Write-ahead logging cannot be used with read-only databases so the value of
    240      * this flag is ignored if the database is opened read-only.
    241      *
    242      * @see #enableWriteAheadLogging
    243      */
    244     public static final int ENABLE_WRITE_AHEAD_LOGGING = 0x20000000;
    245 
    246     /**
    247      * Absolute max value that can be set by {@link #setMaxSqlCacheSize(int)}.
    248      *
    249      * Each prepared-statement is between 1K - 6K, depending on the complexity of the
    250      * SQL statement & schema.  A large SQL cache may use a significant amount of memory.
    251      */
    252     public static final int MAX_SQL_CACHE_SIZE = 100;
    253 
    254     private SQLiteDatabase(String path, int openFlags, CursorFactory cursorFactory,
    255             DatabaseErrorHandler errorHandler) {
    256         mCursorFactory = cursorFactory;
    257         mErrorHandler = errorHandler != null ? errorHandler : new DefaultDatabaseErrorHandler();
    258         mConfigurationLocked = new SQLiteDatabaseConfiguration(path, openFlags);
    259     }
    260 
    261     @Override
    262     protected void finalize() throws Throwable {
    263         try {
    264             dispose(true);
    265         } finally {
    266             super.finalize();
    267         }
    268     }
    269 
    270     @Override
    271     protected void onAllReferencesReleased() {
    272         dispose(false);
    273     }
    274 
    275     private void dispose(boolean finalized) {
    276         final SQLiteConnectionPool pool;
    277         synchronized (mLock) {
    278             if (mCloseGuardLocked != null) {
    279                 if (finalized) {
    280                     mCloseGuardLocked.warnIfOpen();
    281                 }
    282                 mCloseGuardLocked.close();
    283             }
    284 
    285             pool = mConnectionPoolLocked;
    286             mConnectionPoolLocked = null;
    287         }
    288 
    289         if (!finalized) {
    290             synchronized (sActiveDatabases) {
    291                 sActiveDatabases.remove(this);
    292             }
    293 
    294             if (pool != null) {
    295                 pool.close();
    296             }
    297         }
    298     }
    299 
    300     /**
    301      * Attempts to release memory that SQLite holds but does not require to
    302      * operate properly. Typically this memory will come from the page cache.
    303      *
    304      * @return the number of bytes actually released
    305      */
    306     public static int releaseMemory() {
    307         return SQLiteGlobal.releaseMemory();
    308     }
    309 
    310     /**
    311      * Control whether or not the SQLiteDatabase is made thread-safe by using locks
    312      * around critical sections. This is pretty expensive, so if you know that your
    313      * DB will only be used by a single thread then you should set this to false.
    314      * The default is true.
    315      * @param lockingEnabled set to true to enable locks, false otherwise
    316      *
    317      * @deprecated This method now does nothing.  Do not use.
    318      */
    319     @Deprecated
    320     public void setLockingEnabled(boolean lockingEnabled) {
    321     }
    322 
    323     /**
    324      * Gets a label to use when describing the database in log messages.
    325      * @return The label.
    326      */
    327     String getLabel() {
    328         synchronized (mLock) {
    329             return mConfigurationLocked.label;
    330         }
    331     }
    332 
    333     /**
    334      * Sends a corruption message to the database error handler.
    335      */
    336     void onCorruption() {
    337         EventLog.writeEvent(EVENT_DB_CORRUPT, getLabel());
    338         mErrorHandler.onCorruption(this);
    339     }
    340 
    341     /**
    342      * Gets the {@link SQLiteSession} that belongs to this thread for this database.
    343      * Once a thread has obtained a session, it will continue to obtain the same
    344      * session even after the database has been closed (although the session will not
    345      * be usable).  However, a thread that does not already have a session cannot
    346      * obtain one after the database has been closed.
    347      *
    348      * The idea is that threads that have active connections to the database may still
    349      * have work to complete even after the call to {@link #close}.  Active database
    350      * connections are not actually disposed until they are released by the threads
    351      * that own them.
    352      *
    353      * @return The session, never null.
    354      *
    355      * @throws IllegalStateException if the thread does not yet have a session and
    356      * the database is not open.
    357      */
    358     SQLiteSession getThreadSession() {
    359         return mThreadSession.get(); // initialValue() throws if database closed
    360     }
    361 
    362     SQLiteSession createSession() {
    363         final SQLiteConnectionPool pool;
    364         synchronized (mLock) {
    365             throwIfNotOpenLocked();
    366             pool = mConnectionPoolLocked;
    367         }
    368         return new SQLiteSession(pool);
    369     }
    370 
    371     /**
    372      * Gets default connection flags that are appropriate for this thread, taking into
    373      * account whether the thread is acting on behalf of the UI.
    374      *
    375      * @param readOnly True if the connection should be read-only.
    376      * @return The connection flags.
    377      */
    378     int getThreadDefaultConnectionFlags(boolean readOnly) {
    379         int flags = readOnly ? SQLiteConnectionPool.CONNECTION_FLAG_READ_ONLY :
    380                 SQLiteConnectionPool.CONNECTION_FLAG_PRIMARY_CONNECTION_AFFINITY;
    381         if (isMainThread()) {
    382             flags |= SQLiteConnectionPool.CONNECTION_FLAG_INTERACTIVE;
    383         }
    384         return flags;
    385     }
    386 
    387     private static boolean isMainThread() {
    388         // FIXME: There should be a better way to do this.
    389         // Would also be nice to have something that would work across Binder calls.
    390         Looper looper = Looper.myLooper();
    391         return looper != null && looper == Looper.getMainLooper();
    392     }
    393 
    394     /**
    395      * Begins a transaction in EXCLUSIVE mode.
    396      * <p>
    397      * Transactions can be nested.
    398      * When the outer transaction is ended all of
    399      * the work done in that transaction and all of the nested transactions will be committed or
    400      * rolled back. The changes will be rolled back if any transaction is ended without being
    401      * marked as clean (by calling setTransactionSuccessful). Otherwise they will be committed.
    402      * </p>
    403      * <p>Here is the standard idiom for transactions:
    404      *
    405      * <pre>
    406      *   db.beginTransaction();
    407      *   try {
    408      *     ...
    409      *     db.setTransactionSuccessful();
    410      *   } finally {
    411      *     db.endTransaction();
    412      *   }
    413      * </pre>
    414      */
    415     public void beginTransaction() {
    416         beginTransaction(null /* transactionStatusCallback */, true);
    417     }
    418 
    419     /**
    420      * Begins a transaction in IMMEDIATE mode. Transactions can be nested. When
    421      * the outer transaction is ended all of the work done in that transaction
    422      * and all of the nested transactions will be committed or rolled back. The
    423      * changes will be rolled back if any transaction is ended without being
    424      * marked as clean (by calling setTransactionSuccessful). Otherwise they
    425      * will be committed.
    426      * <p>
    427      * Here is the standard idiom for transactions:
    428      *
    429      * <pre>
    430      *   db.beginTransactionNonExclusive();
    431      *   try {
    432      *     ...
    433      *     db.setTransactionSuccessful();
    434      *   } finally {
    435      *     db.endTransaction();
    436      *   }
    437      * </pre>
    438      */
    439     public void beginTransactionNonExclusive() {
    440         beginTransaction(null /* transactionStatusCallback */, false);
    441     }
    442 
    443     /**
    444      * Begins a transaction in EXCLUSIVE mode.
    445      * <p>
    446      * Transactions can be nested.
    447      * When the outer transaction is ended all of
    448      * the work done in that transaction and all of the nested transactions will be committed or
    449      * rolled back. The changes will be rolled back if any transaction is ended without being
    450      * marked as clean (by calling setTransactionSuccessful). Otherwise they will be committed.
    451      * </p>
    452      * <p>Here is the standard idiom for transactions:
    453      *
    454      * <pre>
    455      *   db.beginTransactionWithListener(listener);
    456      *   try {
    457      *     ...
    458      *     db.setTransactionSuccessful();
    459      *   } finally {
    460      *     db.endTransaction();
    461      *   }
    462      * </pre>
    463      *
    464      * @param transactionListener listener that should be notified when the transaction begins,
    465      * commits, or is rolled back, either explicitly or by a call to
    466      * {@link #yieldIfContendedSafely}.
    467      */
    468     public void beginTransactionWithListener(SQLiteTransactionListener transactionListener) {
    469         beginTransaction(transactionListener, true);
    470     }
    471 
    472     /**
    473      * Begins a transaction in IMMEDIATE mode. Transactions can be nested. When
    474      * the outer transaction is ended all of the work done in that transaction
    475      * and all of the nested transactions will be committed or rolled back. The
    476      * changes will be rolled back if any transaction is ended without being
    477      * marked as clean (by calling setTransactionSuccessful). Otherwise they
    478      * will be committed.
    479      * <p>
    480      * Here is the standard idiom for transactions:
    481      *
    482      * <pre>
    483      *   db.beginTransactionWithListenerNonExclusive(listener);
    484      *   try {
    485      *     ...
    486      *     db.setTransactionSuccessful();
    487      *   } finally {
    488      *     db.endTransaction();
    489      *   }
    490      * </pre>
    491      *
    492      * @param transactionListener listener that should be notified when the
    493      *            transaction begins, commits, or is rolled back, either
    494      *            explicitly or by a call to {@link #yieldIfContendedSafely}.
    495      */
    496     public void beginTransactionWithListenerNonExclusive(
    497             SQLiteTransactionListener transactionListener) {
    498         beginTransaction(transactionListener, false);
    499     }
    500 
    501     private void beginTransaction(SQLiteTransactionListener transactionListener,
    502             boolean exclusive) {
    503         acquireReference();
    504         try {
    505             getThreadSession().beginTransaction(
    506                     exclusive ? SQLiteSession.TRANSACTION_MODE_EXCLUSIVE :
    507                             SQLiteSession.TRANSACTION_MODE_IMMEDIATE,
    508                     transactionListener,
    509                     getThreadDefaultConnectionFlags(false /*readOnly*/), null);
    510         } finally {
    511             releaseReference();
    512         }
    513     }
    514 
    515     /**
    516      * End a transaction. See beginTransaction for notes about how to use this and when transactions
    517      * are committed and rolled back.
    518      */
    519     public void endTransaction() {
    520         acquireReference();
    521         try {
    522             getThreadSession().endTransaction(null);
    523         } finally {
    524             releaseReference();
    525         }
    526     }
    527 
    528     /**
    529      * Marks the current transaction as successful. Do not do any more database work between
    530      * calling this and calling endTransaction. Do as little non-database work as possible in that
    531      * situation too. If any errors are encountered between this and endTransaction the transaction
    532      * will still be committed.
    533      *
    534      * @throws IllegalStateException if the current thread is not in a transaction or the
    535      * transaction is already marked as successful.
    536      */
    537     public void setTransactionSuccessful() {
    538         acquireReference();
    539         try {
    540             getThreadSession().setTransactionSuccessful();
    541         } finally {
    542             releaseReference();
    543         }
    544     }
    545 
    546     /**
    547      * Returns true if the current thread has a transaction pending.
    548      *
    549      * @return True if the current thread is in a transaction.
    550      */
    551     public boolean inTransaction() {
    552         acquireReference();
    553         try {
    554             return getThreadSession().hasTransaction();
    555         } finally {
    556             releaseReference();
    557         }
    558     }
    559 
    560     /**
    561      * Returns true if the current thread is holding an active connection to the database.
    562      * <p>
    563      * The name of this method comes from a time when having an active connection
    564      * to the database meant that the thread was holding an actual lock on the
    565      * database.  Nowadays, there is no longer a true "database lock" although threads
    566      * may block if they cannot acquire a database connection to perform a
    567      * particular operation.
    568      * </p>
    569      *
    570      * @return True if the current thread is holding an active connection to the database.
    571      */
    572     public boolean isDbLockedByCurrentThread() {
    573         acquireReference();
    574         try {
    575             return getThreadSession().hasConnection();
    576         } finally {
    577             releaseReference();
    578         }
    579     }
    580 
    581     /**
    582      * Always returns false.
    583      * <p>
    584      * There is no longer the concept of a database lock, so this method always returns false.
    585      * </p>
    586      *
    587      * @return False.
    588      * @deprecated Always returns false.  Do not use this method.
    589      */
    590     @Deprecated
    591     public boolean isDbLockedByOtherThreads() {
    592         return false;
    593     }
    594 
    595     /**
    596      * Temporarily end the transaction to let other threads run. The transaction is assumed to be
    597      * successful so far. Do not call setTransactionSuccessful before calling this. When this
    598      * returns a new transaction will have been created but not marked as successful.
    599      * @return true if the transaction was yielded
    600      * @deprecated if the db is locked more than once (becuase of nested transactions) then the lock
    601      *   will not be yielded. Use yieldIfContendedSafely instead.
    602      */
    603     @Deprecated
    604     public boolean yieldIfContended() {
    605         return yieldIfContendedHelper(false /* do not check yielding */,
    606                 -1 /* sleepAfterYieldDelay */);
    607     }
    608 
    609     /**
    610      * Temporarily end the transaction to let other threads run. The transaction is assumed to be
    611      * successful so far. Do not call setTransactionSuccessful before calling this. When this
    612      * returns a new transaction will have been created but not marked as successful. This assumes
    613      * that there are no nested transactions (beginTransaction has only been called once) and will
    614      * throw an exception if that is not the case.
    615      * @return true if the transaction was yielded
    616      */
    617     public boolean yieldIfContendedSafely() {
    618         return yieldIfContendedHelper(true /* check yielding */, -1 /* sleepAfterYieldDelay*/);
    619     }
    620 
    621     /**
    622      * Temporarily end the transaction to let other threads run. The transaction is assumed to be
    623      * successful so far. Do not call setTransactionSuccessful before calling this. When this
    624      * returns a new transaction will have been created but not marked as successful. This assumes
    625      * that there are no nested transactions (beginTransaction has only been called once) and will
    626      * throw an exception if that is not the case.
    627      * @param sleepAfterYieldDelay if > 0, sleep this long before starting a new transaction if
    628      *   the lock was actually yielded. This will allow other background threads to make some
    629      *   more progress than they would if we started the transaction immediately.
    630      * @return true if the transaction was yielded
    631      */
    632     public boolean yieldIfContendedSafely(long sleepAfterYieldDelay) {
    633         return yieldIfContendedHelper(true /* check yielding */, sleepAfterYieldDelay);
    634     }
    635 
    636     private boolean yieldIfContendedHelper(boolean throwIfUnsafe, long sleepAfterYieldDelay) {
    637         acquireReference();
    638         try {
    639             return getThreadSession().yieldTransaction(sleepAfterYieldDelay, throwIfUnsafe, null);
    640         } finally {
    641             releaseReference();
    642         }
    643     }
    644 
    645     /**
    646      * Deprecated.
    647      * @deprecated This method no longer serves any useful purpose and has been deprecated.
    648      */
    649     @Deprecated
    650     public Map<String, String> getSyncedTables() {
    651         return new HashMap<String, String>(0);
    652     }
    653 
    654     /**
    655      * Open the database according to the flags {@link #OPEN_READWRITE}
    656      * {@link #OPEN_READONLY} {@link #CREATE_IF_NECESSARY} and/or {@link #NO_LOCALIZED_COLLATORS}.
    657      *
    658      * <p>Sets the locale of the database to the  the system's current locale.
    659      * Call {@link #setLocale} if you would like something else.</p>
    660      *
    661      * @param path to database file to open and/or create
    662      * @param factory an optional factory class that is called to instantiate a
    663      *            cursor when query is called, or null for default
    664      * @param flags to control database access mode
    665      * @return the newly opened database
    666      * @throws SQLiteException if the database cannot be opened
    667      */
    668     public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags) {
    669         return openDatabase(path, factory, flags, null);
    670     }
    671 
    672     /**
    673      * Open the database according to the flags {@link #OPEN_READWRITE}
    674      * {@link #OPEN_READONLY} {@link #CREATE_IF_NECESSARY} and/or {@link #NO_LOCALIZED_COLLATORS}.
    675      *
    676      * <p>Sets the locale of the database to the  the system's current locale.
    677      * Call {@link #setLocale} if you would like something else.</p>
    678      *
    679      * <p>Accepts input param: a concrete instance of {@link DatabaseErrorHandler} to be
    680      * used to handle corruption when sqlite reports database corruption.</p>
    681      *
    682      * @param path to database file to open and/or create
    683      * @param factory an optional factory class that is called to instantiate a
    684      *            cursor when query is called, or null for default
    685      * @param flags to control database access mode
    686      * @param errorHandler the {@link DatabaseErrorHandler} obj to be used to handle corruption
    687      * when sqlite reports database corruption
    688      * @return the newly opened database
    689      * @throws SQLiteException if the database cannot be opened
    690      */
    691     public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags,
    692             DatabaseErrorHandler errorHandler) {
    693         SQLiteDatabase db = new SQLiteDatabase(path, flags, factory, errorHandler);
    694         db.open();
    695         return db;
    696     }
    697 
    698     /**
    699      * Equivalent to openDatabase(file.getPath(), factory, CREATE_IF_NECESSARY).
    700      */
    701     public static SQLiteDatabase openOrCreateDatabase(File file, CursorFactory factory) {
    702         return openOrCreateDatabase(file.getPath(), factory);
    703     }
    704 
    705     /**
    706      * Equivalent to openDatabase(path, factory, CREATE_IF_NECESSARY).
    707      */
    708     public static SQLiteDatabase openOrCreateDatabase(String path, CursorFactory factory) {
    709         return openDatabase(path, factory, CREATE_IF_NECESSARY, null);
    710     }
    711 
    712     /**
    713      * Equivalent to openDatabase(path, factory, CREATE_IF_NECESSARY, errorHandler).
    714      */
    715     public static SQLiteDatabase openOrCreateDatabase(String path, CursorFactory factory,
    716             DatabaseErrorHandler errorHandler) {
    717         return openDatabase(path, factory, CREATE_IF_NECESSARY, errorHandler);
    718     }
    719 
    720     /**
    721      * Deletes a database including its journal file and other auxiliary files
    722      * that may have been created by the database engine.
    723      *
    724      * @param file The database file path.
    725      * @return True if the database was successfully deleted.
    726      */
    727     public static boolean deleteDatabase(File file) {
    728         if (file == null) {
    729             throw new IllegalArgumentException("file must not be null");
    730         }
    731 
    732         boolean deleted = false;
    733         deleted |= file.delete();
    734         deleted |= new File(file.getPath() + "-journal").delete();
    735         deleted |= new File(file.getPath() + "-shm").delete();
    736         deleted |= new File(file.getPath() + "-wal").delete();
    737 
    738         File dir = file.getParentFile();
    739         if (dir != null) {
    740             final String prefix = file.getName() + "-mj";
    741             final FileFilter filter = new FileFilter() {
    742                 @Override
    743                 public boolean accept(File candidate) {
    744                     return candidate.getName().startsWith(prefix);
    745                 }
    746             };
    747             for (File masterJournal : dir.listFiles(filter)) {
    748                 deleted |= masterJournal.delete();
    749             }
    750         }
    751         return deleted;
    752     }
    753 
    754     /**
    755      * Reopens the database in read-write mode.
    756      * If the database is already read-write, does nothing.
    757      *
    758      * @throws SQLiteException if the database could not be reopened as requested, in which
    759      * case it remains open in read only mode.
    760      * @throws IllegalStateException if the database is not open.
    761      *
    762      * @see #isReadOnly()
    763      * @hide
    764      */
    765     public void reopenReadWrite() {
    766         synchronized (mLock) {
    767             throwIfNotOpenLocked();
    768 
    769             if (!isReadOnlyLocked()) {
    770                 return; // nothing to do
    771             }
    772 
    773             // Reopen the database in read-write mode.
    774             final int oldOpenFlags = mConfigurationLocked.openFlags;
    775             mConfigurationLocked.openFlags = (mConfigurationLocked.openFlags & ~OPEN_READ_MASK)
    776                     | OPEN_READWRITE;
    777             try {
    778                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
    779             } catch (RuntimeException ex) {
    780                 mConfigurationLocked.openFlags = oldOpenFlags;
    781                 throw ex;
    782             }
    783         }
    784     }
    785 
    786     private void open() {
    787         try {
    788             try {
    789                 openInner();
    790             } catch (SQLiteDatabaseCorruptException ex) {
    791                 onCorruption();
    792                 openInner();
    793             }
    794         } catch (SQLiteException ex) {
    795             Log.e(TAG, "Failed to open database '" + getLabel() + "'.", ex);
    796             close();
    797             throw ex;
    798         }
    799     }
    800 
    801     private void openInner() {
    802         synchronized (mLock) {
    803             assert mConnectionPoolLocked == null;
    804             mConnectionPoolLocked = SQLiteConnectionPool.open(mConfigurationLocked);
    805             mCloseGuardLocked.open("close");
    806         }
    807 
    808         synchronized (sActiveDatabases) {
    809             sActiveDatabases.put(this, null);
    810         }
    811     }
    812 
    813     /**
    814      * Create a memory backed SQLite database.  Its contents will be destroyed
    815      * when the database is closed.
    816      *
    817      * <p>Sets the locale of the database to the  the system's current locale.
    818      * Call {@link #setLocale} if you would like something else.</p>
    819      *
    820      * @param factory an optional factory class that is called to instantiate a
    821      *            cursor when query is called
    822      * @return a SQLiteDatabase object, or null if the database can't be created
    823      */
    824     public static SQLiteDatabase create(CursorFactory factory) {
    825         // This is a magic string with special meaning for SQLite.
    826         return openDatabase(SQLiteDatabaseConfiguration.MEMORY_DB_PATH,
    827                 factory, CREATE_IF_NECESSARY);
    828     }
    829 
    830     /**
    831      * Registers a CustomFunction callback as a function that can be called from
    832      * SQLite database triggers.
    833      *
    834      * @param name the name of the sqlite3 function
    835      * @param numArgs the number of arguments for the function
    836      * @param function callback to call when the function is executed
    837      * @hide
    838      */
    839     public void addCustomFunction(String name, int numArgs, CustomFunction function) {
    840         // Create wrapper (also validates arguments).
    841         SQLiteCustomFunction wrapper = new SQLiteCustomFunction(name, numArgs, function);
    842 
    843         synchronized (mLock) {
    844             throwIfNotOpenLocked();
    845 
    846             mConfigurationLocked.customFunctions.add(wrapper);
    847             try {
    848                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
    849             } catch (RuntimeException ex) {
    850                 mConfigurationLocked.customFunctions.remove(wrapper);
    851                 throw ex;
    852             }
    853         }
    854     }
    855 
    856     /**
    857      * Gets the database version.
    858      *
    859      * @return the database version
    860      */
    861     public int getVersion() {
    862         return ((Long) DatabaseUtils.longForQuery(this, "PRAGMA user_version;", null)).intValue();
    863     }
    864 
    865     /**
    866      * Sets the database version.
    867      *
    868      * @param version the new database version
    869      */
    870     public void setVersion(int version) {
    871         execSQL("PRAGMA user_version = " + version);
    872     }
    873 
    874     /**
    875      * Returns the maximum size the database may grow to.
    876      *
    877      * @return the new maximum database size
    878      */
    879     public long getMaximumSize() {
    880         long pageCount = DatabaseUtils.longForQuery(this, "PRAGMA max_page_count;", null);
    881         return pageCount * getPageSize();
    882     }
    883 
    884     /**
    885      * Sets the maximum size the database will grow to. The maximum size cannot
    886      * be set below the current size.
    887      *
    888      * @param numBytes the maximum database size, in bytes
    889      * @return the new maximum database size
    890      */
    891     public long setMaximumSize(long numBytes) {
    892         long pageSize = getPageSize();
    893         long numPages = numBytes / pageSize;
    894         // If numBytes isn't a multiple of pageSize, bump up a page
    895         if ((numBytes % pageSize) != 0) {
    896             numPages++;
    897         }
    898         long newPageCount = DatabaseUtils.longForQuery(this, "PRAGMA max_page_count = " + numPages,
    899                 null);
    900         return newPageCount * pageSize;
    901     }
    902 
    903     /**
    904      * Returns the current database page size, in bytes.
    905      *
    906      * @return the database page size, in bytes
    907      */
    908     public long getPageSize() {
    909         return DatabaseUtils.longForQuery(this, "PRAGMA page_size;", null);
    910     }
    911 
    912     /**
    913      * Sets the database page size. The page size must be a power of two. This
    914      * method does not work if any data has been written to the database file,
    915      * and must be called right after the database has been created.
    916      *
    917      * @param numBytes the database page size, in bytes
    918      */
    919     public void setPageSize(long numBytes) {
    920         execSQL("PRAGMA page_size = " + numBytes);
    921     }
    922 
    923     /**
    924      * Mark this table as syncable. When an update occurs in this table the
    925      * _sync_dirty field will be set to ensure proper syncing operation.
    926      *
    927      * @param table the table to mark as syncable
    928      * @param deletedTable The deleted table that corresponds to the
    929      *          syncable table
    930      * @deprecated This method no longer serves any useful purpose and has been deprecated.
    931      */
    932     @Deprecated
    933     public void markTableSyncable(String table, String deletedTable) {
    934     }
    935 
    936     /**
    937      * Mark this table as syncable, with the _sync_dirty residing in another
    938      * table. When an update occurs in this table the _sync_dirty field of the
    939      * row in updateTable with the _id in foreignKey will be set to
    940      * ensure proper syncing operation.
    941      *
    942      * @param table an update on this table will trigger a sync time removal
    943      * @param foreignKey this is the column in table whose value is an _id in
    944      *          updateTable
    945      * @param updateTable this is the table that will have its _sync_dirty
    946      * @deprecated This method no longer serves any useful purpose and has been deprecated.
    947      */
    948     @Deprecated
    949     public void markTableSyncable(String table, String foreignKey, String updateTable) {
    950     }
    951 
    952     /**
    953      * Finds the name of the first table, which is editable.
    954      *
    955      * @param tables a list of tables
    956      * @return the first table listed
    957      */
    958     public static String findEditTable(String tables) {
    959         if (!TextUtils.isEmpty(tables)) {
    960             // find the first word terminated by either a space or a comma
    961             int spacepos = tables.indexOf(' ');
    962             int commapos = tables.indexOf(',');
    963 
    964             if (spacepos > 0 && (spacepos < commapos || commapos < 0)) {
    965                 return tables.substring(0, spacepos);
    966             } else if (commapos > 0 && (commapos < spacepos || spacepos < 0) ) {
    967                 return tables.substring(0, commapos);
    968             }
    969             return tables;
    970         } else {
    971             throw new IllegalStateException("Invalid tables");
    972         }
    973     }
    974 
    975     /**
    976      * Compiles an SQL statement into a reusable pre-compiled statement object.
    977      * The parameters are identical to {@link #execSQL(String)}. You may put ?s in the
    978      * statement and fill in those values with {@link SQLiteProgram#bindString}
    979      * and {@link SQLiteProgram#bindLong} each time you want to run the
    980      * statement. Statements may not return result sets larger than 1x1.
    981      *<p>
    982      * No two threads should be using the same {@link SQLiteStatement} at the same time.
    983      *
    984      * @param sql The raw SQL statement, may contain ? for unknown values to be
    985      *            bound later.
    986      * @return A pre-compiled {@link SQLiteStatement} object. Note that
    987      * {@link SQLiteStatement}s are not synchronized, see the documentation for more details.
    988      */
    989     public SQLiteStatement compileStatement(String sql) throws SQLException {
    990         acquireReference();
    991         try {
    992             return new SQLiteStatement(this, sql, null);
    993         } finally {
    994             releaseReference();
    995         }
    996     }
    997 
    998     /**
    999      * Query the given URL, returning a {@link Cursor} over the result set.
   1000      *
   1001      * @param distinct true if you want each row to be unique, false otherwise.
   1002      * @param table The table name to compile the query against.
   1003      * @param columns A list of which columns to return. Passing null will
   1004      *            return all columns, which is discouraged to prevent reading
   1005      *            data from storage that isn't going to be used.
   1006      * @param selection A filter declaring which rows to return, formatted as an
   1007      *            SQL WHERE clause (excluding the WHERE itself). Passing null
   1008      *            will return all rows for the given table.
   1009      * @param selectionArgs You may include ?s in selection, which will be
   1010      *         replaced by the values from selectionArgs, in order that they
   1011      *         appear in the selection. The values will be bound as Strings.
   1012      * @param groupBy A filter declaring how to group rows, formatted as an SQL
   1013      *            GROUP BY clause (excluding the GROUP BY itself). Passing null
   1014      *            will cause the rows to not be grouped.
   1015      * @param having A filter declare which row groups to include in the cursor,
   1016      *            if row grouping is being used, formatted as an SQL HAVING
   1017      *            clause (excluding the HAVING itself). Passing null will cause
   1018      *            all row groups to be included, and is required when row
   1019      *            grouping is not being used.
   1020      * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
   1021      *            (excluding the ORDER BY itself). Passing null will use the
   1022      *            default sort order, which may be unordered.
   1023      * @param limit Limits the number of rows returned by the query,
   1024      *            formatted as LIMIT clause. Passing null denotes no LIMIT clause.
   1025      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
   1026      * {@link Cursor}s are not synchronized, see the documentation for more details.
   1027      * @see Cursor
   1028      */
   1029     public Cursor query(boolean distinct, String table, String[] columns,
   1030             String selection, String[] selectionArgs, String groupBy,
   1031             String having, String orderBy, String limit) {
   1032         return queryWithFactory(null, distinct, table, columns, selection, selectionArgs,
   1033                 groupBy, having, orderBy, limit, null);
   1034     }
   1035 
   1036     /**
   1037      * Query the given URL, returning a {@link Cursor} over the result set.
   1038      *
   1039      * @param distinct true if you want each row to be unique, false otherwise.
   1040      * @param table The table name to compile the query against.
   1041      * @param columns A list of which columns to return. Passing null will
   1042      *            return all columns, which is discouraged to prevent reading
   1043      *            data from storage that isn't going to be used.
   1044      * @param selection A filter declaring which rows to return, formatted as an
   1045      *            SQL WHERE clause (excluding the WHERE itself). Passing null
   1046      *            will return all rows for the given table.
   1047      * @param selectionArgs You may include ?s in selection, which will be
   1048      *         replaced by the values from selectionArgs, in order that they
   1049      *         appear in the selection. The values will be bound as Strings.
   1050      * @param groupBy A filter declaring how to group rows, formatted as an SQL
   1051      *            GROUP BY clause (excluding the GROUP BY itself). Passing null
   1052      *            will cause the rows to not be grouped.
   1053      * @param having A filter declare which row groups to include in the cursor,
   1054      *            if row grouping is being used, formatted as an SQL HAVING
   1055      *            clause (excluding the HAVING itself). Passing null will cause
   1056      *            all row groups to be included, and is required when row
   1057      *            grouping is not being used.
   1058      * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
   1059      *            (excluding the ORDER BY itself). Passing null will use the
   1060      *            default sort order, which may be unordered.
   1061      * @param limit Limits the number of rows returned by the query,
   1062      *            formatted as LIMIT clause. Passing null denotes no LIMIT clause.
   1063      * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
   1064      * If the operation is canceled, then {@link OperationCanceledException} will be thrown
   1065      * when the query is executed.
   1066      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
   1067      * {@link Cursor}s are not synchronized, see the documentation for more details.
   1068      * @see Cursor
   1069      */
   1070     public Cursor query(boolean distinct, String table, String[] columns,
   1071             String selection, String[] selectionArgs, String groupBy,
   1072             String having, String orderBy, String limit, CancellationSignal cancellationSignal) {
   1073         return queryWithFactory(null, distinct, table, columns, selection, selectionArgs,
   1074                 groupBy, having, orderBy, limit, cancellationSignal);
   1075     }
   1076 
   1077     /**
   1078      * Query the given URL, returning a {@link Cursor} over the result set.
   1079      *
   1080      * @param cursorFactory the cursor factory to use, or null for the default factory
   1081      * @param distinct true if you want each row to be unique, false otherwise.
   1082      * @param table The table name to compile the query against.
   1083      * @param columns A list of which columns to return. Passing null will
   1084      *            return all columns, which is discouraged to prevent reading
   1085      *            data from storage that isn't going to be used.
   1086      * @param selection A filter declaring which rows to return, formatted as an
   1087      *            SQL WHERE clause (excluding the WHERE itself). Passing null
   1088      *            will return all rows for the given table.
   1089      * @param selectionArgs You may include ?s in selection, which will be
   1090      *         replaced by the values from selectionArgs, in order that they
   1091      *         appear in the selection. The values will be bound as Strings.
   1092      * @param groupBy A filter declaring how to group rows, formatted as an SQL
   1093      *            GROUP BY clause (excluding the GROUP BY itself). Passing null
   1094      *            will cause the rows to not be grouped.
   1095      * @param having A filter declare which row groups to include in the cursor,
   1096      *            if row grouping is being used, formatted as an SQL HAVING
   1097      *            clause (excluding the HAVING itself). Passing null will cause
   1098      *            all row groups to be included, and is required when row
   1099      *            grouping is not being used.
   1100      * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
   1101      *            (excluding the ORDER BY itself). Passing null will use the
   1102      *            default sort order, which may be unordered.
   1103      * @param limit Limits the number of rows returned by the query,
   1104      *            formatted as LIMIT clause. Passing null denotes no LIMIT clause.
   1105      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
   1106      * {@link Cursor}s are not synchronized, see the documentation for more details.
   1107      * @see Cursor
   1108      */
   1109     public Cursor queryWithFactory(CursorFactory cursorFactory,
   1110             boolean distinct, String table, String[] columns,
   1111             String selection, String[] selectionArgs, String groupBy,
   1112             String having, String orderBy, String limit) {
   1113         return queryWithFactory(cursorFactory, distinct, table, columns, selection,
   1114                 selectionArgs, groupBy, having, orderBy, limit, null);
   1115     }
   1116 
   1117     /**
   1118      * Query the given URL, returning a {@link Cursor} over the result set.
   1119      *
   1120      * @param cursorFactory the cursor factory to use, or null for the default factory
   1121      * @param distinct true if you want each row to be unique, false otherwise.
   1122      * @param table The table name to compile the query against.
   1123      * @param columns A list of which columns to return. Passing null will
   1124      *            return all columns, which is discouraged to prevent reading
   1125      *            data from storage that isn't going to be used.
   1126      * @param selection A filter declaring which rows to return, formatted as an
   1127      *            SQL WHERE clause (excluding the WHERE itself). Passing null
   1128      *            will return all rows for the given table.
   1129      * @param selectionArgs You may include ?s in selection, which will be
   1130      *         replaced by the values from selectionArgs, in order that they
   1131      *         appear in the selection. The values will be bound as Strings.
   1132      * @param groupBy A filter declaring how to group rows, formatted as an SQL
   1133      *            GROUP BY clause (excluding the GROUP BY itself). Passing null
   1134      *            will cause the rows to not be grouped.
   1135      * @param having A filter declare which row groups to include in the cursor,
   1136      *            if row grouping is being used, formatted as an SQL HAVING
   1137      *            clause (excluding the HAVING itself). Passing null will cause
   1138      *            all row groups to be included, and is required when row
   1139      *            grouping is not being used.
   1140      * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
   1141      *            (excluding the ORDER BY itself). Passing null will use the
   1142      *            default sort order, which may be unordered.
   1143      * @param limit Limits the number of rows returned by the query,
   1144      *            formatted as LIMIT clause. Passing null denotes no LIMIT clause.
   1145      * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
   1146      * If the operation is canceled, then {@link OperationCanceledException} will be thrown
   1147      * when the query is executed.
   1148      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
   1149      * {@link Cursor}s are not synchronized, see the documentation for more details.
   1150      * @see Cursor
   1151      */
   1152     public Cursor queryWithFactory(CursorFactory cursorFactory,
   1153             boolean distinct, String table, String[] columns,
   1154             String selection, String[] selectionArgs, String groupBy,
   1155             String having, String orderBy, String limit, CancellationSignal cancellationSignal) {
   1156         acquireReference();
   1157         try {
   1158             String sql = SQLiteQueryBuilder.buildQueryString(
   1159                     distinct, table, columns, selection, groupBy, having, orderBy, limit);
   1160 
   1161             return rawQueryWithFactory(cursorFactory, sql, selectionArgs,
   1162                     findEditTable(table), cancellationSignal);
   1163         } finally {
   1164             releaseReference();
   1165         }
   1166     }
   1167 
   1168     /**
   1169      * Query the given table, returning a {@link Cursor} over the result set.
   1170      *
   1171      * @param table The table name to compile the query against.
   1172      * @param columns A list of which columns to return. Passing null will
   1173      *            return all columns, which is discouraged to prevent reading
   1174      *            data from storage that isn't going to be used.
   1175      * @param selection A filter declaring which rows to return, formatted as an
   1176      *            SQL WHERE clause (excluding the WHERE itself). Passing null
   1177      *            will return all rows for the given table.
   1178      * @param selectionArgs You may include ?s in selection, which will be
   1179      *         replaced by the values from selectionArgs, in order that they
   1180      *         appear in the selection. The values will be bound as Strings.
   1181      * @param groupBy A filter declaring how to group rows, formatted as an SQL
   1182      *            GROUP BY clause (excluding the GROUP BY itself). Passing null
   1183      *            will cause the rows to not be grouped.
   1184      * @param having A filter declare which row groups to include in the cursor,
   1185      *            if row grouping is being used, formatted as an SQL HAVING
   1186      *            clause (excluding the HAVING itself). Passing null will cause
   1187      *            all row groups to be included, and is required when row
   1188      *            grouping is not being used.
   1189      * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
   1190      *            (excluding the ORDER BY itself). Passing null will use the
   1191      *            default sort order, which may be unordered.
   1192      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
   1193      * {@link Cursor}s are not synchronized, see the documentation for more details.
   1194      * @see Cursor
   1195      */
   1196     public Cursor query(String table, String[] columns, String selection,
   1197             String[] selectionArgs, String groupBy, String having,
   1198             String orderBy) {
   1199 
   1200         return query(false, table, columns, selection, selectionArgs, groupBy,
   1201                 having, orderBy, null /* limit */);
   1202     }
   1203 
   1204     /**
   1205      * Query the given table, returning a {@link Cursor} over the result set.
   1206      *
   1207      * @param table The table name to compile the query against.
   1208      * @param columns A list of which columns to return. Passing null will
   1209      *            return all columns, which is discouraged to prevent reading
   1210      *            data from storage that isn't going to be used.
   1211      * @param selection A filter declaring which rows to return, formatted as an
   1212      *            SQL WHERE clause (excluding the WHERE itself). Passing null
   1213      *            will return all rows for the given table.
   1214      * @param selectionArgs You may include ?s in selection, which will be
   1215      *         replaced by the values from selectionArgs, in order that they
   1216      *         appear in the selection. The values will be bound as Strings.
   1217      * @param groupBy A filter declaring how to group rows, formatted as an SQL
   1218      *            GROUP BY clause (excluding the GROUP BY itself). Passing null
   1219      *            will cause the rows to not be grouped.
   1220      * @param having A filter declare which row groups to include in the cursor,
   1221      *            if row grouping is being used, formatted as an SQL HAVING
   1222      *            clause (excluding the HAVING itself). Passing null will cause
   1223      *            all row groups to be included, and is required when row
   1224      *            grouping is not being used.
   1225      * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
   1226      *            (excluding the ORDER BY itself). Passing null will use the
   1227      *            default sort order, which may be unordered.
   1228      * @param limit Limits the number of rows returned by the query,
   1229      *            formatted as LIMIT clause. Passing null denotes no LIMIT clause.
   1230      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
   1231      * {@link Cursor}s are not synchronized, see the documentation for more details.
   1232      * @see Cursor
   1233      */
   1234     public Cursor query(String table, String[] columns, String selection,
   1235             String[] selectionArgs, String groupBy, String having,
   1236             String orderBy, String limit) {
   1237 
   1238         return query(false, table, columns, selection, selectionArgs, groupBy,
   1239                 having, orderBy, limit);
   1240     }
   1241 
   1242     /**
   1243      * Runs the provided SQL and returns a {@link Cursor} over the result set.
   1244      *
   1245      * @param sql the SQL query. The SQL string must not be ; terminated
   1246      * @param selectionArgs You may include ?s in where clause in the query,
   1247      *     which will be replaced by the values from selectionArgs. The
   1248      *     values will be bound as Strings.
   1249      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
   1250      * {@link Cursor}s are not synchronized, see the documentation for more details.
   1251      */
   1252     public Cursor rawQuery(String sql, String[] selectionArgs) {
   1253         return rawQueryWithFactory(null, sql, selectionArgs, null, null);
   1254     }
   1255 
   1256     /**
   1257      * Runs the provided SQL and returns a {@link Cursor} over the result set.
   1258      *
   1259      * @param sql the SQL query. The SQL string must not be ; terminated
   1260      * @param selectionArgs You may include ?s in where clause in the query,
   1261      *     which will be replaced by the values from selectionArgs. The
   1262      *     values will be bound as Strings.
   1263      * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
   1264      * If the operation is canceled, then {@link OperationCanceledException} will be thrown
   1265      * when the query is executed.
   1266      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
   1267      * {@link Cursor}s are not synchronized, see the documentation for more details.
   1268      */
   1269     public Cursor rawQuery(String sql, String[] selectionArgs,
   1270             CancellationSignal cancellationSignal) {
   1271         return rawQueryWithFactory(null, sql, selectionArgs, null, cancellationSignal);
   1272     }
   1273 
   1274     /**
   1275      * Runs the provided SQL and returns a cursor over the result set.
   1276      *
   1277      * @param cursorFactory the cursor factory to use, or null for the default factory
   1278      * @param sql the SQL query. The SQL string must not be ; terminated
   1279      * @param selectionArgs You may include ?s in where clause in the query,
   1280      *     which will be replaced by the values from selectionArgs. The
   1281      *     values will be bound as Strings.
   1282      * @param editTable the name of the first table, which is editable
   1283      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
   1284      * {@link Cursor}s are not synchronized, see the documentation for more details.
   1285      */
   1286     public Cursor rawQueryWithFactory(
   1287             CursorFactory cursorFactory, String sql, String[] selectionArgs,
   1288             String editTable) {
   1289         return rawQueryWithFactory(cursorFactory, sql, selectionArgs, editTable, null);
   1290     }
   1291 
   1292     /**
   1293      * Runs the provided SQL and returns a cursor over the result set.
   1294      *
   1295      * @param cursorFactory the cursor factory to use, or null for the default factory
   1296      * @param sql the SQL query. The SQL string must not be ; terminated
   1297      * @param selectionArgs You may include ?s in where clause in the query,
   1298      *     which will be replaced by the values from selectionArgs. The
   1299      *     values will be bound as Strings.
   1300      * @param editTable the name of the first table, which is editable
   1301      * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
   1302      * If the operation is canceled, then {@link OperationCanceledException} will be thrown
   1303      * when the query is executed.
   1304      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
   1305      * {@link Cursor}s are not synchronized, see the documentation for more details.
   1306      */
   1307     public Cursor rawQueryWithFactory(
   1308             CursorFactory cursorFactory, String sql, String[] selectionArgs,
   1309             String editTable, CancellationSignal cancellationSignal) {
   1310         acquireReference();
   1311         try {
   1312             SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(this, sql, editTable,
   1313                     cancellationSignal);
   1314             return driver.query(cursorFactory != null ? cursorFactory : mCursorFactory,
   1315                     selectionArgs);
   1316         } finally {
   1317             releaseReference();
   1318         }
   1319     }
   1320 
   1321     /**
   1322      * Convenience method for inserting a row into the database.
   1323      *
   1324      * @param table the table to insert the row into
   1325      * @param nullColumnHack optional; may be <code>null</code>.
   1326      *            SQL doesn't allow inserting a completely empty row without
   1327      *            naming at least one column name.  If your provided <code>values</code> is
   1328      *            empty, no column names are known and an empty row can't be inserted.
   1329      *            If not set to null, the <code>nullColumnHack</code> parameter
   1330      *            provides the name of nullable column name to explicitly insert a NULL into
   1331      *            in the case where your <code>values</code> is empty.
   1332      * @param values this map contains the initial column values for the
   1333      *            row. The keys should be the column names and the values the
   1334      *            column values
   1335      * @return the row ID of the newly inserted row, or -1 if an error occurred
   1336      */
   1337     public long insert(String table, String nullColumnHack, ContentValues values) {
   1338         try {
   1339             return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE);
   1340         } catch (SQLException e) {
   1341             Log.e(TAG, "Error inserting " + values, e);
   1342             return -1;
   1343         }
   1344     }
   1345 
   1346     /**
   1347      * Convenience method for inserting a row into the database.
   1348      *
   1349      * @param table the table to insert the row into
   1350      * @param nullColumnHack optional; may be <code>null</code>.
   1351      *            SQL doesn't allow inserting a completely empty row without
   1352      *            naming at least one column name.  If your provided <code>values</code> is
   1353      *            empty, no column names are known and an empty row can't be inserted.
   1354      *            If not set to null, the <code>nullColumnHack</code> parameter
   1355      *            provides the name of nullable column name to explicitly insert a NULL into
   1356      *            in the case where your <code>values</code> is empty.
   1357      * @param values this map contains the initial column values for the
   1358      *            row. The keys should be the column names and the values the
   1359      *            column values
   1360      * @throws SQLException
   1361      * @return the row ID of the newly inserted row, or -1 if an error occurred
   1362      */
   1363     public long insertOrThrow(String table, String nullColumnHack, ContentValues values)
   1364             throws SQLException {
   1365         return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE);
   1366     }
   1367 
   1368     /**
   1369      * Convenience method for replacing a row in the database.
   1370      *
   1371      * @param table the table in which to replace the row
   1372      * @param nullColumnHack optional; may be <code>null</code>.
   1373      *            SQL doesn't allow inserting a completely empty row without
   1374      *            naming at least one column name.  If your provided <code>initialValues</code> is
   1375      *            empty, no column names are known and an empty row can't be inserted.
   1376      *            If not set to null, the <code>nullColumnHack</code> parameter
   1377      *            provides the name of nullable column name to explicitly insert a NULL into
   1378      *            in the case where your <code>initialValues</code> is empty.
   1379      * @param initialValues this map contains the initial column values for
   1380      *   the row.
   1381      * @return the row ID of the newly inserted row, or -1 if an error occurred
   1382      */
   1383     public long replace(String table, String nullColumnHack, ContentValues initialValues) {
   1384         try {
   1385             return insertWithOnConflict(table, nullColumnHack, initialValues,
   1386                     CONFLICT_REPLACE);
   1387         } catch (SQLException e) {
   1388             Log.e(TAG, "Error inserting " + initialValues, e);
   1389             return -1;
   1390         }
   1391     }
   1392 
   1393     /**
   1394      * Convenience method for replacing a row in the database.
   1395      *
   1396      * @param table the table in which to replace the row
   1397      * @param nullColumnHack optional; may be <code>null</code>.
   1398      *            SQL doesn't allow inserting a completely empty row without
   1399      *            naming at least one column name.  If your provided <code>initialValues</code> is
   1400      *            empty, no column names are known and an empty row can't be inserted.
   1401      *            If not set to null, the <code>nullColumnHack</code> parameter
   1402      *            provides the name of nullable column name to explicitly insert a NULL into
   1403      *            in the case where your <code>initialValues</code> is empty.
   1404      * @param initialValues this map contains the initial column values for
   1405      *   the row. The key
   1406      * @throws SQLException
   1407      * @return the row ID of the newly inserted row, or -1 if an error occurred
   1408      */
   1409     public long replaceOrThrow(String table, String nullColumnHack,
   1410             ContentValues initialValues) throws SQLException {
   1411         return insertWithOnConflict(table, nullColumnHack, initialValues,
   1412                 CONFLICT_REPLACE);
   1413     }
   1414 
   1415     /**
   1416      * General method for inserting a row into the database.
   1417      *
   1418      * @param table the table to insert the row into
   1419      * @param nullColumnHack optional; may be <code>null</code>.
   1420      *            SQL doesn't allow inserting a completely empty row without
   1421      *            naming at least one column name.  If your provided <code>initialValues</code> is
   1422      *            empty, no column names are known and an empty row can't be inserted.
   1423      *            If not set to null, the <code>nullColumnHack</code> parameter
   1424      *            provides the name of nullable column name to explicitly insert a NULL into
   1425      *            in the case where your <code>initialValues</code> is empty.
   1426      * @param initialValues this map contains the initial column values for the
   1427      *            row. The keys should be the column names and the values the
   1428      *            column values
   1429      * @param conflictAlgorithm for insert conflict resolver
   1430      * @return the row ID of the newly inserted row
   1431      * OR the primary key of the existing row if the input param 'conflictAlgorithm' =
   1432      * {@link #CONFLICT_IGNORE}
   1433      * OR -1 if any error
   1434      */
   1435     public long insertWithOnConflict(String table, String nullColumnHack,
   1436             ContentValues initialValues, int conflictAlgorithm) {
   1437         acquireReference();
   1438         try {
   1439             StringBuilder sql = new StringBuilder();
   1440             sql.append("INSERT");
   1441             sql.append(CONFLICT_VALUES[conflictAlgorithm]);
   1442             sql.append(" INTO ");
   1443             sql.append(table);
   1444             sql.append('(');
   1445 
   1446             Object[] bindArgs = null;
   1447             int size = (initialValues != null && initialValues.size() > 0)
   1448                     ? initialValues.size() : 0;
   1449             if (size > 0) {
   1450                 bindArgs = new Object[size];
   1451                 int i = 0;
   1452                 for (String colName : initialValues.keySet()) {
   1453                     sql.append((i > 0) ? "," : "");
   1454                     sql.append(colName);
   1455                     bindArgs[i++] = initialValues.get(colName);
   1456                 }
   1457                 sql.append(')');
   1458                 sql.append(" VALUES (");
   1459                 for (i = 0; i < size; i++) {
   1460                     sql.append((i > 0) ? ",?" : "?");
   1461                 }
   1462             } else {
   1463                 sql.append(nullColumnHack + ") VALUES (NULL");
   1464             }
   1465             sql.append(')');
   1466 
   1467             SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs);
   1468             try {
   1469                 return statement.executeInsert();
   1470             } finally {
   1471                 statement.close();
   1472             }
   1473         } finally {
   1474             releaseReference();
   1475         }
   1476     }
   1477 
   1478     /**
   1479      * Convenience method for deleting rows in the database.
   1480      *
   1481      * @param table the table to delete from
   1482      * @param whereClause the optional WHERE clause to apply when deleting.
   1483      *            Passing null will delete all rows.
   1484      * @param whereArgs You may include ?s in the where clause, which
   1485      *            will be replaced by the values from whereArgs. The values
   1486      *            will be bound as Strings.
   1487      * @return the number of rows affected if a whereClause is passed in, 0
   1488      *         otherwise. To remove all rows and get a count pass "1" as the
   1489      *         whereClause.
   1490      */
   1491     public int delete(String table, String whereClause, String[] whereArgs) {
   1492         acquireReference();
   1493         try {
   1494             SQLiteStatement statement =  new SQLiteStatement(this, "DELETE FROM " + table +
   1495                     (!TextUtils.isEmpty(whereClause) ? " WHERE " + whereClause : ""), whereArgs);
   1496             try {
   1497                 return statement.executeUpdateDelete();
   1498             } finally {
   1499                 statement.close();
   1500             }
   1501         } finally {
   1502             releaseReference();
   1503         }
   1504     }
   1505 
   1506     /**
   1507      * Convenience method for updating rows in the database.
   1508      *
   1509      * @param table the table to update in
   1510      * @param values a map from column names to new column values. null is a
   1511      *            valid value that will be translated to NULL.
   1512      * @param whereClause the optional WHERE clause to apply when updating.
   1513      *            Passing null will update all rows.
   1514      * @param whereArgs You may include ?s in the where clause, which
   1515      *            will be replaced by the values from whereArgs. The values
   1516      *            will be bound as Strings.
   1517      * @return the number of rows affected
   1518      */
   1519     public int update(String table, ContentValues values, String whereClause, String[] whereArgs) {
   1520         return updateWithOnConflict(table, values, whereClause, whereArgs, CONFLICT_NONE);
   1521     }
   1522 
   1523     /**
   1524      * Convenience method for updating rows in the database.
   1525      *
   1526      * @param table the table to update in
   1527      * @param values a map from column names to new column values. null is a
   1528      *            valid value that will be translated to NULL.
   1529      * @param whereClause the optional WHERE clause to apply when updating.
   1530      *            Passing null will update all rows.
   1531      * @param whereArgs You may include ?s in the where clause, which
   1532      *            will be replaced by the values from whereArgs. The values
   1533      *            will be bound as Strings.
   1534      * @param conflictAlgorithm for update conflict resolver
   1535      * @return the number of rows affected
   1536      */
   1537     public int updateWithOnConflict(String table, ContentValues values,
   1538             String whereClause, String[] whereArgs, int conflictAlgorithm) {
   1539         if (values == null || values.size() == 0) {
   1540             throw new IllegalArgumentException("Empty values");
   1541         }
   1542 
   1543         acquireReference();
   1544         try {
   1545             StringBuilder sql = new StringBuilder(120);
   1546             sql.append("UPDATE ");
   1547             sql.append(CONFLICT_VALUES[conflictAlgorithm]);
   1548             sql.append(table);
   1549             sql.append(" SET ");
   1550 
   1551             // move all bind args to one array
   1552             int setValuesSize = values.size();
   1553             int bindArgsSize = (whereArgs == null) ? setValuesSize : (setValuesSize + whereArgs.length);
   1554             Object[] bindArgs = new Object[bindArgsSize];
   1555             int i = 0;
   1556             for (String colName : values.keySet()) {
   1557                 sql.append((i > 0) ? "," : "");
   1558                 sql.append(colName);
   1559                 bindArgs[i++] = values.get(colName);
   1560                 sql.append("=?");
   1561             }
   1562             if (whereArgs != null) {
   1563                 for (i = setValuesSize; i < bindArgsSize; i++) {
   1564                     bindArgs[i] = whereArgs[i - setValuesSize];
   1565                 }
   1566             }
   1567             if (!TextUtils.isEmpty(whereClause)) {
   1568                 sql.append(" WHERE ");
   1569                 sql.append(whereClause);
   1570             }
   1571 
   1572             SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs);
   1573             try {
   1574                 return statement.executeUpdateDelete();
   1575             } finally {
   1576                 statement.close();
   1577             }
   1578         } finally {
   1579             releaseReference();
   1580         }
   1581     }
   1582 
   1583     /**
   1584      * Execute a single SQL statement that is NOT a SELECT
   1585      * or any other SQL statement that returns data.
   1586      * <p>
   1587      * It has no means to return any data (such as the number of affected rows).
   1588      * Instead, you're encouraged to use {@link #insert(String, String, ContentValues)},
   1589      * {@link #update(String, ContentValues, String, String[])}, et al, when possible.
   1590      * </p>
   1591      * <p>
   1592      * When using {@link #enableWriteAheadLogging()}, journal_mode is
   1593      * automatically managed by this class. So, do not set journal_mode
   1594      * using "PRAGMA journal_mode'<value>" statement if your app is using
   1595      * {@link #enableWriteAheadLogging()}
   1596      * </p>
   1597      *
   1598      * @param sql the SQL statement to be executed. Multiple statements separated by semicolons are
   1599      * not supported.
   1600      * @throws SQLException if the SQL string is invalid
   1601      */
   1602     public void execSQL(String sql) throws SQLException {
   1603         executeSql(sql, null);
   1604     }
   1605 
   1606     /**
   1607      * Execute a single SQL statement that is NOT a SELECT/INSERT/UPDATE/DELETE.
   1608      * <p>
   1609      * For INSERT statements, use any of the following instead.
   1610      * <ul>
   1611      *   <li>{@link #insert(String, String, ContentValues)}</li>
   1612      *   <li>{@link #insertOrThrow(String, String, ContentValues)}</li>
   1613      *   <li>{@link #insertWithOnConflict(String, String, ContentValues, int)}</li>
   1614      * </ul>
   1615      * <p>
   1616      * For UPDATE statements, use any of the following instead.
   1617      * <ul>
   1618      *   <li>{@link #update(String, ContentValues, String, String[])}</li>
   1619      *   <li>{@link #updateWithOnConflict(String, ContentValues, String, String[], int)}</li>
   1620      * </ul>
   1621      * <p>
   1622      * For DELETE statements, use any of the following instead.
   1623      * <ul>
   1624      *   <li>{@link #delete(String, String, String[])}</li>
   1625      * </ul>
   1626      * <p>
   1627      * For example, the following are good candidates for using this method:
   1628      * <ul>
   1629      *   <li>ALTER TABLE</li>
   1630      *   <li>CREATE or DROP table / trigger / view / index / virtual table</li>
   1631      *   <li>REINDEX</li>
   1632      *   <li>RELEASE</li>
   1633      *   <li>SAVEPOINT</li>
   1634      *   <li>PRAGMA that returns no data</li>
   1635      * </ul>
   1636      * </p>
   1637      * <p>
   1638      * When using {@link #enableWriteAheadLogging()}, journal_mode is
   1639      * automatically managed by this class. So, do not set journal_mode
   1640      * using "PRAGMA journal_mode'<value>" statement if your app is using
   1641      * {@link #enableWriteAheadLogging()}
   1642      * </p>
   1643      *
   1644      * @param sql the SQL statement to be executed. Multiple statements separated by semicolons are
   1645      * not supported.
   1646      * @param bindArgs only byte[], String, Long and Double are supported in bindArgs.
   1647      * @throws SQLException if the SQL string is invalid
   1648      */
   1649     public void execSQL(String sql, Object[] bindArgs) throws SQLException {
   1650         if (bindArgs == null) {
   1651             throw new IllegalArgumentException("Empty bindArgs");
   1652         }
   1653         executeSql(sql, bindArgs);
   1654     }
   1655 
   1656     private int executeSql(String sql, Object[] bindArgs) throws SQLException {
   1657         acquireReference();
   1658         try {
   1659             if (DatabaseUtils.getSqlStatementType(sql) == DatabaseUtils.STATEMENT_ATTACH) {
   1660                 boolean disableWal = false;
   1661                 synchronized (mLock) {
   1662                     if (!mHasAttachedDbsLocked) {
   1663                         mHasAttachedDbsLocked = true;
   1664                         disableWal = true;
   1665                     }
   1666                 }
   1667                 if (disableWal) {
   1668                     disableWriteAheadLogging();
   1669                 }
   1670             }
   1671 
   1672             SQLiteStatement statement = new SQLiteStatement(this, sql, bindArgs);
   1673             try {
   1674                 return statement.executeUpdateDelete();
   1675             } finally {
   1676                 statement.close();
   1677             }
   1678         } finally {
   1679             releaseReference();
   1680         }
   1681     }
   1682 
   1683     /**
   1684      * Returns true if the database is opened as read only.
   1685      *
   1686      * @return True if database is opened as read only.
   1687      */
   1688     public boolean isReadOnly() {
   1689         synchronized (mLock) {
   1690             return isReadOnlyLocked();
   1691         }
   1692     }
   1693 
   1694     private boolean isReadOnlyLocked() {
   1695         return (mConfigurationLocked.openFlags & OPEN_READ_MASK) == OPEN_READONLY;
   1696     }
   1697 
   1698     /**
   1699      * Returns true if the database is in-memory db.
   1700      *
   1701      * @return True if the database is in-memory.
   1702      * @hide
   1703      */
   1704     public boolean isInMemoryDatabase() {
   1705         synchronized (mLock) {
   1706             return mConfigurationLocked.isInMemoryDb();
   1707         }
   1708     }
   1709 
   1710     /**
   1711      * Returns true if the database is currently open.
   1712      *
   1713      * @return True if the database is currently open (has not been closed).
   1714      */
   1715     public boolean isOpen() {
   1716         synchronized (mLock) {
   1717             return mConnectionPoolLocked != null;
   1718         }
   1719     }
   1720 
   1721     /**
   1722      * Returns true if the new version code is greater than the current database version.
   1723      *
   1724      * @param newVersion The new version code.
   1725      * @return True if the new version code is greater than the current database version.
   1726      */
   1727     public boolean needUpgrade(int newVersion) {
   1728         return newVersion > getVersion();
   1729     }
   1730 
   1731     /**
   1732      * Gets the path to the database file.
   1733      *
   1734      * @return The path to the database file.
   1735      */
   1736     public final String getPath() {
   1737         synchronized (mLock) {
   1738             return mConfigurationLocked.path;
   1739         }
   1740     }
   1741 
   1742     /**
   1743      * Sets the locale for this database.  Does nothing if this database has
   1744      * the {@link #NO_LOCALIZED_COLLATORS} flag set or was opened read only.
   1745      *
   1746      * @param locale The new locale.
   1747      *
   1748      * @throws SQLException if the locale could not be set.  The most common reason
   1749      * for this is that there is no collator available for the locale you requested.
   1750      * In this case the database remains unchanged.
   1751      */
   1752     public void setLocale(Locale locale) {
   1753         if (locale == null) {
   1754             throw new IllegalArgumentException("locale must not be null.");
   1755         }
   1756 
   1757         synchronized (mLock) {
   1758             throwIfNotOpenLocked();
   1759 
   1760             final Locale oldLocale = mConfigurationLocked.locale;
   1761             mConfigurationLocked.locale = locale;
   1762             try {
   1763                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
   1764             } catch (RuntimeException ex) {
   1765                 mConfigurationLocked.locale = oldLocale;
   1766                 throw ex;
   1767             }
   1768         }
   1769     }
   1770 
   1771     /**
   1772      * Sets the maximum size of the prepared-statement cache for this database.
   1773      * (size of the cache = number of compiled-sql-statements stored in the cache).
   1774      *<p>
   1775      * Maximum cache size can ONLY be increased from its current size (default = 10).
   1776      * If this method is called with smaller size than the current maximum value,
   1777      * then IllegalStateException is thrown.
   1778      *<p>
   1779      * This method is thread-safe.
   1780      *
   1781      * @param cacheSize the size of the cache. can be (0 to {@link #MAX_SQL_CACHE_SIZE})
   1782      * @throws IllegalStateException if input cacheSize > {@link #MAX_SQL_CACHE_SIZE}.
   1783      */
   1784     public void setMaxSqlCacheSize(int cacheSize) {
   1785         if (cacheSize > MAX_SQL_CACHE_SIZE || cacheSize < 0) {
   1786             throw new IllegalStateException(
   1787                     "expected value between 0 and " + MAX_SQL_CACHE_SIZE);
   1788         }
   1789 
   1790         synchronized (mLock) {
   1791             throwIfNotOpenLocked();
   1792 
   1793             final int oldMaxSqlCacheSize = mConfigurationLocked.maxSqlCacheSize;
   1794             mConfigurationLocked.maxSqlCacheSize = cacheSize;
   1795             try {
   1796                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
   1797             } catch (RuntimeException ex) {
   1798                 mConfigurationLocked.maxSqlCacheSize = oldMaxSqlCacheSize;
   1799                 throw ex;
   1800             }
   1801         }
   1802     }
   1803 
   1804     /**
   1805      * Sets whether foreign key constraints are enabled for the database.
   1806      * <p>
   1807      * By default, foreign key constraints are not enforced by the database.
   1808      * This method allows an application to enable foreign key constraints.
   1809      * It must be called each time the database is opened to ensure that foreign
   1810      * key constraints are enabled for the session.
   1811      * </p><p>
   1812      * A good time to call this method is right after calling {@link #openOrCreateDatabase}
   1813      * or in the {@link SQLiteOpenHelper#onConfigure} callback.
   1814      * </p><p>
   1815      * When foreign key constraints are disabled, the database does not check whether
   1816      * changes to the database will violate foreign key constraints.  Likewise, when
   1817      * foreign key constraints are disabled, the database will not execute cascade
   1818      * delete or update triggers.  As a result, it is possible for the database
   1819      * state to become inconsistent.  To perform a database integrity check,
   1820      * call {@link #isDatabaseIntegrityOk}.
   1821      * </p><p>
   1822      * This method must not be called while a transaction is in progress.
   1823      * </p><p>
   1824      * See also <a href="http://sqlite.org/foreignkeys.html">SQLite Foreign Key Constraints</a>
   1825      * for more details about foreign key constraint support.
   1826      * </p>
   1827      *
   1828      * @param enable True to enable foreign key constraints, false to disable them.
   1829      *
   1830      * @throws IllegalStateException if the are transactions is in progress
   1831      * when this method is called.
   1832      */
   1833     public void setForeignKeyConstraintsEnabled(boolean enable) {
   1834         synchronized (mLock) {
   1835             throwIfNotOpenLocked();
   1836 
   1837             if (mConfigurationLocked.foreignKeyConstraintsEnabled == enable) {
   1838                 return;
   1839             }
   1840 
   1841             mConfigurationLocked.foreignKeyConstraintsEnabled = enable;
   1842             try {
   1843                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
   1844             } catch (RuntimeException ex) {
   1845                 mConfigurationLocked.foreignKeyConstraintsEnabled = !enable;
   1846                 throw ex;
   1847             }
   1848         }
   1849     }
   1850 
   1851     /**
   1852      * This method enables parallel execution of queries from multiple threads on the
   1853      * same database.  It does this by opening multiple connections to the database
   1854      * and using a different database connection for each query.  The database
   1855      * journal mode is also changed to enable writes to proceed concurrently with reads.
   1856      * <p>
   1857      * When write-ahead logging is not enabled (the default), it is not possible for
   1858      * reads and writes to occur on the database at the same time.  Before modifying the
   1859      * database, the writer implicitly acquires an exclusive lock on the database which
   1860      * prevents readers from accessing the database until the write is completed.
   1861      * </p><p>
   1862      * In contrast, when write-ahead logging is enabled (by calling this method), write
   1863      * operations occur in a separate log file which allows reads to proceed concurrently.
   1864      * While a write is in progress, readers on other threads will perceive the state
   1865      * of the database as it was before the write began.  When the write completes, readers
   1866      * on other threads will then perceive the new state of the database.
   1867      * </p><p>
   1868      * It is a good idea to enable write-ahead logging whenever a database will be
   1869      * concurrently accessed and modified by multiple threads at the same time.
   1870      * However, write-ahead logging uses significantly more memory than ordinary
   1871      * journaling because there are multiple connections to the same database.
   1872      * So if a database will only be used by a single thread, or if optimizing
   1873      * concurrency is not very important, then write-ahead logging should be disabled.
   1874      * </p><p>
   1875      * After calling this method, execution of queries in parallel is enabled as long as
   1876      * the database remains open.  To disable execution of queries in parallel, either
   1877      * call {@link #disableWriteAheadLogging} or close the database and reopen it.
   1878      * </p><p>
   1879      * The maximum number of connections used to execute queries in parallel is
   1880      * dependent upon the device memory and possibly other properties.
   1881      * </p><p>
   1882      * If a query is part of a transaction, then it is executed on the same database handle the
   1883      * transaction was begun.
   1884      * </p><p>
   1885      * Writers should use {@link #beginTransactionNonExclusive()} or
   1886      * {@link #beginTransactionWithListenerNonExclusive(SQLiteTransactionListener)}
   1887      * to start a transaction.  Non-exclusive mode allows database file to be in readable
   1888      * by other threads executing queries.
   1889      * </p><p>
   1890      * If the database has any attached databases, then execution of queries in parallel is NOT
   1891      * possible.  Likewise, write-ahead logging is not supported for read-only databases
   1892      * or memory databases.  In such cases, {@link #enableWriteAheadLogging} returns false.
   1893      * </p><p>
   1894      * The best way to enable write-ahead logging is to pass the
   1895      * {@link #ENABLE_WRITE_AHEAD_LOGGING} flag to {@link #openDatabase}.  This is
   1896      * more efficient than calling {@link #enableWriteAheadLogging}.
   1897      * <code><pre>
   1898      *     SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory,
   1899      *             SQLiteDatabase.CREATE_IF_NECESSARY | SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING,
   1900      *             myDatabaseErrorHandler);
   1901      *     db.enableWriteAheadLogging();
   1902      * </pre></code>
   1903      * </p><p>
   1904      * Another way to enable write-ahead logging is to call {@link #enableWriteAheadLogging}
   1905      * after opening the database.
   1906      * <code><pre>
   1907      *     SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory,
   1908      *             SQLiteDatabase.CREATE_IF_NECESSARY, myDatabaseErrorHandler);
   1909      *     db.enableWriteAheadLogging();
   1910      * </pre></code>
   1911      * </p><p>
   1912      * See also <a href="http://sqlite.org/wal.html">SQLite Write-Ahead Logging</a> for
   1913      * more details about how write-ahead logging works.
   1914      * </p>
   1915      *
   1916      * @return True if write-ahead logging is enabled.
   1917      *
   1918      * @throws IllegalStateException if there are transactions in progress at the
   1919      * time this method is called.  WAL mode can only be changed when there are no
   1920      * transactions in progress.
   1921      *
   1922      * @see #ENABLE_WRITE_AHEAD_LOGGING
   1923      * @see #disableWriteAheadLogging
   1924      */
   1925     public boolean enableWriteAheadLogging() {
   1926         synchronized (mLock) {
   1927             throwIfNotOpenLocked();
   1928 
   1929             if ((mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) != 0) {
   1930                 return true;
   1931             }
   1932 
   1933             if (isReadOnlyLocked()) {
   1934                 // WAL doesn't make sense for readonly-databases.
   1935                 // TODO: True, but connection pooling does still make sense...
   1936                 return false;
   1937             }
   1938 
   1939             if (mConfigurationLocked.isInMemoryDb()) {
   1940                 Log.i(TAG, "can't enable WAL for memory databases.");
   1941                 return false;
   1942             }
   1943 
   1944             // make sure this database has NO attached databases because sqlite's write-ahead-logging
   1945             // doesn't work for databases with attached databases
   1946             if (mHasAttachedDbsLocked) {
   1947                 if (Log.isLoggable(TAG, Log.DEBUG)) {
   1948                     Log.d(TAG, "this database: " + mConfigurationLocked.label
   1949                             + " has attached databases. can't  enable WAL.");
   1950                 }
   1951                 return false;
   1952             }
   1953 
   1954             mConfigurationLocked.openFlags |= ENABLE_WRITE_AHEAD_LOGGING;
   1955             try {
   1956                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
   1957             } catch (RuntimeException ex) {
   1958                 mConfigurationLocked.openFlags &= ~ENABLE_WRITE_AHEAD_LOGGING;
   1959                 throw ex;
   1960             }
   1961         }
   1962         return true;
   1963     }
   1964 
   1965     /**
   1966      * This method disables the features enabled by {@link #enableWriteAheadLogging()}.
   1967      *
   1968      * @throws IllegalStateException if there are transactions in progress at the
   1969      * time this method is called.  WAL mode can only be changed when there are no
   1970      * transactions in progress.
   1971      *
   1972      * @see #enableWriteAheadLogging
   1973      */
   1974     public void disableWriteAheadLogging() {
   1975         synchronized (mLock) {
   1976             throwIfNotOpenLocked();
   1977 
   1978             if ((mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) == 0) {
   1979                 return;
   1980             }
   1981 
   1982             mConfigurationLocked.openFlags &= ~ENABLE_WRITE_AHEAD_LOGGING;
   1983             try {
   1984                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
   1985             } catch (RuntimeException ex) {
   1986                 mConfigurationLocked.openFlags |= ENABLE_WRITE_AHEAD_LOGGING;
   1987                 throw ex;
   1988             }
   1989         }
   1990     }
   1991 
   1992     /**
   1993      * Returns true if write-ahead logging has been enabled for this database.
   1994      *
   1995      * @return True if write-ahead logging has been enabled for this database.
   1996      *
   1997      * @see #enableWriteAheadLogging
   1998      * @see #ENABLE_WRITE_AHEAD_LOGGING
   1999      */
   2000     public boolean isWriteAheadLoggingEnabled() {
   2001         synchronized (mLock) {
   2002             throwIfNotOpenLocked();
   2003 
   2004             return (mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) != 0;
   2005         }
   2006     }
   2007 
   2008     /**
   2009      * Collect statistics about all open databases in the current process.
   2010      * Used by bug report.
   2011      */
   2012     static ArrayList<DbStats> getDbStats() {
   2013         ArrayList<DbStats> dbStatsList = new ArrayList<DbStats>();
   2014         for (SQLiteDatabase db : getActiveDatabases()) {
   2015             db.collectDbStats(dbStatsList);
   2016         }
   2017         return dbStatsList;
   2018     }
   2019 
   2020     private void collectDbStats(ArrayList<DbStats> dbStatsList) {
   2021         synchronized (mLock) {
   2022             if (mConnectionPoolLocked != null) {
   2023                 mConnectionPoolLocked.collectDbStats(dbStatsList);
   2024             }
   2025         }
   2026     }
   2027 
   2028     private static ArrayList<SQLiteDatabase> getActiveDatabases() {
   2029         ArrayList<SQLiteDatabase> databases = new ArrayList<SQLiteDatabase>();
   2030         synchronized (sActiveDatabases) {
   2031             databases.addAll(sActiveDatabases.keySet());
   2032         }
   2033         return databases;
   2034     }
   2035 
   2036     /**
   2037      * Dump detailed information about all open databases in the current process.
   2038      * Used by bug report.
   2039      */
   2040     static void dumpAll(Printer printer, boolean verbose) {
   2041         for (SQLiteDatabase db : getActiveDatabases()) {
   2042             db.dump(printer, verbose);
   2043         }
   2044     }
   2045 
   2046     private void dump(Printer printer, boolean verbose) {
   2047         synchronized (mLock) {
   2048             if (mConnectionPoolLocked != null) {
   2049                 printer.println("");
   2050                 mConnectionPoolLocked.dump(printer, verbose);
   2051             }
   2052         }
   2053     }
   2054 
   2055     /**
   2056      * Returns list of full pathnames of all attached databases including the main database
   2057      * by executing 'pragma database_list' on the database.
   2058      *
   2059      * @return ArrayList of pairs of (database name, database file path) or null if the database
   2060      * is not open.
   2061      */
   2062     public List<Pair<String, String>> getAttachedDbs() {
   2063         ArrayList<Pair<String, String>> attachedDbs = new ArrayList<Pair<String, String>>();
   2064         synchronized (mLock) {
   2065             if (mConnectionPoolLocked == null) {
   2066                 return null; // not open
   2067             }
   2068 
   2069             if (!mHasAttachedDbsLocked) {
   2070                 // No attached databases.
   2071                 // There is a small window where attached databases exist but this flag is not
   2072                 // set yet.  This can occur when this thread is in a race condition with another
   2073                 // thread that is executing the SQL statement: "attach database <blah> as <foo>"
   2074                 // If this thread is NOT ok with such a race condition (and thus possibly not
   2075                 // receivethe entire list of attached databases), then the caller should ensure
   2076                 // that no thread is executing any SQL statements while a thread is calling this
   2077                 // method.  Typically, this method is called when 'adb bugreport' is done or the
   2078                 // caller wants to collect stats on the database and all its attached databases.
   2079                 attachedDbs.add(new Pair<String, String>("main", mConfigurationLocked.path));
   2080                 return attachedDbs;
   2081             }
   2082 
   2083             acquireReference();
   2084         }
   2085 
   2086         try {
   2087             // has attached databases. query sqlite to get the list of attached databases.
   2088             Cursor c = null;
   2089             try {
   2090                 c = rawQuery("pragma database_list;", null);
   2091                 while (c.moveToNext()) {
   2092                     // sqlite returns a row for each database in the returned list of databases.
   2093                     //   in each row,
   2094                     //       1st column is the database name such as main, or the database
   2095                     //                              name specified on the "ATTACH" command
   2096                     //       2nd column is the database file path.
   2097                     attachedDbs.add(new Pair<String, String>(c.getString(1), c.getString(2)));
   2098                 }
   2099             } finally {
   2100                 if (c != null) {
   2101                     c.close();
   2102                 }
   2103             }
   2104             return attachedDbs;
   2105         } finally {
   2106             releaseReference();
   2107         }
   2108     }
   2109 
   2110     /**
   2111      * Runs 'pragma integrity_check' on the given database (and all the attached databases)
   2112      * and returns true if the given database (and all its attached databases) pass integrity_check,
   2113      * false otherwise.
   2114      *<p>
   2115      * If the result is false, then this method logs the errors reported by the integrity_check
   2116      * command execution.
   2117      *<p>
   2118      * Note that 'pragma integrity_check' on a database can take a long time.
   2119      *
   2120      * @return true if the given database (and all its attached databases) pass integrity_check,
   2121      * false otherwise.
   2122      */
   2123     public boolean isDatabaseIntegrityOk() {
   2124         acquireReference();
   2125         try {
   2126             List<Pair<String, String>> attachedDbs = null;
   2127             try {
   2128                 attachedDbs = getAttachedDbs();
   2129                 if (attachedDbs == null) {
   2130                     throw new IllegalStateException("databaselist for: " + getPath() + " couldn't " +
   2131                             "be retrieved. probably because the database is closed");
   2132                 }
   2133             } catch (SQLiteException e) {
   2134                 // can't get attachedDb list. do integrity check on the main database
   2135                 attachedDbs = new ArrayList<Pair<String, String>>();
   2136                 attachedDbs.add(new Pair<String, String>("main", getPath()));
   2137             }
   2138 
   2139             for (int i = 0; i < attachedDbs.size(); i++) {
   2140                 Pair<String, String> p = attachedDbs.get(i);
   2141                 SQLiteStatement prog = null;
   2142                 try {
   2143                     prog = compileStatement("PRAGMA " + p.first + ".integrity_check(1);");
   2144                     String rslt = prog.simpleQueryForString();
   2145                     if (!rslt.equalsIgnoreCase("ok")) {
   2146                         // integrity_checker failed on main or attached databases
   2147                         Log.e(TAG, "PRAGMA integrity_check on " + p.second + " returned: " + rslt);
   2148                         return false;
   2149                     }
   2150                 } finally {
   2151                     if (prog != null) prog.close();
   2152                 }
   2153             }
   2154         } finally {
   2155             releaseReference();
   2156         }
   2157         return true;
   2158     }
   2159 
   2160     @Override
   2161     public String toString() {
   2162         return "SQLiteDatabase: " + getPath();
   2163     }
   2164 
   2165     private void throwIfNotOpenLocked() {
   2166         if (mConnectionPoolLocked == null) {
   2167             throw new IllegalStateException("The database '" + mConfigurationLocked.label
   2168                     + "' is not open.");
   2169         }
   2170     }
   2171 
   2172     /**
   2173      * Used to allow returning sub-classes of {@link Cursor} when calling query.
   2174      */
   2175     public interface CursorFactory {
   2176         /**
   2177          * See {@link SQLiteCursor#SQLiteCursor(SQLiteCursorDriver, String, SQLiteQuery)}.
   2178          */
   2179         public Cursor newCursor(SQLiteDatabase db,
   2180                 SQLiteCursorDriver masterQuery, String editTable,
   2181                 SQLiteQuery query);
   2182     }
   2183 
   2184     /**
   2185      * A callback interface for a custom sqlite3 function.
   2186      * This can be used to create a function that can be called from
   2187      * sqlite3 database triggers.
   2188      * @hide
   2189      */
   2190     public interface CustomFunction {
   2191         public void callback(String[] args);
   2192     }
   2193 }
   2194