-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat-IDataCheckAbility-改进了数据校验能力,现在可以根据数据库配置进行自动校验
- Loading branch information
Showing
12 changed files
with
359 additions
and
21 deletions.
There are no files selected for viewing
206 changes: 206 additions & 0 deletions
206
muyun-boot/src/test/java/net/ximatai/muyun/test/core/TestDataCheckAbility.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
99 changes: 97 additions & 2 deletions
99
muyun-core/src/main/java/net/ximatai/muyun/ability/curd/std/IDataCheckAbility.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.