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      *
1375      * @param table the table in which to replace the row
1376      * @param nullColumnHack optional; may be <code>null</code>.
1377      *            SQL doesn't allow inserting a completely empty row without
1378      *            naming at least one column name.  If your provided <code>initialValues</code> is
1379      *            empty, no column names are known and an empty row can't be inserted.
1380      *            If not set to null, the <code>nullColumnHack</code> parameter
1381      *            provides the name of nullable column name to explicitly insert a NULL into
1382      *            in the case where your <code>initialValues</code> is empty.
1383      * @param initialValues this map contains the initial column values for
1384      *   the row.
1385      * @return the row ID of the newly inserted row, or -1 if an error occurred
1386      */
replace(String table, String nullColumnHack, ContentValues initialValues)1387     public long replace(String table, String nullColumnHack, ContentValues initialValues) {
1388         try {
1389             return insertWithOnConflict(table, nullColumnHack, initialValues,
1390                     CONFLICT_REPLACE);
1391         } catch (SQLException e) {
1392             Log.e(TAG, "Error inserting " + initialValues, e);
1393             return -1;
1394         }
1395     }
1396 
1397     /**
1398      * Convenience method for replacing a row in the database.
1399      *
1400      * @param table the table in which to replace the row
1401      * @param nullColumnHack optional; may be <code>null</code>.
1402      *            SQL doesn't allow inserting a completely empty row without
1403      *            naming at least one column name.  If your provided <code>initialValues</code> is
1404      *            empty, no column names are known and an empty row can't be inserted.
1405      *            If not set to null, the <code>nullColumnHack</code> parameter
1406      *            provides the name of nullable column name to explicitly insert a NULL into
1407      *            in the case where your <code>initialValues</code> is empty.
1408      * @param initialValues this map contains the initial column values for
1409      *   the row. The key
1410      * @throws SQLException
1411      * @return the row ID of the newly inserted row, or -1 if an error occurred
1412      */
replaceOrThrow(String table, String nullColumnHack, ContentValues initialValues)1413     public long replaceOrThrow(String table, String nullColumnHack,
1414             ContentValues initialValues) throws SQLException {
1415         return insertWithOnConflict(table, nullColumnHack, initialValues,
1416                 CONFLICT_REPLACE);
1417     }
1418 
1419     /**
1420      * General method for inserting a row into the database.
1421      *
1422      * @param table the table to insert the row into
1423      * @param nullColumnHack optional; may be <code>null</code>.
1424      *            SQL doesn't allow inserting a completely empty row without
1425      *            naming at least one column name.  If your provided <code>initialValues</code> is
1426      *            empty, no column names are known and an empty row can't be inserted.
1427      *            If not set to null, the <code>nullColumnHack</code> parameter
1428      *            provides the name of nullable column name to explicitly insert a NULL into
1429      *            in the case where your <code>initialValues</code> is empty.
1430      * @param initialValues this map contains the initial column values for the
1431      *            row. The keys should be the column names and the values the
1432      *            column values
1433      * @param conflictAlgorithm for insert conflict resolver
1434      * @return the row ID of the newly inserted row OR <code>-1</code> if either the
1435      *            input parameter <code>conflictAlgorithm</code> = {@link #CONFLICT_IGNORE}
1436      *            or an error occurred.
1437      */
insertWithOnConflict(String table, String nullColumnHack, ContentValues initialValues, int conflictAlgorithm)1438     public long insertWithOnConflict(String table, String nullColumnHack,
1439             ContentValues initialValues, int conflictAlgorithm) {
1440         acquireReference();
1441         try {
1442             StringBuilder sql = new StringBuilder();
1443             sql.append("INSERT");
1444             sql.append(CONFLICT_VALUES[conflictAlgorithm]);
1445             sql.append(" INTO ");
1446             sql.append(table);
1447             sql.append('(');
1448 
1449             Object[] bindArgs = null;
1450             int size = (initialValues != null && initialValues.size() > 0)
1451                     ? initialValues.size() : 0;
1452             if (size > 0) {
1453                 bindArgs = new Object[size];
1454                 int i = 0;
1455                 for (String colName : initialValues.keySet()) {
1456                     sql.append((i > 0) ? "," : "");
1457                     sql.append(colName);
1458                     bindArgs[i++] = initialValues.get(colName);
1459                 }
1460                 sql.append(')');
1461                 sql.append(" VALUES (");
1462                 for (i = 0; i < size; i++) {
1463                     sql.append((i > 0) ? ",?" : "?");
1464                 }
1465             } else {
1466                 sql.append(nullColumnHack + ") VALUES (NULL");
1467             }
1468             sql.append(')');
1469 
1470             SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs);
1471             try {
1472                 return statement.executeInsert();
1473             } finally {
1474                 statement.close();
1475             }
1476         } finally {
1477             releaseReference();
1478         }
1479     }
1480 
1481     /**
1482      * Convenience method for deleting rows in the database.
1483      *
1484      * @param table the table to delete from
1485      * @param whereClause the optional WHERE clause to apply when deleting.
1486      *            Passing null will delete all rows.
1487      * @param whereArgs You may include ?s in the where clause, which
1488      *            will be replaced by the values from whereArgs. The values
1489      *            will be bound as Strings.
1490      * @return the number of rows affected if a whereClause is passed in, 0
1491      *         otherwise. To remove all rows and get a count pass "1" as the
1492      *         whereClause.
1493      */
delete(String table, String whereClause, String[] whereArgs)1494     public int delete(String table, String whereClause, String[] whereArgs) {
1495         acquireReference();
1496         try {
1497             SQLiteStatement statement =  new SQLiteStatement(this, "DELETE FROM " + table +
1498                     (!TextUtils.isEmpty(whereClause) ? " WHERE " + whereClause : ""), whereArgs);
1499             try {
1500                 return statement.executeUpdateDelete();
1501             } finally {
1502                 statement.close();
1503             }
1504         } finally {
1505             releaseReference();
1506         }
1507     }
1508 
1509     /**
1510      * Convenience method for updating rows in the database.
1511      *
1512      * @param table the table to update in
1513      * @param values a map from column names to new column values. null is a
1514      *            valid value that will be translated to NULL.
1515      * @param whereClause the optional WHERE clause to apply when updating.
1516      *            Passing null will update all rows.
1517      * @param whereArgs You may include ?s in the where clause, which
1518      *            will be replaced by the values from whereArgs. The values
1519      *            will be bound as Strings.
1520      * @return the number of rows affected
1521      */
update(String table, ContentValues values, String whereClause, String[] whereArgs)1522     public int update(String table, ContentValues values, String whereClause, String[] whereArgs) {
1523         return updateWithOnConflict(table, values, whereClause, whereArgs, CONFLICT_NONE);
1524     }
1525 
1526     /**
1527      * Convenience method for updating rows in the database.
1528      *
1529      * @param table the table to update in
1530      * @param values a map from column names to new column values. null is a
1531      *            valid value that will be translated to NULL.
1532      * @param whereClause the optional WHERE clause to apply when updating.
1533      *            Passing null will update all rows.
1534      * @param whereArgs You may include ?s in the where clause, which
1535      *            will be replaced by the values from whereArgs. The values
1536      *            will be bound as Strings.
1537      * @param conflictAlgorithm for update conflict resolver
1538      * @return the number of rows affected
1539      */
updateWithOnConflict(String table, ContentValues values, String whereClause, String[] whereArgs, int conflictAlgorithm)1540     public int updateWithOnConflict(String table, ContentValues values,
1541             String whereClause, String[] whereArgs, int conflictAlgorithm) {
1542         if (values == null || values.size() == 0) {
1543             throw new IllegalArgumentException("Empty values");
1544         }
1545 
1546         acquireReference();
1547         try {
1548             StringBuilder sql = new StringBuilder(120);
1549             sql.append("UPDATE ");
1550             sql.append(CONFLICT_VALUES[conflictAlgorithm]);
1551             sql.append(table);
1552             sql.append(" SET ");
1553 
1554             // move all bind args to one array
1555             int setValuesSize = values.size();
1556             int bindArgsSize = (whereArgs == null) ? setValuesSize : (setValuesSize + whereArgs.length);
1557             Object[] bindArgs = new Object[bindArgsSize];
1558             int i = 0;
1559             for (String colName : values.keySet()) {
1560                 sql.append((i > 0) ? "," : "");
1561                 sql.append(colName);
1562                 bindArgs[i++] = values.get(colName);
1563                 sql.append("=?");
1564             }
1565             if (whereArgs != null) {
1566                 for (i = setValuesSize; i < bindArgsSize; i++) {
1567                     bindArgs[i] = whereArgs[i - setValuesSize];
1568                 }
1569             }
1570             if (!TextUtils.isEmpty(whereClause)) {
1571                 sql.append(" WHERE ");
1572                 sql.append(whereClause);
1573             }
1574 
1575             SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs);
1576             try {
1577                 return statement.executeUpdateDelete();
1578             } finally {
1579                 statement.close();
1580             }
1581         } finally {
1582             releaseReference();
1583         }
1584     }
1585 
1586     /**
1587      * Execute a single SQL statement that is NOT a SELECT
1588      * or any other SQL statement that returns data.
1589      * <p>
1590      * It has no means to return any data (such as the number of affected rows).
1591      * Instead, you're encouraged to use {@link #insert(String, String, ContentValues)},
1592      * {@link #update(String, ContentValues, String, String[])}, et al, when possible.
1593      * </p>
1594      * <p>
1595      * When using {@link #enableWriteAheadLogging()}, journal_mode is
1596      * automatically managed by this class. So, do not set journal_mode
1597      * using "PRAGMA journal_mode'<value>" statement if your app is using
1598      * {@link #enableWriteAheadLogging()}
1599      * </p>
1600      *
1601      * @param sql the SQL statement to be executed. Multiple statements separated by semicolons are
1602      * not supported.
1603      * @throws SQLException if the SQL string is invalid
1604      */
execSQL(String sql)1605     public void execSQL(String sql) throws SQLException {
1606         executeSql(sql, null);
1607     }
1608 
1609     /**
1610      * Execute a single SQL statement that is NOT a SELECT/INSERT/UPDATE/DELETE.
1611      * <p>
1612      * For INSERT statements, use any of the following instead.
1613      * <ul>
1614      *   <li>{@link #insert(String, String, ContentValues)}</li>
1615      *   <li>{@link #insertOrThrow(String, String, ContentValues)}</li>
1616      *   <li>{@link #insertWithOnConflict(String, String, ContentValues, int)}</li>
1617      * </ul>
1618      * <p>
1619      * For UPDATE statements, use any of the following instead.
1620      * <ul>
1621      *   <li>{@link #update(String, ContentValues, String, String[])}</li>
1622      *   <li>{@link #updateWithOnConflict(String, ContentValues, String, String[], int)}</li>
1623      * </ul>
1624      * <p>
1625      * For DELETE statements, use any of the following instead.
1626      * <ul>
1627      *   <li>{@link #delete(String, String, String[])}</li>
1628      * </ul>
1629      * <p>
1630      * For example, the following are good candidates for using this method:
1631      * <ul>
1632      *   <li>ALTER TABLE</li>
1633      *   <li>CREATE or DROP table / trigger / view / index / virtual table</li>
1634      *   <li>REINDEX</li>
1635      *   <li>RELEASE</li>
1636      *   <li>SAVEPOINT</li>
1637      *   <li>PRAGMA that returns no data</li>
1638      * </ul>
1639      * </p>
1640      * <p>
1641      * When using {@link #enableWriteAheadLogging()}, journal_mode is
1642      * automatically managed by this class. So, do not set journal_mode
1643      * using "PRAGMA journal_mode'<value>" statement if your app is using
1644      * {@link #enableWriteAheadLogging()}
1645      * </p>
1646      *
1647      * @param sql the SQL statement to be executed. Multiple statements separated by semicolons are
1648      * not supported.
1649      * @param bindArgs only byte[], String, Long and Double are supported in bindArgs.
1650      * @throws SQLException if the SQL string is invalid
1651      */
execSQL(String sql, Object[] bindArgs)1652     public void execSQL(String sql, Object[] bindArgs) throws SQLException {
1653         if (bindArgs == null) {
1654             throw new IllegalArgumentException("Empty bindArgs");
1655         }
1656         executeSql(sql, bindArgs);
1657     }
1658 
executeSql(String sql, Object[] bindArgs)1659     private int executeSql(String sql, Object[] bindArgs) throws SQLException {
1660         acquireReference();
1661         try {
1662             if (DatabaseUtils.getSqlStatementType(sql) == DatabaseUtils.STATEMENT_ATTACH) {
1663                 boolean disableWal = false;
1664                 synchronized (mLock) {
1665                     if (!mHasAttachedDbsLocked) {
1666                         mHasAttachedDbsLocked = true;
1667                         disableWal = true;
1668                     }
1669                 }
1670                 if (disableWal) {
1671                     disableWriteAheadLogging();
1672                 }
1673             }
1674 
1675             SQLiteStatement statement = new SQLiteStatement(this, sql, bindArgs);
1676             try {
1677                 return statement.executeUpdateDelete();
1678             } finally {
1679                 statement.close();
1680             }
1681         } finally {
1682             releaseReference();
1683         }
1684     }
1685 
1686     /**
1687      * Verifies that a SQL SELECT statement is valid by compiling it.
1688      * If the SQL statement is not valid, this method will throw a {@link SQLiteException}.
1689      *
1690      * @param sql SQL to be validated
1691      * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
1692      * If the operation is canceled, then {@link OperationCanceledException} will be thrown
1693      * when the query is executed.
1694      * @throws SQLiteException if {@code sql} is invalid
1695      */
validateSql(@onNull String sql, @Nullable CancellationSignal cancellationSignal)1696     public void validateSql(@NonNull String sql, @Nullable CancellationSignal cancellationSignal) {
1697         getThreadSession().prepare(sql,
1698                 getThreadDefaultConnectionFlags(/* readOnly =*/ true), cancellationSignal, null);
1699     }
1700 
1701     /**
1702      * Returns true if the database is opened as read only.
1703      *
1704      * @return True if database is opened as read only.
1705      */
isReadOnly()1706     public boolean isReadOnly() {
1707         synchronized (mLock) {
1708             return isReadOnlyLocked();
1709         }
1710     }
1711 
isReadOnlyLocked()1712     private boolean isReadOnlyLocked() {
1713         return (mConfigurationLocked.openFlags & OPEN_READ_MASK) == OPEN_READONLY;
1714     }
1715 
1716     /**
1717      * Returns true if the database is in-memory db.
1718      *
1719      * @return True if the database is in-memory.
1720      * @hide
1721      */
isInMemoryDatabase()1722     public boolean isInMemoryDatabase() {
1723         synchronized (mLock) {
1724             return mConfigurationLocked.isInMemoryDb();
1725         }
1726     }
1727 
1728     /**
1729      * Returns true if the database is currently open.
1730      *
1731      * @return True if the database is currently open (has not been closed).
1732      */
isOpen()1733     public boolean isOpen() {
1734         synchronized (mLock) {
1735             return mConnectionPoolLocked != null;
1736         }
1737     }
1738 
1739     /**
1740      * Returns true if the new version code is greater than the current database version.
1741      *
1742      * @param newVersion The new version code.
1743      * @return True if the new version code is greater than the current database version.
1744      */
needUpgrade(int newVersion)1745     public boolean needUpgrade(int newVersion) {
1746         return newVersion > getVersion();
1747     }
1748 
1749     /**
1750      * Gets the path to the database file.
1751      *
1752      * @return The path to the database file.
1753      */
getPath()1754     public final String getPath() {
1755         synchronized (mLock) {
1756             return mConfigurationLocked.path;
1757         }
1758     }
1759 
1760     /**
1761      * Sets the locale for this database.  Does nothing if this database has
1762      * the {@link #NO_LOCALIZED_COLLATORS} flag set or was opened read only.
1763      *
1764      * @param locale The new locale.
1765      *
1766      * @throws SQLException if the locale could not be set.  The most common reason
1767      * for this is that there is no collator available for the locale you requested.
1768      * In this case the database remains unchanged.
1769      */
setLocale(Locale locale)1770     public void setLocale(Locale locale) {
1771         if (locale == null) {
1772             throw new IllegalArgumentException("locale must not be null.");
1773         }
1774 
1775         synchronized (mLock) {
1776             throwIfNotOpenLocked();
1777 
1778             final Locale oldLocale = mConfigurationLocked.locale;
1779             mConfigurationLocked.locale = locale;
1780             try {
1781                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
1782             } catch (RuntimeException ex) {
1783                 mConfigurationLocked.locale = oldLocale;
1784                 throw ex;
1785             }
1786         }
1787     }
1788 
1789     /**
1790      * Sets the maximum size of the prepared-statement cache for this database.
1791      * (size of the cache = number of compiled-sql-statements stored in the cache).
1792      *<p>
1793      * Maximum cache size can ONLY be increased from its current size (default = 10).
1794      * If this method is called with smaller size than the current maximum value,
1795      * then IllegalStateException is thrown.
1796      *<p>
1797      * This method is thread-safe.
1798      *
1799      * @param cacheSize the size of the cache. can be (0 to {@link #MAX_SQL_CACHE_SIZE})
1800      * @throws IllegalStateException if input cacheSize > {@link #MAX_SQL_CACHE_SIZE}.
1801      */
setMaxSqlCacheSize(int cacheSize)1802     public void setMaxSqlCacheSize(int cacheSize) {
1803         if (cacheSize > MAX_SQL_CACHE_SIZE || cacheSize < 0) {
1804             throw new IllegalStateException(
1805                     "expected value between 0 and " + MAX_SQL_CACHE_SIZE);
1806         }
1807 
1808         synchronized (mLock) {
1809             throwIfNotOpenLocked();
1810 
1811             final int oldMaxSqlCacheSize = mConfigurationLocked.maxSqlCacheSize;
1812             mConfigurationLocked.maxSqlCacheSize = cacheSize;
1813             try {
1814                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
1815             } catch (RuntimeException ex) {
1816                 mConfigurationLocked.maxSqlCacheSize = oldMaxSqlCacheSize;
1817                 throw ex;
1818             }
1819         }
1820     }
1821 
1822     /**
1823      * Sets whether foreign key constraints are enabled for the database.
1824      * <p>
1825      * By default, foreign key constraints are not enforced by the database.
1826      * This method allows an application to enable foreign key constraints.
1827      * It must be called each time the database is opened to ensure that foreign
1828      * key constraints are enabled for the session.
1829      * </p><p>
1830      * A good time to call this method is right after calling {@link #openOrCreateDatabase}
1831      * or in the {@link SQLiteOpenHelper#onConfigure} callback.
1832      * </p><p>
1833      * When foreign key constraints are disabled, the database does not check whether
1834      * changes to the database will violate foreign key constraints.  Likewise, when
1835      * foreign key constraints are disabled, the database will not execute cascade
1836      * delete or update triggers.  As a result, it is possible for the database
1837      * state to become inconsistent.  To perform a database integrity check,
1838      * call {@link #isDatabaseIntegrityOk}.
1839      * </p><p>
1840      * This method must not be called while a transaction is in progress.
1841      * </p><p>
1842      * See also <a href="http://sqlite.org/foreignkeys.html">SQLite Foreign Key Constraints</a>
1843      * for more details about foreign key constraint support.
1844      * </p>
1845      *
1846      * @param enable True to enable foreign key constraints, false to disable them.
1847      *
1848      * @throws IllegalStateException if the are transactions is in progress
1849      * when this method is called.
1850      */
setForeignKeyConstraintsEnabled(boolean enable)1851     public void setForeignKeyConstraintsEnabled(boolean enable) {
1852         synchronized (mLock) {
1853             throwIfNotOpenLocked();
1854 
1855             if (mConfigurationLocked.foreignKeyConstraintsEnabled == enable) {
1856                 return;
1857             }
1858 
1859             mConfigurationLocked.foreignKeyConstraintsEnabled = enable;
1860             try {
1861                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
1862             } catch (RuntimeException ex) {
1863                 mConfigurationLocked.foreignKeyConstraintsEnabled = !enable;
1864                 throw ex;
1865             }
1866         }
1867     }
1868 
1869     /**
1870      * This method enables parallel execution of queries from multiple threads on the
1871      * same database.  It does this by opening multiple connections to the database
1872      * and using a different database connection for each query.  The database
1873      * journal mode is also changed to enable writes to proceed concurrently with reads.
1874      * <p>
1875      * When write-ahead logging is not enabled (the default), it is not possible for
1876      * reads and writes to occur on the database at the same time.  Before modifying the
1877      * database, the writer implicitly acquires an exclusive lock on the database which
1878      * prevents readers from accessing the database until the write is completed.
1879      * </p><p>
1880      * In contrast, when write-ahead logging is enabled (by calling this method), write
1881      * operations occur in a separate log file which allows reads to proceed concurrently.
1882      * While a write is in progress, readers on other threads will perceive the state
1883      * of the database as it was before the write began.  When the write completes, readers
1884      * on other threads will then perceive the new state of the database.
1885      * </p><p>
1886      * It is a good idea to enable write-ahead logging whenever a database will be
1887      * concurrently accessed and modified by multiple threads at the same time.
1888      * However, write-ahead logging uses significantly more memory than ordinary
1889      * journaling because there are multiple connections to the same database.
1890      * So if a database will only be used by a single thread, or if optimizing
1891      * concurrency is not very important, then write-ahead logging should be disabled.
1892      * </p><p>
1893      * After calling this method, execution of queries in parallel is enabled as long as
1894      * the database remains open.  To disable execution of queries in parallel, either
1895      * call {@link #disableWriteAheadLogging} or close the database and reopen it.
1896      * </p><p>
1897      * The maximum number of connections used to execute queries in parallel is
1898      * dependent upon the device memory and possibly other properties.
1899      * </p><p>
1900      * If a query is part of a transaction, then it is executed on the same database handle the
1901      * transaction was begun.
1902      * </p><p>
1903      * Writers should use {@link #beginTransactionNonExclusive()} or
1904      * {@link #beginTransactionWithListenerNonExclusive(SQLiteTransactionListener)}
1905      * to start a transaction.  Non-exclusive mode allows database file to be in readable
1906      * by other threads executing queries.
1907      * </p><p>
1908      * If the database has any attached databases, then execution of queries in parallel is NOT
1909      * possible.  Likewise, write-ahead logging is not supported for read-only databases
1910      * or memory databases.  In such cases, {@link #enableWriteAheadLogging} returns false.
1911      * </p><p>
1912      * The best way to enable write-ahead logging is to pass the
1913      * {@link #ENABLE_WRITE_AHEAD_LOGGING} flag to {@link #openDatabase}.  This is
1914      * more efficient than calling {@link #enableWriteAheadLogging}.
1915      * <code><pre>
1916      *     SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory,
1917      *             SQLiteDatabase.CREATE_IF_NECESSARY | SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING,
1918      *             myDatabaseErrorHandler);
1919      *     db.enableWriteAheadLogging();
1920      * </pre></code>
1921      * </p><p>
1922      * Another way to enable write-ahead logging is to call {@link #enableWriteAheadLogging}
1923      * after opening the database.
1924      * <code><pre>
1925      *     SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory,
1926      *             SQLiteDatabase.CREATE_IF_NECESSARY, myDatabaseErrorHandler);
1927      *     db.enableWriteAheadLogging();
1928      * </pre></code>
1929      * </p><p>
1930      * See also <a href="http://sqlite.org/wal.html">SQLite Write-Ahead Logging</a> for
1931      * more details about how write-ahead logging works.
1932      * </p>
1933      *
1934      * @return True if write-ahead logging is enabled.
1935      *
1936      * @throws IllegalStateException if there are transactions in progress at the
1937      * time this method is called.  WAL mode can only be changed when there are no
1938      * transactions in progress.
1939      *
1940      * @see #ENABLE_WRITE_AHEAD_LOGGING
1941      * @see #disableWriteAheadLogging
1942      */
enableWriteAheadLogging()1943     public boolean enableWriteAheadLogging() {
1944         synchronized (mLock) {
1945             throwIfNotOpenLocked();
1946 
1947             if ((mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) != 0) {
1948                 return true;
1949             }
1950 
1951             if (isReadOnlyLocked()) {
1952                 // WAL doesn't make sense for readonly-databases.
1953                 // TODO: True, but connection pooling does still make sense...
1954                 return false;
1955             }
1956 
1957             if (mConfigurationLocked.isInMemoryDb()) {
1958                 Log.i(TAG, "can't enable WAL for memory databases.");
1959                 return false;
1960             }
1961 
1962             // make sure this database has NO attached databases because sqlite's write-ahead-logging
1963             // doesn't work for databases with attached databases
1964             if (mHasAttachedDbsLocked) {
1965                 if (Log.isLoggable(TAG, Log.DEBUG)) {
1966                     Log.d(TAG, "this database: " + mConfigurationLocked.label
1967                             + " has attached databases. can't  enable WAL.");
1968                 }
1969                 return false;
1970             }
1971 
1972             mConfigurationLocked.openFlags |= ENABLE_WRITE_AHEAD_LOGGING;
1973             try {
1974                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
1975             } catch (RuntimeException ex) {
1976                 mConfigurationLocked.openFlags &= ~ENABLE_WRITE_AHEAD_LOGGING;
1977                 throw ex;
1978             }
1979         }
1980         return true;
1981     }
1982 
1983     /**
1984      * This method disables the features enabled by {@link #enableWriteAheadLogging()}.
1985      *
1986      * @throws IllegalStateException if there are transactions in progress at the
1987      * time this method is called.  WAL mode can only be changed when there are no
1988      * transactions in progress.
1989      *
1990      * @see #enableWriteAheadLogging
1991      */
disableWriteAheadLogging()1992     public void disableWriteAheadLogging() {
1993         synchronized (mLock) {
1994             throwIfNotOpenLocked();
1995 
1996             if ((mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) == 0) {
1997                 return;
1998             }
1999 
2000             mConfigurationLocked.openFlags &= ~ENABLE_WRITE_AHEAD_LOGGING;
2001             try {
2002                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
2003             } catch (RuntimeException ex) {
2004                 mConfigurationLocked.openFlags |= ENABLE_WRITE_AHEAD_LOGGING;
2005                 throw ex;
2006             }
2007         }
2008     }
2009 
2010     /**
2011      * Returns true if write-ahead logging has been enabled for this database.
2012      *
2013      * @return True if write-ahead logging has been enabled for this database.
2014      *
2015      * @see #enableWriteAheadLogging
2016      * @see #ENABLE_WRITE_AHEAD_LOGGING
2017      */
isWriteAheadLoggingEnabled()2018     public boolean isWriteAheadLoggingEnabled() {
2019         synchronized (mLock) {
2020             throwIfNotOpenLocked();
2021 
2022             return (mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) != 0;
2023         }
2024     }
2025 
2026     /**
2027      * Collect statistics about all open databases in the current process.
2028      * Used by bug report.
2029      */
getDbStats()2030     static ArrayList<DbStats> getDbStats() {
2031         ArrayList<DbStats> dbStatsList = new ArrayList<DbStats>();
2032         for (SQLiteDatabase db : getActiveDatabases()) {
2033             db.collectDbStats(dbStatsList);
2034         }
2035         return dbStatsList;
2036     }
2037 
collectDbStats(ArrayList<DbStats> dbStatsList)2038     private void collectDbStats(ArrayList<DbStats> dbStatsList) {
2039         synchronized (mLock) {
2040             if (mConnectionPoolLocked != null) {
2041                 mConnectionPoolLocked.collectDbStats(dbStatsList);
2042             }
2043         }
2044     }
2045 
getActiveDatabases()2046     private static ArrayList<SQLiteDatabase> getActiveDatabases() {
2047         ArrayList<SQLiteDatabase> databases = new ArrayList<SQLiteDatabase>();
2048         synchronized (sActiveDatabases) {
2049             databases.addAll(sActiveDatabases.keySet());
2050         }
2051         return databases;
2052     }
2053 
2054     /**
2055      * Dump detailed information about all open databases in the current process.
2056      * Used by bug report.
2057      */
dumpAll(Printer printer, boolean verbose)2058     static void dumpAll(Printer printer, boolean verbose) {
2059         for (SQLiteDatabase db : getActiveDatabases()) {
2060             db.dump(printer, verbose);
2061         }
2062     }
2063 
dump(Printer printer, boolean verbose)2064     private void dump(Printer printer, boolean verbose) {
2065         synchronized (mLock) {
2066             if (mConnectionPoolLocked != null) {
2067                 printer.println("");
2068                 mConnectionPoolLocked.dump(printer, verbose);
2069             }
2070         }
2071     }
2072 
2073     /**
2074      * Returns list of full pathnames of all attached databases including the main database
2075      * by executing 'pragma database_list' on the database.
2076      *
2077      * @return ArrayList of pairs of (database name, database file path) or null if the database
2078      * is not open.
2079      */
getAttachedDbs()2080     public List<Pair<String, String>> getAttachedDbs() {
2081         ArrayList<Pair<String, String>> attachedDbs = new ArrayList<Pair<String, String>>();
2082         synchronized (mLock) {
2083             if (mConnectionPoolLocked == null) {
2084                 return null; // not open
2085             }
2086 
2087             if (!mHasAttachedDbsLocked) {
2088                 // No attached databases.
2089                 // There is a small window where attached databases exist but this flag is not
2090                 // set yet.  This can occur when this thread is in a race condition with another
2091                 // thread that is executing the SQL statement: "attach database <blah> as <foo>"
2092                 // If this thread is NOT ok with such a race condition (and thus possibly not
2093                 // receivethe entire list of attached databases), then the caller should ensure
2094                 // that no thread is executing any SQL statements while a thread is calling this
2095                 // method.  Typically, this method is called when 'adb bugreport' is done or the
2096                 // caller wants to collect stats on the database and all its attached databases.
2097                 attachedDbs.add(new Pair<String, String>("main", mConfigurationLocked.path));
2098                 return attachedDbs;
2099             }
2100 
2101             acquireReference();
2102         }
2103 
2104         try {
2105             // has attached databases. query sqlite to get the list of attached databases.
2106             Cursor c = null;
2107             try {
2108                 c = rawQuery("pragma database_list;", null);
2109                 while (c.moveToNext()) {
2110                     // sqlite returns a row for each database in the returned list of databases.
2111                     //   in each row,
2112                     //       1st column is the database name such as main, or the database
2113                     //                              name specified on the "ATTACH" command
2114                     //       2nd column is the database file path.
2115                     attachedDbs.add(new Pair<String, String>(c.getString(1), c.getString(2)));
2116                 }
2117             } finally {
2118                 if (c != null) {
2119                     c.close();
2120                 }
2121             }
2122             return attachedDbs;
2123         } finally {
2124             releaseReference();
2125         }
2126     }
2127 
2128     /**
2129      * Runs 'pragma integrity_check' on the given database (and all the attached databases)
2130      * and returns true if the given database (and all its attached databases) pass integrity_check,
2131      * false otherwise.
2132      *<p>
2133      * If the result is false, then this method logs the errors reported by the integrity_check
2134      * command execution.
2135      *<p>
2136      * Note that 'pragma integrity_check' on a database can take a long time.
2137      *
2138      * @return true if the given database (and all its attached databases) pass integrity_check,
2139      * false otherwise.
2140      */
isDatabaseIntegrityOk()2141     public boolean isDatabaseIntegrityOk() {
2142         acquireReference();
2143         try {
2144             List<Pair<String, String>> attachedDbs = null;
2145             try {
2146                 attachedDbs = getAttachedDbs();
2147                 if (attachedDbs == null) {
2148                     throw new IllegalStateException("databaselist for: " + getPath() + " couldn't " +
2149                             "be retrieved. probably because the database is closed");
2150                 }
2151             } catch (SQLiteException e) {
2152                 // can't get attachedDb list. do integrity check on the main database
2153                 attachedDbs = new ArrayList<Pair<String, String>>();
2154                 attachedDbs.add(new Pair<String, String>("main", getPath()));
2155             }
2156 
2157             for (int i = 0; i < attachedDbs.size(); i++) {
2158                 Pair<String, String> p = attachedDbs.get(i);
2159                 SQLiteStatement prog = null;
2160                 try {
2161                     prog = compileStatement("PRAGMA " + p.first + ".integrity_check(1);");
2162                     String rslt = prog.simpleQueryForString();
2163                     if (!rslt.equalsIgnoreCase("ok")) {
2164                         // integrity_checker failed on main or attached databases
2165                         Log.e(TAG, "PRAGMA integrity_check on " + p.second + " returned: " + rslt);
2166                         return false;
2167                     }
2168                 } finally {
2169                     if (prog != null) prog.close();
2170                 }
2171             }
2172         } finally {
2173             releaseReference();
2174         }
2175         return true;
2176     }
2177 
2178     @Override
toString()2179     public String toString() {
2180         return "SQLiteDatabase: " + getPath();
2181     }
2182 
throwIfNotOpenLocked()2183     private void throwIfNotOpenLocked() {
2184         if (mConnectionPoolLocked == null) {
2185             throw new IllegalStateException("The database '" + mConfigurationLocked.label
2186                     + "' is not open.");
2187         }
2188     }
2189 
2190     /**
2191      * Used to allow returning sub-classes of {@link Cursor} when calling query.
2192      */
2193     public interface CursorFactory {
2194         /**
2195          * See {@link SQLiteCursor#SQLiteCursor(SQLiteCursorDriver, String, SQLiteQuery)}.
2196          */
newCursor(SQLiteDatabase db, SQLiteCursorDriver masterQuery, String editTable, SQLiteQuery query)2197         public Cursor newCursor(SQLiteDatabase db,
2198                 SQLiteCursorDriver masterQuery, String editTable,
2199                 SQLiteQuery query);
2200     }
2201 
2202     /**
2203      * A callback interface for a custom sqlite3 function.
2204      * This can be used to create a function that can be called from
2205      * sqlite3 database triggers.
2206      * @hide
2207      */
2208     public interface CustomFunction {
callback(String[] args)2209         public void callback(String[] args);
2210     }
2211 }
2212