ApplyVisibleCompanyIdsMigration.java 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. import java.sql.Connection;
  2. import java.sql.DriverManager;
  3. import java.sql.PreparedStatement;
  4. import java.sql.ResultSet;
  5. import java.sql.SQLException;
  6. import java.sql.Statement;
  7. import java.util.ArrayList;
  8. import java.util.List;
  9. public class ApplyVisibleCompanyIdsMigration {
  10. private static final String DEFAULT_HOST = "cq-cdb-8fjmemkb.sql.tencentcdb.com";
  11. private static final int DEFAULT_PORT = 27220;
  12. private static final String DEFAULT_USER = "root";
  13. private static final String DEFAULT_PASSWORD = "Ylrz_1q2w3e4r5t6y";
  14. private static final String MASTER_DB = "ylrz_saas";
  15. private static final String CHECK_SQL =
  16. "SELECT COUNT(*) FROM information_schema.COLUMNS "
  17. + "WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'company_workflow_lobster' "
  18. + "AND COLUMN_NAME = 'visible_company_ids'";
  19. private static final String ALTER_SQL =
  20. "ALTER TABLE company_workflow_lobster "
  21. + "ADD COLUMN visible_company_ids VARCHAR(500) DEFAULT NULL AFTER company_id";
  22. public static void main(String[] args) throws Exception {
  23. Class.forName("com.mysql.cj.jdbc.Driver");
  24. List<TenantDb> tenants = new ArrayList<>();
  25. try (Connection master = connect(DEFAULT_HOST, DEFAULT_PORT, MASTER_DB, DEFAULT_USER, DEFAULT_PASSWORD)) {
  26. try (Statement st = master.createStatement();
  27. ResultSet rs = st.executeQuery(
  28. "SELECT id, db_name, db_url, db_account, db_pwd, status FROM tenant_info ORDER BY id")) {
  29. while (rs.next()) {
  30. TenantDb t = new TenantDb();
  31. t.id = rs.getLong("id");
  32. t.status = rs.getInt("status");
  33. t.dbName = rs.getString("db_name");
  34. t.dbUrl = rs.getString("db_url");
  35. t.user = rs.getString("db_account");
  36. t.password = rs.getString("db_pwd");
  37. parseJdbc(t);
  38. tenants.add(t);
  39. }
  40. }
  41. }
  42. System.out.println("Tenants loaded: " + tenants.size());
  43. applyMaster();
  44. int ok = 0;
  45. int skip = 0;
  46. int fail = 0;
  47. for (TenantDb tenant : tenants) {
  48. if (tenant.status != 1) {
  49. continue;
  50. }
  51. try {
  52. if (apply(tenant)) {
  53. ok++;
  54. } else {
  55. skip++;
  56. }
  57. } catch (Exception e) {
  58. fail++;
  59. System.err.println("[FAIL] tenantId=" + tenant.id + " db=" + tenant.database + " - " + e.getMessage());
  60. }
  61. }
  62. System.out.println("Done. added=" + ok + " skip=" + skip + " fail=" + fail);
  63. if (fail > 0) {
  64. System.exit(1);
  65. }
  66. }
  67. private static void applyMaster() throws Exception {
  68. try (Connection conn = connect(DEFAULT_HOST, DEFAULT_PORT, MASTER_DB, DEFAULT_USER, DEFAULT_PASSWORD);
  69. Statement st = conn.createStatement()) {
  70. boolean exists;
  71. try (ResultSet rs = st.executeQuery(CHECK_SQL)) {
  72. rs.next();
  73. exists = rs.getInt(1) > 0;
  74. }
  75. if (exists) {
  76. System.out.println("[SKIP] master db=" + MASTER_DB);
  77. return;
  78. }
  79. st.execute(ALTER_SQL);
  80. System.out.println("[OK] master db=" + MASTER_DB);
  81. }
  82. }
  83. private static boolean apply(TenantDb tenant) throws Exception {
  84. try (Connection conn = connect(tenant.host, tenant.port, tenant.database, tenant.user, tenant.password);
  85. Statement st = conn.createStatement()) {
  86. boolean exists;
  87. try (ResultSet rs = st.executeQuery(CHECK_SQL)) {
  88. rs.next();
  89. exists = rs.getInt(1) > 0;
  90. }
  91. if (exists) {
  92. System.out.println("[SKIP] tenantId=" + tenant.id + " db=" + tenant.database);
  93. return false;
  94. }
  95. st.execute(ALTER_SQL);
  96. System.out.println("[OK] tenantId=" + tenant.id + " db=" + tenant.database);
  97. return true;
  98. }
  99. }
  100. private static void parseJdbc(TenantDb t) {
  101. if (t.dbUrl != null && t.dbUrl.startsWith("jdbc:mysql://")) {
  102. String body = t.dbUrl.substring("jdbc:mysql://".length());
  103. int slash = body.indexOf('/');
  104. String hostPort = slash >= 0 ? body.substring(0, slash) : body;
  105. String rest = slash >= 0 ? body.substring(slash + 1) : t.dbName;
  106. int q = rest.indexOf('?');
  107. t.database = q >= 0 ? rest.substring(0, q) : rest;
  108. int colon = hostPort.indexOf(':');
  109. if (colon >= 0) {
  110. t.host = hostPort.substring(0, colon);
  111. t.port = Integer.parseInt(hostPort.substring(colon + 1));
  112. } else {
  113. t.host = hostPort;
  114. t.port = DEFAULT_PORT;
  115. }
  116. } else {
  117. t.host = DEFAULT_HOST;
  118. t.port = DEFAULT_PORT;
  119. t.database = t.dbName;
  120. }
  121. if (t.user == null || t.user.isEmpty()) {
  122. t.user = DEFAULT_USER;
  123. }
  124. if (t.password == null || t.password.isEmpty()) {
  125. t.password = DEFAULT_PASSWORD;
  126. }
  127. }
  128. private static Connection connect(String host, int port, String database, String user, String password)
  129. throws SQLException {
  130. String url = String.format(
  131. "jdbc:mysql://%s:%d/%s?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT%%2B8&allowMultiQueries=true",
  132. host, port, database);
  133. return DriverManager.getConnection(url, user, password);
  134. }
  135. private static final class TenantDb {
  136. long id;
  137. int status;
  138. String dbName;
  139. String dbUrl;
  140. String user;
  141. String password;
  142. String host;
  143. int port;
  144. String database;
  145. }
  146. }