import java.sql.*; import java.util.ArrayList; import java.util.List; /** Rename lobster workflow menu labels in master + tenant DBs. */ public class ApplyLobsterMenuRename { private static final String MASTER_HOST = getenv("DB_HOST", "cq-cdb-8fjmemkb.sql.tencentcdb.com"); private static final int MASTER_PORT = Integer.parseInt(getenv("DB_PORT", "27220")); private static final String MASTER_USER = getenv("DB_USER", "root"); private static final String MASTER_PASSWORD = getenv("DB_PASSWORD", "Ylrz_1q2w3e4r5t6y"); private static final String MASTER_DB = getenv("DB_NAME", "ylrz_saas"); private static final String MASTER_SQL = "UPDATE sys_menu SET menu_name='\u5de5\u4f5c\u6d41\u6a21\u677f' " + "WHERE menu_name IN ('\u5de5\u4f5c\u6d41\u6a21\u677f\u5e93','\u5de5\u4f5c\u6d41\u6a21\u677f') " + "AND (parent_id=2864 OR path IN ('template','company-workflowLobster'));" + "UPDATE sys_menu SET menu_name='\u5de5\u4f5c\u6d41\u6267\u884c' " + "WHERE menu_name IN ('\u5de5\u4f5c\u6d41\u6267\u884c\u4efb\u52a1','\u5de5\u4f5c\u6d41\u6267\u884c') " + "AND (parent_id=2864 OR path='workflow-execution');" + "UPDATE tenant_sys_menu SET menu_name='\u5de5\u4f5c\u6d41\u6a21\u677f' " + "WHERE menu_name IN ('\u5de5\u4f5c\u6d41\u6a21\u677f\u5e93','\u5de5\u4f5c\u6d41\u6a21\u677f') " + "AND (parent_id=29900 OR path IN ('template','company-workflowLobster') OR menu_id IN (29903,32481));" + "UPDATE tenant_sys_menu SET menu_name='\u5de5\u4f5c\u6d41\u6267\u884c' " + "WHERE menu_name IN ('\u5de5\u4f5c\u6d41\u6267\u884c\u4efb\u52a1','\u5de5\u4f5c\u6d41\u6267\u884c') " + "AND (parent_id=29900 OR path='workflow-execution' OR menu_id=29949);" + "UPDATE tenant_company_menu SET menu_name='\u5de5\u4f5c\u6d41\u6a21\u677f' " + "WHERE menu_name IN ('\u5de5\u4f5c\u6d41\u6a21\u677f\u5e93','\u5de5\u4f5c\u6d41\u6a21\u677f') " + "AND (parent_id=29900 OR path IN ('template','company-workflowLobster') OR menu_id IN (29903,32481));" + "UPDATE tenant_company_menu SET menu_name='\u5de5\u4f5c\u6d41\u6267\u884c' " + "WHERE menu_name IN ('\u5de5\u4f5c\u6d41\u6267\u884c\u4efb\u52a1','\u5de5\u4f5c\u6d41\u6267\u884c') " + "AND (parent_id=29900 OR path='workflow-execution' OR menu_id=29949);"; private static final String TENANT_SQL = "UPDATE sys_menu SET menu_name='\u5de5\u4f5c\u6d41\u6a21\u677f' " + "WHERE menu_name IN ('\u5de5\u4f5c\u6d41\u6a21\u677f\u5e93','\u5de5\u4f5c\u6d41\u6a21\u677f') " + "AND (parent_id=29900 OR path IN ('template','company-workflowLobster') OR menu_id IN (29903,32481));" + "UPDATE sys_menu SET menu_name='\u5de5\u4f5c\u6d41\u6267\u884c' " + "WHERE menu_name IN ('\u5de5\u4f5c\u6d41\u6267\u884c\u4efb\u52a1','\u5de5\u4f5c\u6d41\u6267\u884c') " + "AND (parent_id=29900 OR path='workflow-execution' OR menu_id=29949);" + "UPDATE company_menu SET menu_name='\u5de5\u4f5c\u6d41\u6a21\u677f' " + "WHERE menu_name IN ('\u5de5\u4f5c\u6d41\u6a21\u677f\u5e93','\u5de5\u4f5c\u6d41\u6a21\u677f') " + "AND (parent_id=29900 OR path IN ('template','company-workflowLobster') OR menu_id IN (29903,32481));" + "UPDATE company_menu SET menu_name='\u5de5\u4f5c\u6d41\u6267\u884c' " + "WHERE menu_name IN ('\u5de5\u4f5c\u6d41\u6267\u884c\u4efb\u52a1','\u5de5\u4f5c\u6d41\u6267\u884c') " + "AND (parent_id=29900 OR path='workflow-execution' OR menu_id=29949);"; public static void main(String[] args) throws Exception { try (Connection master = open(MASTER_HOST, MASTER_PORT, MASTER_DB, MASTER_USER, MASTER_PASSWORD)) { execBatch(master, MASTER_SQL); System.out.println("[OK] master"); for (Long tenantId : loadActiveTenantIds(master)) { TenantDb tenant = loadTenant(master, tenantId); if (tenant == null) continue; System.out.println("[TENANT] " + tenantId + " -> " + tenant.database); try (Connection c = open(tenant.host, tenant.port, tenant.database, tenant.user, tenant.password)) { execBatch(c, TENANT_SQL); } System.out.println("[OK] tenant " + tenantId); } } } private static void execBatch(Connection conn, String sql) throws SQLException { try (Statement st = conn.createStatement()) { for (String part : sql.split(";")) { String s = part.trim(); if (!s.isEmpty()) st.execute(s); } } } private static List loadActiveTenantIds(Connection master) throws SQLException { List ids = new ArrayList<>(); try (Statement st = master.createStatement(); ResultSet rs = st.executeQuery("SELECT id FROM tenant_info WHERE status = 1 ORDER BY id")) { while (rs.next()) ids.add(rs.getLong(1)); } return ids; } private static TenantDb loadTenant(Connection master, long tenantId) throws SQLException { try (PreparedStatement ps = master.prepareStatement( "SELECT db_url, db_account, db_pwd FROM tenant_info WHERE id = ? AND status = 1 LIMIT 1")) { ps.setLong(1, tenantId); try (ResultSet rs = ps.executeQuery()) { if (!rs.next()) return null; return parseJdbcUrl(rs.getString("db_url"), rs.getString("db_account"), rs.getString("db_pwd")); } } } private static TenantDb parseJdbcUrl(String jdbcUrl, String user, String password) { String body = jdbcUrl.substring("jdbc:mysql://".length()); int slash = body.indexOf('/'); String hostPort = body.substring(0, slash); String rest = body.substring(slash + 1); int q = rest.indexOf('?'); String database = q >= 0 ? rest.substring(0, q) : rest; int colon = hostPort.indexOf(':'); TenantDb t = new TenantDb(); t.host = colon >= 0 ? hostPort.substring(0, colon) : hostPort; t.port = colon >= 0 ? Integer.parseInt(hostPort.substring(colon + 1)) : 3306; t.database = database; t.user = user != null ? user : MASTER_USER; t.password = password != null ? password : MASTER_PASSWORD; return t; } private static Connection open(String host, int port, String database, String user, String password) throws SQLException { return DriverManager.getConnection( "jdbc:mysql://" + host + ":" + port + "/" + database + "?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&allowMultiQueries=true", user, password); } private static String getenv(String key, String defaultValue) { String v = System.getenv(key); return v != null && !v.isEmpty() ? v : defaultValue; } private static final class TenantDb { String host; int port; String database; String user; String password; } }