Skip to content

Commit

Permalink
feat-IQueryAbility-支持对PG数据类型进行相关的数组比较操作
Browse files Browse the repository at this point in the history
  • Loading branch information
aruis committed Dec 27, 2024
1 parent e5714f3 commit 3495365
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 12 deletions.
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ subprojects {

maven {
url = uri("http://192.168.6.205:8081/repository/maven-snapshots/")
// url = uri("http://127.0.0.1:8081/repository/maven-snapshots/")
isAllowInsecureProtocol = true
credentials {
username = findProperty("office.maven.username").toString()
Expand Down
104 changes: 96 additions & 8 deletions muyun-boot/src/test/java/net/ximatai/muyun/test/core/TestQuery.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ void setUp() {
tableName = testController.getMainTable();
databaseOperations.execute("TRUNCATE TABLE %s".formatted(tableName));

testController.create(Map.of("id", "1", "name", "test1", "t_create", "2024-01-01 12:00:00"));
testController.create(Map.of("id", "2", "name", "test2", "t_create", "2024-01-02 12:00:00"));
testController.create(Map.of("id", "3", "name", "test3", "t_create", "2024-01-03 12:00:00"));
testController.create(Map.of("id", "4", "name", "test4", "t_create", "2024-01-04 12:00:00"));
testController.create(Map.of("id", "5", "name", "test5", "t_create", "2024-01-05 12:00:00"));
testController.create(Map.of("id", "6", "name", "test6", "t_create", "2024-01-06 12:00:00"));
testController.create(Map.of("id", "7", "name", "test7", "t_create", "2024-01-07 12:00:00"));
testController.create(Map.of("id", "8", "name", "test8", "t_create", "2024-01-08 12:00:00"));
testController.create(Map.of("id", "1", "name", "test1", "av_name", List.of("a"), "t_create", "2024-01-01 12:00:00"));
testController.create(Map.of("id", "2", "name", "test2", "av_name", List.of("a", "b"), "t_create", "2024-01-02 12:00:00"));
testController.create(Map.of("id", "3", "name", "test3", "av_name", List.of("a", "b", "c"), "t_create", "2024-01-03 12:00:00"));
testController.create(Map.of("id", "4", "name", "test4", "av_name", List.of("a", "b", "c", "d"), "t_create", "2024-01-04 12:00:00"));
testController.create(Map.of("id", "5", "name", "test5", "av_name", List.of("a", "b", "c"), "t_create", "2024-01-05 12:00:00"));
testController.create(Map.of("id", "6", "name", "test6", "av_name", List.of("b", "c"), "t_create", "2024-01-06 12:00:00"));
testController.create(Map.of("id", "7", "name", "test7", "av_name", List.of("a", "c"), "t_create", "2024-01-07 12:00:00"));
testController.create(Map.of("id", "8", "name", "test8", "av_name", List.of("c"), "t_create", "2024-01-08 12:00:00"));
}

@Test
Expand Down Expand Up @@ -277,6 +277,86 @@ void testRange5() {
assertEquals(1, response.getTotal());
}

@Test
@DisplayName("比较两个数组完全相同")
void testPgArrayEqual() {
Map<String, ?> request = Map.of("av_name1", new String[]{"a", "b"});

PageResult<Map> response = given()
.contentType("application/json")
.queryParam("noPage", true)
.body(request)
.when()
.post("/api%s/view".formatted(path))
.then()
.statusCode(200)
.extract()
.as(new TypeRef<>() {
});

assertEquals(1, response.getTotal());
}

@Test
@DisplayName("比较两个数组有交集")
void testPgArrayOverlap() {
Map<String, ?> request = Map.of("av_name2", new String[]{"a", "b"});

PageResult<Map> response = given()
.contentType("application/json")
.queryParam("noPage", true)
.body(request)
.when()
.post("/api%s/view".formatted(path))
.then()
.statusCode(200)
.extract()
.as(new TypeRef<>() {
});

assertEquals(7, response.getTotal());
}

@Test
@DisplayName("获取在能被传入数组所包含的数据")
void testPgArrayContain() {
Map<String, ?> request = Map.of("av_name3", new String[]{"a", "b"});

PageResult<Map> response = given()
.contentType("application/json")
.queryParam("noPage", true)
.body(request)
.when()
.post("/api%s/view".formatted(path))
.then()
.statusCode(200)
.extract()
.as(new TypeRef<>() {
});

assertEquals(2, response.getTotal());
}

@Test
@DisplayName("获取包含了传入数组的数据")
void testPgArrayBeContain() {
Map<String, ?> request = Map.of("av_name4", new String[]{"a", "b"});

PageResult<Map> response = given()
.contentType("application/json")
.queryParam("noPage", true)
.body(request)
.when()
.post("/api%s/view".formatted(path))
.then()
.statusCode(200)
.extract()
.as(new TypeRef<>() {
});

assertEquals(4, response.getTotal());
}

}

@Path("/test_query")
Expand All @@ -297,6 +377,7 @@ public void fitOut(TableWrapper wrapper) {
wrapper
.setPrimaryKey(Column.ID_POSTGRES)
.addColumn(Column.of("name").setType(ColumnType.VARCHAR))
.addColumn(Column.of("av_name").setType(ColumnType.VARCHAR_ARRAY))
.addColumn(Column.of("t_create").setDefaultValue("now()"));

}
Expand All @@ -309,6 +390,13 @@ public List<QueryItem> queryItemList() {
QueryItem.of("id").setAlias("in_id").setSymbolType(QueryItem.SymbolType.IN),
QueryItem.of("id").setAlias("not_in_id").setSymbolType(QueryItem.SymbolType.NOT_IN),
QueryItem.of("name").setSymbolType(QueryItem.SymbolType.LIKE),
QueryItem.of("av_name").setSymbolType(QueryItem.SymbolType.PG_ARRAY_EQUAL).setAlias("av_name1"),
QueryItem.of("av_name").setSymbolType(QueryItem.SymbolType.PG_ARRAY_OVERLAP).setAlias("av_name2"),
QueryItem.of("av_name").setSymbolType(QueryItem.SymbolType.PG_ARRAY_CONTAIN).setAlias("av_name3"),
QueryItem.of("av_name").setSymbolType(QueryItem.SymbolType.PG_ARRAY_BE_CONTAIN).setAlias("av_name4"),
QueryItem.of("name").setSymbolType(QueryItem.SymbolType.LIKE),
QueryItem.of("name").setSymbolType(QueryItem.SymbolType.LIKE),
QueryItem.of("name").setSymbolType(QueryItem.SymbolType.LIKE),
QueryItem.of("t_create").setTime(true).setSymbolType(QueryItem.SymbolType.RANGE)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,31 @@ default PageResult view(Integer page,
condition.append(" %s= ? ".formatted(notMark));
params.add(v);
break;
case PG_ARRAY_EQUAL, PG_ARRAY_OVERLAP, PG_ARRAY_CONTAIN, PG_ARRAY_BE_CONTAIN:
if (!(v instanceof List list)) {
throw new QueryException("数据比较时参数也应为数组");
}

String s = "=";
if (symbolType.equals(QueryItem.SymbolType.PG_ARRAY_OVERLAP)) {
s = "&&";
}
if (symbolType.equals(QueryItem.SymbolType.PG_ARRAY_CONTAIN)) {
s = "<@";
}
if (symbolType.equals(QueryItem.SymbolType.PG_ARRAY_BE_CONTAIN)) {
s = "@>";
}

String type = "varchar";

if (!list.isEmpty() && list.get(0) instanceof Integer) {
type = "int";
}

condition.append(" %s ? ".formatted(s));
params.add(getDB().createArray(list, type));
break;
case RANGE:
if (!(v instanceof List list) || list.size() != 2) {
throw new QueryException("区间查询%s的内容必须是长度为2的数组".formatted(k));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ public static QueryItem of(String column) {

@Schema(description = "比较类型")
public enum SymbolType {
EQUAL, NOT_EQUAL, LIKE, IN, NOT_IN, RANGE
EQUAL, NOT_EQUAL, LIKE, IN, NOT_IN, RANGE,
PG_ARRAY_EQUAL, PG_ARRAY_OVERLAP, PG_ARRAY_CONTAIN, PG_ARRAY_BE_CONTAIN
}

public QueryItem setColumn(String column) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ public Object execute(String sql) {
return null;
}

public Array toArray(List list, String type) {
public Array createArray(List list, String type) {
try {
return getJdbi().withHandle(handle -> {
Connection connection = handle.getConnection();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import jakarta.inject.Inject;
import net.ximatai.muyun.database.std.argument.List2JsonArgumentFactory;
import net.ximatai.muyun.database.std.argument.Map2JsonArgumentFactory;
import net.ximatai.muyun.database.std.argument.PgArrayArgumentFactory;
import org.jdbi.v3.core.Jdbi;
import org.jdbi.v3.core.statement.Slf4JSqlLogger;

Expand All @@ -20,7 +21,7 @@ public class JdbiProducer {
public Jdbi createJdbi() {
return Jdbi.create(dataSource)
.setSqlLogger(new Slf4JSqlLogger())
// .registerArgument(new StringArrayArgumentFactory())
.registerArgument(new PgArrayArgumentFactory())
.registerArgument(new Map2JsonArgumentFactory())
.registerArgument(new List2JsonArgumentFactory());
// .installPlugin(new PostgresPlugin())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package net.ximatai.muyun.database.std.argument;

import org.jdbi.v3.core.argument.AbstractArgumentFactory;
import org.jdbi.v3.core.argument.Argument;
import org.jdbi.v3.core.config.ConfigRegistry;
import org.postgresql.jdbc.PgArray;

import java.sql.SQLException;
import java.sql.Types;

public class PgArrayArgumentFactory extends AbstractArgumentFactory<PgArray> {

public PgArrayArgumentFactory() {
super(Types.ARRAY); // 指定数据库类型为 ARRAY
}

@Override
protected Argument build(PgArray value, ConfigRegistry config) {
return (position, statement, ctx) -> {
try {
statement.setArray(position, value);
} catch (SQLException e) {
throw new RuntimeException("Error setting PgArray argument", e);
}
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -119,5 +119,5 @@ default Object getItem(String schema, String tableName, String id) {

Object execute(String sql);

Array toArray(List list, String type);
Array createArray(List list, String type);
}

0 comments on commit 3495365

Please sign in to comment.