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