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