/* * Aipo is a groupware program developed by TOWN, Inc. * Copyright (C) 2004-2015 TOWN, Inc. * http://www.aipo.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.aimluck.eip.orm.query; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.apache.cayenne.DataRow; import org.apache.cayenne.access.DataContext; import org.apache.cayenne.exp.Expression; import org.apache.cayenne.map.DbAttribute; import org.apache.cayenne.map.ObjEntity; import com.aimluck.eip.orm.Database; public class SelectQuery<M> extends AbstractQuery<M> { protected CustomSelectQuery delegate; protected CountQuery countQuery; protected int page = 1; public SelectQuery(Class<M> rootClass) { super(rootClass); delegate = new CustomSelectQuery(rootClass); countQuery = new CountQuery(rootClass); dataContext = DataContext.getThreadDataContext(); } public SelectQuery(DataContext dataContext, Class<M> rootClass) { super(dataContext, rootClass); this.rootClass = rootClass; delegate = new CustomSelectQuery(rootClass); countQuery = new CountQuery(rootClass); this.dataContext = dataContext; } public SelectQuery(Class<M> rootClass, Expression qualifier) { super(rootClass); this.rootClass = rootClass; delegate = new CustomSelectQuery(rootClass, qualifier); countQuery = new CountQuery(rootClass); dataContext = DataContext.getThreadDataContext(); } public SelectQuery(DataContext dataContext, Class<M> rootClass, Expression qualifier) { super(dataContext, rootClass); this.rootClass = rootClass; delegate = new CustomSelectQuery(rootClass, qualifier); countQuery = new CountQuery(rootClass); this.dataContext = dataContext; } @Override @SuppressWarnings("unchecked") public List<M> fetchList() { Database.beginTransaction(dataContext); if (delegate.isFetchingDataRows()) { List<DataRow> dataRows = dataContext.performQuery(delegate); List<M> results = new ArrayList<M>(); for (DataRow dataRow : dataRows) { M model = newInstanceFromRowData(dataRow, rootClass); if (model != null) { results.add(model); } } return results; } else { return dataContext.performQuery(delegate); } } public List<DataRow> fetchListAsDataRow() { Database.beginTransaction(dataContext); delegate.setFetchingDataRows(true); @SuppressWarnings("unchecked") List<DataRow> dataRows = dataContext.performQuery(delegate); return dataRows; } public ResultList<M> getResultList() { countQuery.setCustomColumns(getPrimaryKey()); int totalCount = countQuery.count(dataContext, delegate.isDistinct()); int pageSize = delegate.getFetchLimit(); if (pageSize > 0) { int num = ((int) (Math.ceil(totalCount / (double) pageSize))); if ((num > 0) && (num < page)) { page = num; } int offset = pageSize * (page - 1); offset(offset); } else { page = 1; } List<M> fetchList = fetchList(); return new ResultList<M>( fetchList, page, delegate.getPageSize(), totalCount); } public int getCount() { Database.beginTransaction(dataContext); countQuery.setCustomColumns(getPrimaryKey()); return countQuery.count(dataContext, delegate.isDistinct()); } public SelectQuery<M> where(Where where) { delegate.andQualifier(where.exp); countQuery.andQualifier(where.exp); return this; } public SelectQuery<M> where(Where... where) { List<Where> list = Arrays.asList(where); for (Where w : list) { delegate.andQualifier(w.exp); countQuery.andQualifier(w.exp); } return this; } public SelectQuery<M> setQualifier(Expression qualifier) { delegate.setQualifier(qualifier); countQuery.setQualifier(qualifier); return this; } public SelectQuery<M> andQualifier(Expression qualifier) { delegate.andQualifier(qualifier); countQuery.andQualifier(qualifier); return this; } public SelectQuery<M> andQualifier(String qualifier) { delegate.andQualifier(Expression.fromString(qualifier)); countQuery.andQualifier(Expression.fromString(qualifier)); return this; } public SelectQuery<M> orQualifier(Expression qualifier) { delegate.orQualifier(qualifier); countQuery.orQualifier(qualifier); return this; } public SelectQuery<M> orQualifier(String qualifier) { delegate.orQualifier(Expression.fromString(qualifier)); countQuery.orQualifier(Expression.fromString(qualifier)); return this; } public SelectQuery<M> orderAscending(String ordering) { delegate.addOrdering(ordering, true); return this; } public SelectQuery<M> orderDesending(String ordering) { delegate.addOrdering(ordering, false); return this; } public SelectQuery<M> page(int page) { this.page = page; return this; } public SelectQuery<M> limit(int limit) { delegate.setFetchLimit(limit); return this; } public SelectQuery<M> offset(int offset) { delegate.setFetchOffset(offset); return this; } public SelectQuery<M> select(String column) { delegate.addCustomColumn(column); delegate.setFetchingDataRows(true); // delegate.addCustomDbAttribute(column); return this; } public SelectQuery<M> select(String... columns) { delegate.addCustomColumns(columns); delegate.setFetchingDataRows(true); // delegate.addCustomDbAttributes(Arrays.asList(columns)); return this; } public SelectQuery<M> distinct() { delegate.setDistinct(true); countQuery.setDistinct(true); return this; } public SelectQuery<M> distinct(boolean isDistinct) { delegate.setDistinct(isDistinct); countQuery.setDistinct(isDistinct); return this; } public SelectQuery<M> prefetch(String column) { delegate.addPrefetch(column); return this; } public org.apache.cayenne.query.SelectQuery getQuery() { return delegate; } protected String getPrimaryKey() { ObjEntity objEntity = dataContext.getEntityResolver().lookupObjEntity(rootClass); @SuppressWarnings("unchecked") List<DbAttribute> primaryKey = objEntity.getDbEntity().getPrimaryKey(); DbAttribute dbAttribute = primaryKey.get(0); return dbAttribute.getName(); } }