Skip to content

Commit

Permalink
feat-IDataCheckAbility-改进了数据校验能力,现在可以根据数据库配置进行自动校验
Browse files Browse the repository at this point in the history
  • Loading branch information
aruis committed Nov 19, 2024
1 parent d3f34f6 commit 49356db
Show file tree
Hide file tree
Showing 12 changed files with 359 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
package net.ximatai.muyun.test.core;

import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.junit.QuarkusTest;
import jakarta.inject.Inject;
import jakarta.ws.rs.Path;
import net.ximatai.muyun.ability.curd.std.IDataCheckAbility;
import net.ximatai.muyun.base.BaseScaffold;
import net.ximatai.muyun.core.config.MuYunConfig;
import net.ximatai.muyun.database.builder.Column;
import net.ximatai.muyun.database.builder.TableWrapper;
import net.ximatai.muyun.test.testcontainers.PostgresTestResource;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Map;
import java.util.UUID;

import static io.restassured.RestAssured.given;

@QuarkusTest
@QuarkusTestResource(value = PostgresTestResource.class, restrictToAnnotatedClass = true)
public class TestDataCheckAbility {
@Inject
MuYunConfig config;

@Test
void testStringBlank() {
String result = given()
.header("userID", config.superUserId())
.contentType("application/json")
.body(Map.of(
"v_name", " ",
"v_title", "test_title",
"ids_test", List.of(1, 2, 3)
))
.when()
.post("/TestDataCheckAbility/create")
.then()
.statusCode(500)
.extract()
.asString();

Assertions.assertEquals("数据项[名称]要求为必填", result);
}

@Test
void testStringNull() {
String result = given()
.header("userID", config.superUserId())
.contentType("application/json")
.body(Map.of(
"v_name", "name",
"ids_test", List.of(1, 2, 3)
))
.when()
.post("/TestDataCheckAbility/create")
.then()
.statusCode(500)
.extract()
.asString();

Assertions.assertEquals("数据项[标题]要求为必填", result);
}

@Test
void testListEmpty() {
String result = given()
.header("userID", config.superUserId())
.contentType("application/json")
.body(Map.of(
"v_name", "name",
"v_title", "test_title",
"ids_test", List.of()
))
.when()
.post("/TestDataCheckAbility/create")
.then()
.statusCode(500)
.extract()
.asString();

Assertions.assertEquals("数据项[数组测试]要求为必填", result);
}

@Test
void testDuplicateDataCreate() {
String name = UUID.randomUUID().toString();
given()
.header("userID", config.superUserId())
.contentType("application/json")
.body(Map.of(
"v_name", name,
"v_title", "test_title",
"ids_test", List.of(1, 2, 3)
))
.when()
.post("/TestDataCheckAbility/create")
.then()
.statusCode(200)
.extract()
.asString();

String result = given()
.header("userID", config.superUserId())
.contentType("application/json")
.body(Map.of(
"v_name", name,
"v_title", "test_title",
"ids_test", List.of(1, 2, 3)
))
.when()
.post("/TestDataCheckAbility/create")
.then()
.statusCode(500)
.extract()
.asString();

Assertions.assertEquals("数据项[名称]已存在相同的数据", result);
}

@Test
void testDuplicateDataUpdate() {
String name = UUID.randomUUID().toString();
String id = given()
.header("userID", config.superUserId())
.contentType("application/json")
.body(Map.of(
"v_name", name,
"v_title", "test_title",
"ids_test", List.of(1, 2, 3)
))
.when()
.post("/TestDataCheckAbility/create")
.then()
.statusCode(200)
.extract()
.asString();

given()
.header("userID", config.superUserId())
.contentType("application/json")
.body(Map.of(
"v_name", name,
"v_title", "test_title",
"ids_test", List.of(1, 2, 3)
))
.when()
.post("/TestDataCheckAbility/update/%s".formatted(id))
.then()
.statusCode(200)
.extract()
.asString();

String id2 = given()
.header("userID", config.superUserId())
.contentType("application/json")
.body(Map.of(
"v_name", UUID.randomUUID().toString(),
"v_title", "test_title",
"ids_test", List.of(1, 2, 3)
))
.when()
.post("/TestDataCheckAbility/create")
.then()
.statusCode(200)
.extract()
.asString();

String result = given()
.header("userID", config.superUserId())
.contentType("application/json")
.body(Map.of(
"v_name", name,
"v_title", "test_title",
"ids_test", List.of(1, 2, 3)
))
.when()
.post("/TestDataCheckAbility/update/%s".formatted(id2))
.then()
.statusCode(500)
.extract()
.asString();

Assertions.assertEquals("数据项[名称]已存在相同的数据", result);
}
}

