Home | History | Annotate | Download | only in content
      1 /*
      2  * Copyright (C) 2010 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.internal.content;
     18 
     19 import android.content.ContentValues;
     20 import android.database.Cursor;
     21 import android.database.sqlite.SQLiteDatabase;
     22 import android.text.TextUtils;
     23 
     24 import java.util.ArrayList;
     25 
     26 /**
     27  * Helper for building selection clauses for {@link SQLiteDatabase}. Each
     28  * appended clause is combined using {@code AND}. This class is <em>not</em>
     29  * thread safe.
     30  *
     31  * @hide
     32  */
     33 public class SelectionBuilder {
     34     private StringBuilder mSelection = new StringBuilder();
     35     private ArrayList<String> mSelectionArgs = new ArrayList<String>();
     36 
     37     /**
     38      * Reset any internal state, allowing this builder to be recycled.
     39      */
     40     public SelectionBuilder reset() {
     41         mSelection.setLength(0);
     42         mSelectionArgs.clear();
     43         return this;
     44     }
     45 
     46     /**
     47      * Append the given selection clause to the internal state. Each clause is
     48      * surrounded with parenthesis and combined using {@code AND}.
     49      */
     50     public SelectionBuilder append(String selection, Object... selectionArgs) {
     51         if (TextUtils.isEmpty(selection)) {
     52             if (selectionArgs != null && selectionArgs.length > 0) {
     53                 throw new IllegalArgumentException(
     54                         "Valid selection required when including arguments");
     55             }
     56 
     57             // Shortcut when clause is empty
     58             return this;
     59         }
     60 
     61         if (mSelection.length() > 0) {
     62             mSelection.append(" AND ");
     63         }
     64 
     65         mSelection.append("(").append(selection).append(")");
     66         if (selectionArgs != null) {
     67             for (Object arg : selectionArgs) {
     68                 // TODO: switch to storing direct Object instances once
     69                 // http://b/2464440 is fixed
     70                 mSelectionArgs.add(String.valueOf(arg));
     71             }
     72         }
     73 
     74         return this;
     75     }
     76 
     77     /**
     78      * Return selection string for current internal state.
     79      *
     80      * @see #getSelectionArgs()
     81      */
     82     public String getSelection() {
     83         return mSelection.toString();
     84     }
     85 
     86     /**
     87      * Return selection arguments for current internal state.
     88      *
     89      * @see #getSelection()
     90      */
     91     public String[] getSelectionArgs() {
     92         return mSelectionArgs.toArray(new String[mSelectionArgs.size()]);
     93     }
     94 
     95     /**
     96      * Execute query using the current internal state as {@code WHERE} clause.
     97      * Missing arguments as treated as {@code null}.
     98      */
     99     public Cursor query(SQLiteDatabase db, String table, String[] columns, String orderBy) {
    100         return query(db, table, columns, null, null, orderBy, null);
    101     }
    102 
    103     /**
    104      * Execute query using the current internal state as {@code WHERE} clause.
    105      */
    106     public Cursor query(SQLiteDatabase db, String table, String[] columns, String groupBy,
    107             String having, String orderBy, String limit) {
    108         return db.query(table, columns, getSelection(), getSelectionArgs(), groupBy, having,
    109                 orderBy, limit);
    110     }
    111 
    112     /**
    113      * Execute update using the current internal state as {@code WHERE} clause.
    114      */
    115     public int update(SQLiteDatabase db, String table, ContentValues values) {
    116         return db.update(table, values, getSelection(), getSelectionArgs());
    117     }
    118 
    119     /**
    120      * Execute delete using the current internal state as {@code WHERE} clause.
    121      */
    122     public int delete(SQLiteDatabase db, String table) {
    123         return db.delete(table, getSelection(), getSelectionArgs());
    124     }
    125 }
    126