Commit 90083bac authored by terrymanu's avatar terrymanu
Browse files

refactor limit for rewrite module

parent c33a09b7
Loading
Loading
Loading
Loading
+43 −2
Original line number Diff line number Diff line
@@ -17,8 +17,12 @@

package com.dangdang.ddframe.rdb.sharding.parsing.parser.context;

import com.dangdang.ddframe.rdb.sharding.parsing.parser.exception.SQLParsingException;
import com.google.common.base.Optional;
import lombok.Getter;
import lombok.Setter;

import java.util.List;

/**
 * 分页上下文.
@@ -26,11 +30,12 @@ import lombok.Getter;
 * @author zhangliang
 */
@Getter
@Setter
public final class LimitContext {
    
    private final int rowCount;
    private int rowCount;
    
    private final Optional<Integer> offset;
    private Optional<Integer> offset;
    
    private final int rowCountParameterIndex;
    
@@ -50,7 +55,43 @@ public final class LimitContext {
        this.rowCountParameterIndex = rowCountParameterIndex;
    }
    
    /**
     * 获取分页偏移量.
     * 
     * @return 分页偏移量
     */
    public int getOffset() {
        return offset.isPresent() ? offset.get() : 0;
    }
    
    /**
     * 填充改写分页参数.
     *
     * @param parameters 参数
     */
    public void processParameters(final List<Object> parameters) {
        fill(parameters);
        rewrite(parameters);
    }
    
    private void fill(final List<Object> parameters) {
        int offset = -1 == offsetParameterIndex ? getOffset() : (int) parameters.get(offsetParameterIndex);
        int rowCount = -1 == rowCountParameterIndex ? this.rowCount : (int) parameters.get(rowCountParameterIndex);
        this.offset = Optional.of(offset);
        this.rowCount = rowCount;
        if (offset < 0 || rowCount < 0) {
            throw new SQLParsingException("LIMIT offset and row count can not be a negative value.");
        }
    }
    
    private void rewrite(final List<Object> parameters) {
        int rewriteOffset = 0;
        int rewriteRowCount = getOffset() + rowCount;
        if (offsetParameterIndex > -1) {
            parameters.set(offsetParameterIndex, rewriteOffset);
        }
        if (rowCountParameterIndex > -1) {
            parameters.set(rowCountParameterIndex, rewriteRowCount);
        }
    }
}
+0 −49
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 com.dangdang.ddframe.rdb.sharding.rewrite;

import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.LimitContext;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.SQLContext;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.exception.SQLParsingException;

import java.util.List;

/**
 * 补列工具类.
 *
 * @author zhangliang
 */
public final class LimitUtils {
    
