ShowAllTenantMenus.java 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. import java.sql.*;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. /**
  5. * Unhide all menus in tenant DB sys_menu only (visible '1' -> '0').
  6. * Does NOT touch master ylrz_saas or tenant_sys_menu.
  7. */
  8. public class ShowAllTenantMenus {
  9. private static final String MASTER_HOST = getenv("DB_HOST", "cq-cdb-8fjmemkb.sql.tencentcdb.com");
  10. private static final int MASTER_PORT = Integer.parseInt(getenv("DB_PORT", "27220"));
  11. private static final String MASTER_USER = getenv("DB_USER", "root");
  12. private static final String MASTER_PASSWORD = getenv("DB_PASSWORD", "Ylrz_1q2w3e4r5t6y");
  13. private static final String MASTER_DB = getenv("DB_NAME", "ylrz_saas");
  14. public static void main(String[] args) throws Exception {
  15. Class.forName("com.mysql.cj.jdbc.Driver");
  16. boolean dryRun = args.length > 0 && "dry-run".equalsIgnoreCase(args[0]);
  17. Long onlyTenant = null;
  18. for (String arg : args) {
  19. if (arg.startsWith("tenant=")) {
  20. onlyTenant = Long.parseLong(arg.substring("tenant=".length()));
  21. }
  22. }
  23. System.out.println("=== Unhide all menus in tenant sys_menu only === dryRun=" + dryRun);
  24. List<Long> tenantIds;
  25. try (Connection master = open(MASTER_HOST, MASTER_PORT, MASTER_DB, MASTER_USER, MASTER_PASSWORD)) {
  26. tenantIds = loadActiveTenantIds(master);
  27. }
  28. int ok = 0;
  29. for (Long tenantId : tenantIds) {
  30. if (onlyTenant != null && !onlyTenant.equals(tenantId)) {
  31. continue;
  32. }
  33. TenantDb tenant;
  34. try (Connection master = open(MASTER_HOST, MASTER_PORT, MASTER_DB, MASTER_USER, MASTER_PASSWORD)) {
  35. tenant = loadTenant(master, tenantId);
  36. }
  37. if (tenant == null) {
  38. continue;
  39. }
  40. try (Connection conn = open(tenant.host, tenant.port, tenant.database, tenant.user, tenant.password)) {
  41. if (!tableExists(conn, "sys_menu")) {
  42. System.out.println("[TENANT " + tenantId + "] " + tenant.database + " [SKIP] no sys_menu");
  43. continue;
  44. }
  45. int hidden = countHidden(conn);
  46. if (hidden == 0) {
  47. System.out.println("[TENANT " + tenantId + "] " + tenant.database + " already all visible");
  48. ok++;
  49. continue;
  50. }
  51. if (dryRun) {
  52. preview(conn, tenantId, tenant.database, hidden);
  53. } else {
  54. int n = unhide(conn);
  55. System.out.println("[TENANT " + tenantId + "] " + tenant.database + " unhidden=" + n);
  56. }
  57. ok++;
  58. } catch (Exception e) {
  59. System.out.println("[TENANT " + tenantId + "] [ERR] " + e.getMessage());
  60. }
  61. }
  62. System.out.println("\nDone. tenants processed=" + ok);
  63. }
  64. private static int unhide(Connection conn) throws SQLException {
  65. String sql = "UPDATE sys_menu SET visible = '0', update_time = NOW() "
  66. + "WHERE visible = '1' AND status = '0'";
  67. try (Statement st = conn.createStatement()) {
  68. return st.executeUpdate(sql);
  69. }
  70. }
  71. private static int countHidden(Connection conn) throws SQLException {
  72. try (Statement st = conn.createStatement();
  73. ResultSet rs = st.executeQuery(
  74. "SELECT COUNT(*) FROM sys_menu WHERE visible = '1' AND status = '0'")) {
  75. rs.next();
  76. return rs.getInt(1);
  77. }
  78. }
  79. private static void preview(Connection conn, long tenantId, String db, int total) throws SQLException {
  80. System.out.println("\n[TENANT " + tenantId + "] " + db + " will unhide " + total + " menus:");
  81. try (Statement st = conn.createStatement();
  82. ResultSet rs = st.executeQuery(
  83. "SELECT menu_id, parent_id, menu_name, path FROM sys_menu "
  84. + "WHERE visible = '1' AND status = '0' ORDER BY parent_id, menu_id")) {
  85. while (rs.next()) {
  86. System.out.printf(" id=%d parent=%d path=%s name=%s%n",
  87. rs.getLong(1), rs.getLong(2), rs.getString(4), rs.getString(3));
  88. }
  89. }
  90. }
  91. private static boolean tableExists(Connection conn, String table) throws SQLException {
  92. try (ResultSet rs = conn.getMetaData().getTables(null, null, table, null)) {
  93. return rs.next();
  94. }
  95. }
  96. private static List<Long> loadActiveTenantIds(Connection master) throws SQLException {
  97. List<Long> ids = new ArrayList<>();
  98. try (Statement st = master.createStatement();
  99. ResultSet rs = st.executeQuery("SELECT id FROM tenant_info WHERE status = 1 ORDER BY id")) {
  100. while (rs.next()) {
  101. ids.add(rs.getLong(1));
  102. }
  103. }
  104. return ids;
  105. }
  106. private static TenantDb loadTenant(Connection master, long tenantId) throws SQLException {
  107. try (PreparedStatement ps = master.prepareStatement(
  108. "SELECT db_url, db_account, db_pwd FROM tenant_info WHERE id = ? AND status = 1 LIMIT 1")) {
  109. ps.setLong(1, tenantId);
  110. try (ResultSet rs = ps.executeQuery()) {
  111. if (!rs.next()) {
  112. return null;
  113. }
  114. return parseJdbcUrl(rs.getString("db_url"), rs.getString("db_account"), rs.getString("db_pwd"));
  115. }
  116. }
  117. }
  118. private static TenantDb parseJdbcUrl(String jdbcUrl, String user, String password) {
  119. String body = jdbcUrl.substring("jdbc:mysql://".length());
  120. int slash = body.indexOf('/');
  121. String hostPort = body.substring(0, slash);
  122. String rest = body.substring(slash + 1);
  123. int q = rest.indexOf('?');
  124. String database = q >= 0 ? rest.substring(0, q) : rest;
  125. int colon = hostPort.indexOf(':');
  126. TenantDb t = new TenantDb();
  127. t.host = colon >= 0 ? hostPort.substring(0, colon) : hostPort;
  128. t.port = colon >= 0 ? Integer.parseInt(hostPort.substring(colon + 1)) : 3306;
  129. t.database = database;
  130. t.user = user != null ? user : MASTER_USER;
  131. t.password = password != null ? password : MASTER_PASSWORD;
  132. return t;
  133. }
  134. private static Connection open(String host, int port, String database, String user, String password)
  135. throws SQLException {
  136. return DriverManager.getConnection(
  137. "jdbc:mysql://" + host + ":" + port + "/" + database
  138. + "?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&allowMultiQueries=true",
  139. user, password);
  140. }
  141. private static String getenv(String key, String defaultValue) {
  142. String v = System.getenv(key);
  143. return v != null && !v.isEmpty() ? v : defaultValue;
  144. }
  145. private static final class TenantDb {
  146. String host;
  147. int port;
  148. String database;
  149. String user;
  150. String password;
  151. }
  152. }