@Path("/TestDataCheckAbility")
class TestDataCheckAbilityController extends BaseScaffold implements IDataCheckAbility {

@Override
public String getMainTable() {
return "testdatacheckability";
}

@Override
public void fitOut(TableWrapper wrapper) {
wrapper.setPrimaryKey(Column.ID_POSTGRES)
.addColumn("v_name", "名称", null, false)
.addColumn("v_title", "标题", null, false)
.addColumn("ids_test", "数组测试", null, false)
.addIndex("v_name", true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ void test() {
.extract()
.asString();

assertTrue(res.contains("部门必须归属具体机构"));
assertEquals("数据项[所属机构]要求为必填", res);

given()
.header("userID", config.superUserId())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import jakarta.transaction.Transactional;
import net.ximatai.muyun.base.BaseBusinessTable;
import net.ximatai.muyun.core.exception.MyException;
import net.ximatai.muyun.database.IDatabaseOperations;
import net.ximatai.muyun.database.builder.TableBuilder;
import net.ximatai.muyun.database.builder.TableWrapper;
Expand All @@ -23,7 +24,12 @@ default void onTableCreated(boolean isFirst) {

@Transactional
default void create(IDatabaseOperations db) {
TableWrapper wrapper = TableWrapper.withName(getMainTable())
String mainTable = getMainTable();
if (!mainTable.toLowerCase().equals(mainTable)) {
throw new MyException("%s表明不合法,不允许使用大写字母".formatted(mainTable));
}

TableWrapper wrapper = TableWrapper.withName(mainTable)
.setSchema(getSchemaName());

fitOut(wrapper);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,7 @@
import jakarta.transaction.Transactional;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import net.ximatai.muyun.ability.IChildrenAbility;
import net.ximatai.muyun.ability.ICodeGenerateAbility;
import net.ximatai.muyun.ability.IDataBroadcastAbility;
import net.ximatai.muyun.ability.IDatabaseAbilityStd;
import net.ximatai.muyun.ability.IMetadataAbility;
import net.ximatai.muyun.ability.IRuntimeAbility;
import net.ximatai.muyun.ability.ISecurityAbility;
import net.ximatai.muyun.ability.ITreeAbility;
import net.ximatai.muyun.ability.*;
import net.ximatai.muyun.core.exception.MyException;
import net.ximatai.muyun.database.builder.Column;
import net.ximatai.muyun.model.DataChangeChannel;
Expand Down Expand Up @@ -56,6 +49,7 @@ default String create(Map body) {

if (this instanceof IDataCheckAbility dataCheckAbility) {
dataCheckAbility.check(body, false);
dataCheckAbility.checkWhenCreate(body);
}

if (this instanceof ISecurityAbility securityAbility) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,107 @@
package net.ximatai.muyun.ability.curd.std;

import net.ximatai.muyun.ability.IMetadataAbility;
import net.ximatai.muyun.ability.ISoftDeleteAbility;
import net.ximatai.muyun.core.exception.MyException;
import net.ximatai.muyun.database.metadata.DBColumn;
import net.ximatai.muyun.database.metadata.DBTable;
import net.ximatai.muyun.model.CheckConfig;

import java.util.List;
import java.util.Map;

/**
* 数据新增、修改时进行校验的能力
*/
public interface IDataCheckAbility {
public interface IDataCheckAbility extends IMetadataAbility {

default CheckConfig getCheckConfig() {
CheckConfig config = new CheckConfig();
DBTable dbTable = getDBTable();
dbTable.getColumnMap().forEach((k, v) -> {
if (v.isPrimaryKey()) {
return;
}
if (!v.isNullable()) {
config.addNonEmpty(v.getName(), "数据项[%s]要求为必填".formatted(v.getLabel()));
}
});

dbTable.getIndexList().forEach(dbIndex -> {
if (dbIndex.isUnique() && !dbIndex.isMulti()) {
String columnName = dbIndex.getColumns().getFirst();
DBColumn column = dbTable.getColumn(columnName);
config.addUnique(columnName, "数据项[%s]已存在相同的数据".formatted(column.getLabel()));
}

});

fitOut(config);

return config;
}

default void fitOut(CheckConfig config) {
}

default void check(Map body, boolean isUpdate) {

}

default void checkWhenCreate(Map body) {
CheckConfig config = getCheckConfig();
config.getNonEmptyMap().forEach((column, tip) -> {
checkColumn(body.get(column), tip);
});

config.getUniqueMap().forEach((column, tip) -> {
if (body.get(column) != null) {
String deleteWhere = "";
if (this instanceof ISoftDeleteAbility ability) {
deleteWhere += " AND %s = false ".formatted(ability.getSoftDeleteColumn());
}
Object row = getDatabaseOperations().row("select 1 from %s.%s where %s = ? %s"
.formatted(getSchemaName(), getMainTable(), column, deleteWhere), body.get(column));
if (row != null) {
throw new MyException(tip);
}
}
});

}

default void checkWhenUpdate(String id, Map body) {
CheckConfig config = getCheckConfig();
config.getNonEmptyMap().forEach((column, tip) -> {
if (body.containsKey(column)) {
checkColumn(body.get(column), tip);
}

});

config.getUniqueMap().forEach((column, tip) -> {
if (body.get(column) != null) {
String deleteWhere = "";
if (this instanceof ISoftDeleteAbility ability) {
deleteWhere += " and %s = false ".formatted(ability.getSoftDeleteColumn());
}
Object row = getDatabaseOperations().row("select 1 from %s.%s where %s = ? %s and id != ?"
.formatted(getSchemaName(), getMainTable(), column, deleteWhere), body.get(column), id);
if (row != null) {
throw new MyException(tip);
}
}
});
}

void check(Map body, boolean isUpdate);
private void checkColumn(Object field, String tip) {
if (field == null
|| (field instanceof String str && str.isBlank())
|| (field instanceof Map<?, ?> map && map.isEmpty())
|| (field instanceof List<?> list && list.isEmpty())
|| (field instanceof Object[] arr && arr.length == 0)) {
throw new MyException(tip);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ default Integer update(@PathParam("id") String id, Map body) {

if (this instanceof IDataCheckAbility dataCheckAbility) {
dataCheckAbility.check(map, true);
dataCheckAbility.checkWhenUpdate(id, body);
}

if (this instanceof ISecurityAbility securityAbility) {
Expand Down
Loading

0 comments on commit 49356db

Please sign in to comment.