[jOOQ/jOOQ#9819] Add support for INFORMATION_SCHEMA.VIEWS in jooq-meta.xsd

This commit is contained in:
Lukas Eder 2020-02-11 16:06:16 +01:00
parent 20f3fce616
commit 32c536328c
8 changed files with 327 additions and 4 deletions

View File

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

View File

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

View File

@ -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];

View File

@ -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<Check<Record>> checks = new ArrayList<>();
final List<Index> 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

View File

@ -29,6 +29,7 @@ import org.jooq.util.jaxb.tools.XMLBuilder;
* &lt;element name="schemata" type="{http://www.jooq.org/xsd/jooq-meta-3.12.0.xsd}Schemata" minOccurs="0"/&gt;
* &lt;element name="sequences" type="{http://www.jooq.org/xsd/jooq-meta-3.12.0.xsd}Sequences" minOccurs="0"/&gt;
* &lt;element name="tables" type="{http://www.jooq.org/xsd/jooq-meta-3.12.0.xsd}Tables" minOccurs="0"/&gt;
* &lt;element name="views" type="{http://www.jooq.org/xsd/jooq-meta-3.12.0.xsd}Views" minOccurs="0"/&gt;
* &lt;element name="columns" type="{http://www.jooq.org/xsd/jooq-meta-3.12.0.xsd}Columns" minOccurs="0"/&gt;
* &lt;element name="table_constraints" type="{http://www.jooq.org/xsd/jooq-meta-3.12.0.xsd}TableConstraints" minOccurs="0"/&gt;
* &lt;element name="key_column_usages" type="{http://www.jooq.org/xsd/jooq-meta-3.12.0.xsd}KeyColumnUsages" minOccurs="0"/&gt;
@ -71,6 +72,9 @@ public class InformationSchema implements Serializable, XMLAppendable
@XmlElementWrapper(name = "tables")
@XmlElement(name = "table")
protected List<Table> tables;
@XmlElementWrapper(name = "views")
@XmlElement(name = "view")
protected List<View> views;
@XmlElementWrapper(name = "columns")
@XmlElement(name = "column")
protected List<Column> columns;
@ -146,6 +150,17 @@ public class InformationSchema implements Serializable, XMLAppendable
this.tables = tables;
}
public List<View> getViews() {
if (views == null) {
views = new ArrayList<View>();
}
return views;
}
public void setViews(List<View> views) {
this.views = views;
}
public List<Column> getColumns() {
if (columns == null) {
columns = new ArrayList<Column>();
@ -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<View> values) {
if (values!= null) {
getViews().addAll(values);
}
return this;
}
public InformationSchema withViews(List<View> 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()));

View File

@ -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 }
*

View File

@ -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;
/**
* <p>Java class for View complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType name="View"&gt;
* &lt;complexContent&gt;
* &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"&gt;
* &lt;all&gt;
* &lt;element name="table_catalog" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/&gt;
* &lt;element name="table_schema" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/&gt;
* &lt;element name="table_name" type="{http://www.w3.org/2001/XMLSchema}string"/&gt;
* &lt;element name="view_definition" type="{http://www.w3.org/2001/XMLSchema}string"/&gt;
* &lt;/all&gt;
* &lt;/restriction&gt;
* &lt;/complexContent&gt;
* &lt;/complexType&gt;
* </pre>
*
*
*/
@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;
}
}

View File

@ -11,6 +11,7 @@
<element name="schemata" type="tns:Schemata" minOccurs="0" maxOccurs="1" />
<element name="sequences" type="tns:Sequences" minOccurs="0" maxOccurs="1" />
<element name="tables" type="tns:Tables" minOccurs="0" maxOccurs="1" />
<element name="views" type="tns:Views" minOccurs="0" maxOccurs="1" />
<element name="columns" type="tns:Columns" minOccurs="0" maxOccurs="1" />
<element name="table_constraints" type="tns:TableConstraints" minOccurs="0" maxOccurs="1" />
<element name="key_column_usages" type="tns:KeyColumnUsages" minOccurs="0" maxOccurs="1" />
@ -93,6 +94,21 @@
</all>
</complexType>
<complexType name="Views">
<sequence>
<element name="view" type="tns:View" minOccurs="0" maxOccurs="unbounded" />
</sequence>
</complexType>
<complexType name="View">
<all>
<element name="table_catalog" type="string" minOccurs="0" maxOccurs="1" />
<element name="table_schema" type="string" minOccurs="0" maxOccurs="1" />
<element name="table_name" type="string" minOccurs="1" maxOccurs="1" />
<element name="view_definition" type="string" minOccurs="1" maxOccurs="1"/>
</all>
</complexType>
<complexType name="Columns">
<sequence>
<element name="column" type="tns:Column" minOccurs="0" maxOccurs="unbounded" />