Skip to content

Commit

Permalink
for #920, encapsulate closure to InlineExpressionParser
Browse files Browse the repository at this point in the history
  • Loading branch information
terrymanu committed Jun 8, 2018
1 parent bbae27c commit c75a67f
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

package io.shardingsphere.core.routing.strategy.inline;

import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import groovy.lang.Closure;
import groovy.util.Expando;
Expand All @@ -26,7 +25,6 @@
import io.shardingsphere.core.api.algorithm.sharding.ShardingValue;
import io.shardingsphere.core.api.config.strategy.InlineShardingStrategyConfiguration;
import io.shardingsphere.core.routing.strategy.ShardingStrategy;
import io.shardingsphere.core.util.GroovyUtil;
import io.shardingsphere.core.util.InlineExpressionParser;

import java.util.ArrayList;
Expand All @@ -51,7 +49,7 @@ public InlineShardingStrategy(final InlineShardingStrategyConfiguration inlineSh
Preconditions.checkNotNull(inlineShardingStrategyConfig.getAlgorithmExpression(), "Sharding algorithm expression cannot be null.");
shardingColumn = inlineShardingStrategyConfig.getShardingColumn();
String algorithmExpression = InlineExpressionParser.handlePlaceHolder(inlineShardingStrategyConfig.getAlgorithmExpression().trim());
closure = (Closure) GroovyUtil.evaluate(Joiner.on("").join("{it -> \"", algorithmExpression, "\"}"));
closure = new InlineExpressionParser(algorithmExpression).evaluateClosure();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public final class TableRule {
public TableRule(final TableRuleConfiguration tableRuleConfig, final ShardingDataSourceNames shardingDataSourceNames) {
Preconditions.checkNotNull(tableRuleConfig.getLogicTable(), "Logic table cannot be null.");
logicTable = tableRuleConfig.getLogicTable().toLowerCase();
List<String> dataNodes = new InlineExpressionParser(tableRuleConfig.getActualDataNodes()).evaluate();
List<String> dataNodes = new InlineExpressionParser(tableRuleConfig.getActualDataNodes()).splitAndEvaluate();
actualDataNodes = isEmptyDataNodes(dataNodes)
? generateDataNodes(tableRuleConfig.getLogicTable(), shardingDataSourceNames.getDataSourceNames()) : generateDataNodes(dataNodes, shardingDataSourceNames.getDataSourceNames());
databaseShardingStrategy = null == tableRuleConfig.getDatabaseShardingStrategyConfig() ? null : ShardingStrategyFactory.newInstance(tableRuleConfig.getDatabaseShardingStrategyConfig());
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,21 @@
package io.shardingsphere.core.util;

import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.Collections2;
import com.google.common.collect.Sets;
import groovy.lang.Closure;
import groovy.lang.GString;
import groovy.lang.GroovyShell;
import groovy.lang.Script;
import lombok.RequiredArgsConstructor;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
Expand All @@ -40,12 +46,17 @@ public final class InlineExpressionParser {

private static final char SPLITTER = ',';

private static final Map<String, Script> SCRIPTS = new HashMap<>();

private static final GroovyShell SHELL = new GroovyShell();

private final String inlineExpression;

/**
* Replace all the inlineExpression placeholders.
* @param inlineExpression inlineExpression
* @return result inlineExpression
* Replace all inline expression placeholders.
*
* @param inlineExpression inline expression with {@code $->}
* @return result inline expression with {@code $}
*/
public static String handlePlaceHolder(final String inlineExpression) {
return inlineExpression.contains("$->{") ? inlineExpression.replaceAll("\\$->\\{", "\\$\\{") : inlineExpression;
Expand All @@ -56,13 +67,22 @@ public static String handlePlaceHolder(final String inlineExpression) {
*
* @return result list
*/
public List<String> evaluate() {
public List<String> splitAndEvaluate() {
if (null == inlineExpression) {
return Collections.emptyList();
}
return flatten(evaluate(split()));
}

/**
* Evaluate closure.
*
* @return closure
*/
public Closure<?> evaluateClosure() {
return (Closure) evaluate(Joiner.on("").join("{it -> \"", inlineExpression, "\"}"));
}

private List<Object> evaluate(final List<String> inlineExpressions) {
List<Object> result = new ArrayList<>(inlineExpressions.size());
for (String each : inlineExpressions) {
Expand All @@ -73,11 +93,22 @@ private List<Object> evaluate(final List<String> inlineExpressions) {
if (!each.endsWith("\"")) {
expression.append("\"");
}
result.add(GroovyUtil.evaluate(expression.toString()));
result.add(evaluate(expression.toString()));
}
return result;
}

private Object evaluate(final String expression) {
Script script;
if (SCRIPTS.containsKey(expression)) {
script = SCRIPTS.get(expression);
} else {
script = SHELL.parse(expression);
SCRIPTS.put(expression, script);
}
return script.run();
}

private List<String> split() {
List<String> result = new ArrayList<>();
StringBuilder segment = new StringBuilder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,62 +30,62 @@ public final class InlineExpressionParserTest {

@Test
public void assertEvaluateForExpressionIsNull() {
List<String> expected = new InlineExpressionParser(null).evaluate();
List<String> expected = new InlineExpressionParser(null).splitAndEvaluate();
assertThat(expected, is(Collections.<String>emptyList()));
}

@Test
public void assertEvaluateForSimpleString() {
List<String> expected = new InlineExpressionParser(" t_order_0, t_order_1 ").evaluate();
List<String> expected = new InlineExpressionParser(" t_order_0, t_order_1 ").splitAndEvaluate();
assertThat(expected.size(), is(2));
assertThat(expected, hasItems("t_order_0", "t_order_1"));
}

@Test
public void assertEvaluateForNull() {
List<String> expected = new InlineExpressionParser("t_order_${null}").evaluate();
List<String> expected = new InlineExpressionParser("t_order_${null}").splitAndEvaluate();
assertThat(expected.size(), is(1));
assertThat(expected, hasItems("t_order_"));
}

@Test
public void assertEvaluateForLiteral() {
List<String> expected = new InlineExpressionParser("t_order_${'xx'}").evaluate();
List<String> expected = new InlineExpressionParser("t_order_${'xx'}").splitAndEvaluate();
assertThat(expected.size(), is(1));
assertThat(expected, hasItems("t_order_xx"));
}

@Test
public void assertEvaluateForArray() {
List<String> expected = new InlineExpressionParser("t_order_${[0, 1, 2]},t_order_item_${[0, 2]}").evaluate();
List<String> expected = new InlineExpressionParser("t_order_${[0, 1, 2]},t_order_item_${[0, 2]}").splitAndEvaluate();
assertThat(expected.size(), is(5));
assertThat(expected, hasItems("t_order_0", "t_order_1", "t_order_2", "t_order_item_0", "t_order_item_2"));
}

@Test
public void assertEvaluateForRange() {
List<String> expected = new InlineExpressionParser("t_order_${0..2},t_order_item_${0..1}").evaluate();
List<String> expected = new InlineExpressionParser("t_order_${0..2},t_order_item_${0..1}").splitAndEvaluate();
assertThat(expected.size(), is(5));
assertThat(expected, hasItems("t_order_0", "t_order_1", "t_order_2", "t_order_item_0", "t_order_item_1"));
}

@Test
public void assertEvaluateForComplex() {
List<String> expected = new InlineExpressionParser("t_${['new','old']}_order_${1..2}, t_config").evaluate();
List<String> expected = new InlineExpressionParser("t_${['new','old']}_order_${1..2}, t_config").splitAndEvaluate();
assertThat(expected.size(), is(5));
assertThat(expected, hasItems("t_new_order_1", "t_new_order_2", "t_old_order_1", "t_old_order_2", "t_config"));
}

@Test
public void assertEvaluateForCalculate() {
List<String> expected = new InlineExpressionParser("t_${[\"new${1+2}\",'old']}_order_${1..2}").evaluate();
List<String> expected = new InlineExpressionParser("t_${[\"new${1+2}\",'old']}_order_${1..2}").splitAndEvaluate();
assertThat(expected.size(), is(4));
assertThat(expected, hasItems("t_new3_order_1", "t_new3_order_2", "t_old_order_1", "t_old_order_2"));
}

@Test
public void assertEvaluateForExpressionPlaceHolder() {
List<String> expected = new InlineExpressionParser("t_$->{[\"new$->{1+2}\",'old']}_order_$->{1..2}").evaluate();
List<String> expected = new InlineExpressionParser("t_$->{[\"new$->{1+2}\",'old']}_order_$->{1..2}").splitAndEvaluate();
assertThat(expected.size(), is(4));
assertThat(expected, hasItems("t_new3_order_1", "t_new3_order_2", "t_old_order_1", "t_old_order_2"));
}
Expand All @@ -102,7 +102,7 @@ public void assertEvaluateForLong() {
expression.append(",");
}
}
List<String> expected = new InlineExpressionParser(expression.toString()).evaluate();
List<String> expected = new InlineExpressionParser(expression.toString()).splitAndEvaluate();
assertThat(expected.size(), is(1024));
assertThat(expected, hasItems("ds_0.t_user_0", "ds_15.t_user_1023"));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public final class DataSetsRoot {
*/
public DataSetMetadata findDataSetMetadata(final DataNode dataNode) {
for (DataSetMetadata each : metadataList) {
if (contains(new InlineExpressionParser(each.getDataNodes()).evaluate(), dataNode)) {
if (contains(new InlineExpressionParser(each.getDataNodes()).splitAndEvaluate(), dataNode)) {
return each;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ private void assertDataSet() throws SQLException, IOException, JAXBException {
}
assertThat("Only support single table for DML.", expected.getMetadataList().size(), is(1));
DataSetMetadata expectedDataSetMetadata = expected.getMetadataList().get(0);
for (String each : new InlineExpressionParser(expectedDataSetMetadata.getDataNodes()).evaluate()) {
for (String each : new InlineExpressionParser(expectedDataSetMetadata.getDataNodes()).splitAndEvaluate()) {
DataNode dataNode = new DataNode(each);
try (Connection connection = getDataSourceMap().get(dataNode.getDataSourceName()).getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(String.format("SELECT * FROM %s", dataNode.getTableName()))) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ private Map<String, Collection<String>> getDataNodeMap() {

private Map<String, Collection<String>> getDataNodeMap(final DataSetMetadata dataSetMetadata) {
Map<String, Collection<String>> result = new LinkedHashMap<>();
for (String each : new InlineExpressionParser(dataSetMetadata.getDataNodes()).evaluate()) {
for (String each : new InlineExpressionParser(dataSetMetadata.getDataNodes()).splitAndEvaluate()) {
DataNode dataNode = new DataNode(each);
if (!result.containsKey(dataNode.getDataSourceName())) {
result.put(dataNode.getDataSourceName(), new LinkedList<String>());
Expand Down

0 comments on commit c75a67f

Please sign in to comment.