use of io.mycat.config.ShardingFunction in project Mycat2 by MyCATApache.
the class ShardingTableConfigVO method getShardingTableConfig.
@NotNull
public ShardingTableConfig getShardingTableConfig() {
String sql = this.createTableSQL.getText();
String shardingInfoText = this.shardingInfo.getText();
List<List> partitions = new ArrayList<>();
for (PartitionEntry item : partitionsView.getItems()) {
Partition partition = item.toPartition();
String targetName = partition.getTargetName();
String schema = partition.getSchema();
String table = partition.getTable();
Integer dbIndex = partition.getDbIndex();
Integer tableIndex = partition.getTableIndex();
Integer index = partition.getIndex();
if (tableIndex != null) {
partitions.add(Arrays.asList(targetName, schema, table, dbIndex, tableIndex, index));
} else {
partitions.add(Arrays.asList(targetName, schema, table));
}
}
ShardingFunction shardingFuntion = Json.decodeValue(shardingInfoText, ShardingFunction.class);
shardingTableConfig.setCreateTableSQL(sql);
shardingTableConfig.setFunction(shardingFuntion);
shardingTableConfig.setPartition(ShardingBackEndTableInfoConfig.builder().data(partitions).build());
return shardingTableConfig;
}
use of io.mycat.config.ShardingFunction in project Mycat2 by MyCATApache.
the class IndexShardingTableVO method toShardingTableConfig.
public ShardingTableConfig toShardingTableConfig() {
shardingTableConfig.setShardingIndexTables(Collections.emptyMap());
String sql = this.indexCreateTableSQL.getText();
String shardingInfoText = this.indexShardingInfo.getText();
List<List> partitions = new ArrayList<>();
for (PartitionEntry item : indexPartitionsView.getItems()) {
Partition partition = item.toPartition();
String targetName = partition.getTargetName();
String schema = partition.getSchema();
String table = partition.getTable();
Integer dbIndex = partition.getDbIndex();
Integer tableIndex = partition.getTableIndex();
Integer index = partition.getIndex();
partitions.add(Arrays.asList(targetName, schema, table, dbIndex, tableIndex, index));
}
ShardingFunction shardingFuntion;
if (!StringUtil.isEmpty(shardingInfoText)) {
shardingFuntion = Json.decodeValue(shardingInfoText, ShardingFunction.class);
} else {
shardingFuntion = new ShardingFunction();
}
shardingTableConfig.setCreateTableSQL(sql);
shardingTableConfig.setFunction(shardingFuntion);
shardingTableConfig.setPartition(ShardingBackEndTableInfoConfig.builder().data(partitions).build());
shardingTableConfig.setShardingIndexTables(Collections.emptyMap());
return shardingTableConfig;
}
use of io.mycat.config.ShardingFunction in project Mycat2 by MyCATApache.
the class AutoFunctionFactory method getTableFunction.
@SneakyThrows
public static final CustomRuleFunction getTableFunction(ShardingTableHandler tableHandler, ShardingFunction shardingFunction) {
Map<String, Object> properties = shardingFunction.getProperties();
int dbNum = Integer.parseInt(properties.getOrDefault("dbNum", 1).toString());
int tableNum = Integer.parseInt(properties.getOrDefault("tableNum", 1).toString());
int storeNum = Optional.ofNullable(properties.get("storeNum")).map(i -> Integer.parseInt(i.toString())).orElse(0);
boolean prototype = (storeNum == 0);
if (prototype) {
storeNum = 1;
}
Integer storeDbNum = Optional.ofNullable(properties.get("storeDbNum")).map(i -> Integer.parseInt(i.toString())).orElse(dbNum * tableNum / storeNum);
SQLMethodInvokeExpr tableMethod = converyToMethodExpr((String) properties.get("tableMethod"));
SQLMethodInvokeExpr dbMethod = converyToMethodExpr((String) properties.get("dbMethod"));
String sep = "/";
String erUniqueName = Optional.ofNullable(dbMethod).map(i -> i.getMethodName()).orElse("") + Optional.ofNullable(tableMethod).map(i -> i.getMethodName()).orElse("") + " storeNum:" + storeNum + " storeDbNum:" + storeDbNum + " dbNum:" + dbNum + " tableNum:" + tableNum;
ToIntFunction<Object> tableFunction = (o) -> 0;
Set<String> dbShardingKeys = new HashSet<>();
ToIntFunction<Object> dbFunction = (o) -> 0;
Set<String> tableShardingKeys = new HashSet<>();
String mappingFormat = (String) properties.computeIfAbsent("mappingFormat", (unused) -> String.join(sep, prototype ? "prototype" : "c${targetIndex}", tableHandler.getSchemaName() + "_${dbIndex}", tableHandler.getTableName() + ((!supportFlattenMapping(tableMethod, dbMethod)) ? "_${tableIndex}" : "_${index}")));
final boolean flattenMapping = mappingFormat.contains("${index}") && supportFlattenMapping(tableMethod, dbMethod);
boolean dbEnum = Optional.ofNullable(dbMethod).map(db -> {
return ENUM_RANGE.contains(SQLUtils.normalize(db.getMethodName().toUpperCase()));
}).orElse(false);
boolean tableEnum = Optional.ofNullable(tableMethod).map(tb -> {
return ENUM_RANGE.contains(SQLUtils.normalize(tb.getMethodName().toUpperCase()));
}).orElse(false);
if (dbMethod != null) {
int num = dbNum;
SQLMethodInvokeExpr methodInvokeExpr = dbMethod;
if (SQLUtils.nameEquals("HASH", methodInvokeExpr.getMethodName())) {
methodInvokeExpr.setMethodName("MOD_HASH");
}
if (SQLUtils.nameEquals("MOD_HASH", methodInvokeExpr.getMethodName())) {
String shardingKey = getShardingKey(methodInvokeExpr);
dbShardingKeys.add(shardingKey);
SimpleColumnInfo columnInfo = tableHandler.getColumnByName(shardingKey);
dbFunction = specilizeSingleModHash(num, columnInfo);
}
if (SQLUtils.nameEquals("UNI_HASH", methodInvokeExpr.getMethodName())) {
String shardingKey = getShardingKey(methodInvokeExpr);
dbShardingKeys.add(shardingKey);
SimpleColumnInfo columnInfo = tableHandler.getColumnByName(shardingKey);
dbFunction = specilizeSingleModHash(num, columnInfo);
}
if (SQLUtils.nameEquals("RIGHT_SHIFT", methodInvokeExpr.getMethodName())) {
String shardingKey = getShardingKey(methodInvokeExpr);
dbShardingKeys.add(shardingKey);
int shift = Integer.parseInt(getShardingKey(methodInvokeExpr, 1));
SimpleColumnInfo columnInfo = tableHandler.getColumnByName(shardingKey);
dbFunction = specilizeSingleRightShift(num, shift, columnInfo);
}
if (SQLUtils.nameEquals("RANGE_HASH", methodInvokeExpr.getMethodName())) {
String shardingKey1 = getShardingKey(methodInvokeExpr);
dbShardingKeys.add(shardingKey1);
String shardingKey2 = getShardingKey(methodInvokeExpr, 1);
dbShardingKeys.add(shardingKey2);
SimpleColumnInfo column1 = Objects.requireNonNull(tableHandler.getColumnByName(shardingKey1));
SimpleColumnInfo column2 = Objects.requireNonNull(tableHandler.getColumnByName(shardingKey2));
if (!column1.getType().equals(column2.getType())) {
throw new IllegalArgumentException(column1 + " and " + column2 + " type is different");
}
int n;
if (methodInvokeExpr.getArguments().size() > 2) {
n = Integer.parseInt(getShardingKey(methodInvokeExpr, 2));
} else {
n = 0;
}
dbFunction = specilizeSingleRangeHash(num, n, column1);
}
if (SQLUtils.nameEquals("YYYYMM", methodInvokeExpr.getMethodName())) {
String shardingKey = getShardingKey(methodInvokeExpr);
dbShardingKeys.add(shardingKey);
SimpleColumnInfo column1 = Objects.requireNonNull(tableHandler.getColumnByName(shardingKey));
dbFunction = specilizeyyyymm(num, column1);
}
if (SQLUtils.nameEquals("YYYYDD", methodInvokeExpr.getMethodName())) {
String shardingKey = getShardingKey(methodInvokeExpr);
dbShardingKeys.add(shardingKey);
SimpleColumnInfo column1 = Objects.requireNonNull(tableHandler.getColumnByName(shardingKey));
dbFunction = specilizeyyyydd(num, column1);
}
if (SQLUtils.nameEquals("YYYYWEEK", methodInvokeExpr.getMethodName())) {
String shardingKey = getShardingKey(methodInvokeExpr);
dbShardingKeys.add(shardingKey);
SimpleColumnInfo column1 = Objects.requireNonNull(tableHandler.getColumnByName(shardingKey));
dbFunction = specilizeyyyyWeek(num, column1);
}
if ("STR_HASH".equalsIgnoreCase(methodInvokeExpr.getMethodName())) {
String shardingKey = getShardingKey(methodInvokeExpr);
dbShardingKeys.add(shardingKey);
List<SQLExpr> arguments = methodInvokeExpr.getArguments();
int startIndex;
int endIndex;
int valType;
int randSeed;
if (arguments.size() >= 3) {
startIndex = Integer.parseInt(Objects.toString(arguments.get(1)));
endIndex = Integer.parseInt(Objects.toString(arguments.get(2)));
} else {
startIndex = -1;
endIndex = -1;
}
if (arguments.size() >= 4) {
valType = Integer.parseInt(Objects.toString(arguments.get(3)));
} else {
valType = 0;
}
if (arguments.size() >= 5) {
randSeed = Integer.parseInt(Objects.toString(arguments.get(4)));
} else {
randSeed = 31;
}
SimpleColumnInfo column1 = Objects.requireNonNull(tableHandler.getColumnByName(shardingKey));
dbFunction = specilizeStrHash(num, startIndex, endIndex, valType, randSeed, column1);
}
}
if (tableMethod != null) {
int num = tableNum;
SQLMethodInvokeExpr methodInvokeExpr = tableMethod;
if (SQLUtils.nameEquals("HASH", methodInvokeExpr.getMethodName())) {
methodInvokeExpr.setMethodName("MOD_HASH");
}
if (SQLUtils.nameEquals("MOD_HASH", methodInvokeExpr.getMethodName())) {
String shardingKey = getShardingKey(methodInvokeExpr);
tableShardingKeys.add(shardingKey);
SimpleColumnInfo column1 = Objects.requireNonNull(tableHandler.getColumnByName(shardingKey));
tableFunction = specilizeSingleModHash(num, column1);
}
if (SQLUtils.nameEquals("UNI_HASH", methodInvokeExpr.getMethodName())) {
String shardingKey = getShardingKey(methodInvokeExpr);
tableShardingKeys.add(getShardingKey(methodInvokeExpr));
SimpleColumnInfo column1 = Objects.requireNonNull(tableHandler.getColumnByName(shardingKey));
tableFunction = specilizeSingleModHash(num, column1);
}
if (SQLUtils.nameEquals("RIGHT_SHIFT", methodInvokeExpr.getMethodName())) {
String shardingKey = getShardingKey(methodInvokeExpr);
tableShardingKeys.add(shardingKey);
int shift = Integer.parseInt(getShardingKey(methodInvokeExpr, 1));
SimpleColumnInfo column1 = Objects.requireNonNull(tableHandler.getColumnByName(shardingKey));
tableFunction = specilizeSingleRightShift(num, shift, column1);
}
if (SQLUtils.nameEquals("RANGE_HASH", methodInvokeExpr.getMethodName())) {
String shardingKey = getShardingKey(methodInvokeExpr);
tableShardingKeys.add(shardingKey);
tableShardingKeys.add(getShardingKey(methodInvokeExpr, 1));
int n;
if (methodInvokeExpr.getArguments().size() > 2) {
n = Integer.parseInt(getShardingKey(methodInvokeExpr, 2));
} else {
n = 0;
}
SimpleColumnInfo column1 = Objects.requireNonNull(tableHandler.getColumnByName(shardingKey));
tableFunction = specilizeSingleRangeHash(num, n, column1);
}
if (SQLUtils.nameEquals("YYYYMM", methodInvokeExpr.getMethodName())) {
String shardingKey = getShardingKey(methodInvokeExpr);
tableShardingKeys.add(shardingKey);
SimpleColumnInfo column1 = Objects.requireNonNull(tableHandler.getColumnByName(shardingKey));
tableFunction = specilizeyyyymm(num, column1);
}
if (SQLUtils.nameEquals("YYYYDD", methodInvokeExpr.getMethodName())) {
String shardingKey = getShardingKey(methodInvokeExpr);
tableShardingKeys.add(shardingKey);
SimpleColumnInfo column1 = Objects.requireNonNull(tableHandler.getColumnByName(shardingKey));
tableFunction = specilizeyyyydd(num, column1);
}
if (SQLUtils.nameEquals("YYYYWEEK", methodInvokeExpr.getMethodName())) {
String shardingKey = getShardingKey(methodInvokeExpr);
tableShardingKeys.add(shardingKey);
SimpleColumnInfo column1 = Objects.requireNonNull(tableHandler.getColumnByName(shardingKey));
tableFunction = specilizeyyyyWeek(num, column1);
}
if (SQLUtils.nameEquals("WEEK", methodInvokeExpr.getMethodName())) {
String shardingKey = getShardingKey(methodInvokeExpr);
SimpleColumnInfo column1 = Objects.requireNonNull(tableHandler.getColumnByName(shardingKey));
tableShardingKeys.add(shardingKey);
tableFunction = specilizeWeek(num, column1);
}
if (SQLUtils.nameEquals("MMDD", methodInvokeExpr.getMethodName())) {
String shardingKey = getShardingKey(methodInvokeExpr);
SimpleColumnInfo column1 = Objects.requireNonNull(tableHandler.getColumnByName(shardingKey));
tableShardingKeys.add(shardingKey);
tableFunction = specilizemmdd(num, column1);
}
if (SQLUtils.nameEquals("DD", methodInvokeExpr.getMethodName())) {
String shardingKey = getShardingKey(methodInvokeExpr);
SimpleColumnInfo column1 = Objects.requireNonNull(tableHandler.getColumnByName(shardingKey));
tableShardingKeys.add(shardingKey);
tableFunction = specilizedd(num, column1);
}
if (SQLUtils.nameEquals("MM", methodInvokeExpr.getMethodName())) {
String shardingKey = getShardingKey(methodInvokeExpr);
SimpleColumnInfo column1 = Objects.requireNonNull(tableHandler.getColumnByName(shardingKey));
tableShardingKeys.add(shardingKey);
tableFunction = specilizemm(num, column1);
}
if ("STR_HASH".equalsIgnoreCase(methodInvokeExpr.getMethodName())) {
String shardingKey = getShardingKey(methodInvokeExpr);
SimpleColumnInfo column1 = Objects.requireNonNull(tableHandler.getColumnByName(shardingKey));
tableShardingKeys.add(shardingKey);
List<SQLExpr> arguments = methodInvokeExpr.getArguments();
int startIndex;
int endIndex;
int valType;
int randSeed;
if (arguments.size() >= 3) {
startIndex = Integer.parseInt(Objects.toString(arguments.get(1)));
endIndex = Integer.parseInt(Objects.toString(arguments.get(2)));
} else {
startIndex = -1;
endIndex = -1;
}
if (arguments.size() >= 4) {
valType = Integer.parseInt(Objects.toString(arguments.get(3)));
} else {
valType = 0;
}
if (arguments.size() >= 5) {
randSeed = Integer.parseInt(Objects.toString(arguments.get(4)));
} else {
randSeed = 31;
}
tableFunction = specilizeStrHash(num, startIndex, endIndex, valType, randSeed, column1);
}
}
if (flattenMapping) {
String needMethodName = SQLUtils.normalize(dbMethod.getMethodName().toUpperCase());
String tableShardingKey = Objects.requireNonNull(getShardingKey(tableMethod));
SimpleColumnInfo tableColumn = tableHandler.getColumnByName(tableShardingKey);
int total = dbNum * tableNum;
if (SQLUtils.nameEquals("MOD_HASH", needMethodName)) {
ToIntFunction<Object> core = specilizeSingleModHash(total, tableColumn);
tableFunction = core;
dbFunction = value -> core.applyAsInt(value) / tableNum;
} else if (SQLUtils.nameEquals("UNI_HASH", needMethodName)) {
ToIntFunction<Object> core = specilizeSingleModHash(dbNum, tableColumn);
dbFunction = core;
tableFunction = value -> {
int coreIndex = core.applyAsInt(value);
return coreIndex * tableNum + coreIndex % tableNum;
};
} else if (SQLUtils.nameEquals("RIGHT_SHIFT", needMethodName)) {
int shift = Integer.parseInt(getShardingKey(dbMethod, 1));
ToIntFunction<Object> core = specilizeSingleRightShift(dbNum, shift, tableColumn);
dbFunction = core;
tableFunction = value -> {
int coreIndex = core.applyAsInt(value);
return coreIndex * tableNum + coreIndex % tableNum;
};
} else if (SQLUtils.nameEquals("YYYYMM", needMethodName)) {
ToIntFunction<Object> core = specilizeyyyymm(total, tableColumn);
tableFunction = core;
dbFunction = value -> core.applyAsInt(value) / tableNum;
} else if (SQLUtils.nameEquals("YYYYDD", needMethodName)) {
ToIntFunction<Object> core = specilizeyyyydd(total, tableColumn);
tableFunction = core;
dbFunction = value -> core.applyAsInt(value) / tableNum;
} else if (SQLUtils.nameEquals("YYYYWEEK", needMethodName)) {
ToIntFunction<Object> core = specilizeyyyyWeek(total, tableColumn);
tableFunction = core;
dbFunction = value -> core.applyAsInt(value) / tableNum;
}
}
final boolean finalFlattenMapping = flattenMapping;
final ToIntFunction<Object> finalDbFunction = dbFunction;
final ToIntFunction<Object> finalTableFunction = tableFunction;
List<Partition> indexDataNodes = Optional.ofNullable(tableHandler.dataNodes()).map(i -> new ArrayList<>(i)).orElse(new ArrayList<>());
if (indexDataNodes.isEmpty()) {
List<int[]> seq = new ArrayList<>();
int tableCount = 0;
for (int dbIndex = 0; dbIndex < dbNum; dbIndex++) {
for (int tableIndex = 0; tableIndex < tableNum; tableCount++, tableIndex++) {
seq.add(new int[] { dbIndex, tableIndex, tableCount });
}
}
SimpleTemplateEngine templateEngine = new SimpleTemplateEngine();
Template template = templateEngine.createTemplate(mappingFormat);
HashMap<String, Object> context = new HashMap<>(properties);
for (int i = 0; i < seq.size(); i++) {
int seqIndex = i / storeDbNum;
int[] ints = seq.get(i);
int currentDbIndex = ints[0];
int currentTableIndex = ints[1];
int currentTableCount = ints[2];
context.put("targetIndex", String.valueOf(seqIndex));
context.put("dbIndex", String.valueOf(currentDbIndex));
context.put("tableIndex", String.valueOf(currentTableIndex));
context.put("index", String.valueOf(currentTableCount));
StringWriter stringWriter = new StringWriter();
template.make(context).writeTo(stringWriter);
String[] strings = SplitUtil.split(stringWriter.getBuffer().toString(), sep);
IndexDataNode backendTableInfo = new IndexDataNode(strings[0], strings[1], strings[2], currentDbIndex, currentTableIndex, currentTableCount);
indexDataNodes.add(backendTableInfo);
}
}
ShardingTableType shardingTableType = ShardingTableType.computeByName(indexDataNodes);
if (flattenMapping) {
Map<Integer, List<Partition>> dbIndexToNode = indexDataNodes.stream().collect(Collectors.groupingBy(k -> k.getDbIndex()));
return new AutoFunction(dbNum, tableNum, dbMethod, tableMethod, dbShardingKeys, tableShardingKeys, finalDbFunction, finalTableFunction, storeNum) {
@Override
public ShardingTableType getShardingTableType() {
return shardingTableType;
}
@Override
public List<Partition> scanAll() {
return ImmutableList.copyOf(indexDataNodes);
}
@Override
public List<Partition> scanOnlyTableIndex(int index) {
return ImmutableList.of(indexDataNodes.get(index));
}
@Override
public List<Partition> scanOnlyDbIndex(int index) {
return dbIndexToNode.get(index);
}
@Override
public List<Partition> scanOnlyDbTableIndex(int dbIndex, int tableIndex) {
return scanOnlyTableIndex(tableIndex);
}
@Override
public boolean isFlattenMapping() {
return true;
}
@Override
public boolean isShardingDbEnum() {
return dbEnum;
}
@Override
public boolean isShardingTableEnum() {
return tableEnum;
}
};
} else {
Map<Integer, List<Partition>> dbIndexToNode = indexDataNodes.stream().collect(Collectors.groupingBy(k -> k.getDbIndex()));
Map<Integer, List<Partition>> tableIndexToNode = indexDataNodes.stream().collect(Collectors.groupingBy(k -> k.getTableIndex()));
return new AutoFunction(dbNum, tableNum, dbMethod, tableMethod, dbShardingKeys, tableShardingKeys, finalDbFunction, finalTableFunction, storeNum) {
@Override
public ShardingTableType getShardingTableType() {
return shardingTableType;
}
@Override
public List<Partition> scanAll() {
return ImmutableList.copyOf(indexDataNodes);
}
@Override
public List<Partition> scanOnlyTableIndex(int index) {
return ImmutableList.copyOf(tableIndexToNode.get(index));
}
@Override
public List<Partition> scanOnlyDbIndex(int index) {
return ImmutableList.copyOf(dbIndexToNode.get(index));
}
@Override
public List<Partition> scanOnlyDbTableIndex(int dbIndex, int tableIndex) {
List<Partition> dataNodes = Objects.requireNonNull(dbIndexToNode.get(dbIndex));
for (Partition dataNode : dataNodes) {
if (dataNode.getTableIndex() == tableIndex) {
return ImmutableList.of(dataNode);
}
}
return dataNodes;
}
@Override
public boolean isFlattenMapping() {
return false;
}
@Override
public boolean isShardingDbEnum() {
return dbEnum;
}
@Override
public boolean isShardingTableEnum() {
return tableEnum;
}
};
}
}
Aggregations