blob: e575c26ff3c586c13e4e50784562cecc66fefa64 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.database.sqlite;
18
Jeff Brown4c1241d2012-02-02 17:05:00 -080019import android.content.CancellationSignal;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import android.content.ContentValues;
Jeff Brown75ea64f2012-01-25 19:37:13 -080021import android.content.OperationCanceledException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import android.database.Cursor;
Vasu Nori062fc7ce2010-03-31 16:13:05 -070023import android.database.DatabaseErrorHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024import android.database.DatabaseUtils;
Vasu Nori062fc7ce2010-03-31 16:13:05 -070025import android.database.DefaultDatabaseErrorHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026import android.database.SQLException;
Vasu Noric3849202010-03-09 10:47:25 -080027import android.database.sqlite.SQLiteDebug.DbStats;
Jeff Browne5360fb2011-10-31 17:48:13 -070028import android.os.Looper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import android.text.TextUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.util.EventLog;
Dmitri Plotnikov90142c92009-09-15 10:52:17 -070031import android.util.Log;
Vasu Noric3849202010-03-09 10:47:25 -080032import android.util.Pair;
Jeff Browne5360fb2011-10-31 17:48:13 -070033import android.util.Printer;
34
35import dalvik.system.CloseGuard;
36
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037import java.io.File;
Jeff Brown79087e42012-03-01 19:52:44 -080038import java.io.FileFilter;
Vasu Noric3849202010-03-09 10:47:25 -080039import java.util.ArrayList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import java.util.HashMap;
Jesse Wilson9b5a9352011-02-10 11:19:09 -080041import java.util.List;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042import java.util.Locale;
43import java.util.Map;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import java.util.WeakHashMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045
46/**
47 * Exposes methods to manage a SQLite database.
Jeff Browne5360fb2011-10-31 17:48:13 -070048 *
49 * <p>
50 * SQLiteDatabase has methods to create, delete, execute SQL commands, and
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051 * perform other common database management tasks.
Jeff Browne5360fb2011-10-31 17:48:13 -070052 * </p><p>
53 * See the Notepad sample application in the SDK for an example of creating
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054 * and managing a database.
Jeff Browne5360fb2011-10-31 17:48:13 -070055 * </p><p>
56 * Database names must be unique within an application, not across all applications.
57 * </p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058 *
59 * <h3>Localized Collation - ORDER BY</h3>
Jeff Browne5360fb2011-10-31 17:48:13 -070060 * <p>
61 * In addition to SQLite's default <code>BINARY</code> collator, Android supplies
62 * two more, <code>LOCALIZED</code>, which changes with the system's current locale,
63 * and <code>UNICODE</code>, which is the Unicode Collation Algorithm and not tailored
64 * to the current locale.
65 * </p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066 */
Jeff Brownbaefdfa2012-03-05 10:33:13 -080067public final class SQLiteDatabase extends SQLiteClosable {
Vasu Norifb16cbd2010-07-25 16:38:48 -070068 private static final String TAG = "SQLiteDatabase";
Jeff Browne5360fb2011-10-31 17:48:13 -070069
Jeff Hamilton082c2af2009-09-29 11:49:51 -070070 private static final int EVENT_DB_CORRUPT = 75004;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071
Jeff Browne5360fb2011-10-31 17:48:13 -070072 // Stores reference to all databases opened in the current process.
73 // (The referent Object is not used at this time.)
74 // INVARIANT: Guarded by sActiveDatabases.
75 private static WeakHashMap<SQLiteDatabase, Object> sActiveDatabases =
76 new WeakHashMap<SQLiteDatabase, Object>();
77
78 // Thread-local for database sessions that belong to this database.
79 // Each thread has its own database session.
80 // INVARIANT: Immutable.
81 private final ThreadLocal<SQLiteSession> mThreadSession = new ThreadLocal<SQLiteSession>() {
82 @Override
83 protected SQLiteSession initialValue() {
84 return createSession();
85 }
86 };
87
88 // The optional factory to use when creating new Cursors. May be null.
89 // INVARIANT: Immutable.
90 private final CursorFactory mCursorFactory;
91
92 // Error handler to be used when SQLite returns corruption errors.
93 // INVARIANT: Immutable.
94 private final DatabaseErrorHandler mErrorHandler;
95
96 // Shared database state lock.
97 // This lock guards all of the shared state of the database, such as its
98 // configuration, whether it is open or closed, and so on. This lock should
99 // be held for as little time as possible.
100 //
101 // The lock MUST NOT be held while attempting to acquire database connections or
102 // while executing SQL statements on behalf of the client as it can lead to deadlock.
103 //
104 // It is ok to hold the lock while reconfiguring the connection pool or dumping
105 // statistics because those operations are non-reentrant and do not try to acquire
106 // connections that might be held by other threads.
107 //
108 // Basic rule: grab the lock, access or modify global state, release the lock, then
109 // do the required SQL work.
110 private final Object mLock = new Object();
111
112 // Warns if the database is finalized without being closed properly.
113 // INVARIANT: Guarded by mLock.
114 private final CloseGuard mCloseGuardLocked = CloseGuard.get();
115
116 // The database configuration.
117 // INVARIANT: Guarded by mLock.
118 private final SQLiteDatabaseConfiguration mConfigurationLocked;
119
120 // The connection pool for the database, null when closed.
121 // The pool itself is thread-safe, but the reference to it can only be acquired
122 // when the lock is held.
123 // INVARIANT: Guarded by mLock.
124 private SQLiteConnectionPool mConnectionPoolLocked;
125
126 // True if the database has attached databases.
127 // INVARIANT: Guarded by mLock.
128 private boolean mHasAttachedDbsLocked;
129
130 // True if the database is in WAL mode.
131 // INVARIANT: Guarded by mLock.
132 private boolean mIsWALEnabledLocked;
133
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134 /**
Jeff Browne5360fb2011-10-31 17:48:13 -0700135 * When a constraint violation occurs, an immediate ROLLBACK occurs,
Vasu Nori8d45e4e2010-02-05 22:35:47 -0800136 * thus ending the current transaction, and the command aborts with a
137 * return code of SQLITE_CONSTRAINT. If no transaction is active
138 * (other than the implied transaction that is created on every command)
Jeff Browne5360fb2011-10-31 17:48:13 -0700139 * then this algorithm works the same as ABORT.
Vasu Nori8d45e4e2010-02-05 22:35:47 -0800140 */
141 public static final int CONFLICT_ROLLBACK = 1;
Dmitri Plotnikov600bdd82009-09-01 12:12:20 -0700142
Vasu Nori8d45e4e2010-02-05 22:35:47 -0800143 /**
144 * When a constraint violation occurs,no ROLLBACK is executed
145 * so changes from prior commands within the same transaction
146 * are preserved. This is the default behavior.
147 */
148 public static final int CONFLICT_ABORT = 2;
Dmitri Plotnikov600bdd82009-09-01 12:12:20 -0700149
Vasu Nori8d45e4e2010-02-05 22:35:47 -0800150 /**
151 * When a constraint violation occurs, the command aborts with a return
152 * code SQLITE_CONSTRAINT. But any changes to the database that
153 * the command made prior to encountering the constraint violation
154 * are preserved and are not backed out.
155 */
156 public static final int CONFLICT_FAIL = 3;
Dmitri Plotnikov600bdd82009-09-01 12:12:20 -0700157
Vasu Nori8d45e4e2010-02-05 22:35:47 -0800158 /**
159 * When a constraint violation occurs, the one row that contains
160 * the constraint violation is not inserted or changed.
161 * But the command continues executing normally. Other rows before and
162 * after the row that contained the constraint violation continue to be
163 * inserted or updated normally. No error is returned.
164 */
165 public static final int CONFLICT_IGNORE = 4;
Dmitri Plotnikov600bdd82009-09-01 12:12:20 -0700166
Vasu Nori8d45e4e2010-02-05 22:35:47 -0800167 /**
168 * When a UNIQUE constraint violation occurs, the pre-existing rows that
169 * are causing the constraint violation are removed prior to inserting
170 * or updating the current row. Thus the insert or update always occurs.
171 * The command continues executing normally. No error is returned.
172 * If a NOT NULL constraint violation occurs, the NULL value is replaced
173 * by the default value for that column. If the column has no default
174 * value, then the ABORT algorithm is used. If a CHECK constraint
175 * violation occurs then the IGNORE algorithm is used. When this conflict
176 * resolution strategy deletes rows in order to satisfy a constraint,
177 * it does not invoke delete triggers on those rows.
Jeff Browne5360fb2011-10-31 17:48:13 -0700178 * This behavior might change in a future release.
Vasu Nori8d45e4e2010-02-05 22:35:47 -0800179 */
180 public static final int CONFLICT_REPLACE = 5;
Dmitri Plotnikov600bdd82009-09-01 12:12:20 -0700181
Vasu Nori8d45e4e2010-02-05 22:35:47 -0800182 /**
Jeff Browne5360fb2011-10-31 17:48:13 -0700183 * Use the following when no conflict action is specified.
Vasu Nori8d45e4e2010-02-05 22:35:47 -0800184 */
185 public static final int CONFLICT_NONE = 0;
Jeff Browne5360fb2011-10-31 17:48:13 -0700186
Vasu Nori8d45e4e2010-02-05 22:35:47 -0800187 private static final String[] CONFLICT_VALUES = new String[]
188 {"", " OR ROLLBACK ", " OR ABORT ", " OR FAIL ", " OR IGNORE ", " OR REPLACE "};
Dmitri Plotnikov600bdd82009-09-01 12:12:20 -0700189
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800190 /**
191 * Maximum Length Of A LIKE Or GLOB Pattern
192 * The pattern matching algorithm used in the default LIKE and GLOB implementation
193 * of SQLite can exhibit O(N^2) performance (where N is the number of characters in
194 * the pattern) for certain pathological cases. To avoid denial-of-service attacks
195 * the length of the LIKE or GLOB pattern is limited to SQLITE_MAX_LIKE_PATTERN_LENGTH bytes.
196 * The default value of this limit is 50000. A modern workstation can evaluate
197 * even a pathological LIKE or GLOB pattern of 50000 bytes relatively quickly.
198 * The denial of service problem only comes into play when the pattern length gets
199 * into millions of bytes. Nevertheless, since most useful LIKE or GLOB patterns
200 * are at most a few dozen bytes in length, paranoid application developers may
201 * want to reduce this parameter to something in the range of a few hundred
202 * if they know that external users are able to generate arbitrary patterns.
203 */
204 public static final int SQLITE_MAX_LIKE_PATTERN_LENGTH = 50000;
205
206 /**
Jeff Browne5360fb2011-10-31 17:48:13 -0700207 * Open flag: Flag for {@link #openDatabase} to open the database for reading and writing.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800208 * If the disk is full, this may fail even before you actually write anything.
209 *
210 * {@more} Note that the value of this flag is 0, so it is the default.
211 */
212 public static final int OPEN_READWRITE = 0x00000000; // update native code if changing
213
214 /**
Jeff Browne5360fb2011-10-31 17:48:13 -0700215 * Open flag: Flag for {@link #openDatabase} to open the database for reading only.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800216 * This is the only reliable way to open a database if the disk may be full.
217 */
218 public static final int OPEN_READONLY = 0x00000001; // update native code if changing
219
220 private static final int OPEN_READ_MASK = 0x00000001; // update native code if changing
221
222 /**
Jeff Browne5360fb2011-10-31 17:48:13 -0700223 * Open flag: Flag for {@link #openDatabase} to open the database without support for
224 * localized collators.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800225 *
226 * {@more} This causes the collator <code>LOCALIZED</code> not to be created.
227 * You must be consistent when using this flag to use the setting the database was
228 * created with. If this is set, {@link #setLocale} will do nothing.
229 */
230 public static final int NO_LOCALIZED_COLLATORS = 0x00000010; // update native code if changing
231
232 /**
Jeff Browne5360fb2011-10-31 17:48:13 -0700233 * Open flag: Flag for {@link #openDatabase} to create the database file if it does not
234 * already exist.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800235 */
236 public static final int CREATE_IF_NECESSARY = 0x10000000; // update native code if changing
237
238 /**
Jeff Browne5360fb2011-10-31 17:48:13 -0700239 * Absolute max value that can be set by {@link #setMaxSqlCacheSize(int)}.
Vasu Norib729dcc2010-09-14 11:35:49 -0700240 *
Jeff Browne5360fb2011-10-31 17:48:13 -0700241 * Each prepared-statement is between 1K - 6K, depending on the complexity of the
242 * SQL statement & schema. A large SQL cache may use a significant amount of memory.
Vasu Norie495d1f2010-01-06 16:34:19 -0800243 */
Vasu Nori90a367262010-04-12 12:49:09 -0700244 public static final int MAX_SQL_CACHE_SIZE = 100;
Vasu Norib729dcc2010-09-14 11:35:49 -0700245
Jeff Browne5360fb2011-10-31 17:48:13 -0700246 private SQLiteDatabase(String path, int openFlags, CursorFactory cursorFactory,
247 DatabaseErrorHandler errorHandler) {
248 mCursorFactory = cursorFactory;
249 mErrorHandler = errorHandler != null ? errorHandler : new DefaultDatabaseErrorHandler();
250 mConfigurationLocked = new SQLiteDatabaseConfiguration(path, openFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800251 }
Dmitri Plotnikov600bdd82009-09-01 12:12:20 -0700252
Jeff Browne5360fb2011-10-31 17:48:13 -0700253 @Override
254 protected void finalize() throws Throwable {
255 try {
256 dispose(true);
257 } finally {
258 super.finalize();
259 }
Dmitri Plotnikov600bdd82009-09-01 12:12:20 -0700260 }
261
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800262 @Override
263 protected void onAllReferencesReleased() {
Jeff Browne5360fb2011-10-31 17:48:13 -0700264 dispose(false);
265 }
266
267 private void dispose(boolean finalized) {
268 final SQLiteConnectionPool pool;
269 synchronized (mLock) {
270 if (mCloseGuardLocked != null) {
271 if (finalized) {
272 mCloseGuardLocked.warnIfOpen();
273 }
274 mCloseGuardLocked.close();
275 }
276
277 pool = mConnectionPoolLocked;
278 mConnectionPoolLocked = null;
279 }
280
281 if (!finalized) {
282 synchronized (sActiveDatabases) {
283 sActiveDatabases.remove(this);
284 }
285
286 if (pool != null) {
287 pool.close();
288 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800289 }
290 }
291
292 /**
293 * Attempts to release memory that SQLite holds but does not require to
294 * operate properly. Typically this memory will come from the page cache.
Dmitri Plotnikov600bdd82009-09-01 12:12:20 -0700295 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800296 * @return the number of bytes actually released
297 */
Jeff Browne5360fb2011-10-31 17:48:13 -0700298 public static int releaseMemory() {
299 return SQLiteGlobal.releaseMemory();
300 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800301
302 /**
303 * Control whether or not the SQLiteDatabase is made thread-safe by using locks
304 * around critical sections. This is pretty expensive, so if you know that your
305 * DB will only be used by a single thread then you should set this to false.
306 * The default is true.
307 * @param lockingEnabled set to true to enable locks, false otherwise
Jeff Browne5360fb2011-10-31 17:48:13 -0700308 *
309 * @deprecated This method now does nothing. Do not use.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310 */
Jeff Browne5360fb2011-10-31 17:48:13 -0700311 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800312 public void setLockingEnabled(boolean lockingEnabled) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313 }
314
315 /**
Jeff Browne5360fb2011-10-31 17:48:13 -0700316 * Gets a label to use when describing the database in log messages.
317 * @return The label.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800318 */
Jeff Browne5360fb2011-10-31 17:48:13 -0700319 String getLabel() {
320 synchronized (mLock) {
321 return mConfigurationLocked.label;
322 }
323 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800324
Jeff Browne5360fb2011-10-31 17:48:13 -0700325 /**
326 * Sends a corruption message to the database error handler.
327 */
328 void onCorruption() {
329 EventLog.writeEvent(EVENT_DB_CORRUPT, getLabel());
Vasu Noriccd95442010-05-28 17:04:16 -0700330 mErrorHandler.onCorruption(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800331 }
332
333 /**
Jeff Browne5360fb2011-10-31 17:48:13 -0700334 * Gets the {@link SQLiteSession} that belongs to this thread for this database.
335 * Once a thread has obtained a session, it will continue to obtain the same
336 * session even after the database has been closed (although the session will not
337 * be usable). However, a thread that does not already have a session cannot
338 * obtain one after the database has been closed.
Dmitri Plotnikov600bdd82009-09-01 12:12:20 -0700339 *
Jeff Browne5360fb2011-10-31 17:48:13 -0700340 * The idea is that threads that have active connections to the database may still
341 * have work to complete even after the call to {@link #close}. Active database
342 * connections are not actually disposed until they are released by the threads
343 * that own them.
344 *
345 * @return The session, never null.
346 *
347 * @throws IllegalStateException if the thread does not yet have a session and
348 * the database is not open.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800349 */
Jeff Browne5360fb2011-10-31 17:48:13 -0700350 SQLiteSession getThreadSession() {
351 return mThreadSession.get(); // initialValue() throws if database closed
Vasu Nori6d970252010-10-05 10:48:49 -0700352 }
Vasu Nori16057fa2011-03-18 11:40:37 -0700353
Jeff Browne5360fb2011-10-31 17:48:13 -0700354 SQLiteSession createSession() {
355 final SQLiteConnectionPool pool;
356 synchronized (mLock) {
357 throwIfNotOpenLocked();
358 pool = mConnectionPoolLocked;
Vasu Nori6d970252010-10-05 10:48:49 -0700359 }
Jeff Browne5360fb2011-10-31 17:48:13 -0700360 return new SQLiteSession(pool);
Vasu Norid4608a32011-02-03 16:24:06 -0800361 }
362
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800363 /**
Jeff Browne5360fb2011-10-31 17:48:13 -0700364 * Gets default connection flags that are appropriate for this thread, taking into
365 * account whether the thread is acting on behalf of the UI.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800366 *
Jeff Browne5360fb2011-10-31 17:48:13 -0700367 * @param readOnly True if the connection should be read-only.
368 * @return The connection flags.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800369 */
Jeff Browne5360fb2011-10-31 17:48:13 -0700370 int getThreadDefaultConnectionFlags(boolean readOnly) {
371 int flags = readOnly ? SQLiteConnectionPool.CONNECTION_FLAG_READ_ONLY :
372 SQLiteConnectionPool.CONNECTION_FLAG_PRIMARY_CONNECTION_AFFINITY;
373 if (isMainThread()) {
374 flags |= SQLiteConnectionPool.CONNECTION_FLAG_INTERACTIVE;
375 }
376 return flags;
Vasu Nori16057fa2011-03-18 11:40:37 -0700377 }
378
Jeff Browne5360fb2011-10-31 17:48:13 -0700379 private static boolean isMainThread() {
380 // FIXME: There should be a better way to do this.
381 // Would also be nice to have something that would work across Binder calls.
382 Looper looper = Looper.myLooper();
383 return looper != null && looper == Looper.getMainLooper();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800384 }
385
386 /**
Vasu Noriccd95442010-05-28 17:04:16 -0700387 * Begins a transaction in EXCLUSIVE mode.
388 * <p>
389 * Transactions can be nested.
390 * When the outer transaction is ended all of
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800391 * the work done in that transaction and all of the nested transactions will be committed or
392 * rolled back. The changes will be rolled back if any transaction is ended without being
393 * marked as clean (by calling setTransactionSuccessful). Otherwise they will be committed.
Vasu Noriccd95442010-05-28 17:04:16 -0700394 * </p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 * <p>Here is the standard idiom for transactions:
396 *
397 * <pre>
398 * db.beginTransaction();
399 * try {
400 * ...
401 * db.setTransactionSuccessful();
402 * } finally {
403 * db.endTransaction();
404 * }
405 * </pre>
406 */
407 public void beginTransaction() {
Vasu Nori6c354da2010-04-26 23:33:39 -0700408 beginTransaction(null /* transactionStatusCallback */, true);
409 }
410
411 /**
412 * Begins a transaction in IMMEDIATE mode. Transactions can be nested. When
413 * the outer transaction is ended all of the work done in that transaction
414 * and all of the nested transactions will be committed or rolled back. The
415 * changes will be rolled back if any transaction is ended without being
416 * marked as clean (by calling setTransactionSuccessful). Otherwise they
417 * will be committed.
418 * <p>
419 * Here is the standard idiom for transactions:
420 *
421 * <pre>
422 * db.beginTransactionNonExclusive();
423 * try {
424 * ...
425 * db.setTransactionSuccessful();
426 * } finally {
427 * db.endTransaction();
428 * }
429 * </pre>
430 */
431 public void beginTransactionNonExclusive() {
432 beginTransaction(null /* transactionStatusCallback */, false);
Fred Quintanac4516a72009-09-03 12:14:06 -0700433 }
434
435 /**
Vasu Noriccd95442010-05-28 17:04:16 -0700436 * Begins a transaction in EXCLUSIVE mode.
437 * <p>
438 * Transactions can be nested.
439 * When the outer transaction is ended all of
Fred Quintanac4516a72009-09-03 12:14:06 -0700440 * the work done in that transaction and all of the nested transactions will be committed or
441 * rolled back. The changes will be rolled back if any transaction is ended without being
442 * marked as clean (by calling setTransactionSuccessful). Otherwise they will be committed.
Vasu Noriccd95442010-05-28 17:04:16 -0700443 * </p>
Fred Quintanac4516a72009-09-03 12:14:06 -0700444 * <p>Here is the standard idiom for transactions:
445 *
446 * <pre>
447 * db.beginTransactionWithListener(listener);
448 * try {
449 * ...
450 * db.setTransactionSuccessful();
451 * } finally {
452 * db.endTransaction();
453 * }
454 * </pre>
Vasu Noriccd95442010-05-28 17:04:16 -0700455 *
Fred Quintanac4516a72009-09-03 12:14:06 -0700456 * @param transactionListener listener that should be notified when the transaction begins,
457 * commits, or is rolled back, either explicitly or by a call to
458 * {@link #yieldIfContendedSafely}.
459 */
460 public void beginTransactionWithListener(SQLiteTransactionListener transactionListener) {
Vasu Nori6c354da2010-04-26 23:33:39 -0700461 beginTransaction(transactionListener, true);
462 }
463
464 /**
465 * Begins a transaction in IMMEDIATE mode. Transactions can be nested. When
466 * the outer transaction is ended all of the work done in that transaction
467 * and all of the nested transactions will be committed or rolled back. The
468 * changes will be rolled back if any transaction is ended without being
469 * marked as clean (by calling setTransactionSuccessful). Otherwise they
470 * will be committed.
471 * <p>
472 * Here is the standard idiom for transactions:
473 *
474 * <pre>
475 * db.beginTransactionWithListenerNonExclusive(listener);
476 * try {
477 * ...
478 * db.setTransactionSuccessful();
479 * } finally {
480 * db.endTransaction();
481 * }
482 * </pre>
483 *
484 * @param transactionListener listener that should be notified when the
485 * transaction begins, commits, or is rolled back, either
486 * explicitly or by a call to {@link #yieldIfContendedSafely}.
487 */
488 public void beginTransactionWithListenerNonExclusive(
489 SQLiteTransactionListener transactionListener) {
490 beginTransaction(transactionListener, false);
491 }
492
493 private void beginTransaction(SQLiteTransactionListener transactionListener,
494 boolean exclusive) {
Jeff Brown03bd3022012-03-06 13:48:56 -0800495 acquireReference();
496 try {
497 getThreadSession().beginTransaction(
498 exclusive ? SQLiteSession.TRANSACTION_MODE_EXCLUSIVE :
499 SQLiteSession.TRANSACTION_MODE_IMMEDIATE,
500 transactionListener,
501 getThreadDefaultConnectionFlags(false /*readOnly*/), null);
502 } finally {
503 releaseReference();
504 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800505 }
506
507 /**
508 * End a transaction. See beginTransaction for notes about how to use this and when transactions
509 * are committed and rolled back.
510 */
511 public void endTransaction() {
Jeff Brown03bd3022012-03-06 13:48:56 -0800512 acquireReference();
513 try {
514 getThreadSession().endTransaction(null);
515 } finally {
516 releaseReference();
517 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800518 }
519
520 /**
521 * Marks the current transaction as successful. Do not do any more database work between
522 * calling this and calling endTransaction. Do as little non-database work as possible in that
523 * situation too. If any errors are encountered between this and endTransaction the transaction
524 * will still be committed.
525 *
526 * @throws IllegalStateException if the current thread is not in a transaction or the
527 * transaction is already marked as successful.
528 */
529 public void setTransactionSuccessful() {
Jeff Brown03bd3022012-03-06 13:48:56 -0800530 acquireReference();
531 try {
532 getThreadSession().setTransactionSuccessful();
533 } finally {
534 releaseReference();
535 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800536 }
537
538 /**
Jeff Browne5360fb2011-10-31 17:48:13 -0700539 * Returns true if the current thread has a transaction pending.
540 *
541 * @return True if the current thread is in a transaction.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800542 */
543 public boolean inTransaction() {
Jeff Brown03bd3022012-03-06 13:48:56 -0800544 acquireReference();
545 try {
546 return getThreadSession().hasTransaction();
547 } finally {
548 releaseReference();
549 }
Vasu Norice38b982010-07-22 13:57:13 -0700550 }
551
552 /**
Jeff Browne5360fb2011-10-31 17:48:13 -0700553 * Returns true if the current thread is holding an active connection to the database.
Vasu Norice38b982010-07-22 13:57:13 -0700554 * <p>
Jeff Browne5360fb2011-10-31 17:48:13 -0700555 * The name of this method comes from a time when having an active connection
556 * to the database meant that the thread was holding an actual lock on the
557 * database. Nowadays, there is no longer a true "database lock" although threads
558 * may block if they cannot acquire a database connection to perform a
559 * particular operation.
560 * </p>
Vasu Norice38b982010-07-22 13:57:13 -0700561 *
Jeff Browne5360fb2011-10-31 17:48:13 -0700562 * @return True if the current thread is holding an active connection to the database.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800563 */
564 public boolean isDbLockedByCurrentThread() {
Jeff Brown03bd3022012-03-06 13:48:56 -0800565 acquireReference();
566 try {
567 return getThreadSession().hasConnection();
568 } finally {
569 releaseReference();
570 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800571 }
572
573 /**
Jeff Browne5360fb2011-10-31 17:48:13 -0700574 * Always returns false.
575 * <p>
576 * There is no longer the concept of a database lock, so this method always returns false.
577 * </p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800578 *
Jeff Browne5360fb2011-10-31 17:48:13 -0700579 * @return False.
580 * @deprecated Always returns false. Do not use this method.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800581 */
Jeff Browne5360fb2011-10-31 17:48:13 -0700582 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800583 public boolean isDbLockedByOtherThreads() {
Jeff Browne5360fb2011-10-31 17:48:13 -0700584 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800585 }
586
587 /**
588 * Temporarily end the transaction to let other threads run. The transaction is assumed to be
589 * successful so far. Do not call setTransactionSuccessful before calling this. When this
590 * returns a new transaction will have been created but not marked as successful.
591 * @return true if the transaction was yielded
592 * @deprecated if the db is locked more than once (becuase of nested transactions) then the lock
593 * will not be yielded. Use yieldIfContendedSafely instead.
594 */
Dianne Hackborn4a51c202009-08-21 15:14:02 -0700595 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800596 public boolean yieldIfContended() {
Fred Quintana5c7aede2009-08-27 21:41:27 -0700597 return yieldIfContendedHelper(false /* do not check yielding */,
598 -1 /* sleepAfterYieldDelay */);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800599 }
600
601 /**
602 * Temporarily end the transaction to let other threads run. The transaction is assumed to be
603 * successful so far. Do not call setTransactionSuccessful before calling this. When this
604 * returns a new transaction will have been created but not marked as successful. This assumes
605 * that there are no nested transactions (beginTransaction has only been called once) and will
Fred Quintana5c7aede2009-08-27 21:41:27 -0700606 * throw an exception if that is not the case.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800607 * @return true if the transaction was yielded
608 */
609 public boolean yieldIfContendedSafely() {
Fred Quintana5c7aede2009-08-27 21:41:27 -0700610 return yieldIfContendedHelper(true /* check yielding */, -1 /* sleepAfterYieldDelay*/);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800611 }
612
Fred Quintana5c7aede2009-08-27 21:41:27 -0700613 /**
614 * Temporarily end the transaction to let other threads run. The transaction is assumed to be
615 * successful so far. Do not call setTransactionSuccessful before calling this. When this
616 * returns a new transaction will have been created but not marked as successful. This assumes
617 * that there are no nested transactions (beginTransaction has only been called once) and will
618 * throw an exception if that is not the case.
619 * @param sleepAfterYieldDelay if > 0, sleep this long before starting a new transaction if
620 * the lock was actually yielded. This will allow other background threads to make some
621 * more progress than they would if we started the transaction immediately.
622 * @return true if the transaction was yielded
623 */
624 public boolean yieldIfContendedSafely(long sleepAfterYieldDelay) {
625 return yieldIfContendedHelper(true /* check yielding */, sleepAfterYieldDelay);
626 }
627
Jeff Browne5360fb2011-10-31 17:48:13 -0700628 private boolean yieldIfContendedHelper(boolean throwIfUnsafe, long sleepAfterYieldDelay) {
Jeff Brown03bd3022012-03-06 13:48:56 -0800629 acquireReference();
630 try {
631 return getThreadSession().yieldTransaction(sleepAfterYieldDelay, throwIfUnsafe, null);
632 } finally {
633 releaseReference();
634 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800635 }
636
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800637 /**
Jeff Browne5360fb2011-10-31 17:48:13 -0700638 * Deprecated.
Vasu Nori95675132010-07-21 16:24:40 -0700639 * @deprecated This method no longer serves any useful purpose and has been deprecated.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800640 */
Vasu Nori95675132010-07-21 16:24:40 -0700641 @Deprecated
642 public Map<String, String> getSyncedTables() {
643 return new HashMap<String, String>(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800644 }
645
646 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800647 * Open the database according to the flags {@link #OPEN_READWRITE}
648 * {@link #OPEN_READONLY} {@link #CREATE_IF_NECESSARY} and/or {@link #NO_LOCALIZED_COLLATORS}.
649 *
650 * <p>Sets the locale of the database to the the system's current locale.
651 * Call {@link #setLocale} if you would like something else.</p>
652 *
653 * @param path to database file to open and/or create
654 * @param factory an optional factory class that is called to instantiate a
655 * cursor when query is called, or null for default
656 * @param flags to control database access mode
657 * @return the newly opened database
658 * @throws SQLiteException if the database cannot be opened
659 */
660 public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags) {
Vasu Nori062fc7ce2010-03-31 16:13:05 -0700661 return openDatabase(path, factory, flags, new DefaultDatabaseErrorHandler());
662 }
663
664 /**
Vasu Nori74f170f2010-06-01 18:06:18 -0700665 * Open the database according to the flags {@link #OPEN_READWRITE}
666 * {@link #OPEN_READONLY} {@link #CREATE_IF_NECESSARY} and/or {@link #NO_LOCALIZED_COLLATORS}.
667 *
668 * <p>Sets the locale of the database to the the system's current locale.
669 * Call {@link #setLocale} if you would like something else.</p>
670 *
671 * <p>Accepts input param: a concrete instance of {@link DatabaseErrorHandler} to be
672 * used to handle corruption when sqlite reports database corruption.</p>
673 *
674 * @param path to database file to open and/or create
675 * @param factory an optional factory class that is called to instantiate a
676 * cursor when query is called, or null for default
677 * @param flags to control database access mode
678 * @param errorHandler the {@link DatabaseErrorHandler} obj to be used to handle corruption
679 * when sqlite reports database corruption
680 * @return the newly opened database
681 * @throws SQLiteException if the database cannot be opened
Vasu Nori062fc7ce2010-03-31 16:13:05 -0700682 */
683 public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags,
684 DatabaseErrorHandler errorHandler) {
Jeff Browne5360fb2011-10-31 17:48:13 -0700685 SQLiteDatabase db = new SQLiteDatabase(path, flags, factory, errorHandler);
686 db.open();
687 return db;
Vasu Nori062fc7ce2010-03-31 16:13:05 -0700688 }
689
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800690 /**
691 * Equivalent to openDatabase(file.getPath(), factory, CREATE_IF_NECESSARY).
692 */
693 public static SQLiteDatabase openOrCreateDatabase(File file, CursorFactory factory) {
694 return openOrCreateDatabase(file.getPath(), factory);
695 }
696
697 /**
698 * Equivalent to openDatabase(path, factory, CREATE_IF_NECESSARY).
699 */
700 public static SQLiteDatabase openOrCreateDatabase(String path, CursorFactory factory) {
701 return openDatabase(path, factory, CREATE_IF_NECESSARY);
702 }
703
704 /**
Vasu Nori6c354da2010-04-26 23:33:39 -0700705 * Equivalent to openDatabase(path, factory, CREATE_IF_NECESSARY, errorHandler).
Vasu Nori062fc7ce2010-03-31 16:13:05 -0700706 */
707 public static SQLiteDatabase openOrCreateDatabase(String path, CursorFactory factory,
708 DatabaseErrorHandler errorHandler) {
709 return openDatabase(path, factory, CREATE_IF_NECESSARY, errorHandler);
710 }
711
Jeff Brown559d0642012-02-29 10:19:12 -0800712 /**
Jeff Brown79087e42012-03-01 19:52:44 -0800713 * Deletes a database including its journal file and other auxiliary files
714 * that may have been created by the database engine.
715 *
716 * @param file The database file path.
717 * @return True if the database was successfully deleted.
718 */
719 public static boolean deleteDatabase(File file) {
720 if (file == null) {
721 throw new IllegalArgumentException("file must not be null");
722 }
723
724 boolean deleted = false;
725 deleted |= file.delete();
726 deleted |= new File(file.getPath() + "-journal").delete();
727 deleted |= new File(file.getPath() + "-shm").delete();
728 deleted |= new File(file.getPath() + "-wal").delete();
729
730 File dir = file.getParentFile();
731 if (dir != null) {
732 final String prefix = file.getName() + "-mj";
733 final FileFilter filter = new FileFilter() {
734 @Override
735 public boolean accept(File candidate) {
736 return candidate.getName().startsWith(prefix);
737 }
738 };
739 for (File masterJournal : dir.listFiles(filter)) {
740 deleted |= masterJournal.delete();
741 }
742 }
743 return deleted;
744 }
745
746 /**
Jeff Brown559d0642012-02-29 10:19:12 -0800747 * Reopens the database in read-write mode.
748 * If the database is already read-write, does nothing.
749 *
750 * @throws SQLiteException if the database could not be reopened as requested, in which
751 * case it remains open in read only mode.
752 * @throws IllegalStateException if the database is not open.
753 *
754 * @see #isReadOnly()
755 * @hide
756 */
757 public void reopenReadWrite() {
758 synchronized (mLock) {
759 throwIfNotOpenLocked();
760
761 if (!isReadOnlyLocked()) {
762 return; // nothing to do
763 }
764
765 // Reopen the database in read-write mode.
766 final int oldOpenFlags = mConfigurationLocked.openFlags;
767 mConfigurationLocked.openFlags = (mConfigurationLocked.openFlags & ~OPEN_READ_MASK)
768 | OPEN_READWRITE;
769 try {
770 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
771 } catch (RuntimeException ex) {
772 mConfigurationLocked.openFlags = oldOpenFlags;
773 throw ex;
774 }
775 }
776 }
777
Jeff Browne5360fb2011-10-31 17:48:13 -0700778 private void open() {
779 try {
780 try {
781 openInner();
782 } catch (SQLiteDatabaseCorruptException ex) {
783 onCorruption();
784 openInner();
785 }
Jeff Browne5360fb2011-10-31 17:48:13 -0700786 } catch (SQLiteException ex) {
787 Log.e(TAG, "Failed to open database '" + getLabel() + "'.", ex);
788 close();
789 throw ex;
790 }
791 }
792
793 private void openInner() {
794 synchronized (mLock) {
795 assert mConnectionPoolLocked == null;
796 mConnectionPoolLocked = SQLiteConnectionPool.open(mConfigurationLocked);
797 mCloseGuardLocked.open("close");
798 }
799
800 synchronized (sActiveDatabases) {
801 sActiveDatabases.put(this, null);
802 }
803 }
804
Vasu Nori062fc7ce2010-03-31 16:13:05 -0700805 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800806 * Create a memory backed SQLite database. Its contents will be destroyed
807 * when the database is closed.
808 *
809 * <p>Sets the locale of the database to the the system's current locale.
810 * Call {@link #setLocale} if you would like something else.</p>
811 *
812 * @param factory an optional factory class that is called to instantiate a
813 * cursor when query is called
814 * @return a SQLiteDatabase object, or null if the database can't be created
815 */
816 public static SQLiteDatabase create(CursorFactory factory) {
817 // This is a magic string with special meaning for SQLite.
Jeff Browne5360fb2011-10-31 17:48:13 -0700818 return openDatabase(SQLiteDatabaseConfiguration.MEMORY_DB_PATH,
819 factory, CREATE_IF_NECESSARY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800820 }
821
822 /**
Mike Lockwood9d9c1be2010-07-13 19:27:52 -0400823 * Registers a CustomFunction callback as a function that can be called from
Jeff Browne5360fb2011-10-31 17:48:13 -0700824 * SQLite database triggers.
825 *
Mike Lockwood9d9c1be2010-07-13 19:27:52 -0400826 * @param name the name of the sqlite3 function
827 * @param numArgs the number of arguments for the function
828 * @param function callback to call when the function is executed
829 * @hide
830 */
831 public void addCustomFunction(String name, int numArgs, CustomFunction function) {
Jeff Browne5360fb2011-10-31 17:48:13 -0700832 // Create wrapper (also validates arguments).
833 SQLiteCustomFunction wrapper = new SQLiteCustomFunction(name, numArgs, function);
834
835 synchronized (mLock) {
836 throwIfNotOpenLocked();
Jeff Browne67ca422012-03-21 17:24:05 -0700837
Jeff Browne5360fb2011-10-31 17:48:13 -0700838 mConfigurationLocked.customFunctions.add(wrapper);
Jeff Browne67ca422012-03-21 17:24:05 -0700839 try {
840 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
841 } catch (RuntimeException ex) {
842 mConfigurationLocked.customFunctions.remove(wrapper);
843 throw ex;
844 }
Mike Lockwood9d9c1be2010-07-13 19:27:52 -0400845 }
846 }
847
Mike Lockwood9d9c1be2010-07-13 19:27:52 -0400848 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800849 * Gets the database version.
850 *
851 * @return the database version
852 */
853 public int getVersion() {
Vasu Noriccd95442010-05-28 17:04:16 -0700854 return ((Long) DatabaseUtils.longForQuery(this, "PRAGMA user_version;", null)).intValue();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800855 }
856
857 /**
858 * Sets the database version.
859 *
860 * @param version the new database version
861 */
862 public void setVersion(int version) {
863 execSQL("PRAGMA user_version = " + version);
864 }
865
866 /**
867 * Returns the maximum size the database may grow to.
868 *
869 * @return the new maximum database size
870 */
871 public long getMaximumSize() {
Vasu Noriccd95442010-05-28 17:04:16 -0700872 long pageCount = DatabaseUtils.longForQuery(this, "PRAGMA max_page_count;", null);
873 return pageCount * getPageSize();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800874 }
875
876 /**
877 * Sets the maximum size the database will grow to. The maximum size cannot
878 * be set below the current size.
879 *
880 * @param numBytes the maximum database size, in bytes
881 * @return the new maximum database size
882 */
883 public long setMaximumSize(long numBytes) {
Vasu Noriccd95442010-05-28 17:04:16 -0700884 long pageSize = getPageSize();
885 long numPages = numBytes / pageSize;
886 // If numBytes isn't a multiple of pageSize, bump up a page
887 if ((numBytes % pageSize) != 0) {
888 numPages++;
Vasu Norif3cf8a42010-03-23 11:41:44 -0700889 }
Vasu Noriccd95442010-05-28 17:04:16 -0700890 long newPageCount = DatabaseUtils.longForQuery(this, "PRAGMA max_page_count = " + numPages,
891 null);
892 return newPageCount * pageSize;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800893 }
894
895 /**
896 * Returns the current database page size, in bytes.
897 *
898 * @return the database page size, in bytes
899 */
900 public long getPageSize() {
Vasu Noriccd95442010-05-28 17:04:16 -0700901 return DatabaseUtils.longForQuery(this, "PRAGMA page_size;", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800902 }
903
904 /**
905 * Sets the database page size. The page size must be a power of two. This
906 * method does not work if any data has been written to the database file,
907 * and must be called right after the database has been created.
908 *
909 * @param numBytes the database page size, in bytes
910 */
911 public void setPageSize(long numBytes) {
912 execSQL("PRAGMA page_size = " + numBytes);
913 }
914
915 /**
916 * Mark this table as syncable. When an update occurs in this table the
917 * _sync_dirty field will be set to ensure proper syncing operation.
918 *
919 * @param table the table to mark as syncable
920 * @param deletedTable The deleted table that corresponds to the
921 * syncable table
Vasu Nori95675132010-07-21 16:24:40 -0700922 * @deprecated This method no longer serves any useful purpose and has been deprecated.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800923 */
Vasu Nori95675132010-07-21 16:24:40 -0700924 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800925 public void markTableSyncable(String table, String deletedTable) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800926 }
927
928 /**
929 * Mark this table as syncable, with the _sync_dirty residing in another
930 * table. When an update occurs in this table the _sync_dirty field of the
931 * row in updateTable with the _id in foreignKey will be set to
932 * ensure proper syncing operation.
933 *
934 * @param table an update on this table will trigger a sync time removal
935 * @param foreignKey this is the column in table whose value is an _id in
936 * updateTable
937 * @param updateTable this is the table that will have its _sync_dirty
Vasu Nori95675132010-07-21 16:24:40 -0700938 * @deprecated This method no longer serves any useful purpose and has been deprecated.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800939 */
Vasu Nori95675132010-07-21 16:24:40 -0700940 @Deprecated
941 public void markTableSyncable(String table, String foreignKey, String updateTable) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800942 }
943
944 /**
945 * Finds the name of the first table, which is editable.
946 *
947 * @param tables a list of tables
948 * @return the first table listed
949 */
950 public static String findEditTable(String tables) {
951 if (!TextUtils.isEmpty(tables)) {
952 // find the first word terminated by either a space or a comma
953 int spacepos = tables.indexOf(' ');
954 int commapos = tables.indexOf(',');
955
956 if (spacepos > 0 && (spacepos < commapos || commapos < 0)) {
957 return tables.substring(0, spacepos);
958 } else if (commapos > 0 && (commapos < spacepos || spacepos < 0) ) {
959 return tables.substring(0, commapos);
960 }
961 return tables;
962 } else {
963 throw new IllegalStateException("Invalid tables");
964 }
965 }
966
967 /**
968 * Compiles an SQL statement into a reusable pre-compiled statement object.
969 * The parameters are identical to {@link #execSQL(String)}. You may put ?s in the
970 * statement and fill in those values with {@link SQLiteProgram#bindString}
971 * and {@link SQLiteProgram#bindLong} each time you want to run the
972 * statement. Statements may not return result sets larger than 1x1.
Vasu Nori2827d6d2010-07-04 00:26:18 -0700973 *<p>
974 * No two threads should be using the same {@link SQLiteStatement} at the same time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800975 *
976 * @param sql The raw SQL statement, may contain ? for unknown values to be
977 * bound later.
Jeff Hamiltonf3ca9a52010-05-12 15:04:33 -0700978 * @return A pre-compiled {@link SQLiteStatement} object. Note that
979 * {@link SQLiteStatement}s are not synchronized, see the documentation for more details.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800980 */
981 public SQLiteStatement compileStatement(String sql) throws SQLException {
Jeff Brown03bd3022012-03-06 13:48:56 -0800982 acquireReference();
983 try {
984 return new SQLiteStatement(this, sql, null);
985 } finally {
986 releaseReference();
987 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800988 }
989
990 /**
991 * Query the given URL, returning a {@link Cursor} over the result set.
992 *
993 * @param distinct true if you want each row to be unique, false otherwise.
994 * @param table The table name to compile the query against.
995 * @param columns A list of which columns to return. Passing null will
996 * return all columns, which is discouraged to prevent reading
997 * data from storage that isn't going to be used.
998 * @param selection A filter declaring which rows to return, formatted as an
999 * SQL WHERE clause (excluding the WHERE itself). Passing null
1000 * will return all rows for the given table.
1001 * @param selectionArgs You may include ?s in selection, which will be
1002 * replaced by the values from selectionArgs, in order that they
1003 * appear in the selection. The values will be bound as Strings.
1004 * @param groupBy A filter declaring how to group rows, formatted as an SQL
1005 * GROUP BY clause (excluding the GROUP BY itself). Passing null
1006 * will cause the rows to not be grouped.
1007 * @param having A filter declare which row groups to include in the cursor,
1008 * if row grouping is being used, formatted as an SQL HAVING
1009 * clause (excluding the HAVING itself). Passing null will cause
1010 * all row groups to be included, and is required when row
1011 * grouping is not being used.
1012 * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
1013 * (excluding the ORDER BY itself). Passing null will use the
1014 * default sort order, which may be unordered.
1015 * @param limit Limits the number of rows returned by the query,
1016 * formatted as LIMIT clause. Passing null denotes no LIMIT clause.
Jeff Hamiltonf3ca9a52010-05-12 15:04:33 -07001017 * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1018 * {@link Cursor}s are not synchronized, see the documentation for more details.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001019 * @see Cursor
1020 */
1021 public Cursor query(boolean distinct, String table, String[] columns,
1022 String selection, String[] selectionArgs, String groupBy,
1023 String having, String orderBy, String limit) {
1024 return queryWithFactory(null, distinct, table, columns, selection, selectionArgs,
Jeff Brown75ea64f2012-01-25 19:37:13 -08001025 groupBy, having, orderBy, limit, null);
1026 }
1027
1028 /**
1029 * Query the given URL, returning a {@link Cursor} over the result set.
1030 *
1031 * @param distinct true if you want each row to be unique, false otherwise.
1032 * @param table The table name to compile the query against.
1033 * @param columns A list of which columns to return. Passing null will
1034 * return all columns, which is discouraged to prevent reading
1035 * data from storage that isn't going to be used.
1036 * @param selection A filter declaring which rows to return, formatted as an
1037 * SQL WHERE clause (excluding the WHERE itself). Passing null
1038 * will return all rows for the given table.
1039 * @param selectionArgs You may include ?s in selection, which will be
1040 * replaced by the values from selectionArgs, in order that they
1041 * appear in the selection. The values will be bound as Strings.
1042 * @param groupBy A filter declaring how to group rows, formatted as an SQL
1043 * GROUP BY clause (excluding the GROUP BY itself). Passing null
1044 * will cause the rows to not be grouped.
1045 * @param having A filter declare which row groups to include in the cursor,
1046 * if row grouping is being used, formatted as an SQL HAVING
1047 * clause (excluding the HAVING itself). Passing null will cause
1048 * all row groups to be included, and is required when row
1049 * grouping is not being used.
1050 * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
1051 * (excluding the ORDER BY itself). Passing null will use the
1052 * default sort order, which may be unordered.
1053 * @param limit Limits the number of rows returned by the query,
1054 * formatted as LIMIT clause. Passing null denotes no LIMIT clause.
Jeff Brown4c1241d2012-02-02 17:05:00 -08001055 * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
Jeff Brown75ea64f2012-01-25 19:37:13 -08001056 * If the operation is canceled, then {@link OperationCanceledException} will be thrown
1057 * when the query is executed.
1058 * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1059 * {@link Cursor}s are not synchronized, see the documentation for more details.
1060 * @see Cursor
1061 */
1062 public Cursor query(boolean distinct, String table, String[] columns,
1063 String selection, String[] selectionArgs, String groupBy,
Jeff Brown4c1241d2012-02-02 17:05:00 -08001064 String having, String orderBy, String limit, CancellationSignal cancellationSignal) {
Jeff Brown75ea64f2012-01-25 19:37:13 -08001065 return queryWithFactory(null, distinct, table, columns, selection, selectionArgs,
Jeff Brown4c1241d2012-02-02 17:05:00 -08001066 groupBy, having, orderBy, limit, cancellationSignal);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001067 }
1068
1069 /**
1070 * Query the given URL, returning a {@link Cursor} over the result set.
1071 *
1072 * @param cursorFactory the cursor factory to use, or null for the default factory
1073 * @param distinct true if you want each row to be unique, false otherwise.
1074 * @param table The table name to compile the query against.
1075 * @param columns A list of which columns to return. Passing null will
1076 * return all columns, which is discouraged to prevent reading
1077 * data from storage that isn't going to be used.
1078 * @param selection A filter declaring which rows to return, formatted as an
1079 * SQL WHERE clause (excluding the WHERE itself). Passing null
1080 * will return all rows for the given table.
1081 * @param selectionArgs You may include ?s in selection, which will be
1082 * replaced by the values from selectionArgs, in order that they
1083 * appear in the selection. The values will be bound as Strings.
1084 * @param groupBy A filter declaring how to group rows, formatted as an SQL
1085 * GROUP BY clause (excluding the GROUP BY itself). Passing null
1086 * will cause the rows to not be grouped.
1087 * @param having A filter declare which row groups to include in the cursor,
1088 * if row grouping is being used, formatted as an SQL HAVING
1089 * clause (excluding the HAVING itself). Passing null will cause
1090 * all row groups to be included, and is required when row
1091 * grouping is not being used.
1092 * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
1093 * (excluding the ORDER BY itself). Passing null will use the
1094 * default sort order, which may be unordered.
1095 * @param limit Limits the number of rows returned by the query,
1096 * formatted as LIMIT clause. Passing null denotes no LIMIT clause.
Jeff Hamiltonf3ca9a52010-05-12 15:04:33 -07001097 * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1098 * {@link Cursor}s are not synchronized, see the documentation for more details.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001099 * @see Cursor
1100 */
1101 public Cursor queryWithFactory(CursorFactory cursorFactory,
1102 boolean distinct, String table, String[] columns,
1103 String selection, String[] selectionArgs, String groupBy,
1104 String having, String orderBy, String limit) {
Jeff Brown75ea64f2012-01-25 19:37:13 -08001105 return queryWithFactory(cursorFactory, distinct, table, columns, selection,
1106 selectionArgs, groupBy, having, orderBy, limit, null);
1107 }
1108
1109 /**
1110 * Query the given URL, returning a {@link Cursor} over the result set.
1111 *
1112 * @param cursorFactory the cursor factory to use, or null for the default factory
1113 * @param distinct true if you want each row to be unique, false otherwise.
1114 * @param table The table name to compile the query against.
1115 * @param columns A list of which columns to return. Passing null will
1116 * return all columns, which is discouraged to prevent reading
1117 * data from storage that isn't going to be used.
1118 * @param selection A filter declaring which rows to return, formatted as an
1119 * SQL WHERE clause (excluding the WHERE itself). Passing null
1120 * will return all rows for the given table.
1121 * @param selectionArgs You may include ?s in selection, which will be
1122 * replaced by the values from selectionArgs, in order that they
1123 * appear in the selection. The values will be bound as Strings.
1124 * @param groupBy A filter declaring how to group rows, formatted as an SQL
1125 * GROUP BY clause (excluding the GROUP BY itself). Passing null
1126 * will cause the rows to not be grouped.
1127 * @param having A filter declare which row groups to include in the cursor,
1128 * if row grouping is being used, formatted as an SQL HAVING
1129 * clause (excluding the HAVING itself). Passing null will cause
1130 * all row groups to be included, and is required when row
1131 * grouping is not being used.
1132 * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
1133 * (excluding the ORDER BY itself). Passing null will use the
1134 * default sort order, which may be unordered.
1135 * @param limit Limits the number of rows returned by the query,
1136 * formatted as LIMIT clause. Passing null denotes no LIMIT clause.
Jeff Brown4c1241d2012-02-02 17:05:00 -08001137 * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
Jeff Brown75ea64f2012-01-25 19:37:13 -08001138 * If the operation is canceled, then {@link OperationCanceledException} will be thrown
1139 * when the query is executed.
1140 * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1141 * {@link Cursor}s are not synchronized, see the documentation for more details.
1142 * @see Cursor
1143 */
1144 public Cursor queryWithFactory(CursorFactory cursorFactory,
1145 boolean distinct, String table, String[] columns,
1146 String selection, String[] selectionArgs, String groupBy,
Jeff Brown4c1241d2012-02-02 17:05:00 -08001147 String having, String orderBy, String limit, CancellationSignal cancellationSignal) {
Jeff Brown03bd3022012-03-06 13:48:56 -08001148 acquireReference();
1149 try {
1150 String sql = SQLiteQueryBuilder.buildQueryString(
1151 distinct, table, columns, selection, groupBy, having, orderBy, limit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001152
Jeff Brown03bd3022012-03-06 13:48:56 -08001153 return rawQueryWithFactory(cursorFactory, sql, selectionArgs,
1154 findEditTable(table), cancellationSignal);
1155 } finally {
1156 releaseReference();
1157 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001158 }
1159
1160 /**
1161 * Query the given table, returning a {@link Cursor} over the result set.
1162 *
1163 * @param table The table name to compile the query against.
1164 * @param columns A list of which columns to return. Passing null will
1165 * return all columns, which is discouraged to prevent reading
1166 * data from storage that isn't going to be used.
1167 * @param selection A filter declaring which rows to return, formatted as an
1168 * SQL WHERE clause (excluding the WHERE itself). Passing null
1169 * will return all rows for the given table.
1170 * @param selectionArgs You may include ?s in selection, which will be
1171 * replaced by the values from selectionArgs, in order that they
1172 * appear in the selection. The values will be bound as Strings.
1173 * @param groupBy A filter declaring how to group rows, formatted as an SQL
1174 * GROUP BY clause (excluding the GROUP BY itself). Passing null
1175 * will cause the rows to not be grouped.
1176 * @param having A filter declare which row groups to include in the cursor,
1177 * if row grouping is being used, formatted as an SQL HAVING
1178 * clause (excluding the HAVING itself). Passing null will cause
1179 * all row groups to be included, and is required when row
1180 * grouping is not being used.
1181 * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
1182 * (excluding the ORDER BY itself). Passing null will use the
1183 * default sort order, which may be unordered.
Jeff Hamiltonf3ca9a52010-05-12 15:04:33 -07001184 * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1185 * {@link Cursor}s are not synchronized, see the documentation for more details.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001186 * @see Cursor
1187 */
1188 public Cursor query(String table, String[] columns, String selection,
1189 String[] selectionArgs, String groupBy, String having,
1190 String orderBy) {
1191
1192 return query(false, table, columns, selection, selectionArgs, groupBy,
1193 having, orderBy, null /* limit */);
1194 }
1195
1196 /**
1197 * Query the given table, returning a {@link Cursor} over the result set.
1198 *
1199 * @param table The table name to compile the query against.
1200 * @param columns A list of which columns to return. Passing null will
1201 * return all columns, which is discouraged to prevent reading
1202 * data from storage that isn't going to be used.
1203 * @param selection A filter declaring which rows to return, formatted as an
1204 * SQL WHERE clause (excluding the WHERE itself). Passing null
1205 * will return all rows for the given table.
1206 * @param selectionArgs You may include ?s in selection, which will be
1207 * replaced by the values from selectionArgs, in order that they
1208 * appear in the selection. The values will be bound as Strings.
1209 * @param groupBy A filter declaring how to group rows, formatted as an SQL
1210 * GROUP BY clause (excluding the GROUP BY itself). Passing null
1211 * will cause the rows to not be grouped.
1212 * @param having A filter declare which row groups to include in the cursor,
1213 * if row grouping is being used, formatted as an SQL HAVING
1214 * clause (excluding the HAVING itself). Passing null will cause
1215 * all row groups to be included, and is required when row
1216 * grouping is not being used.
1217 * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
1218 * (excluding the ORDER BY itself). Passing null will use the
1219 * default sort order, which may be unordered.
1220 * @param limit Limits the number of rows returned by the query,
1221 * formatted as LIMIT clause. Passing null denotes no LIMIT clause.
Jeff Hamiltonf3ca9a52010-05-12 15:04:33 -07001222 * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1223 * {@link Cursor}s are not synchronized, see the documentation for more details.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001224 * @see Cursor
1225 */
1226 public Cursor query(String table, String[] columns, String selection,
1227 String[] selectionArgs, String groupBy, String having,
1228 String orderBy, String limit) {
1229
1230 return query(false, table, columns, selection, selectionArgs, groupBy,
1231 having, orderBy, limit);
1232 }
1233
1234 /**
1235 * Runs the provided SQL and returns a {@link Cursor} over the result set.
1236 *
1237 * @param sql the SQL query. The SQL string must not be ; terminated
1238 * @param selectionArgs You may include ?s in where clause in the query,
1239 * which will be replaced by the values from selectionArgs. The
1240 * values will be bound as Strings.
Jeff Hamiltonf3ca9a52010-05-12 15:04:33 -07001241 * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1242 * {@link Cursor}s are not synchronized, see the documentation for more details.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001243 */
1244 public Cursor rawQuery(String sql, String[] selectionArgs) {
Jeff Brown75ea64f2012-01-25 19:37:13 -08001245 return rawQueryWithFactory(null, sql, selectionArgs, null, null);
1246 }
1247
1248 /**
1249 * Runs the provided SQL and returns a {@link Cursor} over the result set.
1250 *
1251 * @param sql the SQL query. The SQL string must not be ; terminated
1252 * @param selectionArgs You may include ?s in where clause in the query,
1253 * which will be replaced by the values from selectionArgs. The
1254 * values will be bound as Strings.
Jeff Brown4c1241d2012-02-02 17:05:00 -08001255 * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
Jeff Brown75ea64f2012-01-25 19:37:13 -08001256 * If the operation is canceled, then {@link OperationCanceledException} will be thrown
1257 * when the query is executed.
1258 * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1259 * {@link Cursor}s are not synchronized, see the documentation for more details.
1260 */
1261 public Cursor rawQuery(String sql, String[] selectionArgs,
Jeff Brown4c1241d2012-02-02 17:05:00 -08001262 CancellationSignal cancellationSignal) {
1263 return rawQueryWithFactory(null, sql, selectionArgs, null, cancellationSignal);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001264 }
1265
1266 /**
1267 * Runs the provided SQL and returns a cursor over the result set.
1268 *
1269 * @param cursorFactory the cursor factory to use, or null for the default factory
1270 * @param sql the SQL query. The SQL string must not be ; terminated
1271 * @param selectionArgs You may include ?s in where clause in the query,
1272 * which will be replaced by the values from selectionArgs. The
1273 * values will be bound as Strings.
1274 * @param editTable the name of the first table, which is editable
Jeff Hamiltonf3ca9a52010-05-12 15:04:33 -07001275 * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1276 * {@link Cursor}s are not synchronized, see the documentation for more details.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001277 */
1278 public Cursor rawQueryWithFactory(
1279 CursorFactory cursorFactory, String sql, String[] selectionArgs,
1280 String editTable) {
Jeff Brown75ea64f2012-01-25 19:37:13 -08001281 return rawQueryWithFactory(cursorFactory, sql, selectionArgs, editTable, null);
1282 }
1283
1284 /**
1285 * Runs the provided SQL and returns a cursor over the result set.
1286 *
1287 * @param cursorFactory the cursor factory to use, or null for the default factory
1288 * @param sql the SQL query. The SQL string must not be ; terminated
1289 * @param selectionArgs You may include ?s in where clause in the query,
1290 * which will be replaced by the values from selectionArgs. The
1291 * values will be bound as Strings.
1292 * @param editTable the name of the first table, which is editable
Jeff Brown4c1241d2012-02-02 17:05:00 -08001293 * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
Jeff Brown75ea64f2012-01-25 19:37:13 -08001294 * If the operation is canceled, then {@link OperationCanceledException} will be thrown
1295 * when the query is executed.
1296 * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1297 * {@link Cursor}s are not synchronized, see the documentation for more details.
1298 */
1299 public Cursor rawQueryWithFactory(
1300 CursorFactory cursorFactory, String sql, String[] selectionArgs,
Jeff Brown4c1241d2012-02-02 17:05:00 -08001301 String editTable, CancellationSignal cancellationSignal) {
Jeff Brown03bd3022012-03-06 13:48:56 -08001302 acquireReference();
1303 try {
1304 SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(this, sql, editTable,
1305 cancellationSignal);
1306 return driver.query(cursorFactory != null ? cursorFactory : mCursorFactory,
1307 selectionArgs);
1308 } finally {
1309 releaseReference();
1310 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001311 }
1312
1313 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001314 * Convenience method for inserting a row into the database.
1315 *
1316 * @param table the table to insert the row into
Brad Fitzpatrick69ea4e12011-01-05 11:13:40 -08001317 * @param nullColumnHack optional; may be <code>null</code>.
1318 * SQL doesn't allow inserting a completely empty row without
1319 * naming at least one column name. If your provided <code>values</code> is
1320 * empty, no column names are known and an empty row can't be inserted.
1321 * If not set to null, the <code>nullColumnHack</code> parameter
1322 * provides the name of nullable column name to explicitly insert a NULL into
1323 * in the case where your <code>values</code> is empty.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001324 * @param values this map contains the initial column values for the
1325 * row. The keys should be the column names and the values the
1326 * column values
1327 * @return the row ID of the newly inserted row, or -1 if an error occurred
1328 */
1329 public long insert(String table, String nullColumnHack, ContentValues values) {
1330 try {
Vasu Nori8d45e4e2010-02-05 22:35:47 -08001331 return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001332 } catch (SQLException e) {
1333 Log.e(TAG, "Error inserting " + values, e);
1334 return -1;
1335 }
1336 }
1337
1338 /**
1339 * Convenience method for inserting a row into the database.
1340 *
1341 * @param table the table to insert the row into
Brad Fitzpatrick69ea4e12011-01-05 11:13:40 -08001342 * @param nullColumnHack optional; may be <code>null</code>.
1343 * SQL doesn't allow inserting a completely empty row without
1344 * naming at least one column name. If your provided <code>values</code> is
1345 * empty, no column names are known and an empty row can't be inserted.
1346 * If not set to null, the <code>nullColumnHack</code> parameter
1347 * provides the name of nullable column name to explicitly insert a NULL into
1348 * in the case where your <code>values</code> is empty.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001349 * @param values this map contains the initial column values for the
1350 * row. The keys should be the column names and the values the
1351 * column values
1352 * @throws SQLException
1353 * @return the row ID of the newly inserted row, or -1 if an error occurred
1354 */
1355 public long insertOrThrow(String table, String nullColumnHack, ContentValues values)
1356 throws SQLException {
Vasu Nori8d45e4e2010-02-05 22:35:47 -08001357 return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001358 }
1359
1360 /**
1361 * Convenience method for replacing a row in the database.
1362 *
1363 * @param table the table in which to replace the row
Brad Fitzpatrick69ea4e12011-01-05 11:13:40 -08001364 * @param nullColumnHack optional; may be <code>null</code>.
1365 * SQL doesn't allow inserting a completely empty row without
1366 * naming at least one column name. If your provided <code>initialValues</code> is
1367 * empty, no column names are known and an empty row can't be inserted.
1368 * If not set to null, the <code>nullColumnHack</code> parameter
1369 * provides the name of nullable column name to explicitly insert a NULL into
1370 * in the case where your <code>initialValues</code> is empty.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001371 * @param initialValues this map contains the initial column values for
Brad Fitzpatrick69ea4e12011-01-05 11:13:40 -08001372 * the row.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001373 * @return the row ID of the newly inserted row, or -1 if an error occurred
1374 */
1375 public long replace(String table, String nullColumnHack, ContentValues initialValues) {
1376 try {
Dmitri Plotnikov600bdd82009-09-01 12:12:20 -07001377 return insertWithOnConflict(table, nullColumnHack, initialValues,
Vasu Nori8d45e4e2010-02-05 22:35:47 -08001378 CONFLICT_REPLACE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001379 } catch (SQLException e) {
1380 Log.e(TAG, "Error inserting " + initialValues, e);
1381 return -1;
1382 }
1383 }
1384
1385 /**
1386 * Convenience method for replacing a row in the database.
1387 *
1388 * @param table the table in which to replace the row
Brad Fitzpatrick69ea4e12011-01-05 11:13:40 -08001389 * @param nullColumnHack optional; may be <code>null</code>.
1390 * SQL doesn't allow inserting a completely empty row without
1391 * naming at least one column name. If your provided <code>initialValues</code> is
1392 * empty, no column names are known and an empty row can't be inserted.
1393 * If not set to null, the <code>nullColumnHack</code> parameter
1394 * provides the name of nullable column name to explicitly insert a NULL into
1395 * in the case where your <code>initialValues</code> is empty.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001396 * @param initialValues this map contains the initial column values for
1397 * the row. The key
1398 * @throws SQLException
1399 * @return the row ID of the newly inserted row, or -1 if an error occurred
1400 */
1401 public long replaceOrThrow(String table, String nullColumnHack,
1402 ContentValues initialValues) throws SQLException {
Dmitri Plotnikov600bdd82009-09-01 12:12:20 -07001403 return insertWithOnConflict(table, nullColumnHack, initialValues,
Vasu Nori8d45e4e2010-02-05 22:35:47 -08001404 CONFLICT_REPLACE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001405 }
1406
1407 /**
1408 * General method for inserting a row into the database.
1409 *
1410 * @param table the table to insert the row into
Brad Fitzpatrick69ea4e12011-01-05 11:13:40 -08001411 * @param nullColumnHack optional; may be <code>null</code>.
1412 * SQL doesn't allow inserting a completely empty row without
1413 * naming at least one column name. If your provided <code>initialValues</code> is
1414 * empty, no column names are known and an empty row can't be inserted.
1415 * If not set to null, the <code>nullColumnHack</code> parameter
1416 * provides the name of nullable column name to explicitly insert a NULL into
1417 * in the case where your <code>initialValues</code> is empty.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001418 * @param initialValues this map contains the initial column values for the
1419 * row. The keys should be the column names and the values the
1420 * column values
Vasu Nori8d45e4e2010-02-05 22:35:47 -08001421 * @param conflictAlgorithm for insert conflict resolver
Vasu Nori6eb7c452010-01-27 14:31:24 -08001422 * @return the row ID of the newly inserted row
1423 * OR the primary key of the existing row if the input param 'conflictAlgorithm' =
Vasu Nori8d45e4e2010-02-05 22:35:47 -08001424 * {@link #CONFLICT_IGNORE}
Vasu Nori6eb7c452010-01-27 14:31:24 -08001425 * OR -1 if any error
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001426 */
1427 public long insertWithOnConflict(String table, String nullColumnHack,
Vasu Nori6eb7c452010-01-27 14:31:24 -08001428 ContentValues initialValues, int conflictAlgorithm) {
Jeff Brown03bd3022012-03-06 13:48:56 -08001429 acquireReference();
1430 try {
1431 StringBuilder sql = new StringBuilder();
1432 sql.append("INSERT");
1433 sql.append(CONFLICT_VALUES[conflictAlgorithm]);
1434 sql.append(" INTO ");
1435 sql.append(table);
1436 sql.append('(');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001437
Jeff Brown03bd3022012-03-06 13:48:56 -08001438 Object[] bindArgs = null;
1439 int size = (initialValues != null && initialValues.size() > 0)
1440 ? initialValues.size() : 0;
1441 if (size > 0) {
1442 bindArgs = new Object[size];
1443 int i = 0;
1444 for (String colName : initialValues.keySet()) {
1445 sql.append((i > 0) ? "," : "");
1446 sql.append(colName);
1447 bindArgs[i++] = initialValues.get(colName);
1448 }
1449 sql.append(')');
1450 sql.append(" VALUES (");
1451 for (i = 0; i < size; i++) {
1452 sql.append((i > 0) ? ",?" : "?");
1453 }
1454 } else {
1455 sql.append(nullColumnHack + ") VALUES (NULL");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001456 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001457 sql.append(')');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001458
Jeff Brown03bd3022012-03-06 13:48:56 -08001459 SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs);
1460 try {
1461 return statement.executeInsert();
1462 } finally {
1463 statement.close();
1464 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001465 } finally {
Jeff Brown03bd3022012-03-06 13:48:56 -08001466 releaseReference();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001467 }
1468 }
1469
1470 /**
1471 * Convenience method for deleting rows in the database.
1472 *
1473 * @param table the table to delete from
1474 * @param whereClause the optional WHERE clause to apply when deleting.
1475 * Passing null will delete all rows.
1476 * @return the number of rows affected if a whereClause is passed in, 0
1477 * otherwise. To remove all rows and get a count pass "1" as the
1478 * whereClause.
1479 */
1480 public int delete(String table, String whereClause, String[] whereArgs) {
Jeff Brown03bd3022012-03-06 13:48:56 -08001481 acquireReference();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001482 try {
Jeff Brown03bd3022012-03-06 13:48:56 -08001483 SQLiteStatement statement = new SQLiteStatement(this, "DELETE FROM " + table +
1484 (!TextUtils.isEmpty(whereClause) ? " WHERE " + whereClause : ""), whereArgs);
1485 try {
1486 return statement.executeUpdateDelete();
1487 } finally {
1488 statement.close();
1489 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001490 } finally {
Jeff Brown03bd3022012-03-06 13:48:56 -08001491 releaseReference();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001492 }
1493 }
1494
1495 /**
1496 * Convenience method for updating rows in the database.
1497 *
1498 * @param table the table to update in
1499 * @param values a map from column names to new column values. null is a
1500 * valid value that will be translated to NULL.
1501 * @param whereClause the optional WHERE clause to apply when updating.
1502 * Passing null will update all rows.
1503 * @return the number of rows affected
1504 */
1505 public int update(String table, ContentValues values, String whereClause, String[] whereArgs) {
Vasu Nori8d45e4e2010-02-05 22:35:47 -08001506 return updateWithOnConflict(table, values, whereClause, whereArgs, CONFLICT_NONE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001507 }
Dmitri Plotnikov600bdd82009-09-01 12:12:20 -07001508
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001509 /**
1510 * Convenience method for updating rows in the database.
1511 *
1512 * @param table the table to update in
1513 * @param values a map from column names to new column values. null is a
1514 * valid value that will be translated to NULL.
1515 * @param whereClause the optional WHERE clause to apply when updating.
1516 * Passing null will update all rows.
Vasu Nori8d45e4e2010-02-05 22:35:47 -08001517 * @param conflictAlgorithm for update conflict resolver
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001518 * @return the number of rows affected
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001519 */
Dmitri Plotnikov600bdd82009-09-01 12:12:20 -07001520 public int updateWithOnConflict(String table, ContentValues values,
Vasu Nori6eb7c452010-01-27 14:31:24 -08001521 String whereClause, String[] whereArgs, int conflictAlgorithm) {
Brian Muramatsu46a88512010-11-12 13:53:57 -08001522 if (values == null || values.size() == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001523 throw new IllegalArgumentException("Empty values");
1524 }
1525
Jeff Brown03bd3022012-03-06 13:48:56 -08001526 acquireReference();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001527 try {
Jeff Brown03bd3022012-03-06 13:48:56 -08001528 StringBuilder sql = new StringBuilder(120);
1529 sql.append("UPDATE ");
1530 sql.append(CONFLICT_VALUES[conflictAlgorithm]);
1531 sql.append(table);
1532 sql.append(" SET ");
1533
1534 // move all bind args to one array
1535 int setValuesSize = values.size();
1536 int bindArgsSize = (whereArgs == null) ? setValuesSize : (setValuesSize + whereArgs.length);
1537 Object[] bindArgs = new Object[bindArgsSize];
1538 int i = 0;
1539 for (String colName : values.keySet()) {
1540 sql.append((i > 0) ? "," : "");
1541 sql.append(colName);
1542 bindArgs[i++] = values.get(colName);
1543 sql.append("=?");
1544 }
1545 if (whereArgs != null) {
1546 for (i = setValuesSize; i < bindArgsSize; i++) {
1547 bindArgs[i] = whereArgs[i - setValuesSize];
1548 }
1549 }
1550 if (!TextUtils.isEmpty(whereClause)) {
1551 sql.append(" WHERE ");
1552 sql.append(whereClause);
1553 }
1554
1555 SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs);
1556 try {
1557 return statement.executeUpdateDelete();
1558 } finally {
1559 statement.close();
1560 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001561 } finally {
Jeff Brown03bd3022012-03-06 13:48:56 -08001562 releaseReference();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001563 }
1564 }
1565
1566 /**
Vasu Noriccd95442010-05-28 17:04:16 -07001567 * Execute a single SQL statement that is NOT a SELECT
1568 * or any other SQL statement that returns data.
1569 * <p>
Vasu Norice38b982010-07-22 13:57:13 -07001570 * It has no means to return any data (such as the number of affected rows).
Vasu Noriccd95442010-05-28 17:04:16 -07001571 * Instead, you're encouraged to use {@link #insert(String, String, ContentValues)},
1572 * {@link #update(String, ContentValues, String, String[])}, et al, when possible.
1573 * </p>
Vasu Nori9bf225e2010-07-07 16:38:28 -07001574 * <p>
1575 * When using {@link #enableWriteAheadLogging()}, journal_mode is
1576 * automatically managed by this class. So, do not set journal_mode
1577 * using "PRAGMA journal_mode'<value>" statement if your app is using
1578 * {@link #enableWriteAheadLogging()}
1579 * </p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001580 *
Vasu Noriccd95442010-05-28 17:04:16 -07001581 * @param sql the SQL statement to be executed. Multiple statements separated by semicolons are
1582 * not supported.
Brad Fitzpatrick69ea4e12011-01-05 11:13:40 -08001583 * @throws SQLException if the SQL string is invalid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001584 */
Vasu Norib83cb7c2010-09-14 13:36:01 -07001585 public void execSQL(String sql) throws SQLException {
Vasu Nori16057fa2011-03-18 11:40:37 -07001586 executeSql(sql, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001587 }
1588
1589 /**
Vasu Noriccd95442010-05-28 17:04:16 -07001590 * Execute a single SQL statement that is NOT a SELECT/INSERT/UPDATE/DELETE.
1591 * <p>
1592 * For INSERT statements, use any of the following instead.
1593 * <ul>
1594 * <li>{@link #insert(String, String, ContentValues)}</li>
1595 * <li>{@link #insertOrThrow(String, String, ContentValues)}</li>
1596 * <li>{@link #insertWithOnConflict(String, String, ContentValues, int)}</li>
1597 * </ul>
1598 * <p>
1599 * For UPDATE statements, use any of the following instead.
1600 * <ul>
1601 * <li>{@link #update(String, ContentValues, String, String[])}</li>
1602 * <li>{@link #updateWithOnConflict(String, ContentValues, String, String[], int)}</li>
1603 * </ul>
1604 * <p>
1605 * For DELETE statements, use any of the following instead.
1606 * <ul>
1607 * <li>{@link #delete(String, String, String[])}</li>
1608 * </ul>
1609 * <p>
1610 * For example, the following are good candidates for using this method:
1611 * <ul>
1612 * <li>ALTER TABLE</li>
1613 * <li>CREATE or DROP table / trigger / view / index / virtual table</li>
1614 * <li>REINDEX</li>
1615 * <li>RELEASE</li>
1616 * <li>SAVEPOINT</li>
1617 * <li>PRAGMA that returns no data</li>
1618 * </ul>
1619 * </p>
Vasu Nori9bf225e2010-07-07 16:38:28 -07001620 * <p>
1621 * When using {@link #enableWriteAheadLogging()}, journal_mode is
1622 * automatically managed by this class. So, do not set journal_mode
1623 * using "PRAGMA journal_mode'<value>" statement if your app is using
1624 * {@link #enableWriteAheadLogging()}
1625 * </p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001626 *
Vasu Noriccd95442010-05-28 17:04:16 -07001627 * @param sql the SQL statement to be executed. Multiple statements separated by semicolons are
1628 * not supported.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001629 * @param bindArgs only byte[], String, Long and Double are supported in bindArgs.
Brad Fitzpatrick69ea4e12011-01-05 11:13:40 -08001630 * @throws SQLException if the SQL string is invalid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001631 */
Vasu Norib83cb7c2010-09-14 13:36:01 -07001632 public void execSQL(String sql, Object[] bindArgs) throws SQLException {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001633 if (bindArgs == null) {
1634 throw new IllegalArgumentException("Empty bindArgs");
1635 }
Vasu Norib83cb7c2010-09-14 13:36:01 -07001636 executeSql(sql, bindArgs);
Vasu Norice38b982010-07-22 13:57:13 -07001637 }
1638
Vasu Nori54025902010-09-14 12:14:26 -07001639 private int executeSql(String sql, Object[] bindArgs) throws SQLException {
Jeff Brown03bd3022012-03-06 13:48:56 -08001640 acquireReference();
1641 try {
1642 if (DatabaseUtils.getSqlStatementType(sql) == DatabaseUtils.STATEMENT_ATTACH) {
1643 boolean disableWal = false;
1644 synchronized (mLock) {
1645 if (!mHasAttachedDbsLocked) {
1646 mHasAttachedDbsLocked = true;
1647 disableWal = true;
1648 }
1649 }
1650 if (disableWal) {
1651 disableWriteAheadLogging();
Jeff Browne5360fb2011-10-31 17:48:13 -07001652 }
1653 }
Jeff Browne5360fb2011-10-31 17:48:13 -07001654
Jeff Brown03bd3022012-03-06 13:48:56 -08001655 SQLiteStatement statement = new SQLiteStatement(this, sql, bindArgs);
1656 try {
1657 return statement.executeUpdateDelete();
1658 } finally {
1659 statement.close();
1660 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001661 } finally {
Jeff Brown03bd3022012-03-06 13:48:56 -08001662 releaseReference();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001663 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001664 }
1665
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001666 /**
Jeff Browne5360fb2011-10-31 17:48:13 -07001667 * Returns true if the database is opened as read only.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001668 *
Jeff Browne5360fb2011-10-31 17:48:13 -07001669 * @return True if database is opened as read only.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001670 */
1671 public boolean isReadOnly() {
Jeff Browne5360fb2011-10-31 17:48:13 -07001672 synchronized (mLock) {
1673 return isReadOnlyLocked();
1674 }
1675 }
1676
1677 private boolean isReadOnlyLocked() {
1678 return (mConfigurationLocked.openFlags & OPEN_READ_MASK) == OPEN_READONLY;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001679 }
1680
1681 /**
Jeff Browne5360fb2011-10-31 17:48:13 -07001682 * Returns true if the database is in-memory db.
1683 *
1684 * @return True if the database is in-memory.
1685 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001686 */
Jeff Browne5360fb2011-10-31 17:48:13 -07001687 public boolean isInMemoryDatabase() {
1688 synchronized (mLock) {
1689 return mConfigurationLocked.isInMemoryDb();
1690 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001691 }
1692
Jeff Browne5360fb2011-10-31 17:48:13 -07001693 /**
1694 * Returns true if the database is currently open.
1695 *
1696 * @return True if the database is currently open (has not been closed).
1697 */
1698 public boolean isOpen() {
1699 synchronized (mLock) {
1700 return mConnectionPoolLocked != null;
1701 }
1702 }
1703
1704 /**
1705 * Returns true if the new version code is greater than the current database version.
1706 *
1707 * @param newVersion The new version code.
1708 * @return True if the new version code is greater than the current database version.
1709 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001710 public boolean needUpgrade(int newVersion) {
1711 return newVersion > getVersion();
1712 }
1713
1714 /**
Jeff Browne5360fb2011-10-31 17:48:13 -07001715 * Gets the path to the database file.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001716 *
Jeff Browne5360fb2011-10-31 17:48:13 -07001717 * @return The path to the database file.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001718 */
1719 public final String getPath() {
Jeff Browne5360fb2011-10-31 17:48:13 -07001720 synchronized (mLock) {
1721 return mConfigurationLocked.path;
Christopher Tatead9e8b12011-10-05 17:49:26 -07001722 }
Brad Fitzpatrick722802e2010-03-23 22:22:16 -07001723 }
1724
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001725 /**
1726 * Sets the locale for this database. Does nothing if this database has
Jeff Brown1d9f7422012-03-15 14:32:32 -07001727 * the {@link #NO_LOCALIZED_COLLATORS} flag set or was opened read only.
Jeff Browne5360fb2011-10-31 17:48:13 -07001728 *
1729 * @param locale The new locale.
1730 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001731 * @throws SQLException if the locale could not be set. The most common reason
1732 * for this is that there is no collator available for the locale you requested.
1733 * In this case the database remains unchanged.
1734 */
1735 public void setLocale(Locale locale) {
Jeff Browne5360fb2011-10-31 17:48:13 -07001736 if (locale == null) {
1737 throw new IllegalArgumentException("locale must not be null.");
Jesse Wilsondfe515e2011-02-10 19:06:09 -08001738 }
Vasu Norib729dcc2010-09-14 11:35:49 -07001739
Jeff Browne5360fb2011-10-31 17:48:13 -07001740 synchronized (mLock) {
1741 throwIfNotOpenLocked();
Jeff Browne67ca422012-03-21 17:24:05 -07001742
1743 final Locale oldLocale = mConfigurationLocked.locale;
Jeff Browne5360fb2011-10-31 17:48:13 -07001744 mConfigurationLocked.locale = locale;
Jeff Browne67ca422012-03-21 17:24:05 -07001745 try {
1746 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
1747 } catch (RuntimeException ex) {
1748 mConfigurationLocked.locale = oldLocale;
1749 throw ex;
1750 }
Vasu Norib729dcc2010-09-14 11:35:49 -07001751 }
Vasu Norib729dcc2010-09-14 11:35:49 -07001752 }
1753
Vasu Norie495d1f2010-01-06 16:34:19 -08001754 /**
Vasu Noriccd95442010-05-28 17:04:16 -07001755 * Sets the maximum size of the prepared-statement cache for this database.
Vasu Norie495d1f2010-01-06 16:34:19 -08001756 * (size of the cache = number of compiled-sql-statements stored in the cache).
Vasu Noriccd95442010-05-28 17:04:16 -07001757 *<p>
Vasu Norib729dcc2010-09-14 11:35:49 -07001758 * Maximum cache size can ONLY be increased from its current size (default = 10).
Vasu Noriccd95442010-05-28 17:04:16 -07001759 * If this method is called with smaller size than the current maximum value,
1760 * then IllegalStateException is thrown.
Vasu Norib729dcc2010-09-14 11:35:49 -07001761 *<p>
1762 * This method is thread-safe.
Vasu Norie495d1f2010-01-06 16:34:19 -08001763 *
Vasu Nori90a367262010-04-12 12:49:09 -07001764 * @param cacheSize the size of the cache. can be (0 to {@link #MAX_SQL_CACHE_SIZE})
Jeff Browne5360fb2011-10-31 17:48:13 -07001765 * @throws IllegalStateException if input cacheSize > {@link #MAX_SQL_CACHE_SIZE}.
Vasu Norie495d1f2010-01-06 16:34:19 -08001766 */
Vasu Nori54025902010-09-14 12:14:26 -07001767 public void setMaxSqlCacheSize(int cacheSize) {
Jeff Browne5360fb2011-10-31 17:48:13 -07001768 if (cacheSize > MAX_SQL_CACHE_SIZE || cacheSize < 0) {
1769 throw new IllegalStateException(
1770 "expected value between 0 and " + MAX_SQL_CACHE_SIZE);
Vasu Nori587423a2010-09-27 18:18:34 -07001771 }
Vasu Nori587423a2010-09-27 18:18:34 -07001772
Jeff Browne5360fb2011-10-31 17:48:13 -07001773 synchronized (mLock) {
1774 throwIfNotOpenLocked();
Jeff Browne67ca422012-03-21 17:24:05 -07001775
1776 final int oldMaxSqlCacheSize = mConfigurationLocked.maxSqlCacheSize;
Jeff Browne5360fb2011-10-31 17:48:13 -07001777 mConfigurationLocked.maxSqlCacheSize = cacheSize;
Jeff Browne67ca422012-03-21 17:24:05 -07001778 try {
1779 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
1780 } catch (RuntimeException ex) {
1781 mConfigurationLocked.maxSqlCacheSize = oldMaxSqlCacheSize;
1782 throw ex;
1783 }
Jesse Wilsondfe515e2011-02-10 19:06:09 -08001784 }
1785 }
1786
Vasu Nori6c354da2010-04-26 23:33:39 -07001787 /**
1788 * This method enables parallel execution of queries from multiple threads on the same database.
1789 * It does this by opening multiple handles to the database and using a different
1790 * database handle for each query.
1791 * <p>
1792 * If a transaction is in progress on one connection handle and say, a table is updated in the
1793 * transaction, then query on the same table on another connection handle will block for the
1794 * transaction to complete. But this method enables such queries to execute by having them
1795 * return old version of the data from the table. Most often it is the data that existed in the
1796 * table prior to the above transaction updates on that table.
1797 * <p>
1798 * Maximum number of simultaneous handles used to execute queries in parallel is
1799 * dependent upon the device memory and possibly other properties.
1800 * <p>
1801 * After calling this method, execution of queries in parallel is enabled as long as this
1802 * database handle is open. To disable execution of queries in parallel, database should
1803 * be closed and reopened.
1804 * <p>
1805 * If a query is part of a transaction, then it is executed on the same database handle the
1806 * transaction was begun.
Vasu Nori6c354da2010-04-26 23:33:39 -07001807 * <p>
1808 * If the database has any attached databases, then execution of queries in paralel is NOT
Vasu Noria98cb262010-06-22 13:16:35 -07001809 * possible. In such cases, a message is printed to logcat and false is returned.
1810 * <p>
1811 * This feature is not available for :memory: databases. In such cases,
1812 * a message is printed to logcat and false is returned.
Vasu Nori6c354da2010-04-26 23:33:39 -07001813 * <p>
1814 * A typical way to use this method is the following:
1815 * <pre>
1816 * SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory,
1817 * CREATE_IF_NECESSARY, myDatabaseErrorHandler);
1818 * db.enableWriteAheadLogging();
1819 * </pre>
1820 * <p>
1821 * Writers should use {@link #beginTransactionNonExclusive()} or
1822 * {@link #beginTransactionWithListenerNonExclusive(SQLiteTransactionListener)}
1823 * to start a trsnsaction.
1824 * Non-exclusive mode allows database file to be in readable by threads executing queries.
1825 * </p>
1826 *
Vasu Noria98cb262010-06-22 13:16:35 -07001827 * @return true if write-ahead-logging is set. false otherwise
Jeff Browne67ca422012-03-21 17:24:05 -07001828 *
1829 * @throw IllegalStateException if there are transactions in progress at the
1830 * time this method is called. WAL mode can only be changed when there are no
1831 * transactions in progress.
Vasu Nori6c354da2010-04-26 23:33:39 -07001832 */
Vasu Noriffe06122010-09-27 12:32:57 -07001833 public boolean enableWriteAheadLogging() {
Jeff Browne5360fb2011-10-31 17:48:13 -07001834 synchronized (mLock) {
1835 throwIfNotOpenLocked();
1836
1837 if (mIsWALEnabledLocked) {
Paul Westbrookdae6d372011-02-17 10:59:56 -08001838 return true;
1839 }
Jeff Browne5360fb2011-10-31 17:48:13 -07001840
1841 if (isReadOnlyLocked()) {
1842 // WAL doesn't make sense for readonly-databases.
1843 // TODO: True, but connection pooling does still make sense...
1844 return false;
1845 }
1846
1847 if (mConfigurationLocked.isInMemoryDb()) {
Paul Westbrookdae6d372011-02-17 10:59:56 -08001848 Log.i(TAG, "can't enable WAL for memory databases.");
1849 return false;
1850 }
1851
1852 // make sure this database has NO attached databases because sqlite's write-ahead-logging
1853 // doesn't work for databases with attached databases
Jeff Browne5360fb2011-10-31 17:48:13 -07001854 if (mHasAttachedDbsLocked) {
Paul Westbrookdae6d372011-02-17 10:59:56 -08001855 if (Log.isLoggable(TAG, Log.DEBUG)) {
Jeff Browne5360fb2011-10-31 17:48:13 -07001856 Log.d(TAG, "this database: " + mConfigurationLocked.label
1857 + " has attached databases. can't enable WAL.");
Paul Westbrookdae6d372011-02-17 10:59:56 -08001858 }
1859 return false;
1860 }
Jeff Browne5360fb2011-10-31 17:48:13 -07001861
Jeff Browne67ca422012-03-21 17:24:05 -07001862 final int oldMaxConnectionPoolSize = mConfigurationLocked.maxConnectionPoolSize;
1863 final String oldSyncMode = mConfigurationLocked.syncMode;
1864 final String oldJournalMode = mConfigurationLocked.journalMode;
Jeff Brown5936ff02012-02-29 21:03:20 -08001865 mConfigurationLocked.maxConnectionPoolSize = SQLiteGlobal.getWALConnectionPoolSize();
Jeff Brown8dc3cc22012-03-02 10:33:52 -08001866 mConfigurationLocked.syncMode = SQLiteGlobal.getWALSyncMode();
Jeff Brown5936ff02012-02-29 21:03:20 -08001867 mConfigurationLocked.journalMode = "WAL";
Jeff Browne67ca422012-03-21 17:24:05 -07001868 try {
1869 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
1870 } catch (RuntimeException ex) {
1871 mConfigurationLocked.maxConnectionPoolSize = oldMaxConnectionPoolSize;
1872 mConfigurationLocked.syncMode = oldSyncMode;
1873 mConfigurationLocked.journalMode = oldJournalMode;
1874 throw ex;
1875 }
1876
1877 mIsWALEnabledLocked = true;
Paul Westbrookdae6d372011-02-17 10:59:56 -08001878 }
Jeff Browne5360fb2011-10-31 17:48:13 -07001879 return true;
Vasu Nori6c354da2010-04-26 23:33:39 -07001880 }
1881
Vasu Nori2827d6d2010-07-04 00:26:18 -07001882 /**
Vasu Nori7b04c412010-07-20 10:31:21 -07001883 * This method disables the features enabled by {@link #enableWriteAheadLogging()}.
Jeff Browne67ca422012-03-21 17:24:05 -07001884 *
1885 * @throw IllegalStateException if there are transactions in progress at the
1886 * time this method is called. WAL mode can only be changed when there are no
1887 * transactions in progress.
Vasu Nori2827d6d2010-07-04 00:26:18 -07001888 */
Vasu Nori7b04c412010-07-20 10:31:21 -07001889 public void disableWriteAheadLogging() {
Jeff Browne5360fb2011-10-31 17:48:13 -07001890 synchronized (mLock) {
1891 throwIfNotOpenLocked();
1892
1893 if (!mIsWALEnabledLocked) {
1894 return;
Paul Westbrookdae6d372011-02-17 10:59:56 -08001895 }
Vasu Nori8d111032010-06-22 18:34:21 -07001896
Jeff Browne67ca422012-03-21 17:24:05 -07001897 final int oldMaxConnectionPoolSize = mConfigurationLocked.maxConnectionPoolSize;
1898 final String oldSyncMode = mConfigurationLocked.syncMode;
1899 final String oldJournalMode = mConfigurationLocked.journalMode;
Jeff Browne5360fb2011-10-31 17:48:13 -07001900 mConfigurationLocked.maxConnectionPoolSize = 1;
Jeff Brown8dc3cc22012-03-02 10:33:52 -08001901 mConfigurationLocked.syncMode = SQLiteGlobal.getDefaultSyncMode();
Jeff Brown5936ff02012-02-29 21:03:20 -08001902 mConfigurationLocked.journalMode = SQLiteGlobal.getDefaultJournalMode();
Jeff Browne67ca422012-03-21 17:24:05 -07001903 try {
1904 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
1905 } catch (RuntimeException ex) {
1906 mConfigurationLocked.maxConnectionPoolSize = oldMaxConnectionPoolSize;
1907 mConfigurationLocked.syncMode = oldSyncMode;
1908 mConfigurationLocked.journalMode = oldJournalMode;
1909 throw ex;
1910 }
1911
1912 mIsWALEnabledLocked = false;
Vasu Nori65a88832010-07-16 15:14:08 -07001913 }
Vasu Nori6c354da2010-04-26 23:33:39 -07001914 }
1915
Vasu Norif3cf8a42010-03-23 11:41:44 -07001916 /**
Jeff Browne5360fb2011-10-31 17:48:13 -07001917 * Collect statistics about all open databases in the current process.
1918 * Used by bug report.
Vasu Norif3cf8a42010-03-23 11:41:44 -07001919 */
Jeff Browne5360fb2011-10-31 17:48:13 -07001920 static ArrayList<DbStats> getDbStats() {
Vasu Noric3849202010-03-09 10:47:25 -08001921 ArrayList<DbStats> dbStatsList = new ArrayList<DbStats>();
Jeff Browne5360fb2011-10-31 17:48:13 -07001922 for (SQLiteDatabase db : getActiveDatabases()) {
1923 db.collectDbStats(dbStatsList);
Vasu Nori24675612010-09-27 14:54:19 -07001924 }
Vasu Noric3849202010-03-09 10:47:25 -08001925 return dbStatsList;
1926 }
1927
Jeff Browne5360fb2011-10-31 17:48:13 -07001928 private void collectDbStats(ArrayList<DbStats> dbStatsList) {
1929 synchronized (mLock) {
1930 if (mConnectionPoolLocked != null) {
1931 mConnectionPoolLocked.collectDbStats(dbStatsList);
1932 }
1933 }
1934 }
1935
1936 private static ArrayList<SQLiteDatabase> getActiveDatabases() {
1937 ArrayList<SQLiteDatabase> databases = new ArrayList<SQLiteDatabase>();
1938 synchronized (sActiveDatabases) {
1939 databases.addAll(sActiveDatabases.keySet());
1940 }
1941 return databases;
1942 }
1943
1944 /**
1945 * Dump detailed information about all open databases in the current process.
1946 * Used by bug report.
1947 */
Jeff Browna9be4152012-01-18 15:29:57 -08001948 static void dumpAll(Printer printer, boolean verbose) {
Jeff Browne5360fb2011-10-31 17:48:13 -07001949 for (SQLiteDatabase db : getActiveDatabases()) {
Jeff Browna9be4152012-01-18 15:29:57 -08001950 db.dump(printer, verbose);
Jeff Browne5360fb2011-10-31 17:48:13 -07001951 }
1952 }
1953
Jeff Browna9be4152012-01-18 15:29:57 -08001954 private void dump(Printer printer, boolean verbose) {
Jeff Browne5360fb2011-10-31 17:48:13 -07001955 synchronized (mLock) {
1956 if (mConnectionPoolLocked != null) {
1957 printer.println("");
Jeff Browna9be4152012-01-18 15:29:57 -08001958 mConnectionPoolLocked.dump(printer, verbose);
Jeff Browne5360fb2011-10-31 17:48:13 -07001959 }
1960 }
1961 }
1962
Vasu Noric3849202010-03-09 10:47:25 -08001963 /**
Vasu Noriccd95442010-05-28 17:04:16 -07001964 * Returns list of full pathnames of all attached databases including the main database
1965 * by executing 'pragma database_list' on the database.
1966 *
Vasu Nori062fc7ce2010-03-31 16:13:05 -07001967 * @return ArrayList of pairs of (database name, database file path) or null if the database
1968 * is not open.
Vasu Noric3849202010-03-09 10:47:25 -08001969 */
Vasu Noria017eda2011-01-27 10:52:55 -08001970 public List<Pair<String, String>> getAttachedDbs() {
Vasu Noric3849202010-03-09 10:47:25 -08001971 ArrayList<Pair<String, String>> attachedDbs = new ArrayList<Pair<String, String>>();
Jeff Browne5360fb2011-10-31 17:48:13 -07001972 synchronized (mLock) {
1973 if (mConnectionPoolLocked == null) {
1974 return null; // not open
1975 }
1976
1977 if (!mHasAttachedDbsLocked) {
1978 // No attached databases.
1979 // There is a small window where attached databases exist but this flag is not
1980 // set yet. This can occur when this thread is in a race condition with another
1981 // thread that is executing the SQL statement: "attach database <blah> as <foo>"
1982 // If this thread is NOT ok with such a race condition (and thus possibly not
1983 // receivethe entire list of attached databases), then the caller should ensure
1984 // that no thread is executing any SQL statements while a thread is calling this
1985 // method. Typically, this method is called when 'adb bugreport' is done or the
1986 // caller wants to collect stats on the database and all its attached databases.
1987 attachedDbs.add(new Pair<String, String>("main", mConfigurationLocked.path));
1988 return attachedDbs;
1989 }
Jeff Brown03bd3022012-03-06 13:48:56 -08001990
1991 acquireReference();
Vasu Nori24675612010-09-27 14:54:19 -07001992 }
Jeff Browne5360fb2011-10-31 17:48:13 -07001993
Vasu Nori062fc7ce2010-03-31 16:13:05 -07001994 try {
Jeff Brown03bd3022012-03-06 13:48:56 -08001995 // has attached databases. query sqlite to get the list of attached databases.
1996 Cursor c = null;
1997 try {
1998 c = rawQuery("pragma database_list;", null);
1999 while (c.moveToNext()) {
2000 // sqlite returns a row for each database in the returned list of databases.
2001 // in each row,
2002 // 1st column is the database name such as main, or the database
2003 // name specified on the "ATTACH" command
2004 // 2nd column is the database file path.
2005 attachedDbs.add(new Pair<String, String>(c.getString(1), c.getString(2)));
2006 }
2007 } finally {
2008 if (c != null) {
2009 c.close();
2010 }
Vasu Nori062fc7ce2010-03-31 16:13:05 -07002011 }
Jeff Brown03bd3022012-03-06 13:48:56 -08002012 return attachedDbs;
Vasu Nori062fc7ce2010-03-31 16:13:05 -07002013 } finally {
Jeff Brown03bd3022012-03-06 13:48:56 -08002014 releaseReference();
Vasu Noric3849202010-03-09 10:47:25 -08002015 }
Vasu Noric3849202010-03-09 10:47:25 -08002016 }
2017
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002018 /**
Vasu Noriccd95442010-05-28 17:04:16 -07002019 * Runs 'pragma integrity_check' on the given database (and all the attached databases)
2020 * and returns true if the given database (and all its attached databases) pass integrity_check,
Vasu Nori062fc7ce2010-03-31 16:13:05 -07002021 * false otherwise.
Vasu Noriccd95442010-05-28 17:04:16 -07002022 *<p>
2023 * If the result is false, then this method logs the errors reported by the integrity_check
Vasu Nori062fc7ce2010-03-31 16:13:05 -07002024 * command execution.
Vasu Noriccd95442010-05-28 17:04:16 -07002025 *<p>
2026 * Note that 'pragma integrity_check' on a database can take a long time.
Vasu Nori062fc7ce2010-03-31 16:13:05 -07002027 *
2028 * @return true if the given database (and all its attached databases) pass integrity_check,
Vasu Noriccd95442010-05-28 17:04:16 -07002029 * false otherwise.
Vasu Nori062fc7ce2010-03-31 16:13:05 -07002030 */
2031 public boolean isDatabaseIntegrityOk() {
Jeff Brown03bd3022012-03-06 13:48:56 -08002032 acquireReference();
Vasu Noribfe1dc22010-08-25 16:29:02 -07002033 try {
Jeff Brown03bd3022012-03-06 13:48:56 -08002034 List<Pair<String, String>> attachedDbs = null;
Vasu Nori062fc7ce2010-03-31 16:13:05 -07002035 try {
Jeff Brown03bd3022012-03-06 13:48:56 -08002036 attachedDbs = getAttachedDbs();
2037 if (attachedDbs == null) {
2038 throw new IllegalStateException("databaselist for: " + getPath() + " couldn't " +
2039 "be retrieved. probably because the database is closed");
Vasu Nori062fc7ce2010-03-31 16:13:05 -07002040 }
Jeff Brown03bd3022012-03-06 13:48:56 -08002041 } catch (SQLiteException e) {
2042 // can't get attachedDb list. do integrity check on the main database
2043 attachedDbs = new ArrayList<Pair<String, String>>();
2044 attachedDbs.add(new Pair<String, String>("main", getPath()));
Vasu Nori062fc7ce2010-03-31 16:13:05 -07002045 }
Jeff Brown03bd3022012-03-06 13:48:56 -08002046
2047 for (int i = 0; i < attachedDbs.size(); i++) {
2048 Pair<String, String> p = attachedDbs.get(i);
2049 SQLiteStatement prog = null;
2050 try {
2051 prog = compileStatement("PRAGMA " + p.first + ".integrity_check(1);");
2052 String rslt = prog.simpleQueryForString();
2053 if (!rslt.equalsIgnoreCase("ok")) {
2054 // integrity_checker failed on main or attached databases
2055 Log.e(TAG, "PRAGMA integrity_check on " + p.second + " returned: " + rslt);
2056 return false;
2057 }
2058 } finally {
2059 if (prog != null) prog.close();
2060 }
2061 }
2062 } finally {
2063 releaseReference();
Vasu Nori062fc7ce2010-03-31 16:13:05 -07002064 }
Vasu Noribfe1dc22010-08-25 16:29:02 -07002065 return true;
Vasu Nori062fc7ce2010-03-31 16:13:05 -07002066 }
2067
Jeff Browne5360fb2011-10-31 17:48:13 -07002068 @Override
2069 public String toString() {
2070 return "SQLiteDatabase: " + getPath();
2071 }
2072
Jeff Browne5360fb2011-10-31 17:48:13 -07002073 private void throwIfNotOpenLocked() {
2074 if (mConnectionPoolLocked == null) {
2075 throw new IllegalStateException("The database '" + mConfigurationLocked.label
2076 + "' is not open.");
2077 }
2078 }
Vasu Nori3ef94e22010-02-05 14:49:04 -08002079
2080 /**
Jeff Browne5360fb2011-10-31 17:48:13 -07002081 * Used to allow returning sub-classes of {@link Cursor} when calling query.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002082 */
Jeff Browne5360fb2011-10-31 17:48:13 -07002083 public interface CursorFactory {
2084 /**
2085 * See {@link SQLiteCursor#SQLiteCursor(SQLiteCursorDriver, String, SQLiteQuery)}.
2086 */
2087 public Cursor newCursor(SQLiteDatabase db,
2088 SQLiteCursorDriver masterQuery, String editTable,
2089 SQLiteQuery query);
2090 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002091
2092 /**
Jeff Browne5360fb2011-10-31 17:48:13 -07002093 * A callback interface for a custom sqlite3 function.
2094 * This can be used to create a function that can be called from
2095 * sqlite3 database triggers.
2096 * @hide
Vasu Noric3849202010-03-09 10:47:25 -08002097 */
Jeff Browne5360fb2011-10-31 17:48:13 -07002098 public interface CustomFunction {
2099 public void callback(String[] args);
2100 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002101}