chore: initialize qiming workspace repository
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
package com.xspaceagi.compose.infra.dao.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 自定义字段定义
|
||||
*/
|
||||
@Schema(description = "自定义字段定义")
|
||||
@TableName(value = "custom_field_definition")
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
public class CustomFieldDefinition {
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@Schema(description = "主键ID")
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 是否为系统字段,1:系统字段;-1:非系统字段
|
||||
*/
|
||||
@Schema(description = "是否为系统字段,1:系统字段;-1:非系统字段")
|
||||
private Integer systemFieldFlag;
|
||||
|
||||
/**
|
||||
* 租户ID
|
||||
*/
|
||||
@Schema(description = "租户ID")
|
||||
@TableField(value = "_tenant_id")
|
||||
private Long tenantId;
|
||||
|
||||
/**
|
||||
* 所属空间ID
|
||||
*/
|
||||
@Schema(description = "所属空间ID")
|
||||
private Long spaceId;
|
||||
|
||||
/**
|
||||
* 关联的表ID
|
||||
*/
|
||||
@Schema(description = "关联的表ID")
|
||||
private Long tableId;
|
||||
|
||||
/**
|
||||
* 字段名
|
||||
*/
|
||||
@Schema(description = "字段名")
|
||||
private String fieldName;
|
||||
|
||||
/**
|
||||
* 字段描述
|
||||
*/
|
||||
@Schema(description = "字段描述")
|
||||
private String fieldDescription;
|
||||
|
||||
/**
|
||||
* 字段类型:1:String;2:Integer;3:Number;4:Boolean;5:Date
|
||||
*/
|
||||
@Schema(description = "字段类型:1:String;2:Integer;3:Number;4:Boolean;5:Date")
|
||||
private Integer fieldType;
|
||||
|
||||
/**
|
||||
* 是否可为空:1-可空 -1-非空
|
||||
*/
|
||||
@Schema(description = "是否可为空:1-可空 -1-非空")
|
||||
private Integer nullableFlag;
|
||||
|
||||
/**
|
||||
* 默认值
|
||||
*/
|
||||
@Schema(description = "默认值")
|
||||
@TableField(updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String defaultValue;
|
||||
|
||||
/**
|
||||
* 是否唯一:1-唯一 -1-非唯一
|
||||
*/
|
||||
@Schema(description = "是否唯一:1-唯一 -1-非唯一")
|
||||
private Integer uniqueFlag;
|
||||
|
||||
/**
|
||||
* 是否启用:1-启用 -1-禁用
|
||||
*/
|
||||
@Schema(description = "是否启用:1-启用 -1-禁用")
|
||||
private Integer enabledFlag;
|
||||
|
||||
/**
|
||||
* 字段顺序
|
||||
*/
|
||||
@Schema(description = "字段顺序")
|
||||
private Integer sortIndex;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime created;
|
||||
|
||||
/**
|
||||
* 字符串字段长度,可空,比如字符串,可以指定长度使用
|
||||
*/
|
||||
@Schema(description = "字符串字段长度,可空,比如字符串,可以指定长度使用")
|
||||
private Integer fieldStrLen;
|
||||
|
||||
/**
|
||||
* 创建人id
|
||||
*/
|
||||
@Schema(description = "创建人id")
|
||||
private Long creatorId;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
@Schema(description = "创建人")
|
||||
private String creatorName;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@Schema(description = "更新时间")
|
||||
private LocalDateTime modified;
|
||||
|
||||
/**
|
||||
* 最后修改人id
|
||||
*/
|
||||
@Schema(description = "最后修改人id")
|
||||
private Long modifiedId;
|
||||
|
||||
/**
|
||||
* 最后修改人
|
||||
*/
|
||||
@Schema(description = "最后修改人")
|
||||
private String modifiedName;
|
||||
|
||||
/**
|
||||
* 逻辑标记,1:有效;-1:无效
|
||||
*/
|
||||
@Schema(description = "逻辑标记,1:有效;-1:无效")
|
||||
private Integer yn;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
package com.xspaceagi.compose.infra.dao.entity;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 自定义数据表定义
|
||||
*/
|
||||
@Schema(description = "自定义数据表定义")
|
||||
@TableName(value = "custom_table_definition")
|
||||
@Getter
|
||||
@Setter
|
||||
public class CustomTableDefinition {
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@Schema(description = "主键ID")
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 租户ID
|
||||
*/
|
||||
@Schema(description = "租户ID")
|
||||
@TableField(value = "_tenant_id")
|
||||
private Long tenantId;
|
||||
|
||||
/**
|
||||
* 所属空间ID
|
||||
*/
|
||||
@Schema(description = "所属空间ID")
|
||||
private Long spaceId;
|
||||
|
||||
/**
|
||||
* 图标图片地址
|
||||
*/
|
||||
@Schema(description = "图标图片地址")
|
||||
private String icon;
|
||||
|
||||
/**
|
||||
* 表名
|
||||
*/
|
||||
@Schema(description = "表名")
|
||||
private String tableName;
|
||||
|
||||
/**
|
||||
* 表描述
|
||||
*/
|
||||
@Schema(description = "表描述")
|
||||
private String tableDescription;
|
||||
|
||||
/**
|
||||
* Doris数据库名
|
||||
*/
|
||||
@Schema(description = "Doris数据库名")
|
||||
private String dorisDatabase;
|
||||
|
||||
/**
|
||||
* Doris表名
|
||||
*/
|
||||
@Schema(description = "Doris表名")
|
||||
private String dorisTable;
|
||||
|
||||
/**
|
||||
* 状态:1-启用 -1-禁用
|
||||
*/
|
||||
@Schema(description = "状态:1-启用 -1-禁用")
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime created;
|
||||
|
||||
/**
|
||||
* 创建人id
|
||||
*/
|
||||
@Schema(description = "创建人id")
|
||||
private Long creatorId;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
@Schema(description = "创建人")
|
||||
private String creatorName;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@Schema(description = "更新时间")
|
||||
private LocalDateTime modified;
|
||||
|
||||
/**
|
||||
* 最后修改人id
|
||||
*/
|
||||
@Schema(description = "最后修改人id")
|
||||
private Long modifiedId;
|
||||
|
||||
/**
|
||||
* 最后修改人
|
||||
*/
|
||||
@Schema(description = "最后修改人")
|
||||
private String modifiedName;
|
||||
|
||||
/**
|
||||
* 逻辑标记,1:有效;-1:无效
|
||||
*/
|
||||
@Schema(description = "逻辑标记,1:有效;-1:无效")
|
||||
private Integer yn;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.xspaceagi.compose.infra.dao.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.xspaceagi.compose.infra.dao.entity.CustomFieldDefinition;
|
||||
|
||||
public interface CustomFieldDefinitionMapper extends BaseMapper<CustomFieldDefinition> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.xspaceagi.compose.infra.dao.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.OrderItem;
|
||||
import com.xspaceagi.compose.infra.dao.entity.CustomTableDefinition;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
|
||||
public interface CustomTableDefinitionMapper extends BaseMapper<CustomTableDefinition> {
|
||||
|
||||
/**
|
||||
* 总条数查询
|
||||
*
|
||||
* @param queryMap 筛选条件
|
||||
* @return 总条数
|
||||
*/
|
||||
Long queryTotal(@Param("queryMap") Map<String, Object> queryMap);
|
||||
|
||||
/**
|
||||
* 列表查询
|
||||
*
|
||||
* @param queryMap 筛选条件
|
||||
* @param orderColumns 排序
|
||||
* @param startIndex 索引开始位置
|
||||
* @param pageSize 业务大小
|
||||
* @return 列表
|
||||
*/
|
||||
List<CustomTableDefinition> queryList(@Param("queryMap") Map<String, Object> queryMap,
|
||||
@Param("orderColumns") List<OrderItem> orderColumns,
|
||||
@Param("startIndex") Long startIndex, @Param("pageSize") Long pageSize);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.xspaceagi.compose.infra.dao.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.xspaceagi.compose.infra.dao.entity.CustomFieldDefinition;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 数据表的字段定义
|
||||
*/
|
||||
public interface CustomFieldDefinitionService extends IService<CustomFieldDefinition> {
|
||||
|
||||
/**
|
||||
* 根据ID集合查询列表
|
||||
*
|
||||
* @param ids id集合
|
||||
* @return 列表
|
||||
*/
|
||||
List<CustomFieldDefinition> queryListByIds(List<Long> ids);
|
||||
|
||||
/**
|
||||
* 根据主键查询 单条记录
|
||||
*
|
||||
* @param id id
|
||||
* @return 单条记录
|
||||
*/
|
||||
CustomFieldDefinition queryOneInfoById(Long id);
|
||||
|
||||
/**
|
||||
* 根据表id查询记录数
|
||||
*
|
||||
* @param tableId 表id
|
||||
* @return 记录数
|
||||
*/
|
||||
Long queryCountByTableId(Long tableId);
|
||||
|
||||
/**
|
||||
* 更新
|
||||
*
|
||||
* @param entity entity
|
||||
* @return id
|
||||
*/
|
||||
Long updateInfo(CustomFieldDefinition entity);
|
||||
|
||||
/**
|
||||
* 新增
|
||||
*/
|
||||
Long addInfo(CustomFieldDefinition entity);
|
||||
|
||||
/**
|
||||
* 批量新增
|
||||
*
|
||||
* @param entityList 新增列表
|
||||
* @param userContext 用户上下文
|
||||
*/
|
||||
void batchAddInfo(List<CustomFieldDefinition> entityList);
|
||||
|
||||
/**
|
||||
* 批量更新
|
||||
*
|
||||
* @param entityList 更新列表
|
||||
* @param userContext 用户上下文
|
||||
*/
|
||||
void batchUpdateInfo(List<CustomFieldDefinition> entityList);
|
||||
|
||||
/**
|
||||
* 删除根据主键id
|
||||
*
|
||||
* @param id id
|
||||
*/
|
||||
void deleteById(Long id);
|
||||
|
||||
/**
|
||||
* 根据表id删除
|
||||
*
|
||||
* @param tableId 表id
|
||||
*/
|
||||
void deleteByTableId(Long tableId);
|
||||
|
||||
/**
|
||||
* 根据表id查询列表
|
||||
*
|
||||
* @param tableId 表id
|
||||
* @return 列表
|
||||
*/
|
||||
List<CustomFieldDefinition> queryListByTableId(Long tableId);
|
||||
|
||||
/**
|
||||
* 根据表id集合查询列表
|
||||
*
|
||||
* @param tableIds 表id集合
|
||||
* @return 列表
|
||||
*/
|
||||
List<CustomFieldDefinition> queryListByTableIds(List<Long> tableIds);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.xspaceagi.compose.infra.dao.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.OrderItem;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.xspaceagi.compose.infra.dao.entity.CustomFieldDefinition;
|
||||
import com.xspaceagi.compose.infra.dao.entity.CustomTableDefinition;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 自定义数据表定义服务
|
||||
*/
|
||||
public interface CustomTableDefinitionService extends IService<CustomTableDefinition> {
|
||||
|
||||
/**
|
||||
* 根据ID集合查询列表
|
||||
*
|
||||
* @param ids id集合
|
||||
* @return 列表
|
||||
*/
|
||||
List<CustomTableDefinition> queryListByIds(List<Long> ids);
|
||||
|
||||
/**
|
||||
* 根据主键查询 单条记录
|
||||
*
|
||||
* @param id id
|
||||
* @return 单条记录
|
||||
*/
|
||||
CustomTableDefinition queryOneInfoById(Long id);
|
||||
|
||||
/**
|
||||
* 更新
|
||||
*
|
||||
* @param entity entity
|
||||
* @return id
|
||||
*/
|
||||
Long updateInfo(CustomTableDefinition entity);
|
||||
|
||||
/**
|
||||
* 新增
|
||||
*/
|
||||
Long addInfo(CustomTableDefinition entity);
|
||||
|
||||
/**
|
||||
* 删除根据主键id
|
||||
*
|
||||
* @param id id
|
||||
*/
|
||||
void deleteById(Long id);
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
*
|
||||
* @param queryMap 查询条件
|
||||
* @param orderColumns 排序条件
|
||||
* @param startIndex 开始索引
|
||||
* @param pageSize 页大小
|
||||
* @return 分页数据
|
||||
*/
|
||||
List<CustomTableDefinition> pageQuery(Map<String, Object> queryMap, List<OrderItem> orderColumns, Long startIndex, Long pageSize);
|
||||
|
||||
/**
|
||||
* 查询总数
|
||||
*
|
||||
* @param queryMap 查询条件
|
||||
* @return 总数
|
||||
*/
|
||||
Long queryTotal(Map<String, Object> queryMap);
|
||||
|
||||
/**
|
||||
* 根据条件查询表定义列表
|
||||
*
|
||||
* @param condition 查询条件
|
||||
* @return 表定义列表
|
||||
*/
|
||||
List<CustomTableDefinition> queryListByCondition(CustomTableDefinition condition);
|
||||
|
||||
/**
|
||||
* 根据空间ID查询表定义列表
|
||||
*
|
||||
* @param spaceId 空间ID
|
||||
* @return 表定义列表
|
||||
*/
|
||||
List<CustomTableDefinition> queryListBySpaceId(Long spaceId);
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package com.xspaceagi.compose.infra.dao.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.xspaceagi.compose.infra.dao.entity.CustomFieldDefinition;
|
||||
import com.xspaceagi.compose.infra.dao.mapper.CustomFieldDefinitionMapper;
|
||||
import com.xspaceagi.compose.infra.dao.service.CustomFieldDefinitionService;
|
||||
import com.xspaceagi.system.spec.enums.YnEnum;
|
||||
import com.xspaceagi.system.spec.exception.BizExceptionCodeEnum;
|
||||
import com.xspaceagi.system.spec.exception.ComposeException;
|
||||
|
||||
@Service
|
||||
public class CustomFieldDefinitionServiceImpl extends ServiceImpl<CustomFieldDefinitionMapper, CustomFieldDefinition>
|
||||
implements CustomFieldDefinitionService {
|
||||
|
||||
@Autowired
|
||||
private CustomFieldDefinitionMapper customFieldDefinitionMapper;
|
||||
|
||||
@Override
|
||||
public List<CustomFieldDefinition> queryListByIds(List<Long> ids) {
|
||||
LambdaQueryWrapper<CustomFieldDefinition> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(CustomFieldDefinition::getYn, YnEnum.Y.getKey())
|
||||
.in(CustomFieldDefinition::getId, ids);
|
||||
return this.list(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomFieldDefinition queryOneInfoById(Long id) {
|
||||
LambdaQueryWrapper<CustomFieldDefinition> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(CustomFieldDefinition::getYn, YnEnum.Y.getKey())
|
||||
.eq(CustomFieldDefinition::getId, id);
|
||||
return this.getOne(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long updateInfo(CustomFieldDefinition entity) {
|
||||
var updateObj = this.getById(entity.getId());
|
||||
|
||||
if (Objects.isNull(updateObj)) {
|
||||
throw ComposeException.build(BizExceptionCodeEnum.resourceDataNotFound);
|
||||
}
|
||||
entity.setCreated(null);
|
||||
entity.setModified(null);
|
||||
this.updateById(entity);
|
||||
return entity.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long addInfo(CustomFieldDefinition entity) {
|
||||
entity.setId(null);
|
||||
entity.setCreated(null);
|
||||
entity.setModified(null);
|
||||
this.save(entity);
|
||||
return entity.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteById(Long id) {
|
||||
var existObj = this.getById(id);
|
||||
if (Objects.isNull(existObj)) {
|
||||
throw ComposeException.build(BizExceptionCodeEnum.resourceDataNotFound);
|
||||
}
|
||||
this.removeById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CustomFieldDefinition> queryListByTableId(Long tableId) {
|
||||
LambdaQueryWrapper<CustomFieldDefinition> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(CustomFieldDefinition::getYn, YnEnum.Y.getKey())
|
||||
.eq(CustomFieldDefinition::getTableId, tableId);
|
||||
return this.list(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CustomFieldDefinition> queryListByTableIds(List<Long> tableIds) {
|
||||
LambdaQueryWrapper<CustomFieldDefinition> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(CustomFieldDefinition::getYn, YnEnum.Y.getKey())
|
||||
.in(CustomFieldDefinition::getTableId, tableIds);
|
||||
return this.list(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void batchAddInfo(List<CustomFieldDefinition> entityList) {
|
||||
entityList.forEach(entity -> {
|
||||
entity.setId(null);
|
||||
entity.setCreated(null);
|
||||
entity.setModified(null);
|
||||
});
|
||||
this.saveBatch(entityList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void batchUpdateInfo(List<CustomFieldDefinition> entityList) {
|
||||
entityList.forEach(entity -> {
|
||||
entity.setModified(null);
|
||||
});
|
||||
this.updateBatchById(entityList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByTableId(Long tableId) {
|
||||
LambdaQueryWrapper<CustomFieldDefinition> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(CustomFieldDefinition::getTableId, tableId);
|
||||
this.remove(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long queryCountByTableId(Long tableId) {
|
||||
LambdaQueryWrapper<CustomFieldDefinition> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(CustomFieldDefinition::getTableId, tableId);
|
||||
return this.count(queryWrapper);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
package com.xspaceagi.compose.infra.dao.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.OrderItem;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.xspaceagi.compose.infra.dao.entity.CustomTableDefinition;
|
||||
import com.xspaceagi.compose.infra.dao.mapper.CustomTableDefinitionMapper;
|
||||
import com.xspaceagi.compose.infra.dao.service.CustomTableDefinitionService;
|
||||
import com.xspaceagi.system.spec.enums.YnEnum;
|
||||
import com.xspaceagi.system.spec.exception.BizExceptionCodeEnum;
|
||||
import com.xspaceagi.system.spec.exception.ComposeException;
|
||||
|
||||
@Service
|
||||
public class CustomTableDefinitionServiceImpl extends ServiceImpl<CustomTableDefinitionMapper, CustomTableDefinition>
|
||||
implements CustomTableDefinitionService {
|
||||
|
||||
@Autowired
|
||||
private CustomTableDefinitionMapper customTableDefinitionMapper;
|
||||
|
||||
@Override
|
||||
public List<CustomTableDefinition> queryListByIds(List<Long> ids) {
|
||||
LambdaQueryWrapper<CustomTableDefinition> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(CustomTableDefinition::getYn, YnEnum.Y.getKey())
|
||||
.in(CustomTableDefinition::getId, ids);
|
||||
return this.list(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomTableDefinition queryOneInfoById(Long id) {
|
||||
LambdaQueryWrapper<CustomTableDefinition> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(CustomTableDefinition::getYn, YnEnum.Y.getKey())
|
||||
.eq(CustomTableDefinition::getId, id);
|
||||
return this.getOne(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long updateInfo(CustomTableDefinition entity) {
|
||||
var updateObj = this.getById(entity.getId());
|
||||
|
||||
if (Objects.isNull(updateObj)) {
|
||||
throw ComposeException.build(BizExceptionCodeEnum.resourceDataNotFound);
|
||||
}
|
||||
entity.setCreated(null);
|
||||
entity.setModified(null);
|
||||
this.updateById(entity);
|
||||
return entity.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long addInfo(CustomTableDefinition entity) {
|
||||
entity.setId(null);
|
||||
entity.setCreated(null);
|
||||
entity.setModified(null);
|
||||
this.save(entity);
|
||||
return entity.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteById(Long id) {
|
||||
var existObj = this.getById(id);
|
||||
if (Objects.isNull(existObj)) {
|
||||
throw ComposeException.build(BizExceptionCodeEnum.resourceDataNotFound);
|
||||
}
|
||||
this.removeById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CustomTableDefinition> pageQuery(Map<String, Object> queryMap, List<OrderItem> orderColumns, Long startIndex, Long pageSize) {
|
||||
return customTableDefinitionMapper.queryList(queryMap, orderColumns, startIndex, pageSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long queryTotal(Map<String, Object> queryMap) {
|
||||
return customTableDefinitionMapper.queryTotal(queryMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CustomTableDefinition> queryListByCondition(CustomTableDefinition condition) {
|
||||
LambdaQueryWrapper<CustomTableDefinition> wrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
// 添加租户ID条件(必填)
|
||||
wrapper.eq(CustomTableDefinition::getTenantId, condition.getTenantId());
|
||||
|
||||
// 添加空间ID条件(可选)
|
||||
if (condition.getSpaceId() != null) {
|
||||
wrapper.eq(CustomTableDefinition::getSpaceId, condition.getSpaceId());
|
||||
}
|
||||
|
||||
// 添加表名模糊查询条件(可选)
|
||||
if (StringUtils.hasText(condition.getTableName())) {
|
||||
wrapper.like(CustomTableDefinition::getTableName, condition.getTableName());
|
||||
}
|
||||
|
||||
// 添加表描述模糊查询条件(可选)
|
||||
if (StringUtils.hasText(condition.getTableDescription())) {
|
||||
wrapper.like(CustomTableDefinition::getTableDescription, condition.getTableDescription());
|
||||
}
|
||||
|
||||
// 添加状态条件(可选)
|
||||
if (condition.getStatus() != null) {
|
||||
wrapper.eq(CustomTableDefinition::getStatus, condition.getStatus());
|
||||
} else {
|
||||
// 默认只查询启用状态的表定义
|
||||
wrapper.eq(CustomTableDefinition::getStatus, 1);
|
||||
}
|
||||
|
||||
// 按创建时间降序排序
|
||||
wrapper.orderByDesc(CustomTableDefinition::getId);
|
||||
|
||||
return this.list(wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CustomTableDefinition> queryListBySpaceId(Long spaceId) {
|
||||
if (spaceId == null) {
|
||||
return List.of();
|
||||
}
|
||||
LambdaQueryWrapper<CustomTableDefinition> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(CustomTableDefinition::getSpaceId, spaceId);
|
||||
wrapper.eq(CustomTableDefinition::getYn, YnEnum.Y.getKey());
|
||||
return this.list(wrapper);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,856 @@
|
||||
package com.xspaceagi.compose.infra.respository;
|
||||
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
|
||||
import com.baomidou.dynamic.datasource.tx.DsPropagation;
|
||||
import com.xspaceagi.compose.domain.repository.ICustomDorisTableRepository;
|
||||
import com.xspaceagi.compose.domain.util.SqlParserUtil;
|
||||
import com.xspaceagi.compose.domain.util.SqlParserUtil.SqlType;
|
||||
import com.xspaceagi.compose.domain.util.TableDbWrapperUtil;
|
||||
import com.xspaceagi.compose.sdk.enums.TableFieldTypeEnum;
|
||||
import com.xspaceagi.compose.sdk.vo.data.ExecuteRawResultVo;
|
||||
import com.xspaceagi.compose.sdk.vo.doris.DorisTableDefinitionVo;
|
||||
import com.xspaceagi.compose.sdk.vo.doris.DorisTableFieldVo;
|
||||
import com.xspaceagi.compose.sdk.vo.doris.DorisTableIndexVo;
|
||||
import com.xspaceagi.compose.spec.constants.DorisConfigContants;
|
||||
import com.xspaceagi.compose.spec.utils.ComposeExceptionUtils;
|
||||
import com.xspaceagi.compose.spec.utils.DDLSqlParseUtil;
|
||||
import com.xspaceagi.system.spec.exception.BizExceptionCodeEnum;
|
||||
import com.xspaceagi.system.spec.exception.ComposeException;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.sf.jsqlparser.JSQLParserException;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.jdbc.BadSqlGrammarException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.support.GeneratedKeyHolder;
|
||||
import org.springframework.jdbc.support.KeyHolder;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Slf4j
|
||||
@Repository
|
||||
@DS("doris")
|
||||
public class CustomDorisTableRepository implements ICustomDorisTableRepository {
|
||||
|
||||
@Resource
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
|
||||
@Resource
|
||||
private TableDbWrapperUtil tableDbWrapperUtil;
|
||||
|
||||
@Lazy
|
||||
@Resource
|
||||
private CustomDorisTableRepository self;
|
||||
|
||||
@DS("doris")
|
||||
@Override
|
||||
public boolean hasData(String database, String table) {
|
||||
String sql = "SELECT COUNT(*) FROM `" + database + "`.`" + table + "` LIMIT 1";
|
||||
Integer count = jdbcTemplate.queryForObject(sql, Integer.class);
|
||||
return count != null && count > 0;
|
||||
|
||||
}
|
||||
|
||||
@DSTransactional(propagation = DsPropagation.NOT_SUPPORTED)
|
||||
@Override
|
||||
public boolean tableExists(String database, String table) {
|
||||
|
||||
String sql = tableDbWrapperUtil.getTableExistsSql(database, table);
|
||||
List<Map<String, Object>> result = jdbcTemplate.queryForList(sql);
|
||||
return !result.isEmpty();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeCreateTable(String createTableSql) {
|
||||
jdbcTemplate.execute(createTableSql);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createUniqueIndex(String database, String table, String fieldName) {
|
||||
String sql = tableDbWrapperUtil.buildCreateUniqueIndexSql(database, table, fieldName);
|
||||
log.info("Create unique index, sql={}", sql);
|
||||
jdbcTemplate.execute(sql);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropTable(String database, String table) {
|
||||
String sql = "DROP TABLE IF EXISTS `" + database + "`.`" + table + "`";
|
||||
jdbcTemplate.execute(sql);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void truncateTable(String database, String table) {
|
||||
String sql = "TRUNCATE TABLE `" + database + "`.`" + table + "`";
|
||||
jdbcTemplate.execute(sql);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFieldValueUnique(String database, String table, String fieldName, String fieldValue) {
|
||||
String sql = "SELECT COUNT(*) FROM `" + database + "`.`" + table + "` WHERE `" + fieldName + "` = ?";
|
||||
Integer count = jdbcTemplate.queryForObject(sql, Integer.class, fieldValue);
|
||||
return count != null && count.equals(0);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeAlterTable(String database, String table, String alterSql) {
|
||||
try {
|
||||
log.debug("Execute Doris ALTER SQL: {}", alterSql);
|
||||
jdbcTemplate.execute(alterSql);
|
||||
} catch (Exception e) {
|
||||
log.error("Doris schema change error, database: {}, table: {}, sql: {}", database, table, alterSql, e);
|
||||
var errorMessage = ComposeExceptionUtils.getRootErrorMessage(e);
|
||||
throw ComposeException.build(BizExceptionCodeEnum.composeSqlExecuteFailed, errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int deleteTableDataById(String database, String table, Long id) {
|
||||
try {
|
||||
String sql = "DELETE FROM `" + database + "`.`" + table + "` WHERE id = ?";
|
||||
return jdbcTemplate.update(sql, id);
|
||||
} catch (Exception e) {
|
||||
log.error("Doris delete row error, database: {}, table: {}, id: {}", database, table, id, e);
|
||||
throw ComposeException.build(BizExceptionCodeEnum.resourceDataNotFound, "删除数据失败");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DorisTableDefinitionVo getTableDefinition(String database, String table) {
|
||||
try {
|
||||
// 1. 获取表的建表 DDL
|
||||
String createTableDdl = getCreateTableDdl(database, table);
|
||||
log.info("Table DDL: database={}, table={}, ddl={}", database, table, createTableDdl);
|
||||
|
||||
// 2. 获取表的字段信息
|
||||
String descTableSql = "DESC `" + database + "`.`" + table + "`";
|
||||
List<Map<String, Object>> fieldsResult = jdbcTemplate.queryForList(descTableSql);
|
||||
|
||||
// 3. 获取表的索引信息
|
||||
String showIndexSql = "SHOW INDEX FROM `" + database + "`.`" + table + "`";
|
||||
List<Map<String, Object>> indexesResult = jdbcTemplate.queryForList(showIndexSql);
|
||||
|
||||
// 4. 构建返回对象
|
||||
DorisTableDefinitionVo definition = new DorisTableDefinitionVo();
|
||||
definition.setDatabase(database);
|
||||
definition.setTable(table);
|
||||
definition.setCreateTableDdl(createTableDdl);
|
||||
|
||||
// 调用新的工具类方法进行解析
|
||||
DDLSqlParseUtil.parseCreateTableDdl(createTableDdl, definition);
|
||||
|
||||
// 构建字段列表
|
||||
List<DorisTableFieldVo> fields = new ArrayList<>();
|
||||
for (Map<String, Object> field : fieldsResult) {
|
||||
|
||||
var fieldType = (String) field.get("Type");
|
||||
// 根据Doris/MySQL 类型获取枚举值
|
||||
var fieldTypeEnum = TableFieldTypeEnum.tryGetByDorisType(fieldType);
|
||||
var fieldTypeInteger = Optional.ofNullable(fieldTypeEnum).map(TableFieldTypeEnum::getCode).orElse(null);
|
||||
DorisTableFieldVo fieldVo = DorisTableFieldVo.builder()
|
||||
.fieldName((String) field.get("Field"))
|
||||
.fieldType(fieldTypeInteger)
|
||||
.fieldTypeDesc(fieldType)
|
||||
.nullable("YES".equals(field.get("Null")))
|
||||
.defaultValue((String) field.get("Default"))
|
||||
.comment((String) field.get("Comment"))
|
||||
.build();
|
||||
fields.add(fieldVo);
|
||||
}
|
||||
definition.setFields(fields);
|
||||
|
||||
// 构建索引列表
|
||||
Map<String, DorisTableIndexVo> indexMap = new HashMap<>();
|
||||
for (Map<String, Object> index : indexesResult) {
|
||||
String indexName = (String) index.get("Key_name");
|
||||
String column = (String) index.get("Column_name");
|
||||
String indexType = (String) index.get("Index_type");
|
||||
String indexComment = (String) index.get("Index_comment");
|
||||
|
||||
DorisTableIndexVo indexVo = indexMap.computeIfAbsent(indexName, k -> {
|
||||
DorisTableIndexVo vo = new DorisTableIndexVo();
|
||||
vo.setIndexName(indexName);
|
||||
vo.setIndexType(indexType);
|
||||
vo.setComment(indexComment);
|
||||
vo.setIndexColumns(column);
|
||||
return vo;
|
||||
});
|
||||
|
||||
// 如果已存在,则追加列名
|
||||
if (!column.equals(indexVo.getIndexColumns())) {
|
||||
indexVo.setIndexColumns(indexVo.getIndexColumns() + "," + column);
|
||||
}
|
||||
}
|
||||
definition.setIndexes(new ArrayList<>(indexMap.values()));
|
||||
|
||||
return definition;
|
||||
} catch (Exception e) {
|
||||
log.error("Get Doris table definition error, database: {}, table: {}", database, table, e);
|
||||
throw ComposeException.build(BizExceptionCodeEnum.resourceDataNotFound, "获取表定义失败");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insertRow(String database, String table, Map<String, Object> data) {
|
||||
try {
|
||||
if (data == null || data.isEmpty()) {
|
||||
throw ComposeException.build(BizExceptionCodeEnum.resourceDataNotFound, "插入数据不能为空");
|
||||
}
|
||||
|
||||
StringBuilder sql = new StringBuilder("INSERT INTO `").append(database).append("`.`")
|
||||
.append(table).append("` (");
|
||||
StringBuilder values = new StringBuilder(") VALUES (");
|
||||
List<Object> params = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<String, Object> entry : data.entrySet()) {
|
||||
sql.append("`").append(entry.getKey()).append("`,");
|
||||
values.append("?,");
|
||||
params.add(entry.getValue());
|
||||
}
|
||||
|
||||
// 移除最后的逗号
|
||||
sql.setLength(sql.length() - 1);
|
||||
values.setLength(values.length() - 1);
|
||||
sql.append(values).append(")");
|
||||
|
||||
return jdbcTemplate.update(sql.toString(), params.toArray());
|
||||
} catch (Exception e) {
|
||||
log.error("Doris insert error, database: {}, table: {}, data: {}", database, table, data, e);
|
||||
throw ComposeException.build(BizExceptionCodeEnum.resourceDataNotFound, "插入数据失败");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batchInsert(String database, String table, List<Map<String, Object>> dataList) {
|
||||
try {
|
||||
if (CollectionUtils.isEmpty(dataList)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 获取所有字段名
|
||||
Set<String> allFields = new HashSet<>();
|
||||
for (Map<String, Object> data : dataList) {
|
||||
allFields.addAll(data.keySet());
|
||||
}
|
||||
|
||||
StringBuilder sql = new StringBuilder("INSERT INTO `").append(database).append("`.`")
|
||||
.append(table).append("` (");
|
||||
|
||||
// 构建字段列表
|
||||
for (String field : allFields) {
|
||||
sql.append("`").append(field).append("`,");
|
||||
}
|
||||
sql.setLength(sql.length() - 1);
|
||||
sql.append(") VALUES ");
|
||||
|
||||
// 构建值占位符
|
||||
String valuePlaceholder = "(" + String.join(",", Collections.nCopies(allFields.size(), "?")) + ")";
|
||||
List<String> valuePlaceholders = Collections.nCopies(dataList.size(), valuePlaceholder);
|
||||
sql.append(String.join(",", valuePlaceholders));
|
||||
|
||||
// 准备参数
|
||||
List<Object> params = new ArrayList<>();
|
||||
for (Map<String, Object> data : dataList) {
|
||||
for (String field : allFields) {
|
||||
params.add(data.get(field));
|
||||
}
|
||||
}
|
||||
|
||||
return jdbcTemplate.update(sql.toString(), params.toArray());
|
||||
} catch (Exception e) {
|
||||
log.error("Doris batch insert error, database: {}, table: {}, dataSize: {}",
|
||||
database, table, dataList.size(), e);
|
||||
throw ComposeException.build(BizExceptionCodeEnum.resourceDataNotFound, "批量插入数据失败");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateRow(String database, String table, Long id, Map<String, Object> data) {
|
||||
try {
|
||||
if (data == null || data.isEmpty()) {
|
||||
throw ComposeException.build(BizExceptionCodeEnum.resourceDataNotFound, "更新数据不能为空");
|
||||
}
|
||||
|
||||
StringBuilder sql = new StringBuilder("UPDATE `").append(database).append("`.`")
|
||||
.append(table).append("` SET ");
|
||||
List<Object> params = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<String, Object> entry : data.entrySet()) {
|
||||
sql.append("`").append(entry.getKey()).append("` = ?,");
|
||||
params.add(entry.getValue());
|
||||
}
|
||||
|
||||
sql.setLength(sql.length() - 1);
|
||||
sql.append(" WHERE id = ?");
|
||||
params.add(id);
|
||||
|
||||
return jdbcTemplate.update(sql.toString(), params.toArray());
|
||||
} catch (Exception e) {
|
||||
log.error("Doris update error, database: {}, table: {}, id: {}, data: {}",
|
||||
database, table, id, data, e);
|
||||
throw ComposeException.build(BizExceptionCodeEnum.resourceDataNotFound, "更新数据失败");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batchUpdate(String database, String table, List<Map<String, Object>> dataList) {
|
||||
try {
|
||||
if (CollectionUtils.isEmpty(dataList)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 使用 CASE WHEN 语法进行批量更新
|
||||
StringBuilder sql = new StringBuilder("UPDATE `").append(database).append("`.`")
|
||||
.append(table).append("` SET ");
|
||||
|
||||
// 获取所有需要更新的字段(排除id)
|
||||
Set<String> updateFields = new HashSet<>();
|
||||
List<Object> params = new ArrayList<>();
|
||||
for (Map<String, Object> data : dataList) {
|
||||
updateFields.addAll(data.keySet());
|
||||
}
|
||||
updateFields.remove("id");
|
||||
|
||||
// 构建每个字段的 CASE WHEN 语句
|
||||
boolean first = true;
|
||||
for (String field : updateFields) {
|
||||
if (!first) {
|
||||
sql.append(", ");
|
||||
}
|
||||
first = false;
|
||||
|
||||
sql.append("`").append(field).append("` = CASE id ");
|
||||
for (Map<String, Object> data : dataList) {
|
||||
if (data.containsKey(field)) {
|
||||
sql.append("WHEN ? THEN ? ");
|
||||
params.add(data.get("id"));
|
||||
params.add(data.get(field));
|
||||
}
|
||||
}
|
||||
sql.append("ELSE `").append(field).append("` END");
|
||||
}
|
||||
|
||||
// 添加 WHERE 条件
|
||||
sql.append(" WHERE id IN (");
|
||||
sql.append(String.join(",", Collections.nCopies(dataList.size(), "?")));
|
||||
sql.append(")");
|
||||
|
||||
// 添加 id 参数
|
||||
for (Map<String, Object> data : dataList) {
|
||||
params.add(data.get("id"));
|
||||
}
|
||||
|
||||
return jdbcTemplate.update(sql.toString(), params.toArray());
|
||||
} catch (Exception e) {
|
||||
log.error("Doris batch update error, database: {}, table: {}, dataSize: {}",
|
||||
database, table, dataList.size(), e);
|
||||
throw ComposeException.build(BizExceptionCodeEnum.resourceDataNotFound, "批量更新数据失败");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> queryByConditions(String database, String table,
|
||||
Map<String, Object> conditions, String orderBy, Integer offset, Integer limit) {
|
||||
try {
|
||||
StringBuilder sql = new StringBuilder("SELECT * FROM `").append(database).append("`.`")
|
||||
.append(table).append("`");
|
||||
List<Object> params = new ArrayList<>();
|
||||
|
||||
// 添加查询条件
|
||||
if (conditions != null && !conditions.isEmpty()) {
|
||||
sql.append(" WHERE ");
|
||||
boolean first = true;
|
||||
for (Map.Entry<String, Object> entry : conditions.entrySet()) {
|
||||
if (!first) {
|
||||
sql.append(" AND ");
|
||||
}
|
||||
first = false;
|
||||
sql.append("`").append(entry.getKey()).append("` = ?");
|
||||
params.add(entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
// 添加排序
|
||||
if (StringUtils.hasText(orderBy)) {
|
||||
sql.append(" ORDER BY ").append(orderBy);
|
||||
}
|
||||
|
||||
// 添加分页
|
||||
if (offset != null && limit != null) {
|
||||
sql.append(" LIMIT ?, ?");
|
||||
params.add(offset);
|
||||
params.add(limit);
|
||||
}
|
||||
|
||||
return jdbcTemplate.queryForList(sql.toString(), params.toArray());
|
||||
} catch (Exception e) {
|
||||
log.error("Doris query error, database: {}, table: {}, conditions: {}",
|
||||
database, table, conditions, e);
|
||||
throw ComposeException.build(BizExceptionCodeEnum.resourceDataNotFound, "查询数据失败");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long countByConditions(String database, String table, Map<String, Object> conditions) {
|
||||
try {
|
||||
StringBuilder sql = new StringBuilder("SELECT COUNT(*) FROM `").append(database)
|
||||
.append("`.`").append(table).append("`");
|
||||
List<Object> params = new ArrayList<>();
|
||||
|
||||
// 添加查询条件
|
||||
if (conditions != null && !conditions.isEmpty()) {
|
||||
sql.append(" WHERE ");
|
||||
boolean first = true;
|
||||
for (Map.Entry<String, Object> entry : conditions.entrySet()) {
|
||||
if (!first) {
|
||||
sql.append(" AND ");
|
||||
}
|
||||
first = false;
|
||||
sql.append("`").append(entry.getKey()).append("` = ?");
|
||||
params.add(entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return jdbcTemplate.queryForObject(sql.toString(), Long.class, params.toArray());
|
||||
} catch (Exception e) {
|
||||
log.error("Doris count error, database: {}, table: {}, conditions: {}",
|
||||
database, table, conditions, e);
|
||||
throw ComposeException.build(BizExceptionCodeEnum.resourceDataNotFound, "统计数据失败");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int deleteByConditions(String database, String table, Map<String, Object> conditions) {
|
||||
try {
|
||||
if (conditions == null || conditions.isEmpty()) {
|
||||
throw ComposeException.build(BizExceptionCodeEnum.resourceDataNotFound, "删除条件不能为空");
|
||||
}
|
||||
|
||||
StringBuilder sql = new StringBuilder("DELETE FROM `").append(database).append("`.`")
|
||||
.append(table).append("` WHERE ");
|
||||
List<Object> params = new ArrayList<>();
|
||||
|
||||
boolean first = true;
|
||||
for (Map.Entry<String, Object> entry : conditions.entrySet()) {
|
||||
if (!first) {
|
||||
sql.append(" AND ");
|
||||
}
|
||||
first = false;
|
||||
sql.append("`").append(entry.getKey()).append("` = ?");
|
||||
params.add(entry.getValue());
|
||||
}
|
||||
|
||||
return jdbcTemplate.update(sql.toString(), params.toArray());
|
||||
} catch (Exception e) {
|
||||
log.error("Doris delete error, database: {}, table: {}, conditions: {}",
|
||||
database, table, conditions, e);
|
||||
throw ComposeException.build(BizExceptionCodeEnum.resourceDataNotFound, "删除数据失败");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int batchDelete(String database, String table, List<Long> ids) {
|
||||
try {
|
||||
if (CollectionUtils.isEmpty(ids)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
String sql = "DELETE FROM `" + database + "`.`" + table + "` WHERE id IN (" +
|
||||
String.join(",", Collections.nCopies(ids.size(), "?")) + ")";
|
||||
|
||||
return jdbcTemplate.update(sql, ids.toArray());
|
||||
} catch (Exception e) {
|
||||
log.error("Doris batch delete error, database: {}, table: {}, ids: {}",
|
||||
database, table, ids, e);
|
||||
throw ComposeException.build(BizExceptionCodeEnum.resourceDataNotFound, "批量删除数据失败");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> queryAllData(String database, String table,
|
||||
Map<String, Object> conditions, String orderBy, Integer limit) {
|
||||
try {
|
||||
// 如果 limit 无效,设置默认最大值 DorisConfigContants.EXPORT_EXCEL_DATA_MAX_ROWS
|
||||
int effectiveLimit = (limit != null && limit > 0) ? limit : DorisConfigContants.EXPORT_EXCEL_DATA_MAX_ROWS;
|
||||
|
||||
// 调用现有带分页的方法,offset 设为 0
|
||||
return queryByConditions(database, table, conditions, orderBy, 0, effectiveLimit);
|
||||
} catch (Exception e) {
|
||||
// 异常处理和日志记录已在 queryByConditions 中完成,这里可以不再重复记录
|
||||
// 但仍然需要向上抛出或包装异常
|
||||
log.error("Doris query all error (limit={}), database: {}, table: {}, conditions: {}",
|
||||
limit, database, table, conditions, e);
|
||||
throw ComposeException.build(BizExceptionCodeEnum.composeQueryAllDataFailed);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecuteRawResultVo executeRawQuery(String sql, Object... params) {
|
||||
try {
|
||||
if (!StringUtils.hasText(sql)) {
|
||||
throw ComposeException.build(BizExceptionCodeEnum.composeSqlEmpty);
|
||||
}
|
||||
|
||||
SqlType sqlType;
|
||||
try {
|
||||
sqlType = SqlParserUtil.getSqlType(sql);
|
||||
} catch (JSQLParserException e) {
|
||||
log.error("SQL parse failed: {}", sql, e);
|
||||
var errorMessage = ComposeExceptionUtils.getRootErrorMessage(e);
|
||||
throw ComposeException.build(BizExceptionCodeEnum.composeSqlExecuteFailed, errorMessage);
|
||||
}
|
||||
|
||||
switch (sqlType) {
|
||||
case SELECT: {
|
||||
log.debug("Raw Doris query SQL: {}, params: {}", sql, params);
|
||||
var result = jdbcTemplate.queryForList(sql, params);
|
||||
return ExecuteRawResultVo.builder()
|
||||
.data(result)
|
||||
.rowNum((long) result.size())
|
||||
.build();
|
||||
}
|
||||
case UPDATE: {
|
||||
log.debug("Raw Doris update SQL: {}, params: {}", sql, params);
|
||||
int affectedRows = jdbcTemplate.update(sql, params);
|
||||
return ExecuteRawResultVo.builder()
|
||||
.rowNum((long) affectedRows)
|
||||
.build();
|
||||
}
|
||||
case INSERT: {
|
||||
log.debug("Raw Doris insert SQL: {}, params: {}", sql, params);
|
||||
KeyHolder keyHolder = new GeneratedKeyHolder();
|
||||
try {
|
||||
int affectedRows = jdbcTemplate.update(connection -> {
|
||||
var ps = connection.prepareStatement(sql, java.sql.Statement.RETURN_GENERATED_KEYS);
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
ps.setObject(i + 1, params[i]);
|
||||
}
|
||||
return ps;
|
||||
}, keyHolder);
|
||||
|
||||
// 判断是否为批量插入(通过检查keyHolder中的key数量)
|
||||
List<Map<String, Object>> keyList = keyHolder.getKeyList();
|
||||
if (keyList != null && keyList.size() > 1) {
|
||||
// 批量插入情况,获取所有生成的主键ID
|
||||
log.info("Batch insert, affected: {}, generated keys: {}", affectedRows, keyList.size());
|
||||
|
||||
// 提取所有生成的主键ID
|
||||
List<Long> generatedIds = new ArrayList<>();
|
||||
for (Map<String, Object> keyMap : keyList) {
|
||||
// 通常主键列名为"GENERATED_KEY"或数据库特定的名称
|
||||
Object keyObj = keyMap.get("GENERATED_KEY");
|
||||
if (keyObj != null) {
|
||||
if (keyObj instanceof Number) {
|
||||
generatedIds.add(((Number) keyObj).longValue());
|
||||
} else {
|
||||
try {
|
||||
generatedIds.add(Long.parseLong(keyObj.toString()));
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("Cannot parse generated PK: {}", keyObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 返回第一个主键ID作为rowId,并在data中返回所有主键ID
|
||||
Long firstId = generatedIds.isEmpty() ? null : generatedIds.get(0);
|
||||
Map<String, Object> resultData = new HashMap<>();
|
||||
resultData.put("rowIds", generatedIds);
|
||||
|
||||
return ExecuteRawResultVo.builder()
|
||||
.rowNum((long) affectedRows)
|
||||
.rowId(firstId)
|
||||
.data(Collections.singletonList(resultData))
|
||||
.build();
|
||||
} else {
|
||||
// 单条插入情况,获取生成的主键
|
||||
Number key = keyHolder.getKey();
|
||||
if (key == null) {
|
||||
log.warn("Auto-increment PK not returned after insert, SQL: {}", sql);
|
||||
}
|
||||
var rowId = key != null ? key.longValue() : null;
|
||||
return ExecuteRawResultVo.builder()
|
||||
.rowNum((long) affectedRows)
|
||||
.rowId(rowId)
|
||||
.build();
|
||||
}
|
||||
} catch (DuplicateKeyException e) {
|
||||
// 因为唯一key重复,不抛异常,避免阻塞工作流任务;返回主键id是-1;
|
||||
log.error("Unique key conflict on insert, SQL: {}", sql, e);
|
||||
return ExecuteRawResultVo.builder()
|
||||
.data(List.of())
|
||||
.rowNum(0L)
|
||||
.rowId(-1L)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
case DELETE: {
|
||||
log.debug("Raw Doris delete SQL: {}, params: {}", sql, params);
|
||||
int affectedRows = jdbcTemplate.update(sql, params);
|
||||
return ExecuteRawResultVo.builder()
|
||||
.rowNum((long) affectedRows)
|
||||
.build();
|
||||
}
|
||||
case DDL:
|
||||
default:
|
||||
log.error("DDL raw SQL not allowed: {}", sql);
|
||||
throw ComposeException.build(BizExceptionCodeEnum.composeSqlOnlyDmlAllowed);
|
||||
}
|
||||
} catch (BadSqlGrammarException e) {
|
||||
log.error("DML SQL execution error, SQL: {}", sql, e);
|
||||
var errorMessage = ComposeExceptionUtils.getUserFriendlyErrorMessage(e);
|
||||
throw ComposeException.build(BizExceptionCodeEnum.composeSqlExecuteFailed, errorMessage);
|
||||
} catch (ComposeException ce) {
|
||||
log.error("DML SQL execution error, SQL: {}", sql, ce);
|
||||
throw ce;
|
||||
} catch (Exception e) {
|
||||
log.error("Raw Doris query SQL execution error, SQL: {}", sql, e);
|
||||
var errorMessage = ComposeExceptionUtils.getUserFriendlyErrorMessage(e);
|
||||
throw ComposeException.build(BizExceptionCodeEnum.composeSqlExecuteFailed, errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@DSTransactional(propagation = DsPropagation.NOT_SUPPORTED)
|
||||
@Override
|
||||
public String getCreateTableDdl(String database, String table) {
|
||||
|
||||
// 获取表的建表DDL语句
|
||||
// 检查表是否存在
|
||||
var existFlag = tableExists(database, table);
|
||||
if (!existFlag) {
|
||||
log.error("Table not found, database: {}, table: {}", database, table);
|
||||
throw ComposeException.build(BizExceptionCodeEnum.composeTableDefinitionNotFound);
|
||||
}
|
||||
|
||||
// 1. 获取表的基本信息
|
||||
String showCreateTableSql = tableDbWrapperUtil.getShowCreateTableDdl(database, table);
|
||||
Map<String, Object> createTableResult = jdbcTemplate.queryForMap(showCreateTableSql);
|
||||
// 尝试不同的列名格式(MySQL使用空格,Doris使用下划线)
|
||||
String createTableDdl = (String) createTableResult.get("Create Table"); // MySQL格式
|
||||
if (createTableDdl == null) {
|
||||
createTableDdl = (String) createTableResult.get("Create_table"); // Doris格式
|
||||
}
|
||||
if (createTableDdl == null) {
|
||||
throw ComposeException.build(BizExceptionCodeEnum.composeCannotGetCreateTableDdl);
|
||||
}
|
||||
return createTableDdl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int executeRawAdminSql(String sql) {
|
||||
try {
|
||||
if (!StringUtils.hasText(sql)) {
|
||||
throw ComposeException.build(BizExceptionCodeEnum.composeSqlEmpty); // SQL不能为空
|
||||
}
|
||||
// 不再检查是否为 SELECT
|
||||
log.warn("About to run raw admin/DML/DDL SQL (high risk): {}", sql);
|
||||
int affectedRows = jdbcTemplate.update(sql);
|
||||
log.info("Raw admin/DML/DDL SQL OK: {}, affected: {}", sql, affectedRows);
|
||||
return affectedRows;
|
||||
} catch (BadSqlGrammarException e) {
|
||||
log.error("Raw admin/DML/DDL SQL error, SQL: {}", sql, e);
|
||||
var errorMessage = ComposeExceptionUtils.getUserFriendlyErrorMessage(e);
|
||||
throw ComposeException.build(BizExceptionCodeEnum.composeSqlExecuteFailed, errorMessage);
|
||||
} catch (ComposeException ce) {
|
||||
// 直接抛出业务异常
|
||||
log.error("Raw admin/DML/DDL SQL execution error, SQL: {}", sql, ce);
|
||||
throw ce;
|
||||
} catch (Exception e) {
|
||||
log.error("Raw admin/DML/DDL SQL execution error, SQL: {}", sql, e);
|
||||
// 使用用户友好的错误信息,将数据库技术错误转换为易于理解的提示
|
||||
var errorMessage = ComposeExceptionUtils.getUserFriendlyErrorMessage(e);
|
||||
throw ComposeException.build(BizExceptionCodeEnum.composeGenericMessage, errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getTableTotal(String database, String table) {
|
||||
String sql = "SELECT COUNT(*) FROM " + database + "." + table;
|
||||
return jdbcTemplate.queryForObject(sql, Long.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean queryDorisTableRowDataById(String database, String table, Long id) {
|
||||
String sql = "SELECT COUNT(*) FROM " + database + "." + table + " WHERE id = " + id;
|
||||
return jdbcTemplate.queryForObject(sql, Long.class) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearBusinessData(String database, String table) {
|
||||
String sql = "TRUNCATE TABLE " + database + "." + table;
|
||||
jdbcTemplate.update(sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean existTableData(String database, String table) {
|
||||
// 检查表是否存在
|
||||
var existFlag = tableExists(database, table);
|
||||
if (!existFlag) {
|
||||
log.error("Table not found, database: {}, table: {}", database, table);
|
||||
return false;
|
||||
}
|
||||
|
||||
String sql = "SELECT * FROM " + database + "." + table + " LIMIT 1";
|
||||
List<Map<String, Object>> result = jdbcTemplate.queryForList(sql);
|
||||
return !result.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeRawDDL(String sql) {
|
||||
try {
|
||||
// 只允许 DDL 类型
|
||||
SqlType sqlType = SqlParserUtil.getSqlType(sql);
|
||||
if (sqlType != SqlType.DDL) {
|
||||
log.error("DDL only, sql={}", sql);
|
||||
throw ComposeException.build(BizExceptionCodeEnum.composeSqlOnlyDdl, sql);
|
||||
}
|
||||
jdbcTemplate.execute(sql);
|
||||
} catch (ComposeException e) {
|
||||
throw e;
|
||||
} catch (JSQLParserException e) {
|
||||
log.error("DDL execution error, sql={}", sql, e);
|
||||
var errorMessage = ComposeExceptionUtils.getRootErrorMessage(e);
|
||||
throw ComposeException.build(BizExceptionCodeEnum.composeSqlParseFailed, errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long countRawQuery(String sql) {
|
||||
try {
|
||||
return jdbcTemplate.queryForObject(sql, Long.class);
|
||||
} catch (Exception e) {
|
||||
log.error("Raw Doris query SQL execution error, SQL: {}", sql, e);
|
||||
var errorMessage = ComposeExceptionUtils.getRootErrorMessage(e);
|
||||
throw ComposeException.build(BizExceptionCodeEnum.composeSqlExecuteFailed, errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取根错误信息
|
||||
*
|
||||
* @param e 异常
|
||||
* @return 根错误信息
|
||||
*/
|
||||
private String getRootErrorMessage(Throwable e) {
|
||||
Throwable cause = e;
|
||||
while (cause.getCause() != null) {
|
||||
cause = cause.getCause();
|
||||
}
|
||||
return cause.getMessage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeRawAdminSqls(List<String> sqls) {
|
||||
// 直接调用FAIL_FAST策略,保持原有行为
|
||||
this.self.executeFailFast(sqls);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeRawAdminSqlsWithStrategy(List<String> sqls,
|
||||
ICustomDorisTableRepository.BatchExecuteStrategy strategy) {
|
||||
if (CollectionUtils.isEmpty(sqls)) {
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("Batch run {} SQL statements, strategy: {}", sqls.size(), strategy);
|
||||
|
||||
switch (strategy) {
|
||||
case FAIL_FAST:
|
||||
this.self.executeFailFast(sqls);
|
||||
break;
|
||||
case CONTINUE_ON_ERROR:
|
||||
this.self.executeContinueOnError(sqls);
|
||||
break;
|
||||
case ATOMIC_BATCH:
|
||||
this.self.executeAtomicBatch(sqls);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported execution strategy: " + strategy);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 策略1:遇到错误立即失败(原有行为)
|
||||
*/
|
||||
@DSTransactional(rollbackFor = Exception.class)
|
||||
public void executeFailFast(List<String> sqls) {
|
||||
// 将多条SQL语句合并成一条,使用分号分隔
|
||||
String batchSql = String.join(";", sqls);
|
||||
batchSql = batchSql + ";";
|
||||
this.self.executeRawAdminSql(batchSql);
|
||||
log.info("Batch SQL done (FAIL_FAST)");
|
||||
}
|
||||
|
||||
/**
|
||||
* 策略2:遇到错误继续执行其他SQL(无事务保护)
|
||||
*/
|
||||
@DSTransactional(propagation = DsPropagation.NOT_SUPPORTED) // 不使用事务
|
||||
public void executeContinueOnError(List<String> sqls) {
|
||||
int successCount = 0;
|
||||
List<String> errorSqls = new ArrayList<>();
|
||||
List<String> errorMessages = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < sqls.size(); i++) {
|
||||
String sql = sqls.get(i);
|
||||
try {
|
||||
jdbcTemplate.update(sql);
|
||||
successCount++;
|
||||
log.debug("SQL[{}] OK: {}", i + 1, sql);
|
||||
} catch (Exception e) {
|
||||
String errorMsg = String.format("SQL[%d]执行失败: %s, 错误: %s",
|
||||
i + 1, sql, e.getMessage());
|
||||
log.error(errorMsg, e);
|
||||
errorSqls.add(sql);
|
||||
errorMessages.add(errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
log.info("Batch SQL done (CONTINUE_ON_ERROR): ok {}, failed {}",
|
||||
successCount, errorSqls.size());
|
||||
|
||||
// 如果有失败的SQL,抛出汇总异常
|
||||
if (!errorSqls.isEmpty()) {
|
||||
String summaryError = String.format("批量执行SQL部分失败: 成功%d条,失败%d条。失败详情: %s",
|
||||
successCount, errorSqls.size(),
|
||||
String.join("; ", errorMessages));
|
||||
throw ComposeException.build(BizExceptionCodeEnum.composeSqlExecuteFailed, summaryError);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 策略3:原子性批处理,逐个执行但保持事务完整性
|
||||
*/
|
||||
@DSTransactional(rollbackFor = Exception.class)
|
||||
public void executeAtomicBatch(List<String> sqls) {
|
||||
try {
|
||||
for (int i = 0; i < sqls.size(); i++) {
|
||||
String sql = sqls.get(i);
|
||||
try {
|
||||
int affectedRows = jdbcTemplate.update(sql);
|
||||
log.debug("SQL[{}] OK, affected {}: {}", i + 1, affectedRows, sql);
|
||||
} catch (Exception e) {
|
||||
String errorMsg = String.format("SQL[%d]执行失败: %s", i + 1, sql);
|
||||
log.error(errorMsg, e);
|
||||
// 在事务中抛出异常,会导致整个事务回滚
|
||||
throw ComposeException.build(BizExceptionCodeEnum.composeSqlExecuteFailed,
|
||||
errorMsg + ",错误: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
log.info("Batch SQL done (ATOMIC_BATCH): {} statements", sqls.size());
|
||||
} catch (Exception e) {
|
||||
log.error("Batch SQL failed, rolling back all", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package com.xspaceagi.compose.infra.respository;
|
||||
|
||||
import com.xspaceagi.compose.domain.model.CustomFieldDefinitionModel;
|
||||
import com.xspaceagi.compose.domain.repository.ICustomFieldDefinitionRepository;
|
||||
|
||||
import com.xspaceagi.compose.infra.dao.mapper.CustomFieldDefinitionMapper;
|
||||
import com.xspaceagi.compose.infra.dao.service.CustomFieldDefinitionService;
|
||||
import com.xspaceagi.compose.infra.translator.CustomFieldDefinitionTranslator;
|
||||
import com.xspaceagi.system.spec.common.UserContext;
|
||||
import com.xspaceagi.system.spec.exception.BizExceptionCodeEnum;
|
||||
import com.xspaceagi.system.spec.exception.ComposeException;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Repository
|
||||
public class CustomFieldDefinitionRepository implements ICustomFieldDefinitionRepository {
|
||||
|
||||
@Resource
|
||||
private CustomFieldDefinitionService customFieldDefinitionService;
|
||||
|
||||
@Resource
|
||||
private CustomFieldDefinitionMapper customFieldDefinitionMapper;
|
||||
|
||||
@Resource
|
||||
private CustomFieldDefinitionTranslator customFieldDefinitionTranslator;
|
||||
|
||||
@Override
|
||||
public List<CustomFieldDefinitionModel> queryListByIds(List<Long> ids) {
|
||||
return customFieldDefinitionService.queryListByIds(ids)
|
||||
.stream()
|
||||
.map(customFieldDefinitionTranslator::convertToModel)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomFieldDefinitionModel queryOneInfoById(Long id) {
|
||||
return customFieldDefinitionTranslator.convertToModel(
|
||||
customFieldDefinitionService.queryOneInfoById(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CustomFieldDefinitionModel> queryListByTableId(Long tableId) {
|
||||
return customFieldDefinitionService.queryListByTableId(tableId)
|
||||
.stream()
|
||||
.map(customFieldDefinitionTranslator::convertToModel)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CustomFieldDefinitionModel> queryListByTableIds(List<Long> tableIds) {
|
||||
return customFieldDefinitionService.queryListByTableIds(tableIds)
|
||||
.stream()
|
||||
.map(customFieldDefinitionTranslator::convertToModel)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void batchAddInfo(List<CustomFieldDefinitionModel> modelList, UserContext userContext) {
|
||||
|
||||
modelList.forEach(entity -> {
|
||||
entity.setCreated(null);
|
||||
entity.setModified(null);
|
||||
entity.setModifiedId(userContext.getUserId());
|
||||
entity.setModifiedName(userContext.getUserName());
|
||||
});
|
||||
|
||||
var entityList = modelList.stream()
|
||||
.map(customFieldDefinitionTranslator::convertToEntity)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
customFieldDefinitionService.batchAddInfo(entityList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void batchUpdateInfo(List<CustomFieldDefinitionModel> modelList, UserContext userContext) {
|
||||
|
||||
modelList.forEach(entity -> {
|
||||
entity.setCreated(null);
|
||||
entity.setModified(null);
|
||||
entity.setModifiedId(userContext.getUserId());
|
||||
entity.setModifiedName(userContext.getUserName());
|
||||
});
|
||||
|
||||
var entityList = modelList.stream()
|
||||
.map(customFieldDefinitionTranslator::convertToEntity)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
customFieldDefinitionService.batchUpdateInfo(entityList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteById(Long id, UserContext userContext) {
|
||||
var existOne = customFieldDefinitionService.queryOneInfoById(id);
|
||||
if (Objects.isNull(existOne)) {
|
||||
throw ComposeException.build(BizExceptionCodeEnum.resourceDataNotFound);
|
||||
}
|
||||
|
||||
customFieldDefinitionService.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByTableId(Long tableId) {
|
||||
|
||||
var existCount = customFieldDefinitionService.queryCountByTableId(tableId);
|
||||
if (existCount == 0) {
|
||||
log.info("No columns to drop, tableId={}", tableId);
|
||||
} else {
|
||||
customFieldDefinitionService.deleteByTableId(tableId);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,389 @@
|
||||
package com.xspaceagi.compose.infra.respository;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.xspaceagi.compose.domain.dto.ColumnDefinitionResult;
|
||||
import com.xspaceagi.compose.sdk.vo.data.FrontColumnDefineVo;
|
||||
import com.xspaceagi.system.spec.exception.BizExceptionCodeEnum;
|
||||
import com.xspaceagi.system.spec.exception.ComposeException;
|
||||
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.OrderItem;
|
||||
import com.xspaceagi.compose.spec.constants.DorisConfigContants;
|
||||
import com.xspaceagi.compose.domain.dto.CustomEmptyTableVo;
|
||||
import com.xspaceagi.compose.domain.model.CustomFieldDefinitionModel;
|
||||
import com.xspaceagi.compose.domain.model.CustomTableDefinitionModel;
|
||||
import com.xspaceagi.compose.domain.repository.ICustomFieldDefinitionRepository;
|
||||
import com.xspaceagi.compose.domain.repository.ICustomTableDefinitionRepository;
|
||||
import com.xspaceagi.compose.domain.util.TableDbWrapperUtil;
|
||||
import com.xspaceagi.compose.infra.dao.entity.CustomTableDefinition;
|
||||
import com.xspaceagi.compose.infra.dao.mapper.CustomTableDefinitionMapper;
|
||||
import com.xspaceagi.compose.infra.dao.service.CustomFieldDefinitionService;
|
||||
import com.xspaceagi.compose.infra.dao.service.CustomTableDefinitionService;
|
||||
import com.xspaceagi.compose.infra.translator.CustomFieldDefinitionTranslator;
|
||||
import com.xspaceagi.compose.infra.translator.CustomTableDefinitionTranslator;
|
||||
import com.xspaceagi.system.spec.common.UserContext;
|
||||
import com.xspaceagi.system.spec.enums.YnEnum;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@Repository
|
||||
public class CustomTableDefinitionRepository implements ICustomTableDefinitionRepository {
|
||||
|
||||
@Resource
|
||||
private CustomFieldDefinitionService customFieldDefinitionService;
|
||||
|
||||
@Resource
|
||||
private CustomTableDefinitionService customTableDefinitionService;
|
||||
|
||||
@Resource
|
||||
private CustomTableDefinitionMapper customTableDefinitionMapper;
|
||||
|
||||
@Resource
|
||||
private CustomTableDefinitionTranslator customTableDefinitionTranslator;
|
||||
|
||||
@Resource
|
||||
private CustomFieldDefinitionTranslator customFieldDefinitionTranslator;
|
||||
|
||||
@Resource
|
||||
private ICustomFieldDefinitionRepository customFieldDefinitionRepository;
|
||||
|
||||
@Resource
|
||||
private TableDbWrapperUtil tableDbWrapperUtil;
|
||||
|
||||
@Lazy
|
||||
@Resource
|
||||
private ICustomTableDefinitionRepository self;
|
||||
|
||||
@Override
|
||||
public List<CustomTableDefinitionModel> queryListByIds(List<Long> ids) {
|
||||
List<CustomTableDefinitionModel> tableList = customTableDefinitionService.queryListByIds(ids)
|
||||
.stream()
|
||||
.map(customTableDefinitionTranslator::convertToModel)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return fillFieldList(tableList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomTableDefinitionModel queryOneInfoById(Long id) {
|
||||
var entity = customTableDefinitionService.queryOneInfoById(id);
|
||||
CustomTableDefinitionModel tableModel = customTableDefinitionTranslator.convertToModel(entity);
|
||||
if (tableModel == null) {
|
||||
return null;
|
||||
}
|
||||
return fillFieldList(Collections.singletonList(tableModel)).stream()
|
||||
.findFirst()
|
||||
.orElseThrow();
|
||||
}
|
||||
|
||||
@DSTransactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public Long updateInfo(CustomTableDefinitionModel entity, UserContext userContext) {
|
||||
|
||||
entity.setModified(null);
|
||||
entity.setModifiedId(userContext.getUserId());
|
||||
entity.setModifiedName(userContext.getUserName());
|
||||
|
||||
// 通常更新操作不需要返回完整的字段列表,如果需要则在此处调用 fillFieldList
|
||||
var id = customTableDefinitionService.updateInfo(
|
||||
customTableDefinitionTranslator.convertToEntity(entity));
|
||||
|
||||
// 批量修改 字段定义
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
@DSTransactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public Long addInfo(CustomTableDefinitionModel entity) {
|
||||
|
||||
// 通常新增操作不需要返回完整的字段列表,如果需要则在此处调用 fillFieldList
|
||||
entity.setDorisTable("");
|
||||
var id = customTableDefinitionService.addInfo(
|
||||
customTableDefinitionTranslator.convertToEntity(entity));
|
||||
|
||||
// 更新doris表名
|
||||
var updateEntity = new CustomTableDefinition();
|
||||
updateEntity.setId(id);
|
||||
var dorisTableName = DorisConfigContants.obtainTableName(id);
|
||||
updateEntity.setDorisTable(dorisTableName);
|
||||
|
||||
this.customTableDefinitionService.updateById(updateEntity);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteById(Long id) {
|
||||
customTableDefinitionService.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CustomTableDefinitionModel> pageQuery(Map<String, Object> queryMap, List<OrderItem> orderColumns,
|
||||
Long startIndex, Long pageSize) {
|
||||
List<CustomTableDefinitionModel> tableList = customTableDefinitionService
|
||||
.pageQuery(queryMap, orderColumns, startIndex, pageSize)
|
||||
.stream()
|
||||
.map(customTableDefinitionTranslator::convertToModel)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return fillFieldList(tableList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long queryTotal(Map<String, Object> queryMap) {
|
||||
return customTableDefinitionService.queryTotal(queryMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* 为表定义模型列表填充字段列表信息
|
||||
*
|
||||
* @param tableList 表定义模型列表
|
||||
* @return 填充字段列表后的表定义模型列表
|
||||
*/
|
||||
private List<CustomTableDefinitionModel> fillFieldList(List<CustomTableDefinitionModel> tableList) {
|
||||
if (CollectionUtils.isEmpty(tableList)) {
|
||||
return tableList;
|
||||
}
|
||||
|
||||
// 提取表 ID
|
||||
List<Long> tableIds = tableList.stream().map(CustomTableDefinitionModel::getId).collect(Collectors.toList());
|
||||
|
||||
// 查询表字段
|
||||
List<CustomFieldDefinitionModel> fieldList = customFieldDefinitionRepository.queryListByTableIds(tableIds);
|
||||
|
||||
// 按 TableId 分组
|
||||
Map<Long, List<CustomFieldDefinitionModel>> tableFieldMap = fieldList.stream()
|
||||
.collect(Collectors.groupingBy(CustomFieldDefinitionModel::getTableId));
|
||||
|
||||
// 将表字段添加到表模型中,且 字段需要根据 sortIndex排序,sortIndex越小越靠前
|
||||
tableList.forEach(table -> {
|
||||
List<CustomFieldDefinitionModel> fields = tableFieldMap.getOrDefault(table.getId(),
|
||||
Collections.emptyList());
|
||||
fields.sort(Comparator.comparing(CustomFieldDefinitionModel::getSortIndex,
|
||||
Comparator.nullsLast(Comparator.naturalOrder())));
|
||||
table.setFieldList(fields);
|
||||
});
|
||||
|
||||
return tableList;
|
||||
}
|
||||
|
||||
@DSTransactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public Long addEmptyTableInfo(CustomEmptyTableVo vo, UserContext userContext) {
|
||||
|
||||
var entity = new CustomTableDefinition();
|
||||
entity.setTenantId(userContext.getTenantId());
|
||||
entity.setSpaceId(vo.getSpaceId());
|
||||
entity.setTableName(vo.getTableName());
|
||||
entity.setTableDescription(vo.getTableDescription());
|
||||
entity.setStatus(YnEnum.Y.getKey());
|
||||
entity.setCreated(LocalDateTime.now());
|
||||
entity.setCreatorId(userContext.getUserId());
|
||||
entity.setCreatorName(userContext.getUserName());
|
||||
entity.setDorisDatabase(DorisConfigContants.DEFAULT_DORIS_DATABASE);
|
||||
|
||||
var id = customTableDefinitionService.addInfo(entity);
|
||||
|
||||
// 更新doris表名
|
||||
var updateEntity = new CustomTableDefinition();
|
||||
updateEntity.setId(id);
|
||||
var dorisTableName = DorisConfigContants.obtainTableName(id);
|
||||
updateEntity.setDorisTable(dorisTableName);
|
||||
|
||||
this.customTableDefinitionService.updateById(updateEntity);
|
||||
|
||||
return id;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CustomTableDefinitionModel> queryListByCondition(CustomTableDefinitionModel condition) {
|
||||
log.debug("Query table definitions by condition: {}", condition);
|
||||
|
||||
// 将领域模型转换为实体对象
|
||||
CustomTableDefinition queryCondition = customTableDefinitionTranslator.convertToEntity(condition);
|
||||
|
||||
// 调用 service 层查询
|
||||
List<CustomTableDefinition> entityList = customTableDefinitionService.queryListByCondition(queryCondition);
|
||||
|
||||
// 转换为领域模型
|
||||
if (CollectionUtils.isEmpty(entityList)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<CustomTableDefinitionModel> tableList = entityList.stream()
|
||||
.map(customTableDefinitionTranslator::convertToModel)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 填充字段列表信息
|
||||
return fillFieldList(tableList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColumnDefinitionResult getColumnDefinitions(Long tableId) {
|
||||
// 1. 查询表定义
|
||||
CustomTableDefinitionModel tableModel = this.self.queryOneInfoById(tableId);
|
||||
if (tableModel == null) {
|
||||
throw ComposeException.build(BizExceptionCodeEnum.resourceDataNotFound, "表定义不存在: " + tableId);
|
||||
}
|
||||
if (tableModel.getDorisDatabase() == null || tableModel.getDorisTable() == null) {
|
||||
throw ComposeException.build(BizExceptionCodeEnum.resourceDataNotFound, "表定义缺少Doris库名或表名: " + tableId);
|
||||
}
|
||||
|
||||
// 2. 查询字段定义
|
||||
List<CustomFieldDefinitionModel> fieldModels = tableModel.getFieldList();
|
||||
|
||||
// 按 sortIndex 排序 (假设 CustomFieldDefinitionModel 有 sortIndex 字段)
|
||||
fieldModels.sort(Comparator
|
||||
.comparing(CustomFieldDefinitionModel::getSortIndex, Comparator.nullsLast(Comparator.naturalOrder()))
|
||||
.thenComparing(CustomFieldDefinitionModel::getId)); // 添加ID作为次要排序,保证稳定性
|
||||
|
||||
// 3. 转换为 ExcelColumnDefineVo 并提取有序字段名
|
||||
List<FrontColumnDefineVo> columnDefines = new ArrayList<>();
|
||||
List<String> orderedFieldNames = new ArrayList<>();
|
||||
List<CustomFieldDefinitionModel> fields = new ArrayList<>();
|
||||
|
||||
for (CustomFieldDefinitionModel field : fieldModels) {
|
||||
// 只包含启用的字段
|
||||
if (field.getEnabledFlag() != null && field.getEnabledFlag() == 1) {
|
||||
FrontColumnDefineVo vo = FrontColumnDefineVo.builder()
|
||||
.fieldName(field.getFieldName())
|
||||
.fieldDescription(field.getFieldDescription())
|
||||
.fieldType(field.getFieldType())
|
||||
.nullableFlag(field.getNullableFlag() != null && field.getNullableFlag() == 1)
|
||||
.uniqueFlag(field.getUniqueFlag() != null && field.getUniqueFlag() == 1)
|
||||
.enabledFlag(true) // 既然已经筛选了启用的,这里直接设为 true
|
||||
.defaultValue(field.getDefaultValue())
|
||||
.sortIndex(field.getSortIndex())
|
||||
.build();
|
||||
columnDefines.add(vo);
|
||||
orderedFieldNames.add(field.getFieldName());
|
||||
fields.add(field);
|
||||
}
|
||||
}
|
||||
|
||||
if (columnDefines.isEmpty()) {
|
||||
throw ComposeException.build(BizExceptionCodeEnum.resourceDataNotFound, "表没有定义任何启用的字段: " + tableId);
|
||||
}
|
||||
|
||||
return new ColumnDefinitionResult(tableModel, columnDefines, orderedFieldNames, fields);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long updateTableName(CustomTableDefinitionModel entity, UserContext userContext) {
|
||||
// 1. 查询表定义
|
||||
CustomTableDefinitionModel tableModel = this.self.queryOneInfoById(entity.getId());
|
||||
if (tableModel == null) {
|
||||
throw ComposeException.build(BizExceptionCodeEnum.resourceDataNotFound);
|
||||
}
|
||||
|
||||
// 2. 更新表名称
|
||||
var updateEntity = new CustomTableDefinition();
|
||||
updateEntity.setId(entity.getId());
|
||||
updateEntity.setTableName(entity.getTableName());
|
||||
updateEntity.setTableDescription(entity.getTableDescription());
|
||||
updateEntity.setIcon(entity.getIcon());
|
||||
updateEntity.setModified(LocalDateTime.now());
|
||||
updateEntity.setModifiedId(userContext.getUserId());
|
||||
updateEntity.setModifiedName(userContext.getUserName());
|
||||
|
||||
this.customTableDefinitionService.updateById(updateEntity);
|
||||
|
||||
return entity.getId();
|
||||
|
||||
}
|
||||
|
||||
@DSTransactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public Long copyTableDefinition(Long tableId, UserContext userContext) {
|
||||
// 1. 查询表定义
|
||||
CustomTableDefinitionModel tableModel = this.self.queryOneInfoById(tableId);
|
||||
if (tableModel == null) {
|
||||
throw ComposeException.build(BizExceptionCodeEnum.resourceDataNotFound);
|
||||
}
|
||||
|
||||
// 获取字段定义
|
||||
List<CustomFieldDefinitionModel> fieldModels = tableModel.getFieldList();
|
||||
|
||||
// 2. 创建新表
|
||||
String newTableName = tableModel.getTableName() + "_copy";
|
||||
tableModel.setTableName(newTableName);
|
||||
tableModel.setId(null);
|
||||
|
||||
// 3. 新增新表定义
|
||||
Long newTableId = this.addInfo(tableModel);
|
||||
|
||||
// 4. 去掉主键id,设置绑定的新 newTableId,然后入库
|
||||
fieldModels.forEach(item -> {
|
||||
item.setId(null);
|
||||
item.setTableId(newTableId);
|
||||
});
|
||||
var fieldEntities = fieldModels.stream()
|
||||
.map(customFieldDefinitionTranslator::convertToEntity)
|
||||
.collect(Collectors.toList());
|
||||
this.customFieldDefinitionService.batchAddInfo(fieldEntities);
|
||||
|
||||
// 5. 更新doris表名
|
||||
var updateEntity = new CustomTableDefinition();
|
||||
updateEntity.setId(newTableId);
|
||||
var dorisTableName = DorisConfigContants.obtainTableName(newTableId);
|
||||
updateEntity.setDorisTable(dorisTableName);
|
||||
|
||||
this.customTableDefinitionService.updateById(updateEntity);
|
||||
|
||||
return newTableId;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTableLastModified(Long tableId, UserContext userContext) {
|
||||
|
||||
//根据id查询,看数据是否存在
|
||||
var existEntity = this.customTableDefinitionService.queryOneInfoById(tableId);
|
||||
if (existEntity == null) {
|
||||
throw ComposeException.build(BizExceptionCodeEnum.resourceDataNotFound);
|
||||
}
|
||||
|
||||
var updateEntity = new CustomTableDefinition();
|
||||
updateEntity.setId(tableId);
|
||||
updateEntity.setModified(LocalDateTime.now());
|
||||
updateEntity.setModifiedId(userContext.getUserId());
|
||||
updateEntity.setModifiedName(userContext.getUserName());
|
||||
this.customTableDefinitionService.updateById(updateEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CustomTableDefinitionModel> queryListBySpaceId(Long spaceId) {
|
||||
List<CustomTableDefinition> entityList = customTableDefinitionService.queryListBySpaceId(spaceId);
|
||||
if (CollectionUtils.isEmpty(entityList)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
var data = entityList.stream()
|
||||
.map(customTableDefinitionTranslator::convertToModel)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return fillFieldList(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long countTotalTables(Long userId) {
|
||||
if (userId == null) {
|
||||
return customTableDefinitionService.count();
|
||||
}
|
||||
LambdaQueryWrapper<CustomTableDefinition> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(CustomTableDefinition::getCreatorId, userId);
|
||||
return customTableDefinitionService.count(queryWrapper);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.xspaceagi.compose.infra.translator;
|
||||
|
||||
import com.xspaceagi.compose.domain.model.CustomFieldDefinitionModel;
|
||||
import com.xspaceagi.compose.infra.dao.entity.CustomFieldDefinition;
|
||||
import com.xspaceagi.system.infra.dao.ICommonTranslator;
|
||||
|
||||
public interface CustomFieldDefinitionTranslator extends ICommonTranslator<CustomFieldDefinitionModel, CustomFieldDefinition> {
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.xspaceagi.compose.infra.translator;
|
||||
|
||||
import com.xspaceagi.compose.domain.model.CustomTableDefinitionModel;
|
||||
import com.xspaceagi.compose.infra.dao.entity.CustomTableDefinition;
|
||||
import com.xspaceagi.system.infra.dao.ICommonTranslator;
|
||||
|
||||
public interface CustomTableDefinitionTranslator extends ICommonTranslator<CustomTableDefinitionModel, CustomTableDefinition> {
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.xspaceagi.compose.infra.translator.impl;
|
||||
|
||||
import com.xspaceagi.compose.domain.model.CustomFieldDefinitionModel;
|
||||
import com.xspaceagi.compose.infra.dao.entity.CustomFieldDefinition;
|
||||
import com.xspaceagi.compose.infra.translator.CustomFieldDefinitionTranslator;
|
||||
import com.xspaceagi.system.spec.enums.YnEnum;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class CustomFieldDefinitionTranslatorImpl implements CustomFieldDefinitionTranslator {
|
||||
@Override
|
||||
public CustomFieldDefinitionModel convertToModel(CustomFieldDefinition entity) {
|
||||
if (entity == null) {
|
||||
return null;
|
||||
}
|
||||
CustomFieldDefinitionModel customFieldDefinitionModel = CustomFieldDefinitionModel.builder()
|
||||
.id(entity.getId())
|
||||
.systemFieldFlag(entity.getSystemFieldFlag())
|
||||
.tenantId(entity.getTenantId())
|
||||
.spaceId(entity.getSpaceId())
|
||||
.tableId(entity.getTableId())
|
||||
.fieldName(entity.getFieldName())
|
||||
.fieldDescription(entity.getFieldDescription())
|
||||
.fieldType(entity.getFieldType())
|
||||
.nullableFlag(entity.getNullableFlag())
|
||||
.defaultValue(entity.getDefaultValue())
|
||||
.uniqueFlag(entity.getUniqueFlag())
|
||||
.enabledFlag(entity.getEnabledFlag())
|
||||
.sortIndex(entity.getSortIndex())
|
||||
.created(entity.getCreated())
|
||||
.fieldStrLen(entity.getFieldStrLen())
|
||||
.creatorId(entity.getCreatorId())
|
||||
.creatorName(entity.getCreatorName())
|
||||
.modified(entity.getModified())
|
||||
.modifiedId(entity.getModifiedId())
|
||||
.modifiedName(entity.getModifiedName())
|
||||
.build();
|
||||
return customFieldDefinitionModel;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomFieldDefinition convertToEntity(CustomFieldDefinitionModel model) {
|
||||
if (model == null) {
|
||||
return null;
|
||||
}
|
||||
CustomFieldDefinition customFieldDefinition = CustomFieldDefinition.builder()
|
||||
.id(model.getId())
|
||||
.systemFieldFlag(model.getSystemFieldFlag())
|
||||
.tenantId(model.getTenantId())
|
||||
.spaceId(model.getSpaceId())
|
||||
.tableId(model.getTableId())
|
||||
.fieldName(model.getFieldName())
|
||||
.fieldDescription(model.getFieldDescription())
|
||||
.fieldType(model.getFieldType())
|
||||
.nullableFlag(model.getNullableFlag())
|
||||
.defaultValue(model.getDefaultValue())
|
||||
.uniqueFlag(model.getUniqueFlag())
|
||||
.enabledFlag(model.getEnabledFlag())
|
||||
.sortIndex(model.getSortIndex())
|
||||
.created(model.getCreated())
|
||||
.fieldStrLen(model.getFieldStrLen())
|
||||
.creatorId(model.getCreatorId())
|
||||
.creatorName(model.getCreatorName())
|
||||
.modified(model.getModified())
|
||||
.modifiedId(model.getModifiedId())
|
||||
.modifiedName(model.getModifiedName())
|
||||
.yn(YnEnum.Y.getKey())
|
||||
.build();
|
||||
return customFieldDefinition;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.xspaceagi.compose.infra.translator.impl;
|
||||
|
||||
import com.xspaceagi.compose.domain.model.CustomTableDefinitionModel;
|
||||
import com.xspaceagi.compose.infra.dao.entity.CustomTableDefinition;
|
||||
import com.xspaceagi.compose.infra.translator.CustomTableDefinitionTranslator;
|
||||
import com.xspaceagi.system.spec.enums.YnEnum;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class CustomTableDefinitionTranslatorImpl implements CustomTableDefinitionTranslator {
|
||||
@Override
|
||||
public CustomTableDefinitionModel convertToModel(CustomTableDefinition entity) {
|
||||
if (entity == null) {
|
||||
return null;
|
||||
}
|
||||
CustomTableDefinitionModel customTableDefinitionModel = new CustomTableDefinitionModel();
|
||||
customTableDefinitionModel.setId(entity.getId());
|
||||
customTableDefinitionModel.setTenantId(entity.getTenantId());
|
||||
customTableDefinitionModel.setSpaceId(entity.getSpaceId());
|
||||
customTableDefinitionModel.setIcon(entity.getIcon());
|
||||
customTableDefinitionModel.setTableName(entity.getTableName());
|
||||
customTableDefinitionModel.setTableDescription(entity.getTableDescription());
|
||||
customTableDefinitionModel.setDorisDatabase(entity.getDorisDatabase());
|
||||
customTableDefinitionModel.setDorisTable(entity.getDorisTable());
|
||||
customTableDefinitionModel.setStatus(entity.getStatus());
|
||||
customTableDefinitionModel.setCreated(entity.getCreated());
|
||||
customTableDefinitionModel.setCreatorId(entity.getCreatorId());
|
||||
customTableDefinitionModel.setCreatorName(entity.getCreatorName());
|
||||
customTableDefinitionModel.setModified(entity.getModified());
|
||||
customTableDefinitionModel.setModifiedId(entity.getModifiedId());
|
||||
customTableDefinitionModel.setModifiedName(entity.getModifiedName());
|
||||
return customTableDefinitionModel;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomTableDefinition convertToEntity(CustomTableDefinitionModel model) {
|
||||
if (model == null) {
|
||||
return null;
|
||||
}
|
||||
CustomTableDefinition customTableDefinition = new CustomTableDefinition();
|
||||
customTableDefinition.setId(model.getId());
|
||||
customTableDefinition.setTenantId(model.getTenantId());
|
||||
customTableDefinition.setSpaceId(model.getSpaceId());
|
||||
customTableDefinition.setIcon(model.getIcon());
|
||||
customTableDefinition.setTableName(model.getTableName());
|
||||
customTableDefinition.setTableDescription(model.getTableDescription());
|
||||
customTableDefinition.setDorisDatabase(model.getDorisDatabase());
|
||||
customTableDefinition.setDorisTable(model.getDorisTable());
|
||||
customTableDefinition.setStatus(model.getStatus());
|
||||
customTableDefinition.setCreated(model.getCreated());
|
||||
customTableDefinition.setCreatorId(model.getCreatorId());
|
||||
customTableDefinition.setCreatorName(model.getCreatorName());
|
||||
customTableDefinition.setModified(model.getModified());
|
||||
customTableDefinition.setModifiedId(model.getModifiedId());
|
||||
customTableDefinition.setModifiedName(model.getModifiedName());
|
||||
customTableDefinition.setYn(YnEnum.Y.getKey());
|
||||
return customTableDefinition;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?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="com.xspaceagi.compose.infra.dao.mapper.CustomFieldDefinitionMapper">
|
||||
<resultMap id="BaseResultMap" type="com.xspaceagi.compose.infra.dao.entity.CustomFieldDefinition">
|
||||
</resultMap>
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,66 @@
|
||||
<?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="com.xspaceagi.compose.infra.dao.mapper.CustomTableDefinitionMapper">
|
||||
|
||||
|
||||
<resultMap id="BaseResultMap" type="com.xspaceagi.compose.infra.dao.entity.CustomTableDefinition">
|
||||
</resultMap>
|
||||
<!--后端业务逻辑,公共查询逻辑1-->
|
||||
<sql id="font_base_where">
|
||||
<if test="queryMap.spaceId != null">
|
||||
and space_id = #{queryMap.spaceId}
|
||||
</if>
|
||||
<if test="queryMap.status != null">
|
||||
and status = #{queryMap.status}
|
||||
</if>
|
||||
<if test="queryMap.tableName != null">
|
||||
and table_name like concat('%',#{queryMap.tableName},'%')
|
||||
</if>
|
||||
<if test="queryMap.authSpaceIds != null and queryMap.authSpaceIds.size > 0">
|
||||
and space_id in
|
||||
<foreach collection="queryMap.authSpaceIds" item="spaceId" separator="," open="(" close=")">
|
||||
#{spaceId}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="queryMap.userId != null">
|
||||
and creator_id = #{queryMap.userId}
|
||||
</if>
|
||||
<include refid="SysCommonSql.base_where"></include>
|
||||
and yn = 1
|
||||
|
||||
</sql>
|
||||
|
||||
|
||||
<select id="queryTotal" resultType="java.lang.Long">
|
||||
select count(*)
|
||||
from custom_table_definition
|
||||
<where>
|
||||
<include refid="font_base_where"></include>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="queryList" resultMap="BaseResultMap">
|
||||
select
|
||||
*
|
||||
from custom_table_definition
|
||||
<where>
|
||||
<include refid="font_base_where"></include>
|
||||
</where>
|
||||
<choose>
|
||||
<when test="orderColumns != null and orderColumns.size > 0">
|
||||
<foreach collection="orderColumns" item="entity" index="index" separator="," open="order by " close="">
|
||||
<if test="entity != null">
|
||||
${entity.column}
|
||||
<if test="!entity.asc">
|
||||
desc
|
||||
</if>
|
||||
</if>
|
||||
</foreach>
|
||||
</when>
|
||||
<otherwise>
|
||||
order by created desc
|
||||
</otherwise>
|
||||
</choose>
|
||||
limit #{startIndex}, #{pageSize}
|
||||
</select>
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user