[#3451] Added support for PRIMARY KEY and UNIQUE KEY constraints

This commit is contained in:
Lukas Eder 2014-08-12 18:22:12 +02:00
parent 0b77f452e0
commit 90d8788bca
8 changed files with 257 additions and 19 deletions

View File

@ -41,9 +41,14 @@
package org.jooq.util.xml;
import static org.jooq.tools.StringUtils.defaultIfNull;
import static org.jooq.util.xml.jaxb.TableConstraintType.PRIMARY_KEY;
import static org.jooq.util.xml.jaxb.TableConstraintType.UNIQUE;
import java.io.File;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.xml.bind.JAXB;
@ -51,6 +56,7 @@ import javax.xml.bind.JAXB;
import org.jooq.DSLContext;
import org.jooq.SQLDialect;
import org.jooq.impl.DSL;
import org.jooq.tools.StringUtils;
import org.jooq.util.AbstractDatabase;
import org.jooq.util.ArrayDefinition;
import org.jooq.util.DataTypeDefinition;
@ -65,9 +71,12 @@ import org.jooq.util.SequenceDefinition;
import org.jooq.util.TableDefinition;
import org.jooq.util.UDTDefinition;
import org.jooq.util.xml.jaxb.InformationSchema;
import org.jooq.util.xml.jaxb.KeyColumnUsage;
import org.jooq.util.xml.jaxb.Schema;
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;
/**
* The XML Database.
@ -101,23 +110,87 @@ public class XMLDatabase extends AbstractDatabase {
}
@Override
protected void loadPrimaryKeys(DefaultRelations relations) throws SQLException {
protected void loadPrimaryKeys(DefaultRelations relations) {
for (KeyColumnUsage usage : keyColumnUsage(PRIMARY_KEY)) {
SchemaDefinition schema = getSchema(usage.getConstraintSchema());
String key = usage.getConstraintName();
String tableName = usage.getTableName();
String columnName = usage.getColumnName();
TableDefinition table = getTable(schema, tableName);
if (table != null) {
relations.addPrimaryKey(key, table.getColumn(columnName));
}
}
}
@Override
protected void loadUniqueKeys(DefaultRelations relations) throws SQLException {
protected void loadUniqueKeys(DefaultRelations relations) {
for (KeyColumnUsage usage : keyColumnUsage(UNIQUE)) {
SchemaDefinition schema = getSchema(usage.getConstraintSchema());
String key = usage.getConstraintName();
String tableName = usage.getTableName();
String columnName = usage.getColumnName();
TableDefinition table = getTable(schema, tableName);
if (table != null) {
relations.addPrimaryKey(key, table.getColumn(columnName));
}
}
}
private List<KeyColumnUsage> keyColumnUsage(TableConstraintType constraintType) {
List<KeyColumnUsage> result = new ArrayList<KeyColumnUsage>();
for (TableConstraint constraint : info().getTableConstraints()) {
if (constraintType == constraint.getConstraintType()
&& getInputSchemata().contains(constraint.getConstraintSchema())) {
for (KeyColumnUsage usage : info().getKeyColumnUsages()) {
if ( StringUtils.equals(constraint.getConstraintCatalog(), usage.getConstraintCatalog())
&& StringUtils.equals(constraint.getConstraintSchema(), usage.getConstraintSchema())
&& StringUtils.equals(constraint.getConstraintName(), usage.getConstraintName())) {
result.add(usage);
}
}
}
}
Collections.sort(result, new Comparator<KeyColumnUsage>() {
@Override
public int compare(KeyColumnUsage o1, KeyColumnUsage o2) {
int r = 0;
r = defaultIfNull(o1.getConstraintCatalog(), "").compareTo(defaultIfNull(o2.getConstraintCatalog(), ""));
if (r != 0)
return r;
r = defaultIfNull(o1.getConstraintSchema(), "").compareTo(defaultIfNull(o2.getConstraintSchema(), ""));
if (r != 0)
return r;
r = defaultIfNull(o1.getConstraintName(), "").compareTo(defaultIfNull(o2.getConstraintName(), ""));
if (r != 0)
return r;
return Integer.valueOf(o1.getOrdinalPosition()).compareTo(o2.getOrdinalPosition());
}
});
return result;
}
@Override
protected void loadForeignKeys(DefaultRelations relations) throws SQLException {
protected void loadForeignKeys(DefaultRelations relations) {
}
@Override
protected void loadCheckConstraints(DefaultRelations r) throws SQLException {
protected void loadCheckConstraints(DefaultRelations r) {
}
@Override
protected List<SchemaDefinition> getSchemata0() throws SQLException {
protected List<SchemaDefinition> getSchemata0() {
List<SchemaDefinition> result = new ArrayList<SchemaDefinition>();
for (Schema schema : info().getSchemata()) {
@ -131,12 +204,13 @@ public class XMLDatabase extends AbstractDatabase {
@Override
protected List<SequenceDefinition> getSequences0() throws SQLException {
protected List<SequenceDefinition> getSequences0() {
List<SequenceDefinition> result = new ArrayList<SequenceDefinition>();
for (Sequence sequence : info().getSequences()) {
if (getInputSchemata().contains(sequence.getSequenceSchema())) {
SchemaDefinition schema = getSchema(sequence.getSequenceSchema());
DataTypeDefinition type = new DefaultDataTypeDefinition(
this,
schema,
@ -156,7 +230,7 @@ public class XMLDatabase extends AbstractDatabase {
}
@Override
protected List<TableDefinition> getTables0() throws SQLException {
protected List<TableDefinition> getTables0() {
List<TableDefinition> result = new ArrayList<TableDefinition>();
for (Table table : info().getTables()) {
@ -171,31 +245,31 @@ public class XMLDatabase extends AbstractDatabase {
}
@Override
protected List<EnumDefinition> getEnums0() throws SQLException {
protected List<EnumDefinition> getEnums0() {
List<EnumDefinition> result = new ArrayList<EnumDefinition>();
return result;
}
@Override
protected List<UDTDefinition> getUDTs0() throws SQLException {
protected List<UDTDefinition> getUDTs0() {
List<UDTDefinition> result = new ArrayList<UDTDefinition>();
return result;
}
@Override
protected List<ArrayDefinition> getArrays0() throws SQLException {
protected List<ArrayDefinition> getArrays0() {
List<ArrayDefinition> result = new ArrayList<ArrayDefinition>();
return result;
}
@Override
protected List<RoutineDefinition> getRoutines0() throws SQLException {
protected List<RoutineDefinition> getRoutines0() {
List<RoutineDefinition> result = new ArrayList<RoutineDefinition>();
return result;
}
@Override
protected List<PackageDefinition> getPackages0() throws SQLException {
protected List<PackageDefinition> getPackages0() {
List<PackageDefinition> result = new ArrayList<PackageDefinition>();
return result;
}

View File

@ -11,6 +11,8 @@
<element name="sequences" type="tns:Sequences" minOccurs="0" maxOccurs="1" />
<element name="tables" type="tns:Tables" 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" />
</all>
</complexType>
</element>
@ -82,4 +84,63 @@
<element name="column_default" type="string" minOccurs="0" maxOccurs="1" />
</all>
</complexType>
<complexType name="TableConstraints">
<all>
<element name="table_constraint" type="tns:TableConstraint" minOccurs="0" maxOccurs="unbounded" />
</all>
</complexType>
<complexType name="TableConstraint">
<all>
<element name="constraint_catalog" type="string" minOccurs="0" maxOccurs="1" />
<element name="constraint_schema" type="string" minOccurs="0" maxOccurs="1" />
<element name="constraint_name" type="string" minOccurs="1" maxOccurs="1" />
<element name="constraint_type" type="tns:TableConstraintType" minOccurs="1" maxOccurs="1" />
<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" />
</all>
</complexType>
<simpleType name="TableConstraintType">
<restriction base="string">
<enumeration value="PRIMARY KEY"/>
<enumeration value="UNIQUE"/>
<enumeration value="CHECK"/>
<enumeration value="FOREIGN KEY"/>
</restriction>
</simpleType>
<complexType name="KeyColumnUsages">
<all>
<element name="key_column_usage" type="tns:KeyColumnUsage" minOccurs="0" maxOccurs="unbounded" />
</all>
</complexType>
<complexType name="KeyColumnUsage">
<all>
<element name="column_name" type="string" minOccurs="1" maxOccurs="1" />
<element name="constraint_catalog" type="string" minOccurs="0" maxOccurs="1" />
<element name="constraint_schema" type="string" minOccurs="0" maxOccurs="1" />
<element name="constraint_name" type="string" minOccurs="1" maxOccurs="1" />
<element name="ordinal_position" type="int" minOccurs="1" maxOccurs="1" />
<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" />
</all>
</complexType>
<!--
CONSTRAINT_CATALOG : TableField<Record, String>
CONSTRAINT_NAME : TableField<Record, String>
CONSTRAINT_SCHEMA : TableField<Record, String>
DELETE_RULE : TableField<Record, String>
MATCH_OPTION : TableField<Record, String>
UNIQUE_CONSTRAINT_CATALOG : TableField<Record, String>
UNIQUE_CONSTRAINT_NAME : TableField<Record, String>
UNIQUE_CONSTRAINT_SCHEMA : TableField<Record, String>
UPDATE_RULE : TableField<Record, String>-->
</schema>

View File

@ -33,4 +33,25 @@
<numeric_precision>7</numeric_precision>
</sequence>
</sequences>
<table_constraints>
<table_constraint>
<constraint_schema>TEST</constraint_schema>
<constraint_name>PK_T_AUTHOR</constraint_name>
<constraint_type>PRIMARY KEY</constraint_type>
<table_schema>TEST</table_schema>
<table_name>T_AUTHOR</table_name>
</table_constraint>
</table_constraints>
<key_column_usages>
<key_column_usage>
<constraint_schema>TEST</constraint_schema>
<constraint_name>PK_T_AUTHOR</constraint_name>
<table_schema>TEST</table_schema>
<table_name>T_AUTHOR</table_name>
<column_name>ID</column_name>
<ordinal_position>1</ordinal_position>
</key_column_usage>
</key_column_usages>
</information_schema>

View File

@ -21,6 +21,7 @@ public class Keys {
// UNIQUE and PRIMARY KEY definitions
// -------------------------------------------------------------------------
public static final org.jooq.UniqueKey<org.jooq.test.oracle4.generatedclasses.tables.records.TAuthorRecord> PK_T_AUTHOR = UniqueKeys0.PK_T_AUTHOR;
// -------------------------------------------------------------------------
// FOREIGN KEY definitions
@ -30,4 +31,8 @@ public class Keys {
// -------------------------------------------------------------------------
// [#1459] distribute members to avoid static initialisers > 64kb
// -------------------------------------------------------------------------
private static class UniqueKeys0 extends org.jooq.impl.AbstractKeys {
public static final org.jooq.UniqueKey<org.jooq.test.oracle4.generatedclasses.tables.records.TAuthorRecord> PK_T_AUTHOR = createUniqueKey(org.jooq.test.oracle4.generatedclasses.tables.TAuthor.T_AUTHOR, org.jooq.test.oracle4.generatedclasses.tables.TAuthor.T_AUTHOR.ID);
}
}

View File

@ -9,7 +9,7 @@ package org.jooq.test.oracle4.generatedclasses.tables;
@java.lang.SuppressWarnings({ "all", "unchecked", "rawtypes" })
public class TAuthor extends org.jooq.impl.TableImpl<org.jooq.test.oracle4.generatedclasses.tables.records.TAuthorRecord> {
private static final long serialVersionUID = 799437775;
private static final long serialVersionUID = 1532762721;
/**
* The singleton instance of <code>TEST.T_AUTHOR</code>
@ -51,6 +51,22 @@ public class TAuthor extends org.jooq.impl.TableImpl<org.jooq.test.oracle4.gener
super(alias, org.jooq.test.oracle4.generatedclasses.Test.TEST, aliased, parameters, "");
}
/**
* {@inheritDoc}
*/
@Override
public org.jooq.UniqueKey<org.jooq.test.oracle4.generatedclasses.tables.records.TAuthorRecord> getPrimaryKey() {
return org.jooq.test.oracle4.generatedclasses.Keys.PK_T_AUTHOR;
}
/**
* {@inheritDoc}
*/
@Override
public java.util.List<org.jooq.UniqueKey<org.jooq.test.oracle4.generatedclasses.tables.records.TAuthorRecord>> getKeys() {
return java.util.Arrays.<org.jooq.UniqueKey<org.jooq.test.oracle4.generatedclasses.tables.records.TAuthorRecord>>asList(org.jooq.test.oracle4.generatedclasses.Keys.PK_T_AUTHOR);
}
/**
* {@inheritDoc}
*/

View File

@ -0,0 +1,47 @@
/**
* This class is generated by jOOQ
*/
package org.jooq.test.oracle4.generatedclasses.tables.daos;
/**
* This class is generated by jOOQ.
*/
@java.lang.SuppressWarnings({ "all", "unchecked", "rawtypes" })
public class TAuthorDao extends org.jooq.impl.DAOImpl<org.jooq.test.oracle4.generatedclasses.tables.records.TAuthorRecord, org.jooq.test.oracle4.generatedclasses.tables.pojos.TAuthor, java.lang.Integer> {
/**
* Create a new TAuthorDao without any configuration
*/
public TAuthorDao() {
super(org.jooq.test.oracle4.generatedclasses.tables.TAuthor.T_AUTHOR, org.jooq.test.oracle4.generatedclasses.tables.pojos.TAuthor.class);
}
/**
* Create a new TAuthorDao with an attached configuration
*/
public TAuthorDao(org.jooq.Configuration configuration) {
super(org.jooq.test.oracle4.generatedclasses.tables.TAuthor.T_AUTHOR, org.jooq.test.oracle4.generatedclasses.tables.pojos.TAuthor.class, configuration);
}
/**
* {@inheritDoc}
*/
@Override
protected java.lang.Integer getId(org.jooq.test.oracle4.generatedclasses.tables.pojos.TAuthor object) {
return object.getId();
}
/**
* Fetch records that have <code>ID IN (values)</code>
*/
public java.util.List<org.jooq.test.oracle4.generatedclasses.tables.pojos.TAuthor> fetchById(java.lang.Integer... values) {
return fetch(org.jooq.test.oracle4.generatedclasses.tables.TAuthor.T_AUTHOR.ID, values);
}
/**
* Fetch a unique record that has <code>ID = value</code>
*/
public org.jooq.test.oracle4.generatedclasses.tables.pojos.TAuthor fetchOneById(java.lang.Integer value) {
return fetchOne(org.jooq.test.oracle4.generatedclasses.tables.TAuthor.T_AUTHOR.ID, value);
}
}

View File

@ -11,7 +11,7 @@ package org.jooq.test.oracle4.generatedclasses.tables.pojos;
@javax.persistence.Table(name = "T_AUTHOR", schema = "TEST")
public class TAuthor implements java.io.Serializable {
private static final long serialVersionUID = -2112424480;
private static final long serialVersionUID = -895002231;
private java.lang.Integer id;
@ -23,7 +23,8 @@ public class TAuthor implements java.io.Serializable {
this.id = id;
}
@javax.persistence.Column(name = "ID", nullable = false, precision = 7)
@javax.persistence.Id
@javax.persistence.Column(name = "ID", unique = true, nullable = false, precision = 7)
@javax.validation.constraints.NotNull
public java.lang.Integer getId() {
return this.id;

View File

@ -9,9 +9,9 @@ package org.jooq.test.oracle4.generatedclasses.tables.records;
@java.lang.SuppressWarnings({ "all", "unchecked", "rawtypes" })
@javax.persistence.Entity
@javax.persistence.Table(name = "T_AUTHOR", schema = "TEST")
public class TAuthorRecord extends org.jooq.impl.TableRecordImpl<org.jooq.test.oracle4.generatedclasses.tables.records.TAuthorRecord> implements org.jooq.Record1<java.lang.Integer> {
public class TAuthorRecord extends org.jooq.impl.UpdatableRecordImpl<org.jooq.test.oracle4.generatedclasses.tables.records.TAuthorRecord> implements org.jooq.Record1<java.lang.Integer> {
private static final long serialVersionUID = -115873836;
private static final long serialVersionUID = -2050117306;
/**
* Setter for <code>TEST.T_AUTHOR.ID</code>.
@ -23,12 +23,25 @@ public class TAuthorRecord extends org.jooq.impl.TableRecordImpl<org.jooq.test.o
/**
* Getter for <code>TEST.T_AUTHOR.ID</code>.
*/
@javax.persistence.Column(name = "ID", nullable = false, precision = 7)
@javax.persistence.Id
@javax.persistence.Column(name = "ID", unique = true, nullable = false, precision = 7)
@javax.validation.constraints.NotNull
public java.lang.Integer getId() {
return (java.lang.Integer) getValue(0);
}
// -------------------------------------------------------------------------
// Primary key information
// -------------------------------------------------------------------------
/**
* {@inheritDoc}
*/
@Override
public org.jooq.Record1<java.lang.Integer> key() {
return (org.jooq.Record1) super.key();
}
// -------------------------------------------------------------------------
// Record1 type implementation
// -------------------------------------------------------------------------