1fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey/* 2fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * Copyright (C) 2010 The Android Open Source Project 3fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * 4fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 5fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * you may not use this file except in compliance with the License. 6fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * You may obtain a copy of the License at 7fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * 8fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 9fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * 10fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * Unless required by applicable law or agreed to in writing, software 11fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 12fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * See the License for the specific language governing permissions and 14fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * limitations under the License. 15fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey */ 16fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey 17fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkeypackage com.android.internal.content; 18fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey 19fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkeyimport android.content.ContentValues; 20fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkeyimport android.database.Cursor; 21fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkeyimport android.database.sqlite.SQLiteDatabase; 22fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkeyimport android.text.TextUtils; 23fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey 24fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkeyimport java.util.ArrayList; 25fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey 26fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey/** 27fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * Helper for building selection clauses for {@link SQLiteDatabase}. Each 28fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * appended clause is combined using {@code AND}. This class is <em>not</em> 29fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * thread safe. 30fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * 31fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * @hide 32fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey */ 33fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkeypublic class SelectionBuilder { 34fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey private StringBuilder mSelection = new StringBuilder(); 35fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey private ArrayList<String> mSelectionArgs = new ArrayList<String>(); 36fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey 37fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey /** 38fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * Reset any internal state, allowing this builder to be recycled. 39fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey */ 40fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey public SelectionBuilder reset() { 41fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey mSelection.setLength(0); 42fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey mSelectionArgs.clear(); 43fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey return this; 44fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey } 45fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey 46fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey /** 47fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * Append the given selection clause to the internal state. Each clause is 48fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * surrounded with parenthesis and combined using {@code AND}. 49fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey */ 500cd57a44ea43ec146722774a3f7d623eb9c9cbb3Jeff Sharkey public SelectionBuilder append(String selection, Object... selectionArgs) { 51fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey if (TextUtils.isEmpty(selection)) { 52fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey if (selectionArgs != null && selectionArgs.length > 0) { 53fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey throw new IllegalArgumentException( 54fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey "Valid selection required when including arguments"); 55fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey } 56fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey 57fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey // Shortcut when clause is empty 58fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey return this; 59fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey } 60fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey 61fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey if (mSelection.length() > 0) { 62fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey mSelection.append(" AND "); 63fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey } 64fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey 65fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey mSelection.append("(").append(selection).append(")"); 660cd57a44ea43ec146722774a3f7d623eb9c9cbb3Jeff Sharkey if (selectionArgs != null) { 670cd57a44ea43ec146722774a3f7d623eb9c9cbb3Jeff Sharkey for (Object arg : selectionArgs) { 680cd57a44ea43ec146722774a3f7d623eb9c9cbb3Jeff Sharkey // TODO: switch to storing direct Object instances once 690cd57a44ea43ec146722774a3f7d623eb9c9cbb3Jeff Sharkey // http://b/2464440 is fixed 700cd57a44ea43ec146722774a3f7d623eb9c9cbb3Jeff Sharkey mSelectionArgs.add(String.valueOf(arg)); 710cd57a44ea43ec146722774a3f7d623eb9c9cbb3Jeff Sharkey } 72fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey } 73fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey 74fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey return this; 75fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey } 76fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey 77fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey /** 78fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * Return selection string for current internal state. 79fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * 80fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * @see #getSelectionArgs() 81fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey */ 82fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey public String getSelection() { 83fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey return mSelection.toString(); 84fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey } 85fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey 86fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey /** 87fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * Return selection arguments for current internal state. 88fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * 89fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * @see #getSelection() 90fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey */ 91fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey public String[] getSelectionArgs() { 92fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey return mSelectionArgs.toArray(new String[mSelectionArgs.size()]); 93fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey } 94fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey 95fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey /** 96fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * Execute query using the current internal state as {@code WHERE} clause. 97fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * Missing arguments as treated as {@code null}. 98fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey */ 99fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey public Cursor query(SQLiteDatabase db, String table, String[] columns, String orderBy) { 100fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey return query(db, table, columns, null, null, orderBy, null); 101fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey } 102fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey 103fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey /** 104fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * Execute query using the current internal state as {@code WHERE} clause. 105fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey */ 106fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey public Cursor query(SQLiteDatabase db, String table, String[] columns, String groupBy, 107fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey String having, String orderBy, String limit) { 108fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey return db.query(table, columns, getSelection(), getSelectionArgs(), groupBy, having, 109fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey orderBy, limit); 110fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey } 111fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey 112fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey /** 113fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * Execute update using the current internal state as {@code WHERE} clause. 114fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey */ 115fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey public int update(SQLiteDatabase db, String table, ContentValues values) { 116fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey return db.update(table, values, getSelection(), getSelectionArgs()); 117fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey } 118fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey 119fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey /** 120fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey * Execute delete using the current internal state as {@code WHERE} clause. 121fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey */ 122fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey public int delete(SQLiteDatabase db, String table) { 123fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey return db.delete(table, getSelection(), getSelectionArgs()); 124fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey } 125fe62d04c30e7b3abe408b56c7744c7f547c57640Jeff Sharkey} 126