提交 64b22090 编写于 作者: H haocao

Refactor parser Limit relative classes.

上级 f06fb68e
......@@ -18,7 +18,7 @@
package com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.exception.SQLParsingException;
import com.google.common.base.Optional;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
......@@ -28,31 +28,23 @@ import java.util.List;
* 分页对象.
*
* @author zhangliang
* @author caohao
*/
@AllArgsConstructor
@Getter
@Setter
public final class Limit {
private int rowCount;
private OffsetLimit offsetLimit;
private Optional<Integer> offset;
private RowCountLimit rowCountLimit;
private final int rowCountParameterIndex;
private final int offsetParameterIndex;
public Limit(final int rowCount, final int rowCountParameterIndex) {
this.rowCount = rowCount;
offset = Optional.absent();
this.offsetParameterIndex = -1;
this.rowCountParameterIndex = rowCountParameterIndex;
public Limit(final RowCountLimit rowCount) {
this.rowCountLimit = rowCount;
}
public Limit(final int offset, final int rowCount, final int offsetParameterIndex, final int rowCountParameterIndex) {
this.offset = Optional.of(offset);
this.rowCount = rowCount;
this.offsetParameterIndex = offsetParameterIndex;
this.rowCountParameterIndex = rowCountParameterIndex;
public Limit(final OffsetLimit offsetLimit) {
this.offsetLimit = offsetLimit;
}
/**
......@@ -61,7 +53,16 @@ public final class Limit {
* @return 分页偏移量
*/
public int getOffset() {
return offset.isPresent() ? offset.get() : 0;
return null != offsetLimit ? offsetLimit.getOffset() : 0;
}
/**
* 获取分页行数.
*
* @return 分页行数
*/
public int getRowCount() {
return null != rowCountLimit ? rowCountLimit.getRowCount() : 0;
}
/**
......@@ -78,10 +79,16 @@ public final class Limit {
}
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;
int offset = 0;
if (null != offsetLimit) {
offset = -1 == offsetLimit.getOffsetParameterIndex() ? getOffset() : (int) parameters.get(offsetLimit.getOffsetParameterIndex());
offsetLimit.setOffset(offset);
}
int rowCount = 0;
if (null != rowCountLimit) {
rowCount = -1 == rowCountLimit.getRowCountParameterIndex() ? getRowCount() : (int) parameters.get(rowCountLimit.getRowCountParameterIndex());
rowCountLimit.setRowCount(rowCount);
}
if (offset < 0 || rowCount < 0) {
throw new SQLParsingException("LIMIT offset and row count can not be a negative value.");
}
......@@ -89,12 +96,12 @@ public final class Limit {
private void rewrite(final List<Object> parameters) {
int rewriteOffset = 0;
int rewriteRowCount = getOffset() + rowCount;
if (offsetParameterIndex > -1) {
parameters.set(offsetParameterIndex, rewriteOffset);
int rewriteRowCount = getOffset() + rowCountLimit.getRowCount();
if (null != offsetLimit && offsetLimit.getOffsetParameterIndex() > -1) {
parameters.set(offsetLimit.getOffsetParameterIndex(), rewriteOffset);
}
if (rowCountParameterIndex > -1) {
parameters.set(rowCountParameterIndex, rewriteRowCount);
if (null != rowCountLimit && rowCountLimit.getRowCountParameterIndex() > -1) {
parameters.set(rowCountLimit.getRowCountParameterIndex(), rewriteRowCount);
}
}
}
/*
* 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.parsing.parser.context.limit;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
/**
* 分页偏移量对象.
*
* @author caohao
*/
@AllArgsConstructor
@Getter
@Setter
public class OffsetLimit {
private int offset;
private int offsetParameterIndex;
}
/*
* 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.parsing.parser.context.limit;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
/**
* 分页行数对象.
*
* @author caohao
*/
@AllArgsConstructor
@Getter
@Setter
public class RowCountLimit {
private int rowCount;
private int rowCountParameterIndex;
}
......@@ -24,6 +24,8 @@ import com.dangdang.ddframe.rdb.sharding.parsing.lexer.token.Literals;
import com.dangdang.ddframe.rdb.sharding.parsing.lexer.token.Symbol;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.SQLParser;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.Limit;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.OffsetLimit;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.RowCountLimit;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.statement.SQLStatement;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.exception.SQLParsingException;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.token.OffsetLimitToken;
......@@ -75,7 +77,7 @@ public final class MySQLParser extends SQLParser {
if (!isParameterForValue) {
sqlStatement.getSqlTokens().add(new RowCountLimitToken(valueBeginPosition, value));
}
return new Limit(value, valueIndex);
return new Limit(new RowCountLimit(value, valueIndex));
}
private Limit getLimitWithComma(
......@@ -102,7 +104,7 @@ public final class MySQLParser extends SQLParser {
if (!isParameterForRowCount) {
sqlStatement.getSqlTokens().add(new RowCountLimitToken(rowCountBeginPosition, rowCount));
}
return new Limit(value, rowCount, valueIndex, rowCountIndex);
return new Limit(new OffsetLimit(value, valueIndex), new RowCountLimit(rowCount, rowCountIndex));
}
private Limit getLimitWithOffset(
......@@ -129,6 +131,6 @@ public final class MySQLParser extends SQLParser {
if (!isParameterForValue) {
sqlStatement.getSqlTokens().add(new RowCountLimitToken(valueBeginPosition, value));
}
return new Limit(offset, value, offsetIndex, valueIndex);
return new Limit(new OffsetLimit(offset, offsetIndex), new RowCountLimit(value, valueIndex));
}
}
......@@ -23,13 +23,15 @@ import com.dangdang.ddframe.rdb.sharding.parsing.lexer.token.Literals;
import com.dangdang.ddframe.rdb.sharding.parsing.lexer.token.Symbol;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.SQLParser;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.Limit;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.OffsetLimit;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.RowCountLimit;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.exception.SQLParsingException;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.exception.SQLParsingUnsupportedException;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.statement.select.AbstractSelectParser;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.token.OffsetLimitToken;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.token.RowCountLimitToken;
import java.math.BigDecimal;
import static com.dangdang.ddframe.rdb.sharding.util.NumberUtil.roundHalfUp;
public class PostgreSQLSelectParser extends AbstractSelectParser {
......@@ -86,7 +88,7 @@ public class PostgreSQLSelectParser extends AbstractSelectParser {
getSqlParser().getLexer().nextToken();
} else {
if (getSqlParser().equalAny(Literals.INT, Literals.FLOAT)) {
rowCount = new BigDecimal(getSqlParser().getLexer().getCurrentToken().getLiterals()).setScale(0, BigDecimal.ROUND_HALF_UP).intValue();
rowCount = roundHalfUp(getSqlParser().getLexer().getCurrentToken().getLiterals());
valueBeginPosition = valueBeginPosition - (rowCount + "").length();
getSelectStatement().getSqlTokens().add(new RowCountLimitToken(valueBeginPosition, rowCount));
} else if (getSqlParser().equalAny(Symbol.QUESTION)) {
......@@ -102,7 +104,7 @@ public class PostgreSQLSelectParser extends AbstractSelectParser {
hasOffset = true;
int offsetBeginPosition = getSqlParser().getLexer().getCurrentToken().getEndPosition();
if (getSqlParser().equalAny(Literals.INT, Literals.FLOAT)) {
offset = new BigDecimal(getSqlParser().getLexer().getCurrentToken().getLiterals()).setScale(0, BigDecimal.ROUND_HALF_UP).intValue();
offset = roundHalfUp(getSqlParser().getLexer().getCurrentToken().getLiterals());
offsetBeginPosition = offsetBeginPosition - (offset + "").length();
getSelectStatement().getSqlTokens().add(new OffsetLimitToken(offsetBeginPosition, offset));
} else if (getSqlParser().equalAny(Symbol.QUESTION)) {
......@@ -122,9 +124,9 @@ public class PostgreSQLSelectParser extends AbstractSelectParser {
Limit limit;
// TODO 需处理只有OFFSET情况
if (hasOffset && hasLimit) {
limit = new Limit(offset, rowCount, offsetParameterIndex, rowCountParameterIndex);
limit = new Limit(new OffsetLimit(offset, offsetParameterIndex), new RowCountLimit(rowCount, rowCountParameterIndex));
} else {
limit = new Limit(rowCount, rowCountParameterIndex);
limit = new Limit(new RowCountLimit(rowCount, rowCountParameterIndex));
}
getSelectStatement().setLimit(limit);
}
......
......@@ -25,10 +25,12 @@ import com.dangdang.ddframe.rdb.sharding.parsing.lexer.token.Literals;
import com.dangdang.ddframe.rdb.sharding.parsing.lexer.token.Symbol;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.SQLParser;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.Limit;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.OffsetLimit;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.RowCountLimit;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.Top;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.statement.select.SelectStatement;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.exception.SQLParsingException;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.exception.SQLParsingUnsupportedException;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.statement.select.SelectStatement;
/**
* SQLServer解析器.
......@@ -107,9 +109,9 @@ public final class SQLServerParser extends SQLParser {
}
getLexer().nextToken();
getLexer().nextToken();
limit = new Limit(offset, rowCount, offsetIndex, rowCountIndex);
limit = new Limit(new OffsetLimit(offset, offsetIndex), new RowCountLimit(rowCount, rowCountIndex));
} else {
limit = new Limit(offset, offsetIndex);
limit = new Limit(new OffsetLimit(offset, offsetIndex));
}
selectStatement.setLimit(limit);
}
......
/*
* 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.util;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import java.math.BigDecimal;
/**
* 数字工具类.
*
* @author caohao
*/
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public final class NumberUtil {
/**
* 将字符串四舍五入并转换为整形.
*
* @param str 待转换的字符串
* @return 四舍五入后的整形值
*/
public static int roundHalfUp(final String str) {
return new BigDecimal(str).setScale(0, BigDecimal.ROUND_HALF_UP).intValue();
}
}
......@@ -20,6 +20,8 @@ package com.dangdang.ddframe.rdb.sharding.merger.pipeline.reducer;
import com.dangdang.ddframe.rdb.sharding.merger.ResultSetFactory;
import com.dangdang.ddframe.rdb.sharding.merger.fixture.MockResultSet;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.Limit;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.OffsetLimit;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.RowCountLimit;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.statement.SQLStatement;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.statement.select.SelectStatement;
import org.junit.Test;
......@@ -47,7 +49,7 @@ public final class IteratorResultSetTest {
@Test
public void assertNextWithLimitForAllData() throws SQLException {
SQLStatement selectStatement = new SelectStatement();
selectStatement.setLimit(new Limit(1, 10, -1, -1));
selectStatement.setLimit(new Limit(new OffsetLimit(1, -1), new RowCountLimit(10, -1)));
ResultSet resultSet = ResultSetFactory.getResultSet(Arrays.<ResultSet>asList(new MockResultSet<>(1), new MockResultSet<>(2, 4), new MockResultSet<Integer>()), selectStatement);
int count = 0;
while (resultSet.next()) {
......@@ -59,7 +61,7 @@ public final class IteratorResultSetTest {
@Test
public void assertNextWithLimitForPartData() throws SQLException {
SQLStatement selectStatement = new SelectStatement();
selectStatement.setLimit(new Limit(1, 1, -1, -1));
selectStatement.setLimit(new Limit(new OffsetLimit(1, -1), new RowCountLimit(1, -1)));
ResultSet resultSet = ResultSetFactory.getResultSet(Arrays.<ResultSet>asList(new MockResultSet<>(1), new MockResultSet<>(2, 4), new MockResultSet<Integer>()), selectStatement);
int count = 0;
while (resultSet.next()) {
......
......@@ -26,6 +26,8 @@ import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.OrderBy;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.condition.Condition;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.condition.Conditions;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.Limit;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.OffsetLimit;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.limit.RowCountLimit;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.selectitem.AggregationSelectItem;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.table.Table;
import com.dangdang.ddframe.rdb.sharding.parsing.parser.context.table.Tables;
......@@ -200,9 +202,9 @@ public abstract class AbstractBaseParseTest {
if (null != assertObj.getLimit()) {
if (null != assertObj.getLimit().getOffset() && null != assertObj.getLimit().getOffsetParameterIndex()) {
selectStatement.setLimit(new Limit(
assertObj.getLimit().getOffset(), assertObj.getLimit().getRowCount(), assertObj.getLimit().getOffsetParameterIndex(), assertObj.getLimit().getRowCountParameterIndex()));
new OffsetLimit(assertObj.getLimit().getOffset(), assertObj.getLimit().getOffsetParameterIndex()), new RowCountLimit(assertObj.getLimit().getRowCount(), assertObj.getLimit().getRowCountParameterIndex())));
} else {
selectStatement.setLimit(new Limit(assertObj.getLimit().getRowCount(), assertObj.getLimit().getRowCountParameterIndex()));
selectStatement.setLimit(new Limit(new RowCountLimit(assertObj.getLimit().getRowCount(), assertObj.getLimit().getRowCountParameterIndex())));
}
}
result[4] = selectStatement;
......@@ -252,6 +254,13 @@ public abstract class AbstractBaseParseTest {
}
private void assertLimit(final SQLStatement actual) {
assertTrue(new ReflectionEquals(limit).matches(actual.getLimit()));
if (null != actual.getLimit()) {
if (null != actual.getLimit().getOffsetLimit()) {
assertTrue(new ReflectionEquals(limit.getOffsetLimit()).matches(actual.getLimit().getOffsetLimit()));
}
if (null != actual.getLimit().getRowCountLimit()) {
assertTrue(new ReflectionEquals(limit.getRowCountLimit()).matches(actual.getLimit().getRowCountLimit()));
}
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册