Commit de8a05cb authored by terrymanu's avatar terrymanu
Browse files

support show tables & show databases

parent 43f3ddeb
Loading
Loading
Loading
Loading
+22 −5
Original line number Diff line number Diff line
@@ -17,6 +17,9 @@

package io.shardingjdbc.core.jdbc.core.statement;

import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterators;
import io.shardingjdbc.core.constant.SQLType;
import io.shardingjdbc.core.executor.type.batch.BatchPreparedStatementExecutor;
import io.shardingjdbc.core.executor.type.batch.BatchPreparedStatementUnit;
@@ -27,15 +30,15 @@ import io.shardingjdbc.core.jdbc.core.connection.ShardingConnection;
import io.shardingjdbc.core.jdbc.core.resultset.GeneratedKeysResultSet;
import io.shardingjdbc.core.jdbc.core.resultset.ShardingResultSet;
import io.shardingjdbc.core.merger.MergeEngine;
import io.shardingjdbc.core.merger.SelectMergeEngine;
import io.shardingjdbc.core.merger.ShowMergeEngine;
import io.shardingjdbc.core.parsing.parser.context.GeneratedKey;
import io.shardingjdbc.core.parsing.parser.dialect.mysql.statement.ShowStatement;
import io.shardingjdbc.core.parsing.parser.sql.dml.insert.InsertStatement;
import io.shardingjdbc.core.parsing.parser.sql.dql.select.SelectStatement;
import io.shardingjdbc.core.routing.PreparedStatementRoutingEngine;
import io.shardingjdbc.core.routing.SQLExecutionUnit;
import io.shardingjdbc.core.routing.SQLRouteResult;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterators;
import lombok.AccessLevel;
import lombok.Getter;

@@ -115,7 +118,15 @@ public final class ShardingPreparedStatement extends AbstractShardingPreparedSta
            Collection<PreparedStatementUnit> preparedStatementUnits = route();
            List<ResultSet> resultSets = new PreparedStatementExecutor(
                    getConnection().getShardingContext().getExecutorEngine(), routeResult.getSqlStatement().getType(), preparedStatementUnits, getParameters()).executeQuery();
            result = new ShardingResultSet(resultSets, new MergeEngine(resultSets, (SelectStatement) routeResult.getSqlStatement()).merge(), this);
            MergeEngine mergeEngine;
            if (routeResult.getSqlStatement() instanceof SelectStatement) {
                mergeEngine = new SelectMergeEngine(resultSets, (SelectStatement) routeResult.getSqlStatement());
            } else if (routeResult.getSqlStatement() instanceof ShowStatement) {
                mergeEngine = new ShowMergeEngine(connection.getShardingContext().getShardingRule(), resultSets, (ShowStatement) routeResult.getSqlStatement());
            } else {
                throw new UnsupportedOperationException(String.format("Cannot support type '%s'", routeResult.getSqlStatement().getType()));
            }
            result = new ShardingResultSet(resultSets, mergeEngine.merge(), this);
        } finally {
            clearBatch();
        }
@@ -271,8 +282,14 @@ public final class ShardingPreparedStatement extends AbstractShardingPreparedSta
        for (PreparedStatement each : routedStatements) {
            resultSets.add(each.getResultSet());
        }
        MergeEngine mergeEngine = null;
        if (routeResult.getSqlStatement() instanceof SelectStatement) {
            currentResultSet = new ShardingResultSet(resultSets, new MergeEngine(resultSets, (SelectStatement) routeResult.getSqlStatement()).merge(), this);
            mergeEngine = new SelectMergeEngine(resultSets, (SelectStatement) routeResult.getSqlStatement());
        } else if (routeResult.getSqlStatement() instanceof ShowStatement) {
            mergeEngine = new ShowMergeEngine(connection.getShardingContext().getShardingRule(), resultSets, (ShowStatement) routeResult.getSqlStatement());
        }
        if (null != mergeEngine) {
            currentResultSet = new ShardingResultSet(resultSets, mergeEngine.merge(), this);
        }
        return currentResultSet;
    }
+19 −3
Original line number Diff line number Diff line
@@ -25,7 +25,10 @@ import io.shardingjdbc.core.jdbc.core.connection.ShardingConnection;
import io.shardingjdbc.core.jdbc.core.resultset.GeneratedKeysResultSet;
import io.shardingjdbc.core.jdbc.core.resultset.ShardingResultSet;
import io.shardingjdbc.core.merger.MergeEngine;
import io.shardingjdbc.core.merger.SelectMergeEngine;
import io.shardingjdbc.core.merger.ShowMergeEngine;
import io.shardingjdbc.core.parsing.parser.context.GeneratedKey;
import io.shardingjdbc.core.parsing.parser.dialect.mysql.statement.ShowStatement;
import io.shardingjdbc.core.parsing.parser.sql.dml.insert.InsertStatement;
import io.shardingjdbc.core.parsing.parser.sql.dql.select.SelectStatement;
import io.shardingjdbc.core.routing.SQLExecutionUnit;
@@ -95,8 +98,15 @@ public class ShardingStatement extends AbstractStatementAdapter {
        ResultSet result;
        try {
            List<ResultSet> resultSets = generateExecutor(sql).executeQuery();
            result = new ShardingResultSet(
                    resultSets, new MergeEngine(resultSets, (SelectStatement) routeResult.getSqlStatement()).merge(), this);
            MergeEngine mergeEngine;
            if (routeResult.getSqlStatement() instanceof SelectStatement) {
                mergeEngine = new SelectMergeEngine(resultSets, (SelectStatement) routeResult.getSqlStatement());
            } else if (routeResult.getSqlStatement() instanceof ShowStatement) {
                mergeEngine = new ShowMergeEngine(connection.getShardingContext().getShardingRule(), resultSets, (ShowStatement) routeResult.getSqlStatement());
            } else {
                throw new UnsupportedOperationException(String.format("Cannot support type '%s'", routeResult.getSqlStatement().getType()));
            }
            result = new ShardingResultSet(resultSets, mergeEngine.merge(), this);
        } finally {
            currentResultSet = null;
        }
@@ -247,8 +257,14 @@ public class ShardingStatement extends AbstractStatementAdapter {
        for (Statement each : routedStatements) {
            resultSets.add(each.getResultSet());
        }
        MergeEngine mergeEngine = null;
        if (routeResult.getSqlStatement() instanceof SelectStatement) {
            currentResultSet = new ShardingResultSet(resultSets, new MergeEngine(resultSets, (SelectStatement) routeResult.getSqlStatement()).merge(), this);
            mergeEngine = new SelectMergeEngine(resultSets, (SelectStatement) routeResult.getSqlStatement());
        } else if (routeResult.getSqlStatement() instanceof ShowStatement) {
            mergeEngine = new ShowMergeEngine(connection.getShardingContext().getShardingRule(), resultSets, (ShowStatement) routeResult.getSqlStatement());
        }
        if (null != mergeEngine) {
            currentResultSet = new ShardingResultSet(resultSets, mergeEngine.merge(), this);
        }
        return currentResultSet;
    }
+3 −75
Original line number Diff line number Diff line
@@ -17,52 +17,14 @@

package io.shardingjdbc.core.merger;

import io.shardingjdbc.core.constant.DatabaseType;
import io.shardingjdbc.core.merger.groupby.GroupByMemoryResultSetMerger;
import io.shardingjdbc.core.merger.groupby.GroupByStreamResultSetMerger;
import io.shardingjdbc.core.merger.iterator.IteratorStreamResultSetMerger;
import io.shardingjdbc.core.merger.pagination.LimitDecoratorResultSetMerger;
import io.shardingjdbc.core.merger.pagination.RowNumberDecoratorResultSetMerger;
import io.shardingjdbc.core.merger.pagination.TopAndRowNumberDecoratorResultSetMerger;
import io.shardingjdbc.core.merger.orderby.OrderByStreamResultSetMerger;
import io.shardingjdbc.core.parsing.parser.context.limit.Limit;
import io.shardingjdbc.core.parsing.parser.sql.dql.select.SelectStatement;
import io.shardingjdbc.core.util.SQLUtil;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * ResultSet merge engine.
 * result set merge engine.
 *
 * @author zhangliang
 */
public final class MergeEngine {
    
    private final List<ResultSet> resultSets;
    
    private final SelectStatement selectStatement;
    
    private final Map<String, Integer> columnLabelIndexMap;
    
    public MergeEngine(final List<ResultSet> resultSets, final SelectStatement selectStatement) throws SQLException {
        this.resultSets = resultSets;
        this.selectStatement = selectStatement;
        columnLabelIndexMap = getColumnLabelIndexMap(resultSets.get(0));
    }
    
    private Map<String, Integer> getColumnLabelIndexMap(final ResultSet resultSet) throws SQLException {
        ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
        Map<String, Integer> result = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
        for (int i = 1; i <= resultSetMetaData.getColumnCount(); i++) {
            result.put(SQLUtil.getExactlyValue(resultSetMetaData.getColumnLabel(i)), i);
        }
        return result;
    }
public interface MergeEngine {
    
    /**
     * Merge result sets.
@@ -70,39 +32,5 @@ public final class MergeEngine {
     * @return merged result set.
     * @throws SQLException SQL exception
     */
    public ResultSetMerger merge() throws SQLException {
        selectStatement.setIndexForItems(columnLabelIndexMap);
        return decorate(build());
    }
    
    private ResultSetMerger build() throws SQLException {
        if (!selectStatement.getGroupByItems().isEmpty() || !selectStatement.getAggregationSelectItems().isEmpty()) {
            if (selectStatement.isSameGroupByAndOrderByItems()) {
                return new GroupByStreamResultSetMerger(columnLabelIndexMap, resultSets, selectStatement);
            } else {
                return new GroupByMemoryResultSetMerger(columnLabelIndexMap, resultSets, selectStatement);
            }
        }
        if (!selectStatement.getOrderByItems().isEmpty()) {
            return new OrderByStreamResultSetMerger(resultSets, selectStatement.getOrderByItems());
        }
        return new IteratorStreamResultSetMerger(resultSets);
    }
    
    private ResultSetMerger decorate(final ResultSetMerger resultSetMerger) throws SQLException {
        Limit limit = selectStatement.getLimit();
        if (null == limit) {
            return resultSetMerger;
        }
        if (DatabaseType.MySQL == limit.getDatabaseType() || DatabaseType.PostgreSQL == limit.getDatabaseType() || DatabaseType.H2 == limit.getDatabaseType()) {
            return new LimitDecoratorResultSetMerger(resultSetMerger, selectStatement.getLimit());
        }
        if (DatabaseType.Oracle == limit.getDatabaseType()) {
            return new RowNumberDecoratorResultSetMerger(resultSetMerger, selectStatement.getLimit());
        }
        if (DatabaseType.SQLServer == limit.getDatabaseType()) {
            return new TopAndRowNumberDecoratorResultSetMerger(resultSetMerger, selectStatement.getLimit());
        }
        return resultSetMerger;
    }
    ResultSetMerger merge() throws SQLException;
}
+103 −0
Original line number Diff line number Diff line
/*
 * 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 io.shardingjdbc.core.merger;

import io.shardingjdbc.core.constant.DatabaseType;
import io.shardingjdbc.core.merger.groupby.GroupByMemoryResultSetMerger;
import io.shardingjdbc.core.merger.groupby.GroupByStreamResultSetMerger;
import io.shardingjdbc.core.merger.iterator.IteratorStreamResultSetMerger;
import io.shardingjdbc.core.merger.pagination.LimitDecoratorResultSetMerger;
import io.shardingjdbc.core.merger.pagination.RowNumberDecoratorResultSetMerger;
import io.shardingjdbc.core.merger.pagination.TopAndRowNumberDecoratorResultSetMerger;
import io.shardingjdbc.core.merger.orderby.OrderByStreamResultSetMerger;
import io.shardingjdbc.core.parsing.parser.context.limit.Limit;
import io.shardingjdbc.core.parsing.parser.sql.dql.select.SelectStatement;
import io.shardingjdbc.core.util.SQLUtil;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * Select result set merge engine.
 *
 * @author zhangliang
 */
public final class SelectMergeEngine implements MergeEngine {
    
    private final List<ResultSet> resultSets;
    
    private final SelectStatement selectStatement;
    
    private final Map<String, Integer> columnLabelIndexMap;
    
    public SelectMergeEngine(final List<ResultSet> resultSets, final SelectStatement selectStatement) throws SQLException {
        this.resultSets = resultSets;
        this.selectStatement = selectStatement;
        columnLabelIndexMap = getColumnLabelIndexMap(resultSets.get(0));
    }
    
    private Map<String, Integer> getColumnLabelIndexMap(final ResultSet resultSet) throws SQLException {
        ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
        Map<String, Integer> result = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
        for (int i = 1; i <= resultSetMetaData.getColumnCount(); i++) {
            result.put(SQLUtil.getExactlyValue(resultSetMetaData.getColumnLabel(i)), i);
        }
        return result;
    }
    
    @Override
    public ResultSetMerger merge() throws SQLException {
        selectStatement.setIndexForItems(columnLabelIndexMap);
        return decorate(build());
    }
    
    private ResultSetMerger build() throws SQLException {
        if (!selectStatement.getGroupByItems().isEmpty() || !selectStatement.getAggregationSelectItems().isEmpty()) {
            if (selectStatement.isSameGroupByAndOrderByItems()) {
                return new GroupByStreamResultSetMerger(columnLabelIndexMap, resultSets, selectStatement);
            } else {
                return new GroupByMemoryResultSetMerger(columnLabelIndexMap, resultSets, selectStatement);
            }
        }
        if (!selectStatement.getOrderByItems().isEmpty()) {
            return new OrderByStreamResultSetMerger(resultSets, selectStatement.getOrderByItems());
        }
        return new IteratorStreamResultSetMerger(resultSets);
    }
    
    private ResultSetMerger decorate(final ResultSetMerger resultSetMerger) throws SQLException {
        Limit limit = selectStatement.getLimit();
        if (null == limit) {
            return resultSetMerger;
        }
        if (DatabaseType.MySQL == limit.getDatabaseType() || DatabaseType.PostgreSQL == limit.getDatabaseType() || DatabaseType.H2 == limit.getDatabaseType()) {
            return new LimitDecoratorResultSetMerger(resultSetMerger, selectStatement.getLimit());
        }
        if (DatabaseType.Oracle == limit.getDatabaseType()) {
            return new RowNumberDecoratorResultSetMerger(resultSetMerger, selectStatement.getLimit());
        }
        if (DatabaseType.SQLServer == limit.getDatabaseType()) {
            return new TopAndRowNumberDecoratorResultSetMerger(resultSetMerger, selectStatement.getLimit());
        }
        return resultSetMerger;
    }
}
+56 −0
Original line number Diff line number Diff line
/*
 * 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 io.shardingjdbc.core.merger;

import io.shardingjdbc.core.merger.show.ShowDatabasesResultSetMerger;
import io.shardingjdbc.core.merger.show.ShowOtherResultSetMerger;
import io.shardingjdbc.core.merger.show.ShowTablesResultSetMerger;
import io.shardingjdbc.core.parsing.parser.dialect.mysql.statement.ShowStatement;
import io.shardingjdbc.core.parsing.parser.dialect.mysql.statement.ShowType;
import io.shardingjdbc.core.rule.ShardingRule;
import lombok.RequiredArgsConstructor;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

/**
 * Show result set merge engine.
 *
 * @author zhangliang
 */
@RequiredArgsConstructor
public final class ShowMergeEngine implements MergeEngine {
    
    private final ShardingRule shardingRule;
    
    private final List<ResultSet> resultSets;
    
    private final ShowStatement showStatement;
    
    @Override
    public ResultSetMerger merge() throws SQLException {
        if (ShowType.DATABASES == showStatement.getShowType()) {
            return new ShowDatabasesResultSetMerger();
        }
        if (ShowType.TABLES == showStatement.getShowType()) {
            return new ShowTablesResultSetMerger(shardingRule, resultSets);
        }
        return new ShowOtherResultSetMerger(resultSets.get(0));
    }
}
Loading