/** * Copyright 2016 Alex Yanchenko * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.droidparts.persist.sql.stmt; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashMap; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.util.Pair; import org.droidparts.model.Entity; import org.droidparts.util.L; import static org.droidparts.inner.PersistUtils.getRowCount; import static org.droidparts.util.Strings.join; public class Select<EntityType extends Entity> extends Statement<EntityType> implements AbstractSelect<EntityType> { private String[] columns = null; private boolean distinct = false; private String[] groupBy = null; private String having = null; private int offset = 0; private int limit = 0; private final LinkedHashMap<String, Boolean> orderBy = new LinkedHashMap<String, Boolean>(); public Select(SQLiteDatabase db, String tableName) { super(db, tableName); } @Override public Select<EntityType> whereId(long... oneOrMore) { return (Select<EntityType>) super.whereId(oneOrMore); } @Override public Select<EntityType> where(String columnName, Is operator, Object... columnValue) { return (Select<EntityType>) super.where(columnName, operator, columnValue); } @Override public Select<EntityType> where(Where where) { return (Select<EntityType>) super.where(where); } @Override public Select<EntityType> where(String selection, Object... selectionArgs) { return (Select<EntityType>) super.where(selection, selectionArgs); } public Select<EntityType> columns(String... columns) { this.columns = columns; return this; } public Select<EntityType> distinct() { this.distinct = true; return this; } public Select<EntityType> groupBy(String... columns) { this.groupBy = columns; return this; } public Select<EntityType> having(String having) { this.having = having; return this; } public Select<EntityType> offset(int offset) { this.offset = offset; return this; } public Select<EntityType> limit(int limit) { this.limit = limit; return this; } public Select<EntityType> orderBy(String column, boolean ascending) { orderBy.put(column, ascending); return this; } @Override public Cursor execute() { buildArgs(); L.d(describe("SELECT")); return db.query(distinct, tableName, columns, selection.first, selection.second, groupByStr, having, orderByStr, limitStr); } @Override public int count() { buildArgs(); L.d(describe("COUNT")); return getRowCount(db, distinct, tableName, columns, selection.first, selection.second, groupByStr, having, orderByStr, limitStr); } private Pair<String, String[]> selection; private String groupByStr; private String orderByStr; private String limitStr; private void buildArgs() { selection = getSelection(); groupByStr = null; if (groupBy != null && groupBy.length > 0) { groupByStr = join(groupBy, ", "); } orderByStr = null; if (!orderBy.isEmpty()) { ArrayList<String> list = new ArrayList<String>(); for (String key : orderBy.keySet()) { list.add(key + (orderBy.get(key) ? ASC : DESC)); } orderByStr = join(list, ", "); } limitStr = null; if (offset > 0) { limitStr = offset + DDL.SEPARATOR; } if (limit > 0) { if (limitStr == null) { limitStr = String.valueOf(limit); } else { limitStr += limit; } } else if (limitStr != null) { limitStr += Long.MAX_VALUE; } } private String describe(String prefix) { return prefix + super.toString() + ", columns: '" + Arrays.toString(columns) + "', orderBy: '" + orderByStr + "', groupBy: '" + groupByStr + "', having: '" + having + "', distinct: '" + distinct + "', limit: '" + limitStr + "'."; } @Override public String toString() { buildArgs(); return describe("SELECT"); } }