blob: bf32ea722d800539f30c6e998d46875c9e7beac6 [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();
837 mConfigurationLocked.customFunctions.add(wrapper);
838 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
Mike Lockwood9d9c1be2010-07-13 19:27:52 -0400839 }
840 }
841
Mike Lockwood9d9c1be2010-07-13 19:27:52 -0400842 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800843 * Gets the database version.
844 *
845 * @return the database version
846 */
847 public int getVersion() {
Vasu Noriccd95442010-05-28 17:04:16 -0700848 return ((Long) DatabaseUtils.longForQuery(this, "PRAGMA user_version;", null)).intValue();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800849 }
850
851 /**
852 * Sets the database version.
853 *
854 * @param version the new database version
855 */
856 public void setVersion(int version) {
857 execSQL("PRAGMA user_version = " + version);
858 }
859
860 /**
861 * Returns the maximum size the database may grow to.
862 *
863 * @return the new maximum database size
864 */
865 public long getMaximumSize() {
Vasu Noriccd95442010-05-28 17:04:16 -0700866 long pageCount = DatabaseUtils.longForQuery(this, "PRAGMA max_page_count;", null);
867 return pageCount * getPageSize();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800868 }
869
870 /**
871 * Sets the maximum size the database will grow to. The maximum size cannot
872 * be set below the current size.
873 *
874 * @param numBytes the maximum database size, in bytes
875 * @return the new maximum database size
876 */
877 public long setMaximumSize(long numBytes) {
Vasu Noriccd95442010-05-28 17:04:16 -0700878 long pageSize = getPageSize();
879 long numPages = numBytes / pageSize;
880 // If numBytes isn't a multiple of pageSize, bump up a page
881 if ((numBytes % pageSize) != 0) {
882 numPages++;
Vasu Norif3cf8a42010-03-23 11:41:44 -0700883 }
Vasu Noriccd95442010-05-28 17:04:16 -0700884 long newPageCount = DatabaseUtils.longForQuery(this, "PRAGMA max_page_count = " + numPages,
885 null);
886 return newPageCount * pageSize;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800887 }
888
889 /**
890 * Returns the current database page size, in bytes.
891 *
892 * @return the database page size, in bytes
893 */
894 public long getPageSize() {
Vasu Noriccd95442010-05-28 17:04:16 -0700895 return DatabaseUtils.longForQuery(this, "PRAGMA page_size;", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800896 }
897
898 /**
899 * Sets the database page size. The page size must be a power of two. This
900 * method does not work if any data has been written to the database file,
901 * and must be called right after the database has been created.
902 *
903 * @param numBytes the database page size, in bytes
904 */
905 public void setPageSize(long numBytes) {
906 execSQL("PRAGMA page_size = " + numBytes);
907 }
908
909 /**
910 * Mark this table as syncable. When an update occurs in this table the
911 * _sync_dirty field will be set to ensure proper syncing operation.
912 *
913 * @param table the table to mark as syncable
914 * @param deletedTable The deleted table that corresponds to the
915 * syncable table
Vasu Nori95675132010-07-21 16:24:40 -0700916 * @deprecated This method no longer serves any useful purpose and has been deprecated.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800917 */
Vasu Nori95675132010-07-21 16:24:40 -0700918 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800919 public void markTableSyncable(String table, String deletedTable) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800920 }
921
922 /**
923 * Mark this table as syncable, with the _sync_dirty residing in another
924 * table. When an update occurs in this table the _sync_dirty field of the
925 * row in updateTable with the _id in foreignKey will be set to
926 * ensure proper syncing operation.
927 *
928 * @param table an update on this table will trigger a sync time removal
929 * @param foreignKey this is the column in table whose value is an _id in
930 * updateTable
931 * @param updateTable this is the table that will have its _sync_dirty
Vasu Nori95675132010-07-21 16:24:40 -0700932 * @deprecated This method no longer serves any useful purpose and has been deprecated.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800933 */
Vasu Nori95675132010-07-21 16:24:40 -0700934 @Deprecated
935 public void markTableSyncable(String table, String foreignKey, String updateTable) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800936 }
937
938 /**
939 * Finds the name of the first table, which is editable.
940 *
941 * @param tables a list of tables
942 * @return the first table listed
943 */
944 public static String findEditTable(String tables) {
945 if (!TextUtils.isEmpty(tables)) {
946 // find the first word terminated by either a space or a comma
947 int spacepos = tables.indexOf(' ');
948 int commapos = tables.indexOf(',');
949
950 if (spacepos > 0 && (spacepos < commapos || commapos < 0)) {
951 return tables.substring(0, spacepos);
952 } else if (commapos > 0 && (commapos < spacepos || spacepos < 0) ) {
953 return tables.substring(0, commapos);
954 }
955 return tables;
956 } else {
957 throw new IllegalStateException("Invalid tables");
958 }
959 }
960
961 /**
962 * Compiles an SQL statement into a reusable pre-compiled statement object.
963 * The parameters are identical to {@link #execSQL(String)}. You may put ?s in the
964 * statement and fill in those values with {@link SQLiteProgram#bindString}
965 * and {@link SQLiteProgram#bindLong} each time you want to run the
966 * statement. Statements may not return result sets larger than 1x1.
Vasu Nori2827d6d2010-07-04 00:26:18 -0700967 *<p>
968 * No two threads should be using the same {@link SQLiteStatement} at the same time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800969 *
970 * @param sql The raw SQL statement, may contain ? for unknown values to be
971 * bound later.
Jeff Hamiltonf3ca9a52010-05-12 15:04:33 -0700972 * @return A pre-compiled {@link SQLiteStatement} object. Note that
973 * {@link SQLiteStatement}s are not synchronized, see the documentation for more details.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800974 */
975 public SQLiteStatement compileStatement(String sql) throws SQLException {
Jeff Brown03bd3022012-03-06 13:48:56 -0800976 acquireReference();
977 try {
978 return new SQLiteStatement(this, sql, null);
979 } finally {
980 releaseReference();
981 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800982 }
983
984 /**
985 * Query the given URL, returning a {@link Cursor} over the result set.
986 *
987 * @param distinct true if you want each row to be unique, false otherwise.
988 * @param table The table name to compile the query against.
989 * @param columns A list of which columns to return. Passing null will
990 * return all columns, which is discouraged to prevent reading
991 * data from storage that isn't going to be used.
992 * @param selection A filter declaring which rows to return, formatted as an
993 * SQL WHERE clause (excluding the WHERE itself). Passing null
994 * will return all rows for the given table.
995 * @param selectionArgs You may include ?s in selection, which will be
996 * replaced by the values from selectionArgs, in order that they
997 * appear in the selection. The values will be bound as Strings.
998 * @param groupBy A filter declaring how to group rows, formatted as an SQL
999 * GROUP BY clause (excluding the GROUP BY itself). Passing null
1000 * will cause the rows to not be grouped.
1001 * @param having A filter declare which row groups to include in the cursor,
1002 * if row grouping is being used, formatted as an SQL HAVING
1003 * clause (excluding the HAVING itself). Passing null will cause
1004 * all row groups to be included, and is required when row
1005 * grouping is not being used.
1006 * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
1007 * (excluding the ORDER BY itself). Passing null will use the
1008 * default sort order, which may be unordered.
1009 * @param limit Limits the number of rows returned by the query,
1010 * formatted as LIMIT clause. Passing null denotes no LIMIT clause.
Jeff Hamiltonf3ca9a52010-05-12 15:04:33 -07001011 * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1012 * {@link Cursor}s are not synchronized, see the documentation for more details.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001013 * @see Cursor
1014 */
1015 public Cursor query(boolean distinct, String table, String[] columns,
1016 String selection, String[] selectionArgs, String groupBy,
1017 String having, String orderBy, String limit) {
1018 return queryWithFactory(null, distinct, table, columns, selection, selectionArgs,
Jeff Brown75ea64f2012-01-25 19:37:13 -08001019 groupBy, having, orderBy, limit, null);
1020 }
1021
1022 /**
1023 * Query the given URL, returning a {@link Cursor} over the result set.
1024 *
1025 * @param distinct true if you want each row to be unique, false otherwise.
1026 * @param table The table name to compile the query against.
1027 * @param columns A list of which columns to return. Passing null will
1028 * return all columns, which is discouraged to prevent reading
1029 * data from storage that isn't going to be used.
1030 * @param selection A filter declaring which rows to return, formatted as an
1031 * SQL WHERE clause (excluding the WHERE itself). Passing null
1032 * will return all rows for the given table.
1033 * @param selectionArgs You may include ?s in selection, which will be
1034 * replaced by the values from selectionArgs, in order that they
1035 * appear in the selection. The values will be bound as Strings.
1036 * @param groupBy A filter declaring how to group rows, formatted as an SQL
1037 * GROUP BY clause (excluding the GROUP BY itself). Passing null
1038 * will cause the rows to not be grouped.
1039 * @param having A filter declare which row groups to include in the cursor,
1040 * if row grouping is being used, formatted as an SQL HAVING
1041 * clause (excluding the HAVING itself). Passing null will cause
1042 * all row groups to be included, and is required when row
1043 * grouping is not being used.
1044 * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
1045 * (excluding the ORDER BY itself). Passing null will use the
1046 * default sort order, which may be unordered.
1047 * @param limit Limits the number of rows returned by the query,
1048 * formatted as LIMIT clause. Passing null denotes no LIMIT clause.
Jeff Brown4c1241d2012-02-02 17:05:00 -08001049 * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
Jeff Brown75ea64f2012-01-25 19:37:13 -08001050 * If the operation is canceled, then {@link OperationCanceledException} will be thrown
1051 * when the query is executed.
1052 * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1053 * {@link Cursor}s are not synchronized, see the documentation for more details.
1054 * @see Cursor
1055 */
1056 public Cursor query(boolean distinct, String table, String[] columns,
1057 String selection, String[] selectionArgs, String groupBy,
Jeff Brown4c1241d2012-02-02 17:05:00 -08001058 String having, String orderBy, String limit, CancellationSignal cancellationSignal) {
Jeff Brown75ea64f2012-01-25 19:37:13 -08001059 return queryWithFactory(null, distinct, table, columns, selection, selectionArgs,
Jeff Brown4c1241d2012-02-02 17:05:00 -08001060 groupBy, having, orderBy, limit, cancellationSignal);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001061 }
1062
1063 /**
1064 * Query the given URL, returning a {@link Cursor} over the result set.
1065 *
1066 * @param cursorFactory the cursor factory to use, or null for the default factory
1067 * @param distinct true if you want each row to be unique, false otherwise.
1068 * @param table The table name to compile the query against.
1069 * @param columns A list of which columns to return. Passing null will
1070 * return all columns, which is discouraged to prevent reading
1071 * data from storage that isn't going to be used.
1072 * @param selection A filter declaring which rows to return, formatted as an
1073 * SQL WHERE clause (excluding the WHERE itself). Passing null
1074 * will return all rows for the given table.
1075 * @param selectionArgs You may include ?s in selection, which will be
1076 * replaced by the values from selectionArgs, in order that they
1077 * appear in the selection. The values will be bound as Strings.
1078 * @param groupBy A filter declaring how to group rows, formatted as an SQL
1079 * GROUP BY clause (excluding the GROUP BY itself). Passing null
1080 * will cause the rows to not be grouped.
1081 * @param having A filter declare which row groups to include in the cursor,
1082 * if row grouping is being used, formatted as an SQL HAVING
1083 * clause (excluding the HAVING itself). Passing null will cause
1084 * all row groups to be included, and is required when row
1085 * grouping is not being used.
1086 * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
1087 * (excluding the ORDER BY itself). Passing null will use the
1088 * default sort order, which may be unordered.
1089 * @param limit Limits the number of rows returned by the query,
1090 * formatted as LIMIT clause. Passing null denotes no LIMIT clause.
Jeff Hamiltonf3ca9a52010-05-12 15:04:33 -07001091 * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1092 * {@link Cursor}s are not synchronized, see the documentation for more details.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001093 * @see Cursor
1094 */
1095 public Cursor queryWithFactory(CursorFactory cursorFactory,
1096 boolean distinct, String table, String[] columns,
1097 String selection, String[] selectionArgs, String groupBy,
1098 String having, String orderBy, String limit) {
Jeff Brown75ea64f2012-01-25 19:37:13 -08001099 return queryWithFactory(cursorFactory, distinct, table, columns, selection,
1100 selectionArgs, groupBy, having, orderBy, limit, null);
1101 }
1102
1103 /**
1104 * Query the given URL, returning a {@link Cursor} over the result set.
1105 *
1106 * @param cursorFactory the cursor factory to use, or null for the default factory
1107 * @param distinct true if you want each row to be unique, false otherwise.
1108 * @param table The table name to compile the query against.
1109 * @param columns A list of which columns to return. Passing null will
1110 * return all columns, which is discouraged to prevent reading
1111 * data from storage that isn't going to be used.
1112 * @param selection A filter declaring which rows to return, formatted as an
1113 * SQL WHERE clause (excluding the WHERE itself). Passing null
1114 * will return all rows for the given table.
1115 * @param selectionArgs You may include ?s in selection, which will be
1116 * replaced by the values from selectionArgs, in order that they
1117 * appear in the selection. The values will be bound as Strings.
1118 * @param groupBy A filter declaring how to group rows, formatted as an SQL
1119 * GROUP BY clause (excluding the GROUP BY itself). Passing null
1120 * will cause the rows to not be grouped.
1121 * @param having A filter declare which row groups to include in the cursor,
1122 * if row grouping is being used, formatted as an SQL HAVING
1123 * clause (excluding the HAVING itself). Passing null will cause
1124 * all row groups to be included, and is required when row
1125 * grouping is not being used.
1126 * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
1127 * (excluding the ORDER BY itself). Passing null will use the
1128 * default sort order, which may be unordered.
1129 * @param limit Limits the number of rows returned by the query,
1130 * formatted as LIMIT clause. Passing null denotes no LIMIT clause.
Jeff Brown4c1241d2012-02-02 17:05:00 -08001131 * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
Jeff Brown75ea64f2012-01-25 19:37:13 -08001132 * If the operation is canceled, then {@link OperationCanceledException} will be thrown
1133 * when the query is executed.
1134 * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1135 * {@link Cursor}s are not synchronized, see the documentation for more details.
1136 * @see Cursor
1137 */
1138 public Cursor queryWithFactory(CursorFactory cursorFactory,
1139 boolean distinct, String table, String[] columns,
1140 String selection, String[] selectionArgs, String groupBy,
Jeff Brown4c1241d2012-02-02 17:05:00 -08001141 String having, String orderBy, String limit, CancellationSignal cancellationSignal) {
Jeff Brown03bd3022012-03-06 13:48:56 -08001142 acquireReference();
1143 try {
1144 String sql = SQLiteQueryBuilder.buildQueryString(
1145 distinct, table, columns, selection, groupBy, having, orderBy, limit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001146
Jeff Brown03bd3022012-03-06 13:48:56 -08001147 return rawQueryWithFactory(cursorFactory, sql, selectionArgs,
1148 findEditTable(table), cancellationSignal);
1149 } finally {
1150 releaseReference();
1151 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001152 }
1153
1154 /**
1155 * Query the given table, returning a {@link Cursor} over the result set.
1156 *
1157 * @param table The table name to compile the query against.
1158 * @param columns A list of which columns to return. Passing null will
1159 * return all columns, which is discouraged to prevent reading
1160 * data from storage that isn't going to be used.
1161 * @param selection A filter declaring which rows to return, formatted as an
1162 * SQL WHERE clause (excluding the WHERE itself). Passing null
1163 * will return all rows for the given table.
1164 * @param selectionArgs You may include ?s in selection, which will be
1165 * replaced by the values from selectionArgs, in order that they
1166 * appear in the selection. The values will be bound as Strings.
1167 * @param groupBy A filter declaring how to group rows, formatted as an SQL
1168 * GROUP BY clause (excluding the GROUP BY itself). Passing null
1169 * will cause the rows to not be grouped.
1170 * @param having A filter declare which row groups to include in the cursor,
1171 * if row grouping is being used, formatted as an SQL HAVING
1172 * clause (excluding the HAVING itself). Passing null will cause
1173 * all row groups to be included, and is required when row
1174 * grouping is not being used.
1175 * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
1176 * (excluding the ORDER BY itself). Passing null will use the
1177 * default sort order, which may be unordered.
Jeff Hamiltonf3ca9a52010-05-12 15:04:33 -07001178 * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1179 * {@link Cursor}s are not synchronized, see the documentation for more details.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001180 * @see Cursor
1181 */
1182 public Cursor query(String table, String[] columns, String selection,
1183 String[] selectionArgs, String groupBy, String having,
1184 String orderBy) {
1185
1186 return query(false, table, columns, selection, selectionArgs, groupBy,
1187 having, orderBy, null /* limit */);
1188 }
1189
1190 /**
1191 * Query the given table, returning a {@link Cursor} over the result set.
1192 *
1193 * @param table The table name to compile the query against.
1194 * @param columns A list of which columns to return. Passing null will
1195 * return all columns, which is discouraged to prevent reading
1196 * data from storage that isn't going to be used.
1197 * @param selection A filter declaring which rows to return, formatted as an
1198 * SQL WHERE clause (excluding the WHERE itself). Passing null
1199 * will return all rows for the given table.
1200 * @param selectionArgs You may include ?s in selection, which will be
1201 * replaced by the values from selectionArgs, in order that they
1202 * appear in the selection. The values will be bound as Strings.
1203 * @param groupBy A filter declaring how to group rows, formatted as an SQL
1204 * GROUP BY clause (excluding the GROUP BY itself). Passing null
1205 * will cause the rows to not be grouped.
1206 * @param having A filter declare which row groups to include in the cursor,
1207 * if row grouping is being used, formatted as an SQL HAVING
1208 * clause (excluding the HAVING itself). Passing null will cause
1209 * all row groups to be included, and is required when row
1210 * grouping is not being used.
1211 * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
1212 * (excluding the ORDER BY itself). Passing null will use the
1213 * default sort order, which may be unordered.
1214 * @param limit Limits the number of rows returned by the query,
1215 * formatted as LIMIT clause. Passing null denotes no LIMIT clause.
Jeff Hamiltonf3ca9a52010-05-12 15:04:33 -07001216 * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1217 * {@link Cursor}s are not synchronized, see the documentation for more details.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001218 * @see Cursor
1219 */
1220 public Cursor query(String table, String[] columns, String selection,
1221 String[] selectionArgs, String groupBy, String having,
1222 String orderBy, String limit) {
1223
1224 return query(false, table, columns, selection, selectionArgs, groupBy,
1225 having, orderBy, limit);
1226 }
1227
1228 /**
1229 * Runs the provided SQL and returns a {@link Cursor} over the result set.
1230 *
1231 * @param sql the SQL query. The SQL string must not be ; terminated
1232 * @param selectionArgs You may include ?s in where clause in the query,
1233 * which will be replaced by the values from selectionArgs. The
1234 * values will be bound as Strings.
Jeff Hamiltonf3ca9a52010-05-12 15:04:33 -07001235 * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1236 * {@link Cursor}s are not synchronized, see the documentation for more details.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001237 */
1238 public Cursor rawQuery(String sql, String[] selectionArgs) {
Jeff Brown75ea64f2012-01-25 19:37:13 -08001239 return rawQueryWithFactory(null, sql, selectionArgs, null, null);
1240 }
1241
1242 /**
1243 * Runs the provided SQL and returns a {@link Cursor} over the result set.
1244 *
1245 * @param sql the SQL query. The SQL string must not be ; terminated
1246 * @param selectionArgs You may include ?s in where clause in the query,
1247 * which will be replaced by the values from selectionArgs. The
1248 * values will be bound as Strings.
Jeff Brown4c1241d2012-02-02 17:05:00 -08001249 * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
Jeff Brown75ea64f2012-01-25 19:37:13 -08001250 * If the operation is canceled, then {@link OperationCanceledException} will be thrown
1251 * when the query is executed.
1252 * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1253 * {@link Cursor}s are not synchronized, see the documentation for more details.
1254 */
1255 public Cursor rawQuery(String sql, String[] selectionArgs,
Jeff Brown4c1241d2012-02-02 17:05:00 -08001256 CancellationSignal cancellationSignal) {
1257 return rawQueryWithFactory(null, sql, selectionArgs, null, cancellationSignal);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001258 }
1259
1260 /**
1261 * Runs the provided SQL and returns a cursor over the result set.
1262 *
1263 * @param cursorFactory the cursor factory to use, or null for the default factory
1264 * @param sql the SQL query. The SQL string must not be ; terminated
1265 * @param selectionArgs You may include ?s in where clause in the query,
1266 * which will be replaced by the values from selectionArgs. The
1267 * values will be bound as Strings.
1268 * @param editTable the name of the first table, which is editable
Jeff Hamiltonf3ca9a52010-05-12 15:04:33 -07001269 * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1270 * {@link Cursor}s are not synchronized, see the documentation for more details.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001271 */
1272 public Cursor rawQueryWithFactory(
1273 CursorFactory cursorFactory, String sql, String[] selectionArgs,
1274 String editTable) {
Jeff Brown75ea64f2012-01-25 19:37:13 -08001275 return rawQueryWithFactory(cursorFactory, sql, selectionArgs, editTable, null);
1276 }
1277
1278 /**
1279 * Runs the provided SQL and returns a cursor over the result set.
1280 *
1281 * @param cursorFactory the cursor factory to use, or null for the default factory
1282 * @param sql the SQL query. The SQL string must not be ; terminated
1283 * @param selectionArgs You may include ?s in where clause in the query,
1284 * which will be replaced by the values from selectionArgs. The
1285 * values will be bound as Strings.
1286 * @param editTable the name of the first table, which is editable
Jeff Brown4c1241d2012-02-02 17:05:00 -08001287 * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
Jeff Brown75ea64f2012-01-25 19:37:13 -08001288 * If the operation is canceled, then {@link OperationCanceledException} will be thrown
1289 * when the query is executed.
1290 * @return A {@link Cursor} object, which is positioned before the first entry. Note that
1291 * {@link Cursor}s are not synchronized, see the documentation for more details.
1292 */
1293 public Cursor rawQueryWithFactory(
1294 CursorFactory cursorFactory, String sql, String[] selectionArgs,
Jeff Brown4c1241d2012-02-02 17:05:00 -08001295 String editTable, CancellationSignal cancellationSignal) {
Jeff Brown03bd3022012-03-06 13:48:56 -08001296 acquireReference();
1297 try {
1298 SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(this, sql, editTable,
1299 cancellationSignal);
1300 return driver.query(cursorFactory != null ? cursorFactory : mCursorFactory,
1301 selectionArgs);
1302 } finally {
1303 releaseReference();
1304 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001305 }
1306
1307 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001308 * Convenience method for inserting a row into the database.
1309 *
1310 * @param table the table to insert the row into
Brad Fitzpatrick69ea4e12011-01-05 11:13:40 -08001311 * @param nullColumnHack optional; may be <code>null</code>.
1312 * SQL doesn't allow inserting a completely empty row without
1313 * naming at least one column name. If your provided <code>values</code> is
1314 * empty, no column names are known and an empty row can't be inserted.
1315 * If not set to null, the <code>nullColumnHack</code> parameter
1316 * provides the name of nullable column name to explicitly insert a NULL into
1317 * in the case where your <code>values</code> is empty.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001318 * @param values this map contains the initial column values for the
1319 * row. The keys should be the column names and the values the
1320 * column values
1321 * @return the row ID of the newly inserted row, or -1 if an error occurred
1322 */
1323 public long insert(String table, String nullColumnHack, ContentValues values) {
1324 try {
Vasu Nori8d45e4e2010-02-05 22:35:47 -08001325 return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001326 } catch (SQLException e) {
1327 Log.e(TAG, "Error inserting " + values, e);
1328 return -1;
1329 }
1330 }
1331
1332 /**
1333 * Convenience method for inserting a row into the database.
1334 *
1335 * @param table the table to insert the row into
Brad Fitzpatrick69ea4e12011-01-05 11:13:40 -08001336 * @param nullColumnHack optional; may be <code>null</code>.
1337 * SQL doesn't allow inserting a completely empty row without
1338 * naming at least one column name. If your provided <code>values</code> is
1339 * empty, no column names are known and an empty row can't be inserted.
1340 * If not set to null, the <code>nullColumnHack</code> parameter
1341 * provides the name of nullable column name to explicitly insert a NULL into
1342 * in the case where your <code>values</code> is empty.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001343 * @param values this map contains the initial column values for the
1344 * row. The keys should be the column names and the values the
1345 * column values
1346 * @throws SQLException
1347 * @return the row ID of the newly inserted row, or -1 if an error occurred
1348 */
1349 public long insertOrThrow(String table, String nullColumnHack, ContentValues values)
1350 throws SQLException {
Vasu Nori8d45e4e2010-02-05 22:35:47 -08001351 return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001352 }
1353
1354 /**
1355 * Convenience method for replacing a row in the database.
1356 *
1357 * @param table the table in which to replace the row
Brad Fitzpatrick69ea4e12011-01-05 11:13:40 -08001358 * @param nullColumnHack optional; may be <code>null</code>.
1359 * SQL doesn't allow inserting a completely empty row without
1360 * naming at least one column name. If your provided <code>initialValues</code> is
1361 * empty, no column names are known and an empty row can't be inserted.
1362 * If not set to null, the <code>nullColumnHack</code> parameter
1363 * provides the name of nullable column name to explicitly insert a NULL into
1364 * in the case where your <code>initialValues</code> is empty.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001365 * @param initialValues this map contains the initial column values for
Brad Fitzpatrick69ea4e12011-01-05 11:13:40 -08001366 * the row.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001367 * @return the row ID of the newly inserted row, or -1 if an error occurred
1368 */
1369 public long replace(String table, String nullColumnHack, ContentValues initialValues) {
1370 try {
Dmitri Plotnikov600bdd82009-09-01 12:12:20 -07001371 return insertWithOnConflict(table, nullColumnHack, initialValues,
Vasu Nori8d45e4e2010-02-05 22:35:47 -08001372 CONFLICT_REPLACE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001373 } catch (SQLException e) {
1374 Log.e(TAG, "Error inserting " + initialValues, e);
1375 return -1;
1376 }
1377 }
1378
1379 /**
1380 * Convenience method for replacing a row in the database.
1381 *
1382 * @param table the table in which to replace the row
Brad Fitzpatrick69ea4e12011-01-05 11:13:40 -08001383 * @param nullColumnHack optional; may be <code>null</code>.
1384 * SQL doesn't allow inserting a completely empty row without
1385 * naming at least one column name. If your provided <code>initialValues</code> is
1386 * empty, no column names are known and an empty row can't be inserted.
1387 * If not set to null, the <code>nullColumnHack</code> parameter
1388 * provides the name of nullable column name to explicitly insert a NULL into
1389 * in the case where your <code>initialValues</code> is empty.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001390 * @param initialValues this map contains the initial column values for
1391 * the row. The key
1392 * @throws SQLException
1393 * @return the row ID of the newly inserted row, or -1 if an error occurred
1394 */
1395 public long replaceOrThrow(String table, String nullColumnHack,
1396 ContentValues initialValues) throws SQLException {
Dmitri Plotnikov600bdd82009-09-01 12:12:20 -07001397 return insertWithOnConflict(table, nullColumnHack, initialValues,
Vasu Nori8d45e4e2010-02-05 22:35:47 -08001398 CONFLICT_REPLACE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001399 }
1400
1401 /**
1402 * General method for inserting a row into the database.
1403 *
1404 * @param table the table to insert the row into
Brad Fitzpatrick69ea4e12011-01-05 11:13:40 -08001405 * @param nullColumnHack optional; may be <code>null</code>.
1406 * SQL doesn't allow inserting a completely empty row without
1407 * naming at least one column name. If your provided <code>initialValues</code> is
1408 * empty, no column names are known and an empty row can't be inserted.
1409 * If not set to null, the <code>nullColumnHack</code> parameter
1410 * provides the name of nullable column name to explicitly insert a NULL into
1411 * in the case where your <code>initialValues</code> is empty.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001412 * @param initialValues this map contains the initial column values for the
1413 * row. The keys should be the column names and the values the
1414 * column values
Vasu Nori8d45e4e2010-02-05 22:35:47 -08001415 * @param conflictAlgorithm for insert conflict resolver
Vasu Nori6eb7c452010-01-27 14:31:24 -08001416 * @return the row ID of the newly inserted row
1417 * OR the primary key of the existing row if the input param 'conflictAlgorithm' =
Vasu Nori8d45e4e2010-02-05 22:35:47 -08001418 * {@link #CONFLICT_IGNORE}
Vasu Nori6eb7c452010-01-27 14:31:24 -08001419 * OR -1 if any error
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001420 */
1421 public long insertWithOnConflict(String table, String nullColumnHack,
Vasu Nori6eb7c452010-01-27 14:31:24 -08001422 ContentValues initialValues, int conflictAlgorithm) {
Jeff Brown03bd3022012-03-06 13:48:56 -08001423 acquireReference();
1424 try {
1425 StringBuilder sql = new StringBuilder();
1426 sql.append("INSERT");
1427 sql.append(CONFLICT_VALUES[conflictAlgorithm]);
1428 sql.append(" INTO ");
1429 sql.append(table);
1430 sql.append('(');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001431
Jeff Brown03bd3022012-03-06 13:48:56 -08001432 Object[] bindArgs = null;
1433 int size = (initialValues != null && initialValues.size() > 0)
1434 ? initialValues.size() : 0;
1435 if (size > 0) {
1436 bindArgs = new Object[size];
1437 int i = 0;
1438 for (String colName : initialValues.keySet()) {
1439 sql.append((i > 0) ? "," : "");
1440 sql.append(colName);
1441 bindArgs[i++] = initialValues.get(colName);
1442 }
1443 sql.append(')');
1444 sql.append(" VALUES (");
1445 for (i = 0; i < size; i++) {
1446 sql.append((i > 0) ? ",?" : "?");
1447 }
1448 } else {
1449 sql.append(nullColumnHack + ") VALUES (NULL");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001450 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001451 sql.append(')');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001452
Jeff Brown03bd3022012-03-06 13:48:56 -08001453 SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs);
1454 try {
1455 return statement.executeInsert();
1456 } finally {
1457 statement.close();
1458 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001459 } finally {
Jeff Brown03bd3022012-03-06 13:48:56 -08001460 releaseReference();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001461 }
1462 }
1463
1464 /**
1465 * Convenience method for deleting rows in the database.
1466 *
1467 * @param table the table to delete from
1468 * @param whereClause the optional WHERE clause to apply when deleting.
1469 * Passing null will delete all rows.
1470 * @return the number of rows affected if a whereClause is passed in, 0
1471 * otherwise. To remove all rows and get a count pass "1" as the
1472 * whereClause.
1473 */
1474 public int delete(String table, String whereClause, String[] whereArgs) {
Jeff Brown03bd3022012-03-06 13:48:56 -08001475 acquireReference();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001476 try {
Jeff Brown03bd3022012-03-06 13:48:56 -08001477 SQLiteStatement statement = new SQLiteStatement(this, "DELETE FROM " + table +
1478 (!TextUtils.isEmpty(whereClause) ? " WHERE " + whereClause : ""), whereArgs);
1479 try {
1480 return statement.executeUpdateDelete();
1481 } finally {
1482 statement.close();
1483 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001484 } finally {
Jeff Brown03bd3022012-03-06 13:48:56 -08001485 releaseReference();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001486 }
1487 }
1488
1489 /**
1490 * Convenience method for updating rows in the database.
1491 *
1492 * @param table the table to update in
1493 * @param values a map from column names to new column values. null is a
1494 * valid value that will be translated to NULL.
1495 * @param whereClause the optional WHERE clause to apply when updating.
1496 * Passing null will update all rows.
1497 * @return the number of rows affected
1498 */
1499 public int update(String table, ContentValues values, String whereClause, String[] whereArgs) {
Vasu Nori8d45e4e2010-02-05 22:35:47 -08001500 return updateWithOnConflict(table, values, whereClause, whereArgs, CONFLICT_NONE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001501 }
Dmitri Plotnikov600bdd82009-09-01 12:12:20 -07001502
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001503 /**
1504 * Convenience method for updating rows in the database.
1505 *
1506 * @param table the table to update in
1507 * @param values a map from column names to new column values. null is a
1508 * valid value that will be translated to NULL.
1509 * @param whereClause the optional WHERE clause to apply when updating.
1510 * Passing null will update all rows.
Vasu Nori8d45e4e2010-02-05 22:35:47 -08001511 * @param conflictAlgorithm for update conflict resolver
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001512 * @return the number of rows affected
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001513 */
Dmitri Plotnikov600bdd82009-09-01 12:12:20 -07001514 public int updateWithOnConflict(String table, ContentValues values,
Vasu Nori6eb7c452010-01-27 14:31:24 -08001515 String whereClause, String[] whereArgs, int conflictAlgorithm) {
Brian Muramatsu46a88512010-11-12 13:53:57 -08001516 if (values == null || values.size() == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001517 throw new IllegalArgumentException("Empty values");
1518 }
1519
Jeff Brown03bd3022012-03-06 13:48:56 -08001520 acquireReference();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001521 try {
Jeff Brown03bd3022012-03-06 13:48:56 -08001522 StringBuilder sql = new StringBuilder(120);
1523 sql.append("UPDATE ");
1524 sql.append(CONFLICT_VALUES[conflictAlgorithm]);
1525 sql.append(table);
1526 sql.append(" SET ");
1527
1528 // move all bind args to one array
1529 int setValuesSize = values.size();
1530 int bindArgsSize = (whereArgs == null) ? setValuesSize : (setValuesSize + whereArgs.length);
1531 Object[] bindArgs = new Object[bindArgsSize];
1532 int i = 0;
1533 for (String colName : values.keySet()) {
1534 sql.append((i > 0) ? "," : "");
1535 sql.append(colName);
1536 bindArgs[i++] = values.get(colName);
1537 sql.append("=?");
1538 }
1539 if (whereArgs != null) {
1540 for (i = setValuesSize; i < bindArgsSize; i++) {
1541 bindArgs[i] = whereArgs[i - setValuesSize];
1542 }
1543 }
1544 if (!TextUtils.isEmpty(whereClause)) {
1545 sql.append(" WHERE ");
1546 sql.append(whereClause);
1547 }
1548
1549 SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs);
1550 try {
1551 return statement.executeUpdateDelete();
1552 } finally {
1553 statement.close();
1554 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001555 } finally {
Jeff Brown03bd3022012-03-06 13:48:56 -08001556 releaseReference();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001557 }
1558 }
1559
1560 /**
Vasu Noriccd95442010-05-28 17:04:16 -07001561 * Execute a single SQL statement that is NOT a SELECT
1562 * or any other SQL statement that returns data.
1563 * <p>
Vasu Norice38b982010-07-22 13:57:13 -07001564 * It has no means to return any data (such as the number of affected rows).
Vasu Noriccd95442010-05-28 17:04:16 -07001565 * Instead, you're encouraged to use {@link #insert(String, String, ContentValues)},
1566 * {@link #update(String, ContentValues, String, String[])}, et al, when possible.
1567 * </p>
Vasu Nori9bf225e2010-07-07 16:38:28 -07001568 * <p>
1569 * When using {@link #enableWriteAheadLogging()}, journal_mode is
1570 * automatically managed by this class. So, do not set journal_mode
1571 * using "PRAGMA journal_mode'<value>" statement if your app is using
1572 * {@link #enableWriteAheadLogging()}
1573 * </p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001574 *
Vasu Noriccd95442010-05-28 17:04:16 -07001575 * @param sql the SQL statement to be executed. Multiple statements separated by semicolons are
1576 * not supported.
Brad Fitzpatrick69ea4e12011-01-05 11:13:40 -08001577 * @throws SQLException if the SQL string is invalid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001578 */
Vasu Norib83cb7c2010-09-14 13:36:01 -07001579 public void execSQL(String sql) throws SQLException {
Vasu Nori16057fa2011-03-18 11:40:37 -07001580 executeSql(sql, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001581 }
1582
1583 /**
Vasu Noriccd95442010-05-28 17:04:16 -07001584 * Execute a single SQL statement that is NOT a SELECT/INSERT/UPDATE/DELETE.
1585 * <p>
1586 * For INSERT statements, use any of the following instead.
1587 * <ul>
1588 * <li>{@link #insert(String, String, ContentValues)}</li>
1589 * <li>{@link #insertOrThrow(String, String, ContentValues)}</li>
1590 * <li>{@link #insertWithOnConflict(String, String, ContentValues, int)}</li>
1591 * </ul>
1592 * <p>
1593 * For UPDATE statements, use any of the following instead.
1594 * <ul>
1595 * <li>{@link #update(String, ContentValues, String, String[])}</li>
1596 * <li>{@link #updateWithOnConflict(String, ContentValues, String, String[], int)}</li>
1597 * </ul>
1598 * <p>
1599 * For DELETE statements, use any of the following instead.
1600 * <ul>
1601 * <li>{@link #delete(String, String, String[])}</li>
1602 * </ul>
1603 * <p>
1604 * For example, the following are good candidates for using this method:
1605 * <ul>
1606 * <li>ALTER TABLE</li>
1607 * <li>CREATE or DROP table / trigger / view / index / virtual table</li>
1608 * <li>REINDEX</li>
1609 * <li>RELEASE</li>
1610 * <li>SAVEPOINT</li>
1611 * <li>PRAGMA that returns no data</li>
1612 * </ul>
1613 * </p>
Vasu Nori9bf225e2010-07-07 16:38:28 -07001614 * <p>
1615 * When using {@link #enableWriteAheadLogging()}, journal_mode is
1616 * automatically managed by this class. So, do not set journal_mode
1617 * using "PRAGMA journal_mode'<value>" statement if your app is using
1618 * {@link #enableWriteAheadLogging()}
1619 * </p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001620 *
Vasu Noriccd95442010-05-28 17:04:16 -07001621 * @param sql the SQL statement to be executed. Multiple statements separated by semicolons are
1622 * not supported.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001623 * @param bindArgs only byte[], String, Long and Double are supported in bindArgs.
Brad Fitzpatrick69ea4e12011-01-05 11:13:40 -08001624 * @throws SQLException if the SQL string is invalid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001625 */
Vasu Norib83cb7c2010-09-14 13:36:01 -07001626 public void execSQL(String sql, Object[] bindArgs) throws SQLException {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001627 if (bindArgs == null) {
1628 throw new IllegalArgumentException("Empty bindArgs");
1629 }
Vasu Norib83cb7c2010-09-14 13:36:01 -07001630 executeSql(sql, bindArgs);
Vasu Norice38b982010-07-22 13:57:13 -07001631 }
1632
Vasu Nori54025902010-09-14 12:14:26 -07001633 private int executeSql(String sql, Object[] bindArgs) throws SQLException {
Jeff Brown03bd3022012-03-06 13:48:56 -08001634 acquireReference();
1635 try {
1636 if (DatabaseUtils.getSqlStatementType(sql) == DatabaseUtils.STATEMENT_ATTACH) {
1637 boolean disableWal = false;
1638 synchronized (mLock) {
1639 if (!mHasAttachedDbsLocked) {
1640 mHasAttachedDbsLocked = true;
1641 disableWal = true;
1642 }
1643 }
1644 if (disableWal) {
1645 disableWriteAheadLogging();
Jeff Browne5360fb2011-10-31 17:48:13 -07001646 }
1647 }
Jeff Browne5360fb2011-10-31 17:48:13 -07001648
Jeff Brown03bd3022012-03-06 13:48:56 -08001649 SQLiteStatement statement = new SQLiteStatement(this, sql, bindArgs);
1650 try {
1651 return statement.executeUpdateDelete();
1652 } finally {
1653 statement.close();
1654 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001655 } finally {
Jeff Brown03bd3022012-03-06 13:48:56 -08001656 releaseReference();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001657 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001658 }
1659
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001660 /**
Jeff Browne5360fb2011-10-31 17:48:13 -07001661 * Returns true if the database is opened as read only.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001662 *
Jeff Browne5360fb2011-10-31 17:48:13 -07001663 * @return True if database is opened as read only.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001664 */
1665 public boolean isReadOnly() {
Jeff Browne5360fb2011-10-31 17:48:13 -07001666 synchronized (mLock) {
1667 return isReadOnlyLocked();
1668 }
1669 }
1670
1671 private boolean isReadOnlyLocked() {
1672 return (mConfigurationLocked.openFlags & OPEN_READ_MASK) == OPEN_READONLY;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001673 }
1674
1675 /**
Jeff Browne5360fb2011-10-31 17:48:13 -07001676 * Returns true if the database is in-memory db.
1677 *
1678 * @return True if the database is in-memory.
1679 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001680 */
Jeff Browne5360fb2011-10-31 17:48:13 -07001681 public boolean isInMemoryDatabase() {
1682 synchronized (mLock) {
1683 return mConfigurationLocked.isInMemoryDb();
1684 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001685 }
1686
Jeff Browne5360fb2011-10-31 17:48:13 -07001687 /**
1688 * Returns true if the database is currently open.
1689 *
1690 * @return True if the database is currently open (has not been closed).
1691 */
1692 public boolean isOpen() {
1693 synchronized (mLock) {
1694 return mConnectionPoolLocked != null;
1695 }
1696 }
1697
1698 /**
1699 * Returns true if the new version code is greater than the current database version.
1700 *
1701 * @param newVersion The new version code.
1702 * @return True if the new version code is greater than the current database version.
1703 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001704 public boolean needUpgrade(int newVersion) {
1705 return newVersion > getVersion();
1706 }
1707
1708 /**
Jeff Browne5360fb2011-10-31 17:48:13 -07001709 * Gets the path to the database file.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001710 *
Jeff Browne5360fb2011-10-31 17:48:13 -07001711 * @return The path to the database file.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001712 */
1713 public final String getPath() {
Jeff Browne5360fb2011-10-31 17:48:13 -07001714 synchronized (mLock) {
1715 return mConfigurationLocked.path;
Christopher Tatead9e8b12011-10-05 17:49:26 -07001716 }
Brad Fitzpatrick722802e2010-03-23 22:22:16 -07001717 }
1718
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001719 /**
1720 * Sets the locale for this database. Does nothing if this database has
Jeff Brown1d9f7422012-03-15 14:32:32 -07001721 * the {@link #NO_LOCALIZED_COLLATORS} flag set or was opened read only.
Jeff Browne5360fb2011-10-31 17:48:13 -07001722 *
1723 * @param locale The new locale.
1724 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001725 * @throws SQLException if the locale could not be set. The most common reason
1726 * for this is that there is no collator available for the locale you requested.
1727 * In this case the database remains unchanged.
1728 */
1729 public void setLocale(Locale locale) {
Jeff Browne5360fb2011-10-31 17:48:13 -07001730 if (locale == null) {
1731 throw new IllegalArgumentException("locale must not be null.");
Jesse Wilsondfe515e2011-02-10 19:06:09 -08001732 }
Vasu Norib729dcc2010-09-14 11:35:49 -07001733
Jeff Browne5360fb2011-10-31 17:48:13 -07001734 synchronized (mLock) {
1735 throwIfNotOpenLocked();
1736 mConfigurationLocked.locale = locale;
1737 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
Vasu Norib729dcc2010-09-14 11:35:49 -07001738 }
Vasu Norib729dcc2010-09-14 11:35:49 -07001739 }
1740
Vasu Norie495d1f2010-01-06 16:34:19 -08001741 /**
Vasu Noriccd95442010-05-28 17:04:16 -07001742 * Sets the maximum size of the prepared-statement cache for this database.
Vasu Norie495d1f2010-01-06 16:34:19 -08001743 * (size of the cache = number of compiled-sql-statements stored in the cache).
Vasu Noriccd95442010-05-28 17:04:16 -07001744 *<p>
Vasu Norib729dcc2010-09-14 11:35:49 -07001745 * Maximum cache size can ONLY be increased from its current size (default = 10).
Vasu Noriccd95442010-05-28 17:04:16 -07001746 * If this method is called with smaller size than the current maximum value,
1747 * then IllegalStateException is thrown.
Vasu Norib729dcc2010-09-14 11:35:49 -07001748 *<p>
1749 * This method is thread-safe.
Vasu Norie495d1f2010-01-06 16:34:19 -08001750 *
Vasu Nori90a367262010-04-12 12:49:09 -07001751 * @param cacheSize the size of the cache. can be (0 to {@link #MAX_SQL_CACHE_SIZE})
Jeff Browne5360fb2011-10-31 17:48:13 -07001752 * @throws IllegalStateException if input cacheSize > {@link #MAX_SQL_CACHE_SIZE}.
Vasu Norie495d1f2010-01-06 16:34:19 -08001753 */
Vasu Nori54025902010-09-14 12:14:26 -07001754 public void setMaxSqlCacheSize(int cacheSize) {
Jeff Browne5360fb2011-10-31 17:48:13 -07001755 if (cacheSize > MAX_SQL_CACHE_SIZE || cacheSize < 0) {
1756 throw new IllegalStateException(
1757 "expected value between 0 and " + MAX_SQL_CACHE_SIZE);
Vasu Nori587423a2010-09-27 18:18:34 -07001758 }
Vasu Nori587423a2010-09-27 18:18:34 -07001759
Jeff Browne5360fb2011-10-31 17:48:13 -07001760 synchronized (mLock) {
1761 throwIfNotOpenLocked();
1762 mConfigurationLocked.maxSqlCacheSize = cacheSize;
1763 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
Jesse Wilsondfe515e2011-02-10 19:06:09 -08001764 }
1765 }
1766
Vasu Nori6c354da2010-04-26 23:33:39 -07001767 /**
1768 * This method enables parallel execution of queries from multiple threads on the same database.
1769 * It does this by opening multiple handles to the database and using a different
1770 * database handle for each query.
1771 * <p>
1772 * If a transaction is in progress on one connection handle and say, a table is updated in the
1773 * transaction, then query on the same table on another connection handle will block for the
1774 * transaction to complete. But this method enables such queries to execute by having them
1775 * return old version of the data from the table. Most often it is the data that existed in the
1776 * table prior to the above transaction updates on that table.
1777 * <p>
1778 * Maximum number of simultaneous handles used to execute queries in parallel is
1779 * dependent upon the device memory and possibly other properties.
1780 * <p>
1781 * After calling this method, execution of queries in parallel is enabled as long as this
1782 * database handle is open. To disable execution of queries in parallel, database should
1783 * be closed and reopened.
1784 * <p>
1785 * If a query is part of a transaction, then it is executed on the same database handle the
1786 * transaction was begun.
Vasu Nori6c354da2010-04-26 23:33:39 -07001787 * <p>
1788 * If the database has any attached databases, then execution of queries in paralel is NOT
Vasu Noria98cb262010-06-22 13:16:35 -07001789 * possible. In such cases, a message is printed to logcat and false is returned.
1790 * <p>
1791 * This feature is not available for :memory: databases. In such cases,
1792 * a message is printed to logcat and false is returned.
Vasu Nori6c354da2010-04-26 23:33:39 -07001793 * <p>
1794 * A typical way to use this method is the following:
1795 * <pre>
1796 * SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory,
1797 * CREATE_IF_NECESSARY, myDatabaseErrorHandler);
1798 * db.enableWriteAheadLogging();
1799 * </pre>
1800 * <p>
1801 * Writers should use {@link #beginTransactionNonExclusive()} or
1802 * {@link #beginTransactionWithListenerNonExclusive(SQLiteTransactionListener)}
1803 * to start a trsnsaction.
1804 * Non-exclusive mode allows database file to be in readable by threads executing queries.
1805 * </p>
1806 *
Vasu Noria98cb262010-06-22 13:16:35 -07001807 * @return true if write-ahead-logging is set. false otherwise
Vasu Nori6c354da2010-04-26 23:33:39 -07001808 */
Vasu Noriffe06122010-09-27 12:32:57 -07001809 public boolean enableWriteAheadLogging() {
Jeff Browne5360fb2011-10-31 17:48:13 -07001810 synchronized (mLock) {
1811 throwIfNotOpenLocked();
1812
1813 if (mIsWALEnabledLocked) {
Paul Westbrookdae6d372011-02-17 10:59:56 -08001814 return true;
1815 }
Jeff Browne5360fb2011-10-31 17:48:13 -07001816
1817 if (isReadOnlyLocked()) {
1818 // WAL doesn't make sense for readonly-databases.
1819 // TODO: True, but connection pooling does still make sense...
1820 return false;
1821 }
1822
1823 if (mConfigurationLocked.isInMemoryDb()) {
Paul Westbrookdae6d372011-02-17 10:59:56 -08001824 Log.i(TAG, "can't enable WAL for memory databases.");
1825 return false;
1826 }
1827
1828 // make sure this database has NO attached databases because sqlite's write-ahead-logging
1829 // doesn't work for databases with attached databases
Jeff Browne5360fb2011-10-31 17:48:13 -07001830 if (mHasAttachedDbsLocked) {
Paul Westbrookdae6d372011-02-17 10:59:56 -08001831 if (Log.isLoggable(TAG, Log.DEBUG)) {
Jeff Browne5360fb2011-10-31 17:48:13 -07001832 Log.d(TAG, "this database: " + mConfigurationLocked.label
1833 + " has attached databases. can't enable WAL.");
Paul Westbrookdae6d372011-02-17 10:59:56 -08001834 }
1835 return false;
1836 }
Jeff Browne5360fb2011-10-31 17:48:13 -07001837
1838 mIsWALEnabledLocked = true;
Jeff Brown5936ff02012-02-29 21:03:20 -08001839 mConfigurationLocked.maxConnectionPoolSize = SQLiteGlobal.getWALConnectionPoolSize();
Jeff Brown8dc3cc22012-03-02 10:33:52 -08001840 mConfigurationLocked.syncMode = SQLiteGlobal.getWALSyncMode();
Jeff Brown5936ff02012-02-29 21:03:20 -08001841 mConfigurationLocked.journalMode = "WAL";
Jeff Browne5360fb2011-10-31 17:48:13 -07001842 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
Paul Westbrookdae6d372011-02-17 10:59:56 -08001843 }
Jeff Browne5360fb2011-10-31 17:48:13 -07001844 return true;
Vasu Nori6c354da2010-04-26 23:33:39 -07001845 }
1846
Vasu Nori2827d6d2010-07-04 00:26:18 -07001847 /**
Vasu Nori7b04c412010-07-20 10:31:21 -07001848 * This method disables the features enabled by {@link #enableWriteAheadLogging()}.
1849 * @hide
Vasu Nori2827d6d2010-07-04 00:26:18 -07001850 */
Vasu Nori7b04c412010-07-20 10:31:21 -07001851 public void disableWriteAheadLogging() {
Jeff Browne5360fb2011-10-31 17:48:13 -07001852 synchronized (mLock) {
1853 throwIfNotOpenLocked();
1854
1855 if (!mIsWALEnabledLocked) {
1856 return;
Paul Westbrookdae6d372011-02-17 10:59:56 -08001857 }
Vasu Nori8d111032010-06-22 18:34:21 -07001858
Jeff Browne5360fb2011-10-31 17:48:13 -07001859 mIsWALEnabledLocked = false;
1860 mConfigurationLocked.maxConnectionPoolSize = 1;
Jeff Brown8dc3cc22012-03-02 10:33:52 -08001861 mConfigurationLocked.syncMode = SQLiteGlobal.getDefaultSyncMode();
Jeff Brown5936ff02012-02-29 21:03:20 -08001862 mConfigurationLocked.journalMode = SQLiteGlobal.getDefaultJournalMode();
Jeff Browne5360fb2011-10-31 17:48:13 -07001863 mConnectionPoolLocked.reconfigure(mConfigurationLocked);
Vasu Nori65a88832010-07-16 15:14:08 -07001864 }
Vasu Nori6c354da2010-04-26 23:33:39 -07001865 }
1866
Vasu Norif3cf8a42010-03-23 11:41:44 -07001867 /**
Jeff Browne5360fb2011-10-31 17:48:13 -07001868 * Collect statistics about all open databases in the current process.
1869 * Used by bug report.
Vasu Norif3cf8a42010-03-23 11:41:44 -07001870 */
Jeff Browne5360fb2011-10-31 17:48:13 -07001871 static ArrayList<DbStats> getDbStats() {
Vasu Noric3849202010-03-09 10:47:25 -08001872 ArrayList<DbStats> dbStatsList = new ArrayList<DbStats>();
Jeff Browne5360fb2011-10-31 17:48:13 -07001873 for (SQLiteDatabase db : getActiveDatabases()) {
1874 db.collectDbStats(dbStatsList);
Vasu Nori24675612010-09-27 14:54:19 -07001875 }
Vasu Noric3849202010-03-09 10:47:25 -08001876 return dbStatsList;
1877 }
1878
Jeff Browne5360fb2011-10-31 17:48:13 -07001879 private void collectDbStats(ArrayList<DbStats> dbStatsList) {
1880 synchronized (mLock) {
1881 if (mConnectionPoolLocked != null) {
1882 mConnectionPoolLocked.collectDbStats(dbStatsList);
1883 }
1884 }
1885 }
1886
1887 private static ArrayList<SQLiteDatabase> getActiveDatabases() {
1888 ArrayList<SQLiteDatabase> databases = new ArrayList<SQLiteDatabase>();
1889 synchronized (sActiveDatabases) {
1890 databases.addAll(sActiveDatabases.keySet());
1891 }
1892 return databases;
1893 }
1894
1895 /**
1896 * Dump detailed information about all open databases in the current process.
1897 * Used by bug report.
1898 */
Jeff Browna9be4152012-01-18 15:29:57 -08001899 static void dumpAll(Printer printer, boolean verbose) {
Jeff Browne5360fb2011-10-31 17:48:13 -07001900 for (SQLiteDatabase db : getActiveDatabases()) {
Jeff Browna9be4152012-01-18 15:29:57 -08001901 db.dump(printer, verbose);
Jeff Browne5360fb2011-10-31 17:48:13 -07001902 }
1903 }
1904
Jeff Browna9be4152012-01-18 15:29:57 -08001905 private void dump(Printer printer, boolean verbose) {
Jeff Browne5360fb2011-10-31 17:48:13 -07001906 synchronized (mLock) {
1907 if (mConnectionPoolLocked != null) {
1908 printer.println("");
Jeff Browna9be4152012-01-18 15:29:57 -08001909 mConnectionPoolLocked.dump(printer, verbose);
Jeff Browne5360fb2011-10-31 17:48:13 -07001910 }
1911 }
1912 }
1913
Vasu Noric3849202010-03-09 10:47:25 -08001914 /**
Vasu Noriccd95442010-05-28 17:04:16 -07001915 * Returns list of full pathnames of all attached databases including the main database
1916 * by executing 'pragma database_list' on the database.
1917 *
Vasu Nori062fc7ce2010-03-31 16:13:05 -07001918 * @return ArrayList of pairs of (database name, database file path) or null if the database
1919 * is not open.
Vasu Noric3849202010-03-09 10:47:25 -08001920 */
Vasu Noria017eda2011-01-27 10:52:55 -08001921 public List<Pair<String, String>> getAttachedDbs() {
Vasu Noric3849202010-03-09 10:47:25 -08001922 ArrayList<Pair<String, String>> attachedDbs = new ArrayList<Pair<String, String>>();
Jeff Browne5360fb2011-10-31 17:48:13 -07001923 synchronized (mLock) {
1924 if (mConnectionPoolLocked == null) {
1925 return null; // not open
1926 }
1927
1928 if (!mHasAttachedDbsLocked) {
1929 // No attached databases.
1930 // There is a small window where attached databases exist but this flag is not
1931 // set yet. This can occur when this thread is in a race condition with another
1932 // thread that is executing the SQL statement: "attach database <blah> as <foo>"
1933 // If this thread is NOT ok with such a race condition (and thus possibly not
1934 // receivethe entire list of attached databases), then the caller should ensure
1935 // that no thread is executing any SQL statements while a thread is calling this
1936 // method. Typically, this method is called when 'adb bugreport' is done or the
1937 // caller wants to collect stats on the database and all its attached databases.
1938 attachedDbs.add(new Pair<String, String>("main", mConfigurationLocked.path));
1939 return attachedDbs;
1940 }
Jeff Brown03bd3022012-03-06 13:48:56 -08001941
1942 acquireReference();
Vasu Nori24675612010-09-27 14:54:19 -07001943 }
Jeff Browne5360fb2011-10-31 17:48:13 -07001944
Vasu Nori062fc7ce2010-03-31 16:13:05 -07001945 try {
Jeff Brown03bd3022012-03-06 13:48:56 -08001946 // has attached databases. query sqlite to get the list of attached databases.
1947 Cursor c = null;
1948 try {
1949 c = rawQuery("pragma database_list;", null);
1950 while (c.moveToNext()) {
1951 // sqlite returns a row for each database in the returned list of databases.
1952 // in each row,
1953 // 1st column is the database name such as main, or the database
1954 // name specified on the "ATTACH" command
1955 // 2nd column is the database file path.
1956 attachedDbs.add(new Pair<String, String>(c.getString(1), c.getString(2)));
1957 }
1958 } finally {
1959 if (c != null) {
1960 c.close();
1961 }
Vasu Nori062fc7ce2010-03-31 16:13:05 -07001962 }
Jeff Brown03bd3022012-03-06 13:48:56 -08001963 return attachedDbs;
Vasu Nori062fc7ce2010-03-31 16:13:05 -07001964 } finally {
Jeff Brown03bd3022012-03-06 13:48:56 -08001965 releaseReference();
Vasu Noric3849202010-03-09 10:47:25 -08001966 }
Vasu Noric3849202010-03-09 10:47:25 -08001967 }
1968
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001969 /**
Vasu Noriccd95442010-05-28 17:04:16 -07001970 * Runs 'pragma integrity_check' on the given database (and all the attached databases)
1971 * and returns true if the given database (and all its attached databases) pass integrity_check,
Vasu Nori062fc7ce2010-03-31 16:13:05 -07001972 * false otherwise.
Vasu Noriccd95442010-05-28 17:04:16 -07001973 *<p>
1974 * If the result is false, then this method logs the errors reported by the integrity_check
Vasu Nori062fc7ce2010-03-31 16:13:05 -07001975 * command execution.
Vasu Noriccd95442010-05-28 17:04:16 -07001976 *<p>
1977 * Note that 'pragma integrity_check' on a database can take a long time.
Vasu Nori062fc7ce2010-03-31 16:13:05 -07001978 *
1979 * @return true if the given database (and all its attached databases) pass integrity_check,
Vasu Noriccd95442010-05-28 17:04:16 -07001980 * false otherwise.
Vasu Nori062fc7ce2010-03-31 16:13:05 -07001981 */
1982 public boolean isDatabaseIntegrityOk() {
Jeff Brown03bd3022012-03-06 13:48:56 -08001983 acquireReference();
Vasu Noribfe1dc22010-08-25 16:29:02 -07001984 try {
Jeff Brown03bd3022012-03-06 13:48:56 -08001985 List<Pair<String, String>> attachedDbs = null;
Vasu Nori062fc7ce2010-03-31 16:13:05 -07001986 try {
Jeff Brown03bd3022012-03-06 13:48:56 -08001987 attachedDbs = getAttachedDbs();
1988 if (attachedDbs == null) {
1989 throw new IllegalStateException("databaselist for: " + getPath() + " couldn't " +
1990 "be retrieved. probably because the database is closed");
Vasu Nori062fc7ce2010-03-31 16:13:05 -07001991 }
Jeff Brown03bd3022012-03-06 13:48:56 -08001992 } catch (SQLiteException e) {
1993 // can't get attachedDb list. do integrity check on the main database
1994 attachedDbs = new ArrayList<Pair<String, String>>();
1995 attachedDbs.add(new Pair<String, String>("main", getPath()));
Vasu Nori062fc7ce2010-03-31 16:13:05 -07001996 }
Jeff Brown03bd3022012-03-06 13:48:56 -08001997
1998 for (int i = 0; i < attachedDbs.size(); i++) {
1999 Pair<String, String> p = attachedDbs.get(i);
2000 SQLiteStatement prog = null;
2001 try {
2002 prog = compileStatement("PRAGMA " + p.first + ".integrity_check(1);");
2003 String rslt = prog.simpleQueryForString();
2004 if (!rslt.equalsIgnoreCase("ok")) {
2005 // integrity_checker failed on main or attached databases
2006 Log.e(TAG, "PRAGMA integrity_check on " + p.second + " returned: " + rslt);
2007 return false;
2008 }
2009 } finally {
2010 if (prog != null) prog.close();
2011 }
2012 }
2013 } finally {
2014 releaseReference();
Vasu Nori062fc7ce2010-03-31 16:13:05 -07002015 }
Vasu Noribfe1dc22010-08-25 16:29:02 -07002016 return true;
Vasu Nori062fc7ce2010-03-31 16:13:05 -07002017 }
2018
Jeff Browne5360fb2011-10-31 17:48:13 -07002019 @Override
2020 public String toString() {
2021 return "SQLiteDatabase: " + getPath();
2022 }
2023
Jeff Browne5360fb2011-10-31 17:48:13 -07002024 private void throwIfNotOpenLocked() {
2025 if (mConnectionPoolLocked == null) {
2026 throw new IllegalStateException("The database '" + mConfigurationLocked.label
2027 + "' is not open.");
2028 }
2029 }
Vasu Nori3ef94e22010-02-05 14:49:04 -08002030
2031 /**
Jeff Browne5360fb2011-10-31 17:48:13 -07002032 * Used to allow returning sub-classes of {@link Cursor} when calling query.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002033 */
Jeff Browne5360fb2011-10-31 17:48:13 -07002034 public interface CursorFactory {
2035 /**
2036 * See {@link SQLiteCursor#SQLiteCursor(SQLiteCursorDriver, String, SQLiteQuery)}.
2037 */
2038 public Cursor newCursor(SQLiteDatabase db,
2039 SQLiteCursorDriver masterQuery, String editTable,
2040 SQLiteQuery query);
2041 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002042
2043 /**
Jeff Browne5360fb2011-10-31 17:48:13 -07002044 * A callback interface for a custom sqlite3 function.
2045 * This can be used to create a function that can be called from
2046 * sqlite3 database triggers.
2047 * @hide
Vasu Noric3849202010-03-09 10:47:25 -08002048 */
Jeff Browne5360fb2011-10-31 17:48:13 -07002049 public interface CustomFunction {
2050 public void callback(String[] args);
2051 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002052}