From 749c91bca68998b6838452908ec5adfb8215fbc8 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Tue, 19 Nov 2019 11:24:15 +0100 Subject: [PATCH] [jOOQ/jOOQ#9565] Import and export InformationSchema <-> Meta --- .../jooq/impl/InformationSchemaExport.java | 92 ++++++++++++------- .../jooq/impl/InformationSchemaMetaImpl.java | 51 ++++++++-- .../org/jooq/util/jaxb/tools/XMLBuilder.java | 69 +++++++++----- 3 files changed, 149 insertions(+), 63 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/InformationSchemaExport.java b/jOOQ/src/main/java/org/jooq/impl/InformationSchemaExport.java index 4006381653..ad9b698516 100644 --- a/jOOQ/src/main/java/org/jooq/impl/InformationSchemaExport.java +++ b/jOOQ/src/main/java/org/jooq/impl/InformationSchemaExport.java @@ -38,6 +38,7 @@ package org.jooq.impl; +import static org.jooq.util.xml.jaxb.TableConstraintType.CHECK; import static org.jooq.util.xml.jaxb.TableConstraintType.FOREIGN_KEY; import static org.jooq.util.xml.jaxb.TableConstraintType.PRIMARY_KEY; import static org.jooq.util.xml.jaxb.TableConstraintType.UNIQUE; @@ -47,6 +48,7 @@ import java.util.List; import java.util.Set; import org.jooq.Catalog; +import org.jooq.Check; import org.jooq.Configuration; import org.jooq.Field; import org.jooq.ForeignKey; @@ -59,6 +61,7 @@ import org.jooq.SortOrder; import org.jooq.Table; import org.jooq.UniqueKey; import org.jooq.tools.StringUtils; +import org.jooq.util.xml.jaxb.CheckConstraint; import org.jooq.util.xml.jaxb.Column; import org.jooq.util.xml.jaxb.IndexColumnUsage; import org.jooq.util.xml.jaxb.InformationSchema; @@ -252,25 +255,45 @@ final class InformationSchemaExport { if (includedTables.contains(fk.getKey().getTable())) exportKey0(result, t, fk, FOREIGN_KEY); + for (Check chk : t.getChecks()) + if (includedTables.contains(chk.getTable())) + exportCheck0(configuration, result, t, chk); + for (Index index : t.getIndexes()) exportIndex0(result, t, index); } + private static final void exportCheck0(Configuration configuration, InformationSchema result, Table t, Check chk) { + exportTableConstraint(result, t, chk.getName(), CHECK); + + CheckConstraint c = new CheckConstraint(); + + String catalogName = t.getCatalog().getName(); + String schemaName = t.getSchema().getName(); + + if (!StringUtils.isBlank(catalogName)) + c.setConstraintCatalog(catalogName); + + if (!StringUtils.isBlank(schemaName)) + c.setConstraintSchema(schemaName); + + c.setConstraintName(chk.getName()); + c.setCheckClause(configuration.dsl().render(chk.condition())); + } + private static final void exportIndex0(InformationSchema result, Table t, Index index) { org.jooq.util.xml.jaxb.Index i = new org.jooq.util.xml.jaxb.Index(); String catalogName = t.getCatalog().getName(); String schemaName = t.getSchema().getName(); - if (!StringUtils.isBlank(catalogName)) { - i.setIndexCatalog(catalogName); - i.setTableCatalog(catalogName); - } + if (!StringUtils.isBlank(catalogName)) + i.withIndexCatalog(catalogName) + .withTableCatalog(catalogName); - if (!StringUtils.isBlank(schemaName)) { - i.setIndexSchema(schemaName); - i.setTableSchema(schemaName); - } + if (!StringUtils.isBlank(schemaName)) + i.withIndexSchema(schemaName) + .withTableSchema(schemaName); i.setIndexName(index.getName()); i.setTableName(t.getName()); @@ -281,15 +304,13 @@ final class InformationSchemaExport { for (SortField sortField : index.getFields()) { IndexColumnUsage ic = new IndexColumnUsage(); - if (!StringUtils.isBlank(catalogName)) { - ic.setIndexCatalog(catalogName); - ic.setTableCatalog(catalogName); - } + if (!StringUtils.isBlank(catalogName)) + ic.withIndexCatalog(catalogName) + .withTableCatalog(catalogName); - if (!StringUtils.isBlank(schemaName)) { - ic.setIndexSchema(schemaName); - ic.setTableSchema(schemaName); - } + if (!StringUtils.isBlank(schemaName)) + ic.withIndexSchema(schemaName) + .withTableSchema(schemaName); ic.setIndexName(index.getName()); ic.setTableName(t.getName()); @@ -303,27 +324,11 @@ final class InformationSchemaExport { } private static final void exportKey0(InformationSchema result, Table t, Key key, TableConstraintType constraintType) { - TableConstraint tc = new TableConstraint(); + exportTableConstraint(result, t, key.getName(), constraintType); String catalogName = t.getCatalog().getName(); String schemaName = t.getSchema().getName(); - tc.setConstraintName(key.getName()); - tc.setConstraintType(constraintType); - - if (!StringUtils.isBlank(catalogName)) { - tc.setConstraintCatalog(catalogName); - tc.setTableCatalog(catalogName); - } - - if (!StringUtils.isBlank(schemaName)) { - tc.setConstraintSchema(schemaName); - tc.setTableSchema(schemaName); - } - - tc.setTableName(t.getName()); - result.getTableConstraints().add(tc); - int i = 0; for (Field f : key.getFields()) { KeyColumnUsage kc = new KeyColumnUsage(); @@ -371,5 +376,26 @@ final class InformationSchemaExport { } } + private static final void exportTableConstraint(InformationSchema result, Table t, String constraintName, TableConstraintType constraintType) { + TableConstraint tc = new TableConstraint(); + + String catalogName = t.getCatalog().getName(); + String schemaName = t.getSchema().getName(); + + tc.setConstraintName(constraintName); + tc.setConstraintType(constraintType); + + if (!StringUtils.isBlank(catalogName)) + tc.withConstraintCatalog(catalogName) + .withTableCatalog(catalogName); + + if (!StringUtils.isBlank(schemaName)) + tc.withConstraintSchema(schemaName) + .withTableSchema(schemaName); + + tc.setTableName(t.getName()); + result.getTableConstraints().add(tc); + } + private InformationSchemaExport() {} } diff --git a/jOOQ/src/main/java/org/jooq/impl/InformationSchemaMetaImpl.java b/jOOQ/src/main/java/org/jooq/impl/InformationSchemaMetaImpl.java index c8d34a4357..0216cfcb4a 100644 --- a/jOOQ/src/main/java/org/jooq/impl/InformationSchemaMetaImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/InformationSchemaMetaImpl.java @@ -37,7 +37,6 @@ */ package org.jooq.impl; -import static java.util.Collections.unmodifiableList; import static org.jooq.impl.DSL.name; import static org.jooq.impl.Tools.EMPTY_SORTFIELD; import static org.jooq.util.xml.jaxb.TableConstraintType.PRIMARY_KEY; @@ -50,6 +49,7 @@ import java.util.List; import java.util.Map; import org.jooq.Catalog; +import org.jooq.Check; import org.jooq.Configuration; import org.jooq.DataType; import org.jooq.ForeignKey; @@ -63,6 +63,7 @@ import org.jooq.Table; import org.jooq.TableField; import org.jooq.UniqueKey; import org.jooq.exception.SQLDialectNotSupportedException; +import org.jooq.util.xml.jaxb.CheckConstraint; import org.jooq.util.xml.jaxb.Column; import org.jooq.util.xml.jaxb.IndexColumnUsage; import org.jooq.util.xml.jaxb.InformationSchema; @@ -404,6 +405,32 @@ final class InformationSchemaMetaImpl extends AbstractMeta { } } + tableConstraintLoop: + for (TableConstraint xc : meta.getTableConstraints()) { + switch (xc.getConstraintType()) { + case CHECK: { + Name tableName = name(xc.getTableCatalog(), xc.getTableSchema(), xc.getTableName()); + Name constraintName = name(xc.getConstraintCatalog(), xc.getConstraintSchema(), xc.getConstraintName()); + InformationSchemaTable table = tablesByName.get(tableName); + + if (table == null) { + errors.add(String.format("Table " + tableName + " not defined for constraint " + constraintName)); + continue tableConstraintLoop; + } + + for (CheckConstraint cc : meta.getCheckConstraints()) { + if (constraintName.equals(name(cc.getConstraintCatalog(), cc.getConstraintSchema(), cc.getConstraintName()))) { + table.checks.add(new CheckImpl<>(table, constraintName, DSL.condition(cc.getCheckClause()))); + continue tableConstraintLoop; + } + } + + errors.add(String.format("No check clause found for check constraint " + constraintName)); + continue tableConstraintLoop; + } + } + } + // Sequences // ------------------------------------------------------------------------------------------------------------- sequenceLoop: @@ -533,7 +560,7 @@ final class InformationSchemaMetaImpl extends AbstractMeta { @Override public final List getSchemas() { - return unmodifiableList(schemasPerCatalog.get(this)); + return InformationSchemaMetaImpl.unmodifiableList(schemasPerCatalog.get(this)); } } @@ -550,12 +577,12 @@ final class InformationSchemaMetaImpl extends AbstractMeta { @Override public final List> getTables() { - return Collections.>unmodifiableList(tablesPerSchema.get(this)); + return InformationSchemaMetaImpl.>unmodifiableList(tablesPerSchema.get(this)); } @Override public final List> getSequences() { - return Collections.>unmodifiableList(sequencesPerSchema.get(this)); + return InformationSchemaMetaImpl.>unmodifiableList(sequencesPerSchema.get(this)); } } @@ -569,6 +596,7 @@ final class InformationSchemaMetaImpl extends AbstractMeta { UniqueKey primaryKey; final List> uniqueKeys = new ArrayList<>(); final List> foreignKeys = new ArrayList<>(); + final List> checks = new ArrayList<>(); final List indexes = new ArrayList<>(); public InformationSchemaTable(String name, Schema schema, String comment) { @@ -577,7 +605,7 @@ final class InformationSchemaMetaImpl extends AbstractMeta { @Override public List getIndexes() { - return Collections.unmodifiableList(indexes); + return InformationSchemaMetaImpl.unmodifiableList(indexes); } @Override @@ -587,12 +615,17 @@ final class InformationSchemaMetaImpl extends AbstractMeta { @Override public List> getKeys() { - return Collections.>unmodifiableList(uniqueKeys); + return InformationSchemaMetaImpl.>unmodifiableList(uniqueKeys); } @Override public List> getReferences() { - return Collections.>unmodifiableList(foreignKeys); + return InformationSchemaMetaImpl.>unmodifiableList(foreignKeys); + } + + @Override + public List> getChecks() { + return InformationSchemaMetaImpl.unmodifiableList(checks); } } @@ -608,6 +641,10 @@ final class InformationSchemaMetaImpl extends AbstractMeta { } } + private static final List unmodifiableList(List list) { + return list == null ? Collections.emptyList() : Collections.unmodifiableList(list); + } + @Override public String toString() { return "" + source; diff --git a/jOOQ/src/main/java/org/jooq/util/jaxb/tools/XMLBuilder.java b/jOOQ/src/main/java/org/jooq/util/jaxb/tools/XMLBuilder.java index e5deb6b65a..48456af430 100644 --- a/jOOQ/src/main/java/org/jooq/util/jaxb/tools/XMLBuilder.java +++ b/jOOQ/src/main/java/org/jooq/util/jaxb/tools/XMLBuilder.java @@ -58,21 +58,26 @@ import org.jooq.Internal; public final class XMLBuilder { private final StringBuilder builder = new StringBuilder(); + private final boolean format; + private final boolean nullIsEmpty; + private int indentLevel; + private boolean onNewLine; - private final boolean format; - private int indentLevel; - private boolean onNewLine; - - private XMLBuilder(boolean format) { + private XMLBuilder(boolean format, boolean nullIsEmpty) { this.format = format; + this.nullIsEmpty = nullIsEmpty; } public static XMLBuilder formatting() { - return new XMLBuilder(true); + return new XMLBuilder(true, false); } public static XMLBuilder nonFormatting() { - return new XMLBuilder(false); + return new XMLBuilder(false, false); + } + + public static XMLBuilder nullIsEmpty() { + return new XMLBuilder(false, true); } public XMLBuilder append(XMLAppendable appendable) { @@ -82,25 +87,32 @@ public final class XMLBuilder { } public XMLBuilder append(String elementName, XMLAppendable appendable) { - if (appendable != null) { + if (appendable != null || nullIsEmpty) { openTag(elementName).newLine().indent(); - appendable.appendTo(this); + + if (appendable != null) + appendable.appendTo(this); + unindent().closeTag(elementName).newLine(); } + return this; } public XMLBuilder append(String wrappingElementName, String elementName, List list) { - if (list != null) { + if (list != null || nullIsEmpty) { openTag(wrappingElementName).newLine().indent(); - for (Object o : list) { - if (o instanceof XMLAppendable) - append(elementName, (XMLAppendable) o); - else - append(elementName, o); - } + + if (list != null) + for (Object o : list) + if (o instanceof XMLAppendable) + append(elementName, (XMLAppendable) o); + else + append(elementName, o); + unindent().closeTag(wrappingElementName).newLine(); } + return this; } @@ -154,29 +166,41 @@ public final class XMLBuilder { } public XMLBuilder append(String elementName, String s) { - if (s != null) { + if (s != null || nullIsEmpty) { openTag(elementName); - builder.append(s); + + if (s != null) + builder.append(s); + closeTag(elementName).newLine(); } + return this; } public XMLBuilder append(String elementName, Pattern p) { - if (p != null) { + if (p != null || nullIsEmpty) { openTag(elementName); - builder.append(p.pattern()); + + if (p != null) + builder.append(p.pattern()); + closeTag(elementName).newLine(); } + return this; } public XMLBuilder append(String elementName, Object o) { - if (o != null) { + if (o != null || nullIsEmpty) { openTag(elementName); - builder.append(o); + + if (o != null) + builder.append(o); + closeTag(elementName).newLine(); } + return this; } @@ -188,5 +212,4 @@ public final class XMLBuilder { public void appendTo(Appendable a) throws IOException { a.append(builder); } - }