#159 refactor show tables

This commit is contained in:
yanhuqing666
2017-06-22 18:22:06 +08:00
parent 4b7f45b789
commit d647a1c708
4 changed files with 196 additions and 385 deletions
@@ -23,16 +23,7 @@
*/
package io.mycat.backend.mysql.nio.handler;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Strings;
import io.mycat.MycatServer;
import io.mycat.backend.BackendConnection;
import io.mycat.backend.datasource.PhysicalDBNode;
@@ -41,22 +32,24 @@ import io.mycat.config.ErrorCode;
import io.mycat.config.MycatConfig;
import io.mycat.config.model.SchemaConfig;
import io.mycat.log.transaction.TxnLogHelper;
import io.mycat.net.mysql.BinaryRowDataPacket;
import io.mycat.net.mysql.ErrorPacket;
import io.mycat.net.mysql.FieldPacket;
import io.mycat.net.mysql.OkPacket;
import io.mycat.net.mysql.RowDataPacket;
import io.mycat.net.mysql.*;
import io.mycat.route.RouteResultset;
import io.mycat.route.RouteResultsetNode;
import io.mycat.server.NonBlockingSession;
import io.mycat.server.ServerConnection;
import io.mycat.server.parser.ServerParse;
import io.mycat.server.parser.ServerParseShow;
import io.mycat.server.response.ShowFullTables;
import io.mycat.server.response.ShowTables;
import io.mycat.statistic.stat.QueryResult;
import io.mycat.statistic.stat.QueryResultDispatcher;
import io.mycat.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* @author mycat
*/
@@ -103,10 +96,9 @@ public class SingleNodeHandler implements ResponseHandler, LoadDataResponseHandl
isDefaultNodeShowTable = (ServerParseShow.TABLES == type && !Strings.isNullOrEmpty(schemaConfig.getDataNode()));
isDefaultNodeShowFullTable = (ServerParseShow.FULLTABLES == type && !Strings.isNullOrEmpty(schemaConfig.getDataNode()));
if (isDefaultNodeShowTable) {
shardingTablesSet = ShowTables.getTableSet(source, rrs.getStatement());
shardingTablesSet = ShowTables.getTableSet(source, rrs.getStatement(),false);
} else if (isDefaultNodeShowFullTable) {
shardingTablesSet = ShowFullTables.getTableSet(source, rrs.getStatement());
shardingTablesSet = ShowTables.getTableSet(source, rrs.getStatement(),true);
}
}
}
@@ -27,7 +27,6 @@ import io.mycat.server.ServerConnection;
import io.mycat.server.parser.ServerParse;
import io.mycat.server.parser.ServerParseShow;
import io.mycat.server.response.ShowDatabases;
import io.mycat.server.response.ShowFullTables;
import io.mycat.server.response.ShowMyCATCluster;
import io.mycat.server.response.ShowMyCatStatus;
import io.mycat.server.response.ShowTables;
@@ -49,10 +48,10 @@ public final class ShowHandler {
ShowDatabases.response(c);
break;
case ServerParseShow.TABLES:
ShowTables.response(c, stmt, type);
ShowTables.response(c, stmt, false);
break;
case ServerParseShow.FULLTABLES:
ShowFullTables.response(c, stmt, type);
ShowTables.response(c, stmt, true);
break;
case ServerParseShow.MYCAT_STATUS:
ShowMyCatStatus.response(c);
@@ -1,208 +0,0 @@
package io.mycat.server.response;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.google.common.base.Strings;
import io.mycat.MycatServer;
import io.mycat.backend.mysql.PacketUtil;
import io.mycat.config.ErrorCode;
import io.mycat.config.Fields;
import io.mycat.config.MycatConfig;
import io.mycat.config.model.SchemaConfig;
import io.mycat.config.model.UserConfig;
import io.mycat.meta.SchemaMeta;
import io.mycat.net.mysql.EOFPacket;
import io.mycat.net.mysql.FieldPacket;
import io.mycat.net.mysql.ResultSetHeaderPacket;
import io.mycat.net.mysql.RowDataPacket;
import io.mycat.server.ServerConnection;
import io.mycat.server.parser.ServerParse;
import io.mycat.server.util.SchemaUtil;
import io.mycat.util.StringUtil;
import static io.mycat.server.parser.ServerParseShow.FULL_TABLE_CHECK;
/**
* show tables impl
* @author yanglixue
*
*/
public class ShowFullTables
{
private static final int FIELD_COUNT = 2;
private static final ResultSetHeaderPacket header = PacketUtil.getHeader(FIELD_COUNT);
private static final FieldPacket[] fields = new FieldPacket[FIELD_COUNT];
private static final EOFPacket eof = new EOFPacket();
private static final String SCHEMA_KEY = "schemaName";
private static final String LIKE_KEY = "like";
private static final Pattern pattern = Pattern.compile(FULL_TABLE_CHECK,Pattern.CASE_INSENSITIVE);
/**
* response method.
* @param c
*/
public static void response(ServerConnection c,String stmt,int type) {
String showSchemal= SchemaUtil.parseShowTableSchema(stmt) ;
String cSchema =showSchemal==null? c.getSchema():showSchemal;
SchemaConfig schema = MycatServer.getInstance().getConfig().getSchemas().get(cSchema);
if(schema != null) {
//不分库的schemashow tables从后端 mysql中查
String node = schema.getDataNode();
if(!Strings.isNullOrEmpty(node)) {
c.execute(stmt, ServerParse.SHOW);
return;
}
} else {
c.writeErrMessage(ErrorCode.ER_NO_DB_ERROR,"No database selected");
}
//分库的schema,直接从SchemaConfig中获取所有表名
Map<String,String> parm = buildFields(c,stmt);
Set<String> tableSet = getTableSet(c, parm,cSchema);
int i = 0;
byte packetId = 0;
header.packetId = ++packetId;
fields[i] = PacketUtil.getField("Tables in " + parm.get(SCHEMA_KEY), Fields.FIELD_TYPE_VAR_STRING);
fields[i].packetId = ++packetId;
fields[i+1] = PacketUtil.getField("Table_type " , Fields.FIELD_TYPE_VAR_STRING);
fields[i+1].packetId = ++packetId;
eof.packetId = ++packetId;
ByteBuffer buffer = c.allocate();
// write header
buffer = header.write(buffer, c,true);
// write fields
for (FieldPacket field : fields) {
buffer = field.write(buffer, c,true);
}
// write eof
buffer = eof.write(buffer, c,true);
// write rows
packetId = eof.packetId;
for (String name : tableSet) {
RowDataPacket row = new RowDataPacket(FIELD_COUNT);
row.add(StringUtil.encode(name.toLowerCase(), c.getCharset()));
row.add(StringUtil.encode("SHARDING TABLE", c.getCharset()));
row.packetId = ++packetId;
buffer = row.write(buffer, c,true);
}
// write last eof
EOFPacket lastEof = new EOFPacket();
lastEof.packetId = ++packetId;
buffer = lastEof.write(buffer, c,true);
// post write
c.write(buffer);
}
public static Set<String> getTableSet(ServerConnection c, String stmt)
{
Map<String,String> parm = buildFields(c,stmt);
return getTableSet(c, parm,c.getSchema());
}
private static Set<String> getTableSet(ServerConnection c, Map<String, String> parm,String cSchema)
{
//在这里对于没有建立起来的表格进行过滤,去除尚未新建的表格
SchemaMeta schemata = MycatServer.getInstance().getTmManager().getCatalogs().get(cSchema);
Map meta = null;
if(schemata != null){
meta = schemata.getTableMetas();
}
TreeSet<String> tableSet = new TreeSet<String>();
MycatConfig conf = MycatServer.getInstance().getConfig();
Map<String, UserConfig> users = conf.getUsers();
UserConfig user = users == null ? null : users.get(c.getUser());
if (user != null) {
Map<String, SchemaConfig> schemas = conf.getSchemas();
for (String name:schemas.keySet()){
if (null !=parm.get(SCHEMA_KEY) && parm.get(SCHEMA_KEY).toUpperCase().equals(name.toUpperCase()) ){
if(null==parm.get("LIKE_KEY")){
for (String tname : schemas.get(name).getTables().keySet()){
if(meta.get(tname) != null){
tableSet.add(tname);
}
}
}else{
String p = "^" + parm.get("LIKE_KEY").replaceAll("%", ".*");
Pattern pattern = Pattern.compile(p,Pattern.CASE_INSENSITIVE);
Matcher ma ;
for (String tname : schemas.get(name).getTables().keySet()){
ma=pattern.matcher(tname);
if(ma.matches() && meta.get(tname) != null){
tableSet.add(tname);
}
}
}
}
};
}
return tableSet;
}
/**
* build fields
* @param c
* @param stmt
*/
private static Map<String,String> buildFields(ServerConnection c,String stmt) {
Map<String,String> map = new HashMap<String, String>();
Matcher ma = pattern.matcher(stmt);
if(ma.find()){
String schemaName=ma.group(6);
if (null !=schemaName && (!"".equals(schemaName)) && (!"null".equals(schemaName))){
map.put(SCHEMA_KEY, schemaName);
}
String like = ma.group(9);
if (null !=like && (!"".equals(like)) && (!"null".equals(like))){
map.put("LIKE_KEY", like);
}
}
if(null==map.get(SCHEMA_KEY)){
map.put(SCHEMA_KEY, c.getSchema());
}
return map;
}
}
@@ -1,10 +1,7 @@
package io.mycat.server.response;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -27,6 +24,7 @@ import io.mycat.server.parser.ServerParse;
import io.mycat.server.util.SchemaUtil;
import io.mycat.util.StringUtil;
import static io.mycat.server.parser.ServerParseShow.FULL_TABLE_CHECK;
import static io.mycat.server.parser.ServerParseShow.TABLE_CHECK;
/**
@@ -34,176 +32,206 @@ import static io.mycat.server.parser.ServerParseShow.TABLE_CHECK;
* @author yanglixue
*
*/
public class ShowTables {
private static final int FIELD_COUNT = 1;
private static final ResultSetHeaderPacket header = PacketUtil.getHeader(FIELD_COUNT);
private static final FieldPacket[] fields = new FieldPacket[FIELD_COUNT];
private static final EOFPacket eof = new EOFPacket();
public class ShowTables {
private static final String SCHEMA_KEY = "schemaName";
private static final String LIKE_KEY = "like";
private static final Pattern pattern = Pattern.compile(TABLE_CHECK,Pattern.CASE_INSENSITIVE);
/**
* response method.
* @param c
*/
public static void response(ServerConnection c,String stmt,int type) {
String showSchemal= SchemaUtil.parseShowTableSchema(stmt) ;
String cSchema =showSchemal==null? c.getSchema():showSchemal;
SchemaConfig schema = MycatServer.getInstance().getConfig().getSchemas().get(cSchema);
if(schema != null) {
//不分库的schemashow tables从后端 mysql中查
String node = schema.getDataNode();
if(!Strings.isNullOrEmpty(node)) {
c.execute(stmt, ServerParse.SHOW);
return;
}
} else {
c.writeErrMessage(ErrorCode.ER_NO_DB_ERROR,"No database selected");
return;
}
//分库的schema,直接从SchemaConfig中获取所有表名
Map<String,String> parm = buildFields(c,stmt);
java.util.Set<String> tableSet = getTableSet(c, parm,cSchema);
public static void response(ServerConnection c, String stmt, boolean isFull) {
String showSchema = SchemaUtil.parseShowTableSchema(stmt);
String cSchema = showSchema == null ? c.getSchema() : showSchema;
SchemaConfig schema = MycatServer.getInstance().getConfig().getSchemas().get(cSchema);
if (schema == null) {
c.writeErrMessage(ErrorCode.ER_NO_DB_ERROR, "No database selected");
return;
}
//不分库的schemashow tables从后端 mysql中查
String node = schema.getDataNode();
if (!Strings.isNullOrEmpty(node)) {
c.execute(stmt, ServerParse.SHOW);
return;
}
responseDirect(c, stmt, isFull);
}
private static void responseDirect(ServerConnection c, String stmt, boolean isFull) {
if (isFull) {
responseDirectShowFullTables(c, stmt);
} else {
responseDirectShowTables(c, stmt);
}
}
private static void responseDirectShowFullTables(ServerConnection c, String stmt) {
int FIELD_COUNT = 2;
ResultSetHeaderPacket header = PacketUtil.getHeader(FIELD_COUNT);
FieldPacket[] fields = new FieldPacket[FIELD_COUNT];
EOFPacket eof = new EOFPacket();
Map<String, String> parm = buildShowFullTablesFields(c, stmt);
Set<String> tableSet = getTableSet(c, parm, c.getSchema());
int i = 0;
byte packetId = 0;
header.packetId = ++packetId;
fields[i] = PacketUtil.getField("Tables in " + parm.get(SCHEMA_KEY), Fields.FIELD_TYPE_VAR_STRING);
fields[i].packetId = ++packetId;
fields[i+1] = PacketUtil.getField("Table_type " , Fields.FIELD_TYPE_VAR_STRING);
fields[i+1].packetId = ++packetId;
eof.packetId = ++packetId;
ByteBuffer buffer = c.allocate();
// write header
buffer = header.write(buffer, c,true);
// write fields
for (FieldPacket field : fields) {
buffer = field.write(buffer, c,true);
}
// write eof
buffer = eof.write(buffer, c,true);
// write rows
packetId = eof.packetId;
for (String name : tableSet) {
RowDataPacket row = new RowDataPacket(FIELD_COUNT);
row.add(StringUtil.encode(name.toLowerCase(), c.getCharset()));
row.add(StringUtil.encode("SHARDING TABLE", c.getCharset()));
row.packetId = ++packetId;
buffer = row.write(buffer, c,true);
}
// write last eof
EOFPacket lastEof = new EOFPacket();
lastEof.packetId = ++packetId;
buffer = lastEof.write(buffer, c,true);
int i = 0;
byte packetId = 0;
header.packetId = ++packetId;
fields[i] = PacketUtil.getField("Tables in " + parm.get(SCHEMA_KEY), Fields.FIELD_TYPE_VAR_STRING);
fields[i++].packetId = ++packetId;
eof.packetId = ++packetId;
ByteBuffer buffer = c.allocate();
// post write
c.write(buffer);
}
private static void responseDirectShowTables(ServerConnection c, String stmt) {
int FIELD_COUNT = 1;
ResultSetHeaderPacket header = PacketUtil.getHeader(FIELD_COUNT);
FieldPacket[] fields = new FieldPacket[FIELD_COUNT];
EOFPacket eof = new EOFPacket();
Map<String, String> parm = buildShowTablesFields(c, stmt);
Set<String> tableSet = getTableSet(c, parm, c.getSchema());
int i = 0;
byte packetId = 0;
header.packetId = ++packetId;
fields[i] = PacketUtil.getField("Tables in " + parm.get(SCHEMA_KEY), Fields.FIELD_TYPE_VAR_STRING);
fields[i].packetId = ++packetId;
eof.packetId = ++packetId;
ByteBuffer buffer = c.allocate();
// write header
buffer = header.write(buffer, c, true);
// write fields
for (FieldPacket field : fields) {
buffer = field.write(buffer, c, true);
}
// write eof
buffer = eof.write(buffer, c, true);
// write header
buffer = header.write(buffer, c,true);
// write rows
packetId = eof.packetId;
for (String name : tableSet) {
RowDataPacket row = new RowDataPacket(FIELD_COUNT);
row.add(StringUtil.encode(name.toLowerCase(), c.getCharset()));
row.packetId = ++packetId;
buffer = row.write(buffer, c, true);
}
// write last eof
EOFPacket lastEof = new EOFPacket();
lastEof.packetId = ++packetId;
buffer = lastEof.write(buffer, c, true);
// write fields
for (FieldPacket field : fields) {
buffer = field.write(buffer, c,true);
}
// write eof
buffer = eof.write(buffer, c,true);
// write rows
packetId = eof.packetId;
for (String name : tableSet) {
RowDataPacket row = new RowDataPacket(FIELD_COUNT);
row.add(StringUtil.encode(name.toLowerCase(), c.getCharset()));
row.packetId = ++packetId;
buffer = row.write(buffer, c,true);
}
// write last eof
EOFPacket lastEof = new EOFPacket();
lastEof.packetId = ++packetId;
buffer = lastEof.write(buffer, c,true);
// post write
c.write(buffer);
}
public static Set<String> getTableSet(ServerConnection c, String stmt)
{
Map<String,String> parm = buildFields(c,stmt);
return getTableSet(c, parm,c.getSchema());
}
// post write
c.write(buffer);
}
public static Set<String> getTableSet(ServerConnection c, String stmt, boolean isFull) {
Map<String, String> parm = buildFields(c, stmt, isFull);
return getTableSet(c, parm, c.getSchema());
}
private static Set<String> getTableSet(ServerConnection c, Map<String, String> parm,String cSchema)
{
//在这里对于没有建立起来的表格进行过滤,去除尚未新建的表格
SchemaMeta schemata = MycatServer.getInstance().getTmManager().getCatalogs().get(cSchema);
Map meta = null;
if(schemata != null){
meta = schemata.getTableMetas();
}
//在这里对于没有建立起来的表格进行过滤,去除尚未新建的表格
SchemaMeta schemata = MycatServer.getInstance().getTmManager().getCatalogs().get(cSchema);
if (schemata == null) {
return new HashSet<>();
}
Map meta = schemata.getTableMetas();
TreeSet<String> tableSet = new TreeSet<>();
MycatConfig conf = MycatServer.getInstance().getConfig();
Map<String, UserConfig> users = conf.getUsers();
UserConfig user = users == null ? null : users.get(c.getUser());
if (user != null) {
Map<String, SchemaConfig> schemas = conf.getSchemas();
for (String name : schemas.keySet()) {
if (null != parm.get(SCHEMA_KEY) && parm.get(SCHEMA_KEY).toUpperCase().equals(name.toUpperCase())) {
if (null == parm.get(LIKE_KEY)) {
//tableSet.addAll(schemas.get(name).getTables().keySet());
for (String tname : schemas.get(name).getTables().keySet()) {
if (meta.get(tname) != null) {
tableSet.add(tname);
}
}
} else {
String p = "^" + parm.get(LIKE_KEY).replaceAll("%", ".*");
Pattern pattern = Pattern.compile(p, Pattern.CASE_INSENSITIVE);
Matcher ma;
TreeSet<String> tableSet = new TreeSet<String>();
MycatConfig conf = MycatServer.getInstance().getConfig();
Map<String, UserConfig> users = conf.getUsers();
UserConfig user = users == null ? null : users.get(c.getUser());
if (user != null) {
Map<String, SchemaConfig> schemas = conf.getSchemas();
for (String name:schemas.keySet()){
if (null !=parm.get(SCHEMA_KEY) && parm.get(SCHEMA_KEY).toUpperCase().equals(name.toUpperCase()) ){
if(null==parm.get("LIKE_KEY")){
//tableSet.addAll(schemas.get(name).getTables().keySet());
for (String tname : schemas.get(name).getTables().keySet()){
if(meta.get(tname) != null){
tableSet.add(tname);
}
}
}else{
String p = "^" + parm.get("LIKE_KEY").replaceAll("%", ".*");
Pattern pattern = Pattern.compile(p,Pattern.CASE_INSENSITIVE);
Matcher ma ;
for (String tname : schemas.get(name).getTables().keySet()){
ma=pattern.matcher(tname);
if(ma.matches() && meta.get(tname) != null){
tableSet.add(tname);
}
}
}
}
};
}
return tableSet;
}
/**
* build fields
* @param c
* @param stmt
*/
private static Map<String,String> buildFields(ServerConnection c,String stmt) {
Map<String,String> map = new HashMap<String, String>();
Matcher ma = pattern.matcher(stmt);
if(ma.find()){
String schemaName=ma.group(5);
if (null !=schemaName && (!"".equals(schemaName)) && (!"null".equals(schemaName))){
map.put(SCHEMA_KEY, schemaName);
}
String like = ma.group(8);
if (null !=like && (!"".equals(like)) && (!"null".equals(like))){
map.put("LIKE_KEY", like);
}
for (String tname : schemas.get(name).getTables().keySet()) {
ma = pattern.matcher(tname);
if (ma.matches() && meta.get(tname) != null) {
tableSet.add(tname);
}
}
}
}
}
}
return tableSet;
}
private static Map<String, String> buildFields(ServerConnection c, String stmt, boolean isFull) {
if (isFull) {
return buildShowFullTablesFields(c, stmt);
} else {
return buildShowTablesFields(c, stmt);
}
}
private static Map<String, String> buildShowFullTablesFields(ServerConnection c, String stmt) {
Map<String,String> map = new HashMap<>();
Pattern pattern = Pattern.compile(FULL_TABLE_CHECK,Pattern.CASE_INSENSITIVE);
Matcher ma = pattern.matcher(stmt);
if(ma.find()){
String schemaName=ma.group(6);
if (null !=schemaName && (!"".equals(schemaName)) && (!"null".equals(schemaName))){
map.put(SCHEMA_KEY, schemaName);
}
String like = ma.group(9);
if (null !=like && (!"".equals(like)) && (!"null".equals(like))){
map.put(LIKE_KEY, like);
}
}
if(null==map.get(SCHEMA_KEY)){
map.put(SCHEMA_KEY, c.getSchema());
}
return map;
return map;
}
private static Map<String, String> buildShowTablesFields(ServerConnection c, String stmt) {
Map<String, String> map = new HashMap<>();
Pattern pattern = Pattern.compile(TABLE_CHECK,Pattern.CASE_INSENSITIVE);
Matcher ma = pattern.matcher(stmt);
if (ma.find()) {
String schemaName = ma.group(5);
if (null != schemaName && (!"".equals(schemaName)) && (!"null".equals(schemaName))) {
map.put(SCHEMA_KEY, schemaName);
}
String like = ma.group(8);
if (null != like && (!"".equals(like)) && (!"null".equals(like))) {
map.put(LIKE_KEY, like);
}
}
if (null == map.get(SCHEMA_KEY)) {
map.put(SCHEMA_KEY, c.getSchema());
}
return map;
}
}