1 /* 2 * Copyright (C) 2011 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 package com.android.providers.contacts.util; 17 18 import android.content.ContentValues; 19 import android.database.DatabaseUtils; 20 import android.text.TextUtils; 21 22 import java.util.Map; 23 import java.util.Set; 24 25 /** 26 * Static methods for helping us build database query selection strings. 27 */ 28 public class DbQueryUtils { 29 // Static class with helper methods, so private constructor. DbQueryUtils()30 private DbQueryUtils() { 31 } 32 33 /** Returns a WHERE clause asserting equality of a field to a value. */ getEqualityClause(String field, String value)34 public static String getEqualityClause(String field, String value) { 35 return getClauseWithOperator(field, "=", value); 36 } 37 38 /** Returns a WHERE clause asserting equality of a field to a value. */ getEqualityClause(String field, long value)39 public static String getEqualityClause(String field, long value) { 40 return getClauseWithOperator(field, "=", value); 41 } 42 43 /** Returns a WHERE clause asserting in-equality of a field to a value. */ getInequalityClause(String field, long value)44 public static String getInequalityClause(String field, long value) { 45 return getClauseWithOperator(field, "!=", value); 46 } 47 getClauseWithOperator(String field, String operator, String value)48 private static String getClauseWithOperator(String field, String operator, String value) { 49 StringBuilder clause = new StringBuilder(); 50 clause.append("("); 51 clause.append(field); 52 clause.append(" ").append(operator).append(" "); 53 DatabaseUtils.appendEscapedSQLString(clause, value); 54 clause.append(")"); 55 return clause.toString(); 56 } 57 getClauseWithOperator(String field, String operator, long value)58 private static String getClauseWithOperator(String field, String operator, long value) { 59 StringBuilder clause = new StringBuilder(); 60 clause.append("("); 61 clause.append(field); 62 clause.append(" ").append(operator).append(" "); 63 clause.append(value); 64 clause.append(")"); 65 return clause.toString(); 66 } 67 68 /** Concatenates any number of clauses using "AND". */ concatenateClauses(String... clauses)69 public static String concatenateClauses(String... clauses) { 70 StringBuilder builder = new StringBuilder(); 71 for (String clause : clauses) { 72 if (!TextUtils.isEmpty(clause)) { 73 if (builder.length() > 0) { 74 builder.append(" AND "); 75 } 76 builder.append("("); 77 builder.append(clause); 78 builder.append(")"); 79 } 80 } 81 return builder.toString(); 82 } 83 84 /** 85 * Checks if the given ContentValues contains values within the projection 86 * map. 87 * 88 * @throws IllegalArgumentException if any value in values is not found in 89 * the projection map. 90 */ checkForSupportedColumns(Map<String, String> projectionMap, ContentValues values)91 public static void checkForSupportedColumns(Map<String, String> projectionMap, 92 ContentValues values) { 93 checkForSupportedColumns(projectionMap.keySet(), values, "Is invalid."); 94 } 95 96 /** 97 * @see #checkForSupportedColumns(Map, ContentValues) 98 */ checkForSupportedColumns(Set<String> allowedColumns, ContentValues values, String msgSuffix)99 public static void checkForSupportedColumns(Set<String> allowedColumns, ContentValues values, 100 String msgSuffix) { 101 for (String requestedColumn : values.keySet()) { 102 if (!allowedColumns.contains(requestedColumn)) { 103 throw new IllegalArgumentException("Column '" + requestedColumn + "'. " + 104 msgSuffix); 105 } 106 } 107 } 108 109 /** 110 * Escape values to be used in LIKE sqlite clause. 111 * 112 * The LIKE clause has two special characters: '%' and '_'. If either of these 113 * characters need to be matched literally, then they must be escaped like so: 114 * 115 * WHERE value LIKE 'android\_%' ESCAPE '\' 116 * 117 * The ESCAPE clause is required and no default exists as the escape character in this context. 118 * Since the escape character needs to be defined as part of the sql string, it must be 119 * provided to this method so the escape characters match. 120 * 121 * @param sb The StringBuilder to append the escaped value to. 122 * @param value The value to be escaped. 123 * @param escapeChar The escape character to be defined in the sql ESCAPE clause. 124 */ escapeLikeValue(StringBuilder sb, String value, char escapeChar)125 public static void escapeLikeValue(StringBuilder sb, String value, char escapeChar) { 126 for (int i = 0; i < value.length(); i++) { 127 char ch = value.charAt(i); 128 if (ch == '%' || ch == '_' || ch == escapeChar) { 129 sb.append(escapeChar); 130 } 131 sb.append(ch); 132 } 133 } 134 135 } 136