private List<DataNode> generateDataNodes(final List<String> actualDataNodes, final Collection<String> dataSourceNames) { List<DataNode> result = new LinkedList<>(); int index = 0; for (String each : actualDataNodes) { DataNode dataNode = new DataNode(each); if (!dataSourceNames.contains(dataNode.getDataSourceName())) { throw new ShardingException("Cannot find data source in sharding rule, invalid actual data node is: '%s'", each); } result.add(dataNode); dataNodeIndexMap.put(dataNode, index); index++; } return result; }
/** * Get actual table names via target data source name. * * @param targetDataSource target data source name * @return names of actual tables */ public Collection<String> getActualTableNames(final String targetDataSource) { Collection<String> result = new LinkedHashSet<>(actualDataNodes.size()); for (DataNode each : actualDataNodes) { if (targetDataSource.equals(each.getDataSourceName())) { result.add(each.getTableName()); } } return result; }
/** * Constructs a data node with well-formatted string. * * @param dataNode string of data node. use {@code .} to split data source name and table name. */ public DataNode(final String dataNode) { if (!isValidDataNode(dataNode)) { throw new ShardingConfigurationException("Invalid format for actual data nodes: '%s'", dataNode); } List<String> segments = Splitter.on(DELIMITER).splitToList(dataNode); dataSourceName = segments.get(0); tableName = segments.get(1); }
int findActualTableIndex(final String dataSourceName, final String actualTableName) { DataNode dataNode = new DataNode(dataSourceName, actualTableName); return dataNodeIndexMap.containsKey(dataNode) ? dataNodeIndexMap.get(dataNode) : -1; }
/** * Get actual data source names. * * @return actual data source names */ public Collection<String> getActualDatasourceNames() { Collection<String> result = new LinkedHashSet<>(actualDataNodes.size()); for (DataNode each : actualDataNodes) { result.add(each.getDataSourceName()); } return result; }
boolean isExisted(final String actualTableName) { for (DataNode each : actualDataNodes) { if (each.getTableName().equalsIgnoreCase(actualTableName)) { return true; } } return false; } }
public TableRule(final String defaultDataSourceName, final String logicTableName) { logicTable = logicTableName.toLowerCase(); actualDataNodes = Collections.singletonList(new DataNode(defaultDataSourceName, logicTableName)); dataNodeIndexMap = Collections.emptyMap(); databaseShardingStrategy = null; tableShardingStrategy = null; generateKeyColumn = null; shardingKeyGenerator = null; shardingEncryptorStrategy = null; logicIndex = null; }
/** * Get data node groups. * * @return data node groups, key is data source name, value is tables belong to this data source */ public Map<String, List<DataNode>> getDataNodeGroups() { Map<String, List<DataNode>> result = new LinkedHashMap<>(actualDataNodes.size(), 1); for (DataNode each : actualDataNodes) { String dataSourceName = each.getDataSourceName(); if (!result.containsKey(dataSourceName)) { result.put(dataSourceName, new LinkedList<DataNode>()); } result.get(dataSourceName).add(each); } return result; }
private Collection<TableMetaData> load(final String dataSourceName, final String catalog, final Collection<DataNode> dataNodes) throws SQLException { Collection<TableMetaData> result = new LinkedList<>(); try (Connection connection = connectionManager.getConnection(dataSourceName)) { for (DataNode each : dataNodes) { result.add(new TableMetaData( isTableExist(connection, catalog, each.getTableName()) ? getColumnMetaDataList(connection, catalog, each.getTableName()) : Collections.<ColumnMetaData>emptyList())); } } return result; }
private Collection<TableUnit> getAllTableUnits(final String logicTableName) { Collection<TableUnit> result = new LinkedList<>(); TableRule tableRule = shardingRule.getTableRule(logicTableName); for (DataNode each : tableRule.getActualDataNodes()) { TableUnit tableUnit = new TableUnit(each.getDataSourceName()); tableUnit.getRoutingTables().add(new RoutingTable(logicTableName, each.getTableName())); result.add(tableUnit); } return result; } }
private List<DataNode> generateDataNodes(final String logicTable, final Collection<String> dataSourceNames) { List<DataNode> result = new LinkedList<>(); int index = 0; for (String each : dataSourceNames) { DataNode dataNode = new DataNode(each, logicTable); result.add(dataNode); dataNodeIndexMap.put(dataNode, index); index++; } return result; }
@Override public Collection<TableMetaData> execute(final Collection<DataNode> dataNodes, final boolean isTrunkThread, final Map<String, Object> shardingExecuteDataMap) throws SQLException { String dataSourceName = dataNodes.iterator().next().getDataSourceName(); DataSourceMetaData dataSourceMetaData = shardingDataSourceMetaData.getActualDataSourceMetaData(dataSourceName); String catalog = null == dataSourceMetaData ? null : dataSourceMetaData.getSchemaName(); return load(shardingDataSourceNames.getRawMasterDataSourceName(dataSourceName), catalog, dataNodes); } });
/** * Deduce actual table name from other actual table name in same binding table rule. * * @param dataSource data source name * @param logicTable logic table name * @param otherActualTable other actual table name in same binding table rule * @return actual table name */ public String getBindingActualTable(final String dataSource, final String logicTable, final String otherActualTable) { int index = -1; for (TableRule each : tableRules) { index = each.findActualTableIndex(dataSource, otherActualTable); if (-1 != index) { break; } } if (-1 == index) { throw new ShardingConfigurationException("Actual table [%s].[%s] is not in table config", dataSource, otherActualTable); } for (TableRule each : tableRules) { if (each.getLogicTable().equals(logicTable.toLowerCase())) { return each.getActualDataNodes().get(index).getTableName().toLowerCase(); } } throw new ShardingConfigurationException("Cannot find binding actual table, data source: %s, logic table: %s, other actual table: %s", dataSource, logicTable, otherActualTable); }
private void processInsertShardingCondition(final TableUnit tableUnit, final InsertShardingCondition shardingCondition, final List<String> expressions, final List<Object> parameters) { for (DataNode each : shardingCondition.getDataNodes()) { if (each.getDataSourceName().equals(tableUnit.getDataSourceName()) && each.getTableName().equals(tableUnit.getRoutingTables().iterator().next().getActualTableName())) { expressions.add(shardingCondition.getInsertValueExpression()); parameters.addAll(shardingCondition.getParameters()); return; } } if (shardingCondition.getDataNodes().isEmpty()) { expressions.add(shardingCondition.getInsertValueExpression()); parameters.addAll(shardingCondition.getParameters()); } } }
private Collection<DataNode> routeTables(final TableRule tableRule, final String routedDataSource, final List<ShardingValue> tableShardingValues) { Collection<String> availableTargetTables = tableRule.getActualTableNames(routedDataSource); Collection<String> routedTables = new LinkedHashSet<>(tableShardingValues.isEmpty() ? availableTargetTables : shardingRule.getTableShardingStrategy(tableRule).doSharding(availableTargetTables, tableShardingValues)); Preconditions.checkState(!routedTables.isEmpty(), "no table route info"); Collection<DataNode> result = new LinkedList<>(); for (String each : routedTables) { result.add(new DataNode(routedDataSource, each)); } return result; }
/** * Find data node by data source and logic table. * * @param dataSourceName data source name * @param logicTableName logic table name * @return data node */ public DataNode getDataNode(final String dataSourceName, final String logicTableName) { TableRule tableRule = getTableRule(logicTableName); for (DataNode each : tableRule.getActualDataNodes()) { if (shardingDataSourceNames.getDataSourceNames().contains(each.getDataSourceName()) && each.getDataSourceName().equals(dataSourceName)) { return each; } } throw new ShardingConfigurationException("Cannot find actual data node for data source name: '%s' and logic table name: '%s'", dataSourceName, logicTableName); }
private RoutingResult generateRoutingResult(final Collection<DataNode> routedDataNodes) { RoutingResult result = new RoutingResult(); for (DataNode each : routedDataNodes) { TableUnit tableUnit = new TableUnit(each.getDataSourceName()); tableUnit.getRoutingTables().add(new RoutingTable(logicTableName, each.getTableName())); result.getTableUnits().getTableUnits().add(tableUnit); } return result; }
String logicTableName = logicTables.iterator().next(); DataNode dataNode = shardingRule.getDataNode(logicTableName); TableUnit tableUnit = new TableUnit(dataNode.getDataSourceName()); tableUnit.getRoutingTables().add(new RoutingTable(logicTableName, dataNode.getTableName())); result.getTableUnits().getTableUnits().add(tableUnit); } else { TableRule tableRule = shardingRule.getTableRule(each); DataNode dataNode = tableRule.getActualDataNodes().get(0); routingTables.add(new RoutingTable(each, dataNode.getTableName())); Set<String> currentDataSourceNames = new HashSet<>(tableRule.getActualDatasourceNames().size()); for (DataNode eachDataNode : tableRule.getActualDataNodes()) { currentDataSourceNames.add(eachDataNode.getDataSourceName());