19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.database.sqlite; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ContentValues; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.Cursor; 21062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Noriimport android.database.DatabaseErrorHandler; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.DatabaseUtils; 23062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Noriimport android.database.DefaultDatabaseErrorHandler; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.SQLException; 25c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Noriimport android.database.sqlite.SQLiteDebug.DbStats; 26a7771df3696954f0e279407e8894a916a7cb26ccJeff Brownimport android.os.CancellationSignal; 27e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brownimport android.os.Looper; 28a7771df3696954f0e279407e8894a916a7cb26ccJeff Brownimport android.os.OperationCanceledException; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.EventLog; 3190142c959e6de38eae1563cd8b3d2d448393e15fDmitri Plotnikovimport android.util.Log; 32c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Noriimport android.util.Pair; 33e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brownimport android.util.Printer; 34e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 35e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brownimport dalvik.system.CloseGuard; 36e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File; 3879087e4b967d8af26c488c41b8c1a087a12da84dJeff Brownimport java.io.FileFilter; 39c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Noriimport java.util.ArrayList; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.HashMap; 419b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilsonimport java.util.List; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Locale; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Map; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.WeakHashMap; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Exposes methods to manage a SQLite database. 48e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * 49e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * <p> 50e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * SQLiteDatabase has methods to create, delete, execute SQL commands, and 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * perform other common database management tasks. 52e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * </p><p> 53e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * See the Notepad sample application in the SDK for an example of creating 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and managing a database. 55e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * </p><p> 56e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Database names must be unique within an application, not across all applications. 57e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * </p> 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h3>Localized Collation - ORDER BY</h3> 60e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * <p> 61e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * In addition to SQLite's default <code>BINARY</code> collator, Android supplies 62e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * two more, <code>LOCALIZED</code>, which changes with the system's current locale, 63e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * and <code>UNICODE</code>, which is the Unicode Collation Algorithm and not tailored 64e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * to the current locale. 65e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * </p> 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 67baefdfad6e77e772deb6474380dd85ac776293e8Jeff Brownpublic final class SQLiteDatabase extends SQLiteClosable { 68fb16cbd9b2e86d6878d4bff820422bc09c8938deVasu Nori private static final String TAG = "SQLiteDatabase"; 69e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 70082c2af6859dff103e781b372dfde927cc0f869fJeff Hamilton private static final int EVENT_DB_CORRUPT = 75004; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 72e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // Stores reference to all databases opened in the current process. 73e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // (The referent Object is not used at this time.) 74e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // INVARIANT: Guarded by sActiveDatabases. 75e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown private static WeakHashMap<SQLiteDatabase, Object> sActiveDatabases = 76e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown new WeakHashMap<SQLiteDatabase, Object>(); 77e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 78e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // Thread-local for database sessions that belong to this database. 79e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // Each thread has its own database session. 80e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // INVARIANT: Immutable. 81e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown private final ThreadLocal<SQLiteSession> mThreadSession = new ThreadLocal<SQLiteSession>() { 82e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown @Override 83e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown protected SQLiteSession initialValue() { 84e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown return createSession(); 85e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 86e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown }; 87e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 88e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // The optional factory to use when creating new Cursors. May be null. 89e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // INVARIANT: Immutable. 90e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown private final CursorFactory mCursorFactory; 91e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 92e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // Error handler to be used when SQLite returns corruption errors. 93e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // INVARIANT: Immutable. 94e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown private final DatabaseErrorHandler mErrorHandler; 95e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 96e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // Shared database state lock. 97e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // This lock guards all of the shared state of the database, such as its 98e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // configuration, whether it is open or closed, and so on. This lock should 99e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // be held for as little time as possible. 100e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // 101e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // The lock MUST NOT be held while attempting to acquire database connections or 102e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // while executing SQL statements on behalf of the client as it can lead to deadlock. 103e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // 104e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // It is ok to hold the lock while reconfiguring the connection pool or dumping 105e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // statistics because those operations are non-reentrant and do not try to acquire 106e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // connections that might be held by other threads. 107e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // 108e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // Basic rule: grab the lock, access or modify global state, release the lock, then 109e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // do the required SQL work. 110e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown private final Object mLock = new Object(); 111e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 112e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // Warns if the database is finalized without being closed properly. 113e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // INVARIANT: Guarded by mLock. 114e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown private final CloseGuard mCloseGuardLocked = CloseGuard.get(); 115e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 116e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // The database configuration. 117e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // INVARIANT: Guarded by mLock. 118e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown private final SQLiteDatabaseConfiguration mConfigurationLocked; 119e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 120e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // The connection pool for the database, null when closed. 121e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // The pool itself is thread-safe, but the reference to it can only be acquired 122e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // when the lock is held. 123e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // INVARIANT: Guarded by mLock. 124e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown private SQLiteConnectionPool mConnectionPoolLocked; 125e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 126e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // True if the database has attached databases. 127e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // INVARIANT: Guarded by mLock. 128e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown private boolean mHasAttachedDbsLocked; 129e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 130e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown /** 131e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * When a constraint violation occurs, an immediate ROLLBACK occurs, 1328d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori * thus ending the current transaction, and the command aborts with a 1338d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori * return code of SQLITE_CONSTRAINT. If no transaction is active 1348d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori * (other than the implied transaction that is created on every command) 135e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * then this algorithm works the same as ABORT. 1368d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori */ 1378d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori public static final int CONFLICT_ROLLBACK = 1; 138600bdd82f58c7338e68ce2c8f04b17db4cf4f910Dmitri Plotnikov 1398d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori /** 1408d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori * When a constraint violation occurs,no ROLLBACK is executed 1418d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori * so changes from prior commands within the same transaction 1428d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori * are preserved. This is the default behavior. 1438d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori */ 1448d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori public static final int CONFLICT_ABORT = 2; 145600bdd82f58c7338e68ce2c8f04b17db4cf4f910Dmitri Plotnikov 1468d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori /** 1478d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori * When a constraint violation occurs, the command aborts with a return 1488d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori * code SQLITE_CONSTRAINT. But any changes to the database that 1498d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori * the command made prior to encountering the constraint violation 1508d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori * are preserved and are not backed out. 1518d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori */ 1528d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori public static final int CONFLICT_FAIL = 3; 153600bdd82f58c7338e68ce2c8f04b17db4cf4f910Dmitri Plotnikov 1548d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori /** 1558d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori * When a constraint violation occurs, the one row that contains 1568d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori * the constraint violation is not inserted or changed. 1578d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori * But the command continues executing normally. Other rows before and 1588d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori * after the row that contained the constraint violation continue to be 1598d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori * inserted or updated normally. No error is returned. 1608d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori */ 1618d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori public static final int CONFLICT_IGNORE = 4; 162600bdd82f58c7338e68ce2c8f04b17db4cf4f910Dmitri Plotnikov 1638d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori /** 1648d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori * When a UNIQUE constraint violation occurs, the pre-existing rows that 1658d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori * are causing the constraint violation are removed prior to inserting 1668d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori * or updating the current row. Thus the insert or update always occurs. 1678d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori * The command continues executing normally. No error is returned. 1688d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori * If a NOT NULL constraint violation occurs, the NULL value is replaced 1698d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori * by the default value for that column. If the column has no default 1708d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori * value, then the ABORT algorithm is used. If a CHECK constraint 1718d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori * violation occurs then the IGNORE algorithm is used. When this conflict 1728d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori * resolution strategy deletes rows in order to satisfy a constraint, 1738d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori * it does not invoke delete triggers on those rows. 174e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * This behavior might change in a future release. 1758d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori */ 1768d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori public static final int CONFLICT_REPLACE = 5; 1776eb7c45a8fdb774c4094b5012c8496f2a009c032Vasu Nori 1788d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori /** 179e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Use the following when no conflict action is specified. 1808d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori */ 1818d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori public static final int CONFLICT_NONE = 0; 182e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 1838d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori private static final String[] CONFLICT_VALUES = new String[] 1848d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori {"", " OR ROLLBACK ", " OR ABORT ", " OR FAIL ", " OR IGNORE ", " OR REPLACE "}; 185600bdd82f58c7338e68ce2c8f04b17db4cf4f910Dmitri Plotnikov 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Maximum Length Of A LIKE Or GLOB Pattern 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The pattern matching algorithm used in the default LIKE and GLOB implementation 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of SQLite can exhibit O(N^2) performance (where N is the number of characters in 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the pattern) for certain pathological cases. To avoid denial-of-service attacks 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the length of the LIKE or GLOB pattern is limited to SQLITE_MAX_LIKE_PATTERN_LENGTH bytes. 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default value of this limit is 50000. A modern workstation can evaluate 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * even a pathological LIKE or GLOB pattern of 50000 bytes relatively quickly. 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The denial of service problem only comes into play when the pattern length gets 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * into millions of bytes. Nevertheless, since most useful LIKE or GLOB patterns 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * are at most a few dozen bytes in length, paranoid application developers may 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * want to reduce this parameter to something in the range of a few hundred 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if they know that external users are able to generate arbitrary patterns. 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SQLITE_MAX_LIKE_PATTERN_LENGTH = 50000; 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 203e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Open flag: Flag for {@link #openDatabase} to open the database for reading and writing. 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the disk is full, this may fail even before you actually write anything. 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@more} Note that the value of this flag is 0, so it is the default. 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int OPEN_READWRITE = 0x00000000; // update native code if changing 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 211e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Open flag: Flag for {@link #openDatabase} to open the database for reading only. 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is the only reliable way to open a database if the disk may be full. 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int OPEN_READONLY = 0x00000001; // update native code if changing 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int OPEN_READ_MASK = 0x00000001; // update native code if changing 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 219e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Open flag: Flag for {@link #openDatabase} to open the database without support for 220e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * localized collators. 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@more} This causes the collator <code>LOCALIZED</code> not to be created. 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You must be consistent when using this flag to use the setting the database was 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * created with. If this is set, {@link #setLocale} will do nothing. 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int NO_LOCALIZED_COLLATORS = 0x00000010; // update native code if changing 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 229e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Open flag: Flag for {@link #openDatabase} to create the database file if it does not 230e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * already exist. 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int CREATE_IF_NECESSARY = 0x10000000; // update native code if changing 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 23547847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * Open flag: Flag for {@link #openDatabase} to open the database file with 23647847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * write-ahead logging enabled by default. Using this flag is more efficient 23747847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * than calling {@link #enableWriteAheadLogging}. 23847847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * 23947847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * Write-ahead logging cannot be used with read-only databases so the value of 24047847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * this flag is ignored if the database is opened read-only. 24147847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * 24247847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * @see #enableWriteAheadLogging 24347847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown */ 24447847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown public static final int ENABLE_WRITE_AHEAD_LOGGING = 0x20000000; 24547847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown 24647847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown /** 247e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Absolute max value that can be set by {@link #setMaxSqlCacheSize(int)}. 248b729dcc8a94bc2c2a1ecda47d791be0d6f1d160aVasu Nori * 249e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Each prepared-statement is between 1K - 6K, depending on the complexity of the 250e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * SQL statement & schema. A large SQL cache may use a significant amount of memory. 251e495d1f74af13aec8d5d825e93e4cfe1e4fe7468Vasu Nori */ 25290a36726b7553a1e7efd2f4ecbe01d7e1b3e7a67Vasu Nori public static final int MAX_SQL_CACHE_SIZE = 100; 253a98cb2632dcf07ebd8d036f61c1438f795e262ccVasu Nori 254e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown private SQLiteDatabase(String path, int openFlags, CursorFactory cursorFactory, 255e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown DatabaseErrorHandler errorHandler) { 256e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown mCursorFactory = cursorFactory; 257e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown mErrorHandler = errorHandler != null ? errorHandler : new DefaultDatabaseErrorHandler(); 258e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown mConfigurationLocked = new SQLiteDatabaseConfiguration(path, openFlags); 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 260600bdd82f58c7338e68ce2c8f04b17db4cf4f910Dmitri Plotnikov 261e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown @Override 262e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown protected void finalize() throws Throwable { 263e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown try { 264e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown dispose(true); 265e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } finally { 266e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown super.finalize(); 267e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 268600bdd82f58c7338e68ce2c8f04b17db4cf4f910Dmitri Plotnikov } 269600bdd82f58c7338e68ce2c8f04b17db4cf4f910Dmitri Plotnikov 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onAllReferencesReleased() { 272e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown dispose(false); 273e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 274e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 275e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown private void dispose(boolean finalized) { 276e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown final SQLiteConnectionPool pool; 277e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown synchronized (mLock) { 278e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown if (mCloseGuardLocked != null) { 279e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown if (finalized) { 280e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown mCloseGuardLocked.warnIfOpen(); 281e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 282e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown mCloseGuardLocked.close(); 283e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 284e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 285e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown pool = mConnectionPoolLocked; 286e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown mConnectionPoolLocked = null; 287e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 288e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 289e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown if (!finalized) { 290e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown synchronized (sActiveDatabases) { 291e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown sActiveDatabases.remove(this); 292e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 293e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 294e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown if (pool != null) { 295e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown pool.close(); 296e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Attempts to release memory that SQLite holds but does not require to 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * operate properly. Typically this memory will come from the page cache. 303600bdd82f58c7338e68ce2c8f04b17db4cf4f910Dmitri Plotnikov * 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the number of bytes actually released 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 306e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown public static int releaseMemory() { 307e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown return SQLiteGlobal.releaseMemory(); 308e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Control whether or not the SQLiteDatabase is made thread-safe by using locks 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * around critical sections. This is pretty expensive, so if you know that your 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * DB will only be used by a single thread then you should set this to false. 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The default is true. 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param lockingEnabled set to true to enable locks, false otherwise 316e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * 317e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * @deprecated This method now does nothing. Do not use. 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 319e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown @Deprecated 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setLockingEnabled(boolean lockingEnabled) { 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 324e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Gets a label to use when describing the database in log messages. 325e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * @return The label. 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 327e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown String getLabel() { 328e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown synchronized (mLock) { 329e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown return mConfigurationLocked.label; 330e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 334e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Sends a corruption message to the database error handler. 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 336e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown void onCorruption() { 337e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown EventLog.writeEvent(EVENT_DB_CORRUPT, getLabel()); 338e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown mErrorHandler.onCorruption(this); 339d4608a35e89c2604194b314ff9babb07ba8a14e1Vasu Nori } 340d4608a35e89c2604194b314ff9babb07ba8a14e1Vasu Nori 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 342e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Gets the {@link SQLiteSession} that belongs to this thread for this database. 343e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Once a thread has obtained a session, it will continue to obtain the same 344e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * session even after the database has been closed (although the session will not 345e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * be usable). However, a thread that does not already have a session cannot 346e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * obtain one after the database has been closed. 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 348e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * The idea is that threads that have active connections to the database may still 349e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * have work to complete even after the call to {@link #close}. Active database 350e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * connections are not actually disposed until they are released by the threads 351e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * that own them. 352e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * 353e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * @return The session, never null. 354e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * 355e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * @throws IllegalStateException if the thread does not yet have a session and 356e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * the database is not open. 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 358e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown SQLiteSession getThreadSession() { 359e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown return mThreadSession.get(); // initialValue() throws if database closed 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 362e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown SQLiteSession createSession() { 363e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown final SQLiteConnectionPool pool; 364e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown synchronized (mLock) { 365e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown throwIfNotOpenLocked(); 366e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown pool = mConnectionPoolLocked; 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 368e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown return new SQLiteSession(pool); 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 372e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Gets default connection flags that are appropriate for this thread, taking into 373e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * account whether the thread is acting on behalf of the UI. 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 375e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * @param readOnly True if the connection should be read-only. 376e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * @return The connection flags. 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 378e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown int getThreadDefaultConnectionFlags(boolean readOnly) { 379e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown int flags = readOnly ? SQLiteConnectionPool.CONNECTION_FLAG_READ_ONLY : 380e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown SQLiteConnectionPool.CONNECTION_FLAG_PRIMARY_CONNECTION_AFFINITY; 381e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown if (isMainThread()) { 382e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown flags |= SQLiteConnectionPool.CONNECTION_FLAG_INTERACTIVE; 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 384e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown return flags; 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 387e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown private static boolean isMainThread() { 388e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // FIXME: There should be a better way to do this. 389e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // Would also be nice to have something that would work across Binder calls. 390e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown Looper looper = Looper.myLooper(); 391e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown return looper != null && looper == Looper.getMainLooper(); 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 395ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * Begins a transaction in EXCLUSIVE mode. 396ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * <p> 397ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * Transactions can be nested. 398ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * When the outer transaction is ended all of 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the work done in that transaction and all of the nested transactions will be committed or 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * rolled back. The changes will be rolled back if any transaction is ended without being 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * marked as clean (by calling setTransactionSuccessful). Otherwise they will be committed. 402ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * </p> 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Here is the standard idiom for transactions: 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre> 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * db.beginTransaction(); 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * try { 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ... 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * db.setTransactionSuccessful(); 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * } finally { 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * db.endTransaction(); 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * } 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </pre> 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void beginTransaction() { 4166c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori beginTransaction(null /* transactionStatusCallback */, true); 4176c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori } 4186c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori 4196c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori /** 4206c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * Begins a transaction in IMMEDIATE mode. Transactions can be nested. When 4216c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * the outer transaction is ended all of the work done in that transaction 4226c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * and all of the nested transactions will be committed or rolled back. The 4236c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * changes will be rolled back if any transaction is ended without being 4246c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * marked as clean (by calling setTransactionSuccessful). Otherwise they 4256c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * will be committed. 4266c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * <p> 4276c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * Here is the standard idiom for transactions: 4286c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * 4296c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * <pre> 4306c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * db.beginTransactionNonExclusive(); 4316c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * try { 4326c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * ... 4336c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * db.setTransactionSuccessful(); 4346c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * } finally { 4356c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * db.endTransaction(); 4366c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * } 4376c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * </pre> 4386c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori */ 4396c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori public void beginTransactionNonExclusive() { 4406c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori beginTransaction(null /* transactionStatusCallback */, false); 441c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana } 442c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana 443c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana /** 444ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * Begins a transaction in EXCLUSIVE mode. 445ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * <p> 446ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * Transactions can be nested. 447ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * When the outer transaction is ended all of 448c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana * the work done in that transaction and all of the nested transactions will be committed or 449c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana * rolled back. The changes will be rolled back if any transaction is ended without being 450c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana * marked as clean (by calling setTransactionSuccessful). Otherwise they will be committed. 451ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * </p> 452c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana * <p>Here is the standard idiom for transactions: 453c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana * 454c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana * <pre> 455c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana * db.beginTransactionWithListener(listener); 456c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana * try { 457c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana * ... 458c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana * db.setTransactionSuccessful(); 459c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana * } finally { 460c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana * db.endTransaction(); 461c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana * } 462c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana * </pre> 463ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * 464c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana * @param transactionListener listener that should be notified when the transaction begins, 465c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana * commits, or is rolled back, either explicitly or by a call to 466c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana * {@link #yieldIfContendedSafely}. 467c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana */ 468c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana public void beginTransactionWithListener(SQLiteTransactionListener transactionListener) { 4696c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori beginTransaction(transactionListener, true); 4706c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori } 4716c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori 4726c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori /** 4736c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * Begins a transaction in IMMEDIATE mode. Transactions can be nested. When 4746c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * the outer transaction is ended all of the work done in that transaction 4756c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * and all of the nested transactions will be committed or rolled back. The 4766c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * changes will be rolled back if any transaction is ended without being 4776c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * marked as clean (by calling setTransactionSuccessful). Otherwise they 4786c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * will be committed. 4796c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * <p> 4806c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * Here is the standard idiom for transactions: 4816c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * 4826c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * <pre> 4836c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * db.beginTransactionWithListenerNonExclusive(listener); 4846c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * try { 4856c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * ... 4866c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * db.setTransactionSuccessful(); 4876c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * } finally { 4886c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * db.endTransaction(); 4896c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * } 4906c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * </pre> 4916c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * 4926c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * @param transactionListener listener that should be notified when the 4936c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * transaction begins, commits, or is rolled back, either 4946c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * explicitly or by a call to {@link #yieldIfContendedSafely}. 4956c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori */ 4966c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori public void beginTransactionWithListenerNonExclusive( 4976c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori SQLiteTransactionListener transactionListener) { 4986c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori beginTransaction(transactionListener, false); 4996c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori } 5006c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori 5016c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori private void beginTransaction(SQLiteTransactionListener transactionListener, 5026c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori boolean exclusive) { 50303bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown acquireReference(); 50403bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown try { 50503bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown getThreadSession().beginTransaction( 50603bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown exclusive ? SQLiteSession.TRANSACTION_MODE_EXCLUSIVE : 50703bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown SQLiteSession.TRANSACTION_MODE_IMMEDIATE, 50803bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown transactionListener, 50903bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown getThreadDefaultConnectionFlags(false /*readOnly*/), null); 51003bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } finally { 51103bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown releaseReference(); 51203bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * End a transaction. See beginTransaction for notes about how to use this and when transactions 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * are committed and rolled back. 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void endTransaction() { 52003bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown acquireReference(); 52103bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown try { 52203bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown getThreadSession().endTransaction(null); 52303bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } finally { 52403bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown releaseReference(); 52503bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Marks the current transaction as successful. Do not do any more database work between 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * calling this and calling endTransaction. Do as little non-database work as possible in that 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * situation too. If any errors are encountered between this and endTransaction the transaction 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will still be committed. 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException if the current thread is not in a transaction or the 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * transaction is already marked as successful. 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTransactionSuccessful() { 53803bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown acquireReference(); 53903bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown try { 54003bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown getThreadSession().setTransactionSuccessful(); 54103bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } finally { 54203bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown releaseReference(); 54303bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 547e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Returns true if the current thread has a transaction pending. 548e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * 549e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * @return True if the current thread is in a transaction. 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean inTransaction() { 55203bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown acquireReference(); 55303bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown try { 55403bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown return getThreadSession().hasTransaction(); 55503bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } finally { 55603bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown releaseReference(); 55703bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } 558ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori } 559ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori 560ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori /** 561e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Returns true if the current thread is holding an active connection to the database. 562ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori * <p> 563e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * The name of this method comes from a time when having an active connection 564e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * to the database meant that the thread was holding an actual lock on the 565e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * database. Nowadays, there is no longer a true "database lock" although threads 566e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * may block if they cannot acquire a database connection to perform a 567e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * particular operation. 568e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * </p> 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 570e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * @return True if the current thread is holding an active connection to the database. 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isDbLockedByCurrentThread() { 57303bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown acquireReference(); 57403bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown try { 57503bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown return getThreadSession().hasConnection(); 57603bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } finally { 57703bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown releaseReference(); 57803bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 582e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Always returns false. 583e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * <p> 584e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * There is no longer the concept of a database lock, so this method always returns false. 585e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * </p> 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 587e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * @return False. 588e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * @deprecated Always returns false. Do not use this method. 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 590e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown @Deprecated 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isDbLockedByOtherThreads() { 592e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown return false; 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Temporarily end the transaction to let other threads run. The transaction is assumed to be 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * successful so far. Do not call setTransactionSuccessful before calling this. When this 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * returns a new transaction will have been created but not marked as successful. 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the transaction was yielded 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated if the db is locked more than once (becuase of nested transactions) then the lock 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will not be yielded. Use yieldIfContendedSafely instead. 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6034a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn @Deprecated 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean yieldIfContended() { 6055c7aede8d69f4f0ad617d39decd4453b029ba6afFred Quintana return yieldIfContendedHelper(false /* do not check yielding */, 6065c7aede8d69f4f0ad617d39decd4453b029ba6afFred Quintana -1 /* sleepAfterYieldDelay */); 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Temporarily end the transaction to let other threads run. The transaction is assumed to be 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * successful so far. Do not call setTransactionSuccessful before calling this. When this 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * returns a new transaction will have been created but not marked as successful. This assumes 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that there are no nested transactions (beginTransaction has only been called once) and will 6145c7aede8d69f4f0ad617d39decd4453b029ba6afFred Quintana * throw an exception if that is not the case. 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the transaction was yielded 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean yieldIfContendedSafely() { 6185c7aede8d69f4f0ad617d39decd4453b029ba6afFred Quintana return yieldIfContendedHelper(true /* check yielding */, -1 /* sleepAfterYieldDelay*/); 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6215c7aede8d69f4f0ad617d39decd4453b029ba6afFred Quintana /** 6225c7aede8d69f4f0ad617d39decd4453b029ba6afFred Quintana * Temporarily end the transaction to let other threads run. The transaction is assumed to be 6235c7aede8d69f4f0ad617d39decd4453b029ba6afFred Quintana * successful so far. Do not call setTransactionSuccessful before calling this. When this 6245c7aede8d69f4f0ad617d39decd4453b029ba6afFred Quintana * returns a new transaction will have been created but not marked as successful. This assumes 6255c7aede8d69f4f0ad617d39decd4453b029ba6afFred Quintana * that there are no nested transactions (beginTransaction has only been called once) and will 6265c7aede8d69f4f0ad617d39decd4453b029ba6afFred Quintana * throw an exception if that is not the case. 6275c7aede8d69f4f0ad617d39decd4453b029ba6afFred Quintana * @param sleepAfterYieldDelay if > 0, sleep this long before starting a new transaction if 6285c7aede8d69f4f0ad617d39decd4453b029ba6afFred Quintana * the lock was actually yielded. This will allow other background threads to make some 6295c7aede8d69f4f0ad617d39decd4453b029ba6afFred Quintana * more progress than they would if we started the transaction immediately. 6305c7aede8d69f4f0ad617d39decd4453b029ba6afFred Quintana * @return true if the transaction was yielded 6315c7aede8d69f4f0ad617d39decd4453b029ba6afFred Quintana */ 6325c7aede8d69f4f0ad617d39decd4453b029ba6afFred Quintana public boolean yieldIfContendedSafely(long sleepAfterYieldDelay) { 6335c7aede8d69f4f0ad617d39decd4453b029ba6afFred Quintana return yieldIfContendedHelper(true /* check yielding */, sleepAfterYieldDelay); 6345c7aede8d69f4f0ad617d39decd4453b029ba6afFred Quintana } 6355c7aede8d69f4f0ad617d39decd4453b029ba6afFred Quintana 636e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown private boolean yieldIfContendedHelper(boolean throwIfUnsafe, long sleepAfterYieldDelay) { 63703bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown acquireReference(); 63803bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown try { 63903bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown return getThreadSession().yieldTransaction(sleepAfterYieldDelay, throwIfUnsafe, null); 64003bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } finally { 64103bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown releaseReference(); 64203bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 646e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Deprecated. 64795675137f417173dc711a2d39232a1f545799013Vasu Nori * @deprecated This method no longer serves any useful purpose and has been deprecated. 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 64995675137f417173dc711a2d39232a1f545799013Vasu Nori @Deprecated 65095675137f417173dc711a2d39232a1f545799013Vasu Nori public Map<String, String> getSyncedTables() { 65195675137f417173dc711a2d39232a1f545799013Vasu Nori return new HashMap<String, String>(0); 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open the database according to the flags {@link #OPEN_READWRITE} 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #OPEN_READONLY} {@link #CREATE_IF_NECESSARY} and/or {@link #NO_LOCALIZED_COLLATORS}. 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Sets the locale of the database to the the system's current locale. 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Call {@link #setLocale} if you would like something else.</p> 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param path to database file to open and/or create 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param factory an optional factory class that is called to instantiate a 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * cursor when query is called, or null for default 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param flags to control database access mode 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the newly opened database 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws SQLiteException if the database cannot be opened 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags) { 66947847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown return openDatabase(path, factory, flags, null); 670062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori } 671062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori 672062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori /** 67374f170f9468d3cf6d7d0ef453320141a3e63571bVasu Nori * Open the database according to the flags {@link #OPEN_READWRITE} 67474f170f9468d3cf6d7d0ef453320141a3e63571bVasu Nori * {@link #OPEN_READONLY} {@link #CREATE_IF_NECESSARY} and/or {@link #NO_LOCALIZED_COLLATORS}. 67574f170f9468d3cf6d7d0ef453320141a3e63571bVasu Nori * 67674f170f9468d3cf6d7d0ef453320141a3e63571bVasu Nori * <p>Sets the locale of the database to the the system's current locale. 67774f170f9468d3cf6d7d0ef453320141a3e63571bVasu Nori * Call {@link #setLocale} if you would like something else.</p> 67874f170f9468d3cf6d7d0ef453320141a3e63571bVasu Nori * 67974f170f9468d3cf6d7d0ef453320141a3e63571bVasu Nori * <p>Accepts input param: a concrete instance of {@link DatabaseErrorHandler} to be 68074f170f9468d3cf6d7d0ef453320141a3e63571bVasu Nori * used to handle corruption when sqlite reports database corruption.</p> 68174f170f9468d3cf6d7d0ef453320141a3e63571bVasu Nori * 68274f170f9468d3cf6d7d0ef453320141a3e63571bVasu Nori * @param path to database file to open and/or create 68374f170f9468d3cf6d7d0ef453320141a3e63571bVasu Nori * @param factory an optional factory class that is called to instantiate a 68474f170f9468d3cf6d7d0ef453320141a3e63571bVasu Nori * cursor when query is called, or null for default 68574f170f9468d3cf6d7d0ef453320141a3e63571bVasu Nori * @param flags to control database access mode 68674f170f9468d3cf6d7d0ef453320141a3e63571bVasu Nori * @param errorHandler the {@link DatabaseErrorHandler} obj to be used to handle corruption 68774f170f9468d3cf6d7d0ef453320141a3e63571bVasu Nori * when sqlite reports database corruption 68874f170f9468d3cf6d7d0ef453320141a3e63571bVasu Nori * @return the newly opened database 68974f170f9468d3cf6d7d0ef453320141a3e63571bVasu Nori * @throws SQLiteException if the database cannot be opened 690062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori */ 691062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags, 692062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori DatabaseErrorHandler errorHandler) { 693e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown SQLiteDatabase db = new SQLiteDatabase(path, flags, factory, errorHandler); 694e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown db.open(); 695e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown return db; 696062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori } 697062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Equivalent to openDatabase(file.getPath(), factory, CREATE_IF_NECESSARY). 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static SQLiteDatabase openOrCreateDatabase(File file, CursorFactory factory) { 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return openOrCreateDatabase(file.getPath(), factory); 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Equivalent to openDatabase(path, factory, CREATE_IF_NECESSARY). 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static SQLiteDatabase openOrCreateDatabase(String path, CursorFactory factory) { 70947847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown return openDatabase(path, factory, CREATE_IF_NECESSARY, null); 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7136c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * Equivalent to openDatabase(path, factory, CREATE_IF_NECESSARY, errorHandler). 714062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori */ 715062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori public static SQLiteDatabase openOrCreateDatabase(String path, CursorFactory factory, 716062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori DatabaseErrorHandler errorHandler) { 717062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori return openDatabase(path, factory, CREATE_IF_NECESSARY, errorHandler); 718062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori } 719062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori 720559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown /** 72179087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown * Deletes a database including its journal file and other auxiliary files 72279087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown * that may have been created by the database engine. 72379087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown * 72479087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown * @param file The database file path. 72579087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown * @return True if the database was successfully deleted. 72679087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown */ 72779087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown public static boolean deleteDatabase(File file) { 72879087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown if (file == null) { 72979087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown throw new IllegalArgumentException("file must not be null"); 73079087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown } 73179087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown 73279087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown boolean deleted = false; 73379087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown deleted |= file.delete(); 73479087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown deleted |= new File(file.getPath() + "-journal").delete(); 73579087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown deleted |= new File(file.getPath() + "-shm").delete(); 73679087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown deleted |= new File(file.getPath() + "-wal").delete(); 73779087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown 73879087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown File dir = file.getParentFile(); 73979087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown if (dir != null) { 74079087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown final String prefix = file.getName() + "-mj"; 74179087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown final FileFilter filter = new FileFilter() { 74279087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown @Override 74379087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown public boolean accept(File candidate) { 74479087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown return candidate.getName().startsWith(prefix); 74579087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown } 74679087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown }; 74779087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown for (File masterJournal : dir.listFiles(filter)) { 74879087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown deleted |= masterJournal.delete(); 74979087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown } 75079087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown } 75179087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown return deleted; 75279087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown } 75379087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown 75479087e4b967d8af26c488c41b8c1a087a12da84dJeff Brown /** 755559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown * Reopens the database in read-write mode. 756559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown * If the database is already read-write, does nothing. 757559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown * 758559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown * @throws SQLiteException if the database could not be reopened as requested, in which 759559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown * case it remains open in read only mode. 760559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown * @throws IllegalStateException if the database is not open. 761559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown * 762559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown * @see #isReadOnly() 763559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown * @hide 764559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown */ 765559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown public void reopenReadWrite() { 766559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown synchronized (mLock) { 767559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown throwIfNotOpenLocked(); 768559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown 769559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown if (!isReadOnlyLocked()) { 770559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown return; // nothing to do 771559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown } 772559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown 773559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown // Reopen the database in read-write mode. 774559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown final int oldOpenFlags = mConfigurationLocked.openFlags; 775559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown mConfigurationLocked.openFlags = (mConfigurationLocked.openFlags & ~OPEN_READ_MASK) 776559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown | OPEN_READWRITE; 777559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown try { 778559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown mConnectionPoolLocked.reconfigure(mConfigurationLocked); 779559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown } catch (RuntimeException ex) { 780559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown mConfigurationLocked.openFlags = oldOpenFlags; 781559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown throw ex; 782559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown } 783559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown } 784559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown } 785559d0645ac8f80491671fa5d3c63e8f296f2909eJeff Brown 786e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown private void open() { 787e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown try { 788e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown try { 789e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown openInner(); 790e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } catch (SQLiteDatabaseCorruptException ex) { 791e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown onCorruption(); 792e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown openInner(); 793e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 794e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } catch (SQLiteException ex) { 795e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown Log.e(TAG, "Failed to open database '" + getLabel() + "'.", ex); 796e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown close(); 797e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown throw ex; 798e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 799e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 800e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 801e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown private void openInner() { 802e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown synchronized (mLock) { 803e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown assert mConnectionPoolLocked == null; 804e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown mConnectionPoolLocked = SQLiteConnectionPool.open(mConfigurationLocked); 805e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown mCloseGuardLocked.open("close"); 806e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 807e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 808e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown synchronized (sActiveDatabases) { 809e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown sActiveDatabases.put(this, null); 810e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 811e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 812e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 813062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori /** 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create a memory backed SQLite database. Its contents will be destroyed 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * when the database is closed. 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Sets the locale of the database to the the system's current locale. 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Call {@link #setLocale} if you would like something else.</p> 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param factory an optional factory class that is called to instantiate a 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * cursor when query is called 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return a SQLiteDatabase object, or null if the database can't be created 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static SQLiteDatabase create(CursorFactory factory) { 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is a magic string with special meaning for SQLite. 826e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown return openDatabase(SQLiteDatabaseConfiguration.MEMORY_DB_PATH, 827e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown factory, CREATE_IF_NECESSARY); 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8319d9c1be296db26c6ad36b8593fb77ca263422665Mike Lockwood * Registers a CustomFunction callback as a function that can be called from 832e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * SQLite database triggers. 833e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * 8349d9c1be296db26c6ad36b8593fb77ca263422665Mike Lockwood * @param name the name of the sqlite3 function 8359d9c1be296db26c6ad36b8593fb77ca263422665Mike Lockwood * @param numArgs the number of arguments for the function 8369d9c1be296db26c6ad36b8593fb77ca263422665Mike Lockwood * @param function callback to call when the function is executed 8379d9c1be296db26c6ad36b8593fb77ca263422665Mike Lockwood * @hide 8389d9c1be296db26c6ad36b8593fb77ca263422665Mike Lockwood */ 8399d9c1be296db26c6ad36b8593fb77ca263422665Mike Lockwood public void addCustomFunction(String name, int numArgs, CustomFunction function) { 840e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // Create wrapper (also validates arguments). 841e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown SQLiteCustomFunction wrapper = new SQLiteCustomFunction(name, numArgs, function); 8429d9c1be296db26c6ad36b8593fb77ca263422665Mike Lockwood 843e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown synchronized (mLock) { 844e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown throwIfNotOpenLocked(); 845e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown 846e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown mConfigurationLocked.customFunctions.add(wrapper); 847e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown try { 848e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown mConnectionPoolLocked.reconfigure(mConfigurationLocked); 849e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown } catch (RuntimeException ex) { 850e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown mConfigurationLocked.customFunctions.remove(wrapper); 851e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown throw ex; 852e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown } 8539d9c1be296db26c6ad36b8593fb77ca263422665Mike Lockwood } 8549d9c1be296db26c6ad36b8593fb77ca263422665Mike Lockwood } 8559d9c1be296db26c6ad36b8593fb77ca263422665Mike Lockwood 8569d9c1be296db26c6ad36b8593fb77ca263422665Mike Lockwood /** 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Gets the database version. 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the database version 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getVersion() { 862ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori return ((Long) DatabaseUtils.longForQuery(this, "PRAGMA user_version;", null)).intValue(); 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the database version. 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param version the new database version 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setVersion(int version) { 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project execSQL("PRAGMA user_version = " + version); 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the maximum size the database may grow to. 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the new maximum database size 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long getMaximumSize() { 880ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori long pageCount = DatabaseUtils.longForQuery(this, "PRAGMA max_page_count;", null); 881ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori return pageCount * getPageSize(); 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the maximum size the database will grow to. The maximum size cannot 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * be set below the current size. 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param numBytes the maximum database size, in bytes 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the new maximum database size 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long setMaximumSize(long numBytes) { 892ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori long pageSize = getPageSize(); 893ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori long numPages = numBytes / pageSize; 894ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori // If numBytes isn't a multiple of pageSize, bump up a page 895ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori if ((numBytes % pageSize) != 0) { 896ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori numPages++; 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 898ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori long newPageCount = DatabaseUtils.longForQuery(this, "PRAGMA max_page_count = " + numPages, 899ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori null); 900ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori return newPageCount * pageSize; 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the current database page size, in bytes. 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the database page size, in bytes 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long getPageSize() { 909ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori return DatabaseUtils.longForQuery(this, "PRAGMA page_size;", null); 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the database page size. The page size must be a power of two. This 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * method does not work if any data has been written to the database file, 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and must be called right after the database has been created. 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param numBytes the database page size, in bytes 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setPageSize(long numBytes) { 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project execSQL("PRAGMA page_size = " + numBytes); 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Mark this table as syncable. When an update occurs in this table the 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * _sync_dirty field will be set to ensure proper syncing operation. 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param table the table to mark as syncable 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param deletedTable The deleted table that corresponds to the 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * syncable table 93095675137f417173dc711a2d39232a1f545799013Vasu Nori * @deprecated This method no longer serves any useful purpose and has been deprecated. 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 93295675137f417173dc711a2d39232a1f545799013Vasu Nori @Deprecated 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void markTableSyncable(String table, String deletedTable) { 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Mark this table as syncable, with the _sync_dirty residing in another 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * table. When an update occurs in this table the _sync_dirty field of the 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * row in updateTable with the _id in foreignKey will be set to 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ensure proper syncing operation. 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param table an update on this table will trigger a sync time removal 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param foreignKey this is the column in table whose value is an _id in 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * updateTable 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param updateTable this is the table that will have its _sync_dirty 94695675137f417173dc711a2d39232a1f545799013Vasu Nori * @deprecated This method no longer serves any useful purpose and has been deprecated. 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 94895675137f417173dc711a2d39232a1f545799013Vasu Nori @Deprecated 94995675137f417173dc711a2d39232a1f545799013Vasu Nori public void markTableSyncable(String table, String foreignKey, String updateTable) { 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Finds the name of the first table, which is editable. 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param tables a list of tables 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the first table listed 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static String findEditTable(String tables) { 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!TextUtils.isEmpty(tables)) { 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // find the first word terminated by either a space or a comma 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int spacepos = tables.indexOf(' '); 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int commapos = tables.indexOf(','); 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (spacepos > 0 && (spacepos < commapos || commapos < 0)) { 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return tables.substring(0, spacepos); 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (commapos > 0 && (commapos < spacepos || spacepos < 0) ) { 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return tables.substring(0, commapos); 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return tables; 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalStateException("Invalid tables"); 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Compiles an SQL statement into a reusable pre-compiled statement object. 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The parameters are identical to {@link #execSQL(String)}. You may put ?s in the 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * statement and fill in those values with {@link SQLiteProgram#bindString} 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and {@link SQLiteProgram#bindLong} each time you want to run the 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * statement. Statements may not return result sets larger than 1x1. 9812827d6d974beabb12344040a002dcb52dd7106b5Vasu Nori *<p> 9822827d6d974beabb12344040a002dcb52dd7106b5Vasu Nori * No two threads should be using the same {@link SQLiteStatement} at the same time. 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sql The raw SQL statement, may contain ? for unknown values to be 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * bound later. 986f3ca9a5c7e87319c934b5815566054d2e5c2085fJeff Hamilton * @return A pre-compiled {@link SQLiteStatement} object. Note that 987f3ca9a5c7e87319c934b5815566054d2e5c2085fJeff Hamilton * {@link SQLiteStatement}s are not synchronized, see the documentation for more details. 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public SQLiteStatement compileStatement(String sql) throws SQLException { 99003bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown acquireReference(); 99103bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown try { 99203bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown return new SQLiteStatement(this, sql, null); 99303bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } finally { 99403bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown releaseReference(); 99503bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Query the given URL, returning a {@link Cursor} over the result set. 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param distinct true if you want each row to be unique, false otherwise. 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param table The table name to compile the query against. 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param columns A list of which columns to return. Passing null will 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * return all columns, which is discouraged to prevent reading 10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * data from storage that isn't going to be used. 10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selection A filter declaring which rows to return, formatted as an 10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * SQL WHERE clause (excluding the WHERE itself). Passing null 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will return all rows for the given table. 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selectionArgs You may include ?s in selection, which will be 10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * replaced by the values from selectionArgs, in order that they 10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * appear in the selection. The values will be bound as Strings. 10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param groupBy A filter declaring how to group rows, formatted as an SQL 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * GROUP BY clause (excluding the GROUP BY itself). Passing null 10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will cause the rows to not be grouped. 10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param having A filter declare which row groups to include in the cursor, 10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if row grouping is being used, formatted as an SQL HAVING 10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clause (excluding the HAVING itself). Passing null will cause 10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * all row groups to be included, and is required when row 10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * grouping is not being used. 10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause 10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * (excluding the ORDER BY itself). Passing null will use the 10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * default sort order, which may be unordered. 10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param limit Limits the number of rows returned by the query, 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * formatted as LIMIT clause. Passing null denotes no LIMIT clause. 1025f3ca9a5c7e87319c934b5815566054d2e5c2085fJeff Hamilton * @return A {@link Cursor} object, which is positioned before the first entry. Note that 1026f3ca9a5c7e87319c934b5815566054d2e5c2085fJeff Hamilton * {@link Cursor}s are not synchronized, see the documentation for more details. 10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see Cursor 10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Cursor query(boolean distinct, String table, String[] columns, 10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String selection, String[] selectionArgs, String groupBy, 10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String having, String orderBy, String limit) { 10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return queryWithFactory(null, distinct, table, columns, selection, selectionArgs, 103375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown groupBy, having, orderBy, limit, null); 103475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown } 103575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown 103675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown /** 103775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * Query the given URL, returning a {@link Cursor} over the result set. 103875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * 103975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param distinct true if you want each row to be unique, false otherwise. 104075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param table The table name to compile the query against. 104175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param columns A list of which columns to return. Passing null will 104275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * return all columns, which is discouraged to prevent reading 104375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * data from storage that isn't going to be used. 104475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param selection A filter declaring which rows to return, formatted as an 104575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * SQL WHERE clause (excluding the WHERE itself). Passing null 104675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * will return all rows for the given table. 104775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param selectionArgs You may include ?s in selection, which will be 104875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * replaced by the values from selectionArgs, in order that they 104975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * appear in the selection. The values will be bound as Strings. 105075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param groupBy A filter declaring how to group rows, formatted as an SQL 105175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * GROUP BY clause (excluding the GROUP BY itself). Passing null 105275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * will cause the rows to not be grouped. 105375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param having A filter declare which row groups to include in the cursor, 105475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * if row grouping is being used, formatted as an SQL HAVING 105575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * clause (excluding the HAVING itself). Passing null will cause 105675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * all row groups to be included, and is required when row 105775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * grouping is not being used. 105875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause 105975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * (excluding the ORDER BY itself). Passing null will use the 106075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * default sort order, which may be unordered. 106175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param limit Limits the number of rows returned by the query, 106275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * formatted as LIMIT clause. Passing null denotes no LIMIT clause. 10634c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown * @param cancellationSignal A signal to cancel the operation in progress, or null if none. 106475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * If the operation is canceled, then {@link OperationCanceledException} will be thrown 106575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * when the query is executed. 106675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @return A {@link Cursor} object, which is positioned before the first entry. Note that 106775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * {@link Cursor}s are not synchronized, see the documentation for more details. 106875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @see Cursor 106975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown */ 107075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown public Cursor query(boolean distinct, String table, String[] columns, 107175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown String selection, String[] selectionArgs, String groupBy, 10724c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown String having, String orderBy, String limit, CancellationSignal cancellationSignal) { 107375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown return queryWithFactory(null, distinct, table, columns, selection, selectionArgs, 10744c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown groupBy, having, orderBy, limit, cancellationSignal); 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Query the given URL, returning a {@link Cursor} over the result set. 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param cursorFactory the cursor factory to use, or null for the default factory 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param distinct true if you want each row to be unique, false otherwise. 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param table The table name to compile the query against. 10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param columns A list of which columns to return. Passing null will 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * return all columns, which is discouraged to prevent reading 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * data from storage that isn't going to be used. 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selection A filter declaring which rows to return, formatted as an 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * SQL WHERE clause (excluding the WHERE itself). Passing null 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will return all rows for the given table. 10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selectionArgs You may include ?s in selection, which will be 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * replaced by the values from selectionArgs, in order that they 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * appear in the selection. The values will be bound as Strings. 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param groupBy A filter declaring how to group rows, formatted as an SQL 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * GROUP BY clause (excluding the GROUP BY itself). Passing null 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will cause the rows to not be grouped. 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param having A filter declare which row groups to include in the cursor, 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if row grouping is being used, formatted as an SQL HAVING 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clause (excluding the HAVING itself). Passing null will cause 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * all row groups to be included, and is required when row 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * grouping is not being used. 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * (excluding the ORDER BY itself). Passing null will use the 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * default sort order, which may be unordered. 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param limit Limits the number of rows returned by the query, 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * formatted as LIMIT clause. Passing null denotes no LIMIT clause. 1105f3ca9a5c7e87319c934b5815566054d2e5c2085fJeff Hamilton * @return A {@link Cursor} object, which is positioned before the first entry. Note that 1106f3ca9a5c7e87319c934b5815566054d2e5c2085fJeff Hamilton * {@link Cursor}s are not synchronized, see the documentation for more details. 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see Cursor 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Cursor queryWithFactory(CursorFactory cursorFactory, 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean distinct, String table, String[] columns, 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String selection, String[] selectionArgs, String groupBy, 11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String having, String orderBy, String limit) { 111375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown return queryWithFactory(cursorFactory, distinct, table, columns, selection, 111475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown selectionArgs, groupBy, having, orderBy, limit, null); 111575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown } 111675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown 111775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown /** 111875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * Query the given URL, returning a {@link Cursor} over the result set. 111975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * 112075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param cursorFactory the cursor factory to use, or null for the default factory 112175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param distinct true if you want each row to be unique, false otherwise. 112275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param table The table name to compile the query against. 112375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param columns A list of which columns to return. Passing null will 112475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * return all columns, which is discouraged to prevent reading 112575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * data from storage that isn't going to be used. 112675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param selection A filter declaring which rows to return, formatted as an 112775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * SQL WHERE clause (excluding the WHERE itself). Passing null 112875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * will return all rows for the given table. 112975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param selectionArgs You may include ?s in selection, which will be 113075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * replaced by the values from selectionArgs, in order that they 113175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * appear in the selection. The values will be bound as Strings. 113275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param groupBy A filter declaring how to group rows, formatted as an SQL 113375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * GROUP BY clause (excluding the GROUP BY itself). Passing null 113475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * will cause the rows to not be grouped. 113575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param having A filter declare which row groups to include in the cursor, 113675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * if row grouping is being used, formatted as an SQL HAVING 113775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * clause (excluding the HAVING itself). Passing null will cause 113875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * all row groups to be included, and is required when row 113975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * grouping is not being used. 114075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause 114175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * (excluding the ORDER BY itself). Passing null will use the 114275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * default sort order, which may be unordered. 114375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param limit Limits the number of rows returned by the query, 114475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * formatted as LIMIT clause. Passing null denotes no LIMIT clause. 11454c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown * @param cancellationSignal A signal to cancel the operation in progress, or null if none. 114675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * If the operation is canceled, then {@link OperationCanceledException} will be thrown 114775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * when the query is executed. 114875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @return A {@link Cursor} object, which is positioned before the first entry. Note that 114975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * {@link Cursor}s are not synchronized, see the documentation for more details. 115075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @see Cursor 115175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown */ 115275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown public Cursor queryWithFactory(CursorFactory cursorFactory, 115375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown boolean distinct, String table, String[] columns, 115475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown String selection, String[] selectionArgs, String groupBy, 11554c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown String having, String orderBy, String limit, CancellationSignal cancellationSignal) { 115603bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown acquireReference(); 115703bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown try { 115803bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown String sql = SQLiteQueryBuilder.buildQueryString( 115903bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown distinct, table, columns, selection, groupBy, having, orderBy, limit); 11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 116103bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown return rawQueryWithFactory(cursorFactory, sql, selectionArgs, 116203bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown findEditTable(table), cancellationSignal); 116303bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } finally { 116403bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown releaseReference(); 116503bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } 11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Query the given table, returning a {@link Cursor} over the result set. 11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param table The table name to compile the query against. 11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param columns A list of which columns to return. Passing null will 11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * return all columns, which is discouraged to prevent reading 11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * data from storage that isn't going to be used. 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selection A filter declaring which rows to return, formatted as an 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * SQL WHERE clause (excluding the WHERE itself). Passing null 11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will return all rows for the given table. 11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selectionArgs You may include ?s in selection, which will be 11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * replaced by the values from selectionArgs, in order that they 11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * appear in the selection. The values will be bound as Strings. 11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param groupBy A filter declaring how to group rows, formatted as an SQL 11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * GROUP BY clause (excluding the GROUP BY itself). Passing null 11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will cause the rows to not be grouped. 11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param having A filter declare which row groups to include in the cursor, 11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if row grouping is being used, formatted as an SQL HAVING 11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clause (excluding the HAVING itself). Passing null will cause 11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * all row groups to be included, and is required when row 11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * grouping is not being used. 11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause 11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * (excluding the ORDER BY itself). Passing null will use the 11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * default sort order, which may be unordered. 1192f3ca9a5c7e87319c934b5815566054d2e5c2085fJeff Hamilton * @return A {@link Cursor} object, which is positioned before the first entry. Note that 1193f3ca9a5c7e87319c934b5815566054d2e5c2085fJeff Hamilton * {@link Cursor}s are not synchronized, see the documentation for more details. 11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see Cursor 11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Cursor query(String table, String[] columns, String selection, 11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String[] selectionArgs, String groupBy, String having, 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String orderBy) { 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return query(false, table, columns, selection, selectionArgs, groupBy, 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project having, orderBy, null /* limit */); 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Query the given table, returning a {@link Cursor} over the result set. 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param table The table name to compile the query against. 12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param columns A list of which columns to return. Passing null will 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * return all columns, which is discouraged to prevent reading 12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * data from storage that isn't going to be used. 12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selection A filter declaring which rows to return, formatted as an 12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * SQL WHERE clause (excluding the WHERE itself). Passing null 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will return all rows for the given table. 12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selectionArgs You may include ?s in selection, which will be 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * replaced by the values from selectionArgs, in order that they 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * appear in the selection. The values will be bound as Strings. 12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param groupBy A filter declaring how to group rows, formatted as an SQL 12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * GROUP BY clause (excluding the GROUP BY itself). Passing null 12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will cause the rows to not be grouped. 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param having A filter declare which row groups to include in the cursor, 12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if row grouping is being used, formatted as an SQL HAVING 12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clause (excluding the HAVING itself). Passing null will cause 12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * all row groups to be included, and is required when row 12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * grouping is not being used. 12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause 12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * (excluding the ORDER BY itself). Passing null will use the 12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * default sort order, which may be unordered. 12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param limit Limits the number of rows returned by the query, 12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * formatted as LIMIT clause. Passing null denotes no LIMIT clause. 1230f3ca9a5c7e87319c934b5815566054d2e5c2085fJeff Hamilton * @return A {@link Cursor} object, which is positioned before the first entry. Note that 1231f3ca9a5c7e87319c934b5815566054d2e5c2085fJeff Hamilton * {@link Cursor}s are not synchronized, see the documentation for more details. 12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see Cursor 12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Cursor query(String table, String[] columns, String selection, 12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String[] selectionArgs, String groupBy, String having, 12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String orderBy, String limit) { 12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return query(false, table, columns, selection, selectionArgs, groupBy, 12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project having, orderBy, limit); 12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Runs the provided SQL and returns a {@link Cursor} over the result set. 12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sql the SQL query. The SQL string must not be ; terminated 12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selectionArgs You may include ?s in where clause in the query, 12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * which will be replaced by the values from selectionArgs. The 12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * values will be bound as Strings. 1249f3ca9a5c7e87319c934b5815566054d2e5c2085fJeff Hamilton * @return A {@link Cursor} object, which is positioned before the first entry. Note that 1250f3ca9a5c7e87319c934b5815566054d2e5c2085fJeff Hamilton * {@link Cursor}s are not synchronized, see the documentation for more details. 12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Cursor rawQuery(String sql, String[] selectionArgs) { 125375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown return rawQueryWithFactory(null, sql, selectionArgs, null, null); 125475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown } 125575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown 125675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown /** 125775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * Runs the provided SQL and returns a {@link Cursor} over the result set. 125875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * 125975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param sql the SQL query. The SQL string must not be ; terminated 126075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param selectionArgs You may include ?s in where clause in the query, 126175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * which will be replaced by the values from selectionArgs. The 126275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * values will be bound as Strings. 12634c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown * @param cancellationSignal A signal to cancel the operation in progress, or null if none. 126475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * If the operation is canceled, then {@link OperationCanceledException} will be thrown 126575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * when the query is executed. 126675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @return A {@link Cursor} object, which is positioned before the first entry. Note that 126775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * {@link Cursor}s are not synchronized, see the documentation for more details. 126875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown */ 126975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown public Cursor rawQuery(String sql, String[] selectionArgs, 12704c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown CancellationSignal cancellationSignal) { 12714c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown return rawQueryWithFactory(null, sql, selectionArgs, null, cancellationSignal); 12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Runs the provided SQL and returns a cursor over the result set. 12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param cursorFactory the cursor factory to use, or null for the default factory 12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sql the SQL query. The SQL string must not be ; terminated 12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selectionArgs You may include ?s in where clause in the query, 12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * which will be replaced by the values from selectionArgs. The 12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * values will be bound as Strings. 12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param editTable the name of the first table, which is editable 1283f3ca9a5c7e87319c934b5815566054d2e5c2085fJeff Hamilton * @return A {@link Cursor} object, which is positioned before the first entry. Note that 1284f3ca9a5c7e87319c934b5815566054d2e5c2085fJeff Hamilton * {@link Cursor}s are not synchronized, see the documentation for more details. 12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Cursor rawQueryWithFactory( 12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CursorFactory cursorFactory, String sql, String[] selectionArgs, 12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String editTable) { 128975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown return rawQueryWithFactory(cursorFactory, sql, selectionArgs, editTable, null); 129075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown } 129175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown 129275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown /** 129375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * Runs the provided SQL and returns a cursor over the result set. 129475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * 129575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param cursorFactory the cursor factory to use, or null for the default factory 129675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param sql the SQL query. The SQL string must not be ; terminated 129775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param selectionArgs You may include ?s in where clause in the query, 129875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * which will be replaced by the values from selectionArgs. The 129975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * values will be bound as Strings. 130075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @param editTable the name of the first table, which is editable 13014c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown * @param cancellationSignal A signal to cancel the operation in progress, or null if none. 130275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * If the operation is canceled, then {@link OperationCanceledException} will be thrown 130375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * when the query is executed. 130475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * @return A {@link Cursor} object, which is positioned before the first entry. Note that 130575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown * {@link Cursor}s are not synchronized, see the documentation for more details. 130675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown */ 130775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown public Cursor rawQueryWithFactory( 130875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown CursorFactory cursorFactory, String sql, String[] selectionArgs, 13094c1241df8f8b7fd5ec3dff6c7e0f66271248e76eJeff Brown String editTable, CancellationSignal cancellationSignal) { 131003bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown acquireReference(); 131103bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown try { 131203bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(this, sql, editTable, 131303bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown cancellationSignal); 131403bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown return driver.query(cursorFactory != null ? cursorFactory : mCursorFactory, 131503bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown selectionArgs); 131603bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } finally { 131703bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown releaseReference(); 131803bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } 13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Convenience method for inserting a row into the database. 13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param table the table to insert the row into 132569ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * @param nullColumnHack optional; may be <code>null</code>. 132669ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * SQL doesn't allow inserting a completely empty row without 132769ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * naming at least one column name. If your provided <code>values</code> is 132869ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * empty, no column names are known and an empty row can't be inserted. 132969ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * If not set to null, the <code>nullColumnHack</code> parameter 133069ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * provides the name of nullable column name to explicitly insert a NULL into 133169ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * in the case where your <code>values</code> is empty. 13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values this map contains the initial column values for the 13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * row. The keys should be the column names and the values the 13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * column values 13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the row ID of the newly inserted row, or -1 if an error occurred 13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long insert(String table, String nullColumnHack, ContentValues values) { 13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 13398d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE); 13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SQLException e) { 13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "Error inserting " + values, e); 13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Convenience method for inserting a row into the database. 13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param table the table to insert the row into 135069ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * @param nullColumnHack optional; may be <code>null</code>. 135169ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * SQL doesn't allow inserting a completely empty row without 135269ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * naming at least one column name. If your provided <code>values</code> is 135369ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * empty, no column names are known and an empty row can't be inserted. 135469ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * If not set to null, the <code>nullColumnHack</code> parameter 135569ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * provides the name of nullable column name to explicitly insert a NULL into 135669ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * in the case where your <code>values</code> is empty. 13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values this map contains the initial column values for the 13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * row. The keys should be the column names and the values the 13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * column values 13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws SQLException 13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the row ID of the newly inserted row, or -1 if an error occurred 13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long insertOrThrow(String table, String nullColumnHack, ContentValues values) 13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws SQLException { 13658d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE); 13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Convenience method for replacing a row in the database. 13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param table the table in which to replace the row 137269ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * @param nullColumnHack optional; may be <code>null</code>. 137369ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * SQL doesn't allow inserting a completely empty row without 137469ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * naming at least one column name. If your provided <code>initialValues</code> is 137569ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * empty, no column names are known and an empty row can't be inserted. 137669ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * If not set to null, the <code>nullColumnHack</code> parameter 137769ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * provides the name of nullable column name to explicitly insert a NULL into 137869ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * in the case where your <code>initialValues</code> is empty. 13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param initialValues this map contains the initial column values for 138069ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * the row. 13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the row ID of the newly inserted row, or -1 if an error occurred 13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long replace(String table, String nullColumnHack, ContentValues initialValues) { 13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1385600bdd82f58c7338e68ce2c8f04b17db4cf4f910Dmitri Plotnikov return insertWithOnConflict(table, nullColumnHack, initialValues, 13868d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori CONFLICT_REPLACE); 13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SQLException e) { 13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "Error inserting " + initialValues, e); 13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Convenience method for replacing a row in the database. 13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param table the table in which to replace the row 139769ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * @param nullColumnHack optional; may be <code>null</code>. 139869ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * SQL doesn't allow inserting a completely empty row without 139969ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * naming at least one column name. If your provided <code>initialValues</code> is 140069ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * empty, no column names are known and an empty row can't be inserted. 140169ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * If not set to null, the <code>nullColumnHack</code> parameter 140269ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * provides the name of nullable column name to explicitly insert a NULL into 140369ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * in the case where your <code>initialValues</code> is empty. 14049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param initialValues this map contains the initial column values for 14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the row. The key 14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws SQLException 14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the row ID of the newly inserted row, or -1 if an error occurred 14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long replaceOrThrow(String table, String nullColumnHack, 14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentValues initialValues) throws SQLException { 1411600bdd82f58c7338e68ce2c8f04b17db4cf4f910Dmitri Plotnikov return insertWithOnConflict(table, nullColumnHack, initialValues, 14128d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori CONFLICT_REPLACE); 14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * General method for inserting a row into the database. 14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param table the table to insert the row into 141969ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * @param nullColumnHack optional; may be <code>null</code>. 142069ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * SQL doesn't allow inserting a completely empty row without 142169ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * naming at least one column name. If your provided <code>initialValues</code> is 142269ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * empty, no column names are known and an empty row can't be inserted. 142369ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * If not set to null, the <code>nullColumnHack</code> parameter 142469ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * provides the name of nullable column name to explicitly insert a NULL into 142569ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * in the case where your <code>initialValues</code> is empty. 14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param initialValues this map contains the initial column values for the 14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * row. The keys should be the column names and the values the 14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * column values 14298d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori * @param conflictAlgorithm for insert conflict resolver 14306eb7c45a8fdb774c4094b5012c8496f2a009c032Vasu Nori * @return the row ID of the newly inserted row 14316eb7c45a8fdb774c4094b5012c8496f2a009c032Vasu Nori * OR the primary key of the existing row if the input param 'conflictAlgorithm' = 14328d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori * {@link #CONFLICT_IGNORE} 14336eb7c45a8fdb774c4094b5012c8496f2a009c032Vasu Nori * OR -1 if any error 14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long insertWithOnConflict(String table, String nullColumnHack, 14366eb7c45a8fdb774c4094b5012c8496f2a009c032Vasu Nori ContentValues initialValues, int conflictAlgorithm) { 143703bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown acquireReference(); 143803bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown try { 143903bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown StringBuilder sql = new StringBuilder(); 144003bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown sql.append("INSERT"); 144103bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown sql.append(CONFLICT_VALUES[conflictAlgorithm]); 144203bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown sql.append(" INTO "); 144303bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown sql.append(table); 144403bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown sql.append('('); 144503bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown 144603bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown Object[] bindArgs = null; 144703bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown int size = (initialValues != null && initialValues.size() > 0) 144803bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown ? initialValues.size() : 0; 144903bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown if (size > 0) { 145003bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown bindArgs = new Object[size]; 145103bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown int i = 0; 145203bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown for (String colName : initialValues.keySet()) { 145303bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown sql.append((i > 0) ? "," : ""); 145403bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown sql.append(colName); 145503bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown bindArgs[i++] = initialValues.get(colName); 145603bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } 145703bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown sql.append(')'); 145803bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown sql.append(" VALUES ("); 145903bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown for (i = 0; i < size; i++) { 146003bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown sql.append((i > 0) ? ",?" : "?"); 146103bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } 146203bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } else { 146303bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown sql.append(nullColumnHack + ") VALUES (NULL"); 14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sql.append(')'); 14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 146703bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs); 146803bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown try { 146903bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown return statement.executeInsert(); 147003bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } finally { 147103bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown statement.close(); 147203bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } 14739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 147403bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown releaseReference(); 14759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Convenience method for deleting rows in the database. 14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param table the table to delete from 14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param whereClause the optional WHERE clause to apply when deleting. 14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Passing null will delete all rows. 14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the number of rows affected if a whereClause is passed in, 0 14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * otherwise. To remove all rows and get a count pass "1" as the 14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * whereClause. 14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int delete(String table, String whereClause, String[] whereArgs) { 148903bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown acquireReference(); 14909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 149103bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown SQLiteStatement statement = new SQLiteStatement(this, "DELETE FROM " + table + 149203bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown (!TextUtils.isEmpty(whereClause) ? " WHERE " + whereClause : ""), whereArgs); 149303bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown try { 149403bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown return statement.executeUpdateDelete(); 149503bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } finally { 149603bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown statement.close(); 149703bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } 14989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 149903bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown releaseReference(); 15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 15049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Convenience method for updating rows in the database. 15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param table the table to update in 15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values a map from column names to new column values. null is a 15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * valid value that will be translated to NULL. 15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param whereClause the optional WHERE clause to apply when updating. 15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Passing null will update all rows. 15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the number of rows affected 15129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int update(String table, ContentValues values, String whereClause, String[] whereArgs) { 15148d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori return updateWithOnConflict(table, values, whereClause, whereArgs, CONFLICT_NONE); 15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1516600bdd82f58c7338e68ce2c8f04b17db4cf4f910Dmitri Plotnikov 15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Convenience method for updating rows in the database. 15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param table the table to update in 15219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values a map from column names to new column values. null is a 15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * valid value that will be translated to NULL. 15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param whereClause the optional WHERE clause to apply when updating. 15249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Passing null will update all rows. 15258d45e4e4c6244cc3a508da3b56fec8cfd4cadd1dVasu Nori * @param conflictAlgorithm for update conflict resolver 15269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the number of rows affected 15279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1528600bdd82f58c7338e68ce2c8f04b17db4cf4f910Dmitri Plotnikov public int updateWithOnConflict(String table, ContentValues values, 15296eb7c45a8fdb774c4094b5012c8496f2a009c032Vasu Nori String whereClause, String[] whereArgs, int conflictAlgorithm) { 153046a8851360de255a4a63a0bdf61987a89e1d8e73Brian Muramatsu if (values == null || values.size() == 0) { 15319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Empty values"); 15329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 153403bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown acquireReference(); 153503bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown try { 153603bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown StringBuilder sql = new StringBuilder(120); 153703bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown sql.append("UPDATE "); 153803bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown sql.append(CONFLICT_VALUES[conflictAlgorithm]); 153903bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown sql.append(table); 154003bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown sql.append(" SET "); 154103bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown 154203bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown // move all bind args to one array 154303bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown int setValuesSize = values.size(); 154403bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown int bindArgsSize = (whereArgs == null) ? setValuesSize : (setValuesSize + whereArgs.length); 154503bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown Object[] bindArgs = new Object[bindArgsSize]; 154603bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown int i = 0; 154703bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown for (String colName : values.keySet()) { 154803bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown sql.append((i > 0) ? "," : ""); 154903bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown sql.append(colName); 155003bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown bindArgs[i++] = values.get(colName); 155103bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown sql.append("=?"); 155203bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } 155303bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown if (whereArgs != null) { 155403bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown for (i = setValuesSize; i < bindArgsSize; i++) { 155503bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown bindArgs[i] = whereArgs[i - setValuesSize]; 155603bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } 155703bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } 155803bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown if (!TextUtils.isEmpty(whereClause)) { 155903bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown sql.append(" WHERE "); 156003bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown sql.append(whereClause); 15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 156303bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs); 156403bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown try { 156503bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown return statement.executeUpdateDelete(); 156603bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } finally { 156703bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown statement.close(); 156803bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } 15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 157003bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown releaseReference(); 15719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1575ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * Execute a single SQL statement that is NOT a SELECT 1576ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * or any other SQL statement that returns data. 1577ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * <p> 1578ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori * It has no means to return any data (such as the number of affected rows). 1579ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * Instead, you're encouraged to use {@link #insert(String, String, ContentValues)}, 1580ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * {@link #update(String, ContentValues, String, String[])}, et al, when possible. 1581ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * </p> 15829bf225ef7b82b5eacee1907155a8a8bbb6aa7f42Vasu Nori * <p> 15839bf225ef7b82b5eacee1907155a8a8bbb6aa7f42Vasu Nori * When using {@link #enableWriteAheadLogging()}, journal_mode is 15849bf225ef7b82b5eacee1907155a8a8bbb6aa7f42Vasu Nori * automatically managed by this class. So, do not set journal_mode 15859bf225ef7b82b5eacee1907155a8a8bbb6aa7f42Vasu Nori * using "PRAGMA journal_mode'<value>" statement if your app is using 15869bf225ef7b82b5eacee1907155a8a8bbb6aa7f42Vasu Nori * {@link #enableWriteAheadLogging()} 15879bf225ef7b82b5eacee1907155a8a8bbb6aa7f42Vasu Nori * </p> 15889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1589ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * @param sql the SQL statement to be executed. Multiple statements separated by semicolons are 1590ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * not supported. 159169ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * @throws SQLException if the SQL string is invalid 15929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1593b83cb7cda3947fb35e126eab1530732fcd797ad0Vasu Nori public void execSQL(String sql) throws SQLException { 159416057fad00d47e920fc20721b70c7cafb765f7f8Vasu Nori executeSql(sql, null); 15959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1598ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * Execute a single SQL statement that is NOT a SELECT/INSERT/UPDATE/DELETE. 1599ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * <p> 1600ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * For INSERT statements, use any of the following instead. 1601ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * <ul> 1602ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * <li>{@link #insert(String, String, ContentValues)}</li> 1603ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * <li>{@link #insertOrThrow(String, String, ContentValues)}</li> 1604ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * <li>{@link #insertWithOnConflict(String, String, ContentValues, int)}</li> 1605ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * </ul> 1606ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * <p> 1607ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * For UPDATE statements, use any of the following instead. 1608ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * <ul> 1609ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * <li>{@link #update(String, ContentValues, String, String[])}</li> 1610ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * <li>{@link #updateWithOnConflict(String, ContentValues, String, String[], int)}</li> 1611ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * </ul> 1612ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * <p> 1613ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * For DELETE statements, use any of the following instead. 1614ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * <ul> 1615ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * <li>{@link #delete(String, String, String[])}</li> 1616ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * </ul> 1617ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * <p> 1618ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * For example, the following are good candidates for using this method: 1619ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * <ul> 1620ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * <li>ALTER TABLE</li> 1621ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * <li>CREATE or DROP table / trigger / view / index / virtual table</li> 1622ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * <li>REINDEX</li> 1623ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * <li>RELEASE</li> 1624ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * <li>SAVEPOINT</li> 1625ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * <li>PRAGMA that returns no data</li> 1626ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * </ul> 1627ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * </p> 16289bf225ef7b82b5eacee1907155a8a8bbb6aa7f42Vasu Nori * <p> 16299bf225ef7b82b5eacee1907155a8a8bbb6aa7f42Vasu Nori * When using {@link #enableWriteAheadLogging()}, journal_mode is 16309bf225ef7b82b5eacee1907155a8a8bbb6aa7f42Vasu Nori * automatically managed by this class. So, do not set journal_mode 16319bf225ef7b82b5eacee1907155a8a8bbb6aa7f42Vasu Nori * using "PRAGMA journal_mode'<value>" statement if your app is using 16329bf225ef7b82b5eacee1907155a8a8bbb6aa7f42Vasu Nori * {@link #enableWriteAheadLogging()} 16339bf225ef7b82b5eacee1907155a8a8bbb6aa7f42Vasu Nori * </p> 16349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1635ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * @param sql the SQL statement to be executed. Multiple statements separated by semicolons are 1636ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * not supported. 16379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param bindArgs only byte[], String, Long and Double are supported in bindArgs. 163869ea4e15e52c456537575d21443ac1efdb03a902Brad Fitzpatrick * @throws SQLException if the SQL string is invalid 16399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1640b83cb7cda3947fb35e126eab1530732fcd797ad0Vasu Nori public void execSQL(String sql, Object[] bindArgs) throws SQLException { 16419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bindArgs == null) { 16429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Empty bindArgs"); 16439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1644b83cb7cda3947fb35e126eab1530732fcd797ad0Vasu Nori executeSql(sql, bindArgs); 1645ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori } 1646ce38b98feb1e7c9c1799eb270c40798d833aa9aeVasu Nori 16475402590f1cb8ae1bc31f796705ff6f10bc175730Vasu Nori private int executeSql(String sql, Object[] bindArgs) throws SQLException { 164803bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown acquireReference(); 164903bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown try { 165003bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown if (DatabaseUtils.getSqlStatementType(sql) == DatabaseUtils.STATEMENT_ATTACH) { 165103bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown boolean disableWal = false; 165203bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown synchronized (mLock) { 165303bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown if (!mHasAttachedDbsLocked) { 165403bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown mHasAttachedDbsLocked = true; 165503bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown disableWal = true; 165603bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } 165703bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } 165803bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown if (disableWal) { 165903bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown disableWriteAheadLogging(); 1660e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 1661e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 1662e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 166303bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown SQLiteStatement statement = new SQLiteStatement(this, sql, bindArgs); 166403bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown try { 166503bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown return statement.executeUpdateDelete(); 166603bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } finally { 166703bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown statement.close(); 166803bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } 16699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 167003bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown releaseReference(); 16719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1675e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Returns true if the database is opened as read only. 16769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1677e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * @return True if database is opened as read only. 16789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1679e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown public boolean isReadOnly() { 1680e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown synchronized (mLock) { 1681e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown return isReadOnlyLocked(); 16829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1683e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 1684e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 1685e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown private boolean isReadOnlyLocked() { 1686e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown return (mConfigurationLocked.openFlags & OPEN_READ_MASK) == OPEN_READONLY; 16879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1690e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Returns true if the database is in-memory db. 1691e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * 1692e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * @return True if the database is in-memory. 1693e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * @hide 16949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1695e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown public boolean isInMemoryDatabase() { 1696e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown synchronized (mLock) { 1697e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown return mConfigurationLocked.isInMemoryDb(); 1698e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 16999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1702e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Returns true if the database is currently open. 1703e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * 1704e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * @return True if the database is currently open (has not been closed). 17059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 17069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isOpen() { 1707e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown synchronized (mLock) { 1708e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown return mConnectionPoolLocked != null; 1709e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 17109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1712e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown /** 1713e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Returns true if the new version code is greater than the current database version. 1714e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * 1715e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * @param newVersion The new version code. 1716e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * @return True if the new version code is greater than the current database version. 1717e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown */ 17189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean needUpgrade(int newVersion) { 17199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return newVersion > getVersion(); 17209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1723e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Gets the path to the database file. 17249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1725e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * @return The path to the database file. 17269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 17279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final String getPath() { 1728e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown synchronized (mLock) { 1729e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown return mConfigurationLocked.path; 1730ad9e8b1a87edc8009ff60932a22fead1df944089Christopher Tate } 1731722802e76b8805da523a612ad3482450fd327db0Brad Fitzpatrick } 1732722802e76b8805da523a612ad3482450fd327db0Brad Fitzpatrick 17335a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori /** 1734e495d1f74af13aec8d5d825e93e4cfe1e4fe7468Vasu Nori * Sets the locale for this database. Does nothing if this database has 17351d9f742e001ed8280fa93fd9ba0b1125ce6d00aeJeff Brown * the {@link #NO_LOCALIZED_COLLATORS} flag set or was opened read only. 1736e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * 1737e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * @param locale The new locale. 1738e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * 1739e495d1f74af13aec8d5d825e93e4cfe1e4fe7468Vasu Nori * @throws SQLException if the locale could not be set. The most common reason 1740e495d1f74af13aec8d5d825e93e4cfe1e4fe7468Vasu Nori * for this is that there is no collator available for the locale you requested. 1741e495d1f74af13aec8d5d825e93e4cfe1e4fe7468Vasu Nori * In this case the database remains unchanged. 17425a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori */ 1743e495d1f74af13aec8d5d825e93e4cfe1e4fe7468Vasu Nori public void setLocale(Locale locale) { 1744e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown if (locale == null) { 1745e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown throw new IllegalArgumentException("locale must not be null."); 1746dfe515e49ae8a0275012b56a4a79d2dfcc017db2Jesse Wilson } 1747b729dcc8a94bc2c2a1ecda47d791be0d6f1d160aVasu Nori 1748e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown synchronized (mLock) { 1749e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown throwIfNotOpenLocked(); 1750e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown 1751e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown final Locale oldLocale = mConfigurationLocked.locale; 1752e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown mConfigurationLocked.locale = locale; 1753e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown try { 1754e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown mConnectionPoolLocked.reconfigure(mConfigurationLocked); 1755e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown } catch (RuntimeException ex) { 1756e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown mConfigurationLocked.locale = oldLocale; 1757e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown throw ex; 1758e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown } 1759b729dcc8a94bc2c2a1ecda47d791be0d6f1d160aVasu Nori } 1760b729dcc8a94bc2c2a1ecda47d791be0d6f1d160aVasu Nori } 1761b729dcc8a94bc2c2a1ecda47d791be0d6f1d160aVasu Nori 1762e495d1f74af13aec8d5d825e93e4cfe1e4fe7468Vasu Nori /** 1763ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * Sets the maximum size of the prepared-statement cache for this database. 1764e495d1f74af13aec8d5d825e93e4cfe1e4fe7468Vasu Nori * (size of the cache = number of compiled-sql-statements stored in the cache). 1765ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori *<p> 1766b729dcc8a94bc2c2a1ecda47d791be0d6f1d160aVasu Nori * Maximum cache size can ONLY be increased from its current size (default = 10). 1767ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * If this method is called with smaller size than the current maximum value, 1768ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * then IllegalStateException is thrown. 1769b729dcc8a94bc2c2a1ecda47d791be0d6f1d160aVasu Nori *<p> 1770b729dcc8a94bc2c2a1ecda47d791be0d6f1d160aVasu Nori * This method is thread-safe. 1771e495d1f74af13aec8d5d825e93e4cfe1e4fe7468Vasu Nori * 177290a36726b7553a1e7efd2f4ecbe01d7e1b3e7a67Vasu Nori * @param cacheSize the size of the cache. can be (0 to {@link #MAX_SQL_CACHE_SIZE}) 1773e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * @throws IllegalStateException if input cacheSize > {@link #MAX_SQL_CACHE_SIZE}. 17749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 17755402590f1cb8ae1bc31f796705ff6f10bc175730Vasu Nori public void setMaxSqlCacheSize(int cacheSize) { 1776e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown if (cacheSize > MAX_SQL_CACHE_SIZE || cacheSize < 0) { 1777e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown throw new IllegalStateException( 1778e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown "expected value between 0 and " + MAX_SQL_CACHE_SIZE); 177983ff97d8403db4d8d0a351031f0c9efcb602a99cVasu Nori } 178083ff97d8403db4d8d0a351031f0c9efcb602a99cVasu Nori 1781e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown synchronized (mLock) { 1782e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown throwIfNotOpenLocked(); 1783e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown 1784e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown final int oldMaxSqlCacheSize = mConfigurationLocked.maxSqlCacheSize; 1785e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown mConfigurationLocked.maxSqlCacheSize = cacheSize; 1786e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown try { 1787e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown mConnectionPoolLocked.reconfigure(mConfigurationLocked); 1788e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown } catch (RuntimeException ex) { 1789e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown mConfigurationLocked.maxSqlCacheSize = oldMaxSqlCacheSize; 1790e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown throw ex; 1791e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown } 17926f37f83a4802a0d411395f3abc5f24a2cfec025dVasu Nori } 17936f37f83a4802a0d411395f3abc5f24a2cfec025dVasu Nori } 17946f37f83a4802a0d411395f3abc5f24a2cfec025dVasu Nori 17956f37f83a4802a0d411395f3abc5f24a2cfec025dVasu Nori /** 179696496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown * Sets whether foreign key constraints are enabled for the database. 179796496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown * <p> 179896496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown * By default, foreign key constraints are not enforced by the database. 179996496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown * This method allows an application to enable foreign key constraints. 180096496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown * It must be called each time the database is opened to ensure that foreign 180196496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown * key constraints are enabled for the session. 180296496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown * </p><p> 180396496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown * A good time to call this method is right after calling {@link #openOrCreateDatabase} 180496496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown * or in the {@link SQLiteOpenHelper#onConfigure} callback. 180596496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown * </p><p> 180696496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown * When foreign key constraints are disabled, the database does not check whether 180796496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown * changes to the database will violate foreign key constraints. Likewise, when 180896496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown * foreign key constraints are disabled, the database will not execute cascade 180996496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown * delete or update triggers. As a result, it is possible for the database 181096496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown * state to become inconsistent. To perform a database integrity check, 181196496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown * call {@link #isDatabaseIntegrityOk}. 181296496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown * </p><p> 181396496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown * This method must not be called while a transaction is in progress. 181496496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown * </p><p> 181596496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown * See also <a href="http://sqlite.org/foreignkeys.html">SQLite Foreign Key Constraints</a> 181696496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown * for more details about foreign key constraint support. 181796496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown * </p> 181896496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown * 181996496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown * @param enable True to enable foreign key constraints, false to disable them. 182096496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown * 182196496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown * @throws IllegalStateException if the are transactions is in progress 182296496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown * when this method is called. 182396496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown */ 182496496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown public void setForeignKeyConstraintsEnabled(boolean enable) { 182596496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown synchronized (mLock) { 182696496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown throwIfNotOpenLocked(); 182796496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown 182896496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown if (mConfigurationLocked.foreignKeyConstraintsEnabled == enable) { 182996496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown return; 183096496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown } 183196496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown 183296496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown mConfigurationLocked.foreignKeyConstraintsEnabled = enable; 183396496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown try { 183496496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown mConnectionPoolLocked.reconfigure(mConfigurationLocked); 183596496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown } catch (RuntimeException ex) { 183696496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown mConfigurationLocked.foreignKeyConstraintsEnabled = !enable; 183796496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown throw ex; 183896496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown } 183996496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown } 184096496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown } 184196496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown 184296496adb611ced49ed1c2c778c616d1f8a5d0e6bJeff Brown /** 184347847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * This method enables parallel execution of queries from multiple threads on the 184447847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * same database. It does this by opening multiple connections to the database 184547847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * and using a different database connection for each query. The database 184647847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * journal mode is also changed to enable writes to proceed concurrently with reads. 18476c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * <p> 184847847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * When write-ahead logging is not enabled (the default), it is not possible for 184947847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * reads and writes to occur on the database at the same time. Before modifying the 185047847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * database, the writer implicitly acquires an exclusive lock on the database which 185147847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * prevents readers from accessing the database until the write is completed. 185247847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * </p><p> 185347847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * In contrast, when write-ahead logging is enabled (by calling this method), write 185447847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * operations occur in a separate log file which allows reads to proceed concurrently. 185547847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * While a write is in progress, readers on other threads will perceive the state 185647847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * of the database as it was before the write began. When the write completes, readers 185747847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * on other threads will then perceive the new state of the database. 185847847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * </p><p> 185947847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * It is a good idea to enable write-ahead logging whenever a database will be 186047847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * concurrently accessed and modified by multiple threads at the same time. 186147847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * However, write-ahead logging uses significantly more memory than ordinary 186247847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * journaling because there are multiple connections to the same database. 186347847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * So if a database will only be used by a single thread, or if optimizing 186447847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * concurrency is not very important, then write-ahead logging should be disabled. 186547847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * </p><p> 186647847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * After calling this method, execution of queries in parallel is enabled as long as 186747847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * the database remains open. To disable execution of queries in parallel, either 186847847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * call {@link #disableWriteAheadLogging} or close the database and reopen it. 186947847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * </p><p> 187047847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * The maximum number of connections used to execute queries in parallel is 18716c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * dependent upon the device memory and possibly other properties. 187247847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * </p><p> 18736c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * If a query is part of a transaction, then it is executed on the same database handle the 18746c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * transaction was begun. 187547847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * </p><p> 18766c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * Writers should use {@link #beginTransactionNonExclusive()} or 18776c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * {@link #beginTransactionWithListenerNonExclusive(SQLiteTransactionListener)} 187847847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * to start a transaction. Non-exclusive mode allows database file to be in readable 187947847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * by other threads executing queries. 188047847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * </p><p> 188147847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * If the database has any attached databases, then execution of queries in parallel is NOT 188247847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * possible. Likewise, write-ahead logging is not supported for read-only databases 188347847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * or memory databases. In such cases, {@link #enableWriteAheadLogging} returns false. 188447847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * </p><p> 188547847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * The best way to enable write-ahead logging is to pass the 188647847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * {@link #ENABLE_WRITE_AHEAD_LOGGING} flag to {@link #openDatabase}. This is 188747847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * more efficient than calling {@link #enableWriteAheadLogging}. 188847847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * <code><pre> 188947847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory, 189047847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * SQLiteDatabase.CREATE_IF_NECESSARY | SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING, 189147847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * myDatabaseErrorHandler); 189247847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * db.enableWriteAheadLogging(); 189347847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * </pre></code> 189447847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * </p><p> 189547847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * Another way to enable write-ahead logging is to call {@link #enableWriteAheadLogging} 189647847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * after opening the database. 189747847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * <code><pre> 189847847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory, 189947847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * SQLiteDatabase.CREATE_IF_NECESSARY, myDatabaseErrorHandler); 190047847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * db.enableWriteAheadLogging(); 190147847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * </pre></code> 190247847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * </p><p> 190347847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * See also <a href="http://sqlite.org/wal.html">SQLite Write-Ahead Logging</a> for 190447847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * more details about how write-ahead logging works. 19056c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * </p> 19066c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori * 190747847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * @return True if write-ahead logging is enabled. 1908e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown * 19097364477528488b52071d58a287b888faef222a05Jean-Baptiste Queru * @throws IllegalStateException if there are transactions in progress at the 1910e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown * time this method is called. WAL mode can only be changed when there are no 1911e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown * transactions in progress. 191247847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * 191347847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * @see #ENABLE_WRITE_AHEAD_LOGGING 191447847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * @see #disableWriteAheadLogging 19156c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori */ 1916ffe06127f6ea4e9ea8e797f8ba0365d1f47fe297Vasu Nori public boolean enableWriteAheadLogging() { 1917e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown synchronized (mLock) { 1918e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown throwIfNotOpenLocked(); 1919e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 192047847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown if ((mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) != 0) { 1921dae6d3705d34a45a4ffe2fe411e6de644ef78e47Paul Westbrook return true; 1922dae6d3705d34a45a4ffe2fe411e6de644ef78e47Paul Westbrook } 1923e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 1924e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown if (isReadOnlyLocked()) { 1925e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // WAL doesn't make sense for readonly-databases. 1926e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // TODO: True, but connection pooling does still make sense... 1927e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown return false; 1928e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 1929e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 1930e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown if (mConfigurationLocked.isInMemoryDb()) { 1931dae6d3705d34a45a4ffe2fe411e6de644ef78e47Paul Westbrook Log.i(TAG, "can't enable WAL for memory databases."); 1932dae6d3705d34a45a4ffe2fe411e6de644ef78e47Paul Westbrook return false; 1933dae6d3705d34a45a4ffe2fe411e6de644ef78e47Paul Westbrook } 1934dae6d3705d34a45a4ffe2fe411e6de644ef78e47Paul Westbrook 1935dae6d3705d34a45a4ffe2fe411e6de644ef78e47Paul Westbrook // make sure this database has NO attached databases because sqlite's write-ahead-logging 1936dae6d3705d34a45a4ffe2fe411e6de644ef78e47Paul Westbrook // doesn't work for databases with attached databases 1937e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown if (mHasAttachedDbsLocked) { 1938dae6d3705d34a45a4ffe2fe411e6de644ef78e47Paul Westbrook if (Log.isLoggable(TAG, Log.DEBUG)) { 1939e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown Log.d(TAG, "this database: " + mConfigurationLocked.label 1940e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown + " has attached databases. can't enable WAL."); 1941dae6d3705d34a45a4ffe2fe411e6de644ef78e47Paul Westbrook } 1942dae6d3705d34a45a4ffe2fe411e6de644ef78e47Paul Westbrook return false; 1943dae6d3705d34a45a4ffe2fe411e6de644ef78e47Paul Westbrook } 1944e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 194547847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown mConfigurationLocked.openFlags |= ENABLE_WRITE_AHEAD_LOGGING; 1946e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown try { 1947e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown mConnectionPoolLocked.reconfigure(mConfigurationLocked); 1948e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown } catch (RuntimeException ex) { 194947847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown mConfigurationLocked.openFlags &= ~ENABLE_WRITE_AHEAD_LOGGING; 1950e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown throw ex; 1951e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown } 1952dae6d3705d34a45a4ffe2fe411e6de644ef78e47Paul Westbrook } 1953e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown return true; 19546c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori } 19556c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori 19562827d6d974beabb12344040a002dcb52dd7106b5Vasu Nori /** 19577b04c4176d9cb2f96487ad891f4cf769bccb4f1bVasu Nori * This method disables the features enabled by {@link #enableWriteAheadLogging()}. 1958e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown * 19597364477528488b52071d58a287b888faef222a05Jean-Baptiste Queru * @throws IllegalStateException if there are transactions in progress at the 1960e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown * time this method is called. WAL mode can only be changed when there are no 1961e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown * transactions in progress. 196247847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * 196347847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * @see #enableWriteAheadLogging 19642827d6d974beabb12344040a002dcb52dd7106b5Vasu Nori */ 19657b04c4176d9cb2f96487ad891f4cf769bccb4f1bVasu Nori public void disableWriteAheadLogging() { 1966e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown synchronized (mLock) { 1967e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown throwIfNotOpenLocked(); 19688d1110383d4437eeebae337026cd91449e4e55a5Vasu Nori 196947847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown if ((mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) == 0) { 1970e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown return; 197165a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori } 197265a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori 197347847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown mConfigurationLocked.openFlags &= ~ENABLE_WRITE_AHEAD_LOGGING; 1974e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown try { 1975e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown mConnectionPoolLocked.reconfigure(mConfigurationLocked); 1976e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown } catch (RuntimeException ex) { 197747847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown mConfigurationLocked.openFlags |= ENABLE_WRITE_AHEAD_LOGGING; 1978e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown throw ex; 1979e67ca420e4eb6ddf8ceefeb0d9dcc47d9ca189fcJeff Brown } 1980e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 19816c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori } 19826c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori 1983e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown /** 198447847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * Returns true if write-ahead logging has been enabled for this database. 198547847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * 198647847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * @return True if write-ahead logging has been enabled for this database. 198747847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * 198847847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * @see #enableWriteAheadLogging 198947847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown * @see #ENABLE_WRITE_AHEAD_LOGGING 199047847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown */ 199147847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown public boolean isWriteAheadLoggingEnabled() { 199247847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown synchronized (mLock) { 199347847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown throwIfNotOpenLocked(); 199447847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown 199547847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown return (mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) != 0; 199647847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown } 199747847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown } 199847847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown 199947847f3f4dcf2a0dbea0bc0e4f02528e21d37a88Jeff Brown /** 2000e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Collect statistics about all open databases in the current process. 2001e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Used by bug report. 2002e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown */ 2003e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown static ArrayList<DbStats> getDbStats() { 2004e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown ArrayList<DbStats> dbStatsList = new ArrayList<DbStats>(); 2005e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown for (SQLiteDatabase db : getActiveDatabases()) { 2006e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown db.collectDbStats(dbStatsList); 200765a8883f0e605bb8a73a692987b47ce5da632e72Vasu Nori } 2008e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown return dbStatsList; 2009e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 20106c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori 2011e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown private void collectDbStats(ArrayList<DbStats> dbStatsList) { 2012e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown synchronized (mLock) { 2013e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown if (mConnectionPoolLocked != null) { 2014e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown mConnectionPoolLocked.collectDbStats(dbStatsList); 20156c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori } 20166c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori } 20176c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori } 20186c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori 2019e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown private static ArrayList<SQLiteDatabase> getActiveDatabases() { 2020e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown ArrayList<SQLiteDatabase> databases = new ArrayList<SQLiteDatabase>(); 2021e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown synchronized (sActiveDatabases) { 2022e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown databases.addAll(sActiveDatabases.keySet()); 20236c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori } 2024e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown return databases; 20256c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori } 20266c354da9436e946708fc3f3a1c0d18b18bbfdf43Vasu Nori 2027f3cf8a4da8ef28e62586cc07edce99879e2c3a56Vasu Nori /** 2028e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Dump detailed information about all open databases in the current process. 2029e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Used by bug report. 2030f3cf8a4da8ef28e62586cc07edce99879e2c3a56Vasu Nori */ 2031a9be4154e8dac0de3db5ee42e878beb0639e70e6Jeff Brown static void dumpAll(Printer printer, boolean verbose) { 2032e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown for (SQLiteDatabase db : getActiveDatabases()) { 2033a9be4154e8dac0de3db5ee42e878beb0639e70e6Jeff Brown db.dump(printer, verbose); 20342467561ac2c7de870417e0405a138c857c9d5629Vasu Nori } 2035e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 20362467561ac2c7de870417e0405a138c857c9d5629Vasu Nori 2037a9be4154e8dac0de3db5ee42e878beb0639e70e6Jeff Brown private void dump(Printer printer, boolean verbose) { 2038e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown synchronized (mLock) { 2039e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown if (mConnectionPoolLocked != null) { 2040e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown printer.println(""); 2041a9be4154e8dac0de3db5ee42e878beb0639e70e6Jeff Brown mConnectionPoolLocked.dump(printer, verbose); 20422467561ac2c7de870417e0405a138c857c9d5629Vasu Nori } 20432467561ac2c7de870417e0405a138c857c9d5629Vasu Nori } 2044c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori } 2045c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori 2046c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori /** 2047ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * Returns list of full pathnames of all attached databases including the main database 2048ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * by executing 'pragma database_list' on the database. 2049ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * 2050062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori * @return ArrayList of pairs of (database name, database file path) or null if the database 2051062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori * is not open. 2052c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori */ 2053a017edace756956cd4b4789a85316e3681d04a7eVasu Nori public List<Pair<String, String>> getAttachedDbs() { 2054c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori ArrayList<Pair<String, String>> attachedDbs = new ArrayList<Pair<String, String>>(); 2055e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown synchronized (mLock) { 2056e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown if (mConnectionPoolLocked == null) { 2057e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown return null; // not open 2058e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 2059e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 2060e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown if (!mHasAttachedDbsLocked) { 2061e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // No attached databases. 2062e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // There is a small window where attached databases exist but this flag is not 2063e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // set yet. This can occur when this thread is in a race condition with another 2064e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // thread that is executing the SQL statement: "attach database <blah> as <foo>" 2065e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // If this thread is NOT ok with such a race condition (and thus possibly not 2066e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // receivethe entire list of attached databases), then the caller should ensure 2067e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // that no thread is executing any SQL statements while a thread is calling this 2068e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // method. Typically, this method is called when 'adb bugreport' is done or the 2069e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // caller wants to collect stats on the database and all its attached databases. 2070e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown attachedDbs.add(new Pair<String, String>("main", mConfigurationLocked.path)); 2071e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown return attachedDbs; 2072e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 207303bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown 207403bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown acquireReference(); 20752467561ac2c7de870417e0405a138c857c9d5629Vasu Nori } 2076e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 2077062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori try { 207803bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown // has attached databases. query sqlite to get the list of attached databases. 207903bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown Cursor c = null; 208003bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown try { 208103bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown c = rawQuery("pragma database_list;", null); 208203bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown while (c.moveToNext()) { 208303bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown // sqlite returns a row for each database in the returned list of databases. 208403bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown // in each row, 208503bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown // 1st column is the database name such as main, or the database 208603bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown // name specified on the "ATTACH" command 208703bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown // 2nd column is the database file path. 208803bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown attachedDbs.add(new Pair<String, String>(c.getString(1), c.getString(2))); 208903bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } 209003bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } finally { 209103bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown if (c != null) { 209203bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown c.close(); 209303bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } 2094062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori } 209503bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown return attachedDbs; 2096062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori } finally { 209703bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown releaseReference(); 2098c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori } 2099c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori } 2100c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori 21019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2102ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * Runs 'pragma integrity_check' on the given database (and all the attached databases) 2103ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * and returns true if the given database (and all its attached databases) pass integrity_check, 2104062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori * false otherwise. 2105ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori *<p> 2106ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * If the result is false, then this method logs the errors reported by the integrity_check 2107062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori * command execution. 2108ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori *<p> 2109ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * Note that 'pragma integrity_check' on a database can take a long time. 2110062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori * 2111062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori * @return true if the given database (and all its attached databases) pass integrity_check, 2112ccd954480c32e9f35357b66023ae912e7f3fa76bVasu Nori * false otherwise. 2113062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori */ 2114062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori public boolean isDatabaseIntegrityOk() { 211503bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown acquireReference(); 2116bfe1dc27944c80dcb81f0eb313987999ecd7b6faVasu Nori try { 211703bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown List<Pair<String, String>> attachedDbs = null; 211803bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown try { 211903bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown attachedDbs = getAttachedDbs(); 212003bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown if (attachedDbs == null) { 212103bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown throw new IllegalStateException("databaselist for: " + getPath() + " couldn't " + 212203bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown "be retrieved. probably because the database is closed"); 212303bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } 212403bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } catch (SQLiteException e) { 212503bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown // can't get attachedDb list. do integrity check on the main database 212603bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown attachedDbs = new ArrayList<Pair<String, String>>(); 212703bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown attachedDbs.add(new Pair<String, String>("main", getPath())); 2128bfe1dc27944c80dcb81f0eb313987999ecd7b6faVasu Nori } 2129e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 213003bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown for (int i = 0; i < attachedDbs.size(); i++) { 213103bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown Pair<String, String> p = attachedDbs.get(i); 213203bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown SQLiteStatement prog = null; 213303bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown try { 213403bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown prog = compileStatement("PRAGMA " + p.first + ".integrity_check(1);"); 213503bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown String rslt = prog.simpleQueryForString(); 213603bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown if (!rslt.equalsIgnoreCase("ok")) { 213703bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown // integrity_checker failed on main or attached databases 213803bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown Log.e(TAG, "PRAGMA integrity_check on " + p.second + " returned: " + rslt); 213903bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown return false; 214003bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } 214103bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } finally { 214203bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown if (prog != null) prog.close(); 2143062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori } 2144062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori } 214503bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown } finally { 214603bd302aebbb77f4f95789a269c8a5463ac5a840Jeff Brown releaseReference(); 2147062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori } 2148bfe1dc27944c80dcb81f0eb313987999ecd7b6faVasu Nori return true; 2149062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori } 2150062fc7ce369758d5a26f83f12b50b11cd88e5defVasu Nori 2151e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown @Override 2152e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown public String toString() { 2153e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown return "SQLiteDatabase: " + getPath(); 2154e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 21559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2156e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown private void throwIfNotOpenLocked() { 2157e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown if (mConnectionPoolLocked == null) { 2158e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown throw new IllegalStateException("The database '" + mConfigurationLocked.label 2159e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown + "' is not open."); 2160e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 2161e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 21626f37f83a4802a0d411395f3abc5f24a2cfec025dVasu Nori 21636f37f83a4802a0d411395f3abc5f24a2cfec025dVasu Nori /** 2164e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Used to allow returning sub-classes of {@link Cursor} when calling query. 21656f37f83a4802a0d411395f3abc5f24a2cfec025dVasu Nori */ 2166e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown public interface CursorFactory { 2167e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown /** 2168e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * See {@link SQLiteCursor#SQLiteCursor(SQLiteCursorDriver, String, SQLiteQuery)}. 2169e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown */ 2170e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown public Cursor newCursor(SQLiteDatabase db, 2171e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown SQLiteCursorDriver masterQuery, String editTable, 2172e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown SQLiteQuery query); 2173e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 217434ad57f0e844cd97f59d4ab22087d60d58650ba4Vasu Nori 217534ad57f0e844cd97f59d4ab22087d60d58650ba4Vasu Nori /** 2176e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * A callback interface for a custom sqlite3 function. 2177e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * This can be used to create a function that can be called from 2178e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * sqlite3 database triggers. 2179e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * @hide 218034ad57f0e844cd97f59d4ab22087d60d58650ba4Vasu Nori */ 2181e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown public interface CustomFunction { 2182e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown public void callback(String[] args); 2183e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 21849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2185