MergeContext.java 5.9 KB
Newer Older
T
terrymanu 已提交
1
/*
T
terrymanu 已提交
2 3 4 5 6
 * 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
T
terrymanu 已提交
7
 *
T
terrymanu 已提交
8
 *      http://www.apache.org/licenses/LICENSE-2.0
T
terrymanu 已提交
9
 *
T
terrymanu 已提交
10 11 12 13 14 15 16 17 18 19
 * 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.parser.result.merger;

G
fix #16  
gaohongtao 已提交
20
import com.dangdang.ddframe.rdb.sharding.executor.ExecutorEngine;
G
gaohongtao 已提交
21
import com.dangdang.ddframe.rdb.sharding.merger.component.other.WrapperResultSet;
G
gaohongtao 已提交
22
import com.google.common.base.Function;
G
gaohongtao 已提交
23
import com.google.common.base.Preconditions;
G
gaohongtao 已提交
24
import com.google.common.collect.Lists;
T
terrymanu 已提交
25 26 27 28
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

G
gaoht 已提交
29 30 31 32 33 34
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

T
terrymanu 已提交
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
/**
 * 结果归并上下文.
 * 
 * @author zhangliang
 */
@Getter
@ToString
public final class MergeContext {
    
    private final List<OrderByColumn> orderByColumns = new ArrayList<>();
    
    private final List<GroupByColumn> groupByColumns = new ArrayList<>();
    
    private final List<AggregationColumn> aggregationColumns = new ArrayList<>();
    
    @Setter
    private Limit limit;
    
G
fix #16  
gaohongtao 已提交
53 54 55
    @Setter
    private ExecutorEngine executorEngine;
    
G
gaohongtao 已提交
56 57 58 59 60 61 62 63 64 65 66 67 68
    private Map<String, Integer> columnLabelIndexMap;
    
    private final List<OrderByColumn> currentOrderByKeys = new LinkedList<>();
    
    /**
     * 是否包含分组.
     * 
     * @return 是否包含分组
     */
    public boolean hasGroupBy() {
        return !groupByColumns.isEmpty();
    }
    
G
gaohongtao 已提交
69 70 71 72 73 74 75
    /**
     * 判断是否为分组或者聚合计算.
     * 此处将聚合计算想象成为特殊的分组计算,统一进行处理.
     *
     * @return true:是分组或者聚合计算 false:不是分组且不是聚合计算
     */
    public boolean hasGroupByOrAggregation() {
G
gaohongtao 已提交
76
        return hasGroupBy() || !aggregationColumns.isEmpty();
G
gaohongtao 已提交
77 78 79
    }
    
    /**
G
gaohongtao 已提交
80 81 82
     * 是否包含排序列.
     * 
     * @return true 包含 false 不包含
G
gaohongtao 已提交
83 84 85 86 87 88
     */
    public boolean hasOrderBy() {
        return !orderByColumns.isEmpty();
    }
    
    /**
G
gaohongtao 已提交
89 90 91
     * 判断是否为排序计算并且是否需要进行排序.
     *
     * @return true:是排序计算 false:不是排序计算
G
gaohongtao 已提交
92
     */
G
gaohongtao 已提交
93 94
    public boolean needToSort() {
        return hasOrderBy() && !equalsOrderByKeys(orderByColumns);
G
gaohongtao 已提交
95 96 97
    }
    
    /**
G
gaohongtao 已提交
98 99 100 101
     * 分组排序结果与底层排序是否相同.
     * 不同就修改底层排序键为分组排序键
     *
     * @return true 相同 false 不同
G
gaohongtao 已提交
102
     */
G
gaohongtao 已提交
103 104
    public boolean groupByKeysEqualsOrderByKeys() {
        List<OrderByColumn> orderByKeysFromGroupByColumns = Lists.transform(groupByColumns, new Function<GroupByColumn, OrderByColumn>() {
T
terrymanu 已提交
105
            
G
gaohongtao 已提交
106 107
            @Override
            public OrderByColumn apply(final GroupByColumn input) {
G
gaoht 已提交
108
                OrderByColumn result = new OrderByColumn(input.getOwner(), input.getName().get(), input.getAlias(), input.getOrderByType());
T
terrymanu 已提交
109 110
                result.setColumnIndex(input.getColumnIndex());
                return result;
G
gaohongtao 已提交
111 112
            }
        });
G
gaohongtao 已提交
113 114 115 116 117 118 119 120 121 122
        return equalsOrderByKeys(orderByKeysFromGroupByColumns);
    }
    
    private boolean equalsOrderByKeys(final List<OrderByColumn> expectedOrderByKeys) {
        if (currentOrderByKeys.equals(expectedOrderByKeys)) {
            return true;
        }
        currentOrderByKeys.clear();
        currentOrderByKeys.addAll(expectedOrderByKeys);
        return false;
G
gaohongtao 已提交
123 124
    }
    
T
terrymanu 已提交
125
    /**
G
gaohongtao 已提交
126
     * 判断是否有限定结果集计算.
T
terrymanu 已提交
127
     * 
G
gaohongtao 已提交
128
     * @return true:是限定结果集计算 false:不是限定结果集计算
T
terrymanu 已提交
129
     */
G
gaohongtao 已提交
130 131
    public boolean hasLimit() {
        return limit != null;
T
terrymanu 已提交
132 133
    }
    
T
terrymanu 已提交
134
    /**
G
gaohongtao 已提交
135 136 137 138
     * 使用结果集构造合并上下文信息.
     *
     * @param resultSet 结果集
     * @throws SQLException 访问结果集可能抛出的异常抛出
T
terrymanu 已提交
139
     */
G
gaohongtao 已提交
140 141 142 143
    public void buildContextWithResultSet(final WrapperResultSet resultSet) throws SQLException {
        columnLabelIndexMap = resultSet.getColumnLabelIndexMap();
        setColumnIndex();
        currentOrderByKeys.addAll(orderByColumns);
T
terrymanu 已提交
144 145
    }
    
G
gaohongtao 已提交
146 147 148 149 150 151 152 153 154 155 156
    private void setColumnIndex() {
        for (IndexColumn each : extractFocusedColumns()) {
            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()));
T
terrymanu 已提交
157 158 159 160
            }
        }
    }
    
G
gaohongtao 已提交
161 162 163 164 165 166 167 168 169 170 171 172 173 174
    private List<IndexColumn> extractFocusedColumns() {
        List<IndexColumn> result = new LinkedList<>();
        result.addAll(groupByColumns);
        result.addAll(orderByColumns);
        LinkedList<AggregationColumn> allAggregationColumns = Lists.newLinkedList(aggregationColumns);
        while (allAggregationColumns.size() > 0) {
            AggregationColumn head = allAggregationColumns.poll();
            result.add(head);
            if (head.getDerivedColumns().isEmpty()) {
                continue;
            }
            allAggregationColumns.addAll(head.getDerivedColumns());
        }
        return result;
T
terrymanu 已提交
175 176
    }
}