[jOOQ/jOOQ#12083] Work around missing support for REMARKS on DatabaseMetaData.getColumns()

This commit is contained in:
Lukas Eder 2023-09-05 09:49:08 +02:00
parent c5b498817b
commit 7205d2c9ea
2 changed files with 38 additions and 4 deletions

View File

@ -42,6 +42,8 @@ import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE;
import static java.util.Arrays.asList;
import static org.jooq.impl.DSL.name;
import static org.jooq.tools.StringUtils.defaultIfNull;
import static org.jooq.tools.StringUtils.isEmpty;
import java.sql.Connection;
import java.util.ArrayList;
@ -162,7 +164,7 @@ public abstract class AbstractDefinition implements Definition {
@Override
public final String getComment() {
String c = getComment0();
return c != null ? c : getDatabase().getComments().get(this);
return !isEmpty(c) ? c : defaultIfNull(getDatabase().getComments().get(this), "");
}
private final String getComment0() {

View File

@ -68,6 +68,7 @@ import static org.jooq.impl.DSL.comment;
import static org.jooq.impl.DSL.condition;
import static org.jooq.impl.DSL.field;
import static org.jooq.impl.DSL.name;
import static org.jooq.impl.MetaSQL.M_COMMENTS;
import static org.jooq.impl.MetaSQL.M_SEQUENCES;
import static org.jooq.impl.MetaSQL.M_SEQUENCES_INCLUDING_SYSTEM_SEQUENCES;
import static org.jooq.impl.MetaSQL.M_SOURCES;
@ -384,6 +385,7 @@ final class MetaImpl extends AbstractMeta {
private transient volatile Map<Name, Result<Record>> ukCache;
private transient volatile Map<Name, Result<Record>> sequenceCache;
private transient volatile Map<Name, String> sourceCache;
private transient volatile Map<Name, String> commentCache;
MetaSchema(String name, Catalog catalog) {
super(name, catalog);
@ -718,6 +720,34 @@ final class MetaImpl extends AbstractMeta {
return null;
}
final String comment(String tableName, String columnName) {
if (commentCache == null) {
String sql = M_COMMENTS(family());
if (sql != null) {
Result<Record> result = meta(meta ->
withCatalog(getCatalog(), DSL.using(meta.getConnection(), family()), ctx ->
ctx.resultQuery(sql, MetaSchema.this.getName()).fetch()
)
);
// TODO Support catalogs as well
Map<Record, Result<Record>> groups = result.intoGroups(new Field[] { result.field(0), result.field(1), result.field(2), result.field(3) });
commentCache = new LinkedHashMap<>();
groups.forEach((k, v) -> commentCache.put(
name(k.get(1, String.class), k.get(2, String.class), k.get(3, String.class)),
v.get(0).get(4, String.class)
));
}
}
if (commentCache != null)
return commentCache.get(name(MetaSchema.this.getName(), tableName, columnName));
else
return null;
}
private final String patchSchema(String sql) {
@ -790,17 +820,19 @@ final class MetaImpl extends AbstractMeta {
}
private final class MetaTable extends TableImpl<Record> {
private final MetaSchema schema;
private final Result<Record> uks;
MetaTable(String name, MetaSchema schema, Result<Record> columns, Result<Record> uks, String remarks, TableType tableType) {
super(name(name), schema, null, (ForeignKey<?, Record>) null, null, null, comment(remarks), tableOption(dsl(), schema, name, tableType));
this.schema = schema;
this.uks = uks;
// Possible scenarios for columns being null:
// - The "table" is in fact a SYNONYM
if (columns != null)
initColumns(columns);
this.uks = uks;
}
@Override
@ -1242,7 +1274,7 @@ final class MetaImpl extends AbstractMeta {
}
}
createField(name(columnName), type, this, remarks);
createField(name(columnName), type, this, remarks != null ? remarks : schema.comment(getName(), columnName));
}
}
}