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