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 com.google.android.collect.Maps; 20 21import android.app.ActivityThread; 22import android.app.AppGlobals; 23import android.content.ContentValues; 24import android.database.Cursor; 25import android.database.DatabaseUtils; 26import android.database.SQLException; 27import android.database.sqlite.SQLiteDebug.DbStats; 28import android.os.Debug; 29import android.os.SystemClock; 30import android.os.SystemProperties; 31import android.text.TextUtils; 32import android.util.Config; 33import android.util.EventLog; 34import android.util.Log; 35import android.util.Pair; 36 37import dalvik.system.BlockGuard; 38 39import java.io.File; 40import java.lang.ref.WeakReference; 41import java.text.SimpleDateFormat; 42import java.util.ArrayList; 43import java.util.HashMap; 44import java.util.HashSet; 45import java.util.Iterator; 46import java.util.Locale; 47import java.util.Map; 48import java.util.Random; 49import java.util.Set; 50import java.util.WeakHashMap; 51import java.util.concurrent.locks.ReentrantLock; 52import java.util.regex.Pattern; 53 54/** 55 * Exposes methods to manage a SQLite database. 56 * <p>SQLiteDatabase has methods to create, delete, execute SQL commands, and 57 * perform other common database management tasks. 58 * <p>See the Notepad sample application in the SDK for an example of creating 59 * and managing a database. 60 * <p> Database names must be unique within an application, not across all 61 * applications. 62 * 63 * <h3>Localized Collation - ORDER BY</h3> 64 * <p>In addition to SQLite's default <code>BINARY</code> collator, Android supplies 65 * two more, <code>LOCALIZED</code>, which changes with the system's current locale 66 * if you wire it up correctly (XXX a link needed!), and <code>UNICODE</code>, which 67 * is the Unicode Collation Algorithm and not tailored to the current locale. 68 */ 69public class SQLiteDatabase extends SQLiteClosable { 70 private static final String TAG = "Database"; 71 private static final int EVENT_DB_OPERATION = 52000; 72 private static final int EVENT_DB_CORRUPT = 75004; 73 74 /** 75 * Algorithms used in ON CONFLICT clause 76 * http://www.sqlite.org/lang_conflict.html 77 */ 78 /** 79 * When a constraint violation occurs, an immediate ROLLBACK occurs, 80 * thus ending the current transaction, and the command aborts with a 81 * return code of SQLITE_CONSTRAINT. If no transaction is active 82 * (other than the implied transaction that is created on every command) 83 * then this algorithm works the same as ABORT. 84 */ 85 public static final int CONFLICT_ROLLBACK = 1; 86 87 /** 88 * When a constraint violation occurs,no ROLLBACK is executed 89 * so changes from prior commands within the same transaction 90 * are preserved. This is the default behavior. 91 */ 92 public static final int CONFLICT_ABORT = 2; 93 94 /** 95 * When a constraint violation occurs, the command aborts with a return 96 * code SQLITE_CONSTRAINT. But any changes to the database that 97 * the command made prior to encountering the constraint violation 98 * are preserved and are not backed out. 99 */ 100 public static final int CONFLICT_FAIL = 3; 101 102 /** 103 * When a constraint violation occurs, the one row that contains 104 * the constraint violation is not inserted or changed. 105 * But the command continues executing normally. Other rows before and 106 * after the row that contained the constraint violation continue to be 107 * inserted or updated normally. No error is returned. 108 */ 109 public static final int CONFLICT_IGNORE = 4; 110 111 /** 112 * When a UNIQUE constraint violation occurs, the pre-existing rows that 113 * are causing the constraint violation are removed prior to inserting 114 * or updating the current row. Thus the insert or update always occurs. 115 * The command continues executing normally. No error is returned. 116 * If a NOT NULL constraint violation occurs, the NULL value is replaced 117 * by the default value for that column. If the column has no default 118 * value, then the ABORT algorithm is used. If a CHECK constraint 119 * violation occurs then the IGNORE algorithm is used. When this conflict 120 * resolution strategy deletes rows in order to satisfy a constraint, 121 * it does not invoke delete triggers on those rows. 122 * This behavior might change in a future release. 123 */ 124 public static final int CONFLICT_REPLACE = 5; 125 126 /** 127 * use the following when no conflict action is specified. 128 */ 129 public static final int CONFLICT_NONE = 0; 130 private static final String[] CONFLICT_VALUES = new String[] 131 {"", " OR ROLLBACK ", " OR ABORT ", " OR FAIL ", " OR IGNORE ", " OR REPLACE "}; 132 133 /** 134 * Maximum Length Of A LIKE Or GLOB Pattern 135 * The pattern matching algorithm used in the default LIKE and GLOB implementation 136 * of SQLite can exhibit O(N^2) performance (where N is the number of characters in 137 * the pattern) for certain pathological cases. To avoid denial-of-service attacks 138 * the length of the LIKE or GLOB pattern is limited to SQLITE_MAX_LIKE_PATTERN_LENGTH bytes. 139 * The default value of this limit is 50000. A modern workstation can evaluate 140 * even a pathological LIKE or GLOB pattern of 50000 bytes relatively quickly. 141 * The denial of service problem only comes into play when the pattern length gets 142 * into millions of bytes. Nevertheless, since most useful LIKE or GLOB patterns 143 * are at most a few dozen bytes in length, paranoid application developers may 144 * want to reduce this parameter to something in the range of a few hundred 145 * if they know that external users are able to generate arbitrary patterns. 146 */ 147 public static final int SQLITE_MAX_LIKE_PATTERN_LENGTH = 50000; 148 149 /** 150 * Flag for {@link #openDatabase} to open the database for reading and writing. 151 * If the disk is full, this may fail even before you actually write anything. 152 * 153 * {@more} Note that the value of this flag is 0, so it is the default. 154 */ 155 public static final int OPEN_READWRITE = 0x00000000; // update native code if changing 156 157 /** 158 * Flag for {@link #openDatabase} to open the database for reading only. 159 * This is the only reliable way to open a database if the disk may be full. 160 */ 161 public static final int OPEN_READONLY = 0x00000001; // update native code if changing 162 163 private static final int OPEN_READ_MASK = 0x00000001; // update native code if changing 164 165 /** 166 * Flag for {@link #openDatabase} to open the database without support for localized collators. 167 * 168 * {@more} This causes the collator <code>LOCALIZED</code> not to be created. 169 * You must be consistent when using this flag to use the setting the database was 170 * created with. If this is set, {@link #setLocale} will do nothing. 171 */ 172 public static final int NO_LOCALIZED_COLLATORS = 0x00000010; // update native code if changing 173 174 /** 175 * Flag for {@link #openDatabase} to create the database file if it does not already exist. 176 */ 177 public static final int CREATE_IF_NECESSARY = 0x10000000; // update native code if changing 178 179 /** 180 * Indicates whether the most-recently started transaction has been marked as successful. 181 */ 182 private boolean mInnerTransactionIsSuccessful; 183 184 /** 185 * Valid during the life of a transaction, and indicates whether the entire transaction (the 186 * outer one and all of the inner ones) so far has been successful. 187 */ 188 private boolean mTransactionIsSuccessful; 189 190 /** 191 * Valid during the life of a transaction. 192 */ 193 private SQLiteTransactionListener mTransactionListener; 194 195 /** Synchronize on this when accessing the database */ 196 private final ReentrantLock mLock = new ReentrantLock(true); 197 198 private long mLockAcquiredWallTime = 0L; 199 private long mLockAcquiredThreadTime = 0L; 200 201 // limit the frequency of complaints about each database to one within 20 sec 202 // unless run command adb shell setprop log.tag.Database VERBOSE 203 private static final int LOCK_WARNING_WINDOW_IN_MS = 20000; 204 /** If the lock is held this long then a warning will be printed when it is released. */ 205 private static final int LOCK_ACQUIRED_WARNING_TIME_IN_MS = 300; 206 private static final int LOCK_ACQUIRED_WARNING_THREAD_TIME_IN_MS = 100; 207 private static final int LOCK_ACQUIRED_WARNING_TIME_IN_MS_ALWAYS_PRINT = 2000; 208 209 private static final int SLEEP_AFTER_YIELD_QUANTUM = 1000; 210 211 // The pattern we remove from database filenames before 212 // potentially logging them. 213 private static final Pattern EMAIL_IN_DB_PATTERN = Pattern.compile("[\\w\\.\\-]+@[\\w\\.\\-]+"); 214 215 private long mLastLockMessageTime = 0L; 216 217 // Things related to query logging/sampling for debugging 218 // slow/frequent queries during development. Always log queries 219 // which take (by default) 500ms+; shorter queries are sampled 220 // accordingly. Commit statements, which are typically slow, are 221 // logged together with the most recently executed SQL statement, 222 // for disambiguation. The 500ms value is configurable via a 223 // SystemProperty, but developers actively debugging database I/O 224 // should probably use the regular log tunable, 225 // LOG_SLOW_QUERIES_PROPERTY, defined below. 226 private static int sQueryLogTimeInMillis = 0; // lazily initialized 227 private static final int QUERY_LOG_SQL_LENGTH = 64; 228 private static final String COMMIT_SQL = "COMMIT;"; 229 private final Random mRandom = new Random(); 230 private String mLastSqlStatement = null; 231 232 // String prefix for slow database query EventLog records that show 233 // lock acquistions of the database. 234 /* package */ static final String GET_LOCK_LOG_PREFIX = "GETLOCK:"; 235 236 /** Used by native code, do not rename */ 237 /* package */ int mNativeHandle = 0; 238 239 /** Used to make temp table names unique */ 240 /* package */ int mTempTableSequence = 0; 241 242 /** The path for the database file */ 243 private String mPath; 244 245 /** The anonymized path for the database file for logging purposes */ 246 private String mPathForLogs = null; // lazily populated 247 248 /** The flags passed to open/create */ 249 private int mFlags; 250 251 /** The optional factory to use when creating new Cursors */ 252 private CursorFactory mFactory; 253 254 private WeakHashMap<SQLiteClosable, Object> mPrograms; 255 256 /** 257 * for each instance of this class, a cache is maintained to store 258 * the compiled query statement ids returned by sqlite database. 259 * key = sql statement with "?" for bind args 260 * value = {@link SQLiteCompiledSql} 261 * If an application opens the database and keeps it open during its entire life, then 262 * there will not be an overhead of compilation of sql statements by sqlite. 263 * 264 * why is this cache NOT static? because sqlite attaches compiledsql statements to the 265 * struct created when {@link SQLiteDatabase#openDatabase(String, CursorFactory, int)} is 266 * invoked. 267 * 268 * this cache has an upper limit of mMaxSqlCacheSize (settable by calling the method 269 * (@link setMaxCacheSize(int)}). its default is 0 - i.e., no caching by default because 270 * most of the apps don't use "?" syntax in their sql, caching is not useful for them. 271 */ 272 /* package */ Map<String, SQLiteCompiledSql> mCompiledQueries = Maps.newHashMap(); 273 /** 274 * @hide 275 */ 276 public static final int MAX_SQL_CACHE_SIZE = 250; 277 private int mMaxSqlCacheSize = MAX_SQL_CACHE_SIZE; // max cache size per Database instance 278 private int mCacheFullWarnings; 279 private static final int MAX_WARNINGS_ON_CACHESIZE_CONDITION = 1; 280 281 /** maintain stats about number of cache hits and misses */ 282 private int mNumCacheHits; 283 private int mNumCacheMisses; 284 285 /** the following 2 members maintain the time when a database is opened and closed */ 286 private String mTimeOpened = null; 287 private String mTimeClosed = null; 288 289 /** Used to find out where this object was created in case it never got closed. */ 290 private Throwable mStackTrace = null; 291 292 // System property that enables logging of slow queries. Specify the threshold in ms. 293 private static final String LOG_SLOW_QUERIES_PROPERTY = "db.log.slow_query_threshold"; 294 private final int mSlowQueryThreshold; 295 296 /** 297 * @param closable 298 */ 299 void addSQLiteClosable(SQLiteClosable closable) { 300 lock(); 301 try { 302 mPrograms.put(closable, null); 303 } finally { 304 unlock(); 305 } 306 } 307 308 void removeSQLiteClosable(SQLiteClosable closable) { 309 lock(); 310 try { 311 mPrograms.remove(closable); 312 } finally { 313 unlock(); 314 } 315 } 316 317 @Override 318 protected void onAllReferencesReleased() { 319 if (isOpen()) { 320 if (SQLiteDebug.DEBUG_SQL_CACHE) { 321 mTimeClosed = getTime(); 322 } 323 dbclose(); 324 } 325 } 326 327 /** 328 * Attempts to release memory that SQLite holds but does not require to 329 * operate properly. Typically this memory will come from the page cache. 330 * 331 * @return the number of bytes actually released 332 */ 333 static public native int releaseMemory(); 334 335 /** 336 * Control whether or not the SQLiteDatabase is made thread-safe by using locks 337 * around critical sections. This is pretty expensive, so if you know that your 338 * DB will only be used by a single thread then you should set this to false. 339 * The default is true. 340 * @param lockingEnabled set to true to enable locks, false otherwise 341 */ 342 public void setLockingEnabled(boolean lockingEnabled) { 343 mLockingEnabled = lockingEnabled; 344 } 345 346 /** 347 * If set then the SQLiteDatabase is made thread-safe by using locks 348 * around critical sections 349 */ 350 private boolean mLockingEnabled = true; 351 352 /* package */ void onCorruption() { 353 Log.e(TAG, "Removing corrupt database: " + mPath); 354 EventLog.writeEvent(EVENT_DB_CORRUPT, mPath); 355 try { 356 // Close the database (if we can), which will cause subsequent operations to fail. 357 close(); 358 } finally { 359 // Delete the corrupt file. Don't re-create it now -- that would just confuse people 360 // -- but the next time someone tries to open it, they can set it up from scratch. 361 if (!mPath.equalsIgnoreCase(":memory")) { 362 // delete is only for non-memory database files 363 new File(mPath).delete(); 364 } 365 } 366 } 367 368 /** 369 * Locks the database for exclusive access. The database lock must be held when 370 * touch the native sqlite3* object since it is single threaded and uses 371 * a polling lock contention algorithm. The lock is recursive, and may be acquired 372 * multiple times by the same thread. This is a no-op if mLockingEnabled is false. 373 * 374 * @see #unlock() 375 */ 376 /* package */ void lock() { 377 if (!mLockingEnabled) return; 378 mLock.lock(); 379 if (SQLiteDebug.DEBUG_LOCK_TIME_TRACKING) { 380 if (mLock.getHoldCount() == 1) { 381 // Use elapsed real-time since the CPU may sleep when waiting for IO 382 mLockAcquiredWallTime = SystemClock.elapsedRealtime(); 383 mLockAcquiredThreadTime = Debug.threadCpuTimeNanos(); 384 } 385 } 386 } 387 388 /** 389 * Locks the database for exclusive access. The database lock must be held when 390 * touch the native sqlite3* object since it is single threaded and uses 391 * a polling lock contention algorithm. The lock is recursive, and may be acquired 392 * multiple times by the same thread. 393 * 394 * @see #unlockForced() 395 */ 396 private void lockForced() { 397 mLock.lock(); 398 if (SQLiteDebug.DEBUG_LOCK_TIME_TRACKING) { 399 if (mLock.getHoldCount() == 1) { 400 // Use elapsed real-time since the CPU may sleep when waiting for IO 401 mLockAcquiredWallTime = SystemClock.elapsedRealtime(); 402 mLockAcquiredThreadTime = Debug.threadCpuTimeNanos(); 403 } 404 } 405 } 406 407 /** 408 * Releases the database lock. This is a no-op if mLockingEnabled is false. 409 * 410 * @see #unlock() 411 */ 412 /* package */ void unlock() { 413 if (!mLockingEnabled) return; 414 if (SQLiteDebug.DEBUG_LOCK_TIME_TRACKING) { 415 if (mLock.getHoldCount() == 1) { 416 checkLockHoldTime(); 417 } 418 } 419 mLock.unlock(); 420 } 421 422 /** 423 * Releases the database lock. 424 * 425 * @see #unlockForced() 426 */ 427 private void unlockForced() { 428 if (SQLiteDebug.DEBUG_LOCK_TIME_TRACKING) { 429 if (mLock.getHoldCount() == 1) { 430 checkLockHoldTime(); 431 } 432 } 433 mLock.unlock(); 434 } 435 436 private void checkLockHoldTime() { 437 // Use elapsed real-time since the CPU may sleep when waiting for IO 438 long elapsedTime = SystemClock.elapsedRealtime(); 439 long lockedTime = elapsedTime - mLockAcquiredWallTime; 440 if (lockedTime < LOCK_ACQUIRED_WARNING_TIME_IN_MS_ALWAYS_PRINT && 441 !Log.isLoggable(TAG, Log.VERBOSE) && 442 (elapsedTime - mLastLockMessageTime) < LOCK_WARNING_WINDOW_IN_MS) { 443 return; 444 } 445 if (lockedTime > LOCK_ACQUIRED_WARNING_TIME_IN_MS) { 446 int threadTime = (int) 447 ((Debug.threadCpuTimeNanos() - mLockAcquiredThreadTime) / 1000000); 448 if (threadTime > LOCK_ACQUIRED_WARNING_THREAD_TIME_IN_MS || 449 lockedTime > LOCK_ACQUIRED_WARNING_TIME_IN_MS_ALWAYS_PRINT) { 450 mLastLockMessageTime = elapsedTime; 451 String msg = "lock held on " + mPath + " for " + lockedTime + "ms. Thread time was " 452 + threadTime + "ms"; 453 if (SQLiteDebug.DEBUG_LOCK_TIME_TRACKING_STACK_TRACE) { 454 Log.d(TAG, msg, new Exception()); 455 } else { 456 Log.d(TAG, msg); 457 } 458 } 459 } 460 } 461 462 /** 463 * Begins a transaction. Transactions can be nested. When the outer transaction is ended all of 464 * the work done in that transaction and all of the nested transactions will be committed or 465 * rolled back. The changes will be rolled back if any transaction is ended without being 466 * marked as clean (by calling setTransactionSuccessful). Otherwise they will be committed. 467 * 468 * <p>Here is the standard idiom for transactions: 469 * 470 * <pre> 471 * db.beginTransaction(); 472 * try { 473 * ... 474 * db.setTransactionSuccessful(); 475 * } finally { 476 * db.endTransaction(); 477 * } 478 * </pre> 479 */ 480 public void beginTransaction() { 481 beginTransactionWithListener(null /* transactionStatusCallback */); 482 } 483 484 /** 485 * Begins a transaction. Transactions can be nested. When the outer transaction is ended all of 486 * the work done in that transaction and all of the nested transactions will be committed or 487 * rolled back. The changes will be rolled back if any transaction is ended without being 488 * marked as clean (by calling setTransactionSuccessful). Otherwise they will be committed. 489 * 490 * <p>Here is the standard idiom for transactions: 491 * 492 * <pre> 493 * db.beginTransactionWithListener(listener); 494 * try { 495 * ... 496 * db.setTransactionSuccessful(); 497 * } finally { 498 * db.endTransaction(); 499 * } 500 * </pre> 501 * @param transactionListener listener that should be notified when the transaction begins, 502 * commits, or is rolled back, either explicitly or by a call to 503 * {@link #yieldIfContendedSafely}. 504 */ 505 public void beginTransactionWithListener(SQLiteTransactionListener transactionListener) { 506 lockForced(); 507 if (!isOpen()) { 508 throw new IllegalStateException("database not open"); 509 } 510 boolean ok = false; 511 try { 512 // If this thread already had the lock then get out 513 if (mLock.getHoldCount() > 1) { 514 if (mInnerTransactionIsSuccessful) { 515 String msg = "Cannot call beginTransaction between " 516 + "calling setTransactionSuccessful and endTransaction"; 517 IllegalStateException e = new IllegalStateException(msg); 518 Log.e(TAG, "beginTransaction() failed", e); 519 throw e; 520 } 521 ok = true; 522 return; 523 } 524 525 // This thread didn't already have the lock, so begin a database 526 // transaction now. 527 execSQL("BEGIN EXCLUSIVE;"); 528 mTransactionListener = transactionListener; 529 mTransactionIsSuccessful = true; 530 mInnerTransactionIsSuccessful = false; 531 if (transactionListener != null) { 532 try { 533 transactionListener.onBegin(); 534 } catch (RuntimeException e) { 535 execSQL("ROLLBACK;"); 536 throw e; 537 } 538 } 539 ok = true; 540 } finally { 541 if (!ok) { 542 // beginTransaction is called before the try block so we must release the lock in 543 // the case of failure. 544 unlockForced(); 545 } 546 } 547 } 548 549 /** 550 * End a transaction. See beginTransaction for notes about how to use this and when transactions 551 * are committed and rolled back. 552 */ 553 public void endTransaction() { 554 if (!isOpen()) { 555 throw new IllegalStateException("database not open"); 556 } 557 if (!mLock.isHeldByCurrentThread()) { 558 throw new IllegalStateException("no transaction pending"); 559 } 560 try { 561 if (mInnerTransactionIsSuccessful) { 562 mInnerTransactionIsSuccessful = false; 563 } else { 564 mTransactionIsSuccessful = false; 565 } 566 if (mLock.getHoldCount() != 1) { 567 return; 568 } 569 RuntimeException savedException = null; 570 if (mTransactionListener != null) { 571 try { 572 if (mTransactionIsSuccessful) { 573 mTransactionListener.onCommit(); 574 } else { 575 mTransactionListener.onRollback(); 576 } 577 } catch (RuntimeException e) { 578 savedException = e; 579 mTransactionIsSuccessful = false; 580 } 581 } 582 if (mTransactionIsSuccessful) { 583 execSQL(COMMIT_SQL); 584 } else { 585 try { 586 execSQL("ROLLBACK;"); 587 if (savedException != null) { 588 throw savedException; 589 } 590 } catch (SQLException e) { 591 if (Config.LOGD) { 592 Log.d(TAG, "exception during rollback, maybe the DB previously " 593 + "performed an auto-rollback"); 594 } 595 } 596 } 597 } finally { 598 mTransactionListener = null; 599 unlockForced(); 600 if (Config.LOGV) { 601 Log.v(TAG, "unlocked " + Thread.currentThread() 602 + ", holdCount is " + mLock.getHoldCount()); 603 } 604 } 605 } 606 607 /** 608 * Marks the current transaction as successful. Do not do any more database work between 609 * calling this and calling endTransaction. Do as little non-database work as possible in that 610 * situation too. If any errors are encountered between this and endTransaction the transaction 611 * will still be committed. 612 * 613 * @throws IllegalStateException if the current thread is not in a transaction or the 614 * transaction is already marked as successful. 615 */ 616 public void setTransactionSuccessful() { 617 if (!isOpen()) { 618 throw new IllegalStateException("database not open"); 619 } 620 if (!mLock.isHeldByCurrentThread()) { 621 throw new IllegalStateException("no transaction pending"); 622 } 623 if (mInnerTransactionIsSuccessful) { 624 throw new IllegalStateException( 625 "setTransactionSuccessful may only be called once per call to beginTransaction"); 626 } 627 mInnerTransactionIsSuccessful = true; 628 } 629 630 /** 631 * return true if there is a transaction pending 632 */ 633 public boolean inTransaction() { 634 return mLock.getHoldCount() > 0; 635 } 636 637 /** 638 * Checks if the database lock is held by this thread. 639 * 640 * @return true, if this thread is holding the database lock. 641 */ 642 public boolean isDbLockedByCurrentThread() { 643 return mLock.isHeldByCurrentThread(); 644 } 645 646 /** 647 * Checks if the database is locked by another thread. This is 648 * just an estimate, since this status can change at any time, 649 * including after the call is made but before the result has 650 * been acted upon. 651 * 652 * @return true, if the database is locked by another thread 653 */ 654 public boolean isDbLockedByOtherThreads() { 655 return !mLock.isHeldByCurrentThread() && mLock.isLocked(); 656 } 657 658 /** 659 * Temporarily end the transaction to let other threads run. The transaction is assumed to be 660 * successful so far. Do not call setTransactionSuccessful before calling this. When this 661 * returns a new transaction will have been created but not marked as successful. 662 * @return true if the transaction was yielded 663 * @deprecated if the db is locked more than once (becuase of nested transactions) then the lock 664 * will not be yielded. Use yieldIfContendedSafely instead. 665 */ 666 @Deprecated 667 public boolean yieldIfContended() { 668 return yieldIfContendedHelper(false /* do not check yielding */, 669 -1 /* sleepAfterYieldDelay */); 670 } 671 672 /** 673 * Temporarily end the transaction to let other threads run. The transaction is assumed to be 674 * successful so far. Do not call setTransactionSuccessful before calling this. When this 675 * returns a new transaction will have been created but not marked as successful. This assumes 676 * that there are no nested transactions (beginTransaction has only been called once) and will 677 * throw an exception if that is not the case. 678 * @return true if the transaction was yielded 679 */ 680 public boolean yieldIfContendedSafely() { 681 return yieldIfContendedHelper(true /* check yielding */, -1 /* sleepAfterYieldDelay*/); 682 } 683 684 /** 685 * Temporarily end the transaction to let other threads run. The transaction is assumed to be 686 * successful so far. Do not call setTransactionSuccessful before calling this. When this 687 * returns a new transaction will have been created but not marked as successful. This assumes 688 * that there are no nested transactions (beginTransaction has only been called once) and will 689 * throw an exception if that is not the case. 690 * @param sleepAfterYieldDelay if > 0, sleep this long before starting a new transaction if 691 * the lock was actually yielded. This will allow other background threads to make some 692 * more progress than they would if we started the transaction immediately. 693 * @return true if the transaction was yielded 694 */ 695 public boolean yieldIfContendedSafely(long sleepAfterYieldDelay) { 696 return yieldIfContendedHelper(true /* check yielding */, sleepAfterYieldDelay); 697 } 698 699 private boolean yieldIfContendedHelper(boolean checkFullyYielded, long sleepAfterYieldDelay) { 700 if (mLock.getQueueLength() == 0) { 701 // Reset the lock acquire time since we know that the thread was willing to yield 702 // the lock at this time. 703 mLockAcquiredWallTime = SystemClock.elapsedRealtime(); 704 mLockAcquiredThreadTime = Debug.threadCpuTimeNanos(); 705 return false; 706 } 707 setTransactionSuccessful(); 708 SQLiteTransactionListener transactionListener = mTransactionListener; 709 endTransaction(); 710 if (checkFullyYielded) { 711 if (this.isDbLockedByCurrentThread()) { 712 throw new IllegalStateException( 713 "Db locked more than once. yielfIfContended cannot yield"); 714 } 715 } 716 if (sleepAfterYieldDelay > 0) { 717 // Sleep for up to sleepAfterYieldDelay milliseconds, waking up periodically to 718 // check if anyone is using the database. If the database is not contended, 719 // retake the lock and return. 720 long remainingDelay = sleepAfterYieldDelay; 721 while (remainingDelay > 0) { 722 try { 723 Thread.sleep(remainingDelay < SLEEP_AFTER_YIELD_QUANTUM ? 724 remainingDelay : SLEEP_AFTER_YIELD_QUANTUM); 725 } catch (InterruptedException e) { 726 Thread.interrupted(); 727 } 728 remainingDelay -= SLEEP_AFTER_YIELD_QUANTUM; 729 if (mLock.getQueueLength() == 0) { 730 break; 731 } 732 } 733 } 734 beginTransactionWithListener(transactionListener); 735 return true; 736 } 737 738 /** Maps table names to info about what to which _sync_time column to set 739 * to NULL on an update. This is used to support syncing. */ 740 private final Map<String, SyncUpdateInfo> mSyncUpdateInfo = 741 new HashMap<String, SyncUpdateInfo>(); 742 743 public Map<String, String> getSyncedTables() { 744 synchronized(mSyncUpdateInfo) { 745 HashMap<String, String> tables = new HashMap<String, String>(); 746 for (String table : mSyncUpdateInfo.keySet()) { 747 SyncUpdateInfo info = mSyncUpdateInfo.get(table); 748 if (info.deletedTable != null) { 749 tables.put(table, info.deletedTable); 750 } 751 } 752 return tables; 753 } 754 } 755 756 /** 757 * Internal class used to keep track what needs to be marked as changed 758 * when an update occurs. This is used for syncing, so the sync engine 759 * knows what data has been updated locally. 760 */ 761 static private class SyncUpdateInfo { 762 /** 763 * Creates the SyncUpdateInfo class. 764 * 765 * @param masterTable The table to set _sync_time to NULL in 766 * @param deletedTable The deleted table that corresponds to the 767 * master table 768 * @param foreignKey The key that refers to the primary key in table 769 */ 770 SyncUpdateInfo(String masterTable, String deletedTable, 771 String foreignKey) { 772 this.masterTable = masterTable; 773 this.deletedTable = deletedTable; 774 this.foreignKey = foreignKey; 775 } 776 777 /** The table containing the _sync_time column */ 778 String masterTable; 779 780 /** The deleted table that corresponds to the master table */ 781 String deletedTable; 782 783 /** The key in the local table the row in table. It may be _id, if table 784 * is the local table. */ 785 String foreignKey; 786 } 787 788 /** 789 * Used to allow returning sub-classes of {@link Cursor} when calling query. 790 */ 791 public interface CursorFactory { 792 /** 793 * See 794 * {@link SQLiteCursor#SQLiteCursor(SQLiteDatabase, SQLiteCursorDriver, 795 * String, SQLiteQuery)}. 796 */ 797 public Cursor newCursor(SQLiteDatabase db, 798 SQLiteCursorDriver masterQuery, String editTable, 799 SQLiteQuery query); 800 } 801 802 /** 803 * Open the database according to the flags {@link #OPEN_READWRITE} 804 * {@link #OPEN_READONLY} {@link #CREATE_IF_NECESSARY} and/or {@link #NO_LOCALIZED_COLLATORS}. 805 * 806 * <p>Sets the locale of the database to the the system's current locale. 807 * Call {@link #setLocale} if you would like something else.</p> 808 * 809 * @param path to database file to open and/or create 810 * @param factory an optional factory class that is called to instantiate a 811 * cursor when query is called, or null for default 812 * @param flags to control database access mode 813 * @return the newly opened database 814 * @throws SQLiteException if the database cannot be opened 815 */ 816 public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags) { 817 SQLiteDatabase sqliteDatabase = null; 818 try { 819 // Open the database. 820 sqliteDatabase = new SQLiteDatabase(path, factory, flags); 821 if (SQLiteDebug.DEBUG_SQL_STATEMENTS) { 822 sqliteDatabase.enableSqlTracing(path); 823 } 824 if (SQLiteDebug.DEBUG_SQL_TIME) { 825 sqliteDatabase.enableSqlProfiling(path); 826 } 827 } catch (SQLiteDatabaseCorruptException e) { 828 // Try to recover from this, if we can. 829 // TODO: should we do this for other open failures? 830 Log.e(TAG, "Deleting and re-creating corrupt database " + path, e); 831 EventLog.writeEvent(EVENT_DB_CORRUPT, path); 832 if (!path.equalsIgnoreCase(":memory")) { 833 // delete is only for non-memory database files 834 new File(path).delete(); 835 } 836 sqliteDatabase = new SQLiteDatabase(path, factory, flags); 837 } 838 ActiveDatabases.getInstance().mActiveDatabases.add( 839 new WeakReference<SQLiteDatabase>(sqliteDatabase)); 840 return sqliteDatabase; 841 } 842 843 /** 844 * Equivalent to openDatabase(file.getPath(), factory, CREATE_IF_NECESSARY). 845 */ 846 public static SQLiteDatabase openOrCreateDatabase(File file, CursorFactory factory) { 847 return openOrCreateDatabase(file.getPath(), factory); 848 } 849 850 /** 851 * Equivalent to openDatabase(path, factory, CREATE_IF_NECESSARY). 852 */ 853 public static SQLiteDatabase openOrCreateDatabase(String path, CursorFactory factory) { 854 return openDatabase(path, factory, CREATE_IF_NECESSARY); 855 } 856 857 /** 858 * Create a memory backed SQLite database. Its contents will be destroyed 859 * when the database is closed. 860 * 861 * <p>Sets the locale of the database to the the system's current locale. 862 * Call {@link #setLocale} if you would like something else.</p> 863 * 864 * @param factory an optional factory class that is called to instantiate a 865 * cursor when query is called 866 * @return a SQLiteDatabase object, or null if the database can't be created 867 */ 868 public static SQLiteDatabase create(CursorFactory factory) { 869 // This is a magic string with special meaning for SQLite. 870 return openDatabase(":memory:", factory, CREATE_IF_NECESSARY); 871 } 872 873 /** 874 * Close the database. 875 */ 876 public void close() { 877 if (!isOpen()) { 878 return; // already closed 879 } 880 lock(); 881 try { 882 closeClosable(); 883 // close this database instance - regardless of its reference count value 884 onAllReferencesReleased(); 885 } finally { 886 unlock(); 887 } 888 } 889 890 private void closeClosable() { 891 /* deallocate all compiled sql statement objects from mCompiledQueries cache. 892 * this should be done before de-referencing all {@link SQLiteClosable} objects 893 * from this database object because calling 894 * {@link SQLiteClosable#onAllReferencesReleasedFromContainer()} could cause the database 895 * to be closed. sqlite doesn't let a database close if there are 896 * any unfinalized statements - such as the compiled-sql objects in mCompiledQueries. 897 */ 898 deallocCachedSqlStatements(); 899 900 Iterator<Map.Entry<SQLiteClosable, Object>> iter = mPrograms.entrySet().iterator(); 901 while (iter.hasNext()) { 902 Map.Entry<SQLiteClosable, Object> entry = iter.next(); 903 SQLiteClosable program = entry.getKey(); 904 if (program != null) { 905 program.onAllReferencesReleasedFromContainer(); 906 } 907 } 908 } 909 910 /** 911 * Native call to close the database. 912 */ 913 private native void dbclose(); 914 915 /** 916 * Gets the database version. 917 * 918 * @return the database version 919 */ 920 public int getVersion() { 921 SQLiteStatement prog = null; 922 lock(); 923 if (!isOpen()) { 924 throw new IllegalStateException("database not open"); 925 } 926 try { 927 prog = new SQLiteStatement(this, "PRAGMA user_version;"); 928 long version = prog.simpleQueryForLong(); 929 return (int) version; 930 } finally { 931 if (prog != null) prog.close(); 932 unlock(); 933 } 934 } 935 936 /** 937 * Sets the database version. 938 * 939 * @param version the new database version 940 */ 941 public void setVersion(int version) { 942 execSQL("PRAGMA user_version = " + version); 943 } 944 945 /** 946 * Returns the maximum size the database may grow to. 947 * 948 * @return the new maximum database size 949 */ 950 public long getMaximumSize() { 951 SQLiteStatement prog = null; 952 lock(); 953 if (!isOpen()) { 954 throw new IllegalStateException("database not open"); 955 } 956 try { 957 prog = new SQLiteStatement(this, 958 "PRAGMA max_page_count;"); 959 long pageCount = prog.simpleQueryForLong(); 960 return pageCount * getPageSize(); 961 } finally { 962 if (prog != null) prog.close(); 963 unlock(); 964 } 965 } 966 967 /** 968 * Sets the maximum size the database will grow to. The maximum size cannot 969 * be set below the current size. 970 * 971 * @param numBytes the maximum database size, in bytes 972 * @return the new maximum database size 973 */ 974 public long setMaximumSize(long numBytes) { 975 SQLiteStatement prog = null; 976 lock(); 977 if (!isOpen()) { 978 throw new IllegalStateException("database not open"); 979 } 980 try { 981 long pageSize = getPageSize(); 982 long numPages = numBytes / pageSize; 983 // If numBytes isn't a multiple of pageSize, bump up a page 984 if ((numBytes % pageSize) != 0) { 985 numPages++; 986 } 987 prog = new SQLiteStatement(this, 988 "PRAGMA max_page_count = " + numPages); 989 long newPageCount = prog.simpleQueryForLong(); 990 return newPageCount * pageSize; 991 } finally { 992 if (prog != null) prog.close(); 993 unlock(); 994 } 995 } 996 997 /** 998 * Returns the current database page size, in bytes. 999 * 1000 * @return the database page size, in bytes 1001 */ 1002 public long getPageSize() { 1003 SQLiteStatement prog = null; 1004 lock(); 1005 if (!isOpen()) { 1006 throw new IllegalStateException("database not open"); 1007 } 1008 try { 1009 prog = new SQLiteStatement(this, 1010 "PRAGMA page_size;"); 1011 long size = prog.simpleQueryForLong(); 1012 return size; 1013 } finally { 1014 if (prog != null) prog.close(); 1015 unlock(); 1016 } 1017 } 1018 1019 /** 1020 * Sets the database page size. The page size must be a power of two. This 1021 * method does not work if any data has been written to the database file, 1022 * and must be called right after the database has been created. 1023 * 1024 * @param numBytes the database page size, in bytes 1025 */ 1026 public void setPageSize(long numBytes) { 1027 execSQL("PRAGMA page_size = " + numBytes); 1028 } 1029 1030 /** 1031 * Mark this table as syncable. When an update occurs in this table the 1032 * _sync_dirty field will be set to ensure proper syncing operation. 1033 * 1034 * @param table the table to mark as syncable 1035 * @param deletedTable The deleted table that corresponds to the 1036 * syncable table 1037 */ 1038 public void markTableSyncable(String table, String deletedTable) { 1039 markTableSyncable(table, "_id", table, deletedTable); 1040 } 1041 1042 /** 1043 * Mark this table as syncable, with the _sync_dirty residing in another 1044 * table. When an update occurs in this table the _sync_dirty field of the 1045 * row in updateTable with the _id in foreignKey will be set to 1046 * ensure proper syncing operation. 1047 * 1048 * @param table an update on this table will trigger a sync time removal 1049 * @param foreignKey this is the column in table whose value is an _id in 1050 * updateTable 1051 * @param updateTable this is the table that will have its _sync_dirty 1052 */ 1053 public void markTableSyncable(String table, String foreignKey, 1054 String updateTable) { 1055 markTableSyncable(table, foreignKey, updateTable, null); 1056 } 1057 1058 /** 1059 * Mark this table as syncable, with the _sync_dirty residing in another 1060 * table. When an update occurs in this table the _sync_dirty field of the 1061 * row in updateTable with the _id in foreignKey will be set to 1062 * ensure proper syncing operation. 1063 * 1064 * @param table an update on this table will trigger a sync time removal 1065 * @param foreignKey this is the column in table whose value is an _id in 1066 * updateTable 1067 * @param updateTable this is the table that will have its _sync_dirty 1068 * @param deletedTable The deleted table that corresponds to the 1069 * updateTable 1070 */ 1071 private void markTableSyncable(String table, String foreignKey, 1072 String updateTable, String deletedTable) { 1073 lock(); 1074 try { 1075 native_execSQL("SELECT _sync_dirty FROM " + updateTable 1076 + " LIMIT 0"); 1077 native_execSQL("SELECT " + foreignKey + " FROM " + table 1078 + " LIMIT 0"); 1079 } finally { 1080 unlock(); 1081 } 1082 1083 SyncUpdateInfo info = new SyncUpdateInfo(updateTable, deletedTable, 1084 foreignKey); 1085 synchronized (mSyncUpdateInfo) { 1086 mSyncUpdateInfo.put(table, info); 1087 } 1088 } 1089 1090 /** 1091 * Call for each row that is updated in a cursor. 1092 * 1093 * @param table the table the row is in 1094 * @param rowId the row ID of the updated row 1095 */ 1096 /* package */ void rowUpdated(String table, long rowId) { 1097 SyncUpdateInfo info; 1098 synchronized (mSyncUpdateInfo) { 1099 info = mSyncUpdateInfo.get(table); 1100 } 1101 if (info != null) { 1102 execSQL("UPDATE " + info.masterTable 1103 + " SET _sync_dirty=1 WHERE _id=(SELECT " + info.foreignKey 1104 + " FROM " + table + " WHERE _id=" + rowId + ")"); 1105 } 1106 } 1107 1108 /** 1109 * Finds the name of the first table, which is editable. 1110 * 1111 * @param tables a list of tables 1112 * @return the first table listed 1113 */ 1114 public static String findEditTable(String tables) { 1115 if (!TextUtils.isEmpty(tables)) { 1116 // find the first word terminated by either a space or a comma 1117 int spacepos = tables.indexOf(' '); 1118 int commapos = tables.indexOf(','); 1119 1120 if (spacepos > 0 && (spacepos < commapos || commapos < 0)) { 1121 return tables.substring(0, spacepos); 1122 } else if (commapos > 0 && (commapos < spacepos || spacepos < 0) ) { 1123 return tables.substring(0, commapos); 1124 } 1125 return tables; 1126 } else { 1127 throw new IllegalStateException("Invalid tables"); 1128 } 1129 } 1130 1131 /** 1132 * Compiles an SQL statement into a reusable pre-compiled statement object. 1133 * The parameters are identical to {@link #execSQL(String)}. You may put ?s in the 1134 * statement and fill in those values with {@link SQLiteProgram#bindString} 1135 * and {@link SQLiteProgram#bindLong} each time you want to run the 1136 * statement. Statements may not return result sets larger than 1x1. 1137 * 1138 * @param sql The raw SQL statement, may contain ? for unknown values to be 1139 * bound later. 1140 * @return A pre-compiled {@link SQLiteStatement} object. Note that 1141 * {@link SQLiteStatement}s are not synchronized, see the documentation for more details. 1142 */ 1143 public SQLiteStatement compileStatement(String sql) throws SQLException { 1144 lock(); 1145 if (!isOpen()) { 1146 throw new IllegalStateException("database not open"); 1147 } 1148 try { 1149 return new SQLiteStatement(this, sql); 1150 } finally { 1151 unlock(); 1152 } 1153 } 1154 1155 /** 1156 * Query the given URL, returning a {@link Cursor} over the result set. 1157 * 1158 * @param distinct true if you want each row to be unique, false otherwise. 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 * @param limit Limits the number of rows returned by the query, 1181 * formatted as LIMIT clause. Passing null denotes no LIMIT clause. 1182 * @return A {@link Cursor} object, which is positioned before the first entry. Note that 1183 * {@link Cursor}s are not synchronized, see the documentation for more details. 1184 * @see Cursor 1185 */ 1186 public Cursor query(boolean distinct, String table, String[] columns, 1187 String selection, String[] selectionArgs, String groupBy, 1188 String having, String orderBy, String limit) { 1189 return queryWithFactory(null, distinct, table, columns, selection, selectionArgs, 1190 groupBy, having, orderBy, limit); 1191 } 1192 1193 /** 1194 * Query the given URL, returning a {@link Cursor} over the result set. 1195 * 1196 * @param cursorFactory the cursor factory to use, or null for the default factory 1197 * @param distinct true if you want each row to be unique, false otherwise. 1198 * @param table The table name to compile the query against. 1199 * @param columns A list of which columns to return. Passing null will 1200 * return all columns, which is discouraged to prevent reading 1201 * data from storage that isn't going to be used. 1202 * @param selection A filter declaring which rows to return, formatted as an 1203 * SQL WHERE clause (excluding the WHERE itself). Passing null 1204 * will return all rows for the given table. 1205 * @param selectionArgs You may include ?s in selection, which will be 1206 * replaced by the values from selectionArgs, in order that they 1207 * appear in the selection. The values will be bound as Strings. 1208 * @param groupBy A filter declaring how to group rows, formatted as an SQL 1209 * GROUP BY clause (excluding the GROUP BY itself). Passing null 1210 * will cause the rows to not be grouped. 1211 * @param having A filter declare which row groups to include in the cursor, 1212 * if row grouping is being used, formatted as an SQL HAVING 1213 * clause (excluding the HAVING itself). Passing null will cause 1214 * all row groups to be included, and is required when row 1215 * grouping is not being used. 1216 * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause 1217 * (excluding the ORDER BY itself). Passing null will use the 1218 * default sort order, which may be unordered. 1219 * @param limit Limits the number of rows returned by the query, 1220 * formatted as LIMIT clause. Passing null denotes no LIMIT clause. 1221 * @return A {@link Cursor} object, which is positioned before the first entry. Note that 1222 * {@link Cursor}s are not synchronized, see the documentation for more details. 1223 * @see Cursor 1224 */ 1225 public Cursor queryWithFactory(CursorFactory cursorFactory, 1226 boolean distinct, String table, String[] columns, 1227 String selection, String[] selectionArgs, String groupBy, 1228 String having, String orderBy, String limit) { 1229 if (!isOpen()) { 1230 throw new IllegalStateException("database not open"); 1231 } 1232 String sql = SQLiteQueryBuilder.buildQueryString( 1233 distinct, table, columns, selection, groupBy, having, orderBy, limit); 1234 1235 return rawQueryWithFactory( 1236 cursorFactory, sql, selectionArgs, findEditTable(table)); 1237 } 1238 1239 /** 1240 * Query the given table, returning a {@link Cursor} over the result set. 1241 * 1242 * @param table The table name to compile the query against. 1243 * @param columns A list of which columns to return. Passing null will 1244 * return all columns, which is discouraged to prevent reading 1245 * data from storage that isn't going to be used. 1246 * @param selection A filter declaring which rows to return, formatted as an 1247 * SQL WHERE clause (excluding the WHERE itself). Passing null 1248 * will return all rows for the given table. 1249 * @param selectionArgs You may include ?s in selection, which will be 1250 * replaced by the values from selectionArgs, in order that they 1251 * appear in the selection. The values will be bound as Strings. 1252 * @param groupBy A filter declaring how to group rows, formatted as an SQL 1253 * GROUP BY clause (excluding the GROUP BY itself). Passing null 1254 * will cause the rows to not be grouped. 1255 * @param having A filter declare which row groups to include in the cursor, 1256 * if row grouping is being used, formatted as an SQL HAVING 1257 * clause (excluding the HAVING itself). Passing null will cause 1258 * all row groups to be included, and is required when row 1259 * grouping is not being used. 1260 * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause 1261 * (excluding the ORDER BY itself). Passing null will use the 1262 * default sort order, which may be unordered. 1263 * @return A {@link Cursor} object, which is positioned before the first entry. Note that 1264 * {@link Cursor}s are not synchronized, see the documentation for more details. 1265 * @see Cursor 1266 */ 1267 public Cursor query(String table, String[] columns, String selection, 1268 String[] selectionArgs, String groupBy, String having, 1269 String orderBy) { 1270 1271 return query(false, table, columns, selection, selectionArgs, groupBy, 1272 having, orderBy, null /* limit */); 1273 } 1274 1275 /** 1276 * Query the given table, returning a {@link Cursor} over the result set. 1277 * 1278 * @param table The table name to compile the query against. 1279 * @param columns A list of which columns to return. Passing null will 1280 * return all columns, which is discouraged to prevent reading 1281 * data from storage that isn't going to be used. 1282 * @param selection A filter declaring which rows to return, formatted as an 1283 * SQL WHERE clause (excluding the WHERE itself). Passing null 1284 * will return all rows for the given table. 1285 * @param selectionArgs You may include ?s in selection, which will be 1286 * replaced by the values from selectionArgs, in order that they 1287 * appear in the selection. The values will be bound as Strings. 1288 * @param groupBy A filter declaring how to group rows, formatted as an SQL 1289 * GROUP BY clause (excluding the GROUP BY itself). Passing null 1290 * will cause the rows to not be grouped. 1291 * @param having A filter declare which row groups to include in the cursor, 1292 * if row grouping is being used, formatted as an SQL HAVING 1293 * clause (excluding the HAVING itself). Passing null will cause 1294 * all row groups to be included, and is required when row 1295 * grouping is not being used. 1296 * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause 1297 * (excluding the ORDER BY itself). Passing null will use the 1298 * default sort order, which may be unordered. 1299 * @param limit Limits the number of rows returned by the query, 1300 * formatted as LIMIT clause. Passing null denotes no LIMIT clause. 1301 * @return A {@link Cursor} object, which is positioned before the first entry. Note that 1302 * {@link Cursor}s are not synchronized, see the documentation for more details. 1303 * @see Cursor 1304 */ 1305 public Cursor query(String table, String[] columns, String selection, 1306 String[] selectionArgs, String groupBy, String having, 1307 String orderBy, String limit) { 1308 1309 return query(false, table, columns, selection, selectionArgs, groupBy, 1310 having, orderBy, limit); 1311 } 1312 1313 /** 1314 * Runs the provided SQL and returns a {@link Cursor} over the result set. 1315 * 1316 * @param sql the SQL query. The SQL string must not be ; terminated 1317 * @param selectionArgs You may include ?s in where clause in the query, 1318 * which will be replaced by the values from selectionArgs. The 1319 * values will be bound as Strings. 1320 * @return A {@link Cursor} object, which is positioned before the first entry. Note that 1321 * {@link Cursor}s are not synchronized, see the documentation for more details. 1322 */ 1323 public Cursor rawQuery(String sql, String[] selectionArgs) { 1324 return rawQueryWithFactory(null, sql, selectionArgs, null); 1325 } 1326 1327 /** 1328 * Runs the provided SQL and returns a cursor over the result set. 1329 * 1330 * @param cursorFactory the cursor factory to use, or null for the default factory 1331 * @param sql the SQL query. The SQL string must not be ; terminated 1332 * @param selectionArgs You may include ?s in where clause in the query, 1333 * which will be replaced by the values from selectionArgs. The 1334 * values will be bound as Strings. 1335 * @param editTable the name of the first table, which is editable 1336 * @return A {@link Cursor} object, which is positioned before the first entry. Note that 1337 * {@link Cursor}s are not synchronized, see the documentation for more details. 1338 */ 1339 public Cursor rawQueryWithFactory( 1340 CursorFactory cursorFactory, String sql, String[] selectionArgs, 1341 String editTable) { 1342 if (!isOpen()) { 1343 throw new IllegalStateException("database not open"); 1344 } 1345 BlockGuard.getThreadPolicy().onReadFromDisk(); 1346 long timeStart = 0; 1347 1348 if (Config.LOGV || mSlowQueryThreshold != -1) { 1349 timeStart = System.currentTimeMillis(); 1350 } 1351 1352 SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(this, sql, editTable); 1353 1354 Cursor cursor = null; 1355 try { 1356 cursor = driver.query( 1357 cursorFactory != null ? cursorFactory : mFactory, 1358 selectionArgs); 1359 } finally { 1360 if (Config.LOGV || mSlowQueryThreshold != -1) { 1361 1362 // Force query execution 1363 int count = -1; 1364 if (cursor != null) { 1365 count = cursor.getCount(); 1366 } 1367 1368 long duration = System.currentTimeMillis() - timeStart; 1369 1370 if (Config.LOGV || duration >= mSlowQueryThreshold) { 1371 Log.v(SQLiteCursor.TAG, 1372 "query (" + duration + " ms): " + driver.toString() + ", args are " 1373 + (selectionArgs != null 1374 ? TextUtils.join(",", selectionArgs) 1375 : "<null>") + ", count is " + count); 1376 } 1377 } 1378 } 1379 return cursor; 1380 } 1381 1382 /** 1383 * Runs the provided SQL and returns a cursor over the result set. 1384 * The cursor will read an initial set of rows and the return to the caller. 1385 * It will continue to read in batches and send data changed notifications 1386 * when the later batches are ready. 1387 * @param sql the SQL query. The SQL string must not be ; terminated 1388 * @param selectionArgs You may include ?s in where clause in the query, 1389 * which will be replaced by the values from selectionArgs. The 1390 * values will be bound as Strings. 1391 * @param initialRead set the initial count of items to read from the cursor 1392 * @param maxRead set the count of items to read on each iteration after the first 1393 * @return A {@link Cursor} object, which is positioned before the first entry. Note that 1394 * {@link Cursor}s are not synchronized, see the documentation for more details. 1395 * 1396 * This work is incomplete and not fully tested or reviewed, so currently 1397 * hidden. 1398 * @hide 1399 */ 1400 public Cursor rawQuery(String sql, String[] selectionArgs, 1401 int initialRead, int maxRead) { 1402 SQLiteCursor c = (SQLiteCursor)rawQueryWithFactory( 1403 null, sql, selectionArgs, null); 1404 c.setLoadStyle(initialRead, maxRead); 1405 return c; 1406 } 1407 1408 /** 1409 * Convenience method for inserting a row into the database. 1410 * 1411 * @param table the table to insert the row into 1412 * @param nullColumnHack optional; may be <code>null</code>. 1413 * SQL doesn't allow inserting a completely empty row without 1414 * naming at least one column name. If your provided <code>values</code> is 1415 * empty, no column names are known and an empty row can't be inserted. 1416 * If not set to null, the <code>nullColumnHack</code> parameter 1417 * provides the name of nullable column name to explicitly insert a NULL into 1418 * in the case where your <code>values</code> is empty. 1419 * @param values this map contains the initial column values for the 1420 * row. The keys should be the column names and the values the 1421 * column values 1422 * @return the row ID of the newly inserted row, or -1 if an error occurred 1423 */ 1424 public long insert(String table, String nullColumnHack, ContentValues values) { 1425 try { 1426 return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE); 1427 } catch (SQLException e) { 1428 Log.e(TAG, "Error inserting " + values, e); 1429 return -1; 1430 } 1431 } 1432 1433 /** 1434 * Convenience method for inserting a row into the database. 1435 * 1436 * @param table the table to insert the row into 1437 * @param nullColumnHack optional; may be <code>null</code>. 1438 * SQL doesn't allow inserting a completely empty row without 1439 * naming at least one column name. If your provided <code>values</code> is 1440 * empty, no column names are known and an empty row can't be inserted. 1441 * If not set to null, the <code>nullColumnHack</code> parameter 1442 * provides the name of nullable column name to explicitly insert a NULL into 1443 * in the case where your <code>values</code> is empty. 1444 * @param values this map contains the initial column values for the 1445 * row. The keys should be the column names and the values the 1446 * column values 1447 * @throws SQLException 1448 * @return the row ID of the newly inserted row, or -1 if an error occurred 1449 */ 1450 public long insertOrThrow(String table, String nullColumnHack, ContentValues values) 1451 throws SQLException { 1452 return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE); 1453 } 1454 1455 /** 1456 * Convenience method for replacing a row in the database. 1457 * 1458 * @param table the table in which to replace the row 1459 * @param nullColumnHack optional; may be <code>null</code>. 1460 * SQL doesn't allow inserting a completely empty row without 1461 * naming at least one column name. If your provided <code>initialValues</code> is 1462 * empty, no column names are known and an empty row can't be inserted. 1463 * If not set to null, the <code>nullColumnHack</code> parameter 1464 * provides the name of nullable column name to explicitly insert a NULL into 1465 * in the case where your <code>initialValues</code> is empty. 1466 * @param initialValues this map contains the initial column values for 1467 * the row. 1468 * @return the row ID of the newly inserted row, or -1 if an error occurred 1469 */ 1470 public long replace(String table, String nullColumnHack, ContentValues initialValues) { 1471 try { 1472 return insertWithOnConflict(table, nullColumnHack, initialValues, 1473 CONFLICT_REPLACE); 1474 } catch (SQLException e) { 1475 Log.e(TAG, "Error inserting " + initialValues, e); 1476 return -1; 1477 } 1478 } 1479 1480 /** 1481 * Convenience method for replacing a row in the database. 1482 * 1483 * @param table the table in which to replace the row 1484 * @param nullColumnHack optional; may be <code>null</code>. 1485 * SQL doesn't allow inserting a completely empty row without 1486 * naming at least one column name. If your provided <code>initialValues</code> is 1487 * empty, no column names are known and an empty row can't be inserted. 1488 * If not set to null, the <code>nullColumnHack</code> parameter 1489 * provides the name of nullable column name to explicitly insert a NULL into 1490 * in the case where your <code>initialValues</code> is empty. 1491 * @param initialValues this map contains the initial column values for 1492 * the row. The key 1493 * @throws SQLException 1494 * @return the row ID of the newly inserted row, or -1 if an error occurred 1495 */ 1496 public long replaceOrThrow(String table, String nullColumnHack, 1497 ContentValues initialValues) throws SQLException { 1498 return insertWithOnConflict(table, nullColumnHack, initialValues, 1499 CONFLICT_REPLACE); 1500 } 1501 1502 /** 1503 * General method for inserting a row into the database. 1504 * 1505 * @param table the table to insert the row into 1506 * @param nullColumnHack optional; may be <code>null</code>. 1507 * SQL doesn't allow inserting a completely empty row without 1508 * naming at least one column name. If your provided <code>initialValues</code> is 1509 * empty, no column names are known and an empty row can't be inserted. 1510 * If not set to null, the <code>nullColumnHack</code> parameter 1511 * provides the name of nullable column name to explicitly insert a NULL into 1512 * in the case where your <code>initialValues</code> is empty. 1513 * @param initialValues this map contains the initial column values for the 1514 * row. The keys should be the column names and the values the 1515 * column values 1516 * @param conflictAlgorithm for insert conflict resolver 1517 * @return the row ID of the newly inserted row 1518 * OR the primary key of the existing row if the input param 'conflictAlgorithm' = 1519 * {@link #CONFLICT_IGNORE} 1520 * OR -1 if any error 1521 */ 1522 public long insertWithOnConflict(String table, String nullColumnHack, 1523 ContentValues initialValues, int conflictAlgorithm) { 1524 BlockGuard.getThreadPolicy().onWriteToDisk(); 1525 if (!isOpen()) { 1526 throw new IllegalStateException("database not open"); 1527 } 1528 1529 // Measurements show most sql lengths <= 152 1530 StringBuilder sql = new StringBuilder(152); 1531 sql.append("INSERT"); 1532 sql.append(CONFLICT_VALUES[conflictAlgorithm]); 1533 sql.append(" INTO "); 1534 sql.append(table); 1535 // Measurements show most values lengths < 40 1536 StringBuilder values = new StringBuilder(40); 1537 1538 Set<Map.Entry<String, Object>> entrySet = null; 1539 if (initialValues != null && initialValues.size() > 0) { 1540 entrySet = initialValues.valueSet(); 1541 Iterator<Map.Entry<String, Object>> entriesIter = entrySet.iterator(); 1542 sql.append('('); 1543 1544 boolean needSeparator = false; 1545 while (entriesIter.hasNext()) { 1546 if (needSeparator) { 1547 sql.append(", "); 1548 values.append(", "); 1549 } 1550 needSeparator = true; 1551 Map.Entry<String, Object> entry = entriesIter.next(); 1552 sql.append(entry.getKey()); 1553 values.append('?'); 1554 } 1555 1556 sql.append(')'); 1557 } else { 1558 sql.append("(" + nullColumnHack + ") "); 1559 values.append("NULL"); 1560 } 1561 1562 sql.append(" VALUES("); 1563 sql.append(values); 1564 sql.append(");"); 1565 1566 lock(); 1567 SQLiteStatement statement = null; 1568 try { 1569 statement = compileStatement(sql.toString()); 1570 1571 // Bind the values 1572 if (entrySet != null) { 1573 int size = entrySet.size(); 1574 Iterator<Map.Entry<String, Object>> entriesIter = entrySet.iterator(); 1575 for (int i = 0; i < size; i++) { 1576 Map.Entry<String, Object> entry = entriesIter.next(); 1577 DatabaseUtils.bindObjectToProgram(statement, i + 1, entry.getValue()); 1578 } 1579 } 1580 1581 // Run the program and then cleanup 1582 statement.execute(); 1583 1584 long insertedRowId = lastInsertRow(); 1585 if (insertedRowId == -1) { 1586 Log.e(TAG, "Error inserting " + initialValues + " using " + sql); 1587 } else { 1588 if (Config.LOGD && Log.isLoggable(TAG, Log.VERBOSE)) { 1589 Log.v(TAG, "Inserting row " + insertedRowId + " from " 1590 + initialValues + " using " + sql); 1591 } 1592 } 1593 return insertedRowId; 1594 } catch (SQLiteDatabaseCorruptException e) { 1595 onCorruption(); 1596 throw e; 1597 } finally { 1598 if (statement != null) { 1599 statement.close(); 1600 } 1601 unlock(); 1602 } 1603 } 1604 1605 /** 1606 * Convenience method for deleting rows in the database. 1607 * 1608 * @param table the table to delete from 1609 * @param whereClause the optional WHERE clause to apply when deleting. 1610 * Passing null will delete all rows. 1611 * @return the number of rows affected if a whereClause is passed in, 0 1612 * otherwise. To remove all rows and get a count pass "1" as the 1613 * whereClause. 1614 */ 1615 public int delete(String table, String whereClause, String[] whereArgs) { 1616 BlockGuard.getThreadPolicy().onWriteToDisk(); 1617 lock(); 1618 if (!isOpen()) { 1619 throw new IllegalStateException("database not open"); 1620 } 1621 SQLiteStatement statement = null; 1622 try { 1623 statement = compileStatement("DELETE FROM " + table 1624 + (!TextUtils.isEmpty(whereClause) 1625 ? " WHERE " + whereClause : "")); 1626 if (whereArgs != null) { 1627 int numArgs = whereArgs.length; 1628 for (int i = 0; i < numArgs; i++) { 1629 DatabaseUtils.bindObjectToProgram(statement, i + 1, whereArgs[i]); 1630 } 1631 } 1632 statement.execute(); 1633 return lastChangeCount(); 1634 } catch (SQLiteDatabaseCorruptException e) { 1635 onCorruption(); 1636 throw e; 1637 } finally { 1638 if (statement != null) { 1639 statement.close(); 1640 } 1641 unlock(); 1642 } 1643 } 1644 1645 /** 1646 * Convenience method for updating rows in the database. 1647 * 1648 * @param table the table to update in 1649 * @param values a map from column names to new column values. null is a 1650 * valid value that will be translated to NULL. 1651 * @param whereClause the optional WHERE clause to apply when updating. 1652 * Passing null will update all rows. 1653 * @return the number of rows affected 1654 */ 1655 public int update(String table, ContentValues values, String whereClause, String[] whereArgs) { 1656 return updateWithOnConflict(table, values, whereClause, whereArgs, CONFLICT_NONE); 1657 } 1658 1659 /** 1660 * Convenience method for updating rows in the database. 1661 * 1662 * @param table the table to update in 1663 * @param values a map from column names to new column values. null is a 1664 * valid value that will be translated to NULL. 1665 * @param whereClause the optional WHERE clause to apply when updating. 1666 * Passing null will update all rows. 1667 * @param conflictAlgorithm for update conflict resolver 1668 * @return the number of rows affected 1669 */ 1670 public int updateWithOnConflict(String table, ContentValues values, 1671 String whereClause, String[] whereArgs, int conflictAlgorithm) { 1672 BlockGuard.getThreadPolicy().onWriteToDisk(); 1673 if (values == null || values.size() == 0) { 1674 throw new IllegalArgumentException("Empty values"); 1675 } 1676 1677 StringBuilder sql = new StringBuilder(120); 1678 sql.append("UPDATE "); 1679 sql.append(CONFLICT_VALUES[conflictAlgorithm]); 1680 sql.append(table); 1681 sql.append(" SET "); 1682 1683 Set<Map.Entry<String, Object>> entrySet = values.valueSet(); 1684 Iterator<Map.Entry<String, Object>> entriesIter = entrySet.iterator(); 1685 1686 while (entriesIter.hasNext()) { 1687 Map.Entry<String, Object> entry = entriesIter.next(); 1688 sql.append(entry.getKey()); 1689 sql.append("=?"); 1690 if (entriesIter.hasNext()) { 1691 sql.append(", "); 1692 } 1693 } 1694 1695 if (!TextUtils.isEmpty(whereClause)) { 1696 sql.append(" WHERE "); 1697 sql.append(whereClause); 1698 } 1699 1700 lock(); 1701 if (!isOpen()) { 1702 throw new IllegalStateException("database not open"); 1703 } 1704 SQLiteStatement statement = null; 1705 try { 1706 statement = compileStatement(sql.toString()); 1707 1708 // Bind the values 1709 int size = entrySet.size(); 1710 entriesIter = entrySet.iterator(); 1711 int bindArg = 1; 1712 for (int i = 0; i < size; i++) { 1713 Map.Entry<String, Object> entry = entriesIter.next(); 1714 DatabaseUtils.bindObjectToProgram(statement, bindArg, entry.getValue()); 1715 bindArg++; 1716 } 1717 1718 if (whereArgs != null) { 1719 size = whereArgs.length; 1720 for (int i = 0; i < size; i++) { 1721 statement.bindString(bindArg, whereArgs[i]); 1722 bindArg++; 1723 } 1724 } 1725 1726 // Run the program and then cleanup 1727 statement.execute(); 1728 int numChangedRows = lastChangeCount(); 1729 if (Config.LOGD && Log.isLoggable(TAG, Log.VERBOSE)) { 1730 Log.v(TAG, "Updated " + numChangedRows + " using " + values + " and " + sql); 1731 } 1732 return numChangedRows; 1733 } catch (SQLiteDatabaseCorruptException e) { 1734 onCorruption(); 1735 throw e; 1736 } catch (SQLException e) { 1737 Log.e(TAG, "Error updating " + values + " using " + sql); 1738 throw e; 1739 } finally { 1740 if (statement != null) { 1741 statement.close(); 1742 } 1743 unlock(); 1744 } 1745 } 1746 1747 /** 1748 * Execute a single SQL statement that is not a query. For example, CREATE 1749 * TABLE, DELETE, INSERT, etc. Multiple statements separated by semicolons are not 1750 * supported. Takes a write lock. 1751 * 1752 * @throws SQLException if the SQL string is invalid 1753 */ 1754 public void execSQL(String sql) throws SQLException { 1755 BlockGuard.getThreadPolicy().onWriteToDisk(); 1756 long timeStart = SystemClock.uptimeMillis(); 1757 lock(); 1758 if (!isOpen()) { 1759 throw new IllegalStateException("database not open"); 1760 } 1761 logTimeStat(mLastSqlStatement, timeStart, GET_LOCK_LOG_PREFIX); 1762 try { 1763 native_execSQL(sql); 1764 } catch (SQLiteDatabaseCorruptException e) { 1765 onCorruption(); 1766 throw e; 1767 } finally { 1768 unlock(); 1769 } 1770 1771 // Log commit statements along with the most recently executed 1772 // SQL statement for disambiguation. Note that instance 1773 // equality to COMMIT_SQL is safe here. 1774 if (sql == COMMIT_SQL) { 1775 logTimeStat(mLastSqlStatement, timeStart, COMMIT_SQL); 1776 } else { 1777 logTimeStat(sql, timeStart, null); 1778 } 1779 } 1780 1781 /** 1782 * Execute a single SQL statement that is not a query. For example, CREATE 1783 * TABLE, DELETE, INSERT, etc. Multiple statements separated by semicolons are not 1784 * supported. Takes a write lock. 1785 * 1786 * @param sql 1787 * @param bindArgs only byte[], String, Long and Double are supported in bindArgs. 1788 * @throws SQLException if the SQL string is invalid 1789 */ 1790 public void execSQL(String sql, Object[] bindArgs) throws SQLException { 1791 BlockGuard.getThreadPolicy().onWriteToDisk(); 1792 if (bindArgs == null) { 1793 throw new IllegalArgumentException("Empty bindArgs"); 1794 } 1795 long timeStart = SystemClock.uptimeMillis(); 1796 lock(); 1797 if (!isOpen()) { 1798 throw new IllegalStateException("database not open"); 1799 } 1800 SQLiteStatement statement = null; 1801 try { 1802 statement = compileStatement(sql); 1803 if (bindArgs != null) { 1804 int numArgs = bindArgs.length; 1805 for (int i = 0; i < numArgs; i++) { 1806 DatabaseUtils.bindObjectToProgram(statement, i + 1, bindArgs[i]); 1807 } 1808 } 1809 statement.execute(); 1810 } catch (SQLiteDatabaseCorruptException e) { 1811 onCorruption(); 1812 throw e; 1813 } finally { 1814 if (statement != null) { 1815 statement.close(); 1816 } 1817 unlock(); 1818 } 1819 logTimeStat(sql, timeStart); 1820 } 1821 1822 @Override 1823 protected void finalize() { 1824 if (isOpen()) { 1825 Log.e(TAG, "close() was never explicitly called on database '" + 1826 mPath + "' ", mStackTrace); 1827 closeClosable(); 1828 onAllReferencesReleased(); 1829 } 1830 } 1831 1832 /** 1833 * Private constructor. See {@link #create} and {@link #openDatabase}. 1834 * 1835 * @param path The full path to the database 1836 * @param factory The factory to use when creating cursors, may be NULL. 1837 * @param flags 0 or {@link #NO_LOCALIZED_COLLATORS}. If the database file already 1838 * exists, mFlags will be updated appropriately. 1839 */ 1840 private SQLiteDatabase(String path, CursorFactory factory, int flags) { 1841 if (path == null) { 1842 throw new IllegalArgumentException("path should not be null"); 1843 } 1844 mFlags = flags; 1845 mPath = path; 1846 mSlowQueryThreshold = SystemProperties.getInt(LOG_SLOW_QUERIES_PROPERTY, -1); 1847 mStackTrace = new DatabaseObjectNotClosedException().fillInStackTrace(); 1848 mFactory = factory; 1849 dbopen(mPath, mFlags); 1850 if (SQLiteDebug.DEBUG_SQL_CACHE) { 1851 mTimeOpened = getTime(); 1852 } 1853 mPrograms = new WeakHashMap<SQLiteClosable,Object>(); 1854 try { 1855 setLocale(Locale.getDefault()); 1856 } catch (RuntimeException e) { 1857 Log.e(TAG, "Failed to setLocale() when constructing, closing the database", e); 1858 dbclose(); 1859 if (SQLiteDebug.DEBUG_SQL_CACHE) { 1860 mTimeClosed = getTime(); 1861 } 1862 throw e; 1863 } 1864 } 1865 1866 private String getTime() { 1867 return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS ").format(System.currentTimeMillis()); 1868 } 1869 1870 /** 1871 * return whether the DB is opened as read only. 1872 * @return true if DB is opened as read only 1873 */ 1874 public boolean isReadOnly() { 1875 return (mFlags & OPEN_READ_MASK) == OPEN_READONLY; 1876 } 1877 1878 /** 1879 * @return true if the DB is currently open (has not been closed) 1880 */ 1881 public boolean isOpen() { 1882 return mNativeHandle != 0; 1883 } 1884 1885 public boolean needUpgrade(int newVersion) { 1886 return newVersion > getVersion(); 1887 } 1888 1889 /** 1890 * Getter for the path to the database file. 1891 * 1892 * @return the path to our database file. 1893 */ 1894 public final String getPath() { 1895 return mPath; 1896 } 1897 1898 /* package */ void logTimeStat(String sql, long beginMillis) { 1899 logTimeStat(sql, beginMillis, null); 1900 } 1901 1902 /* package */ void logTimeStat(String sql, long beginMillis, String prefix) { 1903 // Keep track of the last statement executed here, as this is 1904 // the common funnel through which all methods of hitting 1905 // libsqlite eventually flow. 1906 mLastSqlStatement = sql; 1907 1908 // Sample fast queries in proportion to the time taken. 1909 // Quantize the % first, so the logged sampling probability 1910 // exactly equals the actual sampling rate for this query. 1911 1912 int samplePercent; 1913 long durationMillis = SystemClock.uptimeMillis() - beginMillis; 1914 if (durationMillis == 0 && prefix == GET_LOCK_LOG_PREFIX) { 1915 // The common case is locks being uncontended. Don't log those, 1916 // even at 1%, which is our default below. 1917 return; 1918 } 1919 if (sQueryLogTimeInMillis == 0) { 1920 sQueryLogTimeInMillis = SystemProperties.getInt("db.db_operation.threshold_ms", 500); 1921 } 1922 if (durationMillis >= sQueryLogTimeInMillis) { 1923 samplePercent = 100; 1924 } else {; 1925 samplePercent = (int) (100 * durationMillis / sQueryLogTimeInMillis) + 1; 1926 if (mRandom.nextInt(100) >= samplePercent) return; 1927 } 1928 1929 // Note: the prefix will be "COMMIT;" or "GETLOCK:" when non-null. We wait to do 1930 // it here so we avoid allocating in the common case. 1931 if (prefix != null) { 1932 sql = prefix + sql; 1933 } 1934 1935 if (sql.length() > QUERY_LOG_SQL_LENGTH) sql = sql.substring(0, QUERY_LOG_SQL_LENGTH); 1936 1937 // ActivityThread.currentPackageName() only returns non-null if the 1938 // current thread is an application main thread. This parameter tells 1939 // us whether an event loop is blocked, and if so, which app it is. 1940 // 1941 // Sadly, there's no fast way to determine app name if this is *not* a 1942 // main thread, or when we are invoked via Binder (e.g. ContentProvider). 1943 // Hopefully the full path to the database will be informative enough. 1944 1945 String blockingPackage = AppGlobals.getInitialPackage(); 1946 if (blockingPackage == null) blockingPackage = ""; 1947 1948 EventLog.writeEvent( 1949 EVENT_DB_OPERATION, 1950 getPathForLogs(), 1951 sql, 1952 durationMillis, 1953 blockingPackage, 1954 samplePercent); 1955 } 1956 1957 /** 1958 * Removes email addresses from database filenames before they're 1959 * logged to the EventLog where otherwise apps could potentially 1960 * read them. 1961 */ 1962 private String getPathForLogs() { 1963 if (mPathForLogs != null) { 1964 return mPathForLogs; 1965 } 1966 if (mPath == null) { 1967 return null; 1968 } 1969 if (mPath.indexOf('@') == -1) { 1970 mPathForLogs = mPath; 1971 } else { 1972 mPathForLogs = EMAIL_IN_DB_PATTERN.matcher(mPath).replaceAll("XX@YY"); 1973 } 1974 return mPathForLogs; 1975 } 1976 1977 /** 1978 * Sets the locale for this database. Does nothing if this database has 1979 * the NO_LOCALIZED_COLLATORS flag set or was opened read only. 1980 * @throws SQLException if the locale could not be set. The most common reason 1981 * for this is that there is no collator available for the locale you requested. 1982 * In this case the database remains unchanged. 1983 */ 1984 public void setLocale(Locale locale) { 1985 lock(); 1986 try { 1987 native_setLocale(locale.toString(), mFlags); 1988 } finally { 1989 unlock(); 1990 } 1991 } 1992 1993 /* 1994 * ============================================================================ 1995 * 1996 * The following methods deal with compiled-sql cache 1997 * ============================================================================ 1998 */ 1999 /** 2000 * adds the given sql and its compiled-statement-id-returned-by-sqlite to the 2001 * cache of compiledQueries attached to 'this'. 2002 * 2003 * if there is already a {@link SQLiteCompiledSql} in compiledQueries for the given sql, 2004 * the new {@link SQLiteCompiledSql} object is NOT inserted into the cache (i.e.,the current 2005 * mapping is NOT replaced with the new mapping). 2006 */ 2007 /* package */ void addToCompiledQueries(String sql, SQLiteCompiledSql compiledStatement) { 2008 if (mMaxSqlCacheSize == 0) { 2009 // for this database, there is no cache of compiled sql. 2010 if (SQLiteDebug.DEBUG_SQL_CACHE) { 2011 Log.v(TAG, "|NOT adding_sql_to_cache|" + getPath() + "|" + sql); 2012 } 2013 return; 2014 } 2015 2016 SQLiteCompiledSql compiledSql = null; 2017 synchronized(mCompiledQueries) { 2018 // don't insert the new mapping if a mapping already exists 2019 compiledSql = mCompiledQueries.get(sql); 2020 if (compiledSql != null) { 2021 return; 2022 } 2023 // add this <sql, compiledStatement> to the cache 2024 if (mCompiledQueries.size() == mMaxSqlCacheSize) { 2025 /* 2026 * cache size of {@link #mMaxSqlCacheSize} is not enough for this app. 2027 * log a warning MAX_WARNINGS_ON_CACHESIZE_CONDITION times 2028 * chances are it is NOT using ? for bindargs - so caching is useless. 2029 * TODO: either let the callers set max cchesize for their app, or intelligently 2030 * figure out what should be cached for a given app. 2031 */ 2032 if (++mCacheFullWarnings == MAX_WARNINGS_ON_CACHESIZE_CONDITION) { 2033 Log.w(TAG, "Reached MAX size for compiled-sql statement cache for database " + 2034 getPath() + "; i.e., NO space for this sql statement in cache: " + 2035 sql + ". Please change your sql statements to use '?' for " + 2036 "bindargs, instead of using actual values"); 2037 } 2038 // don't add this entry to cache 2039 } else { 2040 // cache is NOT full. add this to cache. 2041 mCompiledQueries.put(sql, compiledStatement); 2042 if (SQLiteDebug.DEBUG_SQL_CACHE) { 2043 Log.v(TAG, "|adding_sql_to_cache|" + getPath() + "|" + 2044 mCompiledQueries.size() + "|" + sql); 2045 } 2046 } 2047 } 2048 return; 2049 } 2050 2051 2052 private void deallocCachedSqlStatements() { 2053 synchronized (mCompiledQueries) { 2054 for (SQLiteCompiledSql compiledSql : mCompiledQueries.values()) { 2055 compiledSql.releaseSqlStatement(); 2056 } 2057 mCompiledQueries.clear(); 2058 } 2059 } 2060 2061 /** 2062 * from the compiledQueries cache, returns the compiled-statement-id for the given sql. 2063 * returns null, if not found in the cache. 2064 */ 2065 /* package */ SQLiteCompiledSql getCompiledStatementForSql(String sql) { 2066 SQLiteCompiledSql compiledStatement = null; 2067 boolean cacheHit; 2068 synchronized(mCompiledQueries) { 2069 if (mMaxSqlCacheSize == 0) { 2070 // for this database, there is no cache of compiled sql. 2071 if (SQLiteDebug.DEBUG_SQL_CACHE) { 2072 Log.v(TAG, "|cache NOT found|" + getPath()); 2073 } 2074 return null; 2075 } 2076 cacheHit = (compiledStatement = mCompiledQueries.get(sql)) != null; 2077 } 2078 if (cacheHit) { 2079 mNumCacheHits++; 2080 } else { 2081 mNumCacheMisses++; 2082 } 2083 2084 if (SQLiteDebug.DEBUG_SQL_CACHE) { 2085 Log.v(TAG, "|cache_stats|" + 2086 getPath() + "|" + mCompiledQueries.size() + 2087 "|" + mNumCacheHits + "|" + mNumCacheMisses + 2088 "|" + cacheHit + "|" + mTimeOpened + "|" + mTimeClosed + "|" + sql); 2089 } 2090 return compiledStatement; 2091 } 2092 2093 /** 2094 * returns true if the given sql is cached in compiled-sql cache. 2095 * @hide 2096 */ 2097 public boolean isInCompiledSqlCache(String sql) { 2098 synchronized(mCompiledQueries) { 2099 return mCompiledQueries.containsKey(sql); 2100 } 2101 } 2102 2103 /** 2104 * purges the given sql from the compiled-sql cache. 2105 * @hide 2106 */ 2107 public void purgeFromCompiledSqlCache(String sql) { 2108 synchronized(mCompiledQueries) { 2109 mCompiledQueries.remove(sql); 2110 } 2111 } 2112 2113 /** 2114 * remove everything from the compiled sql cache 2115 * @hide 2116 */ 2117 public void resetCompiledSqlCache() { 2118 synchronized(mCompiledQueries) { 2119 mCompiledQueries.clear(); 2120 } 2121 } 2122 2123 /** 2124 * return the current maxCacheSqlCacheSize 2125 * @hide 2126 */ 2127 public synchronized int getMaxSqlCacheSize() { 2128 return mMaxSqlCacheSize; 2129 } 2130 2131 /** 2132 * set the max size of the compiled sql cache for this database after purging the cache. 2133 * (size of the cache = number of compiled-sql-statements stored in the cache). 2134 * 2135 * max cache size can ONLY be increased from its current size (default = 0). 2136 * if this method is called with smaller size than the current value of mMaxSqlCacheSize, 2137 * then IllegalStateException is thrown 2138 * 2139 * synchronized because we don't want t threads to change cache size at the same time. 2140 * @param cacheSize the size of the cache. can be (0 to MAX_SQL_CACHE_SIZE) 2141 * @throws IllegalStateException if input cacheSize > MAX_SQL_CACHE_SIZE or < 0 or 2142 * < the value set with previous setMaxSqlCacheSize() call. 2143 * 2144 * @hide 2145 */ 2146 public synchronized void setMaxSqlCacheSize(int cacheSize) { 2147 if (cacheSize > MAX_SQL_CACHE_SIZE || cacheSize < 0) { 2148 throw new IllegalStateException("expected value between 0 and " + MAX_SQL_CACHE_SIZE); 2149 } else if (cacheSize < mMaxSqlCacheSize) { 2150 throw new IllegalStateException("cannot set cacheSize to a value less than the value " + 2151 "set with previous setMaxSqlCacheSize() call."); 2152 } 2153 mMaxSqlCacheSize = cacheSize; 2154 } 2155 2156 static class ActiveDatabases { 2157 private static final ActiveDatabases activeDatabases = new ActiveDatabases(); 2158 private HashSet<WeakReference<SQLiteDatabase>> mActiveDatabases = 2159 new HashSet<WeakReference<SQLiteDatabase>>(); 2160 private ActiveDatabases() {} // disable instantiation of this class 2161 static ActiveDatabases getInstance() {return activeDatabases;} 2162 } 2163 2164 /** 2165 * this method is used to collect data about ALL open databases in the current process. 2166 * bugreport is a user of this data. 2167 */ 2168 /* package */ static ArrayList<DbStats> getDbStats() { 2169 ArrayList<DbStats> dbStatsList = new ArrayList<DbStats>(); 2170 for (WeakReference<SQLiteDatabase> w : ActiveDatabases.getInstance().mActiveDatabases) { 2171 SQLiteDatabase db = w.get(); 2172 if (db == null || !db.isOpen()) { 2173 continue; 2174 } 2175 // get SQLITE_DBSTATUS_LOOKASIDE_USED for the db 2176 int lookasideUsed = db.native_getDbLookaside(); 2177 2178 // get the lastnode of the dbname 2179 String path = db.getPath(); 2180 int indx = path.lastIndexOf("/"); 2181 String lastnode = path.substring((indx != -1) ? ++indx : 0); 2182 2183 // get list of attached dbs and for each db, get its size and pagesize 2184 ArrayList<Pair<String, String>> attachedDbs = getAttachedDbs(db); 2185 if (attachedDbs == null) { 2186 continue; 2187 } 2188 for (int i = 0; i < attachedDbs.size(); i++) { 2189 Pair<String, String> p = attachedDbs.get(i); 2190 long pageCount = getPragmaVal(db, p.first + ".page_count;"); 2191 2192 // first entry in the attached db list is always the main database 2193 // don't worry about prefixing the dbname with "main" 2194 String dbName; 2195 if (i == 0) { 2196 dbName = lastnode; 2197 } else { 2198 // lookaside is only relevant for the main db 2199 lookasideUsed = 0; 2200 dbName = " (attached) " + p.first; 2201 // if the attached db has a path, attach the lastnode from the path to above 2202 if (p.second.trim().length() > 0) { 2203 int idx = p.second.lastIndexOf("/"); 2204 dbName += " : " + p.second.substring((idx != -1) ? ++idx : 0); 2205 } 2206 } 2207 if (pageCount > 0) { 2208 dbStatsList.add(new DbStats(dbName, pageCount, db.getPageSize(), 2209 lookasideUsed)); 2210 } 2211 } 2212 } 2213 return dbStatsList; 2214 } 2215 2216 /** 2217 * get the specified pragma value from sqlite for the specified database. 2218 * only handles pragma's that return int/long. 2219 * NO JAVA locks are held in this method. 2220 * TODO: use this to do all pragma's in this class 2221 */ 2222 private static long getPragmaVal(SQLiteDatabase db, String pragma) { 2223 if (!db.isOpen()) { 2224 return 0; 2225 } 2226 SQLiteStatement prog = null; 2227 try { 2228 prog = new SQLiteStatement(db, "PRAGMA " + pragma); 2229 long val = prog.simpleQueryForLong(); 2230 return val; 2231 } finally { 2232 if (prog != null) prog.close(); 2233 } 2234 } 2235 2236 /** 2237 * returns list of full pathnames of all attached databases 2238 * including the main database 2239 * TODO: move this to {@link DatabaseUtils} 2240 */ 2241 private static ArrayList<Pair<String, String>> getAttachedDbs(SQLiteDatabase dbObj) { 2242 if (!dbObj.isOpen()) { 2243 return null; 2244 } 2245 ArrayList<Pair<String, String>> attachedDbs = new ArrayList<Pair<String, String>>(); 2246 Cursor c = dbObj.rawQuery("pragma database_list;", null); 2247 while (c.moveToNext()) { 2248 attachedDbs.add(new Pair<String, String>(c.getString(1), c.getString(2))); 2249 } 2250 c.close(); 2251 return attachedDbs; 2252 } 2253 2254 /** 2255 * Native call to open the database. 2256 * 2257 * @param path The full path to the database 2258 */ 2259 private native void dbopen(String path, int flags); 2260 2261 /** 2262 * Native call to setup tracing of all sql statements 2263 * 2264 * @param path the full path to the database 2265 */ 2266 private native void enableSqlTracing(String path); 2267 2268 /** 2269 * Native call to setup profiling of all sql statements. 2270 * currently, sqlite's profiling = printing of execution-time 2271 * (wall-clock time) of each of the sql statements, as they 2272 * are executed. 2273 * 2274 * @param path the full path to the database 2275 */ 2276 private native void enableSqlProfiling(String path); 2277 2278 /** 2279 * Native call to execute a raw SQL statement. {@link #lock} must be held 2280 * when calling this method. 2281 * 2282 * @param sql The raw SQL string 2283 * @throws SQLException 2284 */ 2285 /* package */ native void native_execSQL(String sql) throws SQLException; 2286 2287 /** 2288 * Native call to set the locale. {@link #lock} must be held when calling 2289 * this method. 2290 * @throws SQLException 2291 */ 2292 /* package */ native void native_setLocale(String loc, int flags); 2293 2294 /** 2295 * Returns the row ID of the last row inserted into the database. 2296 * 2297 * @return the row ID of the last row inserted into the database. 2298 */ 2299 /* package */ native long lastInsertRow(); 2300 2301 /** 2302 * Returns the number of changes made in the last statement executed. 2303 * 2304 * @return the number of changes made in the last statement executed. 2305 */ 2306 /* package */ native int lastChangeCount(); 2307 2308 /** 2309 * return the SQLITE_DBSTATUS_LOOKASIDE_USED documented here 2310 * http://www.sqlite.org/c3ref/c_dbstatus_lookaside_used.html 2311 * @return int value of SQLITE_DBSTATUS_LOOKASIDE_USED 2312 */ 2313 private native int native_getDbLookaside(); 2314} 2315