(improvement)(Headless) Support setting fields as foreign keys when creating data-model (#1857)

Co-authored-by: lxwcodemonkey
This commit is contained in:
LXW
2024-10-29 18:42:31 +08:00
committed by GitHub
parent 0383683ac0
commit ec6d7ba93d
7 changed files with 61 additions and 11 deletions

View File

@@ -84,14 +84,14 @@ public class SchemaElement implements Serializable {
return false; return false;
} }
Object o = extInfo.get(DimensionConstants.DIMENSION_TYPE); Object o = extInfo.get(DimensionConstants.DIMENSION_TYPE);
DimensionType dimensionTYpe = null; DimensionType dimensionType = null;
if (o instanceof DimensionType) { if (o instanceof DimensionType) {
dimensionTYpe = (DimensionType) o; dimensionType = (DimensionType) o;
} }
if (o instanceof String) { if (o instanceof String) {
dimensionTYpe = DimensionType.valueOf((String) o); dimensionType = DimensionType.valueOf((String) o);
} }
return DimensionType.isIdentity(dimensionTYpe); return DimensionType.isPrimaryKey(dimensionType);
} }
public String getTimeFormat() { public String getTimeFormat() {

View File

@@ -1,7 +1,16 @@
package com.tencent.supersonic.headless.api.pojo.enums; package com.tencent.supersonic.headless.api.pojo.enums;
public enum DimensionType { public enum DimensionType {
categorical, time, partition_time, identify; categorical, time, partition_time, primary_key, foreign_key;
public static DimensionType fromIdentify(String identify) {
if (IdentifyType.foreign.name().equalsIgnoreCase(identify)) {
return DimensionType.foreign_key;
} else if (IdentifyType.primary.name().equalsIgnoreCase(identify)) {
return DimensionType.primary_key;
}
return DimensionType.categorical;
}
public static boolean isTimeDimension(String type) { public static boolean isTimeDimension(String type) {
try { try {
@@ -19,7 +28,7 @@ public enum DimensionType {
return type == partition_time; return type == partition_time;
} }
public static boolean isIdentity(DimensionType type) { public static boolean isPrimaryKey(DimensionType type) {
return type == identify; return type == primary_key;
} }
} }

View File

@@ -7,6 +7,7 @@ import com.tencent.supersonic.headless.api.pojo.Field;
import com.tencent.supersonic.headless.api.pojo.Identify; import com.tencent.supersonic.headless.api.pojo.Identify;
import com.tencent.supersonic.headless.api.pojo.ModelDetail; import com.tencent.supersonic.headless.api.pojo.ModelDetail;
import com.tencent.supersonic.headless.api.pojo.SchemaItem; import com.tencent.supersonic.headless.api.pojo.SchemaItem;
import com.tencent.supersonic.headless.api.pojo.enums.IdentifyType;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
@@ -95,6 +96,16 @@ public class ModelResp extends SchemaItem {
return fieldSet; return fieldSet;
} }
public IdentifyType getIdentifyType(String fieldName) {
List<Identify> identifiers = modelDetail.getIdentifiers();
for (Identify identify : identifiers) {
if (Objects.equals(identify.getFieldName(), fieldName)) {
return IdentifyType.valueOf(identify.getType());
}
}
return null;
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) { if (this == o) {

View File

@@ -8,9 +8,14 @@ import com.tencent.supersonic.common.pojo.JoinCondition;
import com.tencent.supersonic.common.pojo.ModelRela; import com.tencent.supersonic.common.pojo.ModelRela;
import com.tencent.supersonic.common.pojo.User; import com.tencent.supersonic.common.pojo.User;
import com.tencent.supersonic.common.util.BeanMapper; import com.tencent.supersonic.common.util.BeanMapper;
import com.tencent.supersonic.headless.api.pojo.enums.IdentifyType;
import com.tencent.supersonic.headless.api.pojo.response.ModelResp;
import com.tencent.supersonic.headless.server.persistence.dataobject.ModelRelaDO; import com.tencent.supersonic.headless.server.persistence.dataobject.ModelRelaDO;
import com.tencent.supersonic.headless.server.persistence.mapper.ModelRelaDOMapper; import com.tencent.supersonic.headless.server.persistence.mapper.ModelRelaDOMapper;
import com.tencent.supersonic.headless.server.service.ModelRelaService; import com.tencent.supersonic.headless.server.service.ModelRelaService;
import com.tencent.supersonic.headless.server.service.ModelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
@@ -21,8 +26,13 @@ import java.util.stream.Collectors;
public class ModelRelaServiceImpl extends ServiceImpl<ModelRelaDOMapper, ModelRelaDO> public class ModelRelaServiceImpl extends ServiceImpl<ModelRelaDOMapper, ModelRelaDO>
implements ModelRelaService { implements ModelRelaService {
@Lazy
@Autowired
private ModelService modelService;
@Override @Override
public void save(ModelRela modelRela, User user) { public void save(ModelRela modelRela, User user) {
check(modelRela);
modelRela.createdBy(user.getName()); modelRela.createdBy(user.getName());
ModelRelaDO modelRelaDO = convert(modelRela); ModelRelaDO modelRelaDO = convert(modelRela);
save(modelRelaDO); save(modelRelaDO);
@@ -30,11 +40,31 @@ public class ModelRelaServiceImpl extends ServiceImpl<ModelRelaDOMapper, ModelRe
@Override @Override
public void update(ModelRela modelRela, User user) { public void update(ModelRela modelRela, User user) {
check(modelRela);
modelRela.updatedBy(user.getName()); modelRela.updatedBy(user.getName());
ModelRelaDO modelRelaDO = convert(modelRela); ModelRelaDO modelRelaDO = convert(modelRela);
updateById(modelRelaDO); updateById(modelRelaDO);
} }
private void check(ModelRela modelRela) {
ModelResp fromModel = modelService.getModel(modelRela.getFromModelId());
ModelResp toModel = modelService.getModel(modelRela.getToModelId());
if (CollectionUtils.isEmpty(modelRela.getJoinConditions())) {
throw new RuntimeException("关联关系不可为空");
}
for (JoinCondition joinCondition : modelRela.getJoinConditions()) {
IdentifyType identifyTypeLeft = fromModel.getIdentifyType(joinCondition.getLeftField());
IdentifyType identifyTypeRight = toModel.getIdentifyType(joinCondition.getRightField());
if (IdentifyType.foreign.equals(identifyTypeLeft)
|| IdentifyType.foreign.equals(identifyTypeRight)) {
if (!IdentifyType.primary.equals(identifyTypeLeft)
&& !IdentifyType.primary.equals(identifyTypeRight)) {
throw new RuntimeException("外键必须跟主键关联");
}
}
}
}
@Override @Override
public List<ModelRela> getModelRelaList(Long domainId) { public List<ModelRela> getModelRelaList(Long domainId) {
QueryWrapper<ModelRelaDO> wrapper = new QueryWrapper<>(); QueryWrapper<ModelRelaDO> wrapper = new QueryWrapper<>();

View File

@@ -116,7 +116,7 @@ public class DimensionConverter {
try { try {
// Support compatibility with legacy data. // Support compatibility with legacy data.
IdentifyType.valueOf(type.toLowerCase()); IdentifyType.valueOf(type.toLowerCase());
return DimensionType.identify; return DimensionType.primary_key;
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
return DimensionType.valueOf(type); return DimensionType.valueOf(type);
} }

View File

@@ -152,7 +152,7 @@ public class ModelConverter {
dimensionReq.setSemanticType(SemanticType.CATEGORY.name()); dimensionReq.setSemanticType(SemanticType.CATEGORY.name());
dimensionReq.setModelId(modelDO.getId()); dimensionReq.setModelId(modelDO.getId());
dimensionReq.setExpr(identify.getBizName()); dimensionReq.setExpr(identify.getBizName());
dimensionReq.setType(DimensionType.identify.name()); dimensionReq.setType(DimensionType.fromIdentify(identify.getType()).name());
return dimensionReq; return dimensionReq;
} }

View File

@@ -224,7 +224,7 @@ public class S2VisitsDemo extends S2BaseDemo {
modelReq.setAdminOrgs(Collections.emptyList()); modelReq.setAdminOrgs(Collections.emptyList());
List<Identify> identifiers = new ArrayList<>(); List<Identify> identifiers = new ArrayList<>();
ModelDetail modelDetail = new ModelDetail(); ModelDetail modelDetail = new ModelDetail();
identifiers.add(new Identify("用户名", IdentifyType.primary.name(), "user_name", 0)); identifiers.add(new Identify("用户名", IdentifyType.foreign.name(), "user_name", 0));
modelDetail.setIdentifiers(identifiers); modelDetail.setIdentifiers(identifiers);
List<Dim> dimensions = new ArrayList<>(); List<Dim> dimensions = new ArrayList<>();
@@ -268,7 +268,7 @@ public class S2VisitsDemo extends S2BaseDemo {
modelReq.setAdminOrgs(Collections.emptyList()); modelReq.setAdminOrgs(Collections.emptyList());
List<Identify> identifiers = new ArrayList<>(); List<Identify> identifiers = new ArrayList<>();
ModelDetail modelDetail = new ModelDetail(); ModelDetail modelDetail = new ModelDetail();
identifiers.add(new Identify("用户", IdentifyType.primary.name(), "user_name", 0)); identifiers.add(new Identify("用户", IdentifyType.foreign.name(), "user_name", 0));
modelDetail.setIdentifiers(identifiers); modelDetail.setIdentifiers(identifiers);
List<Dim> dimensions = new ArrayList<>(); List<Dim> dimensions = new ArrayList<>();