[jOOQ/jOOQ#9565] Import and export InformationSchema <-> Meta
This commit is contained in:
parent
502cecba02
commit
749c91bca6
@ -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() {}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user