/* * JEF - Copyright 2009-2010 Jiyi (mr.jiyi@gmail.com) * * 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 jef.database.wrapper.clause; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import jef.http.client.support.CommentEntry; import jef.tools.StringUtils; public class GroupClause implements SqlClause { private final List<String> groups = new ArrayList<String>(4); private final List<HavingEle> having = new ArrayList<HavingEle>(4); public static final GroupClause DEFAULT = new GroupClause(); public GroupClause() { } public void addGroup(String selectItem) { groups.add(selectItem); } public void addHaving(HavingEle havingClause) { having.add(havingClause); } public boolean isNotEmpty() { return !(groups.isEmpty() && having.isEmpty()); } @Override public String toString() { return getSql(true); } public String getSql(boolean withHaving) { if (groups.isEmpty() && having.isEmpty()) { return ""; } StringBuilder sb = new StringBuilder(); if (!groups.isEmpty()) { sb.append(" group by "); sb.append(StringUtils.join(groups, ',')); } if (withHaving && !having.isEmpty()) { sb.append(" having "); sb.append(StringUtils.join(having, " and ")); } return sb.toString(); } /* * 当确定需要内存分组时,需要解析Select部分的函数,从而得到合适的内存分组计算规则 每个查询字段信息包括 * * 分组列—— 别名 * * 计算列—— 函数,别名 */ public InMemoryGroupByHaving parseSelectFunction(SelectPart select) { List<GroupByItem> keys = new ArrayList<GroupByItem>(4); List<GroupByItem> values = new ArrayList<GroupByItem>(4); List<HavingEle> he = new ArrayList<HavingEle>(3); Map<String, HavingEle> havings = prepareHavingIndex(); for (int i = 0; i < select.getEntries().size(); i++) { CommentEntry e = select.getEntries().get(i); String sql = e.getKey(); String alias = e.getValue(); if (groups.contains(sql)) { keys.add(new GroupByItem(i, GroupFunctionType.GROUP, alias)); } else { GroupFunctionType type; String exp = sql.toUpperCase(); if (exp.startsWith("AVG(")) { type = GroupFunctionType.AVG; } else if (exp.startsWith("COUNT(")) { type = GroupFunctionType.COUNT; } else if (exp.startsWith("SUM(")) { type = GroupFunctionType.SUM; } else if (exp.startsWith("MIN(")) { type = GroupFunctionType.MIN; } else if (exp.startsWith("MAX(")) { type = GroupFunctionType.MAX; } else if (exp.startsWith("ARRAY_TO_STRING(")) { type = GroupFunctionType.ARRAY_TO_STRING; } else { type = GroupFunctionType.NORMAL; } values.add(new GroupByItem(i, type, alias)); } HavingEle h = havings.remove(sql); if (h != null) { h.setIndex(i); he.add(h); } } InMemoryGroupByHaving process = new InMemoryGroupByHaving(keys, values); if (!he.isEmpty()) { process.setHaving(he); } return process; } private Map<String, HavingEle> prepareHavingIndex() { Map<String, HavingEle> map = new HashMap<String, HavingEle>(4); for (HavingEle h : having) { map.put(h.column, h); } return map; } }