From 32c536328c1ec10ffa3ddb2c7d9e5bb62c2a903c Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Tue, 11 Feb 2020 16:06:16 +0100 Subject: [PATCH] [jOOQ/jOOQ#9819] Add support for INFORMATION_SCHEMA.VIEWS in jooq-meta.xsd --- .../java/org/jooq/codegen/XMLGenerator.java | 12 ++ .../java/org/jooq/meta/xml/XMLDatabase.java | 20 +- .../jooq/impl/InformationSchemaExport.java | 14 ++ .../jooq/impl/InformationSchemaMetaImpl.java | 24 ++- .../jooq/util/xml/jaxb/InformationSchema.java | 47 +++++ .../org/jooq/util/xml/jaxb/ObjectFactory.java | 8 + .../java/org/jooq/util/xml/jaxb/View.java | 190 ++++++++++++++++++ .../main/resources/xsd/jooq-meta-3.13.0.xsd | 16 ++ 8 files changed, 327 insertions(+), 4 deletions(-) create mode 100644 jOOQ/src/main/java/org/jooq/util/xml/jaxb/View.java diff --git a/jOOQ-codegen/src/main/java/org/jooq/codegen/XMLGenerator.java b/jOOQ-codegen/src/main/java/org/jooq/codegen/XMLGenerator.java index 73687896c3..d7bc557daa 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/codegen/XMLGenerator.java +++ b/jOOQ-codegen/src/main/java/org/jooq/codegen/XMLGenerator.java @@ -84,6 +84,7 @@ import org.jooq.util.xml.jaxb.Sequence; import org.jooq.util.xml.jaxb.Table; import org.jooq.util.xml.jaxb.TableConstraint; import org.jooq.util.xml.jaxb.TableType; +import org.jooq.util.xml.jaxb.View; /** * @author Lukas Eder @@ -160,6 +161,17 @@ public class XMLGenerator extends AbstractGenerator { is.getTables().add(table); + if (t.isView()) { + View view = new View(); + + view.setTableCatalog(catalogName); + view.setTableSchema(schemaName); + view.setTableName(tableName); + view.setViewDefinition(t.getSource()); + + is.getViews().add(view); + } + for (ColumnDefinition co : t.getColumns()) { String columnName = co.getOutputName(); DataTypeDefinition type = co.getType(); diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/xml/XMLDatabase.java b/jOOQ-meta/src/main/java/org/jooq/meta/xml/XMLDatabase.java index 9fed586b4b..c5f0439dfb 100644 --- a/jOOQ-meta/src/main/java/org/jooq/meta/xml/XMLDatabase.java +++ b/jOOQ-meta/src/main/java/org/jooq/meta/xml/XMLDatabase.java @@ -111,6 +111,7 @@ import org.jooq.tools.StringUtils; import org.jooq.tools.jdbc.JDBCUtils; import org.jooq.util.jaxb.tools.MiniJAXB; import org.jooq.util.xml.jaxb.CheckConstraint; +import org.jooq.util.xml.jaxb.Column; import org.jooq.util.xml.jaxb.Index; import org.jooq.util.xml.jaxb.IndexColumnUsage; import org.jooq.util.xml.jaxb.InformationSchema; @@ -122,6 +123,7 @@ import org.jooq.util.xml.jaxb.Sequence; import org.jooq.util.xml.jaxb.Table; import org.jooq.util.xml.jaxb.TableConstraint; import org.jooq.util.xml.jaxb.TableConstraintType; +import org.jooq.util.xml.jaxb.View; /** * The XML Database. @@ -556,7 +558,23 @@ public class XMLDatabase extends AbstractDatabase { default: tableType = TableType.TABLE; break; } - result.add(new XMLTableDefinition(schema, info(), table, table.getComment(), tableType, null)); + String source = null; + + if (tableType == TableType.VIEW) { + + viewLoop: + for (View view : info().getViews()) { + if (StringUtils.equals(defaultIfNull(table.getTableCatalog(), ""), defaultIfNull(view.getTableCatalog(), "")) && + StringUtils.equals(defaultIfNull(table.getTableSchema(), ""), defaultIfNull(view.getTableSchema(), "")) && + StringUtils.equals(defaultIfNull(table.getTableName(), ""), defaultIfNull(view.getTableName(), ""))) { + + source = view.getViewDefinition(); + break viewLoop; + } + } + } + + result.add(new XMLTableDefinition(schema, info(), table, table.getComment(), tableType, source)); } } diff --git a/jOOQ/src/main/java/org/jooq/impl/InformationSchemaExport.java b/jOOQ/src/main/java/org/jooq/impl/InformationSchemaExport.java index 0bb7d11a32..b484546d8d 100644 --- a/jOOQ/src/main/java/org/jooq/impl/InformationSchemaExport.java +++ b/jOOQ/src/main/java/org/jooq/impl/InformationSchemaExport.java @@ -243,6 +243,20 @@ final class InformationSchemaExport { it.setComment(t.getComment()); result.getTables().add(it); + if (t.getOptions().type() == org.jooq.TableOptions.TableType.VIEW) { + org.jooq.util.xml.jaxb.View iv = new org.jooq.util.xml.jaxb.View(); + + if (!StringUtils.isBlank(t.getCatalog().getName())) + iv.setTableCatalog(t.getCatalog().getName()); + + if (!StringUtils.isBlank(t.getSchema().getName())) + iv.setTableSchema(t.getSchema().getName()); + + iv.setTableName(t.getName()); + iv.setViewDefinition(t.getOptions().source()); + result.getViews().add(iv); + } + Field[] fields = t.fields(); for (int i = 0; i < fields.length; i++) { Field f = fields[i]; diff --git a/jOOQ/src/main/java/org/jooq/impl/InformationSchemaMetaImpl.java b/jOOQ/src/main/java/org/jooq/impl/InformationSchemaMetaImpl.java index da6d77cffe..f42dbfc1b4 100644 --- a/jOOQ/src/main/java/org/jooq/impl/InformationSchemaMetaImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/InformationSchemaMetaImpl.java @@ -39,6 +39,7 @@ package org.jooq.impl; import static org.jooq.impl.DSL.name; import static org.jooq.impl.Tools.EMPTY_SORTFIELD; +import static org.jooq.tools.StringUtils.defaultIfNull; import static org.jooq.util.xml.jaxb.TableConstraintType.PRIMARY_KEY; import java.math.BigInteger; @@ -66,6 +67,7 @@ import org.jooq.TableOptions; import org.jooq.TableOptions.TableType; import org.jooq.UniqueKey; import org.jooq.exception.SQLDialectNotSupportedException; +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; @@ -182,7 +184,23 @@ final class InformationSchemaMetaImpl extends AbstractMeta { default: tableType = TableType.TABLE; break; } - InformationSchemaTable it = new InformationSchemaTable(xt.getTableName(), schema, xt.getComment(), tableType); + String sql = null; + + if (tableType == TableType.VIEW) { + + viewLoop: + for (org.jooq.util.xml.jaxb.View vt : meta.getViews()) { + if (StringUtils.equals(defaultIfNull(xt.getTableCatalog(), ""), defaultIfNull(vt.getTableCatalog(), "")) && + StringUtils.equals(defaultIfNull(xt.getTableSchema(), ""), defaultIfNull(vt.getTableSchema(), "")) && + StringUtils.equals(defaultIfNull(xt.getTableName(), ""), defaultIfNull(vt.getTableName(), ""))) { + + sql = vt.getViewDefinition(); + break viewLoop; + } + } + } + + InformationSchemaTable it = new InformationSchemaTable(xt.getTableName(), schema, xt.getComment(), tableType, sql); tables.add(it); tablesByName.put(name(xt.getTableCatalog(), xt.getTableSchema(), xt.getTableName()), it); } @@ -623,8 +641,8 @@ final class InformationSchemaMetaImpl extends AbstractMeta { final List> checks = new ArrayList<>(); final List indexes = new ArrayList<>(); - InformationSchemaTable(String name, Schema schema, String comment, TableType tableType) { - super(DSL.name(name), schema, null, null, DSL.comment(comment), TableOptions.of(tableType)); + InformationSchemaTable(String name, Schema schema, String comment, TableType tableType, String source) { + super(DSL.name(name), schema, null, null, DSL.comment(comment), tableType == TableType.VIEW ? TableOptions.view(source) : TableOptions.of(tableType)); } @Override diff --git a/jOOQ/src/main/java/org/jooq/util/xml/jaxb/InformationSchema.java b/jOOQ/src/main/java/org/jooq/util/xml/jaxb/InformationSchema.java index 17a098c664..a01c9da9d2 100644 --- a/jOOQ/src/main/java/org/jooq/util/xml/jaxb/InformationSchema.java +++ b/jOOQ/src/main/java/org/jooq/util/xml/jaxb/InformationSchema.java @@ -29,6 +29,7 @@ import org.jooq.util.jaxb.tools.XMLBuilder; * <element name="schemata" type="{http://www.jooq.org/xsd/jooq-meta-3.12.0.xsd}Schemata" minOccurs="0"/> * <element name="sequences" type="{http://www.jooq.org/xsd/jooq-meta-3.12.0.xsd}Sequences" minOccurs="0"/> * <element name="tables" type="{http://www.jooq.org/xsd/jooq-meta-3.12.0.xsd}Tables" minOccurs="0"/> + * <element name="views" type="{http://www.jooq.org/xsd/jooq-meta-3.12.0.xsd}Views" minOccurs="0"/> * <element name="columns" type="{http://www.jooq.org/xsd/jooq-meta-3.12.0.xsd}Columns" minOccurs="0"/> * <element name="table_constraints" type="{http://www.jooq.org/xsd/jooq-meta-3.12.0.xsd}TableConstraints" minOccurs="0"/> * <element name="key_column_usages" type="{http://www.jooq.org/xsd/jooq-meta-3.12.0.xsd}KeyColumnUsages" minOccurs="0"/> @@ -71,6 +72,9 @@ public class InformationSchema implements Serializable, XMLAppendable @XmlElementWrapper(name = "tables") @XmlElement(name = "table") protected List tables; + @XmlElementWrapper(name = "views") + @XmlElement(name = "view") + protected List views; @XmlElementWrapper(name = "columns") @XmlElement(name = "column") protected List columns; @@ -146,6 +150,17 @@ public class InformationSchema implements Serializable, XMLAppendable this.tables = tables; } + public List getViews() { + if (views == null) { + views = new ArrayList(); + } + return views; + } + + public void setViews(List views) { + this.views = views; + } + public List getColumns() { if (columns == null) { columns = new ArrayList(); @@ -340,6 +355,27 @@ public class InformationSchema implements Serializable, XMLAppendable return this; } + public InformationSchema withViews(View... values) { + if (values!= null) { + for (View value: values) { + getViews().add(value); + } + } + return this; + } + + public InformationSchema withViews(Collection values) { + if (values!= null) { + getViews().addAll(values); + } + return this; + } + + public InformationSchema withViews(List views) { + setViews(views); + return this; + } + public InformationSchema withColumns(Column... values) { if (values!= null) { for (Column value: values) { @@ -556,6 +592,7 @@ public class InformationSchema implements Serializable, XMLAppendable builder.append("schemata", "schema", schemata); builder.append("sequences", "sequence", sequences); builder.append("tables", "table", tables); + builder.append("views", "view", views); builder.append("columns", "column", columns); builder.append("table_constraints", "table_constraint", tableConstraints); builder.append("key_column_usages", "key_column_usage", keyColumnUsages); @@ -623,6 +660,15 @@ public class InformationSchema implements Serializable, XMLAppendable return false; } } + if (views == null) { + if (other.views!= null) { + return false; + } + } else { + if (!views.equals(other.views)) { + return false; + } + } if (columns == null) { if (other.columns!= null) { return false; @@ -724,6 +770,7 @@ public class InformationSchema implements Serializable, XMLAppendable result = ((prime*result)+((schemata == null)? 0 :schemata.hashCode())); result = ((prime*result)+((sequences == null)? 0 :sequences.hashCode())); result = ((prime*result)+((tables == null)? 0 :tables.hashCode())); + result = ((prime*result)+((views == null)? 0 :views.hashCode())); result = ((prime*result)+((columns == null)? 0 :columns.hashCode())); result = ((prime*result)+((tableConstraints == null)? 0 :tableConstraints.hashCode())); result = ((prime*result)+((keyColumnUsages == null)? 0 :keyColumnUsages.hashCode())); diff --git a/jOOQ/src/main/java/org/jooq/util/xml/jaxb/ObjectFactory.java b/jOOQ/src/main/java/org/jooq/util/xml/jaxb/ObjectFactory.java index 5a31bab26f..d7245a2ad8 100644 --- a/jOOQ/src/main/java/org/jooq/util/xml/jaxb/ObjectFactory.java +++ b/jOOQ/src/main/java/org/jooq/util/xml/jaxb/ObjectFactory.java @@ -69,6 +69,14 @@ public class ObjectFactory { return new Table(); } + /** + * Create an instance of {@link View } + * + */ + public View createView() { + return new View(); + } + /** * Create an instance of {@link Column } * diff --git a/jOOQ/src/main/java/org/jooq/util/xml/jaxb/View.java b/jOOQ/src/main/java/org/jooq/util/xml/jaxb/View.java new file mode 100644 index 0000000000..239eca61a8 --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/util/xml/jaxb/View.java @@ -0,0 +1,190 @@ + +package org.jooq.util.xml.jaxb; + +import java.io.Serializable; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import org.jooq.util.jaxb.tools.StringAdapter; +import org.jooq.util.jaxb.tools.XMLAppendable; +import org.jooq.util.jaxb.tools.XMLBuilder; + + +/** + *

Java class for View complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="View">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <all>
+ *         <element name="table_catalog" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="table_schema" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="table_name" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         <element name="view_definition" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *       </all>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "View", propOrder = { + +}) +@SuppressWarnings({ + "all" +}) +public class View implements Serializable, XMLAppendable +{ + + private final static long serialVersionUID = 31300L; + @XmlElement(name = "table_catalog") + @XmlJavaTypeAdapter(StringAdapter.class) + protected String tableCatalog; + @XmlElement(name = "table_schema") + @XmlJavaTypeAdapter(StringAdapter.class) + protected String tableSchema; + @XmlElement(name = "table_name", required = true) + @XmlJavaTypeAdapter(StringAdapter.class) + protected String tableName; + @XmlElement(name = "view_definition", required = true) + @XmlJavaTypeAdapter(StringAdapter.class) + protected String viewDefinition; + + public String getTableCatalog() { + return tableCatalog; + } + + public void setTableCatalog(String value) { + this.tableCatalog = value; + } + + public String getTableSchema() { + return tableSchema; + } + + public void setTableSchema(String value) { + this.tableSchema = value; + } + + public String getTableName() { + return tableName; + } + + public void setTableName(String value) { + this.tableName = value; + } + + public String getViewDefinition() { + return viewDefinition; + } + + public void setViewDefinition(String value) { + this.viewDefinition = value; + } + + public View withTableCatalog(String value) { + setTableCatalog(value); + return this; + } + + public View withTableSchema(String value) { + setTableSchema(value); + return this; + } + + public View withTableName(String value) { + setTableName(value); + return this; + } + + public View withViewDefinition(String value) { + setViewDefinition(value); + return this; + } + + @Override + public final void appendTo(XMLBuilder builder) { + builder.append("table_catalog", tableCatalog); + builder.append("table_schema", tableSchema); + builder.append("table_name", tableName); + builder.append("view_definition", viewDefinition); + } + + @Override + public String toString() { + XMLBuilder builder = XMLBuilder.nonFormatting(); + appendTo(builder); + return builder.toString(); + } + + @Override + public boolean equals(Object that) { + if (this == that) { + return true; + } + if (that == null) { + return false; + } + if (getClass()!= that.getClass()) { + return false; + } + View other = ((View) that); + if (tableCatalog == null) { + if (other.tableCatalog!= null) { + return false; + } + } else { + if (!tableCatalog.equals(other.tableCatalog)) { + return false; + } + } + if (tableSchema == null) { + if (other.tableSchema!= null) { + return false; + } + } else { + if (!tableSchema.equals(other.tableSchema)) { + return false; + } + } + if (tableName == null) { + if (other.tableName!= null) { + return false; + } + } else { + if (!tableName.equals(other.tableName)) { + return false; + } + } + if (viewDefinition == null) { + if (other.viewDefinition!= null) { + return false; + } + } else { + if (!viewDefinition.equals(other.viewDefinition)) { + return false; + } + } + return true; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = ((prime*result)+((tableCatalog == null)? 0 :tableCatalog.hashCode())); + result = ((prime*result)+((tableSchema == null)? 0 :tableSchema.hashCode())); + result = ((prime*result)+((tableName == null)? 0 :tableName.hashCode())); + result = ((prime*result)+((viewDefinition == null)? 0 :viewDefinition.hashCode())); + return result; + } + +} diff --git a/jOOQ/src/main/resources/xsd/jooq-meta-3.13.0.xsd b/jOOQ/src/main/resources/xsd/jooq-meta-3.13.0.xsd index 2e8ec12768..2a19e36e63 100644 --- a/jOOQ/src/main/resources/xsd/jooq-meta-3.13.0.xsd +++ b/jOOQ/src/main/resources/xsd/jooq-meta-3.13.0.xsd @@ -11,6 +11,7 @@ + @@ -93,6 +94,21 @@ + + + + + + + + + + + + + + +