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             File[] files = dir.listFiles(new FileFilter() {
    742                 @Override
    743                 public boolean accept(File candidate) {
    744                     return candidate.getName().startsWith(prefix);
    745                 }
    746             });
    747             if (files != null) {
    748                 for (File masterJournal : files) {
    749                     deleted |= masterJournal.delete();
    750                 }
    751             }
    752         }
    753         return deleted;
    754     }
    755 
    756     /**
    757      * Reopens the database in read-write mode.
    758      * If the database is already read-write, does nothing.
    759      *
    760      * @throws SQLiteException if the database could not be reopened as requested, in which
    761      * case it remains open in read only mode.
    762      * @throws IllegalStateException if the database is not open.
    763      *
    764      * @see #isReadOnly()
    765      * @hide
    766      */
    767     public void reopenReadWrite() {
    768         synchronized (mLock) {
    769             throwIfNotOpenLocked();
    770 
    771             if (!isReadOnlyLocked()) {
    772                 return; // nothing to do
    773             }
    774 
    775             // Reopen the database in read-write mode.
    776             final int oldOpenFlags = mConfigurationLocked.openFlags;
    777             mConfigurationLocked.openFlags = (mConfigurationLocked.openFlags & ~OPEN_READ_MASK)
    778                     | OPEN_READWRITE;
    779             try {
    780                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
    781             } catch (RuntimeException ex) {
    782                 mConfigurationLocked.openFlags = oldOpenFlags;
    783                 throw ex;
    784             }
    785         }
    786     }
    787 
    788     private void open() {
    789         try {
    790             try {
    791                 openInner();
    792             } catch (SQLiteDatabaseCorruptException ex) {
    793                 onCorruption();
    794                 openInner();
    795             }
    796         } catch (SQLiteException ex) {
    797             Log.e(TAG, "Failed to open database '" + getLabel() + "'.", ex);
    798             close();
    799             throw ex;
    800         }
    801     }
    802 
    803     private void openInner() {
    804         synchronized (mLock) {
    805             assert mConnectionPoolLocked == null;
    806             mConnectionPoolLocked = SQLiteConnectionPool.open(mConfigurationLocked);
    807             mCloseGuardLocked.open("close");
    808         }
    809 
    810         synchronized (sActiveDatabases) {
    811             sActiveDatabases.put(this, null);
    812         }
    813     }
    814 
    815     /**
    816      * Create a memory backed SQLite database.  Its contents will be destroyed
    817      * when the database is closed.
    818      *
    819      * <p>Sets the locale of the database to the  the system's current locale.
    820      * Call {@link #setLocale} if you would like something else.</p>
    821      *
    822      * @param factory an optional factory class that is called to instantiate a
    823      *            cursor when query is called
    824      * @return a SQLiteDatabase object, or null if the database can't be created
    825      */
    826     public static SQLiteDatabase create(CursorFactory factory) {
    827         // This is a magic string with special meaning for SQLite.
    828         return openDatabase(SQLiteDatabaseConfiguration.MEMORY_DB_PATH,
    829                 factory, CREATE_IF_NECESSARY);
    830     }
    831 
    832     /**
    833      * Registers a CustomFunction callback as a function that can be called from
    834      * SQLite database triggers.
    835      *
    836      * @param name the name of the sqlite3 function
    837      * @param numArgs the number of arguments for the function
    838      * @param function callback to call when the function is executed
    839      * @hide
    840      */
    841     public void addCustomFunction(String name, int numArgs, CustomFunction function) {
    842         // Create wrapper (also validates arguments).
    843         SQLiteCustomFunction wrapper = new SQLiteCustomFunction(name, numArgs, function);
    844 
    845         synchronized (mLock) {
    846             throwIfNotOpenLocked();
    847 
    848             mConfigurationLocked.customFunctions.add(wrapper);
    849             try {
    850                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
    851             } catch (RuntimeException ex) {
    852                 mConfigurationLocked.customFunctions.remove(wrapper);
    853                 throw ex;
    854             }
    855         }
    856     }
    857 
    858     /**
    859      * Gets the database version.
    860      *
    861      * @return the database version
    862      */
    863     public int getVersion() {
    864         return ((Long) DatabaseUtils.longForQuery(this, "PRAGMA user_version;", null)).intValue();
    865     }
    866 
    867     /**
    868      * Sets the database version.
    869      *
    870      * @param version the new database version
    871      */
    872     public void setVersion(int version) {
    873         execSQL("PRAGMA user_version = " + version);
    874     }
    875 
    876     /**
    877      * Returns the maximum size the database may grow to.
    878      *
    879      * @return the new maximum database size
    880      */
    881     public long getMaximumSize() {
    882         long pageCount = DatabaseUtils.longForQuery(this, "PRAGMA max_page_count;", null);
    883         return pageCount * getPageSize();
    884     }
    885 
    886     /**
    887      * Sets the maximum size the database will grow to. The maximum size cannot
    888      * be set below the current size.
    889      *
    890      * @param numBytes the maximum database size, in bytes
    891      * @return the new maximum database size
    892      */
    893     public long setMaximumSize(long numBytes) {
    894         long pageSize = getPageSize();
    895         long numPages = numBytes / pageSize;
    896         // If numBytes isn't a multiple of pageSize, bump up a page
    897         if ((numBytes % pageSize) != 0) {
    898             numPages++;
    899         }
    900         long newPageCount = DatabaseUtils.longForQuery(this, "PRAGMA max_page_count = " + numPages,
    901                 null);
    902         return newPageCount * pageSize;
    903     }
    904 
    905     /**
    906      * Returns the current database page size, in bytes.
    907      *
    908      * @return the database page size, in bytes
    909      */
    910     public long getPageSize() {
    911         return DatabaseUtils.longForQuery(this, "PRAGMA page_size;", null);
    912     }
    913 
    914     /**
    915      * Sets the database page size. The page size must be a power of two. This
    916      * method does not work if any data has been written to the database file,
    917      * and must be called right after the database has been created.
    918      *
    919      * @param numBytes the database page size, in bytes
    920      */
    921     public void setPageSize(long numBytes) {
    922         execSQL("PRAGMA page_size = " + numBytes);
    923     }
    924 
    925     /**
    926      * Mark this table as syncable. When an update occurs in this table the
    927      * _sync_dirty field will be set to ensure proper syncing operation.
    928      *
    929      * @param table the table to mark as syncable
    930      * @param deletedTable The deleted table that corresponds to the
    931      *          syncable table
    932      * @deprecated This method no longer serves any useful purpose and has been deprecated.
    933      */
    934     @Deprecated
    935     public void markTableSyncable(String table, String deletedTable) {
    936     }
    937 
    938     /**
    939      * Mark this table as syncable, with the _sync_dirty residing in another
    940      * table. When an update occurs in this table the _sync_dirty field of the
    941      * row in updateTable with the _id in foreignKey will be set to
    942      * ensure proper syncing operation.
    943      *
    944      * @param table an update on this table will trigger a sync time removal
    945      * @param foreignKey this is the column in table whose value is an _id in
    946      *          updateTable
    947      * @param updateTable this is the table that will have its _sync_dirty
    948      * @deprecated This method no longer serves any useful purpose and has been deprecated.
    949      */
    950     @Deprecated
    951     public void markTableSyncable(String table, String foreignKey, String updateTable) {
    952     }
    953 
    954     /**
    955      * Finds the name of the first table, which is editable.
    956      *
    957      * @param tables a list of tables
    958      * @return the first table listed
    959      */
    960     public static String findEditTable(String tables) {
    961         if (!TextUtils.isEmpty(tables)) {
    962             // find the first word terminated by either a space or a comma
    963             int spacepos = tables.indexOf(' ');
    964             int commapos = tables.indexOf(',');
    965 
    966             if (spacepos > 0 && (spacepos < commapos || commapos < 0)) {
    967                 return tables.substring(0, spacepos);
    968             } else if (commapos > 0 && (commapos < spacepos || spacepos < 0) ) {
    969                 return tables.substring(0, commapos);
    970             }
    971             return tables;
    972         } else {
    973             throw new IllegalStateException("Invalid tables");
    974         }
    975     }
    976 
    977     /**
    978      * Compiles an SQL statement into a reusable pre-compiled statement object.
    979      * The parameters are identical to {@link #execSQL(String)}. You may put ?s in the
    980      * statement and fill in those values with {@link SQLiteProgram#bindString}
    981      * and {@link SQLiteProgram#bindLong} each time you want to run the
    982      * statement. Statements may not return result sets larger than 1x1.
    983      *<p>
    984      * No two threads should be using the same {@link SQLiteStatement} at the same time.
    985      *
    986      * @param sql The raw SQL statement, may contain ? for unknown values to be
    987      *            bound later.
    988      * @return A pre-compiled {@link SQLiteStatement} object. Note that
    989      * {@link SQLiteStatement}s are not synchronized, see the documentation for more details.
    990      */
    991     public SQLiteStatement compileStatement(String sql) throws SQLException {
    992         acquireReference();
    993         try {
    994             return new SQLiteStatement(this, sql, null);
    995         } finally {
    996             releaseReference();
    997         }
    998     }
    999 
   1000     /**
   1001      * Query the given URL, returning a {@link Cursor} over the result set.
   1002      *
   1003      * @param distinct true if you want each row to be unique, false otherwise.
   1004      * @param table The table name to compile the query against.
   1005      * @param columns A list of which columns to return. Passing null will
   1006      *            return all columns, which is discouraged to prevent reading
   1007      *            data from storage that isn't going to be used.
   1008      * @param selection A filter declaring which rows to return, formatted as an
   1009      *            SQL WHERE clause (excluding the WHERE itself). Passing null
   1010      *            will return all rows for the given table.
   1011      * @param selectionArgs You may include ?s in selection, which will be
   1012      *         replaced by the values from selectionArgs, in order that they
   1013      *         appear in the selection. The values will be bound as Strings.
   1014      * @param groupBy A filter declaring how to group rows, formatted as an SQL
   1015      *            GROUP BY clause (excluding the GROUP BY itself). Passing null
   1016      *            will cause the rows to not be grouped.
   1017      * @param having A filter declare which row groups to include in the cursor,
   1018      *            if row grouping is being used, formatted as an SQL HAVING
   1019      *            clause (excluding the HAVING itself). Passing null will cause
   1020      *            all row groups to be included, and is required when row
   1021      *            grouping is not being used.
   1022      * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
   1023      *            (excluding the ORDER BY itself). Passing null will use the
   1024      *            default sort order, which may be unordered.
   1025      * @param limit Limits the number of rows returned by the query,
   1026      *            formatted as LIMIT clause. Passing null denotes no LIMIT clause.
   1027      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
   1028      * {@link Cursor}s are not synchronized, see the documentation for more details.
   1029      * @see Cursor
   1030      */
   1031     public Cursor query(boolean distinct, String table, String[] columns,
   1032             String selection, String[] selectionArgs, String groupBy,
   1033             String having, String orderBy, String limit) {
   1034         return queryWithFactory(null, distinct, table, columns, selection, selectionArgs,
   1035                 groupBy, having, orderBy, limit, null);
   1036     }
   1037 
   1038     /**
   1039      * Query the given URL, returning a {@link Cursor} over the result set.
   1040      *
   1041      * @param distinct true if you want each row to be unique, false otherwise.
   1042      * @param table The table name to compile the query against.
   1043      * @param columns A list of which columns to return. Passing null will
   1044      *            return all columns, which is discouraged to prevent reading
   1045      *            data from storage that isn't going to be used.
   1046      * @param selection A filter declaring which rows to return, formatted as an
   1047      *            SQL WHERE clause (excluding the WHERE itself). Passing null
   1048      *            will return all rows for the given table.
   1049      * @param selectionArgs You may include ?s in selection, which will be
   1050      *         replaced by the values from selectionArgs, in order that they
   1051      *         appear in the selection. The values will be bound as Strings.
   1052      * @param groupBy A filter declaring how to group rows, formatted as an SQL
   1053      *            GROUP BY clause (excluding the GROUP BY itself). Passing null
   1054      *            will cause the rows to not be grouped.
   1055      * @param having A filter declare which row groups to include in the cursor,
   1056      *            if row grouping is being used, formatted as an SQL HAVING
   1057      *            clause (excluding the HAVING itself). Passing null will cause
   1058      *            all row groups to be included, and is required when row
   1059      *            grouping is not being used.
   1060      * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
   1061      *            (excluding the ORDER BY itself). Passing null will use the
   1062      *            default sort order, which may be unordered.
   1063      * @param limit Limits the number of rows returned by the query,
   1064      *            formatted as LIMIT clause. Passing null denotes no LIMIT clause.
   1065      * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
   1066      * If the operation is canceled, then {@link OperationCanceledException} will be thrown
   1067      * when the query is executed.
   1068      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
   1069      * {@link Cursor}s are not synchronized, see the documentation for more details.
   1070      * @see Cursor
   1071      */
   1072     public Cursor query(boolean distinct, String table, String[] columns,
   1073             String selection, String[] selectionArgs, String groupBy,
   1074             String having, String orderBy, String limit, CancellationSignal cancellationSignal) {
   1075         return queryWithFactory(null, distinct, table, columns, selection, selectionArgs,
   1076                 groupBy, having, orderBy, limit, cancellationSignal);
   1077     }
   1078 
   1079     /**
   1080      * Query the given URL, returning a {@link Cursor} over the result set.
   1081      *
   1082      * @param cursorFactory the cursor factory to use, or null for the default factory
   1083      * @param distinct true if you want each row to be unique, false otherwise.
   1084      * @param table The table name to compile the query against.
   1085      * @param columns A list of which columns to return. Passing null will
   1086      *            return all columns, which is discouraged to prevent reading
   1087      *            data from storage that isn't going to be used.
   1088      * @param selection A filter declaring which rows to return, formatted as an
   1089      *            SQL WHERE clause (excluding the WHERE itself). Passing null
   1090      *            will return all rows for the given table.
   1091      * @param selectionArgs You may include ?s in selection, which will be
   1092      *         replaced by the values from selectionArgs, in order that they
   1093      *         appear in the selection. The values will be bound as Strings.
   1094      * @param groupBy A filter declaring how to group rows, formatted as an SQL
   1095      *            GROUP BY clause (excluding the GROUP BY itself). Passing null
   1096      *            will cause the rows to not be grouped.
   1097      * @param having A filter declare which row groups to include in the cursor,
   1098      *            if row grouping is being used, formatted as an SQL HAVING
   1099      *            clause (excluding the HAVING itself). Passing null will cause
   1100      *            all row groups to be included, and is required when row
   1101      *            grouping is not being used.
   1102      * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
   1103      *            (excluding the ORDER BY itself). Passing null will use the
   1104      *            default sort order, which may be unordered.
   1105      * @param limit Limits the number of rows returned by the query,
   1106      *            formatted as LIMIT clause. Passing null denotes no LIMIT clause.
   1107      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
   1108      * {@link Cursor}s are not synchronized, see the documentation for more details.
   1109      * @see Cursor
   1110      */
   1111     public Cursor queryWithFactory(CursorFactory cursorFactory,
   1112             boolean distinct, String table, String[] columns,
   1113             String selection, String[] selectionArgs, String groupBy,
   1114             String having, String orderBy, String limit) {
   1115         return queryWithFactory(cursorFactory, distinct, table, columns, selection,
   1116                 selectionArgs, groupBy, having, orderBy, limit, null);
   1117     }
   1118 
   1119     /**
   1120      * Query the given URL, returning a {@link Cursor} over the result set.
   1121      *
   1122      * @param cursorFactory the cursor factory to use, or null for the default factory
   1123      * @param distinct true if you want each row to be unique, false otherwise.
   1124      * @param table The table name to compile the query against.
   1125      * @param columns A list of which columns to return. Passing null will
   1126      *            return all columns, which is discouraged to prevent reading
   1127      *            data from storage that isn't going to be used.
   1128      * @param selection A filter declaring which rows to return, formatted as an
   1129      *            SQL WHERE clause (excluding the WHERE itself). Passing null
   1130      *            will return all rows for the given table.
   1131      * @param selectionArgs You may include ?s in selection, which will be
   1132      *         replaced by the values from selectionArgs, in order that they
   1133      *         appear in the selection. The values will be bound as Strings.
   1134      * @param groupBy A filter declaring how to group rows, formatted as an SQL
   1135      *            GROUP BY clause (excluding the GROUP BY itself). Passing null
   1136      *            will cause the rows to not be grouped.
   1137      * @param having A filter declare which row groups to include in the cursor,
   1138      *            if row grouping is being used, formatted as an SQL HAVING
   1139      *            clause (excluding the HAVING itself). Passing null will cause
   1140      *            all row groups to be included, and is required when row
   1141      *            grouping is not being used.
   1142      * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
   1143      *            (excluding the ORDER BY itself). Passing null will use the
   1144      *            default sort order, which may be unordered.
   1145      * @param limit Limits the number of rows returned by the query,
   1146      *            formatted as LIMIT clause. Passing null denotes no LIMIT clause.
   1147      * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
   1148      * If the operation is canceled, then {@link OperationCanceledException} will be thrown
   1149      * when the query is executed.
   1150      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
   1151      * {@link Cursor}s are not synchronized, see the documentation for more details.
   1152      * @see Cursor
   1153      */
   1154     public Cursor queryWithFactory(CursorFactory cursorFactory,
   1155             boolean distinct, String table, String[] columns,
   1156             String selection, String[] selectionArgs, String groupBy,
   1157             String having, String orderBy, String limit, CancellationSignal cancellationSignal) {
   1158         acquireReference();
   1159         try {
   1160             String sql = SQLiteQueryBuilder.buildQueryString(
   1161                     distinct, table, columns, selection, groupBy, having, orderBy, limit);
   1162 
   1163             return rawQueryWithFactory(cursorFactory, sql, selectionArgs,
   1164                     findEditTable(table), cancellationSignal);
   1165         } finally {
   1166             releaseReference();
   1167         }
   1168     }
   1169 
   1170     /**
   1171      * Query the given table, returning a {@link Cursor} over the result set.
   1172      *
   1173      * @param table The table name to compile the query against.
   1174      * @param columns A list of which columns to return. Passing null will
   1175      *            return all columns, which is discouraged to prevent reading
   1176      *            data from storage that isn't going to be used.
   1177      * @param selection A filter declaring which rows to return, formatted as an
   1178      *            SQL WHERE clause (excluding the WHERE itself). Passing null
   1179      *            will return all rows for the given table.
   1180      * @param selectionArgs You may include ?s in selection, which will be
   1181      *         replaced by the values from selectionArgs, in order that they
   1182      *         appear in the selection. The values will be bound as Strings.
   1183      * @param groupBy A filter declaring how to group rows, formatted as an SQL
   1184      *            GROUP BY clause (excluding the GROUP BY itself). Passing null
   1185      *            will cause the rows to not be grouped.
   1186      * @param having A filter declare which row groups to include in the cursor,
   1187      *            if row grouping is being used, formatted as an SQL HAVING
   1188      *            clause (excluding the HAVING itself). Passing null will cause
   1189      *            all row groups to be included, and is required when row
   1190      *            grouping is not being used.
   1191      * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
   1192      *            (excluding the ORDER BY itself). Passing null will use the
   1193      *            default sort order, which may be unordered.
   1194      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
   1195      * {@link Cursor}s are not synchronized, see the documentation for more details.
   1196      * @see Cursor
   1197      */
   1198     public Cursor query(String table, String[] columns, String selection,
   1199             String[] selectionArgs, String groupBy, String having,
   1200             String orderBy) {
   1201 
   1202         return query(false, table, columns, selection, selectionArgs, groupBy,
   1203                 having, orderBy, null /* limit */);
   1204     }
   1205 
   1206     /**
   1207      * Query the given table, returning a {@link Cursor} over the result set.
   1208      *
   1209      * @param table The table name to compile the query against.
   1210      * @param columns A list of which columns to return. Passing null will
   1211      *            return all columns, which is discouraged to prevent reading
   1212      *            data from storage that isn't going to be used.
   1213      * @param selection A filter declaring which rows to return, formatted as an
   1214      *            SQL WHERE clause (excluding the WHERE itself). Passing null
   1215      *            will return all rows for the given table.
   1216      * @param selectionArgs You may include ?s in selection, which will be
   1217      *         replaced by the values from selectionArgs, in order that they
   1218      *         appear in the selection. The values will be bound as Strings.
   1219      * @param groupBy A filter declaring how to group rows, formatted as an SQL
   1220      *            GROUP BY clause (excluding the GROUP BY itself). Passing null
   1221      *            will cause the rows to not be grouped.
   1222      * @param having A filter declare which row groups to include in the cursor,
   1223      *            if row grouping is being used, formatted as an SQL HAVING
   1224      *            clause (excluding the HAVING itself). Passing null will cause
   1225      *            all row groups to be included, and is required when row
   1226      *            grouping is not being used.
   1227      * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
   1228      *            (excluding the ORDER BY itself). Passing null will use the
   1229      *            default sort order, which may be unordered.
   1230      * @param limit Limits the number of rows returned by the query,
   1231      *            formatted as LIMIT clause. Passing null denotes no LIMIT clause.
   1232      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
   1233      * {@link Cursor}s are not synchronized, see the documentation for more details.
   1234      * @see Cursor
   1235      */
   1236     public Cursor query(String table, String[] columns, String selection,
   1237             String[] selectionArgs, String groupBy, String having,
   1238             String orderBy, String limit) {
   1239 
   1240         return query(false, table, columns, selection, selectionArgs, groupBy,
   1241                 having, orderBy, limit);
   1242     }
   1243 
   1244     /**
   1245      * Runs the provided SQL and returns a {@link Cursor} over the result set.
   1246      *
   1247      * @param sql the SQL query. The SQL string must not be ; terminated
   1248      * @param selectionArgs You may include ?s in where clause in the query,
   1249      *     which will be replaced by the values from selectionArgs. The
   1250      *     values will be bound as Strings.
   1251      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
   1252      * {@link Cursor}s are not synchronized, see the documentation for more details.
   1253      */
   1254     public Cursor rawQuery(String sql, String[] selectionArgs) {
   1255         return rawQueryWithFactory(null, sql, selectionArgs, null, null);
   1256     }
   1257 
   1258     /**
   1259      * Runs the provided SQL and returns a {@link Cursor} over the result set.
   1260      *
   1261      * @param sql the SQL query. The SQL string must not be ; terminated
   1262      * @param selectionArgs You may include ?s in where clause in the query,
   1263      *     which will be replaced by the values from selectionArgs. The
   1264      *     values will be bound as Strings.
   1265      * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
   1266      * If the operation is canceled, then {@link OperationCanceledException} will be thrown
   1267      * when the query is executed.
   1268      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
   1269      * {@link Cursor}s are not synchronized, see the documentation for more details.
   1270      */
   1271     public Cursor rawQuery(String sql, String[] selectionArgs,
   1272             CancellationSignal cancellationSignal) {
   1273         return rawQueryWithFactory(null, sql, selectionArgs, null, cancellationSignal);
   1274     }
   1275 
   1276     /**
   1277      * Runs the provided SQL and returns a cursor over the result set.
   1278      *
   1279      * @param cursorFactory the cursor factory to use, or null for the default factory
   1280      * @param sql the SQL query. The SQL string must not be ; terminated
   1281      * @param selectionArgs You may include ?s in where clause in the query,
   1282      *     which will be replaced by the values from selectionArgs. The
   1283      *     values will be bound as Strings.
   1284      * @param editTable the name of the first table, which is editable
   1285      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
   1286      * {@link Cursor}s are not synchronized, see the documentation for more details.
   1287      */
   1288     public Cursor rawQueryWithFactory(
   1289             CursorFactory cursorFactory, String sql, String[] selectionArgs,
   1290             String editTable) {
   1291         return rawQueryWithFactory(cursorFactory, sql, selectionArgs, editTable, null);
   1292     }
   1293 
   1294     /**
   1295      * Runs the provided SQL and returns a cursor over the result set.
   1296      *
   1297      * @param cursorFactory the cursor factory to use, or null for the default factory
   1298      * @param sql the SQL query. The SQL string must not be ; terminated
   1299      * @param selectionArgs You may include ?s in where clause in the query,
   1300      *     which will be replaced by the values from selectionArgs. The
   1301      *     values will be bound as Strings.
   1302      * @param editTable the name of the first table, which is editable
   1303      * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
   1304      * If the operation is canceled, then {@link OperationCanceledException} will be thrown
   1305      * when the query is executed.
   1306      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
   1307      * {@link Cursor}s are not synchronized, see the documentation for more details.
   1308      */
   1309     public Cursor rawQueryWithFactory(
   1310             CursorFactory cursorFactory, String sql, String[] selectionArgs,
   1311             String editTable, CancellationSignal cancellationSignal) {
   1312         acquireReference();
   1313         try {
   1314             SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(this, sql, editTable,
   1315                     cancellationSignal);
   1316             return driver.query(cursorFactory != null ? cursorFactory : mCursorFactory,
   1317                     selectionArgs);
   1318         } finally {
   1319             releaseReference();
   1320         }
   1321     }
   1322 
   1323     /**
   1324      * Convenience method for inserting a row into the database.
   1325      *
   1326      * @param table the table to insert the row into
   1327      * @param nullColumnHack optional; may be <code>null</code>.
   1328      *            SQL doesn't allow inserting a completely empty row without
   1329      *            naming at least one column name.  If your provided <code>values</code> is
   1330      *            empty, no column names are known and an empty row can't be inserted.
   1331      *            If not set to null, the <code>nullColumnHack</code> parameter
   1332      *            provides the name of nullable column name to explicitly insert a NULL into
   1333      *            in the case where your <code>values</code> is empty.
   1334      * @param values this map contains the initial column values for the
   1335      *            row. The keys should be the column names and the values the
   1336      *            column values
   1337      * @return the row ID of the newly inserted row, or -1 if an error occurred
   1338      */
   1339     public long insert(String table, String nullColumnHack, ContentValues values) {
   1340         try {
   1341             return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE);
   1342         } catch (SQLException e) {
   1343             Log.e(TAG, "Error inserting " + values, e);
   1344             return -1;
   1345         }
   1346     }
   1347 
   1348     /**
   1349      * Convenience method for inserting a row into the database.
   1350      *
   1351      * @param table the table to insert the row into
   1352      * @param nullColumnHack optional; may be <code>null</code>.
   1353      *            SQL doesn't allow inserting a completely empty row without
   1354      *            naming at least one column name.  If your provided <code>values</code> is
   1355      *            empty, no column names are known and an empty row can't be inserted.
   1356      *            If not set to null, the <code>nullColumnHack</code> parameter
   1357      *            provides the name of nullable column name to explicitly insert a NULL into
   1358      *            in the case where your <code>values</code> is empty.
   1359      * @param values this map contains the initial column values for the
   1360      *            row. The keys should be the column names and the values the
   1361      *            column values
   1362      * @throws SQLException
   1363      * @return the row ID of the newly inserted row, or -1 if an error occurred
   1364      */
   1365     public long insertOrThrow(String table, String nullColumnHack, ContentValues values)
   1366             throws SQLException {
   1367         return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE);
   1368     }
   1369 
   1370     /**
   1371      * Convenience method for replacing a row in the database.
   1372      *
   1373      * @param table the table in which to replace the row
   1374      * @param nullColumnHack optional; may be <code>null</code>.
   1375      *            SQL doesn't allow inserting a completely empty row without
   1376      *            naming at least one column name.  If your provided <code>initialValues</code> is
   1377      *            empty, no column names are known and an empty row can't be inserted.
   1378      *            If not set to null, the <code>nullColumnHack</code> parameter
   1379      *            provides the name of nullable column name to explicitly insert a NULL into
   1380      *            in the case where your <code>initialValues</code> is empty.
   1381      * @param initialValues this map contains the initial column values for
   1382      *   the row.
   1383      * @return the row ID of the newly inserted row, or -1 if an error occurred
   1384      */
   1385     public long replace(String table, String nullColumnHack, ContentValues initialValues) {
   1386         try {
   1387             return insertWithOnConflict(table, nullColumnHack, initialValues,
   1388                     CONFLICT_REPLACE);
   1389         } catch (SQLException e) {
   1390             Log.e(TAG, "Error inserting " + initialValues, e);
   1391             return -1;
   1392         }
   1393     }
   1394 
   1395     /**
   1396      * Convenience method for replacing a row in the database.
   1397      *
   1398      * @param table the table in which to replace the row
   1399      * @param nullColumnHack optional; may be <code>null</code>.
   1400      *            SQL doesn't allow inserting a completely empty row without
   1401      *            naming at least one column name.  If your provided <code>initialValues</code> is
   1402      *            empty, no column names are known and an empty row can't be inserted.
   1403      *            If not set to null, the <code>nullColumnHack</code> parameter
   1404      *            provides the name of nullable column name to explicitly insert a NULL into
   1405      *            in the case where your <code>initialValues</code> is empty.
   1406      * @param initialValues this map contains the initial column values for
   1407      *   the row. The key
   1408      * @throws SQLException
   1409      * @return the row ID of the newly inserted row, or -1 if an error occurred
   1410      */
   1411     public long replaceOrThrow(String table, String nullColumnHack,
   1412             ContentValues initialValues) throws SQLException {
   1413         return insertWithOnConflict(table, nullColumnHack, initialValues,
   1414                 CONFLICT_REPLACE);
   1415     }
   1416 
   1417     /**
   1418      * General method for inserting a row into the database.
   1419      *
   1420      * @param table the table to insert the row into
   1421      * @param nullColumnHack optional; may be <code>null</code>.
   1422      *            SQL doesn't allow inserting a completely empty row without
   1423      *            naming at least one column name.  If your provided <code>initialValues</code> is
   1424      *            empty, no column names are known and an empty row can't be inserted.
   1425      *            If not set to null, the <code>nullColumnHack</code> parameter
   1426      *            provides the name of nullable column name to explicitly insert a NULL into
   1427      *            in the case where your <code>initialValues</code> is empty.
   1428      * @param initialValues this map contains the initial column values for the
   1429      *            row. The keys should be the column names and the values the
   1430      *            column values
   1431      * @param conflictAlgorithm for insert conflict resolver
   1432      * @return the row ID of the newly inserted row
   1433      * OR the primary key of the existing row if the input param 'conflictAlgorithm' =
   1434      * {@link #CONFLICT_IGNORE}
   1435      * OR -1 if any error
   1436      */
   1437     public long insertWithOnConflict(String table, String nullColumnHack,
   1438             ContentValues initialValues, int conflictAlgorithm) {
   1439         acquireReference();
   1440         try {
   1441             StringBuilder sql = new StringBuilder();
   1442             sql.append("INSERT");
   1443             sql.append(CONFLICT_VALUES[conflictAlgorithm]);
   1444             sql.append(" INTO ");
   1445             sql.append(table);
   1446             sql.append('(');
   1447 
   1448             Object[] bindArgs = null;
   1449             int size = (initialValues != null && initialValues.size() > 0)
   1450                     ? initialValues.size() : 0;
   1451             if (size > 0) {
   1452                 bindArgs = new Object[size];
   1453                 int i = 0;
   1454                 for (String colName : initialValues.keySet()) {
   1455                     sql.append((i > 0) ? "," : "");
   1456                     sql.append(colName);
   1457                     bindArgs[i++] = initialValues.get(colName);
   1458                 }
   1459                 sql.append(')');
   1460                 sql.append(" VALUES (");
   1461                 for (i = 0; i < size; i++) {
   1462                     sql.append((i > 0) ? ",?" : "?");
   1463                 }
   1464             } else {
   1465                 sql.append(nullColumnHack + ") VALUES (NULL");
   1466             }
   1467             sql.append(')');
   1468 
   1469             SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs);
   1470             try {
   1471                 return statement.executeInsert();
   1472             } finally {
   1473                 statement.close();
   1474             }
   1475         } finally {
   1476             releaseReference();
   1477         }
   1478     }
   1479 
   1480     /**
   1481      * Convenience method for deleting rows in the database.
   1482      *
   1483      * @param table the table to delete from
   1484      * @param whereClause the optional WHERE clause to apply when deleting.
   1485      *            Passing null will delete all rows.
   1486      * @param whereArgs You may include ?s in the where clause, which
   1487      *            will be replaced by the values from whereArgs. The values
   1488      *            will be bound as Strings.
   1489      * @return the number of rows affected if a whereClause is passed in, 0
   1490      *         otherwise. To remove all rows and get a count pass "1" as the
   1491      *         whereClause.
   1492      */
   1493     public int delete(String table, String whereClause, String[] whereArgs) {
   1494         acquireReference();
   1495         try {
   1496             SQLiteStatement statement =  new SQLiteStatement(this, "DELETE FROM " + table +
   1497                     (!TextUtils.isEmpty(whereClause) ? " WHERE " + whereClause : ""), whereArgs);
   1498             try {
   1499                 return statement.executeUpdateDelete();
   1500             } finally {
   1501                 statement.close();
   1502             }
   1503         } finally {
   1504             releaseReference();
   1505         }
   1506     }
   1507 
   1508     /**
   1509      * Convenience method for updating rows in the database.
   1510      *
   1511      * @param table the table to update in
   1512      * @param values a map from column names to new column values. null is a
   1513      *            valid value that will be translated to NULL.
   1514      * @param whereClause the optional WHERE clause to apply when updating.
   1515      *            Passing null will update all rows.
   1516      * @param whereArgs You may include ?s in the where clause, which
   1517      *            will be replaced by the values from whereArgs. The values
   1518      *            will be bound as Strings.
   1519      * @return the number of rows affected
   1520      */
   1521     public int update(String table, ContentValues values, String whereClause, String[] whereArgs) {
   1522         return updateWithOnConflict(table, values, whereClause, whereArgs, CONFLICT_NONE);
   1523     }
   1524 
   1525     /**
   1526      * Convenience method for updating rows in the database.
   1527      *
   1528      * @param table the table to update in
   1529      * @param values a map from column names to new column values. null is a
   1530      *            valid value that will be translated to NULL.
   1531      * @param whereClause the optional WHERE clause to apply when updating.
   1532      *            Passing null will update all rows.
   1533      * @param whereArgs You may include ?s in the where clause, which
   1534      *            will be replaced by the values from whereArgs. The values
   1535      *            will be bound as Strings.
   1536      * @param conflictAlgorithm for update conflict resolver
   1537      * @return the number of rows affected
   1538      */
   1539     public int updateWithOnConflict(String table, ContentValues values,
   1540             String whereClause, String[] whereArgs, int conflictAlgorithm) {
   1541         if (values == null || values.size() == 0) {
   1542             throw new IllegalArgumentException("Empty values");
   1543         }
   1544 
   1545         acquireReference();
   1546         try {
   1547             StringBuilder sql = new StringBuilder(120);
   1548             sql.append("UPDATE ");
   1549             sql.append(CONFLICT_VALUES[conflictAlgorithm]);
   1550             sql.append(table);
   1551             sql.append(" SET ");
   1552 
   1553             // move all bind args to one array
   1554             int setValuesSize = values.size();
   1555             int bindArgsSize = (whereArgs == null) ? setValuesSize : (setValuesSize + whereArgs.length);
   1556             Object[] bindArgs = new Object[bindArgsSize];
   1557             int i = 0;
   1558             for (String colName : values.keySet()) {
   1559                 sql.append((i > 0) ? "," : "");
   1560                 sql.append(colName);
   1561                 bindArgs[i++] = values.get(colName);
   1562                 sql.append("=?");
   1563             }
   1564             if (whereArgs != null) {
   1565                 for (i = setValuesSize; i < bindArgsSize; i++) {
   1566                     bindArgs[i] = whereArgs[i - setValuesSize];
   1567                 }
   1568             }
   1569             if (!TextUtils.isEmpty(whereClause)) {
   1570                 sql.append(" WHERE ");
   1571                 sql.append(whereClause);
   1572             }
   1573 
   1574             SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs);
   1575             try {
   1576                 return statement.executeUpdateDelete();
   1577             } finally {
   1578                 statement.close();
   1579             }
   1580         } finally {
   1581             releaseReference();
   1582         }
   1583     }
   1584 
   1585     /**
   1586      * Execute a single SQL statement that is NOT a SELECT
   1587      * or any other SQL statement that returns data.
   1588      * <p>
   1589      * It has no means to return any data (such as the number of affected rows).
   1590      * Instead, you're encouraged to use {@link #insert(String, String, ContentValues)},
   1591      * {@link #update(String, ContentValues, String, String[])}, et al, when possible.
   1592      * </p>
   1593      * <p>
   1594      * When using {@link #enableWriteAheadLogging()}, journal_mode is
   1595      * automatically managed by this class. So, do not set journal_mode
   1596      * using "PRAGMA journal_mode'<value>" statement if your app is using
   1597      * {@link #enableWriteAheadLogging()}
   1598      * </p>
   1599      *
   1600      * @param sql the SQL statement to be executed. Multiple statements separated by semicolons are
   1601      * not supported.
   1602      * @throws SQLException if the SQL string is invalid
   1603      */
   1604     public void execSQL(String sql) throws SQLException {
   1605         executeSql(sql, null);
   1606     }
   1607 
   1608     /**
   1609      * Execute a single SQL statement that is NOT a SELECT/INSERT/UPDATE/DELETE.
   1610      * <p>
   1611      * For INSERT statements, use any of the following instead.
   1612      * <ul>
   1613      *   <li>{@link #insert(String, String, ContentValues)}</li>
   1614      *   <li>{@link #insertOrThrow(String, String, ContentValues)}</li>
   1615      *   <li>{@link #insertWithOnConflict(String, String, ContentValues, int)}</li>
   1616      * </ul>
   1617      * <p>
   1618      * For UPDATE statements, use any of the following instead.
   1619      * <ul>
   1620      *   <li>{@link #update(String, ContentValues, String, String[])}</li>
   1621      *   <li>{@link #updateWithOnConflict(String, ContentValues, String, String[], int)}</li>
   1622      * </ul>
   1623      * <p>
   1624      * For DELETE statements, use any of the following instead.
   1625      * <ul>
   1626      *   <li>{@link #delete(String, String, String[])}</li>
   1627      * </ul>
   1628      * <p>
   1629      * For example, the following are good candidates for using this method:
   1630      * <ul>
   1631      *   <li>ALTER TABLE</li>
   1632      *   <li>CREATE or DROP table / trigger / view / index / virtual table</li>
   1633      *   <li>REINDEX</li>
   1634      *   <li>RELEASE</li>
   1635      *   <li>SAVEPOINT</li>
   1636      *   <li>PRAGMA that returns no data</li>
   1637      * </ul>
   1638      * </p>
   1639      * <p>
   1640      * When using {@link #enableWriteAheadLogging()}, journal_mode is
   1641      * automatically managed by this class. So, do not set journal_mode
   1642      * using "PRAGMA journal_mode'<value>" statement if your app is using
   1643      * {@link #enableWriteAheadLogging()}
   1644      * </p>
   1645      *
   1646      * @param sql the SQL statement to be executed. Multiple statements separated by semicolons are
   1647      * not supported.
   1648      * @param bindArgs only byte[], String, Long and Double are supported in bindArgs.
   1649      * @throws SQLException if the SQL string is invalid
   1650      */
   1651     public void execSQL(String sql, Object[] bindArgs) throws SQLException {
   1652         if (bindArgs == null) {
   1653             throw new IllegalArgumentException("Empty bindArgs");
   1654         }
   1655         executeSql(sql, bindArgs);
   1656     }
   1657 
   1658     private int executeSql(String sql, Object[] bindArgs) throws SQLException {
   1659         acquireReference();
   1660         try {
   1661             if (DatabaseUtils.getSqlStatementType(sql) == DatabaseUtils.STATEMENT_ATTACH) {
   1662                 boolean disableWal = false;
   1663                 synchronized (mLock) {
   1664                     if (!mHasAttachedDbsLocked) {
   1665                         mHasAttachedDbsLocked = true;
   1666                         disableWal = true;
   1667                     }
   1668                 }
   1669                 if (disableWal) {
   1670                     disableWriteAheadLogging();
   1671                 }
   1672             }
   1673 
   1674             SQLiteStatement statement = new SQLiteStatement(this, sql, bindArgs);
   1675             try {
   1676                 return statement.executeUpdateDelete();
   1677             } finally {
   1678                 statement.close();
   1679             }
   1680         } finally {
   1681             releaseReference();
   1682         }
   1683     }
   1684 
   1685     /**
   1686      * Returns true if the database is opened as read only.
   1687      *
   1688      * @return True if database is opened as read only.
   1689      */
   1690     public boolean isReadOnly() {
   1691         synchronized (mLock) {
   1692             return isReadOnlyLocked();
   1693         }
   1694     }
   1695 
   1696     private boolean isReadOnlyLocked() {
   1697         return (mConfigurationLocked.openFlags & OPEN_READ_MASK) == OPEN_READONLY;
   1698     }
   1699 
   1700     /**
   1701      * Returns true if the database is in-memory db.
   1702      *
   1703      * @return True if the database is in-memory.
   1704      * @hide
   1705      */
   1706     public boolean isInMemoryDatabase() {
   1707         synchronized (mLock) {
   1708             return mConfigurationLocked.isInMemoryDb();
   1709         }
   1710     }
   1711 
   1712     /**
   1713      * Returns true if the database is currently open.
   1714      *
   1715      * @return True if the database is currently open (has not been closed).
   1716      */
   1717     public boolean isOpen() {
   1718         synchronized (mLock) {
   1719             return mConnectionPoolLocked != null;
   1720         }
   1721     }
   1722 
   1723     /**
   1724      * Returns true if the new version code is greater than the current database version.
   1725      *
   1726      * @param newVersion The new version code.
   1727      * @return True if the new version code is greater than the current database version.
   1728      */
   1729     public boolean needUpgrade(int newVersion) {
   1730         return newVersion > getVersion();
   1731     }
   1732 
   1733     /**
   1734      * Gets the path to the database file.
   1735      *
   1736      * @return The path to the database file.
   1737      */
   1738     public final String getPath() {
   1739         synchronized (mLock) {
   1740             return mConfigurationLocked.path;
   1741         }
   1742     }
   1743 
   1744     /**
   1745      * Sets the locale for this database.  Does nothing if this database has
   1746      * the {@link #NO_LOCALIZED_COLLATORS} flag set or was opened read only.
   1747      *
   1748      * @param locale The new locale.
   1749      *
   1750      * @throws SQLException if the locale could not be set.  The most common reason
   1751      * for this is that there is no collator available for the locale you requested.
   1752      * In this case the database remains unchanged.
   1753      */
   1754     public void setLocale(Locale locale) {
   1755         if (locale == null) {
   1756             throw new IllegalArgumentException("locale must not be null.");
   1757         }
   1758 
   1759         synchronized (mLock) {
   1760             throwIfNotOpenLocked();
   1761 
   1762             final Locale oldLocale = mConfigurationLocked.locale;
   1763             mConfigurationLocked.locale = locale;
   1764             try {
   1765                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
   1766             } catch (RuntimeException ex) {
   1767                 mConfigurationLocked.locale = oldLocale;
   1768                 throw ex;
   1769             }
   1770         }
   1771     }
   1772 
   1773     /**
   1774      * Sets the maximum size of the prepared-statement cache for this database.
   1775      * (size of the cache = number of compiled-sql-statements stored in the cache).
   1776      *<p>
   1777      * Maximum cache size can ONLY be increased from its current size (default = 10).
   1778      * If this method is called with smaller size than the current maximum value,
   1779      * then IllegalStateException is thrown.
   1780      *<p>
   1781      * This method is thread-safe.
   1782      *
   1783      * @param cacheSize the size of the cache. can be (0 to {@link #MAX_SQL_CACHE_SIZE})
   1784      * @throws IllegalStateException if input cacheSize > {@link #MAX_SQL_CACHE_SIZE}.
   1785      */
   1786     public void setMaxSqlCacheSize(int cacheSize) {
   1787         if (cacheSize > MAX_SQL_CACHE_SIZE || cacheSize < 0) {
   1788             throw new IllegalStateException(
   1789                     "expected value between 0 and " + MAX_SQL_CACHE_SIZE);
   1790         }
   1791 
   1792         synchronized (mLock) {
   1793             throwIfNotOpenLocked();
   1794 
   1795             final int oldMaxSqlCacheSize = mConfigurationLocked.maxSqlCacheSize;
   1796             mConfigurationLocked.maxSqlCacheSize = cacheSize;
   1797             try {
   1798                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
   1799             } catch (RuntimeException ex) {
   1800                 mConfigurationLocked.maxSqlCacheSize = oldMaxSqlCacheSize;
   1801                 throw ex;
   1802             }
   1803         }
   1804     }
   1805 
   1806     /**
   1807      * Sets whether foreign key constraints are enabled for the database.
   1808      * <p>
   1809      * By default, foreign key constraints are not enforced by the database.
   1810      * This method allows an application to enable foreign key constraints.
   1811      * It must be called each time the database is opened to ensure that foreign
   1812      * key constraints are enabled for the session.
   1813      * </p><p>
   1814      * A good time to call this method is right after calling {@link #openOrCreateDatabase}
   1815      * or in the {@link SQLiteOpenHelper#onConfigure} callback.
   1816      * </p><p>
   1817      * When foreign key constraints are disabled, the database does not check whether
   1818      * changes to the database will violate foreign key constraints.  Likewise, when
   1819      * foreign key constraints are disabled, the database will not execute cascade
   1820      * delete or update triggers.  As a result, it is possible for the database
   1821      * state to become inconsistent.  To perform a database integrity check,
   1822      * call {@link #isDatabaseIntegrityOk}.
   1823      * </p><p>
   1824      * This method must not be called while a transaction is in progress.
   1825      * </p><p>
   1826      * See also <a href="http://sqlite.org/foreignkeys.html">SQLite Foreign Key Constraints</a>
   1827      * for more details about foreign key constraint support.
   1828      * </p>
   1829      *
   1830      * @param enable True to enable foreign key constraints, false to disable them.
   1831      *
   1832      * @throws IllegalStateException if the are transactions is in progress
   1833      * when this method is called.
   1834      */
   1835     public void setForeignKeyConstraintsEnabled(boolean enable) {
   1836         synchronized (mLock) {
   1837             throwIfNotOpenLocked();
   1838 
   1839             if (mConfigurationLocked.foreignKeyConstraintsEnabled == enable) {
   1840                 return;
   1841             }
   1842 
   1843             mConfigurationLocked.foreignKeyConstraintsEnabled = enable;
   1844             try {
   1845                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
   1846             } catch (RuntimeException ex) {
   1847                 mConfigurationLocked.foreignKeyConstraintsEnabled = !enable;
   1848                 throw ex;
   1849             }
   1850         }
   1851     }
   1852 
   1853     /**
   1854      * This method enables parallel execution of queries from multiple threads on the
   1855      * same database.  It does this by opening multiple connections to the database
   1856      * and using a different database connection for each query.  The database
   1857      * journal mode is also changed to enable writes to proceed concurrently with reads.
   1858      * <p>
   1859      * When write-ahead logging is not enabled (the default), it is not possible for
   1860      * reads and writes to occur on the database at the same time.  Before modifying the
   1861      * database, the writer implicitly acquires an exclusive lock on the database which
   1862      * prevents readers from accessing the database until the write is completed.
   1863      * </p><p>
   1864      * In contrast, when write-ahead logging is enabled (by calling this method), write
   1865      * operations occur in a separate log file which allows reads to proceed concurrently.
   1866      * While a write is in progress, readers on other threads will perceive the state
   1867      * of the database as it was before the write began.  When the write completes, readers
   1868      * on other threads will then perceive the new state of the database.
   1869      * </p><p>
   1870      * It is a good idea to enable write-ahead logging whenever a database will be
   1871      * concurrently accessed and modified by multiple threads at the same time.
   1872      * However, write-ahead logging uses significantly more memory than ordinary
   1873      * journaling because there are multiple connections to the same database.
   1874      * So if a database will only be used by a single thread, or if optimizing
   1875      * concurrency is not very important, then write-ahead logging should be disabled.
   1876      * </p><p>
   1877      * After calling this method, execution of queries in parallel is enabled as long as
   1878      * the database remains open.  To disable execution of queries in parallel, either
   1879      * call {@link #disableWriteAheadLogging} or close the database and reopen it.
   1880      * </p><p>
   1881      * The maximum number of connections used to execute queries in parallel is
   1882      * dependent upon the device memory and possibly other properties.
   1883      * </p><p>
   1884      * If a query is part of a transaction, then it is executed on the same database handle the
   1885      * transaction was begun.
   1886      * </p><p>
   1887      * Writers should use {@link #beginTransactionNonExclusive()} or
   1888      * {@link #beginTransactionWithListenerNonExclusive(SQLiteTransactionListener)}
   1889      * to start a transaction.  Non-exclusive mode allows database file to be in readable
   1890      * by other threads executing queries.
   1891      * </p><p>
   1892      * If the database has any attached databases, then execution of queries in parallel is NOT
   1893      * possible.  Likewise, write-ahead logging is not supported for read-only databases
   1894      * or memory databases.  In such cases, {@link #enableWriteAheadLogging} returns false.
   1895      * </p><p>
   1896      * The best way to enable write-ahead logging is to pass the
   1897      * {@link #ENABLE_WRITE_AHEAD_LOGGING} flag to {@link #openDatabase}.  This is
   1898      * more efficient than calling {@link #enableWriteAheadLogging}.
   1899      * <code><pre>
   1900      *     SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory,
   1901      *             SQLiteDatabase.CREATE_IF_NECESSARY | SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING,
   1902      *             myDatabaseErrorHandler);
   1903      *     db.enableWriteAheadLogging();
   1904      * </pre></code>
   1905      * </p><p>
   1906      * Another way to enable write-ahead logging is to call {@link #enableWriteAheadLogging}
   1907      * after opening the database.
   1908      * <code><pre>
   1909      *     SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory,
   1910      *             SQLiteDatabase.CREATE_IF_NECESSARY, myDatabaseErrorHandler);
   1911      *     db.enableWriteAheadLogging();
   1912      * </pre></code>
   1913      * </p><p>
   1914      * See also <a href="http://sqlite.org/wal.html">SQLite Write-Ahead Logging</a> for
   1915      * more details about how write-ahead logging works.
   1916      * </p>
   1917      *
   1918      * @return True if write-ahead logging is enabled.
   1919      *
   1920      * @throws IllegalStateException if there are transactions in progress at the
   1921      * time this method is called.  WAL mode can only be changed when there are no
   1922      * transactions in progress.
   1923      *
   1924      * @see #ENABLE_WRITE_AHEAD_LOGGING
   1925      * @see #disableWriteAheadLogging
   1926      */
   1927     public boolean enableWriteAheadLogging() {
   1928         synchronized (mLock) {
   1929             throwIfNotOpenLocked();
   1930 
   1931             if ((mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) != 0) {
   1932                 return true;
   1933             }
   1934 
   1935             if (isReadOnlyLocked()) {
   1936                 // WAL doesn't make sense for readonly-databases.
   1937                 // TODO: True, but connection pooling does still make sense...
   1938                 return false;
   1939             }
   1940 
   1941             if (mConfigurationLocked.isInMemoryDb()) {
   1942                 Log.i(TAG, "can't enable WAL for memory databases.");
   1943                 return false;
   1944             }
   1945 
   1946             // make sure this database has NO attached databases because sqlite's write-ahead-logging
   1947             // doesn't work for databases with attached databases
   1948             if (mHasAttachedDbsLocked) {
   1949                 if (Log.isLoggable(TAG, Log.DEBUG)) {
   1950                     Log.d(TAG, "this database: " + mConfigurationLocked.label
   1951                             + " has attached databases. can't  enable WAL.");
   1952                 }
   1953                 return false;
   1954             }
   1955 
   1956             mConfigurationLocked.openFlags |= ENABLE_WRITE_AHEAD_LOGGING;
   1957             try {
   1958                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
   1959             } catch (RuntimeException ex) {
   1960                 mConfigurationLocked.openFlags &= ~ENABLE_WRITE_AHEAD_LOGGING;
   1961                 throw ex;
   1962             }
   1963         }
   1964         return true;
   1965     }
   1966 
   1967     /**
   1968      * This method disables the features enabled by {@link #enableWriteAheadLogging()}.
   1969      *
   1970      * @throws IllegalStateException if there are transactions in progress at the
   1971      * time this method is called.  WAL mode can only be changed when there are no
   1972      * transactions in progress.
   1973      *
   1974      * @see #enableWriteAheadLogging
   1975      */
   1976     public void disableWriteAheadLogging() {
   1977         synchronized (mLock) {
   1978             throwIfNotOpenLocked();
   1979 
   1980             if ((mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) == 0) {
   1981                 return;
   1982             }
   1983 
   1984             mConfigurationLocked.openFlags &= ~ENABLE_WRITE_AHEAD_LOGGING;
   1985             try {
   1986                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
   1987             } catch (RuntimeException ex) {
   1988                 mConfigurationLocked.openFlags |= ENABLE_WRITE_AHEAD_LOGGING;
   1989                 throw ex;
   1990             }
   1991         }
   1992     }
   1993 
   1994     /**
   1995      * Returns true if write-ahead logging has been enabled for this database.
   1996      *
   1997      * @return True if write-ahead logging has been enabled for this database.
   1998      *
   1999      * @see #enableWriteAheadLogging
   2000      * @see #ENABLE_WRITE_AHEAD_LOGGING
   2001      */
   2002     public boolean isWriteAheadLoggingEnabled() {
   2003         synchronized (mLock) {
   2004             throwIfNotOpenLocked();
   2005 
   2006             return (mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) != 0;
   2007         }
   2008     }
   2009 
   2010     /**
   2011      * Collect statistics about all open databases in the current process.
   2012      * Used by bug report.
   2013      */
   2014     static ArrayList<DbStats> getDbStats() {
   2015         ArrayList<DbStats> dbStatsList = new ArrayList<DbStats>();
   2016         for (SQLiteDatabase db : getActiveDatabases()) {
   2017             db.collectDbStats(dbStatsList);
   2018         }
   2019         return dbStatsList;
   2020     }
   2021 
   2022     private void collectDbStats(ArrayList<DbStats> dbStatsList) {
   2023         synchronized (mLock) {
   2024             if (mConnectionPoolLocked != null) {
   2025                 mConnectionPoolLocked.collectDbStats(dbStatsList);
   2026             }
   2027         }
   2028     }
   2029 
   2030     private static ArrayList<SQLiteDatabase> getActiveDatabases() {
   2031         ArrayList<SQLiteDatabase> databases = new ArrayList<SQLiteDatabase>();
   2032         synchronized (sActiveDatabases) {
   2033             databases.addAll(sActiveDatabases.keySet());
   2034         }
   2035         return databases;
   2036     }
   2037 
   2038     /**
   2039      * Dump detailed information about all open databases in the current process.
   2040      * Used by bug report.
   2041      */
   2042     static void dumpAll(Printer printer, boolean verbose) {
   2043         for (SQLiteDatabase db : getActiveDatabases()) {
   2044             db.dump(printer, verbose);
   2045         }
   2046     }
   2047 
   2048     private void dump(Printer printer, boolean verbose) {
   2049         synchronized (mLock) {
   2050             if (mConnectionPoolLocked != null) {
   2051                 printer.println("");
   2052                 mConnectionPoolLocked.dump(printer, verbose);
   2053             }
   2054         }
   2055     }
   2056 
   2057     /**
   2058      * Returns list of full pathnames of all attached databases including the main database
   2059      * by executing 'pragma database_list' on the database.
   2060      *
   2061      * @return ArrayList of pairs of (database name, database file path) or null if the database
   2062      * is not open.
   2063      */
   2064     public List<Pair<String, String>> getAttachedDbs() {
   2065         ArrayList<Pair<String, String>> attachedDbs = new ArrayList<Pair<String, String>>();
   2066         synchronized (mLock) {
   2067             if (mConnectionPoolLocked == null) {
   2068                 return null; // not open
   2069             }
   2070 
   2071             if (!mHasAttachedDbsLocked) {
   2072                 // No attached databases.
   2073                 // There is a small window where attached databases exist but this flag is not
   2074                 // set yet.  This can occur when this thread is in a race condition with another
   2075                 // thread that is executing the SQL statement: "attach database <blah> as <foo>"
   2076                 // If this thread is NOT ok with such a race condition (and thus possibly not
   2077                 // receivethe entire list of attached databases), then the caller should ensure
   2078                 // that no thread is executing any SQL statements while a thread is calling this
   2079                 // method.  Typically, this method is called when 'adb bugreport' is done or the
   2080                 // caller wants to collect stats on the database and all its attached databases.
   2081                 attachedDbs.add(new Pair<String, String>("main", mConfigurationLocked.path));
   2082                 return attachedDbs;
   2083             }
   2084 
   2085             acquireReference();
   2086         }
   2087 
   2088         try {
   2089             // has attached databases. query sqlite to get the list of attached databases.
   2090             Cursor c = null;
   2091             try {
   2092                 c = rawQuery("pragma database_list;", null);
   2093                 while (c.moveToNext()) {
   2094                     // sqlite returns a row for each database in the returned list of databases.
   2095                     //   in each row,
   2096                     //       1st column is the database name such as main, or the database
   2097                     //                              name specified on the "ATTACH" command
   2098                     //       2nd column is the database file path.
   2099                     attachedDbs.add(new Pair<String, String>(c.getString(1), c.getString(2)));
   2100                 }
   2101             } finally {
   2102                 if (c != null) {
   2103                     c.close();
   2104                 }
   2105             }
   2106             return attachedDbs;
   2107         } finally {
   2108             releaseReference();
   2109         }
   2110     }
   2111 
   2112     /**
   2113      * Runs 'pragma integrity_check' on the given database (and all the attached databases)
   2114      * and returns true if the given database (and all its attached databases) pass integrity_check,
   2115      * false otherwise.
   2116      *<p>
   2117      * If the result is false, then this method logs the errors reported by the integrity_check
   2118      * command execution.
   2119      *<p>
   2120      * Note that 'pragma integrity_check' on a database can take a long time.
   2121      *
   2122      * @return true if the given database (and all its attached databases) pass integrity_check,
   2123      * false otherwise.
   2124      */
   2125     public boolean isDatabaseIntegrityOk() {
   2126         acquireReference();
   2127         try {
   2128             List<Pair<String, String>> attachedDbs = null;
   2129             try {
   2130                 attachedDbs = getAttachedDbs();
   2131                 if (attachedDbs == null) {
   2132                     throw new IllegalStateException("databaselist for: " + getPath() + " couldn't " +
   2133                             "be retrieved. probably because the database is closed");
   2134                 }
   2135             } catch (SQLiteException e) {
   2136                 // can't get attachedDb list. do integrity check on the main database
   2137                 attachedDbs = new ArrayList<Pair<String, String>>();
   2138                 attachedDbs.add(new Pair<String, String>("main", getPath()));
   2139             }
   2140 
   2141             for (int i = 0; i < attachedDbs.size(); i++) {
   2142                 Pair<String, String> p = attachedDbs.get(i);
   2143                 SQLiteStatement prog = null;
   2144                 try {
   2145                     prog = compileStatement("PRAGMA " + p.first + ".integrity_check(1);");
   2146                     String rslt = prog.simpleQueryForString();
   2147                     if (!rslt.equalsIgnoreCase("ok")) {
   2148                         // integrity_checker failed on main or attached databases
   2149                         Log.e(TAG, "PRAGMA integrity_check on " + p.second + " returned: " + rslt);
   2150                         return false;
   2151                     }
   2152                 } finally {
   2153                     if (prog != null) prog.close();
   2154                 }
   2155             }
   2156         } finally {
   2157             releaseReference();
   2158         }
   2159         return true;
   2160     }
   2161 
   2162     @Override
   2163     public String toString() {
   2164         return "SQLiteDatabase: " + getPath();
   2165     }
   2166 
   2167     private void throwIfNotOpenLocked() {
   2168         if (mConnectionPoolLocked == null) {
   2169             throw new IllegalStateException("The database '" + mConfigurationLocked.label
   2170                     + "' is not open.");
   2171         }
   2172     }
   2173 
   2174     /**
   2175      * Used to allow returning sub-classes of {@link Cursor} when calling query.
   2176      */
   2177     public interface CursorFactory {
   2178         /**
   2179          * See {@link SQLiteCursor#SQLiteCursor(SQLiteCursorDriver, String, SQLiteQuery)}.
   2180          */
   2181         public Cursor newCursor(SQLiteDatabase db,
   2182                 SQLiteCursorDriver masterQuery, String editTable,
   2183                 SQLiteQuery query);
   2184     }
   2185 
   2186     /**
   2187      * A callback interface for a custom sqlite3 function.
   2188      * This can be used to create a function that can be called from
   2189      * sqlite3 database triggers.
   2190      * @hide
   2191      */
   2192     public interface CustomFunction {
   2193         public void callback(String[] args);
   2194     }
   2195 }
   2196