private Collection<TableRule> createTableRules(final ShardingRuleConfiguration shardingRuleConfig) { Collection<TableRuleConfiguration> tableRuleConfigurations = shardingRuleConfig.getTableRuleConfigs(); Collection<TableRule> result = new ArrayList<>(tableRuleConfigurations.size()); for (TableRuleConfiguration each : tableRuleConfigurations) { result.add(new TableRule(each, shardingDataSourceNames, getDefaultGenerateKeyColumn(shardingRuleConfig))); } return result; }
public TableRule(final Collection<String> dataSourceNames, final String logicTableName) { logicTable = logicTableName.toLowerCase(); dataNodeIndexMap = new HashMap<>(dataSourceNames.size(), 1); actualDataNodes = generateDataNodes(logicTableName, dataSourceNames); databaseShardingStrategy = null; tableShardingStrategy = null; generateKeyColumn = null; shardingKeyGenerator = null; shardingEncryptorStrategy = null; logicIndex = null; }
/** * Find data node by logic table name. * * @param logicTableName logic table name * @return data node */ public DataNode getDataNode(final String logicTableName) { TableRule tableRule = getTableRule(logicTableName); return tableRule.getActualDataNodes().get(0); }
/** * Find column of generated key. * * @param logicTableName logic table name * @return generated key's column */ public Optional<Column> findGenerateKeyColumn(final String logicTableName) { for (TableRule each : tableRules) { if (each.getLogicTable().equalsIgnoreCase(logicTableName) && null != each.getGenerateKeyColumn()) { return Optional.of(new Column(each.getGenerateKeyColumn(), logicTableName)); } } return Optional.absent(); }
/** * Get logic table name base on logic index name. * * @param logicIndexName logic index name * @return logic table name */ public String getLogicTableName(final String logicIndexName) { for (TableRule each : tableRules) { if (logicIndexName.equals(each.getLogicIndex())) { return each.getLogicTable(); } } throw new ShardingConfigurationException("Cannot find logic table name with logic index name: '%s'", logicIndexName); }
/** * 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); }
public TableRule(final TableRuleConfiguration tableRuleConfig, final ShardingDataSourceNames shardingDataSourceNames, final String defaultGenerateKeyColumn) { Preconditions.checkNotNull(tableRuleConfig.getLogicTable(), "Logic table cannot be null."); logicTable = tableRuleConfig.getLogicTable().toLowerCase(); List<String> dataNodes = new InlineExpressionParser(tableRuleConfig.getActualDataNodes()).splitAndEvaluate(); dataNodeIndexMap = new HashMap<>(dataNodes.size(), 1); actualDataNodes = isEmptyDataNodes(dataNodes) ? generateDataNodes(tableRuleConfig.getLogicTable(), shardingDataSourceNames.getDataSourceNames()) : generateDataNodes(dataNodes, shardingDataSourceNames.getDataSourceNames()); databaseShardingStrategy = null == tableRuleConfig.getDatabaseShardingStrategyConfig() ? null : ShardingStrategyFactory.newInstance(tableRuleConfig.getDatabaseShardingStrategyConfig()); tableShardingStrategy = null == tableRuleConfig.getTableShardingStrategyConfig() ? null : ShardingStrategyFactory.newInstance(tableRuleConfig.getTableShardingStrategyConfig()); generateKeyColumn = getGenerateKeyColumn(tableRuleConfig.getKeyGeneratorConfig(), defaultGenerateKeyColumn); shardingKeyGenerator = null == tableRuleConfig.getKeyGeneratorConfig() ? null : tableRuleConfig.getKeyGeneratorConfig().getKeyGenerator().orNull(); shardingEncryptorStrategy = null == tableRuleConfig.getEncryptorConfig() ? null : tableRuleConfig.getEncryptorConfig().getShardingEncryptorStrategy(); logicIndex = null == tableRuleConfig.getLogicIndex() ? null : tableRuleConfig.getLogicIndex().toLowerCase(); }
for (String each : logicTables) { 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());
private Collection<String> routeDataSources(final TableRule tableRule, final List<ShardingValue> databaseShardingValues) { Collection<String> availableTargetDatabases = tableRule.getActualDatasourceNames(); if (databaseShardingValues.isEmpty()) { return availableTargetDatabases; } Collection<String> result = new LinkedHashSet<>(shardingRule.getDatabaseShardingStrategy(tableRule).doSharding(availableTargetDatabases, databaseShardingValues)); Preconditions.checkState(!result.isEmpty(), "no database route info"); return result; }
/** * Get database sharding strategy. * * <p> * Use default database sharding strategy if not found. * </p> * * @param tableRule table rule * @return database sharding strategy */ public ShardingStrategy getDatabaseShardingStrategy(final TableRule tableRule) { return null == tableRule.getDatabaseShardingStrategy() ? defaultDatabaseShardingStrategy : tableRule.getDatabaseShardingStrategy(); }
private Map<String, List<DataNode>> getDataNodeGroups(final String logicTableName, final ShardingRule shardingRule) { Map<String, List<DataNode>> result = shardingRule.getTableRule(logicTableName).getDataNodeGroups(); if (isCheckingMetaData) { return result; } String firstKey = result.keySet().iterator().next(); return Collections.singletonMap(firstKey, Collections.singletonList(result.get(firstKey).get(0))); }
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; }
private void parseForceIndex(final String tableName, final SQLStatement sqlStatement) { boolean skipIfForce = lexerEngine.skipIfEqual(MySQLKeyword.FORCE) && this.lexerEngine.skipIfEqual(DefaultKeyword.INDEX); if (skipIfForce) { lexerEngine.accept(Symbol.LEFT_PAREN); do { lexerEngine.skipIfEqual(Symbol.COMMA); String literals = lexerEngine.getCurrentToken().getLiterals(); Preconditions.checkState(!Symbol.RIGHT_PAREN.getLiterals().equals(literals), "There is an error in the vicinity of the force index syntax."); if (literals.equals(shardingRule.getTableRule(tableName).getLogicIndex())) { int beginPosition = lexerEngine.getCurrentToken().getEndPosition() - literals.length(); sqlStatement.addSQLToken(new IndexToken(beginPosition, lexerEngine.getCurrentToken().getEndPosition() - 1, tableName)); } lexerEngine.nextToken(); } while (lexerEngine.skipIfEqual(Symbol.COMMA)); lexerEngine.accept(Symbol.RIGHT_PAREN); } }
/** * Get actual data source name. * * @param actualTableName actual table name * @return actual data source name */ public String getActualDataSourceName(final String actualTableName) { Optional<TableRule> tableRule = findTableRuleByActualTable(actualTableName); if (tableRule.isPresent()) { return tableRule.get().getActualDatasourceNames().iterator().next(); } if (!Strings.isNullOrEmpty(shardingDataSourceNames.getDefaultDataSourceName())) { return shardingDataSourceNames.getDefaultDataSourceName(); } throw new ShardingException("Cannot found actual data source name of '%s' in sharding rule.", actualTableName); }
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; } }
/** * Get table rule. * * @param logicTableName logic table name * @return table rule */ public TableRule getTableRule(final String logicTableName) { Optional<TableRule> tableRule = findTableRule(logicTableName); if (tableRule.isPresent()) { return tableRule.get(); } if (isBroadcastTable(logicTableName)) { return new TableRule(shardingDataSourceNames.getDataSourceNames(), logicTableName); } if (!Strings.isNullOrEmpty(shardingDataSourceNames.getDefaultDataSourceName())) { return new TableRule(shardingDataSourceNames.getDefaultDataSourceName(), logicTableName); } throw new ShardingConfigurationException("Cannot find table rule and default data source with logic table: '%s'", logicTableName); }
/** * 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); }