• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.database.sqlite;
18 
19 import android.annotation.IntDef;
20 import android.annotation.IntRange;
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.app.ActivityManager;
24 import android.app.ActivityThread;
25 import android.compat.annotation.UnsupportedAppUsage;
26 import android.content.ContentResolver;
27 import android.content.ContentValues;
28 import android.database.Cursor;
29 import android.database.DatabaseErrorHandler;
30 import android.database.DatabaseUtils;
31 import android.database.DefaultDatabaseErrorHandler;
32 import android.database.SQLException;
33 import android.database.sqlite.SQLiteDebug.DbStats;
34 import android.os.Build;
35 import android.os.CancellationSignal;
36 import android.os.Looper;
37 import android.os.OperationCanceledException;
38 import android.os.SystemProperties;
39 import android.text.TextUtils;
40 import android.util.ArraySet;
41 import android.util.EventLog;
42 import android.util.Log;
43 import android.util.Pair;
44 import android.util.Printer;
45 
46 import com.android.internal.util.Preconditions;
47 
48 import dalvik.system.CloseGuard;
49 
50 import java.io.File;
51 import java.io.FileFilter;
52 import java.io.IOException;
53 import java.lang.annotation.Retention;
54 import java.lang.annotation.RetentionPolicy;
55 import java.nio.file.FileSystems;
56 import java.nio.file.Files;
57 import java.nio.file.attribute.BasicFileAttributes;
58 import java.util.ArrayList;
59 import java.util.Arrays;
60 import java.util.HashMap;
61 import java.util.List;
62 import java.util.Locale;
63 import java.util.Map;
64 import java.util.Objects;
65 import java.util.WeakHashMap;
66 import java.util.function.BinaryOperator;
67 import java.util.function.UnaryOperator;
68 
69 /**
70  * Exposes methods to manage a SQLite database.
71  *
72  * <p>
73  * SQLiteDatabase has methods to create, delete, execute SQL commands, and
74  * perform other common database management tasks.
75  * </p><p>
76  * See the Notepad sample application in the SDK for an example of creating
77  * and managing a database.
78  * </p><p>
79  * Database names must be unique within an application, not across all applications.
80  * </p>
81  *
82  * <h3>Localized Collation - ORDER BY</h3>
83  * <p>
84  * In addition to SQLite's default <code>BINARY</code> collator, Android supplies
85  * two more, <code>LOCALIZED</code>, which changes with the system's current locale,
86  * and <code>UNICODE</code>, which is the Unicode Collation Algorithm and not tailored
87  * to the current locale.
88  * </p>
89  */
90 public final class SQLiteDatabase extends SQLiteClosable {
91     private static final String TAG = "SQLiteDatabase";
92 
93     private static final int EVENT_DB_CORRUPT = 75004;
94 
95     // By default idle connections are not closed
96     private static final boolean DEBUG_CLOSE_IDLE_CONNECTIONS = SystemProperties
97             .getBoolean("persist.debug.sqlite.close_idle_connections", false);
98 
99     // Stores reference to all databases opened in the current process.
100     // (The referent Object is not used at this time.)
101     // INVARIANT: Guarded by sActiveDatabases.
102     private static WeakHashMap<SQLiteDatabase, Object> sActiveDatabases = new WeakHashMap<>();
103 
104     // Thread-local for database sessions that belong to this database.
105     // Each thread has its own database session.
106     // INVARIANT: Immutable.
107     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
108     private final ThreadLocal<SQLiteSession> mThreadSession = ThreadLocal
109             .withInitial(this::createSession);
110 
111     // The optional factory to use when creating new Cursors.  May be null.
112     // INVARIANT: Immutable.
113     private final CursorFactory mCursorFactory;
114 
115     // Error handler to be used when SQLite returns corruption errors.
116     // INVARIANT: Immutable.
117     private final DatabaseErrorHandler mErrorHandler;
118 
119     // Shared database state lock.
120     // This lock guards all of the shared state of the database, such as its
121     // configuration, whether it is open or closed, and so on.  This lock should
122     // be held for as little time as possible.
123     //
124     // The lock MUST NOT be held while attempting to acquire database connections or
125     // while executing SQL statements on behalf of the client as it can lead to deadlock.
126     //
127     // It is ok to hold the lock while reconfiguring the connection pool or dumping
128     // statistics because those operations are non-reentrant and do not try to acquire
129     // connections that might be held by other threads.
130     //
131     // Basic rule: grab the lock, access or modify global state, release the lock, then
132     // do the required SQL work.
133     private final Object mLock = new Object();
134 
135     // Warns if the database is finalized without being closed properly.
136     // INVARIANT: Guarded by mLock.
137     private final CloseGuard mCloseGuardLocked = CloseGuard.get();
138 
139     // The database configuration.
140     // INVARIANT: Guarded by mLock.
141     @UnsupportedAppUsage
142     private final SQLiteDatabaseConfiguration mConfigurationLocked;
143 
144     // The connection pool for the database, null when closed.
145     // The pool itself is thread-safe, but the reference to it can only be acquired
146     // when the lock is held.
147     // INVARIANT: Guarded by mLock.
148     @UnsupportedAppUsage
149     private SQLiteConnectionPool mConnectionPoolLocked;
150 
151     // True if the database has attached databases.
152     // INVARIANT: Guarded by mLock.
153     private boolean mHasAttachedDbsLocked;
154 
155     /**
156      * When a constraint violation occurs, an immediate ROLLBACK occurs,
157      * thus ending the current transaction, and the command aborts with a
158      * return code of SQLITE_CONSTRAINT. If no transaction is active
159      * (other than the implied transaction that is created on every command)
160      * then this algorithm works the same as ABORT.
161      */
162     public static final int CONFLICT_ROLLBACK = 1;
163 
164     /**
165      * When a constraint violation occurs,no ROLLBACK is executed
166      * so changes from prior commands within the same transaction
167      * are preserved. This is the default behavior.
168      */
169     public static final int CONFLICT_ABORT = 2;
170 
171     /**
172      * When a constraint violation occurs, the command aborts with a return
173      * code SQLITE_CONSTRAINT. But any changes to the database that
174      * the command made prior to encountering the constraint violation
175      * are preserved and are not backed out.
176      */
177     public static final int CONFLICT_FAIL = 3;
178 
179     /**
180      * When a constraint violation occurs, the one row that contains
181      * the constraint violation is not inserted or changed.
182      * But the command continues executing normally. Other rows before and
183      * after the row that contained the constraint violation continue to be
184      * inserted or updated normally. No error is returned.
185      */
186     public static final int CONFLICT_IGNORE = 4;
187 
188     /**
189      * When a UNIQUE constraint violation occurs, the pre-existing rows that
190      * are causing the constraint violation are removed prior to inserting
191      * or updating the current row. Thus the insert or update always occurs.
192      * The command continues executing normally. No error is returned.
193      * If a NOT NULL constraint violation occurs, the NULL value is replaced
194      * by the default value for that column. If the column has no default
195      * value, then the ABORT algorithm is used. If a CHECK constraint
196      * violation occurs then the IGNORE algorithm is used. When this conflict
197      * resolution strategy deletes rows in order to satisfy a constraint,
198      * it does not invoke delete triggers on those rows.
199      * This behavior might change in a future release.
200      */
201     public static final int CONFLICT_REPLACE = 5;
202 
203     /**
204      * Use the following when no conflict action is specified.
205      */
206     public static final int CONFLICT_NONE = 0;
207 
208     /** {@hide} */
209     @UnsupportedAppUsage
210     public static final String[] CONFLICT_VALUES = new String[]
211             {"", " OR ROLLBACK ", " OR ABORT ", " OR FAIL ", " OR IGNORE ", " OR REPLACE "};
212 
213     /**
214      * Maximum Length Of A LIKE Or GLOB Pattern
215      * The pattern matching algorithm used in the default LIKE and GLOB implementation
216      * of SQLite can exhibit O(N^2) performance (where N is the number of characters in
217      * the pattern) for certain pathological cases. To avoid denial-of-service attacks
218      * the length of the LIKE or GLOB pattern is limited to SQLITE_MAX_LIKE_PATTERN_LENGTH bytes.
219      * The default value of this limit is 50000. A modern workstation can evaluate
220      * even a pathological LIKE or GLOB pattern of 50000 bytes relatively quickly.
221      * The denial of service problem only comes into play when the pattern length gets
222      * into millions of bytes. Nevertheless, since most useful LIKE or GLOB patterns
223      * are at most a few dozen bytes in length, cautious application developers may
224      * want to reduce this parameter to something in the range of a few hundred
225      * if they know that external users are able to generate arbitrary patterns.
226      */
227     public static final int SQLITE_MAX_LIKE_PATTERN_LENGTH = 50000;
228 
229     /**
230      * Open flag: Flag for {@link #openDatabase} to open the database for reading and writing.
231      * If the disk is full, this may fail even before you actually write anything.
232      *
233      * {@more} Note that the value of this flag is 0, so it is the default.
234      */
235     public static final int OPEN_READWRITE = 0x00000000;          // update native code if changing
236 
237     /**
238      * Open flag: Flag for {@link #openDatabase} to open the database for reading only.
239      * This is the only reliable way to open a database if the disk may be full.
240      */
241     public static final int OPEN_READONLY = 0x00000001;           // update native code if changing
242 
243     private static final int OPEN_READ_MASK = 0x00000001;         // update native code if changing
244 
245     /**
246      * Open flag: Flag for {@link #openDatabase} to open the database without support for
247      * localized collators.
248      *
249      * {@more} This causes the collator <code>LOCALIZED</code> not to be created.
250      * You must be consistent when using this flag to use the setting the database was
251      * created with.  If this is set, {@link #setLocale} will do nothing.
252      */
253     public static final int NO_LOCALIZED_COLLATORS = 0x00000010;  // update native code if changing
254 
255     /**
256      * Open flag: Flag for {@link #openDatabase} to create the database file if it does not
257      * already exist.
258      */
259     public static final int CREATE_IF_NECESSARY = 0x10000000;     // update native code if changing
260 
261     /**
262      * Open flag: Flag for {@link #openDatabase} to open the database file with
263      * write-ahead logging enabled by default.  Using this flag is more efficient
264      * than calling {@link #enableWriteAheadLogging}.
265      *
266      * Write-ahead logging cannot be used with read-only databases so the value of
267      * this flag is ignored if the database is opened read-only.
268      *
269      * @see #enableWriteAheadLogging
270      */
271     public static final int ENABLE_WRITE_AHEAD_LOGGING = 0x20000000;
272 
273 
274     // Note: The below value was only used on Android Pie.
275     // public static final int DISABLE_COMPATIBILITY_WAL = 0x40000000;
276 
277     /**
278      * Open flag: Flag for {@link #openDatabase} to enable the legacy Compatibility WAL when opening
279      * database.
280      *
281      * @hide
282      */
283     public static final int ENABLE_LEGACY_COMPATIBILITY_WAL = 0x80000000;
284 
285     /**
286      * Absolute max value that can be set by {@link #setMaxSqlCacheSize(int)}.
287      *
288      * Each prepared-statement is between 1K - 6K, depending on the complexity of the
289      * SQL statement & schema.  A large SQL cache may use a significant amount of memory.
290      */
291     public static final int MAX_SQL_CACHE_SIZE = 100;
292 
SQLiteDatabase(final String path, final int openFlags, CursorFactory cursorFactory, DatabaseErrorHandler errorHandler, int lookasideSlotSize, int lookasideSlotCount, long idleConnectionTimeoutMs, String journalMode, String syncMode)293     private SQLiteDatabase(final String path, final int openFlags,
294             CursorFactory cursorFactory, DatabaseErrorHandler errorHandler,
295             int lookasideSlotSize, int lookasideSlotCount, long idleConnectionTimeoutMs,
296             String journalMode, String syncMode) {
297         mCursorFactory = cursorFactory;
298         mErrorHandler = errorHandler != null ? errorHandler : new DefaultDatabaseErrorHandler();
299         mConfigurationLocked = new SQLiteDatabaseConfiguration(path, openFlags);
300         mConfigurationLocked.lookasideSlotSize = lookasideSlotSize;
301         mConfigurationLocked.lookasideSlotCount = lookasideSlotCount;
302         // Disable lookaside allocator on low-RAM devices
303         if (ActivityManager.isLowRamDeviceStatic()) {
304             mConfigurationLocked.lookasideSlotCount = 0;
305             mConfigurationLocked.lookasideSlotSize = 0;
306         }
307         long effectiveTimeoutMs = Long.MAX_VALUE;
308         // Never close idle connections for in-memory databases
309         if (!mConfigurationLocked.isInMemoryDb()) {
310             // First, check app-specific value. Otherwise use defaults
311             // -1 in idleConnectionTimeoutMs indicates unset value
312             if (idleConnectionTimeoutMs >= 0) {
313                 effectiveTimeoutMs = idleConnectionTimeoutMs;
314             } else if (DEBUG_CLOSE_IDLE_CONNECTIONS) {
315                 effectiveTimeoutMs = SQLiteGlobal.getIdleConnectionTimeout();
316             }
317         }
318         mConfigurationLocked.idleConnectionTimeoutMs = effectiveTimeoutMs;
319         mConfigurationLocked.journalMode = journalMode;
320         mConfigurationLocked.syncMode = syncMode;
321         if (SQLiteCompatibilityWalFlags.isLegacyCompatibilityWalEnabled()) {
322             mConfigurationLocked.openFlags |= ENABLE_LEGACY_COMPATIBILITY_WAL;
323         }
324     }
325 
326     @Override
finalize()327     protected void finalize() throws Throwable {
328         try {
329             dispose(true);
330         } finally {
331             super.finalize();
332         }
333     }
334 
335     @Override
onAllReferencesReleased()336     protected void onAllReferencesReleased() {
337         dispose(false);
338     }
339 
dispose(boolean finalized)340     private void dispose(boolean finalized) {
341         final SQLiteConnectionPool pool;
342         synchronized (mLock) {
343             if (mCloseGuardLocked != null) {
344                 if (finalized) {
345                     mCloseGuardLocked.warnIfOpen();
346                 }
347                 mCloseGuardLocked.close();
348             }
349 
350             pool = mConnectionPoolLocked;
351             mConnectionPoolLocked = null;
352         }
353 
354         if (!finalized) {
355             synchronized (sActiveDatabases) {
356                 sActiveDatabases.remove(this);
357             }
358 
359             if (pool != null) {
360                 pool.close();
361             }
362         }
363     }
364 
365     /**
366      * Attempts to release memory that SQLite holds but does not require to
367      * operate properly. Typically this memory will come from the page cache.
368      *
369      * @return the number of bytes actually released
370      */
releaseMemory()371     public static int releaseMemory() {
372         return SQLiteGlobal.releaseMemory();
373     }
374 
375     /**
376      * Control whether or not the SQLiteDatabase is made thread-safe by using locks
377      * around critical sections. This is pretty expensive, so if you know that your
378      * DB will only be used by a single thread then you should set this to false.
379      * The default is true.
380      * @param lockingEnabled set to true to enable locks, false otherwise
381      *
382      * @deprecated This method now does nothing.  Do not use.
383      */
384     @Deprecated
setLockingEnabled(boolean lockingEnabled)385     public void setLockingEnabled(boolean lockingEnabled) {
386     }
387 
388     /**
389      * Gets a label to use when describing the database in log messages.
390      * @return The label.
391      */
getLabel()392     String getLabel() {
393         synchronized (mLock) {
394             return mConfigurationLocked.label;
395         }
396     }
397 
398     /**
399      * Sends a corruption message to the database error handler.
400      */
onCorruption()401     void onCorruption() {
402         EventLog.writeEvent(EVENT_DB_CORRUPT, getLabel());
403         mErrorHandler.onCorruption(this);
404     }
405 
406     /**
407      * Gets the {@link SQLiteSession} that belongs to this thread for this database.
408      * Once a thread has obtained a session, it will continue to obtain the same
409      * session even after the database has been closed (although the session will not
410      * be usable).  However, a thread that does not already have a session cannot
411      * obtain one after the database has been closed.
412      *
413      * The idea is that threads that have active connections to the database may still
414      * have work to complete even after the call to {@link #close}.  Active database
415      * connections are not actually disposed until they are released by the threads
416      * that own them.
417      *
418      * @return The session, never null.
419      *
420      * @throws IllegalStateException if the thread does not yet have a session and
421      * the database is not open.
422      */
423     @UnsupportedAppUsage
getThreadSession()424     SQLiteSession getThreadSession() {
425         return mThreadSession.get(); // initialValue() throws if database closed
426     }
427 
createSession()428     SQLiteSession createSession() {
429         final SQLiteConnectionPool pool;
430         synchronized (mLock) {
431             throwIfNotOpenLocked();
432             pool = mConnectionPoolLocked;
433         }
434         return new SQLiteSession(pool);
435     }
436 
437     /**
438      * Gets default connection flags that are appropriate for this thread, taking into
439      * account whether the thread is acting on behalf of the UI.
440      *
441      * @param readOnly True if the connection should be read-only.
442      * @return The connection flags.
443      */
getThreadDefaultConnectionFlags(boolean readOnly)444     int getThreadDefaultConnectionFlags(boolean readOnly) {
445         int flags = readOnly ? SQLiteConnectionPool.CONNECTION_FLAG_READ_ONLY :
446                 SQLiteConnectionPool.CONNECTION_FLAG_PRIMARY_CONNECTION_AFFINITY;
447         if (isMainThread()) {
448             flags |= SQLiteConnectionPool.CONNECTION_FLAG_INTERACTIVE;
449         }
450         return flags;
451     }
452 
isMainThread()453     private static boolean isMainThread() {
454         // FIXME: There should be a better way to do this.
455         // Would also be nice to have something that would work across Binder calls.
456         Looper looper = Looper.myLooper();
457         return looper != null && looper == Looper.getMainLooper();
458     }
459 
460     /**
461      * Begins a transaction in EXCLUSIVE mode.
462      * <p>
463      * Transactions can be nested.
464      * When the outer transaction is ended all of
465      * the work done in that transaction and all of the nested transactions will be committed or
466      * rolled back. The changes will be rolled back if any transaction is ended without being
467      * marked as clean (by calling setTransactionSuccessful). Otherwise they will be committed.
468      * </p>
469      * <p>Here is the standard idiom for transactions:
470      *
471      * <pre>
472      *   db.beginTransaction();
473      *   try {
474      *     ...
475      *     db.setTransactionSuccessful();
476      *   } finally {
477      *     db.endTransaction();
478      *   }
479      * </pre>
480      */
beginTransaction()481     public void beginTransaction() {
482         beginTransaction(null /* transactionStatusCallback */, true);
483     }
484 
485     /**
486      * Begins a transaction in IMMEDIATE mode. Transactions can be nested. When
487      * the outer transaction is ended all of the work done in that transaction
488      * and all of the nested transactions will be committed or rolled back. The
489      * changes will be rolled back if any transaction is ended without being
490      * marked as clean (by calling setTransactionSuccessful). Otherwise they
491      * will be committed.
492      * <p>
493      * Here is the standard idiom for transactions:
494      *
495      * <pre>
496      *   db.beginTransactionNonExclusive();
497      *   try {
498      *     ...
499      *     db.setTransactionSuccessful();
500      *   } finally {
501      *     db.endTransaction();
502      *   }
503      * </pre>
504      */
beginTransactionNonExclusive()505     public void beginTransactionNonExclusive() {
506         beginTransaction(null /* transactionStatusCallback */, false);
507     }
508 
509     /**
510      * Begins a transaction in EXCLUSIVE mode.
511      * <p>
512      * Transactions can be nested.
513      * When the outer transaction is ended all of
514      * the work done in that transaction and all of the nested transactions will be committed or
515      * rolled back. The changes will be rolled back if any transaction is ended without being
516      * marked as clean (by calling setTransactionSuccessful). Otherwise they will be committed.
517      * </p>
518      * <p>Here is the standard idiom for transactions:
519      *
520      * <pre>
521      *   db.beginTransactionWithListener(listener);
522      *   try {
523      *     ...
524      *     db.setTransactionSuccessful();
525      *   } finally {
526      *     db.endTransaction();
527      *   }
528      * </pre>
529      *
530      * @param transactionListener listener that should be notified when the transaction begins,
531      * commits, or is rolled back, either explicitly or by a call to
532      * {@link #yieldIfContendedSafely}.
533      */
beginTransactionWithListener(SQLiteTransactionListener transactionListener)534     public void beginTransactionWithListener(SQLiteTransactionListener transactionListener) {
535         beginTransaction(transactionListener, true);
536     }
537 
538     /**
539      * Begins a transaction in IMMEDIATE mode. Transactions can be nested. When
540      * the outer transaction is ended all of the work done in that transaction
541      * and all of the nested transactions will be committed or rolled back. The
542      * changes will be rolled back if any transaction is ended without being
543      * marked as clean (by calling setTransactionSuccessful). Otherwise they
544      * will be committed.
545      * <p>
546      * Here is the standard idiom for transactions:
547      *
548      * <pre>
549      *   db.beginTransactionWithListenerNonExclusive(listener);
550      *   try {
551      *     ...
552      *     db.setTransactionSuccessful();
553      *   } finally {
554      *     db.endTransaction();
555      *   }
556      * </pre>
557      *
558      * @param transactionListener listener that should be notified when the
559      *            transaction begins, commits, or is rolled back, either
560      *            explicitly or by a call to {@link #yieldIfContendedSafely}.
561      */
beginTransactionWithListenerNonExclusive( SQLiteTransactionListener transactionListener)562     public void beginTransactionWithListenerNonExclusive(
563             SQLiteTransactionListener transactionListener) {
564         beginTransaction(transactionListener, false);
565     }
566 
567     @UnsupportedAppUsage
beginTransaction(SQLiteTransactionListener transactionListener, boolean exclusive)568     private void beginTransaction(SQLiteTransactionListener transactionListener,
569             boolean exclusive) {
570         acquireReference();
571         try {
572             getThreadSession().beginTransaction(
573                     exclusive ? SQLiteSession.TRANSACTION_MODE_EXCLUSIVE :
574                             SQLiteSession.TRANSACTION_MODE_IMMEDIATE,
575                     transactionListener,
576                     getThreadDefaultConnectionFlags(false /*readOnly*/), null);
577         } finally {
578             releaseReference();
579         }
580     }
581 
582     /**
583      * End a transaction. See beginTransaction for notes about how to use this and when transactions
584      * are committed and rolled back.
585      */
endTransaction()586     public void endTransaction() {
587         acquireReference();
588         try {
589             getThreadSession().endTransaction(null);
590         } finally {
591             releaseReference();
592         }
593     }
594 
595     /**
596      * Marks the current transaction as successful. Do not do any more database work between
597      * calling this and calling endTransaction. Do as little non-database work as possible in that
598      * situation too. If any errors are encountered between this and endTransaction the transaction
599      * will still be committed.
600      *
601      * @throws IllegalStateException if the current thread is not in a transaction or the
602      * transaction is already marked as successful.
603      */
setTransactionSuccessful()604     public void setTransactionSuccessful() {
605         acquireReference();
606         try {
607             getThreadSession().setTransactionSuccessful();
608         } finally {
609             releaseReference();
610         }
611     }
612 
613     /**
614      * Returns true if the current thread has a transaction pending.
615      *
616      * @return True if the current thread is in a transaction.
617      */
inTransaction()618     public boolean inTransaction() {
619         acquireReference();
620         try {
621             return getThreadSession().hasTransaction();
622         } finally {
623             releaseReference();
624         }
625     }
626 
627     /**
628      * Returns true if the current thread is holding an active connection to the database.
629      * <p>
630      * The name of this method comes from a time when having an active connection
631      * to the database meant that the thread was holding an actual lock on the
632      * database.  Nowadays, there is no longer a true "database lock" although threads
633      * may block if they cannot acquire a database connection to perform a
634      * particular operation.
635      * </p>
636      *
637      * @return True if the current thread is holding an active connection to the database.
638      */
isDbLockedByCurrentThread()639     public boolean isDbLockedByCurrentThread() {
640         acquireReference();
641         try {
642             return getThreadSession().hasConnection();
643         } finally {
644             releaseReference();
645         }
646     }
647 
648     /**
649      * Always returns false.
650      * <p>
651      * There is no longer the concept of a database lock, so this method always returns false.
652      * </p>
653      *
654      * @return False.
655      * @deprecated Always returns false.  Do not use this method.
656      */
657     @Deprecated
isDbLockedByOtherThreads()658     public boolean isDbLockedByOtherThreads() {
659         return false;
660     }
661 
662     /**
663      * Temporarily end the transaction to let other threads run. The transaction is assumed to be
664      * successful so far. Do not call setTransactionSuccessful before calling this. When this
665      * returns a new transaction will have been created but not marked as successful.
666      * @return true if the transaction was yielded
667      * @deprecated if the db is locked more than once (because of nested transactions) then the lock
668      *   will not be yielded. Use yieldIfContendedSafely instead.
669      */
670     @Deprecated
yieldIfContended()671     public boolean yieldIfContended() {
672         return yieldIfContendedHelper(false /* do not check yielding */,
673                 -1 /* sleepAfterYieldDelay */);
674     }
675 
676     /**
677      * Temporarily end the transaction to let other threads run. The transaction is assumed to be
678      * successful so far. Do not call setTransactionSuccessful before calling this. When this
679      * returns a new transaction will have been created but not marked as successful. This assumes
680      * that there are no nested transactions (beginTransaction has only been called once) and will
681      * throw an exception if that is not the case.
682      * @return true if the transaction was yielded
683      */
yieldIfContendedSafely()684     public boolean yieldIfContendedSafely() {
685         return yieldIfContendedHelper(true /* check yielding */, -1 /* sleepAfterYieldDelay*/);
686     }
687 
688     /**
689      * Temporarily end the transaction to let other threads run. The transaction is assumed to be
690      * successful so far. Do not call setTransactionSuccessful before calling this. When this
691      * returns a new transaction will have been created but not marked as successful. This assumes
692      * that there are no nested transactions (beginTransaction has only been called once) and will
693      * throw an exception if that is not the case.
694      * @param sleepAfterYieldDelay if > 0, sleep this long before starting a new transaction if
695      *   the lock was actually yielded. This will allow other background threads to make some
696      *   more progress than they would if we started the transaction immediately.
697      * @return true if the transaction was yielded
698      */
yieldIfContendedSafely(long sleepAfterYieldDelay)699     public boolean yieldIfContendedSafely(long sleepAfterYieldDelay) {
700         return yieldIfContendedHelper(true /* check yielding */, sleepAfterYieldDelay);
701     }
702 
yieldIfContendedHelper(boolean throwIfUnsafe, long sleepAfterYieldDelay)703     private boolean yieldIfContendedHelper(boolean throwIfUnsafe, long sleepAfterYieldDelay) {
704         acquireReference();
705         try {
706             return getThreadSession().yieldTransaction(sleepAfterYieldDelay, throwIfUnsafe, null);
707         } finally {
708             releaseReference();
709         }
710     }
711 
712     /**
713      * Deprecated.
714      * @deprecated This method no longer serves any useful purpose and has been deprecated.
715      */
716     @Deprecated
getSyncedTables()717     public Map<String, String> getSyncedTables() {
718         return new HashMap<String, String>(0);
719     }
720 
721     /**
722      * Open the database according to the flags {@link #OPEN_READWRITE}
723      * {@link #OPEN_READONLY} {@link #CREATE_IF_NECESSARY} and/or {@link #NO_LOCALIZED_COLLATORS}.
724      *
725      * <p>Sets the locale of the database to the  the system's current locale.
726      * Call {@link #setLocale} if you would like something else.</p>
727      *
728      * @param path to database file to open and/or create
729      * @param factory an optional factory class that is called to instantiate a
730      *            cursor when query is called, or null for default
731      * @param flags to control database access mode
732      * @return the newly opened database
733      * @throws SQLiteException if the database cannot be opened
734      */
openDatabase(@onNull String path, @Nullable CursorFactory factory, @DatabaseOpenFlags int flags)735     public static SQLiteDatabase openDatabase(@NonNull String path, @Nullable CursorFactory factory,
736             @DatabaseOpenFlags int flags) {
737         return openDatabase(path, factory, flags, null);
738     }
739 
740     /**
741      * Open the database according to the specified {@link OpenParams parameters}
742      *
743      * @param path path to database file to open and/or create.
744      * <p><strong>Important:</strong> The file should be constructed either from an absolute path or
745      * by using {@link android.content.Context#getDatabasePath(String)}.
746      * @param openParams configuration parameters that are used for opening {@link SQLiteDatabase}
747      * @return the newly opened database
748      * @throws SQLiteException if the database cannot be opened
749      */
openDatabase(@onNull File path, @NonNull OpenParams openParams)750     public static SQLiteDatabase openDatabase(@NonNull File path,
751             @NonNull OpenParams openParams) {
752         return openDatabase(path.getPath(), openParams);
753     }
754 
755     @UnsupportedAppUsage
openDatabase(@onNull String path, @NonNull OpenParams openParams)756     private static SQLiteDatabase openDatabase(@NonNull String path,
757             @NonNull OpenParams openParams) {
758         Preconditions.checkArgument(openParams != null, "OpenParams cannot be null");
759         SQLiteDatabase db = new SQLiteDatabase(path, openParams.mOpenFlags,
760                 openParams.mCursorFactory, openParams.mErrorHandler,
761                 openParams.mLookasideSlotSize, openParams.mLookasideSlotCount,
762                 openParams.mIdleConnectionTimeout, openParams.mJournalMode, openParams.mSyncMode);
763         db.open();
764         return db;
765     }
766 
767     /**
768      * Open the database according to the flags {@link #OPEN_READWRITE}
769      * {@link #OPEN_READONLY} {@link #CREATE_IF_NECESSARY} and/or {@link #NO_LOCALIZED_COLLATORS}.
770      *
771      * <p>Sets the locale of the database to the  the system's current locale.
772      * Call {@link #setLocale} if you would like something else.</p>
773      *
774      * <p>Accepts input param: a concrete instance of {@link DatabaseErrorHandler} to be
775      * used to handle corruption when sqlite reports database corruption.</p>
776      *
777      * @param path to database file to open and/or create
778      * @param factory an optional factory class that is called to instantiate a
779      *            cursor when query is called, or null for default
780      * @param flags to control database access mode
781      * @param errorHandler the {@link DatabaseErrorHandler} obj to be used to handle corruption
782      * when sqlite reports database corruption
783      * @return the newly opened database
784      * @throws SQLiteException if the database cannot be opened
785      */
openDatabase(@onNull String path, @Nullable CursorFactory factory, @DatabaseOpenFlags int flags, @Nullable DatabaseErrorHandler errorHandler)786     public static SQLiteDatabase openDatabase(@NonNull String path, @Nullable CursorFactory factory,
787             @DatabaseOpenFlags int flags, @Nullable DatabaseErrorHandler errorHandler) {
788         SQLiteDatabase db = new SQLiteDatabase(path, flags, factory, errorHandler, -1, -1, -1, null,
789                 null);
790         db.open();
791         return db;
792     }
793 
794     /**
795      * Equivalent to openDatabase(file.getPath(), factory, CREATE_IF_NECESSARY).
796      */
openOrCreateDatabase(@onNull File file, @Nullable CursorFactory factory)797     public static SQLiteDatabase openOrCreateDatabase(@NonNull File file,
798             @Nullable CursorFactory factory) {
799         return openOrCreateDatabase(file.getPath(), factory);
800     }
801 
802     /**
803      * Equivalent to openDatabase(path, factory, CREATE_IF_NECESSARY).
804      */
openOrCreateDatabase(@onNull String path, @Nullable CursorFactory factory)805     public static SQLiteDatabase openOrCreateDatabase(@NonNull String path,
806             @Nullable CursorFactory factory) {
807         return openDatabase(path, factory, CREATE_IF_NECESSARY, null);
808     }
809 
810     /**
811      * Equivalent to openDatabase(path, factory, CREATE_IF_NECESSARY, errorHandler).
812      */
openOrCreateDatabase(@onNull String path, @Nullable CursorFactory factory, @Nullable DatabaseErrorHandler errorHandler)813     public static SQLiteDatabase openOrCreateDatabase(@NonNull String path,
814             @Nullable CursorFactory factory, @Nullable DatabaseErrorHandler errorHandler) {
815         return openDatabase(path, factory, CREATE_IF_NECESSARY, errorHandler);
816     }
817 
818     /**
819      * Deletes a database including its journal file and other auxiliary files
820      * that may have been created by the database engine.
821      *
822      * @param file The database file path.
823      * @return True if the database was successfully deleted.
824      */
deleteDatabase(@onNull File file)825     public static boolean deleteDatabase(@NonNull File file) {
826         return deleteDatabase(file, /*removeCheckFile=*/ true);
827     }
828 
829 
830     /** @hide */
deleteDatabase(@onNull File file, boolean removeCheckFile)831     public static boolean deleteDatabase(@NonNull File file, boolean removeCheckFile) {
832         if (file == null) {
833             throw new IllegalArgumentException("file must not be null");
834         }
835 
836         boolean deleted = false;
837         deleted |= file.delete();
838         deleted |= new File(file.getPath() + "-journal").delete();
839         deleted |= new File(file.getPath() + "-shm").delete();
840         deleted |= new File(file.getPath() + "-wal").delete();
841 
842         // This file is not a standard SQLite file, so don't update the deleted flag.
843         new File(file.getPath() + SQLiteGlobal.WIPE_CHECK_FILE_SUFFIX).delete();
844 
845         File dir = file.getParentFile();
846         if (dir != null) {
847             final String prefix = file.getName() + "-mj";
848             File[] files = dir.listFiles(new FileFilter() {
849                 @Override
850                 public boolean accept(File candidate) {
851                     return candidate.getName().startsWith(prefix);
852                 }
853             });
854             if (files != null) {
855                 for (File masterJournal : files) {
856                     deleted |= masterJournal.delete();
857                 }
858             }
859         }
860         return deleted;
861     }
862 
863     /**
864      * Reopens the database in read-write mode.
865      * If the database is already read-write, does nothing.
866      *
867      * @throws SQLiteException if the database could not be reopened as requested, in which
868      * case it remains open in read only mode.
869      * @throws IllegalStateException if the database is not open.
870      *
871      * @see #isReadOnly()
872      * @hide
873      */
874     @UnsupportedAppUsage
reopenReadWrite()875     public void reopenReadWrite() {
876         synchronized (mLock) {
877             throwIfNotOpenLocked();
878 
879             if (!isReadOnlyLocked()) {
880                 return; // nothing to do
881             }
882 
883             // Reopen the database in read-write mode.
884             final int oldOpenFlags = mConfigurationLocked.openFlags;
885             mConfigurationLocked.openFlags = (mConfigurationLocked.openFlags & ~OPEN_READ_MASK)
886                     | OPEN_READWRITE;
887             try {
888                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
889             } catch (RuntimeException ex) {
890                 mConfigurationLocked.openFlags = oldOpenFlags;
891                 throw ex;
892             }
893         }
894     }
895 
open()896     private void open() {
897         try {
898             try {
899                 openInner();
900             } catch (RuntimeException ex) {
901                 if (SQLiteDatabaseCorruptException.isCorruptException(ex)) {
902                     Log.e(TAG, "Database corruption detected in open()", ex);
903                     onCorruption();
904                     openInner();
905                 } else {
906                     throw ex;
907                 }
908             }
909         } catch (SQLiteException ex) {
910             Log.e(TAG, "Failed to open database '" + getLabel() + "'.", ex);
911             close();
912             throw ex;
913         }
914     }
915 
openInner()916     private void openInner() {
917         synchronized (mLock) {
918             assert mConnectionPoolLocked == null;
919             mConnectionPoolLocked = SQLiteConnectionPool.open(mConfigurationLocked);
920             mCloseGuardLocked.open("close");
921         }
922 
923         synchronized (sActiveDatabases) {
924             sActiveDatabases.put(this, null);
925         }
926     }
927 
928     /**
929      * Create a memory backed SQLite database.  Its contents will be destroyed
930      * when the database is closed.
931      *
932      * <p>Sets the locale of the database to the  the system's current locale.
933      * Call {@link #setLocale} if you would like something else.</p>
934      *
935      * @param factory an optional factory class that is called to instantiate a
936      *            cursor when query is called
937      * @return a SQLiteDatabase instance
938      * @throws SQLiteException if the database cannot be created
939      */
940     @NonNull
create(@ullable CursorFactory factory)941     public static SQLiteDatabase create(@Nullable CursorFactory factory) {
942         // This is a magic string with special meaning for SQLite.
943         return openDatabase(SQLiteDatabaseConfiguration.MEMORY_DB_PATH,
944                 factory, CREATE_IF_NECESSARY);
945     }
946 
947     /**
948      * Create a memory backed SQLite database.  Its contents will be destroyed
949      * when the database is closed.
950      *
951      * <p>Sets the locale of the database to the  the system's current locale.
952      * Call {@link #setLocale} if you would like something else.</p>
953      * @param openParams configuration parameters that are used for opening SQLiteDatabase
954      * @return a SQLiteDatabase instance
955      * @throws SQLException if the database cannot be created
956      */
957     @NonNull
createInMemory(@onNull OpenParams openParams)958     public static SQLiteDatabase createInMemory(@NonNull OpenParams openParams) {
959         return openDatabase(SQLiteDatabaseConfiguration.MEMORY_DB_PATH,
960                 openParams.toBuilder().addOpenFlags(CREATE_IF_NECESSARY).build());
961     }
962 
963     /**
964      * Register a custom scalar function that can be called from SQL
965      * expressions.
966      * <p>
967      * For example, registering a custom scalar function named {@code REVERSE}
968      * could be used in a query like
969      * {@code SELECT REVERSE(name) FROM employees}.
970      * <p>
971      * When attempting to register multiple functions with the same function
972      * name, SQLite will replace any previously defined functions with the
973      * latest definition, regardless of what function type they are. SQLite does
974      * not support unregistering functions.
975      *
976      * @param functionName Case-insensitive name to register this function
977      *            under, limited to 255 UTF-8 bytes in length.
978      * @param scalarFunction Functional interface that will be invoked when the
979      *            function name is used by a SQL statement. The argument values
980      *            from the SQL statement are passed to the functional interface,
981      *            and the return values from the functional interface are
982      *            returned back into the SQL statement.
983      * @throws SQLiteException if the custom function could not be registered.
984      * @see #setCustomAggregateFunction(String, BinaryOperator)
985      */
setCustomScalarFunction(@onNull String functionName, @NonNull UnaryOperator<String> scalarFunction)986     public void setCustomScalarFunction(@NonNull String functionName,
987             @NonNull UnaryOperator<String> scalarFunction) throws SQLiteException {
988         Objects.requireNonNull(functionName);
989         Objects.requireNonNull(scalarFunction);
990 
991         synchronized (mLock) {
992             throwIfNotOpenLocked();
993 
994             mConfigurationLocked.customScalarFunctions.put(functionName, scalarFunction);
995             try {
996                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
997             } catch (RuntimeException ex) {
998                 mConfigurationLocked.customScalarFunctions.remove(functionName);
999                 throw ex;
1000             }
1001         }
1002     }
1003 
1004     /**
1005      * Register a custom aggregate function that can be called from SQL
1006      * expressions.
1007      * <p>
1008      * For example, registering a custom aggregation function named
1009      * {@code LONGEST} could be used in a query like
1010      * {@code SELECT LONGEST(name) FROM employees}.
1011      * <p>
1012      * The implementation of this method follows the reduction flow outlined in
1013      * {@link java.util.stream.Stream#reduce(BinaryOperator)}, and the custom
1014      * aggregation function is expected to be an associative accumulation
1015      * function, as defined by that class.
1016      * <p>
1017      * When attempting to register multiple functions with the same function
1018      * name, SQLite will replace any previously defined functions with the
1019      * latest definition, regardless of what function type they are. SQLite does
1020      * not support unregistering functions.
1021      *
1022      * @param functionName Case-insensitive name to register this function
1023      *            under, limited to 255 UTF-8 bytes in length.
1024      * @param aggregateFunction Functional interface that will be invoked when
1025      *            the function name is used by a SQL statement. The argument
1026      *            values from the SQL statement are passed to the functional
1027      *            interface, and the return values from the functional interface
1028      *            are returned back into the SQL statement.
1029      * @throws SQLiteException if the custom function could not be registered.
1030      * @see #setCustomScalarFunction(String, UnaryOperator)
1031      */
setCustomAggregateFunction(@onNull String functionName, @NonNull BinaryOperator<String> aggregateFunction)1032     public void setCustomAggregateFunction(@NonNull String functionName,
1033             @NonNull BinaryOperator<String> aggregateFunction) throws SQLiteException {
1034         Objects.requireNonNull(functionName);
1035         Objects.requireNonNull(aggregateFunction);
1036 
1037         synchronized (mLock) {
1038             throwIfNotOpenLocked();
1039 
1040             mConfigurationLocked.customAggregateFunctions.put(functionName, aggregateFunction);
1041             try {
1042                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
1043             } catch (RuntimeException ex) {
1044                 mConfigurationLocked.customAggregateFunctions.remove(functionName);
1045                 throw ex;
1046             }
1047         }
1048     }
1049 
1050     /**
1051      * Execute the given SQL statement on all connections to this database.
1052      * <p>
1053      * This statement will be immediately executed on all existing connections,
1054      * and will be automatically executed on all future connections.
1055      * <p>
1056      * Some example usages are changes like {@code PRAGMA trusted_schema=OFF} or
1057      * functions like {@code SELECT icu_load_collation()}. If you execute these
1058      * statements using {@link #execSQL} then they will only apply to a single
1059      * database connection; using this method will ensure that they are
1060      * uniformly applied to all current and future connections.
1061      *
1062      * @param sql The SQL statement to be executed. Multiple statements
1063      *            separated by semicolons are not supported.
1064      * @param bindArgs The arguments that should be bound to the SQL statement.
1065      */
execPerConnectionSQL(@onNull String sql, @Nullable Object[] bindArgs)1066     public void execPerConnectionSQL(@NonNull String sql, @Nullable Object[] bindArgs)
1067             throws SQLException {
1068         Objects.requireNonNull(sql);
1069 
1070         // Copy arguments to ensure that the caller doesn't accidentally change
1071         // the values used by future connections
1072         bindArgs = DatabaseUtils.deepCopyOf(bindArgs);
1073 
1074         synchronized (mLock) {
1075             throwIfNotOpenLocked();
1076 
1077             final int index = mConfigurationLocked.perConnectionSql.size();
1078             mConfigurationLocked.perConnectionSql.add(Pair.create(sql, bindArgs));
1079             try {
1080                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
1081             } catch (RuntimeException ex) {
1082                 mConfigurationLocked.perConnectionSql.remove(index);
1083                 throw ex;
1084             }
1085         }
1086     }
1087 
1088     /**
1089      * Gets the database version.
1090      *
1091      * @return the database version
1092      */
getVersion()1093     public int getVersion() {
1094         return ((Long) DatabaseUtils.longForQuery(this, "PRAGMA user_version;", null)).intValue();
1095     }
1096 
1097     /**
1098      * Sets the database version.
1099      *
1100      * @param version the new database version
1101      */
setVersion(int version)1102     public void setVersion(int version) {
1103         execSQL("PRAGMA user_version = " + version);
1104     }
1105 
1106     /**
1107      * Returns the maximum size the database may grow to.
1108      *
1109      * @return the new maximum database size
1110      */
getMaximumSize()1111     public long getMaximumSize() {
1112         long pageCount = DatabaseUtils.longForQuery(this, "PRAGMA max_page_count;", null);
1113         return pageCount * getPageSize();
1114     }
1115 
1116     /**
1117      * Sets the maximum size the database will grow to. The maximum size cannot
1118      * be set below the current size.
1119      *
1120      * @param numBytes the maximum database size, in bytes
1121      * @return the new maximum database size
1122      */
setMaximumSize(long numBytes)1123     public long setMaximumSize(long numBytes) {
1124         long pageSize = getPageSize();
1125         long numPages = numBytes / pageSize;
1126         // If numBytes isn't a multiple of pageSize, bump up a page
1127         if ((numBytes % pageSize) != 0) {
1128             numPages++;
1129         }
1130         long newPageCount = DatabaseUtils.longForQuery(this, "PRAGMA max_page_count = " + numPages,
1131                 null);
1132         return newPageCount * pageSize;
1133     }
1134 
1135     /**
1136      * Returns the current database page size, in bytes.
1137      *
1138      * @return the database page size, in bytes
1139      */
getPageSize()1140     public long getPageSize() {
1141         return DatabaseUtils.longForQuery(this, "PRAGMA page_size;", null);
1142     }
1143 
1144     /**
1145      * Sets the database page size. The page size must be a power of two. This
1146      * method does not work if any data has been written to the database file,
1147      * and must be called right after the database has been created.
1148      *
1149      * @param numBytes the database page size, in bytes
1150      */
setPageSize(long numBytes)1151     public void setPageSize(long numBytes) {
1152         execSQL("PRAGMA page_size = " + numBytes);
1153     }
1154 
1155     /**
1156      * Mark this table as syncable. When an update occurs in this table the
1157      * _sync_dirty field will be set to ensure proper syncing operation.
1158      *
1159      * @param table the table to mark as syncable
1160      * @param deletedTable The deleted table that corresponds to the
1161      *          syncable table
1162      * @deprecated This method no longer serves any useful purpose and has been deprecated.
1163      */
1164     @Deprecated
markTableSyncable(String table, String deletedTable)1165     public void markTableSyncable(String table, String deletedTable) {
1166     }
1167 
1168     /**
1169      * Mark this table as syncable, with the _sync_dirty residing in another
1170      * table. When an update occurs in this table the _sync_dirty field of the
1171      * row in updateTable with the _id in foreignKey will be set to
1172      * ensure proper syncing operation.
1173      *
1174      * @param table an update on this table will trigger a sync time removal
1175      * @param foreignKey this is the column in table whose value is an _id in
1176      *          updateTable
1177      * @param updateTable this is the table that will have its _sync_dirty
1178      * @deprecated This method no longer serves any useful purpose and has been deprecated.
1179      */
1180     @Deprecated
markTableSyncable(String table, String foreignKey, String updateTable)1181     public void markTableSyncable(String table, String foreignKey, String updateTable) {
1182     }
1183 
1184     /**
1185      * Finds the name of the first table, which is editable.
1186      *
1187      * @param tables a list of tables
1188      * @return the first table listed
1189      */
findEditTable(String tables)1190     public static String findEditTable(String tables) {
1191         if (!TextUtils.isEmpty(tables)) {
1192             // find the first word terminated by either a space or a comma
1193             int spacepos = tables.indexOf(' ');
1194             int commapos = tables.indexOf(',');
1195 
1196             if (spacepos > 0 && (spacepos < commapos || commapos < 0)) {
1197                 return tables.substring(0, spacepos);
1198             } else if (commapos > 0 && (commapos < spacepos || spacepos < 0) ) {
1199                 return tables.substring(0, commapos);
1200             }
1201             return tables;
1202         } else {
1203             throw new IllegalStateException("Invalid tables");
1204         }
1205     }
1206 
1207     /**
1208      * Compiles an SQL statement into a reusable pre-compiled statement object.
1209      * The parameters are identical to {@link #execSQL(String)}. You may put ?s in the
1210      * statement and fill in those values with {@link SQLiteProgram#bindString}
1211      * and {@link SQLiteProgram#bindLong} each time you want to run the
1212      * statement. Statements may not return result sets larger than 1x1.
1213      *<p>
1214      * No two threads should be using the same {@link SQLiteStatement} at the same time.
1215      *
1216      * @param sql The raw SQL statement, may contain ? for unknown values to be
1217      *            bound later.
1218      * @return A pre-compiled {@link SQLiteStatement} object. Note that
1219      * {@link SQLiteStatement}s are not synchronized, see the documentation for more details.
1220      */
compileStatement(String sql)1221     public SQLiteStatement compileStatement(String sql) throws SQLException {
1222         acquireReference();
1223         try {
1224             return new SQLiteStatement(this, sql, null);
1225         } finally {
1226             releaseReference();
1227         }
1228     }
1229 
1230     /**
1231      * Query the given URL, returning a {@link Cursor} over the result set.
1232      *
1233      * @param distinct true if you want each row to be unique, false otherwise.
1234      * @param table The table name to compile the query against.
1235      * @param columns A list of which columns to return. Passing null will
1236      *            return all columns, which is discouraged to prevent reading
1237      *            data from storage that isn't going to be used.
1238      * @param selection A filter declaring which rows to return, formatted as an
1239      *            SQL WHERE clause (excluding the WHERE itself). Passing null
1240      *            will return all rows for the given table.
1241      * @param selectionArgs You may include ?s in selection, which will be
1242      *         replaced by the values from selectionArgs, in order that they
1243      *         appear in the selection. The values will be bound as Strings.
1244      * @param groupBy A filter declaring how to group rows, formatted as an SQL
1245      *            GROUP BY clause (excluding the GROUP BY itself). Passing null
1246      *            will cause the rows to not be grouped.
1247      * @param having A filter declare which row groups to include in the cursor,
1248      *            if row grouping is being used, formatted as an SQL HAVING
1249      *            clause (excluding the HAVING itself). Passing null will cause
1250      *            all row groups to be included, and is required when row
1251      *            grouping is not being used.
1252      * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
1253      *            (excluding the ORDER BY itself). Passing null will use the
1254      *            default sort order, which may be unordered.
1255      * @param limit Limits the number of rows returned by the query,
1256      *            formatted as LIMIT clause. Passing null denotes no LIMIT clause.
1257      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1258      * {@link Cursor}s are not synchronized, see the documentation for more details.
1259      * @see Cursor
1260      */
query(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)1261     public Cursor query(boolean distinct, String table, String[] columns,
1262             String selection, String[] selectionArgs, String groupBy,
1263             String having, String orderBy, String limit) {
1264         return queryWithFactory(null, distinct, table, columns, selection, selectionArgs,
1265                 groupBy, having, orderBy, limit, null);
1266     }
1267 
1268     /**
1269      * Query the given URL, returning a {@link Cursor} over the result set.
1270      *
1271      * @param distinct true if you want each row to be unique, false otherwise.
1272      * @param table The table name to compile the query against.
1273      * @param columns A list of which columns to return. Passing null will
1274      *            return all columns, which is discouraged to prevent reading
1275      *            data from storage that isn't going to be used.
1276      * @param selection A filter declaring which rows to return, formatted as an
1277      *            SQL WHERE clause (excluding the WHERE itself). Passing null
1278      *            will return all rows for the given table.
1279      * @param selectionArgs You may include ?s in selection, which will be
1280      *         replaced by the values from selectionArgs, in order that they
1281      *         appear in the selection. The values will be bound as Strings.
1282      * @param groupBy A filter declaring how to group rows, formatted as an SQL
1283      *            GROUP BY clause (excluding the GROUP BY itself). Passing null
1284      *            will cause the rows to not be grouped.
1285      * @param having A filter declare which row groups to include in the cursor,
1286      *            if row grouping is being used, formatted as an SQL HAVING
1287      *            clause (excluding the HAVING itself). Passing null will cause
1288      *            all row groups to be included, and is required when row
1289      *            grouping is not being used.
1290      * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
1291      *            (excluding the ORDER BY itself). Passing null will use the
1292      *            default sort order, which may be unordered.
1293      * @param limit Limits the number of rows returned by the query,
1294      *            formatted as LIMIT clause. Passing null denotes no LIMIT clause.
1295      * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
1296      * If the operation is canceled, then {@link OperationCanceledException} will be thrown
1297      * when the query is executed.
1298      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1299      * {@link Cursor}s are not synchronized, see the documentation for more details.
1300      * @see Cursor
1301      */
query(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit, CancellationSignal cancellationSignal)1302     public Cursor query(boolean distinct, String table, String[] columns,
1303             String selection, String[] selectionArgs, String groupBy,
1304             String having, String orderBy, String limit, CancellationSignal cancellationSignal) {
1305         return queryWithFactory(null, distinct, table, columns, selection, selectionArgs,
1306                 groupBy, having, orderBy, limit, cancellationSignal);
1307     }
1308 
1309     /**
1310      * Query the given URL, returning a {@link Cursor} over the result set.
1311      *
1312      * @param cursorFactory the cursor factory to use, or null for the default factory
1313      * @param distinct true if you want each row to be unique, false otherwise.
1314      * @param table The table name to compile the query against.
1315      * @param columns A list of which columns to return. Passing null will
1316      *            return all columns, which is discouraged to prevent reading
1317      *            data from storage that isn't going to be used.
1318      * @param selection A filter declaring which rows to return, formatted as an
1319      *            SQL WHERE clause (excluding the WHERE itself). Passing null
1320      *            will return all rows for the given table.
1321      * @param selectionArgs You may include ?s in selection, which will be
1322      *         replaced by the values from selectionArgs, in order that they
1323      *         appear in the selection. The values will be bound as Strings.
1324      * @param groupBy A filter declaring how to group rows, formatted as an SQL
1325      *            GROUP BY clause (excluding the GROUP BY itself). Passing null
1326      *            will cause the rows to not be grouped.
1327      * @param having A filter declare which row groups to include in the cursor,
1328      *            if row grouping is being used, formatted as an SQL HAVING
1329      *            clause (excluding the HAVING itself). Passing null will cause
1330      *            all row groups to be included, and is required when row
1331      *            grouping is not being used.
1332      * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
1333      *            (excluding the ORDER BY itself). Passing null will use the
1334      *            default sort order, which may be unordered.
1335      * @param limit Limits the number of rows returned by the query,
1336      *            formatted as LIMIT clause. Passing null denotes no LIMIT clause.
1337      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1338      * {@link Cursor}s are not synchronized, see the documentation for more details.
1339      * @see Cursor
1340      */
queryWithFactory(CursorFactory cursorFactory, boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)1341     public Cursor queryWithFactory(CursorFactory cursorFactory,
1342             boolean distinct, String table, String[] columns,
1343             String selection, String[] selectionArgs, String groupBy,
1344             String having, String orderBy, String limit) {
1345         return queryWithFactory(cursorFactory, distinct, table, columns, selection,
1346                 selectionArgs, groupBy, having, orderBy, limit, null);
1347     }
1348 
1349     /**
1350      * Query the given URL, returning a {@link Cursor} over the result set.
1351      *
1352      * @param cursorFactory the cursor factory to use, or null for the default factory
1353      * @param distinct true if you want each row to be unique, false otherwise.
1354      * @param table The table name to compile the query against.
1355      * @param columns A list of which columns to return. Passing null will
1356      *            return all columns, which is discouraged to prevent reading
1357      *            data from storage that isn't going to be used.
1358      * @param selection A filter declaring which rows to return, formatted as an
1359      *            SQL WHERE clause (excluding the WHERE itself). Passing null
1360      *            will return all rows for the given table.
1361      * @param selectionArgs You may include ?s in selection, which will be
1362      *         replaced by the values from selectionArgs, in order that they
1363      *         appear in the selection. The values will be bound as Strings.
1364      * @param groupBy A filter declaring how to group rows, formatted as an SQL
1365      *            GROUP BY clause (excluding the GROUP BY itself). Passing null
1366      *            will cause the rows to not be grouped.
1367      * @param having A filter declare which row groups to include in the cursor,
1368      *            if row grouping is being used, formatted as an SQL HAVING
1369      *            clause (excluding the HAVING itself). Passing null will cause
1370      *            all row groups to be included, and is required when row
1371      *            grouping is not being used.
1372      * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
1373      *            (excluding the ORDER BY itself). Passing null will use the
1374      *            default sort order, which may be unordered.
1375      * @param limit Limits the number of rows returned by the query,
1376      *            formatted as LIMIT clause. Passing null denotes no LIMIT clause.
1377      * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
1378      * If the operation is canceled, then {@link OperationCanceledException} will be thrown
1379      * when the query is executed.
1380      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1381      * {@link Cursor}s are not synchronized, see the documentation for more details.
1382      * @see Cursor
1383      */
queryWithFactory(CursorFactory cursorFactory, boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit, CancellationSignal cancellationSignal)1384     public Cursor queryWithFactory(CursorFactory cursorFactory,
1385             boolean distinct, String table, String[] columns,
1386             String selection, String[] selectionArgs, String groupBy,
1387             String having, String orderBy, String limit, CancellationSignal cancellationSignal) {
1388         acquireReference();
1389         try {
1390             String sql = SQLiteQueryBuilder.buildQueryString(
1391                     distinct, table, columns, selection, groupBy, having, orderBy, limit);
1392 
1393             return rawQueryWithFactory(cursorFactory, sql, selectionArgs,
1394                     findEditTable(table), cancellationSignal);
1395         } finally {
1396             releaseReference();
1397         }
1398     }
1399 
1400     /**
1401      * Query the given table, returning a {@link Cursor} over the result set.
1402      *
1403      * @param table The table name to compile the query against.
1404      * @param columns A list of which columns to return. Passing null will
1405      *            return all columns, which is discouraged to prevent reading
1406      *            data from storage that isn't going to be used.
1407      * @param selection A filter declaring which rows to return, formatted as an
1408      *            SQL WHERE clause (excluding the WHERE itself). Passing null
1409      *            will return all rows for the given table.
1410      * @param selectionArgs You may include ?s in selection, which will be
1411      *         replaced by the values from selectionArgs, in order that they
1412      *         appear in the selection. The values will be bound as Strings.
1413      * @param groupBy A filter declaring how to group rows, formatted as an SQL
1414      *            GROUP BY clause (excluding the GROUP BY itself). Passing null
1415      *            will cause the rows to not be grouped.
1416      * @param having A filter declare which row groups to include in the cursor,
1417      *            if row grouping is being used, formatted as an SQL HAVING
1418      *            clause (excluding the HAVING itself). Passing null will cause
1419      *            all row groups to be included, and is required when row
1420      *            grouping is not being used.
1421      * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
1422      *            (excluding the ORDER BY itself). Passing null will use the
1423      *            default sort order, which may be unordered.
1424      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1425      * {@link Cursor}s are not synchronized, see the documentation for more details.
1426      * @see Cursor
1427      */
query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)1428     public Cursor query(String table, String[] columns, String selection,
1429             String[] selectionArgs, String groupBy, String having,
1430             String orderBy) {
1431 
1432         return query(false, table, columns, selection, selectionArgs, groupBy,
1433                 having, orderBy, null /* limit */);
1434     }
1435 
1436     /**
1437      * Query the given table, returning a {@link Cursor} over the result set.
1438      *
1439      * @param table The table name to compile the query against.
1440      * @param columns A list of which columns to return. Passing null will
1441      *            return all columns, which is discouraged to prevent reading
1442      *            data from storage that isn't going to be used.
1443      * @param selection A filter declaring which rows to return, formatted as an
1444      *            SQL WHERE clause (excluding the WHERE itself). Passing null
1445      *            will return all rows for the given table.
1446      * @param selectionArgs You may include ?s in selection, which will be
1447      *         replaced by the values from selectionArgs, in order that they
1448      *         appear in the selection. The values will be bound as Strings.
1449      * @param groupBy A filter declaring how to group rows, formatted as an SQL
1450      *            GROUP BY clause (excluding the GROUP BY itself). Passing null
1451      *            will cause the rows to not be grouped.
1452      * @param having A filter declare which row groups to include in the cursor,
1453      *            if row grouping is being used, formatted as an SQL HAVING
1454      *            clause (excluding the HAVING itself). Passing null will cause
1455      *            all row groups to be included, and is required when row
1456      *            grouping is not being used.
1457      * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
1458      *            (excluding the ORDER BY itself). Passing null will use the
1459      *            default sort order, which may be unordered.
1460      * @param limit Limits the number of rows returned by the query,
1461      *            formatted as LIMIT clause. Passing null denotes no LIMIT clause.
1462      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1463      * {@link Cursor}s are not synchronized, see the documentation for more details.
1464      * @see Cursor
1465      */
query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)1466     public Cursor query(String table, String[] columns, String selection,
1467             String[] selectionArgs, String groupBy, String having,
1468             String orderBy, String limit) {
1469 
1470         return query(false, table, columns, selection, selectionArgs, groupBy,
1471                 having, orderBy, limit);
1472     }
1473 
1474     /**
1475      * Runs the provided SQL and returns a {@link Cursor} over the result set.
1476      *
1477      * @param sql the SQL query. The SQL string must not be ; terminated
1478      * @param selectionArgs You may include ?s in where clause in the query,
1479      *     which will be replaced by the values from selectionArgs. The
1480      *     values will be bound as Strings.
1481      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1482      * {@link Cursor}s are not synchronized, see the documentation for more details.
1483      */
rawQuery(String sql, String[] selectionArgs)1484     public Cursor rawQuery(String sql, String[] selectionArgs) {
1485         return rawQueryWithFactory(null, sql, selectionArgs, null, null);
1486     }
1487 
1488     /**
1489      * Runs the provided SQL and returns a {@link Cursor} over the result set.
1490      *
1491      * @param sql the SQL query. The SQL string must not be ; terminated
1492      * @param selectionArgs You may include ?s in where clause in the query,
1493      *     which will be replaced by the values from selectionArgs. The
1494      *     values will be bound as Strings.
1495      * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
1496      * If the operation is canceled, then {@link OperationCanceledException} will be thrown
1497      * when the query is executed.
1498      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1499      * {@link Cursor}s are not synchronized, see the documentation for more details.
1500      */
rawQuery(String sql, String[] selectionArgs, CancellationSignal cancellationSignal)1501     public Cursor rawQuery(String sql, String[] selectionArgs,
1502             CancellationSignal cancellationSignal) {
1503         return rawQueryWithFactory(null, sql, selectionArgs, null, cancellationSignal);
1504     }
1505 
1506     /**
1507      * Runs the provided SQL and returns a cursor over the result set.
1508      *
1509      * @param cursorFactory the cursor factory to use, or null for the default factory
1510      * @param sql the SQL query. The SQL string must not be ; terminated
1511      * @param selectionArgs You may include ?s in where clause in the query,
1512      *     which will be replaced by the values from selectionArgs. The
1513      *     values will be bound as Strings.
1514      * @param editTable the name of the first table, which is editable
1515      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1516      * {@link Cursor}s are not synchronized, see the documentation for more details.
1517      */
rawQueryWithFactory( CursorFactory cursorFactory, String sql, String[] selectionArgs, String editTable)1518     public Cursor rawQueryWithFactory(
1519             CursorFactory cursorFactory, String sql, String[] selectionArgs,
1520             String editTable) {
1521         return rawQueryWithFactory(cursorFactory, sql, selectionArgs, editTable, null);
1522     }
1523 
1524     /**
1525      * Runs the provided SQL and returns a cursor over the result set.
1526      *
1527      * @param cursorFactory the cursor factory to use, or null for the default factory
1528      * @param sql the SQL query. The SQL string must not be ; terminated
1529      * @param selectionArgs You may include ?s in where clause in the query,
1530      *     which will be replaced by the values from selectionArgs. The
1531      *     values will be bound as Strings.
1532      * @param editTable the name of the first table, which is editable
1533      * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
1534      * If the operation is canceled, then {@link OperationCanceledException} will be thrown
1535      * when the query is executed.
1536      * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1537      * {@link Cursor}s are not synchronized, see the documentation for more details.
1538      */
rawQueryWithFactory( CursorFactory cursorFactory, String sql, String[] selectionArgs, String editTable, CancellationSignal cancellationSignal)1539     public Cursor rawQueryWithFactory(
1540             CursorFactory cursorFactory, String sql, String[] selectionArgs,
1541             String editTable, CancellationSignal cancellationSignal) {
1542         acquireReference();
1543         try {
1544             SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(this, sql, editTable,
1545                     cancellationSignal);
1546             return driver.query(cursorFactory != null ? cursorFactory : mCursorFactory,
1547                     selectionArgs);
1548         } finally {
1549             releaseReference();
1550         }
1551     }
1552 
1553     /**
1554      * Convenience method for inserting a row into the database.
1555      *
1556      * @param table the table to insert the row into
1557      * @param nullColumnHack optional; may be <code>null</code>.
1558      *            SQL doesn't allow inserting a completely empty row without
1559      *            naming at least one column name.  If your provided <code>values</code> is
1560      *            empty, no column names are known and an empty row can't be inserted.
1561      *            If not set to null, the <code>nullColumnHack</code> parameter
1562      *            provides the name of nullable column name to explicitly insert a NULL into
1563      *            in the case where your <code>values</code> is empty.
1564      * @param values this map contains the initial column values for the
1565      *            row. The keys should be the column names and the values the
1566      *            column values
1567      * @return the row ID of the newly inserted row, or -1 if an error occurred
1568      */
insert(String table, String nullColumnHack, ContentValues values)1569     public long insert(String table, String nullColumnHack, ContentValues values) {
1570         try {
1571             return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE);
1572         } catch (SQLException e) {
1573             Log.e(TAG, "Error inserting " + values, e);
1574             return -1;
1575         }
1576     }
1577 
1578     /**
1579      * Convenience method for inserting a row into the database.
1580      *
1581      * @param table the table to insert the row into
1582      * @param nullColumnHack optional; may be <code>null</code>.
1583      *            SQL doesn't allow inserting a completely empty row without
1584      *            naming at least one column name.  If your provided <code>values</code> is
1585      *            empty, no column names are known and an empty row can't be inserted.
1586      *            If not set to null, the <code>nullColumnHack</code> parameter
1587      *            provides the name of nullable column name to explicitly insert a NULL into
1588      *            in the case where your <code>values</code> is empty.
1589      * @param values this map contains the initial column values for the
1590      *            row. The keys should be the column names and the values the
1591      *            column values
1592      * @throws SQLException
1593      * @return the row ID of the newly inserted row, or -1 if an error occurred
1594      */
insertOrThrow(String table, String nullColumnHack, ContentValues values)1595     public long insertOrThrow(String table, String nullColumnHack, ContentValues values)
1596             throws SQLException {
1597         return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE);
1598     }
1599 
1600     /**
1601      * Convenience method for replacing a row in the database.
1602      * Inserts a new row if a row does not already exist.
1603      *
1604      * @param table the table in which to replace the row
1605      * @param nullColumnHack optional; may be <code>null</code>.
1606      *            SQL doesn't allow inserting a completely empty row without
1607      *            naming at least one column name.  If your provided <code>initialValues</code> is
1608      *            empty, no column names are known and an empty row can't be inserted.
1609      *            If not set to null, the <code>nullColumnHack</code> parameter
1610      *            provides the name of nullable column name to explicitly insert a NULL into
1611      *            in the case where your <code>initialValues</code> is empty.
1612      * @param initialValues this map contains the initial column values for
1613      *   the row. The keys should be the column names and the values the column values.
1614      * @return the row ID of the newly inserted row, or -1 if an error occurred
1615      */
replace(String table, String nullColumnHack, ContentValues initialValues)1616     public long replace(String table, String nullColumnHack, ContentValues initialValues) {
1617         try {
1618             return insertWithOnConflict(table, nullColumnHack, initialValues,
1619                     CONFLICT_REPLACE);
1620         } catch (SQLException e) {
1621             Log.e(TAG, "Error inserting " + initialValues, e);
1622             return -1;
1623         }
1624     }
1625 
1626     /**
1627      * Convenience method for replacing a row in the database.
1628      * Inserts a new row if a row does not already exist.
1629      *
1630      * @param table the table in which to replace the row
1631      * @param nullColumnHack optional; may be <code>null</code>.
1632      *            SQL doesn't allow inserting a completely empty row without
1633      *            naming at least one column name.  If your provided <code>initialValues</code> is
1634      *            empty, no column names are known and an empty row can't be inserted.
1635      *            If not set to null, the <code>nullColumnHack</code> parameter
1636      *            provides the name of nullable column name to explicitly insert a NULL into
1637      *            in the case where your <code>initialValues</code> is empty.
1638      * @param initialValues this map contains the initial column values for
1639      *   the row. The keys should be the column names and the values the column values.
1640      * @throws SQLException
1641      * @return the row ID of the newly inserted row, or -1 if an error occurred
1642      */
replaceOrThrow(String table, String nullColumnHack, ContentValues initialValues)1643     public long replaceOrThrow(String table, String nullColumnHack,
1644             ContentValues initialValues) throws SQLException {
1645         return insertWithOnConflict(table, nullColumnHack, initialValues,
1646                 CONFLICT_REPLACE);
1647     }
1648 
1649     /**
1650      * General method for inserting a row into the database.
1651      *
1652      * @param table the table to insert the row into
1653      * @param nullColumnHack optional; may be <code>null</code>.
1654      *            SQL doesn't allow inserting a completely empty row without
1655      *            naming at least one column name.  If your provided <code>initialValues</code> is
1656      *            empty, no column names are known and an empty row can't be inserted.
1657      *            If not set to null, the <code>nullColumnHack</code> parameter
1658      *            provides the name of nullable column name to explicitly insert a NULL into
1659      *            in the case where your <code>initialValues</code> is empty.
1660      * @param initialValues this map contains the initial column values for the
1661      *            row. The keys should be the column names and the values the
1662      *            column values
1663      * @param conflictAlgorithm for insert conflict resolver
1664      * @return the row ID of the newly inserted row OR <code>-1</code> if either the
1665      *            input parameter <code>conflictAlgorithm</code> = {@link #CONFLICT_IGNORE}
1666      *            or an error occurred.
1667      */
insertWithOnConflict(String table, String nullColumnHack, ContentValues initialValues, int conflictAlgorithm)1668     public long insertWithOnConflict(String table, String nullColumnHack,
1669             ContentValues initialValues, int conflictAlgorithm) {
1670         acquireReference();
1671         try {
1672             StringBuilder sql = new StringBuilder();
1673             sql.append("INSERT");
1674             sql.append(CONFLICT_VALUES[conflictAlgorithm]);
1675             sql.append(" INTO ");
1676             sql.append(table);
1677             sql.append('(');
1678 
1679             Object[] bindArgs = null;
1680             int size = (initialValues != null && !initialValues.isEmpty())
1681                     ? initialValues.size() : 0;
1682             if (size > 0) {
1683                 bindArgs = new Object[size];
1684                 int i = 0;
1685                 for (String colName : initialValues.keySet()) {
1686                     sql.append((i > 0) ? "," : "");
1687                     sql.append(colName);
1688                     bindArgs[i++] = initialValues.get(colName);
1689                 }
1690                 sql.append(')');
1691                 sql.append(" VALUES (");
1692                 for (i = 0; i < size; i++) {
1693                     sql.append((i > 0) ? ",?" : "?");
1694                 }
1695             } else {
1696                 sql.append(nullColumnHack).append(") VALUES (NULL");
1697             }
1698             sql.append(')');
1699 
1700             SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs);
1701             try {
1702                 return statement.executeInsert();
1703             } finally {
1704                 statement.close();
1705             }
1706         } finally {
1707             releaseReference();
1708         }
1709     }
1710 
1711     /**
1712      * Convenience method for deleting rows in the database.
1713      *
1714      * @param table the table to delete from
1715      * @param whereClause the optional WHERE clause to apply when deleting.
1716      *            Passing null will delete all rows.
1717      * @param whereArgs You may include ?s in the where clause, which
1718      *            will be replaced by the values from whereArgs. The values
1719      *            will be bound as Strings.
1720      * @return the number of rows affected if a whereClause is passed in, 0
1721      *         otherwise. To remove all rows and get a count pass "1" as the
1722      *         whereClause.
1723      */
delete(String table, String whereClause, String[] whereArgs)1724     public int delete(String table, String whereClause, String[] whereArgs) {
1725         acquireReference();
1726         try {
1727             SQLiteStatement statement =  new SQLiteStatement(this, "DELETE FROM " + table +
1728                     (!TextUtils.isEmpty(whereClause) ? " WHERE " + whereClause : ""), whereArgs);
1729             try {
1730                 return statement.executeUpdateDelete();
1731             } finally {
1732                 statement.close();
1733             }
1734         } finally {
1735             releaseReference();
1736         }
1737     }
1738 
1739     /**
1740      * Convenience method for updating rows in the database.
1741      *
1742      * @param table the table to update in
1743      * @param values a map from column names to new column values. null is a
1744      *            valid value that will be translated to NULL.
1745      * @param whereClause the optional WHERE clause to apply when updating.
1746      *            Passing null will update all rows.
1747      * @param whereArgs You may include ?s in the where clause, which
1748      *            will be replaced by the values from whereArgs. The values
1749      *            will be bound as Strings.
1750      * @return the number of rows affected
1751      */
update(String table, ContentValues values, String whereClause, String[] whereArgs)1752     public int update(String table, ContentValues values, String whereClause, String[] whereArgs) {
1753         return updateWithOnConflict(table, values, whereClause, whereArgs, CONFLICT_NONE);
1754     }
1755 
1756     /**
1757      * Convenience method for updating rows in the database.
1758      *
1759      * @param table the table to update in
1760      * @param values a map from column names to new column values. null is a
1761      *            valid value that will be translated to NULL.
1762      * @param whereClause the optional WHERE clause to apply when updating.
1763      *            Passing null will update all rows.
1764      * @param whereArgs You may include ?s in the where clause, which
1765      *            will be replaced by the values from whereArgs. The values
1766      *            will be bound as Strings.
1767      * @param conflictAlgorithm for update conflict resolver
1768      * @return the number of rows affected
1769      */
updateWithOnConflict(String table, ContentValues values, String whereClause, String[] whereArgs, int conflictAlgorithm)1770     public int updateWithOnConflict(String table, ContentValues values,
1771             String whereClause, String[] whereArgs, int conflictAlgorithm) {
1772         if (values == null || values.isEmpty()) {
1773             throw new IllegalArgumentException("Empty values");
1774         }
1775 
1776         acquireReference();
1777         try {
1778             StringBuilder sql = new StringBuilder(120);
1779             sql.append("UPDATE ");
1780             sql.append(CONFLICT_VALUES[conflictAlgorithm]);
1781             sql.append(table);
1782             sql.append(" SET ");
1783 
1784             // move all bind args to one array
1785             int setValuesSize = values.size();
1786             int bindArgsSize = (whereArgs == null) ? setValuesSize : (setValuesSize + whereArgs.length);
1787             Object[] bindArgs = new Object[bindArgsSize];
1788             int i = 0;
1789             for (String colName : values.keySet()) {
1790                 sql.append((i > 0) ? "," : "");
1791                 sql.append(colName);
1792                 bindArgs[i++] = values.get(colName);
1793                 sql.append("=?");
1794             }
1795             if (whereArgs != null) {
1796                 for (i = setValuesSize; i < bindArgsSize; i++) {
1797                     bindArgs[i] = whereArgs[i - setValuesSize];
1798                 }
1799             }
1800             if (!TextUtils.isEmpty(whereClause)) {
1801                 sql.append(" WHERE ");
1802                 sql.append(whereClause);
1803             }
1804 
1805             SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs);
1806             try {
1807                 return statement.executeUpdateDelete();
1808             } finally {
1809                 statement.close();
1810             }
1811         } finally {
1812             releaseReference();
1813         }
1814     }
1815 
1816     /**
1817      * Execute a single SQL statement that is NOT a SELECT
1818      * or any other SQL statement that returns data.
1819      * <p>
1820      * It has no means to return any data (such as the number of affected rows).
1821      * Instead, you're encouraged to use {@link #insert(String, String, ContentValues)},
1822      * {@link #update(String, ContentValues, String, String[])}, et al, when possible.
1823      * </p>
1824      * <p>
1825      * When using {@link #enableWriteAheadLogging()}, journal_mode is
1826      * automatically managed by this class. So, do not set journal_mode
1827      * using "PRAGMA journal_mode'<value>" statement if your app is using
1828      * {@link #enableWriteAheadLogging()}
1829      * </p>
1830      * <p>
1831      * Note that {@code PRAGMA} values which apply on a per-connection basis
1832      * should <em>not</em> be configured using this method; you should instead
1833      * use {@link #execPerConnectionSQL} to ensure that they are uniformly
1834      * applied to all current and future connections.
1835      * </p>
1836      *
1837      * @param sql the SQL statement to be executed. Multiple statements separated by semicolons are
1838      * not supported.
1839      * @throws SQLException if the SQL string is invalid
1840      */
execSQL(String sql)1841     public void execSQL(String sql) throws SQLException {
1842         executeSql(sql, null);
1843     }
1844 
1845     /**
1846      * Execute a single SQL statement that is NOT a SELECT/INSERT/UPDATE/DELETE.
1847      * <p>
1848      * For INSERT statements, use any of the following instead.
1849      * <ul>
1850      *   <li>{@link #insert(String, String, ContentValues)}</li>
1851      *   <li>{@link #insertOrThrow(String, String, ContentValues)}</li>
1852      *   <li>{@link #insertWithOnConflict(String, String, ContentValues, int)}</li>
1853      * </ul>
1854      * <p>
1855      * For UPDATE statements, use any of the following instead.
1856      * <ul>
1857      *   <li>{@link #update(String, ContentValues, String, String[])}</li>
1858      *   <li>{@link #updateWithOnConflict(String, ContentValues, String, String[], int)}</li>
1859      * </ul>
1860      * <p>
1861      * For DELETE statements, use any of the following instead.
1862      * <ul>
1863      *   <li>{@link #delete(String, String, String[])}</li>
1864      * </ul>
1865      * <p>
1866      * For example, the following are good candidates for using this method:
1867      * <ul>
1868      *   <li>ALTER TABLE</li>
1869      *   <li>CREATE or DROP table / trigger / view / index / virtual table</li>
1870      *   <li>REINDEX</li>
1871      *   <li>RELEASE</li>
1872      *   <li>SAVEPOINT</li>
1873      *   <li>PRAGMA that returns no data</li>
1874      * </ul>
1875      * </p>
1876      * <p>
1877      * When using {@link #enableWriteAheadLogging()}, journal_mode is
1878      * automatically managed by this class. So, do not set journal_mode
1879      * using "PRAGMA journal_mode'<value>" statement if your app is using
1880      * {@link #enableWriteAheadLogging()}
1881      * </p>
1882      * <p>
1883      * Note that {@code PRAGMA} values which apply on a per-connection basis
1884      * should <em>not</em> be configured using this method; you should instead
1885      * use {@link #execPerConnectionSQL} to ensure that they are uniformly
1886      * applied to all current and future connections.
1887      * </p>
1888      *
1889      * @param sql the SQL statement to be executed. Multiple statements separated by semicolons are
1890      * not supported.
1891      * @param bindArgs only byte[], String, Long and Double are supported in bindArgs.
1892      * @throws SQLException if the SQL string is invalid
1893      */
execSQL(String sql, Object[] bindArgs)1894     public void execSQL(String sql, Object[] bindArgs) throws SQLException {
1895         if (bindArgs == null) {
1896             throw new IllegalArgumentException("Empty bindArgs");
1897         }
1898         executeSql(sql, bindArgs);
1899     }
1900 
1901     /** {@hide} */
executeSql(String sql, Object[] bindArgs)1902     public int executeSql(String sql, Object[] bindArgs) throws SQLException {
1903         acquireReference();
1904         try {
1905             final int statementType = DatabaseUtils.getSqlStatementType(sql);
1906             if (statementType == DatabaseUtils.STATEMENT_ATTACH) {
1907                 boolean disableWal = false;
1908                 synchronized (mLock) {
1909                     if (!mHasAttachedDbsLocked) {
1910                         mHasAttachedDbsLocked = true;
1911                         disableWal = true;
1912                         mConnectionPoolLocked.disableIdleConnectionHandler();
1913                     }
1914                 }
1915                 if (disableWal) {
1916                     disableWriteAheadLogging();
1917                 }
1918             }
1919 
1920             try (SQLiteStatement statement = new SQLiteStatement(this, sql, bindArgs)) {
1921                 return statement.executeUpdateDelete();
1922             } finally {
1923                 // If schema was updated, close non-primary connections, otherwise they might
1924                 // have outdated schema information
1925                 if (statementType == DatabaseUtils.STATEMENT_DDL) {
1926                     mConnectionPoolLocked.closeAvailableNonPrimaryConnectionsAndLogExceptions();
1927                 }
1928             }
1929         } finally {
1930             releaseReference();
1931         }
1932     }
1933 
1934     /**
1935      * Verifies that a SQL SELECT statement is valid by compiling it.
1936      * If the SQL statement is not valid, this method will throw a {@link SQLiteException}.
1937      *
1938      * @param sql SQL to be validated
1939      * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
1940      * If the operation is canceled, then {@link OperationCanceledException} will be thrown
1941      * when the query is executed.
1942      * @throws SQLiteException if {@code sql} is invalid
1943      */
validateSql(@onNull String sql, @Nullable CancellationSignal cancellationSignal)1944     public void validateSql(@NonNull String sql, @Nullable CancellationSignal cancellationSignal) {
1945         getThreadSession().prepare(sql,
1946                 getThreadDefaultConnectionFlags(/* readOnly =*/ true), cancellationSignal, null);
1947     }
1948 
1949     /**
1950      * Returns true if the database is opened as read only.
1951      *
1952      * @return True if database is opened as read only.
1953      */
isReadOnly()1954     public boolean isReadOnly() {
1955         synchronized (mLock) {
1956             return isReadOnlyLocked();
1957         }
1958     }
1959 
isReadOnlyLocked()1960     private boolean isReadOnlyLocked() {
1961         return (mConfigurationLocked.openFlags & OPEN_READ_MASK) == OPEN_READONLY;
1962     }
1963 
1964     /**
1965      * Returns true if the database is in-memory db.
1966      *
1967      * @return True if the database is in-memory.
1968      * @hide
1969      */
isInMemoryDatabase()1970     public boolean isInMemoryDatabase() {
1971         synchronized (mLock) {
1972             return mConfigurationLocked.isInMemoryDb();
1973         }
1974     }
1975 
1976     /**
1977      * Returns true if the database is currently open.
1978      *
1979      * @return True if the database is currently open (has not been closed).
1980      */
isOpen()1981     public boolean isOpen() {
1982         synchronized (mLock) {
1983             return mConnectionPoolLocked != null;
1984         }
1985     }
1986 
1987     /**
1988      * Returns true if the new version code is greater than the current database version.
1989      *
1990      * @param newVersion The new version code.
1991      * @return True if the new version code is greater than the current database version.
1992      */
needUpgrade(int newVersion)1993     public boolean needUpgrade(int newVersion) {
1994         return newVersion > getVersion();
1995     }
1996 
1997     /**
1998      * Gets the path to the database file.
1999      *
2000      * @return The path to the database file.
2001      */
getPath()2002     public final String getPath() {
2003         synchronized (mLock) {
2004             return mConfigurationLocked.path;
2005         }
2006     }
2007 
2008     /**
2009      * Sets the locale for this database.  Does nothing if this database has
2010      * the {@link #NO_LOCALIZED_COLLATORS} flag set or was opened read only.
2011      *
2012      * @param locale The new locale.
2013      *
2014      * @throws SQLException if the locale could not be set.  The most common reason
2015      * for this is that there is no collator available for the locale you requested.
2016      * In this case the database remains unchanged.
2017      */
setLocale(Locale locale)2018     public void setLocale(Locale locale) {
2019         if (locale == null) {
2020             throw new IllegalArgumentException("locale must not be null.");
2021         }
2022 
2023         synchronized (mLock) {
2024             throwIfNotOpenLocked();
2025 
2026             final Locale oldLocale = mConfigurationLocked.locale;
2027             mConfigurationLocked.locale = locale;
2028             try {
2029                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
2030             } catch (RuntimeException ex) {
2031                 mConfigurationLocked.locale = oldLocale;
2032                 throw ex;
2033             }
2034         }
2035     }
2036 
2037     /**
2038      * Sets the maximum size of the prepared-statement cache for this database.
2039      * (size of the cache = number of compiled-sql-statements stored in the cache).
2040      *<p>
2041      * Maximum cache size can ONLY be increased from its current size (default = 10).
2042      * If this method is called with smaller size than the current maximum value,
2043      * then IllegalStateException is thrown.
2044      *<p>
2045      * This method is thread-safe.
2046      *
2047      * @param cacheSize the size of the cache. can be (0 to {@link #MAX_SQL_CACHE_SIZE})
2048      * @throws IllegalStateException if input cacheSize > {@link #MAX_SQL_CACHE_SIZE}.
2049      */
setMaxSqlCacheSize(int cacheSize)2050     public void setMaxSqlCacheSize(int cacheSize) {
2051         if (cacheSize > MAX_SQL_CACHE_SIZE || cacheSize < 0) {
2052             throw new IllegalStateException(
2053                     "expected value between 0 and " + MAX_SQL_CACHE_SIZE);
2054         }
2055 
2056         synchronized (mLock) {
2057             throwIfNotOpenLocked();
2058 
2059             final int oldMaxSqlCacheSize = mConfigurationLocked.maxSqlCacheSize;
2060             mConfigurationLocked.maxSqlCacheSize = cacheSize;
2061             try {
2062                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
2063             } catch (RuntimeException ex) {
2064                 mConfigurationLocked.maxSqlCacheSize = oldMaxSqlCacheSize;
2065                 throw ex;
2066             }
2067         }
2068     }
2069 
2070     /**
2071      * Sets whether foreign key constraints are enabled for the database.
2072      * <p>
2073      * By default, foreign key constraints are not enforced by the database.
2074      * This method allows an application to enable foreign key constraints.
2075      * It must be called each time the database is opened to ensure that foreign
2076      * key constraints are enabled for the session.
2077      * </p><p>
2078      * A good time to call this method is right after calling {@link #openOrCreateDatabase}
2079      * or in the {@link SQLiteOpenHelper#onConfigure} callback.
2080      * </p><p>
2081      * When foreign key constraints are disabled, the database does not check whether
2082      * changes to the database will violate foreign key constraints.  Likewise, when
2083      * foreign key constraints are disabled, the database will not execute cascade
2084      * delete or update triggers.  As a result, it is possible for the database
2085      * state to become inconsistent.  To perform a database integrity check,
2086      * call {@link #isDatabaseIntegrityOk}.
2087      * </p><p>
2088      * This method must not be called while a transaction is in progress.
2089      * </p><p>
2090      * See also <a href="http://sqlite.org/foreignkeys.html">SQLite Foreign Key Constraints</a>
2091      * for more details about foreign key constraint support.
2092      * </p>
2093      *
2094      * @param enable True to enable foreign key constraints, false to disable them.
2095      *
2096      * @throws IllegalStateException if the are transactions is in progress
2097      * when this method is called.
2098      */
setForeignKeyConstraintsEnabled(boolean enable)2099     public void setForeignKeyConstraintsEnabled(boolean enable) {
2100         synchronized (mLock) {
2101             throwIfNotOpenLocked();
2102 
2103             if (mConfigurationLocked.foreignKeyConstraintsEnabled == enable) {
2104                 return;
2105             }
2106 
2107             mConfigurationLocked.foreignKeyConstraintsEnabled = enable;
2108             try {
2109                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
2110             } catch (RuntimeException ex) {
2111                 mConfigurationLocked.foreignKeyConstraintsEnabled = !enable;
2112                 throw ex;
2113             }
2114         }
2115     }
2116 
2117     /**
2118      * This method enables parallel execution of queries from multiple threads on the
2119      * same database.  It does this by opening multiple connections to the database
2120      * and using a different database connection for each query.  The database
2121      * journal mode is also changed to enable writes to proceed concurrently with reads.
2122      * <p>
2123      * When write-ahead logging is not enabled (the default), it is not possible for
2124      * reads and writes to occur on the database at the same time.  Before modifying the
2125      * database, the writer implicitly acquires an exclusive lock on the database which
2126      * prevents readers from accessing the database until the write is completed.
2127      * </p><p>
2128      * In contrast, when write-ahead logging is enabled (by calling this method), write
2129      * operations occur in a separate log file which allows reads to proceed concurrently.
2130      * While a write is in progress, readers on other threads will perceive the state
2131      * of the database as it was before the write began.  When the write completes, readers
2132      * on other threads will then perceive the new state of the database.
2133      * </p><p>
2134      * It is a good idea to enable write-ahead logging whenever a database will be
2135      * concurrently accessed and modified by multiple threads at the same time.
2136      * However, write-ahead logging uses significantly more memory than ordinary
2137      * journaling because there are multiple connections to the same database.
2138      * So if a database will only be used by a single thread, or if optimizing
2139      * concurrency is not very important, then write-ahead logging should be disabled.
2140      * </p><p>
2141      * After calling this method, execution of queries in parallel is enabled as long as
2142      * the database remains open.  To disable execution of queries in parallel, either
2143      * call {@link #disableWriteAheadLogging} or close the database and reopen it.
2144      * </p><p>
2145      * The maximum number of connections used to execute queries in parallel is
2146      * dependent upon the device memory and possibly other properties.
2147      * </p><p>
2148      * If a query is part of a transaction, then it is executed on the same database handle the
2149      * transaction was begun.
2150      * </p><p>
2151      * Writers should use {@link #beginTransactionNonExclusive()} or
2152      * {@link #beginTransactionWithListenerNonExclusive(SQLiteTransactionListener)}
2153      * to start a transaction.  Non-exclusive mode allows database file to be in readable
2154      * by other threads executing queries.
2155      * </p><p>
2156      * If the database has any attached databases, then execution of queries in parallel is NOT
2157      * possible.  Likewise, write-ahead logging is not supported for read-only databases
2158      * or memory databases.  In such cases, {@link #enableWriteAheadLogging} returns false.
2159      * </p><p>
2160      * The best way to enable write-ahead logging is to pass the
2161      * {@link #ENABLE_WRITE_AHEAD_LOGGING} flag to {@link #openDatabase}.  This is
2162      * more efficient than calling {@link #enableWriteAheadLogging}.
2163      * <code><pre>
2164      *     SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory,
2165      *             SQLiteDatabase.CREATE_IF_NECESSARY | SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING,
2166      *             myDatabaseErrorHandler);
2167      * </pre></code>
2168      * </p><p>
2169      * Another way to enable write-ahead logging is to call {@link #enableWriteAheadLogging}
2170      * after opening the database.
2171      * <code><pre>
2172      *     SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory,
2173      *             SQLiteDatabase.CREATE_IF_NECESSARY, myDatabaseErrorHandler);
2174      *     db.enableWriteAheadLogging();
2175      * </pre></code>
2176      * </p><p>
2177      * See also <a href="http://sqlite.org/wal.html">SQLite Write-Ahead Logging</a> for
2178      * more details about how write-ahead logging works.
2179      * </p>
2180      *
2181      * @return True if write-ahead logging is enabled.
2182      *
2183      * @throws IllegalStateException if there are transactions in progress at the
2184      * time this method is called.  WAL mode can only be changed when there are no
2185      * transactions in progress.
2186      *
2187      * @see #ENABLE_WRITE_AHEAD_LOGGING
2188      * @see #disableWriteAheadLogging
2189      */
enableWriteAheadLogging()2190     public boolean enableWriteAheadLogging() {
2191         synchronized (mLock) {
2192             throwIfNotOpenLocked();
2193 
2194             if ((mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) != 0) {
2195                 return true;
2196             }
2197 
2198             if (isReadOnlyLocked()) {
2199                 // WAL doesn't make sense for readonly-databases.
2200                 // TODO: True, but connection pooling does still make sense...
2201                 return false;
2202             }
2203 
2204             if (mConfigurationLocked.isInMemoryDb()) {
2205                 Log.i(TAG, "can't enable WAL for memory databases.");
2206                 return false;
2207             }
2208 
2209             // make sure this database has NO attached databases because sqlite's write-ahead-logging
2210             // doesn't work for databases with attached databases
2211             if (mHasAttachedDbsLocked) {
2212                 if (Log.isLoggable(TAG, Log.DEBUG)) {
2213                     Log.d(TAG, "this database: " + mConfigurationLocked.label
2214                             + " has attached databases. can't  enable WAL.");
2215                 }
2216                 return false;
2217             }
2218 
2219             mConfigurationLocked.openFlags |= ENABLE_WRITE_AHEAD_LOGGING;
2220             try {
2221                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
2222             } catch (RuntimeException ex) {
2223                 mConfigurationLocked.openFlags &= ~ENABLE_WRITE_AHEAD_LOGGING;
2224                 throw ex;
2225             }
2226         }
2227         return true;
2228     }
2229 
2230     /**
2231      * This method disables the features enabled by {@link #enableWriteAheadLogging()}.
2232      *
2233      * @throws IllegalStateException if there are transactions in progress at the
2234      * time this method is called.  WAL mode can only be changed when there are no
2235      * transactions in progress.
2236      *
2237      * @see #enableWriteAheadLogging
2238      */
disableWriteAheadLogging()2239     public void disableWriteAheadLogging() {
2240         synchronized (mLock) {
2241             throwIfNotOpenLocked();
2242 
2243             final int oldFlags = mConfigurationLocked.openFlags;
2244             final boolean walEnabled = (oldFlags & ENABLE_WRITE_AHEAD_LOGGING) != 0;
2245             final boolean compatibilityWalEnabled =
2246                     (oldFlags & ENABLE_LEGACY_COMPATIBILITY_WAL) != 0;
2247             // WAL was never enabled for this database, so there's nothing left to do.
2248             if (!walEnabled && !compatibilityWalEnabled) {
2249                 return;
2250             }
2251 
2252             // If an app explicitly disables WAL, it takes priority over any directive
2253             // to use the legacy "compatibility WAL" mode.
2254             mConfigurationLocked.openFlags &= ~ENABLE_WRITE_AHEAD_LOGGING;
2255             mConfigurationLocked.openFlags &= ~ENABLE_LEGACY_COMPATIBILITY_WAL;
2256 
2257             try {
2258                 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
2259             } catch (RuntimeException ex) {
2260                 mConfigurationLocked.openFlags = oldFlags;
2261                 throw ex;
2262             }
2263         }
2264     }
2265 
2266     /**
2267      * Returns true if write-ahead logging has been enabled for this database.
2268      *
2269      * @return True if write-ahead logging has been enabled for this database.
2270      *
2271      * @see #enableWriteAheadLogging
2272      * @see #ENABLE_WRITE_AHEAD_LOGGING
2273      */
isWriteAheadLoggingEnabled()2274     public boolean isWriteAheadLoggingEnabled() {
2275         synchronized (mLock) {
2276             throwIfNotOpenLocked();
2277 
2278             return (mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) != 0;
2279         }
2280     }
2281 
2282     /**
2283      * Collect statistics about all open databases in the current process.
2284      * Used by bug report.
2285      */
getDbStats()2286     static ArrayList<DbStats> getDbStats() {
2287         ArrayList<DbStats> dbStatsList = new ArrayList<DbStats>();
2288         for (SQLiteDatabase db : getActiveDatabases()) {
2289             db.collectDbStats(dbStatsList);
2290         }
2291         return dbStatsList;
2292     }
2293 
2294     @UnsupportedAppUsage
collectDbStats(ArrayList<DbStats> dbStatsList)2295     private void collectDbStats(ArrayList<DbStats> dbStatsList) {
2296         synchronized (mLock) {
2297             if (mConnectionPoolLocked != null) {
2298                 mConnectionPoolLocked.collectDbStats(dbStatsList);
2299             }
2300         }
2301     }
2302 
2303     @UnsupportedAppUsage
getActiveDatabases()2304     private static ArrayList<SQLiteDatabase> getActiveDatabases() {
2305         ArrayList<SQLiteDatabase> databases = new ArrayList<SQLiteDatabase>();
2306         synchronized (sActiveDatabases) {
2307             databases.addAll(sActiveDatabases.keySet());
2308         }
2309         return databases;
2310     }
2311 
2312     /**
2313      * Dump detailed information about all open databases in the current process.
2314      * Used by bug report.
2315      */
dumpAll(Printer printer, boolean verbose, boolean isSystem)2316     static void dumpAll(Printer printer, boolean verbose, boolean isSystem) {
2317         // Use this ArraySet to collect file paths.
2318         final ArraySet<String> directories = new ArraySet<>();
2319 
2320         for (SQLiteDatabase db : getActiveDatabases()) {
2321             db.dump(printer, verbose, isSystem, directories);
2322         }
2323 
2324         // Dump DB files in the directories.
2325         if (directories.size() > 0) {
2326             final String[] dirs = directories.toArray(new String[directories.size()]);
2327             Arrays.sort(dirs);
2328             for (String dir : dirs) {
2329                 dumpDatabaseDirectory(printer, new File(dir), isSystem);
2330             }
2331         }
2332     }
2333 
dump(Printer printer, boolean verbose, boolean isSystem, ArraySet directories)2334     private void dump(Printer printer, boolean verbose, boolean isSystem, ArraySet directories) {
2335         synchronized (mLock) {
2336             if (mConnectionPoolLocked != null) {
2337                 printer.println("");
2338                 mConnectionPoolLocked.dump(printer, verbose, directories);
2339             }
2340         }
2341     }
2342 
dumpDatabaseDirectory(Printer pw, File dir, boolean isSystem)2343     private static void dumpDatabaseDirectory(Printer pw, File dir, boolean isSystem) {
2344         pw.println("");
2345         pw.println("Database files in " + dir.getAbsolutePath() + ":");
2346         final File[] files = dir.listFiles();
2347         if (files == null || files.length == 0) {
2348             pw.println("  [none]");
2349             return;
2350         }
2351         Arrays.sort(files, (a, b) -> a.getName().compareTo(b.getName()));
2352 
2353         for (File f : files) {
2354             if (isSystem) {
2355                 // If called within the system server, the directory contains other files too, so
2356                 // filter by file extensions.
2357                 // (If it's an app, just print all files because they may not use *.db
2358                 // extension.)
2359                 final String name = f.getName();
2360                 if (!(name.endsWith(".db") || name.endsWith(".db-wal")
2361                         || name.endsWith(".db-journal")
2362                         || name.endsWith(SQLiteGlobal.WIPE_CHECK_FILE_SUFFIX))) {
2363                     continue;
2364                 }
2365             }
2366             pw.println(String.format("  %-40s %7db %s", f.getName(), f.length(),
2367                     SQLiteDatabase.getFileTimestamps(f.getAbsolutePath())));
2368         }
2369     }
2370 
2371     /**
2372      * Returns list of full pathnames of all attached databases including the main database
2373      * by executing 'pragma database_list' on the database.
2374      *
2375      * @return ArrayList of pairs of (database name, database file path) or null if the database
2376      * is not open.
2377      */
getAttachedDbs()2378     public List<Pair<String, String>> getAttachedDbs() {
2379         ArrayList<Pair<String, String>> attachedDbs = new ArrayList<Pair<String, String>>();
2380         synchronized (mLock) {
2381             if (mConnectionPoolLocked == null) {
2382                 return null; // not open
2383             }
2384 
2385             if (!mHasAttachedDbsLocked) {
2386                 // No attached databases.
2387                 // There is a small window where attached databases exist but this flag is not
2388                 // set yet.  This can occur when this thread is in a race condition with another
2389                 // thread that is executing the SQL statement: "attach database <blah> as <foo>"
2390                 // If this thread is NOT ok with such a race condition (and thus possibly not
2391                 // receivethe entire list of attached databases), then the caller should ensure
2392                 // that no thread is executing any SQL statements while a thread is calling this
2393                 // method.  Typically, this method is called when 'adb bugreport' is done or the
2394                 // caller wants to collect stats on the database and all its attached databases.
2395                 attachedDbs.add(new Pair<String, String>("main", mConfigurationLocked.path));
2396                 return attachedDbs;
2397             }
2398 
2399             acquireReference();
2400         }
2401 
2402         try {
2403             // has attached databases. query sqlite to get the list of attached databases.
2404             Cursor c = null;
2405             try {
2406                 c = rawQuery("pragma database_list;", null);
2407                 while (c.moveToNext()) {
2408                     // sqlite returns a row for each database in the returned list of databases.
2409                     //   in each row,
2410                     //       1st column is the database name such as main, or the database
2411                     //                              name specified on the "ATTACH" command
2412                     //       2nd column is the database file path.
2413                     attachedDbs.add(new Pair<String, String>(c.getString(1), c.getString(2)));
2414                 }
2415             } finally {
2416                 if (c != null) {
2417                     c.close();
2418                 }
2419             }
2420             return attachedDbs;
2421         } finally {
2422             releaseReference();
2423         }
2424     }
2425 
2426     /**
2427      * Runs 'pragma integrity_check' on the given database (and all the attached databases)
2428      * and returns true if the given database (and all its attached databases) pass integrity_check,
2429      * false otherwise.
2430      *<p>
2431      * If the result is false, then this method logs the errors reported by the integrity_check
2432      * command execution.
2433      *<p>
2434      * Note that 'pragma integrity_check' on a database can take a long time.
2435      *
2436      * @return true if the given database (and all its attached databases) pass integrity_check,
2437      * false otherwise.
2438      */
isDatabaseIntegrityOk()2439     public boolean isDatabaseIntegrityOk() {
2440         acquireReference();
2441         try {
2442             List<Pair<String, String>> attachedDbs = null;
2443             try {
2444                 attachedDbs = getAttachedDbs();
2445                 if (attachedDbs == null) {
2446                     throw new IllegalStateException("databaselist for: " + getPath() + " couldn't " +
2447                             "be retrieved. probably because the database is closed");
2448                 }
2449             } catch (SQLiteException e) {
2450                 // can't get attachedDb list. do integrity check on the main database
2451                 attachedDbs = new ArrayList<Pair<String, String>>();
2452                 attachedDbs.add(new Pair<String, String>("main", getPath()));
2453             }
2454 
2455             for (int i = 0; i < attachedDbs.size(); i++) {
2456                 Pair<String, String> p = attachedDbs.get(i);
2457                 SQLiteStatement prog = null;
2458                 try {
2459                     prog = compileStatement("PRAGMA " + p.first + ".integrity_check(1);");
2460                     String rslt = prog.simpleQueryForString();
2461                     if (!rslt.equalsIgnoreCase("ok")) {
2462                         // integrity_checker failed on main or attached databases
2463                         Log.e(TAG, "PRAGMA integrity_check on " + p.second + " returned: " + rslt);
2464                         return false;
2465                     }
2466                 } finally {
2467                     if (prog != null) prog.close();
2468                 }
2469             }
2470         } finally {
2471             releaseReference();
2472         }
2473         return true;
2474     }
2475 
2476     @Override
toString()2477     public String toString() {
2478         return "SQLiteDatabase: " + getPath();
2479     }
2480 
throwIfNotOpenLocked()2481     private void throwIfNotOpenLocked() {
2482         if (mConnectionPoolLocked == null) {
2483             throw new IllegalStateException("The database '" + mConfigurationLocked.label
2484                     + "' is not open.");
2485         }
2486     }
2487 
2488     /**
2489      * Used to allow returning sub-classes of {@link Cursor} when calling query.
2490      */
2491     public interface CursorFactory {
2492         /**
2493          * See {@link SQLiteCursor#SQLiteCursor(SQLiteCursorDriver, String, SQLiteQuery)}.
2494          */
newCursor(SQLiteDatabase db, SQLiteCursorDriver masterQuery, String editTable, SQLiteQuery query)2495         public Cursor newCursor(SQLiteDatabase db,
2496                 SQLiteCursorDriver masterQuery, String editTable,
2497                 SQLiteQuery query);
2498     }
2499 
2500     /**
2501      * A callback interface for a custom sqlite3 function.
2502      * This can be used to create a function that can be called from
2503      * sqlite3 database triggers.
2504      * @hide
2505      */
2506     public interface CustomFunction {
callback(String[] args)2507         public void callback(String[] args);
2508     }
2509 
2510     /**
2511      * Wrapper for configuration parameters that are used for opening {@link SQLiteDatabase}
2512      */
2513     public static final class OpenParams {
2514         private final int mOpenFlags;
2515         private final CursorFactory mCursorFactory;
2516         private final DatabaseErrorHandler mErrorHandler;
2517         private final int mLookasideSlotSize;
2518         private final int mLookasideSlotCount;
2519         private final long mIdleConnectionTimeout;
2520         private final String mJournalMode;
2521         private final String mSyncMode;
2522 
OpenParams(int openFlags, CursorFactory cursorFactory, DatabaseErrorHandler errorHandler, int lookasideSlotSize, int lookasideSlotCount, long idleConnectionTimeout, String journalMode, String syncMode)2523         private OpenParams(int openFlags, CursorFactory cursorFactory,
2524                 DatabaseErrorHandler errorHandler, int lookasideSlotSize, int lookasideSlotCount,
2525                 long idleConnectionTimeout, String journalMode, String syncMode) {
2526             mOpenFlags = openFlags;
2527             mCursorFactory = cursorFactory;
2528             mErrorHandler = errorHandler;
2529             mLookasideSlotSize = lookasideSlotSize;
2530             mLookasideSlotCount = lookasideSlotCount;
2531             mIdleConnectionTimeout = idleConnectionTimeout;
2532             mJournalMode = journalMode;
2533             mSyncMode = syncMode;
2534         }
2535 
2536         /**
2537          * Returns size in bytes of each lookaside slot or -1 if not set.
2538          *
2539          * @see Builder#setLookasideConfig(int, int)
2540          */
2541         @IntRange(from = -1)
getLookasideSlotSize()2542         public int getLookasideSlotSize() {
2543             return mLookasideSlotSize;
2544         }
2545 
2546         /**
2547          * Returns total number of lookaside memory slots per database connection or -1 if not
2548          * set.
2549          *
2550          * @see Builder#setLookasideConfig(int, int)
2551          */
2552         @IntRange(from = -1)
getLookasideSlotCount()2553         public int getLookasideSlotCount() {
2554             return mLookasideSlotCount;
2555         }
2556 
2557         /**
2558          * Returns flags to control database access mode. Default value is 0.
2559          *
2560          * @see Builder#setOpenFlags(int)
2561          */
2562         @DatabaseOpenFlags
getOpenFlags()2563         public int getOpenFlags() {
2564             return mOpenFlags;
2565         }
2566 
2567         /**
2568          * Returns an optional factory class that is called to instantiate a cursor when query
2569          * is called
2570          *
2571          * @see Builder#setCursorFactory(CursorFactory)
2572          */
2573         @Nullable
getCursorFactory()2574         public CursorFactory getCursorFactory() {
2575             return mCursorFactory;
2576         }
2577 
2578         /**
2579          * Returns handler for database corruption errors
2580          *
2581          * @see Builder#setErrorHandler(DatabaseErrorHandler)
2582          */
2583         @Nullable
getErrorHandler()2584         public DatabaseErrorHandler getErrorHandler() {
2585             return mErrorHandler;
2586         }
2587 
2588         /**
2589          * Returns maximum number of milliseconds that SQLite connection is allowed to be idle
2590          * before it is closed and removed from the pool.
2591          * <p>If the value isn't set, the timeout defaults to the system wide timeout
2592          *
2593          * @return timeout in milliseconds or -1 if the value wasn't set.
2594          */
getIdleConnectionTimeout()2595         public long getIdleConnectionTimeout() {
2596             return mIdleConnectionTimeout;
2597         }
2598 
2599         /**
2600          * Returns <a href="https://sqlite.org/pragma.html#pragma_journal_mode">journal mode</a>.
2601          * This journal mode will only be used if {@link SQLiteDatabase#ENABLE_WRITE_AHEAD_LOGGING}
2602          * flag is not set, otherwise a platform will use "WAL" journal mode.
2603          * @see Builder#setJournalMode(String)
2604          */
2605         @Nullable
getJournalMode()2606         public String getJournalMode() {
2607             return mJournalMode;
2608         }
2609 
2610         /**
2611          * Returns <a href="https://sqlite.org/pragma.html#pragma_synchronous">synchronous mode</a>.
2612          * If not set, a system wide default will be used.
2613          * @see Builder#setSynchronousMode(String)
2614          */
2615         @Nullable
getSynchronousMode()2616         public String getSynchronousMode() {
2617             return mSyncMode;
2618         }
2619 
2620         /**
2621          * Creates a new instance of builder {@link Builder#Builder(OpenParams) initialized} with
2622          * {@code this} parameters.
2623          * @hide
2624          */
2625         @NonNull
toBuilder()2626         public Builder toBuilder() {
2627             return new Builder(this);
2628         }
2629 
2630         /**
2631          * Builder for {@link OpenParams}.
2632          */
2633         public static final class Builder {
2634             private int mLookasideSlotSize = -1;
2635             private int mLookasideSlotCount = -1;
2636             private long mIdleConnectionTimeout = -1;
2637             private int mOpenFlags;
2638             private CursorFactory mCursorFactory;
2639             private DatabaseErrorHandler mErrorHandler;
2640             private String mJournalMode;
2641             private String mSyncMode;
2642 
Builder()2643             public Builder() {
2644             }
2645 
Builder(OpenParams params)2646             public Builder(OpenParams params) {
2647                 mLookasideSlotSize = params.mLookasideSlotSize;
2648                 mLookasideSlotCount = params.mLookasideSlotCount;
2649                 mOpenFlags = params.mOpenFlags;
2650                 mCursorFactory = params.mCursorFactory;
2651                 mErrorHandler = params.mErrorHandler;
2652                 mJournalMode = params.mJournalMode;
2653                 mSyncMode = params.mSyncMode;
2654             }
2655 
2656             /**
2657              * Configures
2658              * <a href="https://sqlite.org/malloc.html#lookaside">lookaside memory allocator</a>
2659              *
2660              * <p>SQLite default settings will be used, if this method isn't called.
2661              * Use {@code setLookasideConfig(0,0)} to disable lookaside
2662              *
2663              * <p><strong>Note:</strong> Provided slotSize/slotCount configuration is just a
2664              * recommendation. The system may choose different values depending on a device, e.g.
2665              * lookaside allocations can be disabled on low-RAM devices
2666              *
2667              * @param slotSize The size in bytes of each lookaside slot.
2668              * @param slotCount The total number of lookaside memory slots per database connection.
2669              */
setLookasideConfig(@ntRangefrom = 0) final int slotSize, @IntRange(from = 0) final int slotCount)2670             public Builder setLookasideConfig(@IntRange(from = 0) final int slotSize,
2671                     @IntRange(from = 0) final int slotCount) {
2672                 Preconditions.checkArgument(slotSize >= 0,
2673                         "lookasideSlotCount cannot be negative");
2674                 Preconditions.checkArgument(slotCount >= 0,
2675                         "lookasideSlotSize cannot be negative");
2676                 Preconditions.checkArgument(
2677                         (slotSize > 0 && slotCount > 0) || (slotCount == 0 && slotSize == 0),
2678                         "Invalid configuration: %d, %d", slotSize, slotCount);
2679 
2680                 mLookasideSlotSize = slotSize;
2681                 mLookasideSlotCount = slotCount;
2682                 return this;
2683             }
2684 
2685             /**
2686              * Returns true if {@link #ENABLE_WRITE_AHEAD_LOGGING} flag is set
2687              * @hide
2688              */
isWriteAheadLoggingEnabled()2689             public boolean isWriteAheadLoggingEnabled() {
2690                 return (mOpenFlags & ENABLE_WRITE_AHEAD_LOGGING) != 0;
2691             }
2692 
2693             /**
2694              * Sets flags to control database access mode
2695              * @param openFlags The new flags to set
2696              * @see #OPEN_READWRITE
2697              * @see #OPEN_READONLY
2698              * @see #CREATE_IF_NECESSARY
2699              * @see #NO_LOCALIZED_COLLATORS
2700              * @see #ENABLE_WRITE_AHEAD_LOGGING
2701              * @return same builder instance for chaining multiple calls into a single statement
2702              */
2703             @NonNull
setOpenFlags(@atabaseOpenFlags int openFlags)2704             public Builder setOpenFlags(@DatabaseOpenFlags int openFlags) {
2705                 mOpenFlags = openFlags;
2706                 return this;
2707             }
2708 
2709             /**
2710              * Adds flags to control database access mode
2711              *
2712              * @param openFlags The new flags to add
2713              * @return same builder instance for chaining multiple calls into a single statement
2714              */
2715             @NonNull
addOpenFlags(@atabaseOpenFlags int openFlags)2716             public Builder addOpenFlags(@DatabaseOpenFlags int openFlags) {
2717                 mOpenFlags |= openFlags;
2718                 return this;
2719             }
2720 
2721             /**
2722              * Removes database access mode flags
2723              *
2724              * @param openFlags Flags to remove
2725              * @return same builder instance for chaining multiple calls into a single statement
2726              */
2727             @NonNull
removeOpenFlags(@atabaseOpenFlags int openFlags)2728             public Builder removeOpenFlags(@DatabaseOpenFlags int openFlags) {
2729                 mOpenFlags &= ~openFlags;
2730                 return this;
2731             }
2732 
2733             /**
2734              * Sets {@link #ENABLE_WRITE_AHEAD_LOGGING} flag if {@code enabled} is {@code true},
2735              * unsets otherwise
2736              * @hide
2737              */
setWriteAheadLoggingEnabled(boolean enabled)2738             public void setWriteAheadLoggingEnabled(boolean enabled) {
2739                 if (enabled) {
2740                     addOpenFlags(ENABLE_WRITE_AHEAD_LOGGING);
2741                 } else {
2742                     removeOpenFlags(ENABLE_WRITE_AHEAD_LOGGING);
2743                 }
2744             }
2745 
2746             /**
2747              * Set an optional factory class that is called to instantiate a cursor when query
2748              * is called.
2749              *
2750              * @param cursorFactory instance
2751              * @return same builder instance for chaining multiple calls into a single statement
2752              */
2753             @NonNull
setCursorFactory(@ullable CursorFactory cursorFactory)2754             public Builder setCursorFactory(@Nullable CursorFactory cursorFactory) {
2755                 mCursorFactory = cursorFactory;
2756                 return this;
2757             }
2758 
2759 
2760             /**
2761              * Sets {@link DatabaseErrorHandler} object to handle db corruption errors
2762              */
2763             @NonNull
setErrorHandler(@ullable DatabaseErrorHandler errorHandler)2764             public Builder setErrorHandler(@Nullable DatabaseErrorHandler errorHandler) {
2765                 mErrorHandler = errorHandler;
2766                 return this;
2767             }
2768 
2769             /**
2770              * Sets the maximum number of milliseconds that SQLite connection is allowed to be idle
2771              * before it is closed and removed from the pool.
2772              *
2773              * <p><b>DO NOT USE</b> this method.
2774              * This feature has negative side effects that are very hard to foresee.
2775              * <p>A connection timeout allows the system to internally close a connection to
2776              * a SQLite database after a given timeout, which is good for reducing app's memory
2777              * consumption.
2778              * <b>However</b> the side effect is it <b>will reset all of SQLite's per-connection
2779              * states</b>, which are typically modified with a {@code PRAGMA} statement, and
2780              * these states <b>will not be restored</b> when a connection is re-established
2781              * internally, and the system does not provide a callback for an app to reconfigure a
2782              * connection.
2783              * This feature may only be used if an app relies on none of such per-connection states.
2784              *
2785              * @param idleConnectionTimeoutMs timeout in milliseconds. Use {@link Long#MAX_VALUE}
2786              * to allow unlimited idle connections.
2787              *
2788              * @see SQLiteOpenHelper#setIdleConnectionTimeout(long)
2789              *
2790              * @deprecated DO NOT USE this method. See the javadoc for the details.
2791              */
2792             @NonNull
2793             @Deprecated
setIdleConnectionTimeout( @ntRangefrom = 0) long idleConnectionTimeoutMs)2794             public Builder setIdleConnectionTimeout(
2795                     @IntRange(from = 0) long idleConnectionTimeoutMs) {
2796                 Preconditions.checkArgument(idleConnectionTimeoutMs >= 0,
2797                         "idle connection timeout cannot be negative");
2798                 mIdleConnectionTimeout = idleConnectionTimeoutMs;
2799                 return this;
2800             }
2801 
2802 
2803             /**
2804              * Sets <a href="https://sqlite.org/pragma.html#pragma_journal_mode">journal mode</a>
2805              * to use when {@link SQLiteDatabase#ENABLE_WRITE_AHEAD_LOGGING} flag is not set.
2806              */
2807             @NonNull
setJournalMode(@onNull String journalMode)2808             public Builder setJournalMode(@NonNull  String journalMode) {
2809                 Objects.requireNonNull(journalMode);
2810                 mJournalMode = journalMode;
2811                 return this;
2812             }
2813 
2814             /**w
2815              * Sets <a href="https://sqlite.org/pragma.html#pragma_synchronous">synchronous mode</a>
2816              * .
2817              * @return
2818              */
2819             @NonNull
setSynchronousMode(@onNull String syncMode)2820             public Builder setSynchronousMode(@NonNull String syncMode) {
2821                 Objects.requireNonNull(syncMode);
2822                 mSyncMode = syncMode;
2823                 return this;
2824             }
2825 
2826             /**
2827              * Creates an instance of {@link OpenParams} with the options that were previously set
2828              * on this builder
2829              */
2830             @NonNull
build()2831             public OpenParams build() {
2832                 return new OpenParams(mOpenFlags, mCursorFactory, mErrorHandler, mLookasideSlotSize,
2833                         mLookasideSlotCount, mIdleConnectionTimeout, mJournalMode, mSyncMode);
2834             }
2835         }
2836     }
2837 
2838     /** @hide */
2839     @IntDef(flag = true, prefix = {"OPEN_", "CREATE_", "NO_", "ENABLE_"}, value = {
2840             OPEN_READWRITE,
2841             OPEN_READONLY,
2842             CREATE_IF_NECESSARY,
2843             NO_LOCALIZED_COLLATORS,
2844             ENABLE_WRITE_AHEAD_LOGGING
2845     })
2846     @Retention(RetentionPolicy.SOURCE)
2847     public @interface DatabaseOpenFlags {}
2848 
2849     /** @hide */
wipeDetected(String filename, String reason)2850     public static void wipeDetected(String filename, String reason) {
2851         wtfAsSystemServer(TAG, "DB wipe detected:"
2852                 + " package=" + ActivityThread.currentPackageName()
2853                 + " reason=" + reason
2854                 + " file=" + filename
2855                 + " " + getFileTimestamps(filename)
2856                 + " checkfile " + getFileTimestamps(filename + SQLiteGlobal.WIPE_CHECK_FILE_SUFFIX),
2857                 new Throwable("STACKTRACE"));
2858     }
2859 
2860     /** @hide */
getFileTimestamps(String path)2861     public static String getFileTimestamps(String path) {
2862         try {
2863             BasicFileAttributes attr = Files.readAttributes(
2864                     FileSystems.getDefault().getPath(path), BasicFileAttributes.class);
2865             return "ctime=" + attr.creationTime()
2866                     + " mtime=" + attr.lastModifiedTime()
2867                     + " atime=" + attr.lastAccessTime();
2868         } catch (IOException e) {
2869             return "[unable to obtain timestamp]";
2870         }
2871     }
2872 
2873     /** @hide */
wtfAsSystemServer(String tag, String message, Throwable stacktrace)2874     static void wtfAsSystemServer(String tag, String message, Throwable stacktrace) {
2875         Log.e(tag, message, stacktrace);
2876         ContentResolver.onDbCorruption(tag, message, stacktrace);
2877     }
2878 }
2879 
2880