/*
* 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;
import com.dangdang.ddframe.rdb.sharding.merger.pipeline.coupling.GroupByCouplingResultSet;
import com.dangdang.ddframe.rdb.sharding.merger.pipeline.coupling.LimitCouplingResultSet;
import com.dangdang.ddframe.rdb.sharding.merger.pipeline.coupling.MemoryOrderByCouplingResultSet;
import com.dangdang.ddframe.rdb.sharding.merger.pipeline.reducer.IteratorReducerResultSet;
import com.dangdang.ddframe.rdb.sharding.merger.pipeline.reducer.MemoryOrderByReducerResultSet;
import com.dangdang.ddframe.rdb.sharding.merger.pipeline.reducer.StreamingOrderByReducerResultSet;
import com.dangdang.ddframe.rdb.sharding.parser.result.merger.MergeContext;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
/**
* 分片结果集归并工厂.
*
* @author gaohongtao
* @author zhangliang
*/
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
@Slf4j
public final class ResultSetFactory {
/**
* 获取结果集.
*
* @param resultSets 结果集列表
* @param mergeContext 结果归并上下文
* @return 结果集包装
*/
public static ResultSet getResultSet(final List<ResultSet> resultSets, final MergeContext mergeContext) throws SQLException {
ShardingResultSets shardingResultSets = new ShardingResultSets(resultSets);
log.debug("Sharding-JDBC: Sharding result sets type is '{}'", shardingResultSets.getType().toString());
switch (shardingResultSets.getType()) {
case EMPTY:
return buildEmpty(resultSets);
case SINGLE:
return buildSingle(shardingResultSets);
case MULTIPLE:
return buildMultiple(shardingResultSets, mergeContext);
default:
throw new UnsupportedOperationException(shardingResultSets.getType().toString());
}
}
private static ResultSet buildEmpty(final List<ResultSet> resultSets) {
return resultSets.get(0);
}
private static ResultSet buildSingle(final ShardingResultSets shardingResultSets) throws SQLException {
return shardingResultSets.getResultSets().get(0);
}
private static ResultSet buildMultiple(final ShardingResultSets shardingResultSets, final MergeContext mergeContext) throws SQLException {
ResultSetMergeContext resultSetMergeContext = new ResultSetMergeContext(shardingResultSets, mergeContext);
return buildCoupling(buildReducer(resultSetMergeContext), resultSetMergeContext);
}
private static ResultSet buildReducer(final ResultSetMergeContext resultSetMergeContext) throws SQLException {
if (resultSetMergeContext.isNeedMemorySortForGroupBy()) {
resultSetMergeContext.setGroupByKeysToCurrentOrderByKeys();
return new MemoryOrderByReducerResultSet(resultSetMergeContext);
}
if (resultSetMergeContext.getMergeContext().hasGroupBy() || resultSetMergeContext.getMergeContext().hasOrderBy()) {
return new StreamingOrderByReducerResultSet(resultSetMergeContext);
}
return new IteratorReducerResultSet(resultSetMergeContext);
}
private static ResultSet buildCoupling(final ResultSet resultSet, final ResultSetMergeContext resultSetMergeContext) throws SQLException {
ResultSet result = resultSet;
if (resultSetMergeContext.getMergeContext().hasGroupByOrAggregation()) {
result = new GroupByCouplingResultSet(result, resultSetMergeContext);
}
if (resultSetMergeContext.isNeedMemorySortForOrderBy()) {
resultSetMergeContext.setOrderByKeysToCurrentOrderByKeys();
result = new MemoryOrderByCouplingResultSet(result, resultSetMergeContext);
}
if (resultSetMergeContext.getMergeContext().hasLimit()) {
result = new LimitCouplingResultSet(result, resultSetMergeContext.getMergeContext());
}
return result;
}
}