Skip to content

Commit

Permalink
feat-IDatabaseAccess-提升insertItem、updateItem对特殊数据类型的兼容性
Browse files Browse the repository at this point in the history
  • Loading branch information
aruis committed Sep 5, 2024
1 parent d3fe0b0 commit 37a16fa
Show file tree
Hide file tree
Showing 11 changed files with 163 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public interface ICreateAbilityUni extends IDatabaseUniAbility, IMetadataAbility
@POST
@Path("/create")
default Uni<String> create(Map body) {
return getDatabase().insertItem(getMainTable(), body);
return getDatabase().insertItem(getSchemaName(), getMainTable(), body);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public interface ICreateAbility extends IDatabaseAbility, IMetadataAbility {
@POST
@Path("/create")
default String create(Map body) {
return getDatabase().insertItem(getMainTable(), body);
return getDatabase().insertItem(getSchemaName(), getMainTable(), body);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public interface IUpdateAbility extends IDatabaseAbility, IMetadataAbility {
@Transactional
default Integer update(@PathParam("id") String id, Map body) {
body.put("id", id);
return getDatabase().updateItem(getMainTable(), body);
return getDatabase().updateItem(getSchemaName(), getMainTable(), body);
}

}
1 change: 1 addition & 0 deletions my-database-std/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ dependencies {
api enforcedPlatform(libs.quarkus.platform.bom)
api project(':my-database')

api "org.eclipse:yasson:3.0.4"
api "io.quarkus:quarkus-hibernate-orm"
api "io.quarkus:quarkus-jdbc-postgresql"
}
Original file line number Diff line number Diff line change
@@ -1,40 +1,78 @@
package net.ximatai.muyun.database.std;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.json.bind.Jsonb;
import jakarta.json.bind.JsonbBuilder;
import jakarta.transaction.Transactional;
import net.ximatai.muyun.database.DBInfoProvider;
import net.ximatai.muyun.database.IDatabaseAccessStd;
import net.ximatai.muyun.database.exception.MyDatabaseException;

import net.ximatai.muyun.database.metadata.DBColumn;
import net.ximatai.muyun.database.metadata.DBTable;
import org.postgresql.util.PGobject;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@ApplicationScoped
public class DataAccessStd extends DBInfoProvider implements IDatabaseAccessStd {

Jsonb jsonb = JsonbBuilder.create();

@Override
public <T> T insert(String sql, Map<String, ?> params, String pk, Class<T> idType) {
return getJdbi().withHandle(handle -> {
var query = handle.createUpdate(sql);
if (params != null) {
params.forEach(query::bind);
public Map<String, ?> transformDataForDB(DBTable dbTable, Map<String, ?> data) {
// 创建一个新的 Map 来存储修改后的数据
Map<String, Object> transformedData = new HashMap<>(data);

// 遍历原数据并修改
transformedData.forEach((k, v) -> {
DBColumn dbColumn = dbTable.getColumn(k);
if (dbColumn != null) {
transformedData.put(k, getDBValue(v, dbColumn.getType()));
}
return query.executeAndReturnGeneratedKeys(pk).mapTo(idType).one();

});

return transformedData;
}

public Object getDBValue(Object value, String type) {
if (value == null || isBlank(value.toString())) {
return null;
}

return switch (type) {
case "varchar" -> value.toString();
case "int8" -> convertToBigInteger(value);
case "int4", "int2" -> convertToInteger(value);
case "bool" -> isTrue(value);
case "date", "timestamp" -> handleDateTimestamp(value);
case "numeric" -> convertToBigDecimal(value);
case "json", "jsonb" -> convertToJson(value);
case "bytea" -> convertToByteArray(value);
default -> value;
};
}

@Override
public Map<String, Object> row(String sql, Map<String, ?> params) {
var row = getJdbi().withHandle(handle -> {
var query = handle.createQuery(sql);
if (params != null) {
params.forEach(query::bind);
}
public <T> T insert(String sql, Map<String, ?> params, String pk, Class<T> idType) {
return getJdbi().withHandle(handle -> handle.createUpdate(sql)
.bindMap(params)
.executeAndReturnGeneratedKeys(pk).mapTo(idType).one());
}

return query.mapToMap().findOne().orElse(null);
});
@Override
public Map<String, Object> row(String sql, Map<String, ?> params) {
var row = getJdbi().withHandle(handle -> handle.createQuery(sql)
.bindMap(params)
.mapToMap().findOne().orElse(null));

if (row == null) {
throw new MyDatabaseException(null, MyDatabaseException.Type.DATA_NOT_FOUND);
Expand All @@ -47,7 +85,6 @@ public Map<String, Object> row(String sql, Map<String, ?> params) {
public Map<String, Object> row(String sql, List<?> params) {
var row = getJdbi().withHandle(handle -> {
var query = handle.createQuery(sql);

if (params != null && !params.isEmpty()) {
for (int i = 0; i < params.size(); i++) {
query.bind(i, params.get(i)); // 通过索引绑定参数
Expand All @@ -71,14 +108,9 @@ public Map<String, Object> row(String sql) {

@Override
public List<Map<String, Object>> query(String sql, Map<String, ?> params) {
return getJdbi().withHandle(handle -> {
var query = handle.createQuery(sql);
if (params != null) {
params.forEach(query::bind);
}

return query.mapToMap().list();
});
return getJdbi().withHandle(handle -> handle.createQuery(sql)
.bindMap(params)
.mapToMap().list());
}

@Override
Expand All @@ -104,13 +136,9 @@ public List<Map<String, Object>> query(String sql) {
@Override
@Transactional
public Integer update(String sql, Map<String, ?> params) {
return getJdbi().withHandle(handle -> {
var update = handle.createUpdate(sql);
if (params != null) {
params.forEach(update::bind);
}
return update.execute();
});
return getJdbi().withHandle(handle -> handle.createUpdate(sql)
.bindMap(params)
.execute());
}

@Override
Expand All @@ -123,4 +151,79 @@ public Object execute(String sql) {
getJdbi().withHandle(handle -> handle.execute(sql));
return null;
}

private BigInteger convertToBigInteger(Object value) {
if (value instanceof String) {
return new BigInteger((String) value);
} else if (value instanceof Number) {
return BigInteger.valueOf(((Number) value).longValue());
}
throw new IllegalArgumentException("Cannot convert to BigInteger: " + value);
}

private Integer convertToInteger(Object value) {
if (value instanceof String) {
return Integer.valueOf((String) value);
} else if (value instanceof Number) {
return ((Number) value).intValue();
}
throw new IllegalArgumentException("Cannot convert to Integer: " + value);
}

private BigDecimal convertToBigDecimal(Object value) {
if (value instanceof String && !isBlank((String) value)) {
return new BigDecimal((String) value);
} else if (value instanceof Number) {
return BigDecimal.valueOf(((Number) value).doubleValue());
}
return null;
}

private byte[] convertToByteArray(Object value) {
if (value instanceof byte[]) {
return (byte[]) value;
}
return value.toString().getBytes();
}

private PGobject convertToJson(Object value) {
try {
PGobject jsonObject = new PGobject();
jsonObject.setType("json");

if (value instanceof String string) {
jsonObject.setValue(string);
} else if (value instanceof Map || value instanceof List) {
jsonObject.setValue(jsonb.toJson(value));
} else {
throw new MyDatabaseException("Invalid JSON content: value type is " + value.getClass().getName());
}

return jsonObject;

} catch (SQLException e) {
throw new MyDatabaseException("Error converting to PGobject for JSON type: " + e.getMessage());
}
}

private Timestamp handleDateTimestamp(Object value) {
if (value instanceof Date) {
return new Timestamp(((Date) value).getTime());
} else if (value instanceof String strValue) {
try {
return strValue.length() == 10 ? Timestamp.valueOf(strValue + " 00:00:00") : Timestamp.valueOf(strValue);
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Invalid date format: " + value);
}
}
return null;
}

private boolean isBlank(String value) {
return value == null || value.trim().isEmpty();
}

private boolean isTrue(Object value) {
return Objects.equals(value, Boolean.TRUE) || "true".equalsIgnoreCase(value.toString());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
public interface IDatabaseAccessUni extends IDatabaseAccess {

@Override
default Uni<String> insertItem(String tableName, Map<String, ?> params) {
return (Uni<String>) IDatabaseAccess.super.insertItem(tableName, params);
default Uni<String> insertItem(String schema, String tableName, Map<String, ?> params) {
return (Uni<String>) IDatabaseAccess.super.insertItem(schema, tableName, params);
}

default Uni<Boolean> updateItem(String tableName, Map<String, ?> params) {
Uni<Integer> updated = (Uni<Integer>) IDatabaseAccess.super.updateItem(tableName, params);
default Uni<Boolean> updateItem(String schema, String tableName, Map<String, ?> params) {
Uni<Integer> updated = (Uni<Integer>) IDatabaseAccess.super.updateItem(schema, tableName, params);
return updated.onItem().transform(rowsUpdated -> rowsUpdated == 1);
}

Expand Down
1 change: 1 addition & 0 deletions my-database/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ plugins {

dependencies {
api libs.jdbi.core
testImplementation 'com.h2database:h2:2.1.214'
}

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@

public interface IDatabaseAccess extends IDBInfoProvider {

default Map<String, ?> transformDataForDB(DBTable dbTable, Map<String, ?> data) {
return data;
}

default String buildInsertSql(String tableName, Map<String, ?> params) {
DBTable dbTable = getDBInfo().getTables().get(tableName);
Objects.requireNonNull(dbTable);
Expand Down Expand Up @@ -44,12 +48,16 @@ default String buildUpdateSql(String tableName, Map<String, ?> params, String pk
return "UPDATE " + tableName + " SET " + setClause + " WHERE " + pk + "=:" + pk;
}

default Object insertItem(String tableName, Map<String, ?> params) {
return this.insert(buildInsertSql(tableName, params), params, "id", String.class);
default Object insertItem(String schema, String tableName, Map<String, ?> params) {
DBTable table = getDBInfo().getSchema(schema).getTable(tableName);
Map<String, ?> transformed = transformDataForDB(table, params);
return this.insert(buildInsertSql(tableName, transformed), transformed, "id", String.class);
}

default Object updateItem(String tableName, Map<String, ?> params) {
return this.update(buildUpdateSql(tableName, params, "id"), params);
default Object updateItem(String schema, String tableName, Map<String, ?> params) {
DBTable table = getDBInfo().getSchema(schema).getTable(tableName);
Map<String, ?> transformed = transformDataForDB(table, params);
return this.update(buildUpdateSql(tableName, transformed, "id"), transformed);
}

default Object deleteItem(String tableName, String id) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@

public interface IDatabaseAccessStd extends IDatabaseAccess {

default String insertItem(String tableName, Map<String, ?> params) {
return (String) IDatabaseAccess.super.insertItem(tableName, params);
default String insertItem(String schema, String tableName, Map<String, ?> params) {
return (String) IDatabaseAccess.super.insertItem(schema, tableName, params);
}

default Integer updateItem(String tableName, Map<String, ?> params) {
Integer num = (Integer) IDatabaseAccess.super.updateItem(tableName, params);
default Integer updateItem(String schema, String tableName, Map<String, ?> params) {
Integer num = (Integer) IDatabaseAccess.super.updateItem(schema, tableName, params);
if (num == 0) {
throw new MyDatabaseException(MyDatabaseException.Type.DATA_NOT_FOUND);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
package net.ximatai.muyun.platform.controller;

import jakarta.inject.Inject;
import jakarta.ws.rs.Path;
import net.ximatai.muyun.ability.curd.std.ICURDAbility;
import net.ximatai.muyun.database.IDatabaseAccess;
import net.ximatai.muyun.core.Scaffold;

@Path("/module")
public class ModuleController implements ICURDAbility {

@Inject
IDatabaseAccess databaseAccess;
public class ModuleController extends Scaffold implements ICURDAbility {

@Override
public String getSchemaName() {
Expand All @@ -21,8 +17,4 @@ public String getMainTable() {
return "app_module";
}

@Override
public IDatabaseAccess getDatabaseAccess() {
return databaseAccess;
}
}
2 changes: 1 addition & 1 deletion settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ plugins {
id "com.gradle.develocity" version "3.17.5"
}

rootProject.name = 'MuYun'
rootProject.name = 'muyun'

assert JavaVersion.current() >= JavaVersion.VERSION_21:
"You must use at least Java 21 to build the project, you're currently using ${System.getProperty("java.version")}"
Expand Down

0 comments on commit 37a16fa

Please sign in to comment.