    /**
     * 追加分页.
     * 
     * @param sqlContext SQL上下文
     * @param parameters 参数
     */
    public static void appendLimit(final SQLContext sqlContext, final List<Object> parameters) {
        int offset = -1 == sqlContext.getLimitContext().getOffsetParameterIndex()
                ? sqlContext.getLimitContext().getOffset() : (int) parameters.get(sqlContext.getLimitContext().getOffsetParameterIndex());
        int rowCount = -1 == sqlContext.getLimitContext().getRowCountParameterIndex()
                ? sqlContext.getLimitContext().getRowCount() : (int) parameters.get(sqlContext.getLimitContext().getRowCountParameterIndex());
        sqlContext.setLimitContext(new LimitContext(offset, rowCount, sqlContext.getLimitContext().getOffsetParameterIndex(), sqlContext.getLimitContext().getRowCountParameterIndex()));
        if (offset < 0 || rowCount < 0) {
            throw new SQLParsingException("LIMIT offset and row count can not be a negative value.");
        }
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -127,14 +127,14 @@ public final class SQLRewriteEngine {
    }
    
    private void appendLimitRowCount(final SQLBuilder sqlBuilder, final RowCountLimitToken rowCountLimitToken, final int count, final List<SQLToken> sqlTokens) {
        sqlBuilder.appendToken(RowCountLimitToken.COUNT_NAME, rowCountLimitToken.getRowCount() + "");
        sqlBuilder.appendToken(RowCountLimitToken.COUNT_NAME, rowCountLimitToken.getRowCount() + limit.getOffset() + "");
        int beginPosition = rowCountLimitToken.getBeginPosition() + (rowCountLimitToken.getRowCount() + "").length();
        int endPosition = sqlTokens.size() - 1 == count ? originalSQL.length() : sqlTokens.get(count + 1).getBeginPosition();
        sqlBuilder.append(originalSQL.substring(beginPosition, endPosition));
    }
    
    private void appendLimitOffsetToken(final SQLBuilder sqlBuilder, final OffsetLimitToken offsetLimitToken, final int count, final List<SQLToken> sqlTokens) {
        sqlBuilder.appendToken(OffsetLimitToken.OFFSET_NAME, offsetLimitToken.getOffset() + "");
        sqlBuilder.appendToken(OffsetLimitToken.OFFSET_NAME, "0");
        int beginPosition = offsetLimitToken.getBeginPosition() + (offsetLimitToken.getOffset() + "").length();
        int endPosition = sqlTokens.size() - 1 == count ? originalSQL.length() : sqlTokens.get(count + 1).getBeginPosition();
        sqlBuilder.append(originalSQL.substring(beginPosition, endPosition));
+13 −22
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ import com.dangdang.ddframe.rdb.sharding.parsing.parser.token.OffsetLimitToken;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.token.RowCountLimitToken;
import com.dangdang.ddframe.rdb.sharding.rewrite.DerivedColumnUtils;
import com.dangdang.ddframe.rdb.sharding.rewrite.GenerateKeysUtils;
import com.dangdang.ddframe.rdb.sharding.rewrite.LimitUtils;
import com.dangdang.ddframe.rdb.sharding.rewrite.SQLBuilder;
import com.dangdang.ddframe.rdb.sharding.rewrite.SQLRewriteEngine;
import com.dangdang.ddframe.rdb.sharding.router.binding.BindingTablesRouter;
@@ -104,7 +103,7 @@ public final class SQLRouteEngine {
            DerivedColumnUtils.appendDerivedColumns((SelectSQLContext) result);
        }
        if (null != result.getLimitContext()) {
            LimitUtils.appendLimit(result, parameters);
            result.getLimitContext().processParameters(parameters);
        }
        return result;
    }
@@ -169,26 +168,18 @@ public final class SQLRouteEngine {
    private void amendSQLAccordingToRouteResult(final List<Object> parameters, final SQLRouteResult sqlRouteResult, final SQLRewriteEngine sqlRewriteEngine) {
        LimitContext limit = sqlRouteResult.getSqlContext().getLimitContext();
        SQLBuilder sqlBuilder = sqlRewriteEngine.rewrite();
        if (null != limit) {
            if (1 == sqlRouteResult.getExecutionUnits().size()) {
        if (null == limit || 1 != sqlRouteResult.getExecutionUnits().size()) {
            return;
        }
        if (limit.getOffsetParameterIndex() > -1) {
            parameters.set(limit.getOffsetParameterIndex(), limit.getOffset());
        } else {
            sqlBuilder.buildSQL(OffsetLimitToken.OFFSET_NAME, String.valueOf(limit.getOffset()));
        }
        if (limit.getRowCountParameterIndex() > -1) {
            parameters.set(limit.getRowCountParameterIndex(), limit.getRowCount());
                }
        } else {
                int offset = 0;
                int rowCount = limit.getOffset() + limit.getRowCount();
                if (limit.getOffsetParameterIndex() > -1) {
                    parameters.set(limit.getOffsetParameterIndex(), offset);
                }
                if (limit.getRowCountParameterIndex() > -1) {
                    parameters.set(limit.getRowCountParameterIndex(), rowCount);
                }
                sqlBuilder.buildSQL(OffsetLimitToken.OFFSET_NAME, String.valueOf(offset));
                sqlBuilder.buildSQL(RowCountLimitToken.COUNT_NAME, String.valueOf(rowCount));
            }
            sqlBuilder.buildSQL(RowCountLimitToken.COUNT_NAME, String.valueOf(limit.getRowCount()));
        }
    }
}