[jOOQ/jOOQ#9565] Import and export InformationSchema <-> Meta

This commit is contained in:
Lukas Eder 2019-11-19 11:24:15 +01:00
parent 502cecba02
commit 749c91bca6
3 changed files with 149 additions and 63 deletions

View File

@ -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() {}
}

View File

@ -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<Schema> 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<Table<?>> getTables() {
return Collections.<Table<?>>unmodifiableList(tablesPerSchema.get(this));
return InformationSchemaMetaImpl.<Table<?>>unmodifiableList(tablesPerSchema.get(this));
}
@Override
public final List<Sequence<?>> getSequences() {
return Collections.<Sequence<?>>unmodifiableList(sequencesPerSchema.get(this));
return InformationSchemaMetaImpl.<Sequence<?>>unmodifiableList(sequencesPerSchema.get(this));
}
}
@ -569,6 +596,7 @@ final class InformationSchemaMetaImpl extends AbstractMeta {
UniqueKey<Record> primaryKey;
final List<UniqueKey<Record>> uniqueKeys = new ArrayList<>();
final List<ForeignKey<Record, Record>> foreignKeys = new ArrayList<>();
final List<Check<Record>> checks = new ArrayList<>();
final List<Index> indexes = new ArrayList<>();
public InformationSchemaTable(String name, Schema schema, String comment) {
@ -577,7 +605,7 @@ final class InformationSchemaMetaImpl extends AbstractMeta {
@Override
public List<Index> getIndexes() {
return Collections.unmodifiableList(indexes);
return InformationSchemaMetaImpl.unmodifiableList(indexes);
}
@Override
@ -587,12 +615,17 @@ final class InformationSchemaMetaImpl extends AbstractMeta {
@Override
public List<UniqueKey<Record>> getKeys() {
return Collections.<UniqueKey<Record>>unmodifiableList(uniqueKeys);
return InformationSchemaMetaImpl.<UniqueKey<Record>>unmodifiableList(uniqueKeys);
}
@Override
public List<ForeignKey<Record, ?>> getReferences() {
return Collections.<ForeignKey<Record, ?>>unmodifiableList(foreignKeys);
return InformationSchemaMetaImpl.<ForeignKey<Record, ?>>unmodifiableList(foreignKeys);
}
@Override
public List<Check<Record>> getChecks() {
return InformationSchemaMetaImpl.unmodifiableList(checks);
}
}
@ -608,6 +641,10 @@ final class InformationSchemaMetaImpl extends AbstractMeta {
}
}
private static final <T> List<T> unmodifiableList(List<? extends T> list) {
return list == null ? Collections.emptyList() : Collections.unmodifiableList(list);
}
@Override
public String toString() {
return "" + source;

View File

@ -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);
}
}