mirror of
https://github.com/CodePhiliaX/Chat2DB.git
synced 2025-07-30 19:22:58 +08:00
hive的表结构查询需要根据DESCRIBE FORMATTED %s
.%s
结果进行解析。
This commit is contained in:
@ -7,19 +7,15 @@ import ai.chat2db.spi.CommandExecutor;
|
||||
import ai.chat2db.spi.MetaData;
|
||||
import ai.chat2db.spi.SqlBuilder;
|
||||
import ai.chat2db.spi.jdbc.DefaultMetaService;
|
||||
import ai.chat2db.spi.model.Database;
|
||||
import ai.chat2db.spi.model.Schema;
|
||||
import ai.chat2db.spi.model.Table;
|
||||
import ai.chat2db.spi.model.TableMeta;
|
||||
import ai.chat2db.spi.model.*;
|
||||
import ai.chat2db.spi.sql.SQLExecutor;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class HiveMetaData extends DefaultMetaService implements MetaData {
|
||||
@ -97,28 +93,179 @@ public class HiveMetaData extends DefaultMetaService implements MetaData {
|
||||
}
|
||||
|
||||
|
||||
private static String SELECT_TABLE_SQL = "DESCRIBE EXTENDED %s";
|
||||
private static String SELECT_TAB_COLS = "DESCRIBE FORMATTED `%s`.`%s`";
|
||||
// TODO 待完善
|
||||
@Override
|
||||
public List<Table> tables(Connection connection, String databaseName, String schemaName, String tableName) {
|
||||
String sql = String.format(SELECT_TABLE_SQL, schemaName);
|
||||
if (StringUtils.isNotBlank(tableName)) {
|
||||
sql = sql + " and A.TABLE_NAME = '" + tableName + "'";
|
||||
}
|
||||
public List<TableColumn> columns(Connection connection, String databaseName, String schemaName, String tableName) {
|
||||
String sql = String.format(SELECT_TAB_COLS, databaseName, tableName);
|
||||
return SQLExecutor.getInstance().execute(connection, sql, resultSet -> {
|
||||
List<Table> tables = new ArrayList<>();
|
||||
List<TableColumn> tableColumns = new ArrayList<>();
|
||||
Map<String, String> detailTableInfo = new HashMap<>();
|
||||
Map<String, String> tableParams = new HashMap<>();
|
||||
Map<String, String> storageInfo = new HashMap<>();
|
||||
Map<String, String> storageDescParams = new HashMap<>();
|
||||
Map<String, Map<String, String>> constraints = new HashMap<>();
|
||||
List<Map<String, String>> columns = new ArrayList<>();
|
||||
List<Map<String, String>> partitions = new ArrayList<>();
|
||||
Map<String, String> moduleMap = getDescTableModule();
|
||||
|
||||
String infoModule = "";
|
||||
while (resultSet.next()) {
|
||||
Table table = new Table();
|
||||
table.setDatabaseName(databaseName);
|
||||
table.setSchemaName(schemaName);
|
||||
table.setName(resultSet.getString("TABLE_NAME"));
|
||||
table.setComment(resultSet.getString("COMMENTS"));
|
||||
tables.add(table);
|
||||
String title = resultSet.getString(1).trim();
|
||||
if (("".equals(title) && resultSet.getString(2) == null) || "# Constraints".equals(title)) {
|
||||
continue;
|
||||
}
|
||||
if (moduleMap.containsKey(title)) {
|
||||
if ("partition_info".equals(infoModule) && "col_name".equals(moduleMap.get(title))) {
|
||||
continue;
|
||||
}
|
||||
infoModule = moduleMap.get(title);
|
||||
continue;
|
||||
}
|
||||
|
||||
String key = null;
|
||||
String value = null;
|
||||
switch (infoModule) {
|
||||
case "col_name":
|
||||
Map<String, String> map = new HashMap<>();
|
||||
int colNum = resultSet.getMetaData().getColumnCount();
|
||||
for (int col = 1; col <= colNum; col++) {
|
||||
String columnName = resultSet.getMetaData().getColumnName(col);
|
||||
String columnValue = resultSet.getString(columnName);
|
||||
map.put(columnName, columnValue);
|
||||
}
|
||||
columns.add(map);
|
||||
break;
|
||||
case "table_info":
|
||||
key = resultSet.getString(1).trim().replace(":", "");
|
||||
value = resultSet.getString(2).trim();
|
||||
detailTableInfo.put(key, value);
|
||||
break;
|
||||
|
||||
case "table_param":
|
||||
key = resultSet.getString(2).trim().replace(":", "");
|
||||
value = resultSet.getString(3).trim();
|
||||
tableParams.put(key, value);
|
||||
break;
|
||||
|
||||
case "storage_info":
|
||||
key = resultSet.getString(1).trim().replace(":", "");
|
||||
value = resultSet.getString(2).trim();
|
||||
storageInfo.put(key, value);
|
||||
break;
|
||||
|
||||
case "storage_desc":
|
||||
key = resultSet.getString(2).trim().replace(":", "");
|
||||
value = resultSet.getString(3).trim();
|
||||
storageDescParams.put(key, value);
|
||||
break;
|
||||
case "primary_key":
|
||||
Map<String, String> primaryKeyMap = constraints.getOrDefault("primaryKey", new HashMap<>());
|
||||
if ("Table:".equals(title.trim())) {
|
||||
resultSet.next();
|
||||
}
|
||||
String primaryKeyName = resultSet.getString(2).trim();
|
||||
resultSet.next();
|
||||
|
||||
key = resultSet.getString(2).trim();
|
||||
primaryKeyMap.put(key, primaryKeyName);
|
||||
|
||||
constraints.put("primaryKey", primaryKeyMap);
|
||||
break;
|
||||
case "not_null_constraint":
|
||||
Map<String, String> notNullMap = constraints.getOrDefault("notnull", new HashMap<>());
|
||||
if ("Table:".equals(title.trim())) {
|
||||
resultSet.next();
|
||||
}
|
||||
|
||||
String notNullConstraintName = resultSet.getString(2).trim();
|
||||
resultSet.next();
|
||||
|
||||
key = resultSet.getString(2).trim();
|
||||
notNullMap.put(key, notNullConstraintName);
|
||||
|
||||
constraints.put("notnull", notNullMap);
|
||||
break;
|
||||
|
||||
case "default_constraint":
|
||||
Map<String, String> defaultMap = constraints.getOrDefault("default", new HashMap<>());
|
||||
if ("Table:".equals(title.trim())) { resultSet.next();}
|
||||
|
||||
String defaultConstraintName = resultSet.getString(2).trim();
|
||||
resultSet.next();
|
||||
|
||||
key = resultSet.getString(1).trim().split(":")[1];
|
||||
value = resultSet.getString(2).trim();
|
||||
int valueIndex = value.indexOf(":");
|
||||
value = value.substring(valueIndex + 1);
|
||||
|
||||
defaultMap.put(key + "_constraintName", defaultConstraintName);
|
||||
|
||||
constraints.put("default", defaultMap);
|
||||
break;
|
||||
|
||||
case "partition_info":
|
||||
Map<String, String> partitionMap = new HashMap<>();
|
||||
int partitionColNum = resultSet.getMetaData().getColumnCount();
|
||||
for (int col = 0; col < partitionColNum; col++) {
|
||||
String columnName = resultSet.getMetaData().getColumnName(col + 1);
|
||||
String columnValue = resultSet.getString(columnName);
|
||||
partitionMap.put(columnName, columnValue);
|
||||
}
|
||||
partitions.add(partitionMap);
|
||||
break;
|
||||
default:
|
||||
System.out.print("unknown module,please update method to support it : " + infoModule);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return tables;
|
||||
|
||||
TableColumn tableColumn = new TableColumn();
|
||||
tableColumn.setTableName(tableName);
|
||||
tableColumn.setSchemaName(schemaName);
|
||||
tableColumn.setName(resultSet.getString("col_name"));
|
||||
tableColumn.setColumnType(resultSet.getString("data_type"));
|
||||
/*Integer dataPrecision = resultSet.getInt("DATA_PRECISION");
|
||||
if(dataPrecision!=null) {
|
||||
tableColumn.setColumnSize(dataPrecision);
|
||||
}else {
|
||||
tableColumn.setColumnSize(resultSet.getInt("DATA_LENGTH"));
|
||||
}*/
|
||||
|
||||
tableColumn.setComment(resultSet.getString("comment"));
|
||||
/* tableColumn.setNullable("Y".equalsIgnoreCase(resultSet.getString("NULLABLE")) ? 1 : 0);
|
||||
tableColumn.setOrdinalPosition(resultSet.getInt("COLUMN_ID"));
|
||||
tableColumn.setDecimalDigits(resultSet.getInt("DATA_SCALE"));
|
||||
String charUsed = resultSet.getString("CHAR_USED");
|
||||
if ("B".equalsIgnoreCase(charUsed)) {
|
||||
tableColumn.setUnit("BYTE");
|
||||
} else if ("C".equalsIgnoreCase(charUsed)) {
|
||||
tableColumn.setUnit("CHAR");
|
||||
}*/
|
||||
|
||||
tableColumns.add(tableColumn);
|
||||
return tableColumns;
|
||||
});
|
||||
}
|
||||
|
||||
private static Map<String, String> getDescTableModule() {
|
||||
Map<String, String> descTableModule = new HashMap<>();
|
||||
|
||||
descTableModule.put("# col_name", "col_name");
|
||||
descTableModule.put("# Detailed Table Information", "table_info");
|
||||
descTableModule.put("Table Parameters:", "table_param");
|
||||
descTableModule.put("# Storage Information", "storage_info");
|
||||
descTableModule.put("Storage Desc Params:", "storage_desc");
|
||||
descTableModule.put("# Not Null Constraints", "not_null_constraint");
|
||||
descTableModule.put("# Default Constraints", "default_constraint");
|
||||
descTableModule.put("# Partition Information", "partition_info");
|
||||
descTableModule.put("# Primary Key", "primary_key");
|
||||
|
||||
return descTableModule;
|
||||
}
|
||||
|
||||
public static String format(String name) {
|
||||
return "`" + name + "`";
|
||||
}
|
||||
|
Reference in New Issue
Block a user