package de.superx.util.db; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; import de.superx.rest.model.TableInfo; import de.superx.rest.model.TableInfo.ColumnInfo; public class PostgresMetadataHelper { private final Connection connection; public PostgresMetadataHelper(Connection connection) { this.connection = connection; } public List getTablesWithComments(String schema, boolean withColumns) throws SQLException { return getTablesWithComments(schema, "%", withColumns); } public List getTablesWithComments(String schema, String tableFilter, boolean withColumns) throws SQLException { List tables = new ArrayList<>(); // Get tables via DatabaseMetaData DatabaseMetaData meta = connection.getMetaData(); ResultSet tableRs = meta.getTables(null, schema, tableFilter, new String[]{"TABLE"}); while (tableRs.next()) { String tableName = tableRs.getString("TABLE_NAME"); // Get table comment via PostgreSQL catalog String comment = getTableComment(schema, tableName); int rowCount = 0; try (Statement st = connection.createStatement(); ResultSet rs = st.executeQuery(String.format("SELECT COUNT(*) FROM %s.%s", schema, tableName))) { rs.next(); rowCount = rs.getInt(1); } TableInfo info = new TableInfo(tableName, schema, comment, Integer.valueOf(rowCount)); if (withColumns) { // Get columns ResultSet colRs = meta.getColumns(null, schema, tableName, "%"); List columns = new ArrayList<>(); while (colRs.next()) { ColumnInfo col = new ColumnInfo(); col.name = colRs.getString("COLUMN_NAME"); col.typeName = colRs.getString("TYPE_NAME"); col.size = colRs.getInt("COLUMN_SIZE"); col.nullable = colRs.getInt("NULLABLE") == DatabaseMetaData.columnNullable; col.defaultValue = colRs.getString("COLUMN_DEF"); col.comment = getColumnComment(schema, tableName, col.name); columns.add(col); } colRs.close(); info.setColumns(columns); } tables.add(info); } tableRs.close(); return tables; } private String getTableComment(String schema, String table) throws SQLException { String sql = """ SELECT d.description FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace LEFT JOIN pg_description d ON d.objoid = c.oid AND d.objsubid = 0 WHERE c.relname = ? AND n.nspname = ? """; try (PreparedStatement stmt = connection.prepareStatement(sql)) { stmt.setString(1, table); stmt.setString(2, schema); try (ResultSet rs = stmt.executeQuery()) { return rs.next() ? rs.getString(1) : null; } } } private String getColumnComment(String schema, String table, String column) throws SQLException { String sql = """ SELECT d.description FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace JOIN pg_attribute a ON a.attrelid = c.oid LEFT JOIN pg_description d ON d.objoid = a.attrelid AND d.objsubid = a.attnum WHERE c.relname = ? AND n.nspname = ? AND a.attname = ? """; try (PreparedStatement stmt = connection.prepareStatement(sql)) { stmt.setString(1, table); stmt.setString(2, schema); stmt.setString(3, column); try (ResultSet rs = stmt.executeQuery()) { return rs.next() ? rs.getString(1) : null; } } } }