support PinService

This commit is contained in:
jipengfei-jpf
2023-06-24 16:32:02 +08:00
parent 1e8a56b1f0
commit efd9aa490a
32 changed files with 595 additions and 95 deletions

View File

@ -11,7 +11,7 @@ public class PostgreSQLDBManage implements DBManage {
@Override
public void connectDatabase(String database) {
try {
SQLExecutor.getInstance().execute("connect " + database + "");
SQLExecutor.getInstance().execute("SELECT pg_database_size('"+database+"');");
} catch (SQLException e) {
throw new RuntimeException(e);
}

View File

@ -2,6 +2,7 @@ package ai.chat2db.plugin.redis;
import ai.chat2db.spi.MetaData;
import ai.chat2db.spi.jdbc.DefaultMetaService;
import ai.chat2db.spi.model.Database;
import ai.chat2db.spi.model.Table;
import ai.chat2db.spi.sql.SQLExecutor;
import jakarta.validation.constraints.NotEmpty;
@ -19,15 +20,16 @@ public class RedisMetaData extends DefaultMetaService implements MetaData {
@Override
public List<String> databases() {
List<String> databases = new ArrayList<>();
public List<Database> databases() {
List<Database> databases = new ArrayList<>();
return SQLExecutor.getInstance().executeSql("config get databases", resultSet -> {
try {
if (resultSet.next()) {
Object count = resultSet.getObject(2);
if(StringUtils.isNotBlank(count.toString())) {
for (int i = 0; i < Integer.parseInt(count.toString()); i++) {
databases.add(String.valueOf(i));
Database database = Database.builder().name(String.valueOf(i)).build();
databases.add(database);
}
}
}

View File

@ -2,6 +2,8 @@ package ai.chat2db.plugin.sqlite;
import ai.chat2db.spi.MetaData;
import ai.chat2db.spi.jdbc.DefaultMetaService;
import ai.chat2db.spi.model.Database;
import ai.chat2db.spi.model.Schema;
import ai.chat2db.spi.sql.SQLExecutor;
import com.google.common.collect.Lists;
@ -24,12 +26,12 @@ public class SqliteMetaData extends DefaultMetaService implements MetaData {
});
}
@Override
public List<String> databases() {
return Lists.newArrayList("main");
public List<Database> databases() {
return Lists.newArrayList(Database.builder().name("main").build());
}
@Override
public List<String> schemas(String databaseName) {
public List<Schema> schemas(String databaseName) {
return Lists.newArrayList();
}
}

View File

@ -0,0 +1,18 @@
package ai.chat2db.server.domain.api.param;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class MetaDataQueryParam {
@NotNull
private Long dataSourceId;
}

View File

@ -0,0 +1,31 @@
package ai.chat2db.server.domain.api.param;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Data
public class PinTableParam {
@NotNull
private Long dataSourceId;
/**
* DB名称
*/
private String databaseName;
/**
* 表所在空间
*/
private String schemaName;
/**
* tableName
*/
private String tableName;
/**
* pin userId
*/
private Long userId;
}

View File

@ -24,6 +24,5 @@ public class SchemaQueryParam {
@NotNull
private Long dataSourceId;
@NotNull
private String dataBaseName;
}

View File

@ -1,9 +1,8 @@
package ai.chat2db.server.domain.api.service;
import ai.chat2db.server.domain.api.param.DatabaseOperationParam;
import ai.chat2db.server.domain.api.param.DatabaseQueryAllParam;
import ai.chat2db.server.domain.api.param.SchemaOperationParam;
import ai.chat2db.server.domain.api.param.SchemaQueryParam;
import ai.chat2db.server.domain.api.param.*;
import ai.chat2db.server.tools.base.wrapper.Result;
import ai.chat2db.server.tools.base.wrapper.result.DataResult;
import ai.chat2db.spi.model.*;
import ai.chat2db.server.tools.base.wrapper.result.ActionResult;
import ai.chat2db.server.tools.base.wrapper.result.ListResult;
@ -32,6 +31,13 @@ public interface DatabaseService {
*/
ListResult<Schema> querySchema(SchemaQueryParam param);
/**
* query Database and Schema
* @param param
* @return
*/
DataResult<MetaSchema> queryDatabaseSchema(MetaDataQueryParam param);
/**

View File

@ -0,0 +1,33 @@
package ai.chat2db.server.domain.api.service;
import ai.chat2db.server.domain.api.param.PinTableParam;
import ai.chat2db.server.tools.base.wrapper.result.ActionResult;
import ai.chat2db.server.tools.base.wrapper.result.ListResult;
import java.util.List;
public interface PinService {
/**
* User pin table
* @param param
* @return
*/
ActionResult pinTable(PinTableParam param);
/**
* Delete pin table
* @param param
* @return
*/
ActionResult deletePinTable(PinTableParam param);
/**
* Query user pin tables
* @param param
* @return
*/
ListResult<String> queryPinTables(PinTableParam param);
}

View File

@ -0,0 +1,21 @@
package ai.chat2db.server.domain.core.converter;
import ai.chat2db.server.domain.api.param.PinTableParam;
import ai.chat2db.server.domain.api.param.TablePageQueryParam;
import ai.chat2db.server.domain.repository.entity.PinTableDO;
import org.mapstruct.Mapper;
@Mapper(componentModel = "spring")
public abstract class PinTableConverter {
/**
*
* @param param
* @return
*/
public abstract PinTableDO param2do(PinTableParam param);
public abstract PinTableParam toPinTableParam (TablePageQueryParam param);
}

View File

@ -137,8 +137,8 @@ public class DataSourceServiceImpl implements DataSourceService {
public ListResult<Database> connect(Long id) {
DatabaseQueryAllParam queryAllParam = new DatabaseQueryAllParam();
queryAllParam.setDataSourceId(id);
List<String> databases = Chat2DBContext.getMetaData().databases();
return ListResult.of(EasyCollectionUtils.toList(databases, name -> Database.builder().name(name).build()));
List<Database> databases = Chat2DBContext.getMetaData().databases();
return ListResult.of(databases);
}
@Override

View File

@ -1,20 +1,23 @@
package ai.chat2db.server.domain.core.impl;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import ai.chat2db.server.domain.api.param.DatabaseOperationParam;
import ai.chat2db.server.domain.api.param.SchemaOperationParam;
import ai.chat2db.server.domain.api.param.*;
import ai.chat2db.server.domain.api.service.DatabaseService;
import ai.chat2db.server.tools.base.wrapper.Result;
import ai.chat2db.server.tools.base.wrapper.result.DataResult;
import ai.chat2db.spi.model.Database;
import ai.chat2db.spi.model.MetaSchema;
import ai.chat2db.spi.model.Schema;
import ai.chat2db.server.domain.api.param.DatabaseQueryAllParam;
import ai.chat2db.server.domain.api.param.SchemaQueryParam;
import ai.chat2db.server.tools.base.wrapper.result.ActionResult;
import ai.chat2db.server.tools.base.wrapper.result.ListResult;
import ai.chat2db.server.tools.common.util.EasyCollectionUtils;
import ai.chat2db.spi.sql.Chat2DBContext;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
/**
* @author moji
@ -26,14 +29,29 @@ public class DatabaseServiceImpl implements DatabaseService {
@Override
public ListResult<Database> queryAll(DatabaseQueryAllParam param) {
List<String> databases = Chat2DBContext.getMetaData().databases();
return ListResult.of(EasyCollectionUtils.toList(databases, name -> Database.builder().name(name).build()));
return ListResult.of(Chat2DBContext.getMetaData().databases());
}
@Override
public ListResult<Schema> querySchema(SchemaQueryParam param) {
List<String> databases = Chat2DBContext.getMetaData().schemas(param.getDataBaseName());
return ListResult.of(EasyCollectionUtils.toList(databases, name -> Schema.builder().name(name).build()));
return ListResult.of(Chat2DBContext.getMetaData().schemas(param.getDataBaseName()));
}
@Override
public DataResult<MetaSchema> queryDatabaseSchema(MetaDataQueryParam param) {
MetaSchema metaSchema = new MetaSchema();
List<Database> databases = Chat2DBContext.getMetaData().databases();
if (!CollectionUtils.isEmpty(databases)) {
for (Database dataBase : databases) {
List<Schema> schemaList = Chat2DBContext.getMetaData().schemas(dataBase.getName());
dataBase.setSchemas(schemaList);
}
metaSchema.setDatabases(databases);
} else {
List<Schema> schemas = Chat2DBContext.getMetaData().schemas(null);
metaSchema.setSchemas(schemas);
}
return DataResult.of(metaSchema);
}
@Override
@ -50,25 +68,25 @@ public class DatabaseServiceImpl implements DatabaseService {
@Override
public ActionResult modifyDatabase(DatabaseOperationParam param) {
Chat2DBContext.getDBManage().modifyDatabase(param.getDatabaseName(),param.getNewDatabaseName());
Chat2DBContext.getDBManage().modifyDatabase(param.getDatabaseName(), param.getNewDatabaseName());
return ActionResult.isSuccess();
}
@Override
public ActionResult deleteSchema(SchemaOperationParam param) {
Chat2DBContext.getDBManage().dropSchema(param.getDatabaseName(),param.getSchemaName());
Chat2DBContext.getDBManage().dropSchema(param.getDatabaseName(), param.getSchemaName());
return ActionResult.isSuccess();
}
@Override
public ActionResult createSchema(SchemaOperationParam param) {
Chat2DBContext.getDBManage().createSchema(param.getDatabaseName(),param.getSchemaName());
Chat2DBContext.getDBManage().createSchema(param.getDatabaseName(), param.getSchemaName());
return ActionResult.isSuccess();
}
@Override
public ActionResult modifySchema(SchemaOperationParam param) {
Chat2DBContext.getDBManage().modifySchema(param.getDatabaseName(),param.getSchemaName(),
Chat2DBContext.getDBManage().modifySchema(param.getDatabaseName(), param.getSchemaName(),
param.getNewSchemaName());
return ActionResult.isSuccess();
}

View File

@ -0,0 +1,77 @@
package ai.chat2db.server.domain.core.impl;
import ai.chat2db.server.domain.api.param.PinTableParam;
import ai.chat2db.server.domain.api.service.PinService;
import ai.chat2db.server.domain.core.converter.PinTableConverter;
import ai.chat2db.server.domain.repository.entity.PinTableDO;
import ai.chat2db.server.domain.repository.mapper.PinTableMapper;
import ai.chat2db.server.tools.base.wrapper.result.ActionResult;
import ai.chat2db.server.tools.base.wrapper.result.ListResult;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class PinServiceImpl implements PinService {
@Autowired
private PinTableConverter pinTableConverter;
@Autowired
private PinTableMapper pinTableMapper;
@Override
public ActionResult pinTable(PinTableParam param) {
PinTableDO entity = pinTableConverter.param2do(param);
pinTableMapper.insert(entity);
return ActionResult.isSuccess();
}
@Override
public ActionResult deletePinTable(PinTableParam param) {
LambdaUpdateWrapper<PinTableDO> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(PinTableDO::getUserId, param.getUserId());
updateWrapper.eq(PinTableDO::getDataSourceId, param.getDataSourceId());
if (StringUtils.isNotBlank(param.getDatabaseName())) {
updateWrapper.eq(PinTableDO::getDatabaseName, param.getDatabaseName());
}
if (StringUtils.isNotBlank(param.getSchemaName())) {
updateWrapper.eq(PinTableDO::getSchemaName, param.getSchemaName());
}
if (StringUtils.isNotBlank(param.getTableName())) {
updateWrapper.eq(PinTableDO::getTableName, param.getTableName());
}
pinTableMapper.delete(updateWrapper);
return ActionResult.isSuccess();
}
@Override
public ListResult<String> queryPinTables(PinTableParam param) {
List<String> result = new ArrayList<>();
LambdaQueryWrapper<PinTableDO> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(PinTableDO::getUserId, param.getUserId());
queryWrapper.eq(PinTableDO::getDataSourceId, param.getDataSourceId());
if (StringUtils.isNotBlank(param.getDatabaseName())) {
queryWrapper.eq(PinTableDO::getDatabaseName, param.getDatabaseName());
}
if (StringUtils.isNotBlank(param.getSchemaName())) {
queryWrapper.eq(PinTableDO::getSchemaName, param.getSchemaName());
}
if (StringUtils.isNotBlank(param.getTableName())) {
queryWrapper.eq(PinTableDO::getTableName, param.getTableName());
}
queryWrapper.orderByDesc(PinTableDO::getGmtModified);
List<PinTableDO> list = pinTableMapper.selectList(queryWrapper);
if (!CollectionUtils.isEmpty(list)) {
result = list.stream().map(pinTableDO -> pinTableDO.getTableName()).collect(Collectors.toList());
}
return ListResult.of(result);
}
}

View File

@ -1,19 +1,22 @@
package ai.chat2db.server.domain.core.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import ai.chat2db.server.domain.api.param.*;
import ai.chat2db.server.domain.api.service.PinService;
import ai.chat2db.server.domain.api.service.TableService;
import ai.chat2db.server.domain.core.converter.PinTableConverter;
import ai.chat2db.server.tools.common.util.ContextUtils;
import ai.chat2db.spi.DBManage;
import ai.chat2db.spi.MetaData;
import ai.chat2db.spi.model.Sql;
import ai.chat2db.spi.model.Table;
import ai.chat2db.spi.model.TableColumn;
import ai.chat2db.spi.model.TableIndex;
import ai.chat2db.server.domain.api.param.DropParam;
import ai.chat2db.server.domain.api.param.ShowCreateTableParam;
import ai.chat2db.server.domain.api.param.TablePageQueryParam;
import ai.chat2db.server.domain.api.param.TableQueryParam;
import ai.chat2db.server.domain.api.param.TableSelector;
import ai.chat2db.server.tools.base.wrapper.result.ActionResult;
import ai.chat2db.server.tools.base.wrapper.result.DataResult;
import ai.chat2db.server.tools.base.wrapper.result.ListResult;
@ -22,7 +25,9 @@ import ai.chat2db.server.tools.common.util.EasyEnumUtils;
import ai.chat2db.spi.sql.Chat2DBContext;
import ai.chat2db.spi.util.SqlUtils;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
@ -33,6 +38,12 @@ import org.springframework.stereotype.Service;
@Service
public class TableServiceImpl implements TableService {
@Autowired
private PinService pinService;
@Autowired
private PinTableConverter pinTableConverter;
@Override
public DataResult<String> showCreateTable(ShowCreateTableParam param) {
MetaData metaSchema = Chat2DBContext.getMetaData();
@ -83,12 +94,42 @@ public class TableServiceImpl implements TableService {
public PageResult<Table> pageQuery(TablePageQueryParam param, TableSelector selector) {
MetaData metaSchema = Chat2DBContext.getMetaData();
List<Table> list = metaSchema.tables(param.getDatabaseName(), param.getSchemaName(), param.getTableName());
list = pinTable(list,param);
if (CollectionUtils.isEmpty(list)) {
return PageResult.of(list, 0L, param);
}
return PageResult.of(list, Long.valueOf(list.size()), param);
}
private List<Table> pinTable(List<Table> list, TablePageQueryParam param) {
if (CollectionUtils.isEmpty(list)) {
return Lists.newArrayList();
}
PinTableParam pinTableParam = pinTableConverter.toPinTableParam(param);
pinTableParam.setUserId(ContextUtils.getUserId());
ListResult<String> listResult = pinService.queryPinTables(pinTableParam);
if (!listResult.success() || CollectionUtils.isEmpty(listResult.getData())) {
return list;
}
List<Table> tables = new ArrayList<>();
Map<String, Table> tableMap = list.stream().collect(Collectors.toMap(Table::getName, Function.identity()));
for (String tableName : listResult.getData()) {
Table table = tableMap.get(tableName);
if (table != null) {
table.setPinned(true);
tables.add(table);
}
}
for (Table table : list) {
if (table!=null && !tables.contains(table)) {
tables.add(table);
}
}
return tables;
}
@Override
public List<TableColumn> queryColumns(TableQueryParam param) {
MetaData metaSchema = Chat2DBContext.getMetaData();

View File

@ -0,0 +1,61 @@
package ai.chat2db.server.domain.repository.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.time.LocalDateTime;
@Getter
@Setter
@TableName("PIN_TABLE")
public class PinTableDO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "ID", type = IdType.AUTO)
private Long id;
/**
* 创建时间
*/
private LocalDateTime gmtCreate;
/**
* 修改时间
*/
private LocalDateTime gmtModified;
/**
* 数据源连接ID
*/
private Long dataSourceId;
/**
* db名称
*/
private String databaseName;
/**
* 保存名称
*/
private String schemaName;
/**
* userId
*/
private Long userId;
/**
* tableName
*/
private String tableName;
}

View File

@ -0,0 +1,8 @@
package ai.chat2db.server.domain.repository.mapper;
import ai.chat2db.server.domain.repository.entity.PinTableDO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface PinTableMapper extends BaseMapper<PinTableDO> {
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="ai.chat2db.server.domain.repository.mapper.PinTableMapper">
</mapper>

View File

@ -0,0 +1,14 @@
CREATE TABLE IF NOT EXISTS `pin_table` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`data_source_id` bigint(20) unsigned NOT NULL COMMENT '数据源连接ID',
`database_name` varchar(128) DEFAULT NULL COMMENT 'db名称',
`schema_name` varchar(128) DEFAULT NULL COMMENT 'schema名称',
`table_name` varchar(128) DEFAULT NULL COMMENT 'table_name',
`deleted` text DEFAULT NULL COMMENT '是否被删除,y表示删除,n表示未删除',
`user_id` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '用户id',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='PIN TABLES'
;
create INDEX idx_user_id_data_source_id on pin_table(user_id,data_source_id) ;

View File

@ -0,0 +1,35 @@
package ai.chat2db.server.web.api.controller.pin;
import ai.chat2db.server.domain.api.service.PinService;
import ai.chat2db.server.tools.base.wrapper.result.ActionResult;
import ai.chat2db.server.web.api.controller.pin.converter.PinWebConverter;
import ai.chat2db.server.web.api.controller.pin.request.PinTableRequest;
import ai.chat2db.server.web.api.controller.rdb.request.DataExportRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/api/pin")
@RestController
public class PinController {
@Autowired
private PinService pinService;
@Autowired
private PinWebConverter pinWebConverter;
@PostMapping("/table/add")
public ActionResult add(PinTableRequest request) {
return pinService.pinTable(pinWebConverter.req2param(request));
}
@PostMapping("/table/delete")
public ActionResult delete(PinTableRequest request) {
return pinService.deletePinTable(pinWebConverter.req2param(request));
}
}

View File

@ -0,0 +1,12 @@
package ai.chat2db.server.web.api.controller.pin.converter;
import ai.chat2db.server.domain.api.param.PinTableParam;
import ai.chat2db.server.web.api.controller.pin.request.PinTableRequest;
import org.mapstruct.Mapper;
@Mapper(componentModel = "spring")
public abstract class PinWebConverter {
public abstract PinTableParam req2param(PinTableRequest request);
}

View File

@ -0,0 +1,35 @@
package ai.chat2db.server.web.api.controller.pin.request;
import ai.chat2db.server.web.api.controller.data.source.request.DataSourceBaseRequest;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class PinTableRequest {
/**
* 数据源id
*/
@NotNull
private Long dataSourceId;
/**
* DB名称
*/
private String databaseName;
/**
* 表所在空间
*/
private String schemaName;
/**
* Pin table name
*/
private String tableName;
}

View File

@ -2,21 +2,12 @@ package ai.chat2db.server.web.api.controller.rdb;
import java.util.List;
import ai.chat2db.server.domain.api.param.DatabaseOperationParam;
import ai.chat2db.server.domain.api.param.DropParam;
import ai.chat2db.server.domain.api.param.SchemaOperationParam;
import ai.chat2db.server.domain.api.param.SchemaQueryParam;
import ai.chat2db.server.domain.api.param.ShowCreateTableParam;
import ai.chat2db.server.domain.api.param.TablePageQueryParam;
import ai.chat2db.server.domain.api.param.TableQueryParam;
import ai.chat2db.server.domain.api.param.TableSelector;
import ai.chat2db.server.domain.api.param.*;
import ai.chat2db.server.domain.api.service.DatabaseService;
import ai.chat2db.server.domain.api.service.DlTemplateService;
import ai.chat2db.server.domain.api.service.TableService;
import ai.chat2db.spi.model.Schema;
import ai.chat2db.spi.model.Table;
import ai.chat2db.spi.model.TableColumn;
import ai.chat2db.spi.model.TableIndex;
import ai.chat2db.server.web.api.controller.rdb.vo.*;
import ai.chat2db.spi.model.*;
import ai.chat2db.server.tools.base.wrapper.result.ActionResult;
import ai.chat2db.server.tools.base.wrapper.result.DataResult;
import ai.chat2db.server.tools.base.wrapper.result.ListResult;
@ -34,11 +25,6 @@ import ai.chat2db.server.web.api.controller.rdb.request.TableModifySqlRequest;
import ai.chat2db.server.web.api.controller.rdb.request.TableUpdateDdlQueryRequest;
import ai.chat2db.server.web.api.controller.rdb.request.UpdateDatabaseRequest;
import ai.chat2db.server.web.api.controller.rdb.request.UpdateSchemaRequest;
import ai.chat2db.server.web.api.controller.rdb.vo.ColumnVO;
import ai.chat2db.server.web.api.controller.rdb.vo.IndexVO;
import ai.chat2db.server.web.api.controller.rdb.vo.SchemaVO;
import ai.chat2db.server.web.api.controller.rdb.vo.SqlVO;
import ai.chat2db.server.web.api.controller.rdb.vo.TableVO;
import com.google.common.collect.Lists;
import jakarta.validation.Valid;
@ -106,6 +92,20 @@ public class RdbDdlController {
return ListResult.of(tableVOS);
}
/**
* 查询数据库里包含的database_schema_list
*
* @param request
* @return
*/
@GetMapping("/database_schema_list")
public DataResult<MetaSchemaVO> databaseSchemaList(@Valid DataSourceBaseRequest request) {
MetaDataQueryParam queryParam = MetaDataQueryParam.builder().dataSourceId(request.getDataSourceId()).build();
DataResult<MetaSchema> result = databaseService.queryDatabaseSchema(queryParam);
MetaSchemaVO schemaDto2vo = rdbWebConverter.metaSchemaDto2vo(result.getData());
return DataResult.of(schemaDto2vo);
}
/**
* 删除数据库
*

View File

@ -8,12 +8,9 @@ import ai.chat2db.server.domain.api.param.DropParam;
import ai.chat2db.server.domain.api.param.ShowCreateTableParam;
import ai.chat2db.server.domain.api.param.TablePageQueryParam;
import ai.chat2db.server.domain.api.param.TableQueryParam;
import ai.chat2db.spi.model.ExecuteResult;
import ai.chat2db.spi.model.Schema;
import ai.chat2db.spi.model.Sql;
import ai.chat2db.spi.model.Table;
import ai.chat2db.spi.model.TableColumn;
import ai.chat2db.spi.model.TableIndex;
import ai.chat2db.server.tools.base.wrapper.result.DataResult;
import ai.chat2db.server.web.api.controller.rdb.vo.*;
import ai.chat2db.spi.model.*;
import ai.chat2db.server.web.api.controller.rdb.request.DdlCountRequest;
import ai.chat2db.server.web.api.controller.rdb.request.DdlExportRequest;
import ai.chat2db.server.web.api.controller.rdb.request.DdlRequest;
@ -22,12 +19,6 @@ import ai.chat2db.server.web.api.controller.rdb.request.TableBriefQueryRequest;
import ai.chat2db.server.web.api.controller.rdb.request.TableDeleteRequest;
import ai.chat2db.server.web.api.controller.rdb.request.TableDetailQueryRequest;
import ai.chat2db.server.web.api.controller.rdb.request.TableRequest;
import ai.chat2db.server.web.api.controller.rdb.vo.ColumnVO;
import ai.chat2db.server.web.api.controller.rdb.vo.ExecuteResultVO;
import ai.chat2db.server.web.api.controller.rdb.vo.IndexVO;
import ai.chat2db.server.web.api.controller.rdb.vo.SchemaVO;
import ai.chat2db.server.web.api.controller.rdb.vo.SqlVO;
import ai.chat2db.server.web.api.controller.rdb.vo.TableVO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
@ -199,4 +190,6 @@ public abstract class RdbWebConverter {
* @return
*/
public abstract SchemaVO schemaDto2vo(Schema dto);
public abstract MetaSchemaVO metaSchemaDto2vo(MetaSchema data);
}

View File

@ -0,0 +1,19 @@
package ai.chat2db.server.web.api.controller.rdb.vo;
import ai.chat2db.spi.model.Database;
import ai.chat2db.spi.model.Schema;
import lombok.Data;
import java.util.List;
@Data
public class MetaSchemaVO {
/**
* database list
*/
private List<Database> databases;
/**
* schema list
*/
private List<Schema> schemas;
}

View File

@ -60,5 +60,9 @@
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -6,12 +6,7 @@ package ai.chat2db.spi;
import java.util.List;
import ai.chat2db.spi.model.Function;
import ai.chat2db.spi.model.Procedure;
import ai.chat2db.spi.model.Table;
import ai.chat2db.spi.model.TableColumn;
import ai.chat2db.spi.model.TableIndex;
import ai.chat2db.spi.model.Trigger;
import ai.chat2db.spi.model.*;
import jakarta.validation.constraints.NotEmpty;
/**
@ -26,7 +21,7 @@ public interface MetaData {
*
* @return
*/
List<String> databases();
List<Database> databases();
/**
* Querying all schemas under a database
@ -34,7 +29,7 @@ public interface MetaData {
* @param databaseName
* @return
*/
List<String> schemas(String databaseName);
List<Schema> schemas(String databaseName);
/**
* Querying DDL information

View File

@ -4,16 +4,18 @@
*/
package ai.chat2db.spi.jdbc;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import ai.chat2db.spi.MetaData;
import ai.chat2db.spi.model.Function;
import ai.chat2db.spi.model.Procedure;
import ai.chat2db.spi.model.Table;
import ai.chat2db.spi.model.TableColumn;
import ai.chat2db.spi.model.TableIndex;
import ai.chat2db.spi.model.Trigger;
import ai.chat2db.spi.model.*;
import ai.chat2db.spi.sql.SQLExecutor;
import cn.hutool.json.JSON;
import com.google.common.collect.Lists;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.util.CollectionUtils;
/**
* @author jipengfei
@ -21,13 +23,32 @@ import ai.chat2db.spi.sql.SQLExecutor;
*/
public class DefaultMetaService implements MetaData {
@Override
public List<String> databases() {
return SQLExecutor.getInstance().databases();
public List<Database> databases() {
List<String> dataBases = SQLExecutor.getInstance().databases();
if (CollectionUtils.isEmpty(dataBases)) {
return Lists.newArrayList();
}
return dataBases.stream().map(str -> Database.builder().name(str).build()).collect(Collectors.toList());
}
@Override
public List<String> schemas(String databaseName) {
return SQLExecutor.getInstance().schemas(databaseName, null);
public List<Schema> schemas(String databaseName) {
List<Map<String, String>> maps = SQLExecutor.getInstance().schemas(databaseName, null);
if (CollectionUtils.isEmpty(maps)) {
return Lists.newArrayList();
}
return maps.stream().map(map -> map2Schema(map)).collect(Collectors.toList());
}
private Schema map2Schema(Map<String, String> map) {
Schema schema = new Schema();
try {
BeanUtils.populate(schema, map);
} catch (Exception e) {
}
return schema;
}
@Override
@ -37,12 +58,12 @@ public class DefaultMetaService implements MetaData {
@Override
public List<Table> tables(String databaseName, String schemaName, String tableName) {
return SQLExecutor.getInstance().tables(databaseName, schemaName, tableName, new String[] {"TABLE"});
return SQLExecutor.getInstance().tables(databaseName, schemaName, tableName, new String[]{"TABLE"});
}
@Override
public List<? extends Table> views(String databaseName, String schemaName) {
return SQLExecutor.getInstance().tables(databaseName, schemaName, null, new String[] {"VIEW"});
return SQLExecutor.getInstance().tables(databaseName, schemaName, null, new String[]{"VIEW"});
}
@Override

View File

@ -5,6 +5,8 @@ import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.util.List;
/**
* 数据库
*
@ -16,7 +18,12 @@ import lombok.experimental.SuperBuilder;
@AllArgsConstructor
public class Database {
/**
* 数据名字
* 数据名字
*/
private String name;
/**
* schema name
*/
private List<Schema> schemas;
}

View File

@ -0,0 +1,25 @@
package ai.chat2db.spi.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.util.List;
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class MetaSchema {
/**
* database list
*/
private List<Database> databases;
/**
* schema list
*/
private List<Schema> schemas;
}

View File

@ -18,6 +18,11 @@ import lombok.experimental.SuperBuilder;
@NoArgsConstructor
@AllArgsConstructor
public class Schema {
/**
* databaseName
*/
private String databaseName;
/**
* 数据名字
*/

View File

@ -59,6 +59,9 @@ public class Table {
*/
private String type;
/**
* 是否置顶
*/
private boolean pinned;
}

View File

@ -9,7 +9,9 @@ import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
@ -203,13 +205,16 @@ public class SQLExecutor {
* @param schemaName
* @return
*/
public List<String> schemas(String databaseName, String schemaName) {
List<String> schemaList = Lists.newArrayList();
public List<Map<String,String>> schemas(String databaseName, String schemaName) {
List<Map<String,String>> schemaList = Lists.newArrayList();
try {
ResultSet resultSet = getConnection().getMetaData().getSchemas(databaseName, schemaName);
if (resultSet != null) {
while (resultSet.next()) {
schemaList.add(resultSet.getString("TABLE_SCHEM"));
Map<String,String> map = new HashMap<>();
map.put("name",resultSet.getString("TABLE_SCHEM"));
map.put("databaseName",resultSet.getString("TABLE_CATALOG"));
schemaList.add(map);
}
}
} catch (SQLException e) {

View File

@ -217,6 +217,11 @@
<version>6.0.10</version>
<scope>optional</scope>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.4</version>
</dependency>
</dependencies>
</dependencyManagement>