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