mirror of
https://github.com/getrebuild/rebuild.git
synced 2024-09-20 07:25:54 +08:00
Fix 3.6.5 (#763)
* fix: clearFields N2N * fix: v3.7 BW 无需修正,值由用户提供 * be: isEnableBizzPart * be: dbInfo, allowPublicKeyRetrieval * 3.6.5 * be
This commit is contained in:
parent
ba912dcb7a
commit
bcdd1e0292
2
pom.xml
2
pom.xml
|
@ -10,7 +10,7 @@
|
|||
</parent>
|
||||
<groupId>com.rebuild</groupId>
|
||||
<artifactId>rebuild</artifactId>
|
||||
<version>3.6.4</version>
|
||||
<version>3.6.5</version>
|
||||
<name>rebuild</name>
|
||||
<description>Building your business-systems freely!</description>
|
||||
<url>https://getrebuild.com/</url>
|
||||
|
|
|
@ -74,11 +74,11 @@ public class Application implements ApplicationListener<ApplicationStartedEvent>
|
|||
/**
|
||||
* Rebuild Version
|
||||
*/
|
||||
public static final String VER = "3.6.4";
|
||||
public static final String VER = "3.6.5";
|
||||
/**
|
||||
* Rebuild Build [MAJOR]{1}[MINOR]{2}[PATCH]{2}[BUILD]{2}
|
||||
*/
|
||||
public static final int BUILD = 3060409;
|
||||
public static final int BUILD = 3060510;
|
||||
|
||||
static {
|
||||
// Driver for DB
|
||||
|
|
|
@ -42,7 +42,7 @@ public class UserFilters {
|
|||
}
|
||||
|
||||
/**
|
||||
* 是否允许访问
|
||||
* 指定用户是否允许访问
|
||||
*
|
||||
* @param user
|
||||
* @param bizzId
|
||||
|
@ -55,20 +55,32 @@ public class UserFilters {
|
|||
if (isEnableBizzPart(user)) {
|
||||
final User ub = Application.getUserStore().getUser(user);
|
||||
|
||||
if (bizzId.getEntityCode() == EntityHelper.Department) {
|
||||
return ub.getOwningDept() != null && bizzId.equals(ub.getOwningDept().getIdentity());
|
||||
// 本部门及子部门的用户
|
||||
if (bizzId.getEntityCode() == EntityHelper.User) {
|
||||
if (user.equals(bizzId)) return true;
|
||||
if (ub.getOwningDept() == null) return false;
|
||||
|
||||
// 可访问部门就是可访问部门下的用户
|
||||
Department dept = UserHelper.getDepartment(bizzId);
|
||||
if (dept == null) return false;
|
||||
bizzId = (ID) dept.getIdentity();
|
||||
}
|
||||
|
||||
// 本部门及子部门
|
||||
if (bizzId.getEntityCode() == EntityHelper.Department) {
|
||||
Department dept = ub.getOwningDept();
|
||||
if (dept == null) return false;
|
||||
if (bizzId.equals(dept.getIdentity())) return true;
|
||||
return UserHelper.getAllChildren(dept).contains(bizzId);
|
||||
}
|
||||
|
||||
// 所在团队
|
||||
if (bizzId.getEntityCode() == EntityHelper.Team) {
|
||||
for (Team m : ub.getOwningTeams()) {
|
||||
if (bizzId.equals(m.getIdentity())) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bizzId.getEntityCode() == EntityHelper.User) {
|
||||
return user.equals(bizzId);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -657,6 +657,9 @@ public class AdvFilterParser extends SetUser {
|
|||
EasyMetaFactory.valueOf(field).getExtraAttr(EasyFieldConfigProps.DATE_FORMAT),
|
||||
DisplayType.DATE.getDefaultFormat());
|
||||
|
||||
// v3.7 BW 无需修正,值由用户提供
|
||||
if (ParseHelper.BW.equals(op)) dateFormat = "0";
|
||||
|
||||
if (dateFormat.length() == 4) {
|
||||
value = value.substring(0, 4) + "-01-01";
|
||||
} else if (dateFormat.length() == 7) {
|
||||
|
|
|
@ -233,13 +233,12 @@ public class FieldWriteback extends FieldAggregation {
|
|||
}
|
||||
|
||||
// v3.3 修改/清空时修改前值
|
||||
// TODO N2N 是否也需要???
|
||||
boolean clearFields = ((JSONObject) actionContext.getActionContent()).getBooleanValue("clearFields");
|
||||
if (clearFields) {
|
||||
Record beforeRecord = operatingContext.getBeforeRecord();
|
||||
Object beforeValue = beforeRecord == null ? null : beforeRecord.getObjectValue(targetFieldEntity[0]);
|
||||
if (beforeValue != null && !beforeValue.equals(o)) {
|
||||
fieldWritebackRefresh = new FieldWritebackRefresh(this, (ID) beforeValue);
|
||||
fieldWritebackRefresh = new FieldWritebackRefresh(this, beforeValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,8 +16,9 @@ import com.rebuild.core.privileges.UserService;
|
|||
import com.rebuild.core.service.general.OperatingContext;
|
||||
import com.rebuild.core.service.trigger.ActionContext;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* @author RB
|
||||
|
@ -27,9 +28,10 @@ import java.util.Collections;
|
|||
public class FieldWritebackRefresh {
|
||||
|
||||
final private FieldWriteback parent;
|
||||
final private ID beforeValue;
|
||||
// ID or ID[]
|
||||
final private Object beforeValue;
|
||||
|
||||
protected FieldWritebackRefresh(FieldWriteback parent, ID beforeValue) {
|
||||
protected FieldWritebackRefresh(FieldWriteback parent, Object beforeValue) {
|
||||
this.parent = parent;
|
||||
this.beforeValue = beforeValue;
|
||||
}
|
||||
|
@ -37,6 +39,7 @@ public class FieldWritebackRefresh {
|
|||
/**
|
||||
*/
|
||||
public void refresh() {
|
||||
if (beforeValue instanceof ID[] && ((ID[]) beforeValue).length == 0) return;
|
||||
if (NullValue.isNull(beforeValue)) return;
|
||||
|
||||
ID triggerUser = UserService.SYSTEM_USER;
|
||||
|
@ -48,7 +51,10 @@ public class FieldWritebackRefresh {
|
|||
FieldWriteback fa = new FieldWriteback(actionContext);
|
||||
fa.sourceEntity = parent.sourceEntity;
|
||||
fa.targetEntity = parent.targetEntity;
|
||||
fa.targetRecordIds = Collections.singleton(beforeValue);
|
||||
|
||||
fa.targetRecordIds = new HashSet<>();
|
||||
if (beforeValue instanceof ID[]) CollectionUtils.addAll(fa.targetRecordIds, (ID[]) beforeValue);
|
||||
else fa.targetRecordIds.add((ID) beforeValue);
|
||||
|
||||
ID fakeSourceId = EntityHelper.newUnsavedId(fa.sourceEntity.getEntityCode());
|
||||
Record fakeSourceRecord = EntityHelper.forUpdate(fakeSourceId, triggerUser, false);
|
||||
|
|
61
src/main/java/com/rebuild/core/support/setup/DbInfo.java
Normal file
61
src/main/java/com/rebuild/core/support/setup/DbInfo.java
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*!
|
||||
Copyright (c) REBUILD <https://getrebuild.com/> and/or its owners. All rights reserved.
|
||||
|
||||
rebuild is dual-licensed under commercial and open source licenses (GPLv3).
|
||||
See LICENSE and COMMERCIAL in the project root for license information.
|
||||
*/
|
||||
|
||||
package com.rebuild.core.support.setup;
|
||||
|
||||
/**
|
||||
* @author RB
|
||||
* @since 2024/4/10
|
||||
*/
|
||||
public class DbInfo {
|
||||
|
||||
final private String desc;
|
||||
|
||||
protected DbInfo(String desc) {
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public boolean isOceanBase() {
|
||||
return desc.contains("OceanBase");
|
||||
}
|
||||
|
||||
public boolean isH2() {
|
||||
return desc.contains("H2");
|
||||
}
|
||||
|
||||
public boolean isMySQL56() {
|
||||
if (isOceanBase()) return false;
|
||||
return desc.contains("5.6.");
|
||||
}
|
||||
|
||||
public boolean isMySQL80() {
|
||||
if (isOceanBase()) return false;
|
||||
return desc.contains("8.0.") || desc.contains("8.1.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param L
|
||||
* @return
|
||||
*/
|
||||
protected boolean isIgnoredSqlLine(String L) {
|
||||
if (isH2()) {
|
||||
// NOTE `double` 字段也不支持
|
||||
return L.startsWith("fulltext ") || L.startsWith("unique ") || L.startsWith("index ");
|
||||
}
|
||||
|
||||
if (isOceanBase()) {
|
||||
return L.startsWith("fulltext ");
|
||||
}
|
||||
|
||||
if (isMySQL56()) {
|
||||
// FIXME 针对实体,注意后续添加
|
||||
return L.startsWith("index IX0_attachment_folder");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -80,6 +80,11 @@ public class Installer implements InstallState {
|
|||
|
||||
private JSONObject installProps;
|
||||
|
||||
private DbInfo dbInfo;
|
||||
|
||||
// for MySQL8
|
||||
private boolean allowPublicKeyRetrieval = false;
|
||||
|
||||
private String EXISTS_SN;
|
||||
|
||||
private Installer() { }
|
||||
|
@ -107,6 +112,15 @@ public class Installer implements InstallState {
|
|||
installProps.put("db.passwd", String.format("AES(%s)", AES.encrypt(dbPasswd)));
|
||||
}
|
||||
|
||||
if (dbInfo.isOceanBase()) {
|
||||
installProps.put("db.type", "OceanBase");
|
||||
} else if (dbInfo.isMySQL80()) {
|
||||
// https://www.cnblogs.com/lusaisai/p/13372763.html
|
||||
String dbUrl8 = installProps.getProperty("db.url");
|
||||
if (!dbUrl8.contains("allowPublicKeyRetrieval")) dbUrl8 += "&allowPublicKeyRetrieval=true";
|
||||
installProps.put("db.url", dbUrl8);
|
||||
}
|
||||
|
||||
// Redis
|
||||
JSONObject cacheProps = this.installProps.getJSONObject("cacheProps");
|
||||
if (cacheProps != null && !cacheProps.isEmpty()) {
|
||||
|
@ -127,8 +141,8 @@ public class Installer implements InstallState {
|
|||
try {
|
||||
FileUtils.deleteQuietly(dest);
|
||||
try (OutputStream os = Files.newOutputStream(dest.toPath())) {
|
||||
installProps.store(os, "REBUILD (v2) INSTALLER MAGIC !!! DO NOT EDIT !!!");
|
||||
log.info("Saved installation file : " + dest);
|
||||
installProps.store(os, "REBUILD INSTALLER MAGIC !!! DO NOT EDIT !!!");
|
||||
log.info("Saved installation file : {}", dest);
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
|
@ -211,9 +225,22 @@ public class Installer implements InstallState {
|
|||
* @throws SQLException
|
||||
*/
|
||||
public Connection getConnection(String dbName) throws SQLException {
|
||||
Properties props = this.buildConnectionProps(dbName);
|
||||
return DriverManager.getConnection(
|
||||
props.getProperty("db.url"), props.getProperty("db.user"), props.getProperty("db.passwd"));
|
||||
Properties props = buildConnectionProps(dbName);
|
||||
try {
|
||||
return DriverManager.getConnection(
|
||||
props.getProperty("db.url"), props.getProperty("db.user"), props.getProperty("db.passwd"));
|
||||
} catch (SQLException ex) {
|
||||
|
||||
// Plugin 'mysql_native_password' is not loaded
|
||||
allowPublicKeyRetrieval = ex.getMessage().contains("Public Key Retrieval is not allowed");
|
||||
if (allowPublicKeyRetrieval) {
|
||||
props = buildConnectionProps(dbName);
|
||||
return DriverManager.getConnection(
|
||||
props.getProperty("db.url"), props.getProperty("db.user"), props.getProperty("db.passwd"));
|
||||
}
|
||||
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -230,7 +257,7 @@ public class Installer implements InstallState {
|
|||
Properties props = new Properties();
|
||||
dbName = StringUtils.defaultIfBlank(dbName, "H2DB");
|
||||
File dbFile = RebuildConfiguration.getFileOfData(dbName);
|
||||
log.warn("Use H2 database : " + dbFile);
|
||||
log.warn("Use H2 database : {}", dbFile);
|
||||
|
||||
props.put("db.url", String.format("jdbc:h2:file:%s;MODE=MYSQL;DATABASE_TO_LOWER=TRUE;IGNORECASE=TRUE",
|
||||
dbFile.getAbsolutePath()));
|
||||
|
@ -249,7 +276,7 @@ public class Installer implements InstallState {
|
|||
getTimeZoneId());
|
||||
|
||||
// https://www.cnblogs.com/lusaisai/p/13372763.html
|
||||
// allowPublicKeyRetrieval=true
|
||||
if (allowPublicKeyRetrieval) dbUrl += "&allowPublicKeyRetrieval=true";
|
||||
|
||||
String dbUser = dbProps.getString("dbUser");
|
||||
String dbPassword = dbProps.getString("dbPassword");
|
||||
|
@ -268,6 +295,8 @@ public class Installer implements InstallState {
|
|||
* @return
|
||||
*/
|
||||
protected boolean installDatabase() {
|
||||
dbInfo = getDbInfo();
|
||||
|
||||
// 本身就是 RB 数据库,无需创建
|
||||
if (isRbDatabase()) {
|
||||
log.warn("Use exists REBUILD database without create");
|
||||
|
@ -280,7 +309,7 @@ public class Installer implements InstallState {
|
|||
try (Connection ignored = getConnection(null)) {
|
||||
// NOOP
|
||||
} catch (SQLException e) {
|
||||
if (!e.getLocalizedMessage().contains("Unknown database")) {
|
||||
if (!e.getMessage().contains("Unknown database")) {
|
||||
throw new SetupException(e);
|
||||
}
|
||||
|
||||
|
@ -290,7 +319,7 @@ public class Installer implements InstallState {
|
|||
try (Connection conn = getConnection("mysql")) {
|
||||
try (Statement stmt = conn.createStatement()) {
|
||||
stmt.executeUpdate(createDb);
|
||||
log.warn("Database created : " + createDb);
|
||||
log.warn("Database created : {}", createDb);
|
||||
}
|
||||
|
||||
} catch (SQLException sqlex) {
|
||||
|
@ -302,13 +331,13 @@ public class Installer implements InstallState {
|
|||
// 初始化数据库
|
||||
try (Connection conn = getConnection(null)) {
|
||||
int affetced = 0;
|
||||
for (final String sql : getDbInitScript()) {
|
||||
for (final String s : getDbInitScript()) {
|
||||
try (Statement stmt = conn.createStatement()) {
|
||||
stmt.execute(sql);
|
||||
stmt.execute(s);
|
||||
affetced++;
|
||||
}
|
||||
}
|
||||
log.info("Schemes of database created : " + affetced);
|
||||
log.info("Database schemes init : {}", affetced);
|
||||
|
||||
} catch (SQLException | IOException e) {
|
||||
throw new SetupException(e);
|
||||
|
@ -317,6 +346,23 @@ public class Installer implements InstallState {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public DbInfo getDbInfo() {
|
||||
if (quickMode) return new DbInfo("H2");
|
||||
|
||||
try (Connection conn = getConnection("mysql")) {
|
||||
try (Statement stmt = conn.createStatement()) {
|
||||
try (ResultSet rs = stmt.executeQuery("select version()")) {
|
||||
if (rs.next()) return new DbInfo(rs.getString(1));
|
||||
}
|
||||
}
|
||||
} catch (SQLException ignored) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @throws IOException
|
||||
|
@ -332,13 +378,9 @@ public class Installer implements InstallState {
|
|||
boolean ignoreTerms = false;
|
||||
for (Object L : LS) {
|
||||
String L2 = L.toString().trim();
|
||||
|
||||
// NOTE double 字段也不支持
|
||||
boolean H2Unsupported = quickMode
|
||||
&& (L2.startsWith("fulltext ") || L2.startsWith("unique ") || L2.startsWith("index "));
|
||||
|
||||
// Ignore comments and line of blank
|
||||
if (StringUtils.isEmpty(L2) || L2.startsWith("--") || H2Unsupported) {
|
||||
// IGNORED
|
||||
if (StringUtils.isEmpty(L2) || L2.startsWith("--")
|
||||
|| (dbInfo != null && dbInfo.isIgnoredSqlLine(L2))) {
|
||||
continue;
|
||||
}
|
||||
if (L2.startsWith("/*") || L2.endsWith("*/")) {
|
||||
|
@ -396,7 +438,7 @@ public class Installer implements InstallState {
|
|||
}
|
||||
|
||||
} catch (SQLException sqlex) {
|
||||
log.error("Cannot execute SQL : " + sql, sqlex);
|
||||
log.error("Cannot execute SQL : {}", sql, sqlex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -476,12 +518,13 @@ public class Installer implements InstallState {
|
|||
EXISTS_SN = value;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (SQLException ex) {
|
||||
log.error("Check REBUILD database error : " + ex.getLocalizedMessage());
|
||||
log.info("Check REBUILD database error : {}", ex.getLocalizedMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -519,6 +562,16 @@ public class Installer implements InstallState {
|
|||
return dbUrl != null && dbUrl.startsWith("jdbc:h2:");
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否 OceanBase 数据库
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static boolean isUseOceanBase() {
|
||||
String dbType = BootEnvironmentPostProcessor.getProperty("db.type");
|
||||
return dbType != null && dbType.contains("OceanBase");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
|
|
|
@ -102,7 +102,7 @@ public class InstallController extends BaseController implements InstallState {
|
|||
return RespBody.ok(okMsg);
|
||||
|
||||
} catch (SQLException ex) {
|
||||
if (ex.getLocalizedMessage().contains("Unknown database")) {
|
||||
if (ex.getMessage().contains("Unknown database")) {
|
||||
String okMsg = Language.L("连接成功 : 数据库 **%s** 不存在,系统将自动创建", dbProps.getString("dbName"));
|
||||
return RespBody.ok(okMsg);
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue