Home | History | Annotate | Download | only in util
      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.HashMap;
     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.
     30     private DbQueryUtils() {
     31     }
     32 
     33     /** Returns a WHERE clause asserting equality of a field to a 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. */
     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. */
     44     public static String getInequalityClause(String field, long value) {
     45         return getClauseWithOperator(field, "!=", value);
     46     }
     47 
     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 
     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". */
     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      */
     91     public static void checkForSupportedColumns(HashMap<String, String> projectionMap,
     92             ContentValues values) {
     93         checkForSupportedColumns(projectionMap.keySet(), values, "Is invalid.");
     94     }
     95 
     96     /**
     97      * @see #checkForSupportedColumns(HashMap, ContentValues)
     98      */
     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      */
    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 == '_') {
    129                 sb.append(escapeChar);
    130             }
    131             sb.append(ch);
    132         }
    133     }
    134 
    135 }
    136