19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.database.sqlite;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Noriimport java.util.ArrayList;
20c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori
2189101cd9d9b5c1a6ff1ed85eba0613ca4c4802e2Jeff Brownimport android.os.Build;
2289101cd9d9b5c1a6ff1ed85eba0613ca4c4802e2Jeff Brownimport android.os.SystemProperties;
23c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintanaimport android.util.Log;
246754ba24f12a54b97b3ca1c5d29fc23c15980abeJeff Brownimport android.util.Printer;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Provides debugging info about all SQLite databases running in the current process.
284dd4ab4cc322e82401f380aeb877daa4a20d7069Vasu Nori *
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide}
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic final class SQLiteDebug {
32254fba8960b018a29c5fe422b8a0fd9eeedbf3e4Jeff Brown    private static native void nativeGetPagerStats(PagerStats stats);
33254fba8960b018a29c5fe422b8a0fd9eeedbf3e4Jeff Brown
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
35e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     * Controls the printing of informational SQL log messages.
36638eff7ee10ea16b5eabc56411a6609355cd8243Jeff Brown     *
37638eff7ee10ea16b5eabc56411a6609355cd8243Jeff Brown     * Enable using "adb shell setprop log.tag.SQLiteLog VERBOSE".
38e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown     */
39e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    public static final boolean DEBUG_SQL_LOG =
40e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown            Log.isLoggable("SQLiteLog", Log.VERBOSE);
41e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
42e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    /**
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Controls the printing of SQL statements as they are executed.
44638eff7ee10ea16b5eabc56411a6609355cd8243Jeff Brown     *
45638eff7ee10ea16b5eabc56411a6609355cd8243Jeff Brown     * Enable using "adb shell setprop log.tag.SQLiteStatements VERBOSE".
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
47c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana    public static final boolean DEBUG_SQL_STATEMENTS =
48c4516a7b62de525e3d6d5e76851bdfaf12c11f05Fred Quintana            Log.isLoggable("SQLiteStatements", Log.VERBOSE);
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
513ef94e25b4c896ecaa85aa2c12b8863ecdf98df0Vasu Nori     * Controls the printing of wall-clock time taken to execute SQL statements
523ef94e25b4c896ecaa85aa2c12b8863ecdf98df0Vasu Nori     * as they are executed.
53638eff7ee10ea16b5eabc56411a6609355cd8243Jeff Brown     *
54638eff7ee10ea16b5eabc56411a6609355cd8243Jeff Brown     * Enable using "adb shell setprop log.tag.SQLiteTime VERBOSE".
555a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori     */
563ef94e25b4c896ecaa85aa2c12b8863ecdf98df0Vasu Nori    public static final boolean DEBUG_SQL_TIME =
573ef94e25b4c896ecaa85aa2c12b8863ecdf98df0Vasu Nori            Log.isLoggable("SQLiteTime", Log.VERBOSE);
585a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori
595a03f36ef845f73eb4473193dbb0f93dd12a51afVasu Nori    /**
6089101cd9d9b5c1a6ff1ed85eba0613ca4c4802e2Jeff Brown     * True to enable database performance testing instrumentation.
6189101cd9d9b5c1a6ff1ed85eba0613ca4c4802e2Jeff Brown     * @hide
6289101cd9d9b5c1a6ff1ed85eba0613ca4c4802e2Jeff Brown     */
6389101cd9d9b5c1a6ff1ed85eba0613ca4c4802e2Jeff Brown    public static final boolean DEBUG_LOG_SLOW_QUERIES = Build.IS_DEBUGGABLE;
6489101cd9d9b5c1a6ff1ed85eba0613ca4c4802e2Jeff Brown
65baefdfad6e77e772deb6474380dd85ac776293e8Jeff Brown    private SQLiteDebug() {
66baefdfad6e77e772deb6474380dd85ac776293e8Jeff Brown    }
67baefdfad6e77e772deb6474380dd85ac776293e8Jeff Brown
6889101cd9d9b5c1a6ff1ed85eba0613ca4c4802e2Jeff Brown    /**
6989101cd9d9b5c1a6ff1ed85eba0613ca4c4802e2Jeff Brown     * Determines whether a query should be logged.
7089101cd9d9b5c1a6ff1ed85eba0613ca4c4802e2Jeff Brown     *
7189101cd9d9b5c1a6ff1ed85eba0613ca4c4802e2Jeff Brown     * Reads the "db.log.slow_query_threshold" system property, which can be changed
7289101cd9d9b5c1a6ff1ed85eba0613ca4c4802e2Jeff Brown     * by the user at any time.  If the value is zero, then all queries will
73638eff7ee10ea16b5eabc56411a6609355cd8243Jeff Brown     * be considered slow.  If the value does not exist or is negative, then no queries will
7489101cd9d9b5c1a6ff1ed85eba0613ca4c4802e2Jeff Brown     * be considered slow.
7589101cd9d9b5c1a6ff1ed85eba0613ca4c4802e2Jeff Brown     *
7689101cd9d9b5c1a6ff1ed85eba0613ca4c4802e2Jeff Brown     * This value can be changed dynamically while the system is running.
77638eff7ee10ea16b5eabc56411a6609355cd8243Jeff Brown     * For example, "adb shell setprop db.log.slow_query_threshold 200" will
78638eff7ee10ea16b5eabc56411a6609355cd8243Jeff Brown     * log all queries that take 200ms or longer to run.
7989101cd9d9b5c1a6ff1ed85eba0613ca4c4802e2Jeff Brown     * @hide
8089101cd9d9b5c1a6ff1ed85eba0613ca4c4802e2Jeff Brown     */
8189101cd9d9b5c1a6ff1ed85eba0613ca4c4802e2Jeff Brown    public static final boolean shouldLogSlowQuery(long elapsedTimeMillis) {
8289101cd9d9b5c1a6ff1ed85eba0613ca4c4802e2Jeff Brown        int slowQueryMillis = SystemProperties.getInt("db.log.slow_query_threshold", -1);
83638eff7ee10ea16b5eabc56411a6609355cd8243Jeff Brown        return slowQueryMillis >= 0 && elapsedTimeMillis >= slowQueryMillis;
8489101cd9d9b5c1a6ff1ed85eba0613ca4c4802e2Jeff Brown    }
8589101cd9d9b5c1a6ff1ed85eba0613ca4c4802e2Jeff Brown
8689101cd9d9b5c1a6ff1ed85eba0613ca4c4802e2Jeff Brown    /**
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Contains statistics about the active pagers in the current process.
884dd4ab4cc322e82401f380aeb877daa4a20d7069Vasu Nori     *
89254fba8960b018a29c5fe422b8a0fd9eeedbf3e4Jeff Brown     * @see #nativeGetPagerStats(PagerStats)
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static class PagerStats {
92c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori        /** the current amount of memory checked out by sqlite using sqlite3_malloc().
93c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori         * documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html
94c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori         */
95c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori        public int memoryUsed;
96c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori
97c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori        /** the number of bytes of page cache allocation which could not be sattisfied by the
98c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori         * SQLITE_CONFIG_PAGECACHE buffer and where forced to overflow to sqlite3_malloc().
99c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori         * The returned value includes allocations that overflowed because they where too large
100c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori         * (they were larger than the "sz" parameter to SQLITE_CONFIG_PAGECACHE) and allocations
101c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori         * that overflowed because no space was left in the page cache.
102c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori         * documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html
103c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori         */
1042a293b61cb0efbf24994d74ed980f58b820bb35aJeff Brown        public int pageCacheOverflow;
105c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori
106c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori        /** records the largest memory allocation request handed to sqlite3.
107c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori         * documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html
108c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori         */
109c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori        public int largestMemAlloc;
110c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori
111c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori        /** a list of {@link DbStats} - one for each main database opened by the applications
112c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori         * running on the android device
113c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori         */
114c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori        public ArrayList<DbStats> dbStats;
115c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori    }
116c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori
117c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori    /**
118c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori     * contains statistics about a database
119c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori     */
120c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori    public static class DbStats {
121c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori        /** name of the database */
12200e40171892c73295b6e7221ed83126731230b98Vasu Nori        public String dbName;
123c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori
124c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori        /** the page size for the database */
12500e40171892c73295b6e7221ed83126731230b98Vasu Nori        public long pageSize;
126c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori
127c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori        /** the database size */
12800e40171892c73295b6e7221ed83126731230b98Vasu Nori        public long dbSize;
129c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori
130c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori        /** documented here http://www.sqlite.org/c3ref/c_dbstatus_lookaside_used.html */
13100e40171892c73295b6e7221ed83126731230b98Vasu Nori        public int lookaside;
132c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori
13390a36726b7553a1e7efd2f4ecbe01d7e1b3e7a67Vasu Nori        /** statement cache stats: hits/misses/cachesize */
13400e40171892c73295b6e7221ed83126731230b98Vasu Nori        public String cache;
13590a36726b7553a1e7efd2f4ecbe01d7e1b3e7a67Vasu Nori
13690a36726b7553a1e7efd2f4ecbe01d7e1b3e7a67Vasu Nori        public DbStats(String dbName, long pageCount, long pageSize, int lookaside,
13700e40171892c73295b6e7221ed83126731230b98Vasu Nori            int hits, int misses, int cachesize) {
138c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori            this.dbName = dbName;
13990a36726b7553a1e7efd2f4ecbe01d7e1b3e7a67Vasu Nori            this.pageSize = pageSize / 1024;
140c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori            dbSize = (pageCount * pageSize) / 1024;
141c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori            this.lookaside = lookaside;
14290a36726b7553a1e7efd2f4ecbe01d7e1b3e7a67Vasu Nori            this.cache = hits + "/" + misses + "/" + cachesize;
143c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori        }
144c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori    }
145c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori
146c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori    /**
147c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori     * return all pager and database stats for the current process.
148c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori     * @return {@link PagerStats}
149c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori     */
150c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori    public static PagerStats getDatabaseInfo() {
151c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori        PagerStats stats = new PagerStats();
152254fba8960b018a29c5fe422b8a0fd9eeedbf3e4Jeff Brown        nativeGetPagerStats(stats);
153c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori        stats.dbStats = SQLiteDatabase.getDbStats();
154c3849200fa60b22ea583ba2a6f902d6a632a5e7eVasu Nori        return stats;
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1586754ba24f12a54b97b3ca1c5d29fc23c15980abeJeff Brown     * Dumps detailed information about all databases used by the process.
1596754ba24f12a54b97b3ca1c5d29fc23c15980abeJeff Brown     * @param printer The printer for dumping database state.
160a9be4154e8dac0de3db5ee42e878beb0639e70e6Jeff Brown     * @param args Command-line arguments supplied to dumpsys dbinfo
1616754ba24f12a54b97b3ca1c5d29fc23c15980abeJeff Brown     */
1626754ba24f12a54b97b3ca1c5d29fc23c15980abeJeff Brown    public static void dump(Printer printer, String[] args) {
163a9be4154e8dac0de3db5ee42e878beb0639e70e6Jeff Brown        boolean verbose = false;
164a9be4154e8dac0de3db5ee42e878beb0639e70e6Jeff Brown        for (String arg : args) {
165a9be4154e8dac0de3db5ee42e878beb0639e70e6Jeff Brown            if (arg.equals("-v")) {
166a9be4154e8dac0de3db5ee42e878beb0639e70e6Jeff Brown                verbose = true;
167a9be4154e8dac0de3db5ee42e878beb0639e70e6Jeff Brown            }
168a9be4154e8dac0de3db5ee42e878beb0639e70e6Jeff Brown        }
169a9be4154e8dac0de3db5ee42e878beb0639e70e6Jeff Brown
170a9be4154e8dac0de3db5ee42e878beb0639e70e6Jeff Brown        SQLiteDatabase.dumpAll(printer, verbose);
1716754ba24f12a54b97b3ca1c5d29fc23c15980abeJeff Brown    }
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
173