/* * 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.jdbc.adapter.AbstractResultSetAdapter; import com.dangdang.ddframe.rdb.sharding.parser.result.merger.AggregationColumn; import com.dangdang.ddframe.rdb.sharding.parser.result.merger.GroupByColumn; import com.dangdang.ddframe.rdb.sharding.parser.result.merger.IndexColumn; import com.dangdang.ddframe.rdb.sharding.parser.result.merger.MergeContext; import com.dangdang.ddframe.rdb.sharding.parser.result.merger.OrderByColumn; import com.google.common.base.Function; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import lombok.Getter; import java.sql.SQLException; import java.util.LinkedList; import java.util.List; import java.util.Map; /** * 结果集归并上下文. * * @author zhangliang */ @Getter public final class ResultSetMergeContext { private final ShardingResultSets shardingResultSets; private final MergeContext mergeContext; private final List<OrderByColumn> currentOrderByKeys; public ResultSetMergeContext(final ShardingResultSets shardingResultSets, final MergeContext mergeContext) throws SQLException { this.shardingResultSets = shardingResultSets; this.mergeContext = mergeContext; currentOrderByKeys = new LinkedList<>(); init(); } private void init() throws SQLException { setColumnIndex(((AbstractResultSetAdapter) shardingResultSets.getResultSets().get(0)).getColumnLabelIndexMap()); currentOrderByKeys.addAll(mergeContext.getOrderByColumns()); } private void setColumnIndex(final Map<String, Integer> columnLabelIndexMap) { for (IndexColumn each : getAllFocusedColumns()) { if (each.getColumnIndex() > 0) { continue; } Preconditions.checkState( columnLabelIndexMap.containsKey(each.getColumnLabel().orNull()) || columnLabelIndexMap.containsKey(each.getColumnName().orNull()), String.format("%s has not index", each)); if (each.getColumnLabel().isPresent() && columnLabelIndexMap.containsKey(each.getColumnLabel().get())) { each.setColumnIndex(columnLabelIndexMap.get(each.getColumnLabel().get())); } else if (each.getColumnName().isPresent() && columnLabelIndexMap.containsKey(each.getColumnName().get())) { each.setColumnIndex(columnLabelIndexMap.get(each.getColumnName().get())); } } } private List<IndexColumn> getAllFocusedColumns() { List<IndexColumn> result = new LinkedList<>(); result.addAll(mergeContext.getGroupByColumns()); result.addAll(mergeContext.getOrderByColumns()); LinkedList<AggregationColumn> allAggregationColumns = Lists.newLinkedList(mergeContext.getAggregationColumns()); while (!allAggregationColumns.isEmpty()) { AggregationColumn firstElement = allAggregationColumns.poll(); result.add(firstElement); if (!firstElement.getDerivedColumns().isEmpty()) { allAggregationColumns.addAll(firstElement.getDerivedColumns()); } } return result; } /** * 判断分组归并是否需要内存排序. * * @return 分组归并是否需要内存排序 */ public boolean isNeedMemorySortForGroupBy() { return mergeContext.hasGroupBy() && !currentOrderByKeys.equals(transformGroupByColumnsToOrderByColumns()); } /** * 将分组顺序设置为排序序列. */ public void setGroupByKeysToCurrentOrderByKeys() { currentOrderByKeys.clear(); currentOrderByKeys.addAll(transformGroupByColumnsToOrderByColumns()); } private List<OrderByColumn> transformGroupByColumnsToOrderByColumns() { return Lists.transform(mergeContext.getGroupByColumns(), new Function<GroupByColumn, OrderByColumn>() { @Override public OrderByColumn apply(final GroupByColumn input) { OrderByColumn result = new OrderByColumn(input.getOwner(), input.getName().get(), input.getAlias(), input.getOrderByType()); result.setColumnIndex(input.getColumnIndex()); return result; } }); } /** * 判断排序归并是否需要内存排序. * * @return 排序归并是否需要内存排序 */ public boolean isNeedMemorySortForOrderBy() { return mergeContext.hasOrderBy() && !currentOrderByKeys.equals(mergeContext.getOrderByColumns()); } /** * 将排序顺序设置为排序序列. */ public void setOrderByKeysToCurrentOrderByKeys() { currentOrderByKeys.clear(); currentOrderByKeys.addAll(mergeContext.getOrderByColumns()); } }