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