1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor;
19
20 import lombok.Getter;
21 import lombok.RequiredArgsConstructor;
22 import org.apache.shardingsphere.infra.database.core.metadata.database.system.SystemDatabase;
23 import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
24 import org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResult;
25 import org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResultMetaData;
26 import org.apache.shardingsphere.infra.executor.sql.execute.result.query.impl.raw.metadata.RawQueryResultColumnMetaData;
27 import org.apache.shardingsphere.infra.executor.sql.execute.result.query.impl.raw.metadata.RawQueryResultMetaData;
28 import org.apache.shardingsphere.infra.executor.sql.execute.result.query.impl.raw.type.RawMemoryQueryResult;
29 import org.apache.shardingsphere.infra.executor.sql.execute.result.query.type.memory.row.MemoryQueryResultDataRow;
30 import org.apache.shardingsphere.infra.merge.result.MergedResult;
31 import org.apache.shardingsphere.infra.merge.result.impl.transparent.TransparentMergedResult;
32 import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereTable;
33 import org.apache.shardingsphere.infra.util.regex.RegexUtils;
34 import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
35 import org.apache.shardingsphere.proxy.backend.handler.admin.executor.DatabaseAdminQueryExecutor;
36 import org.apache.shardingsphere.proxy.backend.session.ConnectionSession;
37 import org.apache.shardingsphere.sql.parser.statement.mysql.dal.show.table.MySQLShowTablesStatement;
38
39 import java.sql.Types;
40 import java.util.Arrays;
41 import java.util.Collection;
42 import java.util.Collections;
43 import java.util.Comparator;
44 import java.util.LinkedList;
45 import java.util.List;
46 import java.util.Optional;
47 import java.util.regex.Pattern;
48 import java.util.stream.Collectors;
49
50
51
52
53 @RequiredArgsConstructor
54 public final class ShowTablesExecutor implements DatabaseAdminQueryExecutor {
55
56 private final MySQLShowTablesStatement sqlStatement;
57
58 private final DatabaseType databaseType;
59
60 @Getter
61 private QueryResultMetaData queryResultMetaData;
62
63 @Getter
64 private MergedResult mergedResult;
65
66 @Override
67 public void execute(final ConnectionSession connectionSession) {
68 String databaseName = sqlStatement.getFromDatabase().map(schema -> schema.getDatabase().getIdentifier().getValue()).orElseGet(connectionSession::getUsedDatabaseName);
69 queryResultMetaData = createQueryResultMetaData(databaseName);
70 mergedResult = new TransparentMergedResult(getQueryResult(databaseName));
71 }
72
73 private QueryResultMetaData createQueryResultMetaData(final String databaseName) {
74 List<RawQueryResultColumnMetaData> columnNames = new LinkedList<>();
75 String tableColumnName = String.format("Tables_in_%s", databaseName);
76 columnNames.add(new RawQueryResultColumnMetaData("", tableColumnName, tableColumnName, Types.VARCHAR, "VARCHAR", 255, 0));
77 if (sqlStatement.isContainsFull()) {
78 columnNames.add(new RawQueryResultColumnMetaData("", "Table_type", "Table_type", Types.VARCHAR, "VARCHAR", 20, 0));
79 }
80 return new RawQueryResultMetaData(columnNames);
81 }
82
83 private QueryResult getQueryResult(final String databaseName) {
84 SystemDatabase systemDatabase = new SystemDatabase(databaseType);
85 if (!systemDatabase.getSystemSchemas().contains(databaseName) && !ProxyContext.getInstance().getContextManager().getDatabase(databaseName).isComplete()) {
86 return new RawMemoryQueryResult(queryResultMetaData, Collections.emptyList());
87 }
88 List<MemoryQueryResultDataRow> rows = getTables(databaseName).stream().map(this::getRow).collect(Collectors.toList());
89 return new RawMemoryQueryResult(queryResultMetaData, rows);
90 }
91
92 private MemoryQueryResultDataRow getRow(final ShardingSphereTable table) {
93 return sqlStatement.isContainsFull()
94 ? new MemoryQueryResultDataRow(Arrays.asList(table.getName(), table.getType()))
95 : new MemoryQueryResultDataRow(Collections.singletonList(table.getName()));
96 }
97
98 private Collection<ShardingSphereTable> getTables(final String databaseName) {
99 if (null == ProxyContext.getInstance().getContextManager().getDatabase(databaseName).getSchema(databaseName)) {
100 return Collections.emptyList();
101 }
102 Collection<ShardingSphereTable> tables = ProxyContext.getInstance().getContextManager().getDatabase(databaseName).getSchema(databaseName).getAllTables();
103 Collection<ShardingSphereTable> filteredTables = filterByLike(tables);
104 return filteredTables.stream().sorted(Comparator.comparing(ShardingSphereTable::getName)).collect(Collectors.toList());
105 }
106
107 private Collection<ShardingSphereTable> filterByLike(final Collection<ShardingSphereTable> tables) {
108 Optional<Pattern> likePattern = getLikePattern();
109 return likePattern.isPresent() ? tables.stream().filter(each -> likePattern.get().matcher(each.getName()).matches()).collect(Collectors.toList()) : tables;
110 }
111
112 private Optional<Pattern> getLikePattern() {
113 if (!sqlStatement.getFilter().isPresent()) {
114 return Optional.empty();
115 }
116 Optional<String> regex = sqlStatement.getFilter().get().getLike().map(optional -> RegexUtils.convertLikePatternToRegex(optional.getPattern()));
117 return regex.map(optional -> Pattern.compile(optional, Pattern.CASE_INSENSITIVE));
118 }
119 }