package io.mycat.server.response; import com.google.common.base.Strings; import io.mycat.MycatServer; import io.mycat.net.BufferArray; import io.mycat.net.NetSystem; import io.mycat.server.ErrorCode; import io.mycat.server.Fields; import io.mycat.server.MySQLFrontConnection; import io.mycat.server.config.node.MycatConfig; import io.mycat.server.config.node.SchemaConfig; import io.mycat.server.config.node.UserConfig; import io.mycat.server.packet.EOFPacket; import io.mycat.server.packet.FieldPacket; import io.mycat.server.packet.ResultSetHeaderPacket; import io.mycat.server.packet.RowDataPacket; import io.mycat.server.packet.util.PacketUtil; import io.mycat.server.parser.ServerParse; import io.mycat.util.StringUtil; 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; /** * show tables impl * * @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(); private static final String SCHEMA_KEY = "schemaName"; private static final Pattern pattern = Pattern .compile( "^\\s*(SHOW)\\s+(TABLES)(\\s+(FROM)\\s+([a-zA-Z_0-9]+))?(\\s+(LIKE\\s+'(.*)'))?\\s*", Pattern.CASE_INSENSITIVE); /** * response method. * * @param c */ public static void response(MySQLFrontConnection c, String stmt, int type) { SchemaConfig schema = MycatServer.getInstance().getConfig() .getSchemas().get(c.getSchema()); if (schema != null) { //不分库的schema,show 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); BufferArray bufferArray = NetSystem.getInstance().getBufferPool() .allocateArray(); 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; // write header header.write(bufferArray); // write fields for (FieldPacket field : fields) { field.write(bufferArray); } // write eof eof.write(bufferArray); // write rows packetId = eof.packetId; TreeSet<String> tableSet = getTables(c, parm); for (String name : tableSet) { RowDataPacket row = new RowDataPacket(FIELD_COUNT); row.add(StringUtil.encode(name.toLowerCase(), c.getCharset())); row.packetId = ++packetId; row.write(bufferArray); } // write last eof EOFPacket lastEof = new EOFPacket(); lastEof.packetId = ++packetId; lastEof.write(bufferArray); // post write c.write(bufferArray); } public static Set<String> getTableSet(MySQLFrontConnection c, String stmt) { Map<String,String> parm = buildFields(c,stmt); return getTables(c, parm); } private static TreeSet<String> getTables(MySQLFrontConnection c, Map<String, String> parm) { 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()); } 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()) { tableSet.add(tname); } } } } } } return tableSet; } /** * build fields * * @param c * @param stmt */ private static Map<String, String> buildFields(MySQLFrontConnection 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); } } if (null == map.get(SCHEMA_KEY)) { map.put(SCHEMA_KEY, c.getSchema()); } return map; } }