diff --git a/sharding-core/src/main/java/io/shardingjdbc/core/metadata/ShardingMetaData.java b/sharding-core/src/main/java/io/shardingjdbc/core/metadata/ShardingMetaData.java index 8d82136ce8587b867d9a6ccbffc84ac247faa5d1..974cde7eefd05afecde67daa7b8661393bfce3fb 100644 --- a/sharding-core/src/main/java/io/shardingjdbc/core/metadata/ShardingMetaData.java +++ b/sharding-core/src/main/java/io/shardingjdbc/core/metadata/ShardingMetaData.java @@ -22,7 +22,6 @@ import io.shardingjdbc.core.rule.DataNode; import io.shardingjdbc.core.rule.ShardingRule; import io.shardingjdbc.core.rule.TableRule; import lombok.Getter; - import java.sql.SQLException; import java.util.Collection; import java.util.HashMap; diff --git a/sharding-core/src/main/java/io/shardingjdbc/core/metadata/TableMetaData.java b/sharding-core/src/main/java/io/shardingjdbc/core/metadata/TableMetaData.java index b4824fe20b30af340522a64bfd4cc8b469d2a8eb..95f5c12c52f6bd53101c5d70ce7a36f5a2f68cca 100644 --- a/sharding-core/src/main/java/io/shardingjdbc/core/metadata/TableMetaData.java +++ b/sharding-core/src/main/java/io/shardingjdbc/core/metadata/TableMetaData.java @@ -20,7 +20,6 @@ package io.shardingjdbc.core.metadata; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.RequiredArgsConstructor; - import java.util.Collection; /** diff --git a/sharding-core/src/main/java/io/shardingjdbc/core/parsing/parser/clause/SelectListClauseParser.java b/sharding-core/src/main/java/io/shardingjdbc/core/parsing/parser/clause/SelectListClauseParser.java index f43c7f76efceed37c33758914affe3b8977977db..117c1c2756b07f4962392c9ee2da8bd873ab62c8 100644 --- a/sharding-core/src/main/java/io/shardingjdbc/core/parsing/parser/clause/SelectListClauseParser.java +++ b/sharding-core/src/main/java/io/shardingjdbc/core/parsing/parser/clause/SelectListClauseParser.java @@ -83,7 +83,10 @@ public class SelectListClauseParser implements SQLClauseParser { result = parseAggregationSelectItem(selectStatement); parseRestSelectItem(selectStatement); } else { - result = new CommonSelectItem(SQLUtil.getExactlyValue(parseCommonSelectItem(selectStatement) + parseRestSelectItem(selectStatement)), aliasExpressionParser.parseSelectItemAlias()); + SelectItem selectItem = parseCommonOrStarSelectItem(selectStatement); + result = selectItem instanceof StarSelectItem ? selectItem + : new CommonSelectItem(SQLUtil.getExactlyValue(selectItem.getExpression() + + parseRestSelectItem(selectStatement)), aliasExpressionParser.parseSelectItemAlias()); } return result; } @@ -110,17 +113,13 @@ public class SelectListClauseParser implements SQLClauseParser { return new StarSelectItem(Optional.absent()); } - private boolean isAggregationSelectItem() { - return lexerEngine.equalAny(DefaultKeyword.MAX, DefaultKeyword.MIN, DefaultKeyword.SUM, DefaultKeyword.AVG, DefaultKeyword.COUNT); - } - - private SelectItem parseAggregationSelectItem(final SelectStatement selectStatement) { - AggregationType aggregationType = AggregationType.valueOf(lexerEngine.getCurrentToken().getLiterals().toUpperCase()); + private SelectItem parseStarSelectItem(final String owner) { lexerEngine.nextToken(); - return new AggregationSelectItem(aggregationType, lexerEngine.skipParentheses(selectStatement), aliasExpressionParser.parseSelectItemAlias()); + aliasExpressionParser.parseSelectItemAlias(); + return new StarSelectItem(Optional.fromNullable(owner)); } - private String parseCommonSelectItem(final SelectStatement selectStatement) { + private SelectItem parseCommonOrStarSelectItem(final SelectStatement selectStatement) { String literals = lexerEngine.getCurrentToken().getLiterals(); int position = lexerEngine.getCurrentToken().getEndPosition() - literals.length(); StringBuilder result = new StringBuilder(); @@ -135,10 +134,24 @@ public class SelectListClauseParser implements SQLClauseParser { } result.append(lexerEngine.getCurrentToken().getLiterals()); lexerEngine.nextToken(); + if (lexerEngine.equalAny(Symbol.STAR)) { + return parseStarSelectItem(literals); + } result.append(lexerEngine.getCurrentToken().getLiterals()); lexerEngine.nextToken(); } - return result.toString(); + return new CommonSelectItem(result.toString(), Optional.absent()); + + } + + private boolean isAggregationSelectItem() { + return lexerEngine.equalAny(DefaultKeyword.MAX, DefaultKeyword.MIN, DefaultKeyword.SUM, DefaultKeyword.AVG, DefaultKeyword.COUNT); + } + + private SelectItem parseAggregationSelectItem(final SelectStatement selectStatement) { + AggregationType aggregationType = AggregationType.valueOf(lexerEngine.getCurrentToken().getLiterals().toUpperCase()); + lexerEngine.nextToken(); + return new AggregationSelectItem(aggregationType, lexerEngine.skipParentheses(selectStatement), aliasExpressionParser.parseSelectItemAlias()); } private String parseRestSelectItem(final SelectStatement selectStatement) { @@ -146,7 +159,8 @@ public class SelectListClauseParser implements SQLClauseParser { while (lexerEngine.equalAny(Symbol.getOperators())) { result.append(lexerEngine.getCurrentToken().getLiterals()); lexerEngine.nextToken(); - result.append(parseCommonSelectItem(selectStatement)); + SelectItem selectItem = parseCommonOrStarSelectItem(selectStatement); + result.append(selectItem.getExpression()); } return result.toString(); } diff --git a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/jdbc/core/ShardingContext.java b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/jdbc/core/ShardingContext.java index 596f7b9a4536b2ccb5ac985ee96f2ad594b994a7..c98ff72b8a674bf0161967d754417b39711917d4 100644 --- a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/jdbc/core/ShardingContext.java +++ b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/jdbc/core/ShardingContext.java @@ -19,6 +19,7 @@ package io.shardingjdbc.core.jdbc.core; import io.shardingjdbc.core.constant.DatabaseType; import io.shardingjdbc.core.executor.ExecutorEngine; +import io.shardingjdbc.core.metadata.ShardingMetaData; import io.shardingjdbc.core.rule.ShardingRule; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -30,6 +31,7 @@ import java.util.Map; * Sharding runtime context. * * @author gaohongtao + * @author panjuan */ @RequiredArgsConstructor @Getter @@ -43,5 +45,7 @@ public final class ShardingContext { private final ExecutorEngine executorEngine; + private final ShardingMetaData shardingMetaData; + private final boolean showSQL; } diff --git a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/jdbc/core/datasource/ShardingDataSource.java b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/jdbc/core/datasource/ShardingDataSource.java index 345cf3bf8c4ac45006b6079ea32aa785da31cbd3..6aefe6f8fa93a002384500a844e7b0c5c532bbf2 100644 --- a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/jdbc/core/datasource/ShardingDataSource.java +++ b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/jdbc/core/datasource/ShardingDataSource.java @@ -20,10 +20,13 @@ package io.shardingjdbc.core.jdbc.core.datasource; import io.shardingjdbc.core.api.ConfigMapContext; import io.shardingjdbc.core.constant.ShardingProperties; import io.shardingjdbc.core.constant.ShardingPropertiesConstant; +import io.shardingjdbc.core.exception.ShardingJdbcException; import io.shardingjdbc.core.executor.ExecutorEngine; import io.shardingjdbc.core.jdbc.adapter.AbstractDataSourceAdapter; import io.shardingjdbc.core.jdbc.core.ShardingContext; import io.shardingjdbc.core.jdbc.core.connection.ShardingConnection; +import io.shardingjdbc.core.jdbc.metadata.JDBCShardingMetaData; +import io.shardingjdbc.core.metadata.ShardingMetaData; import io.shardingjdbc.core.rule.ShardingRule; import lombok.Getter; @@ -59,8 +62,10 @@ public class ShardingDataSource extends AbstractDataSourceAdapter implements Aut shardingProperties = new ShardingProperties(null == props ? new Properties() : props); int executorSize = shardingProperties.getValue(ShardingPropertiesConstant.EXECUTOR_SIZE); executorEngine = new ExecutorEngine(executorSize); + ShardingMetaData shardingMetaData = new JDBCShardingMetaData(dataSourceMap, getDatabaseType()); + shardingMetaData.init(shardingRule); boolean showSQL = shardingProperties.getValue(ShardingPropertiesConstant.SQL_SHOW); - shardingContext = new ShardingContext(dataSourceMap, shardingRule, getDatabaseType(), executorEngine, showSQL); + shardingContext = new ShardingContext(dataSourceMap, shardingRule, getDatabaseType(), executorEngine, shardingMetaData, showSQL); } /** @@ -80,8 +85,15 @@ public class ShardingDataSource extends AbstractDataSourceAdapter implements Aut originalExecutorEngine.close(); } boolean newShowSQL = newShardingProperties.getValue(ShardingPropertiesConstant.SQL_SHOW); + ShardingMetaData shardingMetaData = new JDBCShardingMetaData(newDataSourceMap, getDatabaseType()); + try { + shardingMetaData.init(newShardingRule); + } catch (SQLException ex) { + throw new ShardingJdbcException(ex); + } + shardingProperties = newShardingProperties; - shardingContext = new ShardingContext(newDataSourceMap, newShardingRule, getDatabaseType(), executorEngine, newShowSQL); + shardingContext = new ShardingContext(newDataSourceMap, newShardingRule, getDatabaseType(), executorEngine, shardingMetaData, newShowSQL); } @Override diff --git a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/jdbc/metadata/JDBCShardingMetaData.java b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/jdbc/metadata/JDBCShardingMetaData.java index 192f53cbe215ad1e03731d263276ace19807c0ee..4c9faa8b02b5ab3e8c844037974d7b7fd88ca9e7 100644 --- a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/jdbc/metadata/JDBCShardingMetaData.java +++ b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/jdbc/metadata/JDBCShardingMetaData.java @@ -17,6 +17,7 @@ package io.shardingjdbc.core.jdbc.metadata; +import io.shardingjdbc.core.constant.DatabaseType; import io.shardingjdbc.core.metadata.ColumnMetaData; import io.shardingjdbc.core.metadata.ShardingMetaData; import io.shardingjdbc.core.rule.DataNode; @@ -28,7 +29,7 @@ import java.util.Collection; import java.util.Map; /** - * Sharding metadata. + * Sharding metadata for JDBC. * * @author panjuan */ @@ -38,9 +39,11 @@ public final class JDBCShardingMetaData extends ShardingMetaData { private final Map dataSourceMap; + private final DatabaseType databaseType; + @Override protected Collection getColumnMetaDataList(final DataNode dataNode) throws SQLException { - return ShardingMetaDataHandlerFactory.newInstance(dataSourceMap.get(dataNode.getDataSourceName()), dataNode.getTableName()).getColumnMetaDataList(); + return ShardingMetaDataHandlerFactory.newInstance(dataSourceMap.get(dataNode.getDataSourceName()), dataNode.getTableName(), databaseType).getColumnMetaDataList(); } } diff --git a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/jdbc/metadata/ShardingMetaDataHandlerFactory.java b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/jdbc/metadata/ShardingMetaDataHandlerFactory.java index 4b4701db9ace52501966db83835330a30b7d7974..68dd511631f3e9dd2d9236c2fe73d9599b017e75 100644 --- a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/jdbc/metadata/ShardingMetaDataHandlerFactory.java +++ b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/jdbc/metadata/ShardingMetaDataHandlerFactory.java @@ -18,11 +18,11 @@ package io.shardingjdbc.core.jdbc.metadata; import io.shardingjdbc.core.constant.DatabaseType; +import io.shardingjdbc.core.jdbc.metadata.dialect.DefaultShardingMetaDataHandler; import io.shardingjdbc.core.jdbc.metadata.dialect.MySQLShardingMetaDataHandler; import io.shardingjdbc.core.jdbc.metadata.dialect.ShardingMetaDataHandler; import lombok.AccessLevel; import lombok.NoArgsConstructor; - import javax.sql.DataSource; import java.sql.SQLException; @@ -39,16 +39,16 @@ public final class ShardingMetaDataHandlerFactory { * * @param dataSource data source. * @param actualTableName actual table name. + * @param databaseType database type. * @return abstract table metadata handler. * @throws SQLException SQL exception. */ - public static ShardingMetaDataHandler newInstance(final DataSource dataSource, final String actualTableName) throws SQLException { - DatabaseType databaseType = DatabaseType.valueFrom(dataSource.getConnection().getMetaData().getDatabaseProductName()); + public static ShardingMetaDataHandler newInstance(final DataSource dataSource, final String actualTableName, final DatabaseType databaseType) throws SQLException { switch (databaseType) { case MySQL: return new MySQLShardingMetaDataHandler(dataSource, actualTableName); default: - throw new UnsupportedOperationException(String.format("Cannot support database [%s].", databaseType)); + return new DefaultShardingMetaDataHandler(dataSource, actualTableName); } } } diff --git a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/jdbc/metadata/dialect/DefaultShardingMetaDataHandler.java b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/jdbc/metadata/dialect/DefaultShardingMetaDataHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..1e85a34b38393f685fa89ea0c2c2188b114c37d3 --- /dev/null +++ b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/jdbc/metadata/dialect/DefaultShardingMetaDataHandler.java @@ -0,0 +1,42 @@ +/* + * Copyright 1999-2015 dangdang.com. + *

+ * 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. + *

+ */ + +package io.shardingjdbc.core.jdbc.metadata.dialect; + +import io.shardingjdbc.core.metadata.ColumnMetaData; + +import javax.sql.DataSource; +import java.sql.SQLException; +import java.util.Collection; +import java.util.LinkedList; + +/** + * MySQL table metadata handler. + * + * @author panjuan + */ +public final class DefaultShardingMetaDataHandler extends ShardingMetaDataHandler { + + public DefaultShardingMetaDataHandler(final DataSource dataSource, final String actualTableName) { + super(dataSource, actualTableName); + } + + @Override + public Collection getColumnMetaDataList() throws SQLException { + return new LinkedList<>(); + } +} diff --git a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/jdbc/metadata/dialect/MySQLShardingMetaDataHandler.java b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/jdbc/metadata/dialect/MySQLShardingMetaDataHandler.java index e0e0aafd7e393adb64c668f134b711e757719c19..2842e484490b5a9a70babab4db078d97c9770390 100644 --- a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/jdbc/metadata/dialect/MySQLShardingMetaDataHandler.java +++ b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/jdbc/metadata/dialect/MySQLShardingMetaDataHandler.java @@ -19,6 +19,7 @@ package io.shardingjdbc.core.jdbc.metadata.dialect; import io.shardingjdbc.core.metadata.ColumnMetaData; import javax.sql.DataSource; +import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; @@ -40,9 +41,9 @@ public final class MySQLShardingMetaDataHandler extends ShardingMetaDataHandler @Override public Collection getColumnMetaDataList() throws SQLException { List result = new LinkedList<>(); - try (Statement statement = getDataSource().getConnection().createStatement()) { - statement.executeQuery(String.format("desc %s;", getActualTableName())); - ResultSet resultSet = statement.getResultSet(); + try (Connection connection = getDataSource().getConnection(); + Statement statement = connection.createStatement()) { + ResultSet resultSet = statement.executeQuery(String.format("desc %s;", getActualTableName())); while (resultSet.next()) { result.add(new ColumnMetaData(resultSet.getString("Field"), resultSet.getString("Type"), resultSet.getString("Key"))); } diff --git a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/jdbc/metadata/dialect/ShardingMetaDataHandler.java b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/jdbc/metadata/dialect/ShardingMetaDataHandler.java index ca15f78b6dc8cc0e48238de1485bf31f7e1b2ebc..13ae215775310508922fe321081f26172cadc623 100644 --- a/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/jdbc/metadata/dialect/ShardingMetaDataHandler.java +++ b/sharding-jdbc-core/src/main/java/io/shardingjdbc/core/jdbc/metadata/dialect/ShardingMetaDataHandler.java @@ -21,7 +21,6 @@ import io.shardingjdbc.core.jdbc.core.datasource.MasterSlaveDataSource; import io.shardingjdbc.core.metadata.ColumnMetaData; import lombok.AccessLevel; import lombok.Getter; - import javax.sql.DataSource; import java.sql.SQLException; import java.util.Collection; diff --git a/sharding-jdbc-core/src/test/java/io/shardingjdbc/core/jdbc/core/connection/ShardingConnectionTest.java b/sharding-jdbc-core/src/test/java/io/shardingjdbc/core/jdbc/core/connection/ShardingConnectionTest.java index a96f72088df2918fee3cb52574395fe1dc02fe7b..18b217842a2330099c9e431038255980b1387d76 100644 --- a/sharding-jdbc-core/src/test/java/io/shardingjdbc/core/jdbc/core/connection/ShardingConnectionTest.java +++ b/sharding-jdbc-core/src/test/java/io/shardingjdbc/core/jdbc/core/connection/ShardingConnectionTest.java @@ -24,6 +24,8 @@ import io.shardingjdbc.core.constant.SQLType; import io.shardingjdbc.core.fixture.TestDataSource; import io.shardingjdbc.core.jdbc.core.ShardingContext; import io.shardingjdbc.core.jdbc.core.datasource.MasterSlaveDataSource; +import io.shardingjdbc.core.jdbc.metadata.JDBCShardingMetaData; +import io.shardingjdbc.core.metadata.ShardingMetaData; import io.shardingjdbc.core.rule.ShardingRule; import org.junit.After; import org.junit.Before; @@ -61,14 +63,15 @@ public final class ShardingConnectionTest { } @Before - public void setUp() { + public void setUp() throws SQLException { ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration(); TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration(); tableRuleConfig.setLogicTable("test"); shardingRuleConfig.getTableRuleConfigs().add(tableRuleConfig); Map dataSourceMap = new HashMap<>(1, 1); dataSourceMap.put(DS_NAME, masterSlaveDataSource); - ShardingContext shardingContext = new ShardingContext(dataSourceMap, new ShardingRule(shardingRuleConfig, dataSourceMap.keySet()), null, null, false); + ShardingMetaData shardingMetaData = new JDBCShardingMetaData(dataSourceMap, null); + ShardingContext shardingContext = new ShardingContext(dataSourceMap, new ShardingRule(shardingRuleConfig, dataSourceMap.keySet()), null, null, shardingMetaData, false); connection = new ShardingConnection(shardingContext); } diff --git a/sharding-jdbc-core/src/test/java/io/shardingjdbc/core/jdbc/core/datasource/ShardingDataSourceTest.java b/sharding-jdbc-core/src/test/java/io/shardingjdbc/core/jdbc/core/datasource/ShardingDataSourceTest.java index c88d769922a32d68b634dbdc2bf557e0027be1ce..4943919456e41a3a4d6ddd703877532a1291eeb5 100644 --- a/sharding-jdbc-core/src/test/java/io/shardingjdbc/core/jdbc/core/datasource/ShardingDataSourceTest.java +++ b/sharding-jdbc-core/src/test/java/io/shardingjdbc/core/jdbc/core/datasource/ShardingDataSourceTest.java @@ -27,25 +27,17 @@ import io.shardingjdbc.core.constant.ShardingPropertiesConstant; import io.shardingjdbc.core.executor.ExecutorEngine; import io.shardingjdbc.core.rule.ShardingRule; import org.junit.Test; +import org.mockito.ArgumentMatchers; import javax.sql.DataSource; import java.lang.reflect.Field; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.SQLException; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Properties; +import java.sql.*; +import java.util.*; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; public final class ShardingDataSourceTest { @@ -121,9 +113,13 @@ public final class ShardingDataSourceTest { DataSource result = mock(DataSource.class); Connection connection = mock(Connection.class); DatabaseMetaData databaseMetaData = mock(DatabaseMetaData.class); + Statement statement = mock(Statement.class); + ResultSet resultSet = mock(ResultSet.class); when(connection.getMetaData()).thenReturn(databaseMetaData); when(databaseMetaData.getDatabaseProductName()).thenReturn(dataBaseProductName); when(result.getConnection()).thenReturn(connection); + when(connection.createStatement()).thenReturn(statement); + when(statement.executeQuery(ArgumentMatchers.any())).thenReturn(resultSet); return result; } diff --git a/sharding-proxy/src/main/java/io/shardingjdbc/proxy/config/ShardingRuleRegistry.java b/sharding-proxy/src/main/java/io/shardingjdbc/proxy/config/ShardingRuleRegistry.java index e70c4cd99e314ae86720ec515e408595cf3d47f6..bd88c1d6a58d06953ff1c0cc07bac1798c17dca1 100644 --- a/sharding-proxy/src/main/java/io/shardingjdbc/proxy/config/ShardingRuleRegistry.java +++ b/sharding-proxy/src/main/java/io/shardingjdbc/proxy/config/ShardingRuleRegistry.java @@ -18,13 +18,16 @@ package io.shardingjdbc.proxy.config; import io.shardingjdbc.core.exception.ShardingJdbcException; +import io.shardingjdbc.core.metadata.ShardingMetaData; import io.shardingjdbc.core.rule.ShardingRule; import io.shardingjdbc.core.yaml.sharding.YamlShardingConfiguration; +import io.shardingjdbc.proxy.metadata.ProxyShardingMetaData; import lombok.Getter; import javax.sql.DataSource; import java.io.File; import java.io.IOException; +import java.sql.SQLException; import java.util.Collections; import java.util.Map; @@ -42,15 +45,23 @@ public final class ShardingRuleRegistry { private final ShardingRule shardingRule; + private final ShardingMetaData shardingMetaData; + private ShardingRuleRegistry() { YamlShardingConfiguration yamlShardingConfig; try { yamlShardingConfig = YamlShardingConfiguration.unmarshal(new File(getClass().getResource("/conf/sharding-config.yaml").getFile())); - } catch (IOException ex) { + } catch (final IOException ex) { throw new ShardingJdbcException(ex); } dataSourceMap = yamlShardingConfig.getDataSources(); shardingRule = yamlShardingConfig.getShardingRule(Collections.emptyList()); + try { + shardingMetaData = new ProxyShardingMetaData(dataSourceMap); + shardingMetaData.init(shardingRule); + } catch (final SQLException ex) { + throw new ShardingJdbcException(ex); + } } /** diff --git a/sharding-proxy/src/main/java/io/shardingjdbc/proxy/metadata/ProxyShardingMetaData.java b/sharding-proxy/src/main/java/io/shardingjdbc/proxy/metadata/ProxyShardingMetaData.java new file mode 100644 index 0000000000000000000000000000000000000000..4b95c34e6c717dd9a47f330c431f81b416f3d798 --- /dev/null +++ b/sharding-proxy/src/main/java/io/shardingjdbc/proxy/metadata/ProxyShardingMetaData.java @@ -0,0 +1,48 @@ +/* + * Copyright 1999-2015 dangdang.com. + *

+ * 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. + *

+ */ + +package io.shardingjdbc.proxy.metadata; + +import io.shardingjdbc.core.metadata.ColumnMetaData; +import io.shardingjdbc.core.metadata.ShardingMetaData; +import io.shardingjdbc.core.rule.DataNode; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import javax.sql.DataSource; +import java.sql.SQLException; +import java.util.Collection; +import java.util.Map; + +/** + * Sharding metadata for proxy. + * + * @author panjuan + */ +@RequiredArgsConstructor +@Getter +public final class ProxyShardingMetaData extends ShardingMetaData { + + private final Map dataSourceMap; + + @Override + protected Collection getColumnMetaDataList(final DataNode dataNode) throws SQLException { + return new ShardingMetaDataHandler(dataSourceMap.get(dataNode.getDataSourceName()), dataNode.getTableName()).getColumnMetaDataList(); + } +} + + diff --git a/sharding-proxy/src/main/java/io/shardingjdbc/proxy/metadata/ShardingMetaDataHandler.java b/sharding-proxy/src/main/java/io/shardingjdbc/proxy/metadata/ShardingMetaDataHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..f3182f75152c74af4e1ba079068ac1595b7d2266 --- /dev/null +++ b/sharding-proxy/src/main/java/io/shardingjdbc/proxy/metadata/ShardingMetaDataHandler.java @@ -0,0 +1,69 @@ +/* + * Copyright 1999-2015 dangdang.com. + *

+ * 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. + *

+ */ + +package io.shardingjdbc.proxy.metadata; + +import io.shardingjdbc.core.jdbc.core.datasource.MasterSlaveDataSource; +import io.shardingjdbc.core.metadata.ColumnMetaData; +import lombok.Getter; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; + +/** + * Sharding meta data handler. + * + * @author panjuan + */ +@Getter +public final class ShardingMetaDataHandler { + + private final DataSource dataSource; + + private final String actualTableName; + + public ShardingMetaDataHandler(final DataSource dataSource, final String actualTableName) { + this.dataSource = dataSource instanceof MasterSlaveDataSource + ? ((MasterSlaveDataSource) dataSource).getMasterDataSource().values().iterator().next() : dataSource; + this.actualTableName = actualTableName; + } + + /** + * Get column meta data list. + * + * @return column meta data list + * @throws SQLException SQL exception + */ + public Collection getColumnMetaDataList() throws SQLException { + List result = new LinkedList<>(); + try (Connection connection = getDataSource().getConnection(); + Statement statement = connection.createStatement()) { + statement.executeQuery(String.format("desc %s;", getActualTableName())); + ResultSet resultSet = statement.getResultSet(); + while (resultSet.next()) { + result.add(new ColumnMetaData(resultSet.getString("Field"), resultSet.getString("Type"), resultSet.getString("Key"))); + } + } + return result; + } +}