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