Home | History | Annotate | Download | only in sqlite
      1 /*
      2  * Copyright (C) 2007 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 
     17 package android.database.sqlite;
     18 
     19 import java.util.ArrayList;
     20 
     21 import android.os.Build;
     22 import android.os.SystemProperties;
     23 import android.util.Log;
     24 import android.util.Printer;
     25 
     26 /**
     27  * Provides debugging info about all SQLite databases running in the current process.
     28  *
     29  * {@hide}
     30  */
     31 public final class SQLiteDebug {
     32     private static native void nativeGetPagerStats(PagerStats stats);
     33 
     34     /**
     35      * Controls the printing of informational SQL log messages.
     36      *
     37      * Enable using "adb shell setprop log.tag.SQLiteLog VERBOSE".
     38      */
     39     public static final boolean DEBUG_SQL_LOG =
     40             Log.isLoggable("SQLiteLog", Log.VERBOSE);
     41 
     42     /**
     43      * Controls the printing of SQL statements as they are executed.
     44      *
     45      * Enable using "adb shell setprop log.tag.SQLiteStatements VERBOSE".
     46      */
     47     public static final boolean DEBUG_SQL_STATEMENTS =
     48             Log.isLoggable("SQLiteStatements", Log.VERBOSE);
     49 
     50     /**
     51      * Controls the printing of wall-clock time taken to execute SQL statements
     52      * as they are executed.
     53      *
     54      * Enable using "adb shell setprop log.tag.SQLiteTime VERBOSE".
     55      */
     56     public static final boolean DEBUG_SQL_TIME =
     57             Log.isLoggable("SQLiteTime", Log.VERBOSE);
     58 
     59     /**
     60      * True to enable database performance testing instrumentation.
     61      * @hide
     62      */
     63     public static final boolean DEBUG_LOG_SLOW_QUERIES = Build.IS_DEBUGGABLE;
     64 
     65     private SQLiteDebug() {
     66     }
     67 
     68     /**
     69      * Determines whether a query should be logged.
     70      *
     71      * Reads the "db.log.slow_query_threshold" system property, which can be changed
     72      * by the user at any time.  If the value is zero, then all queries will
     73      * be considered slow.  If the value does not exist or is negative, then no queries will
     74      * be considered slow.
     75      *
     76      * This value can be changed dynamically while the system is running.
     77      * For example, "adb shell setprop db.log.slow_query_threshold 200" will
     78      * log all queries that take 200ms or longer to run.
     79      * @hide
     80      */
     81     public static final boolean shouldLogSlowQuery(long elapsedTimeMillis) {
     82         int slowQueryMillis = SystemProperties.getInt("db.log.slow_query_threshold", -1);
     83         return slowQueryMillis >= 0 && elapsedTimeMillis >= slowQueryMillis;
     84     }
     85 
     86     /**
     87      * Contains statistics about the active pagers in the current process.
     88      *
     89      * @see #nativeGetPagerStats(PagerStats)
     90      */
     91     public static class PagerStats {
     92         /** the current amount of memory checked out by sqlite using sqlite3_malloc().
     93          * documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html
     94          */
     95         public int memoryUsed;
     96 
     97         /** the number of bytes of page cache allocation which could not be sattisfied by the
     98          * SQLITE_CONFIG_PAGECACHE buffer and where forced to overflow to sqlite3_malloc().
     99          * The returned value includes allocations that overflowed because they where too large
    100          * (they were larger than the "sz" parameter to SQLITE_CONFIG_PAGECACHE) and allocations
    101          * that overflowed because no space was left in the page cache.
    102          * documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html
    103          */
    104         public int pageCacheOverflow;
    105 
    106         /** records the largest memory allocation request handed to sqlite3.
    107          * documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html
    108          */
    109         public int largestMemAlloc;
    110 
    111         /** a list of {@link DbStats} - one for each main database opened by the applications
    112          * running on the android device
    113          */
    114         public ArrayList<DbStats> dbStats;
    115     }
    116 
    117     /**
    118      * contains statistics about a database
    119      */
    120     public static class DbStats {
    121         /** name of the database */
    122         public String dbName;
    123 
    124         /** the page size for the database */
    125         public long pageSize;
    126 
    127         /** the database size */
    128         public long dbSize;
    129 
    130         /** documented here http://www.sqlite.org/c3ref/c_dbstatus_lookaside_used.html */
    131         public int lookaside;
    132 
    133         /** statement cache stats: hits/misses/cachesize */
    134         public String cache;
    135 
    136         public DbStats(String dbName, long pageCount, long pageSize, int lookaside,
    137             int hits, int misses, int cachesize) {
    138             this.dbName = dbName;
    139             this.pageSize = pageSize / 1024;
    140             dbSize = (pageCount * pageSize) / 1024;
    141             this.lookaside = lookaside;
    142             this.cache = hits + "/" + misses + "/" + cachesize;
    143         }
    144     }
    145 
    146     /**
    147      * return all pager and database stats for the current process.
    148      * @return {@link PagerStats}
    149      */
    150     public static PagerStats getDatabaseInfo() {
    151         PagerStats stats = new PagerStats();
    152         nativeGetPagerStats(stats);
    153         stats.dbStats = SQLiteDatabase.getDbStats();
    154         return stats;
    155     }
    156 
    157     /**
    158      * Dumps detailed information about all databases used by the process.
    159      * @param printer The printer for dumping database state.
    160      * @param args Command-line arguments supplied to dumpsys dbinfo
    161      */
    162     public static void dump(Printer printer, String[] args) {
    163         boolean verbose = false;
    164         for (String arg : args) {
    165             if (arg.equals("-v")) {
    166                 verbose = true;
    167             }
    168         }
    169 
    170         SQLiteDatabase.dumpAll(printer, verbose);
    171     }
    172 }
    173