1 /* 2 * Copyright (C) 2013 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 com.android.providers.contacts.database; 18 19 import android.annotation.Nullable; 20 import android.database.Cursor; 21 import android.database.DatabaseUtils; 22 import android.util.Log; 23 24 import com.android.providers.contacts.util.NeededForTesting; 25 26 /** 27 * Static methods for database operations. 28 */ 29 public class MoreDatabaseUtils { 30 31 /** 32 * Builds a CREATE INDEX ddl statement for a given table and field. 33 * 34 * @param table The table name. 35 * @param field The field to index. 36 * @return The create index sql statement. 37 */ buildCreateIndexSql(String table, String field)38 public static String buildCreateIndexSql(String table, String field) { 39 return "CREATE INDEX " + buildIndexName(table, field) + " ON " + table 40 + "(" + field + ")"; 41 } 42 43 /** 44 * Builds a DROP INDEX ddl statement for a given table and field. 45 * 46 * @param table The table name that was originally used to create the index. 47 * @param field The field that was originally used to create the index. 48 * @return The drop index sql statement. 49 */ 50 @NeededForTesting buildDropIndexSql(String table, String field)51 public static String buildDropIndexSql(String table, String field) { 52 return "DROP INDEX IF EXISTS " + buildIndexName(table, field); 53 } 54 55 /** 56 * The index is created with a name using the following convention: 57 * <p> 58 * [table name]_[field name]_index 59 */ buildIndexName(String table, String field)60 public static String buildIndexName(String table, String field) { 61 return table + "_" + field + "_index"; 62 } 63 64 /** 65 * Build a bind arg where clause. 66 * <p> 67 * e.g. Calling this method with value of 4 results in: 68 * <p> 69 * "?,?,?,?" 70 * 71 * @param numArgs The number of arguments. 72 * @return A string that can be used for bind args in a sql where clause. 73 */ 74 @NeededForTesting buildBindArgString(int numArgs)75 public static String buildBindArgString(int numArgs) { 76 final StringBuilder sb = new StringBuilder(); 77 String delimiter = ""; 78 for (int i = 0; i < numArgs; i++) { 79 sb.append(delimiter).append("?"); 80 delimiter = ","; 81 } 82 return sb.toString(); 83 } 84 85 /** Debug utility that dumps a cursor on logcat. */ dumpCursor(String logTag, String name, Cursor c)86 public static final void dumpCursor(String logTag, String name, Cursor c) { 87 Log.d(logTag, "Dumping cursor " + name + " containing " + c.getCount() + " rows"); 88 89 // Dump the column names. 90 final StringBuilder sb = new StringBuilder(); 91 for (int i = 0; i < c.getColumnCount(); i++) { 92 if (sb.length() > 0) sb.append(" "); 93 sb.append(c.getColumnName(i)); 94 } 95 Log.d(logTag, sb.toString()); 96 97 // Dump the values. 98 c.moveToPosition(-1); 99 while (c.moveToNext()) { 100 sb.setLength(0); 101 sb.append("row#"); 102 sb.append(c.getPosition()); 103 104 for (int i = 0; i < c.getColumnCount(); i++) { 105 sb.append(" "); 106 107 String s = c.getString(i); 108 sb.append(s == null ? "{null}" : s.replaceAll("\\s", "{space}")); 109 } 110 Log.d(logTag, sb.toString()); 111 } 112 } 113 114 /** 115 * Same as {@link DatabaseUtils#sqlEscapeString(String)} but handles a null argument by 116 * returning the string "NULL". 117 * 118 * @return the SQL-escaped string or "NULL" if the argument is null. 119 */ 120 @Nullable sqlEscapeNullableString(@ullable String s)121 public static String sqlEscapeNullableString(@Nullable String s) { 122 return s == null 123 ? "NULL" 124 : DatabaseUtils.sqlEscapeString(s); 125 } 126 127 /** 128 * Same as {@link DatabaseUtils#appendEscapedSQLString(StringBuilder, String)} but handles a 129 * null argument by appending the literal string "NULL". 130 */ 131 @Nullable appendEscapedSQLStringOrLiteralNull(StringBuilder sb, @Nullable String s)132 public static void appendEscapedSQLStringOrLiteralNull(StringBuilder sb, @Nullable String s) { 133 if (s == null) { 134 sb.append("NULL"); 135 } else { 136 DatabaseUtils.appendEscapedSQLString(sb, s); 137 } 138 } 139 } 140