SQLiteDebug.java revision 4dd4ab4cc322e82401f380aeb877daa4a20d7069
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 17package android.database.sqlite; 18 19import android.util.Log; 20 21/** 22 * Provides debugging info about all SQLite databases running in the current process. 23 * 24 * {@hide} 25 */ 26public final class SQLiteDebug { 27 /** 28 * Controls the printing of SQL statements as they are executed. 29 */ 30 public static final boolean DEBUG_SQL_STATEMENTS = 31 Log.isLoggable("SQLiteStatements", Log.VERBOSE); 32 33 /** 34 * Controls the printing of compiled-sql-statement cache stats. 35 */ 36 public static final boolean DEBUG_SQL_CACHE = 37 Log.isLoggable("SQLiteCompiledSql", Log.VERBOSE); 38 39 /** 40 * Controls the capturing and printing of complete sql statement including the bind args and 41 * the database name. 42 */ 43 public static final boolean DEBUG_CAPTURE_SQL = 44 Log.isLoggable("SQLiteCaptureSql", Log.VERBOSE); 45 46 /** 47 * Controls the stack trace reporting of active cursors being 48 * finalized. 49 */ 50 public static final boolean DEBUG_ACTIVE_CURSOR_FINALIZATION = 51 Log.isLoggable("SQLiteCursorClosing", Log.VERBOSE); 52 53 /** 54 * Controls the tracking of time spent holding the database lock. 55 */ 56 public static final boolean DEBUG_LOCK_TIME_TRACKING = 57 Log.isLoggable("SQLiteLockTime", Log.VERBOSE); 58 59 /** 60 * Controls the printing of stack traces when tracking the time spent holding the database lock. 61 */ 62 public static final boolean DEBUG_LOCK_TIME_TRACKING_STACK_TRACE = 63 Log.isLoggable("SQLiteLockStackTrace", Log.VERBOSE); 64 65 /** 66 * Contains statistics about the active pagers in the current process. 67 * 68 * @see #getPagerStats(PagerStats) 69 */ 70 public static class PagerStats { 71 /** The total number of bytes in all pagers in the current process */ 72 public long totalBytes; 73 /** The number of bytes in referenced pages in all pagers in the current process */ 74 public long referencedBytes; 75 /** The number of bytes in all database files opened in the current process */ 76 public long databaseBytes; 77 /** The number of pagers opened in the current process */ 78 public int numPagers; 79 } 80 81 /** 82 * Gathers statistics about all pagers in the current process. 83 */ 84 public static native void getPagerStats(PagerStats stats); 85 86 /** 87 * Returns the size of the SQLite heap. 88 * @return The size of the SQLite heap in bytes. 89 */ 90 public static native long getHeapSize(); 91 92 /** 93 * Returns the amount of allocated memory in the SQLite heap. 94 * @return The allocated size in bytes. 95 */ 96 public static native long getHeapAllocatedSize(); 97 98 /** 99 * Returns the amount of free memory in the SQLite heap. 100 * @return The freed size in bytes. 101 */ 102 public static native long getHeapFreeSize(); 103 104 /** 105 * Determines the number of dirty belonging to the SQLite 106 * heap segments of this process. pages[0] returns the number of 107 * shared pages, pages[1] returns the number of private pages 108 */ 109 public static native void getHeapDirtyPages(int[] pages); 110 111 private static int sNumActiveCursorsFinalized = 0; 112 113 /** 114 * Returns the number of active cursors that have been finalized. This depends on the GC having 115 * run but is still useful for tests. 116 */ 117 public static int getNumActiveCursorsFinalized() { 118 return sNumActiveCursorsFinalized; 119 } 120 121 static synchronized void notifyActiveCursorFinalized() { 122 sNumActiveCursorsFinalized++; 123 } 124 125 /** 126 * returns a message containing the given database name (path) and the string built by 127 * replacing "?" characters in the given sql string with the corresponding 128 * positional values from the given param bindArgs. 129 * 130 * @param path the database name 131 * @param sql sql string with possibly "?" for bindargs 132 * @param bindArgs args for "?"s in the above string 133 * @return the String to be logged 134 */ 135 /* package */ static String captureSql(String path, String sql, Object[] bindArgs) { 136 // how many bindargs in sql 137 sql = sql.trim(); 138 String args[] = sql.split("\\?"); 139 // how many "?"s in the given sql string? 140 int varArgsInSql = (sql.endsWith("?")) ? args.length : args.length - 1; 141 142 // how many bind args do we have in the given input param bindArgs 143 int bindArgsLen = (bindArgs == null) ? 0 : bindArgs.length; 144 if (varArgsInSql < bindArgsLen) { 145 return "too many bindArgs provided. " + 146 "# of bindArgs = " + bindArgsLen + ", # of varargs = " + varArgsInSql + 147 "; sql = " + sql; 148 } 149 150 // if there are no bindArgs, we are done. log the sql as is. 151 if (bindArgsLen == 0 && varArgsInSql == 0) { 152 return logSql(path, sql); 153 } 154 155 StringBuilder buf = new StringBuilder(); 156 157 // take the supplied bindArgs and plug them into sql 158 for (int i = 0; i < bindArgsLen; i++) { 159 buf.append(args[i]); 160 buf.append(bindArgs[i]); 161 } 162 163 // does given sql have more varArgs than the supplied bindArgs 164 // if so, assign nulls to the extra varArgs in sql 165 for (int i = bindArgsLen; i < varArgsInSql; i ++) { 166 buf.append(args[i]); 167 buf.append("null"); 168 } 169 170 // if there are any characters left in the given sql string AFTER the last "?" 171 // log them also. for example, if the given sql = "select * from test where a=? and b=1 172 // then the following code appends " and b=1" string to buf. 173 if (varArgsInSql < args.length) { 174 buf.append(args[varArgsInSql]); 175 } 176 return logSql(path, buf.toString()); 177 } 178 179 private static String logSql(String path, String sql) { 180 return "captured_sql|" + path + "|" + sql + ";"; 181 } 182} 183