Companion code for the Flyway vs Liquibase article: checksum validation, out-of-order and repeatable migrations, baselining an existing schema, Flyway Community's undo/diff/deploy stubs, concurrent-startup locking for both tools, Liquibase changeset identity and rollback (auto-generated vs explicit), a verified Liquibase 5.0.3 filename-caching defect, the new OSS license service, the FSL license change, and running both tools against one database. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Q6XdRjtsp4862EM44T7i9a
73 lines
2.6 KiB
Java
73 lines
2.6 KiB
Java
package com.ankurm.dbmigrations;
|
|
|
|
import java.sql.Connection;
|
|
import java.sql.ResultSet;
|
|
import java.sql.ResultSetMetaData;
|
|
import java.sql.SQLException;
|
|
import java.sql.Statement;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
/** Renders a JDBC query as a plain-text table for transcripts — no ORM, no formatting library. */
|
|
public final class DbDump {
|
|
|
|
private DbDump() {
|
|
}
|
|
|
|
public static String table(Connection conn, String sql) {
|
|
try (Statement st = conn.createStatement(); ResultSet rs = st.executeQuery(sql)) {
|
|
ResultSetMetaData meta = rs.getMetaData();
|
|
int cols = meta.getColumnCount();
|
|
List<String> headers = new ArrayList<>();
|
|
for (int i = 1; i <= cols; i++) {
|
|
headers.add(meta.getColumnLabel(i));
|
|
}
|
|
List<List<String>> rows = new ArrayList<>();
|
|
while (rs.next()) {
|
|
List<String> row = new ArrayList<>();
|
|
for (int i = 1; i <= cols; i++) {
|
|
Object v = rs.getObject(i);
|
|
row.add(v == null ? "NULL" : v.toString());
|
|
}
|
|
rows.add(row);
|
|
}
|
|
int[] widths = new int[cols];
|
|
for (int i = 0; i < cols; i++) {
|
|
widths[i] = headers.get(i).length();
|
|
}
|
|
for (List<String> row : rows) {
|
|
for (int i = 0; i < cols; i++) {
|
|
widths[i] = Math.max(widths[i], row.get(i).length());
|
|
}
|
|
}
|
|
StringBuilder sb = new StringBuilder();
|
|
appendRow(sb, headers, widths);
|
|
StringBuilder sep = new StringBuilder();
|
|
for (int i = 0; i < cols; i++) {
|
|
sep.append("-".repeat(widths[i])).append(i < cols - 1 ? "-+-" : "");
|
|
}
|
|
sb.append(sep).append(System.lineSeparator());
|
|
for (List<String> row : rows) {
|
|
appendRow(sb, row, widths);
|
|
}
|
|
sb.append("(").append(rows.size()).append(" row").append(rows.size() == 1 ? "" : "s").append(")");
|
|
return sb.toString();
|
|
}
|
|
catch (SQLException ex) {
|
|
return "query failed: " + ex.getMessage();
|
|
}
|
|
}
|
|
|
|
private static void appendRow(StringBuilder sb, List<String> values, int[] widths) {
|
|
for (int i = 0; i < values.size(); i++) {
|
|
sb.append(pad(values.get(i), widths[i]));
|
|
sb.append(i < values.size() - 1 ? " | " : "");
|
|
}
|
|
sb.append(System.lineSeparator());
|
|
}
|
|
|
|
private static String pad(String s, int width) {
|
|
return s + " ".repeat(Math.max(0, width - s.length()));
|
|
}
|
|
}
|