/*
* Copyright 1999-2015 dangdang.com.
* <p>
* 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.
* </p>
*/
package com.dangdang.ddframe.rdb.sharding.merger.resultset.memory.row;
import com.dangdang.ddframe.rdb.sharding.merger.pipeline.coupling.aggregation.AggregationUnit;
import com.dangdang.ddframe.rdb.sharding.merger.pipeline.coupling.aggregation.AggregationUnitFactory;
import com.dangdang.ddframe.rdb.sharding.parser.result.merger.AggregationColumn;
import com.dangdang.ddframe.rdb.sharding.parser.result.merger.GroupByColumn;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* 具有分组功能的数据行对象.
*
* @author gaohongtao
* @author zhangliang
*/
public final class GroupByResultSetRow extends AbstractResultSetRow {
private final ResultSet resultSet;
private final List<GroupByColumn> groupByColumns;
private final Map<AggregationColumn, AggregationUnit> aggregationUnitMap;
public GroupByResultSetRow(final ResultSet resultSet, final List<GroupByColumn> groupByColumns, final List<AggregationColumn> aggregationColumns) throws SQLException {
super(resultSet);
this.resultSet = resultSet;
this.groupByColumns = groupByColumns;
aggregationUnitMap = Maps.toMap(aggregationColumns, new Function<AggregationColumn, AggregationUnit>() {
@Override
public AggregationUnit apply(final AggregationColumn input) {
return AggregationUnitFactory.create(input.getAggregationType());
}
});
}
/**
* 处理聚合函数结果集.
*
* @throws SQLException SQL异常
*/
public void aggregate() throws SQLException {
for (Map.Entry<AggregationColumn, AggregationUnit> each : aggregationUnitMap.entrySet()) {
each.getValue().merge(getAggregationValues(each.getKey().getDerivedColumns().isEmpty() ? Collections.singletonList(each.getKey()) : each.getKey().getDerivedColumns()));
}
}
private List<Comparable<?>> getAggregationValues(final List<AggregationColumn> aggregationColumns) throws SQLException {
List<Comparable<?>> result = new ArrayList<>(aggregationColumns.size());
for (AggregationColumn each : aggregationColumns) {
result.add((Comparable<?>) resultSet.getObject(each.getColumnIndex()));
}
return result;
}
/**
* 生成结果.
*/
public void generateResult() {
for (AggregationColumn each : aggregationUnitMap.keySet()) {
setCell(each.getColumnIndex(), aggregationUnitMap.get(each).getResult());
}
}
/**
* 获取分组值.
*
* @return 分组值集合
* @throws SQLException SQL异常
*/
public List<Object> getGroupByValues() throws SQLException {
List<Object> result = new ArrayList<>(groupByColumns.size());
for (GroupByColumn each : groupByColumns) {
result.add(resultSet.getObject(each.getColumnIndex()));
}
return result;
}
@Override
public String toString() {
StringBuilder result = new StringBuilder("GroupByKey is: ");
result.append(Lists.transform(groupByColumns, new Function<GroupByColumn, Object>() {
@Override
public Object apply(final GroupByColumn input) {
return getCell(input.getColumnIndex());
}
}));
if (aggregationUnitMap.isEmpty()) {
return result.toString();
}
result.append("; Aggregation result is: ").append(Lists.transform(new ArrayList<>(aggregationUnitMap.keySet()), new Function<AggregationColumn, String>() {
@Override
public String apply(final AggregationColumn input) {
Object value = getCell(input.getColumnIndex());
value = null == value ? "null" : value;
return String.format("{index:%d, type:%s, value:%s}", input.getColumnIndex(), input.getAggregationType(), value);
}
}));
return result.toString();
}
}