DeleteLobsterNodeDetailMenu29926.java 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. import java.io.*;
  2. import java.sql.*;
  3. import java.util.*;
  4. /**
  5. * Delete hidden lobster menu 29926 (node-detail) from master + all tenant DBs.
  6. */
  7. public class DeleteLobsterNodeDetailMenu29926 {
  8. private static final long MENU_ID = 29926L;
  9. private static final String HOST = getenv("DB_HOST", "cq-cdb-8fjmemkb.sql.tencentcdb.com");
  10. private static final int PORT = Integer.parseInt(getenv("DB_PORT", "27220"));
  11. private static final String USER = getenv("DB_USER", "root");
  12. private static final String PASS = getenv("DB_PASSWORD", "Ylrz_1q2w3e4r5t6y");
  13. private static final String MASTER_DB = getenv("DB_NAME", "ylrz_saas");
  14. private static final String[] MENU_TABLES = {"sys_menu", "tenant_sys_menu", "tenant_company_menu", "company_menu"};
  15. private static final String[][] ROLE_TABLES = {
  16. {"sys_role_menu", "sys_menu"},
  17. {"company_role_menu", "company_menu"}
  18. };
  19. public static void main(String[] args) throws Exception {
  20. Class.forName("com.mysql.cj.jdbc.Driver");
  21. new File("output").mkdirs();
  22. try (PrintWriter report = new PrintWriter(new OutputStreamWriter(
  23. new FileOutputStream("output/delete-menu-29926-report.txt"), "UTF-8"));
  24. Connection master = open(MASTER_DB)) {
  25. deleteOnConn(master, report, MASTER_DB);
  26. for (TenantDb tenant : loadTenants(master)) {
  27. try (Connection c = openDb(tenant)) {
  28. deleteOnConn(c, report, tenant.database);
  29. } catch (Exception e) {
  30. report.println("[ERROR] " + tenant.database + ": " + e.getMessage());
  31. }
  32. }
  33. report.println("\nDone.");
  34. System.out.println("Wrote output/delete-menu-29926-report.txt");
  35. }
  36. }
  37. private static void deleteOnConn(Connection conn, PrintWriter report, String label) throws SQLException {
  38. if (!menuExists(conn)) {
  39. report.println(label + ": menu 29926 not found, skip");
  40. return;
  41. }
  42. for (String[] pair : ROLE_TABLES) {
  43. if (!tableExists(conn, pair[0])) {
  44. continue;
  45. }
  46. try (PreparedStatement ps = conn.prepareStatement(
  47. "DELETE FROM " + pair[0] + " WHERE menu_id = ?")) {
  48. ps.setLong(1, MENU_ID);
  49. int n = ps.executeUpdate();
  50. if (n > 0) {
  51. report.println(label + "." + pair[0] + " deleted role refs=" + n);
  52. }
  53. }
  54. }
  55. for (String table : MENU_TABLES) {
  56. if (!tableExists(conn, table)) {
  57. continue;
  58. }
  59. try (PreparedStatement ps = conn.prepareStatement("DELETE FROM " + table + " WHERE menu_id = ?")) {
  60. ps.setLong(1, MENU_ID);
  61. int n = ps.executeUpdate();
  62. if (n > 0) {
  63. report.println(label + "." + table + " deleted rows=" + n);
  64. }
  65. }
  66. }
  67. }
  68. private static boolean menuExists(Connection conn) throws SQLException {
  69. for (String table : MENU_TABLES) {
  70. if (!tableExists(conn, table)) {
  71. continue;
  72. }
  73. try (PreparedStatement ps = conn.prepareStatement("SELECT 1 FROM " + table + " WHERE menu_id = ? LIMIT 1")) {
  74. ps.setLong(1, MENU_ID);
  75. try (ResultSet rs = ps.executeQuery()) {
  76. if (rs.next()) {
  77. return true;
  78. }
  79. }
  80. }
  81. }
  82. return false;
  83. }
  84. private static List<TenantDb> loadTenants(Connection master) throws SQLException {
  85. List<TenantDb> list = new ArrayList<>();
  86. try (Statement st = master.createStatement();
  87. ResultSet rs = st.executeQuery("SELECT id, db_url, db_account, db_pwd FROM tenant_info WHERE status = 1 ORDER BY id")) {
  88. while (rs.next()) {
  89. TenantDb t = parseJdbcUrl(rs.getString("db_url"), rs.getString("db_account"), rs.getString("db_pwd"));
  90. if (t != null) {
  91. list.add(t);
  92. }
  93. }
  94. }
  95. return list;
  96. }
  97. private static TenantDb parseJdbcUrl(String jdbcUrl, String user, String password) {
  98. if (jdbcUrl == null || !jdbcUrl.startsWith("jdbc:mysql://")) {
  99. return null;
  100. }
  101. String body = jdbcUrl.substring("jdbc:mysql://".length());
  102. int slash = body.indexOf('/');
  103. if (slash < 0) {
  104. return null;
  105. }
  106. String hostPort = body.substring(0, slash);
  107. String rest = body.substring(slash + 1);
  108. int q = rest.indexOf('?');
  109. String database = q >= 0 ? rest.substring(0, q) : rest;
  110. TenantDb t = new TenantDb();
  111. int colon = hostPort.indexOf(':');
  112. if (colon >= 0) {
  113. t.host = hostPort.substring(0, colon);
  114. t.port = Integer.parseInt(hostPort.substring(colon + 1));
  115. } else {
  116. t.host = hostPort;
  117. t.port = 3306;
  118. }
  119. t.database = database;
  120. t.user = user != null ? user : USER;
  121. t.password = password != null ? password : PASS;
  122. return t;
  123. }
  124. private static boolean tableExists(Connection conn, String table) throws SQLException {
  125. try (PreparedStatement ps = conn.prepareStatement(
  126. "SELECT 1 FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = ? LIMIT 1")) {
  127. ps.setString(1, table);
  128. try (ResultSet rs = ps.executeQuery()) {
  129. return rs.next();
  130. }
  131. }
  132. }
  133. private static Connection open(String database) throws SQLException {
  134. return DriverManager.getConnection(buildUrl(HOST, PORT, database), USER, PASS);
  135. }
  136. private static Connection openDb(TenantDb tenant) throws SQLException {
  137. return DriverManager.getConnection(buildUrl(tenant.host, tenant.port, tenant.database), tenant.user, tenant.password);
  138. }
  139. private static String buildUrl(String host, int port, String database) {
  140. return "jdbc:mysql://" + host + ":" + port + "/" + database
  141. + "?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&allowMultiQueries=true";
  142. }
  143. private static String getenv(String key, String defaultValue) {
  144. String v = System.getenv(key);
  145. return v != null && !v.isEmpty() ? v : defaultValue;
  146. }
  147. private static class TenantDb {
  148. String host;
  149. int port;
  150. String database;
  151. String user;
  152. String password;
  153. }
  154. }