[#3451] Added support for foreign key constraints

This commit is contained in:
Lukas Eder 2014-08-12 18:41:39 +02:00
parent 90d8788bca
commit 00e6fdd2b8
11 changed files with 476 additions and 14 deletions

View File

@ -1,5 +1,4 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/main/resources=UTF-8
encoding//target/generated-sources/xjc=UTF-8
encoding/<project>=UTF-8

View File

@ -59,6 +59,7 @@ import org.jooq.impl.DSL;
import org.jooq.tools.StringUtils;
import org.jooq.util.AbstractDatabase;
import org.jooq.util.ArrayDefinition;
import org.jooq.util.ColumnDefinition;
import org.jooq.util.DataTypeDefinition;
import org.jooq.util.DefaultDataTypeDefinition;
import org.jooq.util.DefaultRelations;
@ -72,6 +73,7 @@ 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.ReferentialConstraint;
import org.jooq.util.xml.jaxb.Schema;
import org.jooq.util.xml.jaxb.Sequence;
import org.jooq.util.xml.jaxb.Table;
@ -183,6 +185,32 @@ public class XMLDatabase extends AbstractDatabase {
@Override
protected void loadForeignKeys(DefaultRelations relations) {
for (ReferentialConstraint constraint : info().getReferentialConstraints()) {
if (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())) {
SchemaDefinition foreignKeySchema = getSchema(constraint.getConstraintSchema());
SchemaDefinition uniqueKeySchema = getSchema(constraint.getUniqueConstraintSchema());
String foreignKey = usage.getConstraintName();
String foreignKeyTable = usage.getTableName();
String foreignKeyColumn = usage.getColumnName();
String uniqueKey = constraint.getUniqueConstraintName();
TableDefinition referencingTable = getTable(foreignKeySchema, foreignKeyTable);
if (referencingTable != null) {
ColumnDefinition referencingColumn = referencingTable.getColumn(foreignKeyColumn);
relations.addForeignKey(foreignKey, uniqueKey, referencingColumn, uniqueKeySchema);
}
}
}
}
}
}
@Override

View File

@ -13,6 +13,7 @@
<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" />
<element name="referential_constraints" type="tns:ReferentialConstraints" minOccurs="0" maxOccurs="1" />
</all>
</complexType>
</element>
@ -131,16 +132,20 @@
</all>
</complexType>
<!--
<complexType name="ReferentialConstraints">
<all>
<element name="referential_constraint" type="tns:ReferentialConstraint" minOccurs="0" maxOccurs="unbounded" />
</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>-->
<complexType name="ReferentialConstraint">
<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="unique_constraint_catalog" type="string" minOccurs="0" maxOccurs="1" />
<element name="unique_constraint_schema" type="string" minOccurs="0" maxOccurs="1" />
<element name="unique_constraint_name" type="string" minOccurs="1" maxOccurs="1" />
</all>
</complexType>
</schema>

View File

@ -11,6 +11,10 @@
<table_schema>TEST</table_schema>
<table_name>T_AUTHOR</table_name>
</table>
<table>
<table_schema>TEST</table_schema>
<table_name>T_BOOK</table_name>
</table>
</tables>
<columns>
@ -23,6 +27,25 @@
<ordinal_position>1</ordinal_position>
<is_nullable>false</is_nullable>
</column>
<column>
<table_schema>TEST</table_schema>
<table_name>T_BOOK</table_name>
<column_name>ID</column_name>
<data_type>NUMBER</data_type>
<numeric_precision>7</numeric_precision>
<ordinal_position>1</ordinal_position>
<is_nullable>false</is_nullable>
</column>
<column>
<table_schema>TEST</table_schema>
<table_name>T_BOOK</table_name>
<column_name>AUTHOR_ID</column_name>
<data_type>NUMBER</data_type>
<numeric_precision>7</numeric_precision>
<ordinal_position>1</ordinal_position>
<is_nullable>false</is_nullable>
</column>
</columns>
<sequences>
@ -42,6 +65,14 @@
<table_schema>TEST</table_schema>
<table_name>T_AUTHOR</table_name>
</table_constraint>
<table_constraint>
<constraint_schema>TEST</constraint_schema>
<constraint_name>PK_T_BOOK</constraint_name>
<constraint_type>PRIMARY KEY</constraint_type>
<table_schema>TEST</table_schema>
<table_name>T_BOOK</table_name>
</table_constraint>
</table_constraints>
<key_column_usages>
@ -53,5 +84,32 @@
<column_name>ID</column_name>
<ordinal_position>1</ordinal_position>
</key_column_usage>
<key_column_usage>
<constraint_schema>TEST</constraint_schema>
<constraint_name>PK_T_BOOK</constraint_name>
<table_schema>TEST</table_schema>
<table_name>T_BOOK</table_name>
<column_name>ID</column_name>
<ordinal_position>1</ordinal_position>
</key_column_usage>
<key_column_usage>
<constraint_schema>TEST</constraint_schema>
<constraint_name>FK_T_BOOK_AUTHOR_ID</constraint_name>
<table_schema>TEST</table_schema>
<table_name>T_BOOK</table_name>
<column_name>AUTHOR_ID</column_name>
<ordinal_position>1</ordinal_position>
</key_column_usage>
</key_column_usages>
<referential_constraints>
<referential_constraint>
<constraint_schema>TEST</constraint_schema>
<constraint_name>FK_T_BOOK_AUTHOR_ID</constraint_name>
<unique_constraint_schema>TEST</unique_constraint_schema>
<unique_constraint_name>PK_T_AUTHOR</unique_constraint_name>
</referential_constraint>
</referential_constraints>
</information_schema>

View File

@ -22,11 +22,13 @@ public class Keys {
// -------------------------------------------------------------------------
public static final org.jooq.UniqueKey<org.jooq.test.oracle4.generatedclasses.tables.records.TAuthorRecord> PK_T_AUTHOR = UniqueKeys0.PK_T_AUTHOR;
public static final org.jooq.UniqueKey<org.jooq.test.oracle4.generatedclasses.tables.records.TBookRecord> PK_T_BOOK = UniqueKeys0.PK_T_BOOK;
// -------------------------------------------------------------------------
// FOREIGN KEY definitions
// -------------------------------------------------------------------------
public static final org.jooq.ForeignKey<org.jooq.test.oracle4.generatedclasses.tables.records.TBookRecord, org.jooq.test.oracle4.generatedclasses.tables.records.TAuthorRecord> FK_T_BOOK_AUTHOR_ID = ForeignKeys0.FK_T_BOOK_AUTHOR_ID;
// -------------------------------------------------------------------------
// [#1459] distribute members to avoid static initialisers > 64kb
@ -34,5 +36,10 @@ public class Keys {
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);
public static final org.jooq.UniqueKey<org.jooq.test.oracle4.generatedclasses.tables.records.TBookRecord> PK_T_BOOK = createUniqueKey(org.jooq.test.oracle4.generatedclasses.tables.TBook.T_BOOK, org.jooq.test.oracle4.generatedclasses.tables.TBook.T_BOOK.ID);
}
private static class ForeignKeys0 extends org.jooq.impl.AbstractKeys {
public static final org.jooq.ForeignKey<org.jooq.test.oracle4.generatedclasses.tables.records.TBookRecord, org.jooq.test.oracle4.generatedclasses.tables.records.TAuthorRecord> FK_T_BOOK_AUTHOR_ID = createForeignKey(org.jooq.test.oracle4.generatedclasses.Keys.PK_T_AUTHOR, org.jooq.test.oracle4.generatedclasses.tables.TBook.T_BOOK, org.jooq.test.oracle4.generatedclasses.tables.TBook.T_BOOK.AUTHOR_ID);
}
}

View File

@ -15,4 +15,9 @@ public class Tables {
* The table TEST.T_AUTHOR
*/
public static final org.jooq.test.oracle4.generatedclasses.tables.TAuthor T_AUTHOR = org.jooq.test.oracle4.generatedclasses.tables.TAuthor.T_AUTHOR;
/**
* The table TEST.T_BOOK
*/
public static final org.jooq.test.oracle4.generatedclasses.tables.TBook T_BOOK = org.jooq.test.oracle4.generatedclasses.tables.TBook.T_BOOK;
}

View File

@ -9,7 +9,7 @@ package org.jooq.test.oracle4.generatedclasses;
@java.lang.SuppressWarnings({ "all", "unchecked", "rawtypes" })
public class Test extends org.jooq.impl.SchemaImpl {
private static final long serialVersionUID = 1552778377;
private static final long serialVersionUID = -363396858;
/**
* The singleton instance of <code>TEST</code>
@ -44,6 +44,7 @@ public class Test extends org.jooq.impl.SchemaImpl {
private final java.util.List<org.jooq.Table<?>> getTables0() {
return java.util.Arrays.<org.jooq.Table<?>>asList(
org.jooq.test.oracle4.generatedclasses.tables.TAuthor.T_AUTHOR);
org.jooq.test.oracle4.generatedclasses.tables.TAuthor.T_AUTHOR,
org.jooq.test.oracle4.generatedclasses.tables.TBook.T_BOOK);
}
}

View File

@ -0,0 +1,97 @@
/**
* This class is generated by jOOQ
*/
package org.jooq.test.oracle4.generatedclasses.tables;
/**
* This class is generated by jOOQ.
*/
@java.lang.SuppressWarnings({ "all", "unchecked", "rawtypes" })
public class TBook extends org.jooq.impl.TableImpl<org.jooq.test.oracle4.generatedclasses.tables.records.TBookRecord> {
private static final long serialVersionUID = 1558602969;
/**
* The singleton instance of <code>TEST.T_BOOK</code>
*/
public static final org.jooq.test.oracle4.generatedclasses.tables.TBook T_BOOK = new org.jooq.test.oracle4.generatedclasses.tables.TBook();
/**
* The class holding records for this type
*/
@Override
public java.lang.Class<org.jooq.test.oracle4.generatedclasses.tables.records.TBookRecord> getRecordType() {
return org.jooq.test.oracle4.generatedclasses.tables.records.TBookRecord.class;
}
/**
* The column <code>TEST.T_BOOK.ID</code>.
*/
public final org.jooq.TableField<org.jooq.test.oracle4.generatedclasses.tables.records.TBookRecord, java.lang.Integer> ID = createField("ID", org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, "");
/**
* The column <code>TEST.T_BOOK.AUTHOR_ID</code>.
*/
public final org.jooq.TableField<org.jooq.test.oracle4.generatedclasses.tables.records.TBookRecord, java.lang.Integer> AUTHOR_ID = createField("AUTHOR_ID", org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, "");
/**
* Create a <code>TEST.T_BOOK</code> table reference
*/
public TBook() {
this("T_BOOK", null);
}
/**
* Create an aliased <code>TEST.T_BOOK</code> table reference
*/
public TBook(java.lang.String alias) {
this(alias, org.jooq.test.oracle4.generatedclasses.tables.TBook.T_BOOK);
}
private TBook(java.lang.String alias, org.jooq.Table<org.jooq.test.oracle4.generatedclasses.tables.records.TBookRecord> aliased) {
this(alias, aliased, null);
}
private TBook(java.lang.String alias, org.jooq.Table<org.jooq.test.oracle4.generatedclasses.tables.records.TBookRecord> aliased, org.jooq.Field<?>[] parameters) {
super(alias, org.jooq.test.oracle4.generatedclasses.Test.TEST, aliased, parameters, "");
}
/**
* {@inheritDoc}
*/
@Override
public org.jooq.UniqueKey<org.jooq.test.oracle4.generatedclasses.tables.records.TBookRecord> getPrimaryKey() {
return org.jooq.test.oracle4.generatedclasses.Keys.PK_T_BOOK;
}
/**
* {@inheritDoc}
*/
@Override
public java.util.List<org.jooq.UniqueKey<org.jooq.test.oracle4.generatedclasses.tables.records.TBookRecord>> getKeys() {
return java.util.Arrays.<org.jooq.UniqueKey<org.jooq.test.oracle4.generatedclasses.tables.records.TBookRecord>>asList(org.jooq.test.oracle4.generatedclasses.Keys.PK_T_BOOK);
}
/**
* {@inheritDoc}
*/
@Override
public java.util.List<org.jooq.ForeignKey<org.jooq.test.oracle4.generatedclasses.tables.records.TBookRecord, ?>> getReferences() {
return java.util.Arrays.<org.jooq.ForeignKey<org.jooq.test.oracle4.generatedclasses.tables.records.TBookRecord, ?>>asList(org.jooq.test.oracle4.generatedclasses.Keys.FK_T_BOOK_AUTHOR_ID);
}
/**
* {@inheritDoc}
*/
@Override
public org.jooq.test.oracle4.generatedclasses.tables.TBook as(java.lang.String alias) {
return new org.jooq.test.oracle4.generatedclasses.tables.TBook(alias, this);
}
/**
* Rename this table
*/
public org.jooq.test.oracle4.generatedclasses.tables.TBook rename(java.lang.String name) {
return new org.jooq.test.oracle4.generatedclasses.tables.TBook(name, null);
}
}

View File

@ -0,0 +1,54 @@
/**
* 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 TBookDao extends org.jooq.impl.DAOImpl<org.jooq.test.oracle4.generatedclasses.tables.records.TBookRecord, org.jooq.test.oracle4.generatedclasses.tables.pojos.TBook, java.lang.Integer> {
/**
* Create a new TBookDao without any configuration
*/
public TBookDao() {
super(org.jooq.test.oracle4.generatedclasses.tables.TBook.T_BOOK, org.jooq.test.oracle4.generatedclasses.tables.pojos.TBook.class);
}
/**
* Create a new TBookDao with an attached configuration
*/
public TBookDao(org.jooq.Configuration configuration) {
super(org.jooq.test.oracle4.generatedclasses.tables.TBook.T_BOOK, org.jooq.test.oracle4.generatedclasses.tables.pojos.TBook.class, configuration);
}
/**
* {@inheritDoc}
*/
@Override
protected java.lang.Integer getId(org.jooq.test.oracle4.generatedclasses.tables.pojos.TBook object) {
return object.getId();
}
/**
* Fetch records that have <code>ID IN (values)</code>
*/
public java.util.List<org.jooq.test.oracle4.generatedclasses.tables.pojos.TBook> fetchById(java.lang.Integer... values) {
return fetch(org.jooq.test.oracle4.generatedclasses.tables.TBook.T_BOOK.ID, values);
}
/**
* Fetch a unique record that has <code>ID = value</code>
*/
public org.jooq.test.oracle4.generatedclasses.tables.pojos.TBook fetchOneById(java.lang.Integer value) {
return fetchOne(org.jooq.test.oracle4.generatedclasses.tables.TBook.T_BOOK.ID, value);
}
/**
* Fetch records that have <code>AUTHOR_ID IN (values)</code>
*/
public java.util.List<org.jooq.test.oracle4.generatedclasses.tables.pojos.TBook> fetchByAuthorId(java.lang.Integer... values) {
return fetch(org.jooq.test.oracle4.generatedclasses.tables.TBook.T_BOOK.AUTHOR_ID, values);
}
}

View File

@ -0,0 +1,49 @@
/**
* This class is generated by jOOQ
*/
package org.jooq.test.oracle4.generatedclasses.tables.pojos;
/**
* This class is generated by jOOQ.
*/
@java.lang.SuppressWarnings({ "all", "unchecked", "rawtypes" })
@javax.persistence.Entity
@javax.persistence.Table(name = "T_BOOK", schema = "TEST")
public class TBook implements java.io.Serializable {
private static final long serialVersionUID = -2023862248;
private java.lang.Integer id;
private java.lang.Integer authorId;
public TBook() {}
public TBook(
java.lang.Integer id,
java.lang.Integer authorId
) {
this.id = id;
this.authorId = authorId;
}
@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;
}
public void setId(java.lang.Integer id) {
this.id = id;
}
@javax.persistence.Column(name = "AUTHOR_ID", nullable = false, precision = 7)
@javax.validation.constraints.NotNull
public java.lang.Integer getAuthorId() {
return this.authorId;
}
public void setAuthorId(java.lang.Integer authorId) {
this.authorId = authorId;
}
}

View File

@ -0,0 +1,159 @@
/**
* This class is generated by jOOQ
*/
package org.jooq.test.oracle4.generatedclasses.tables.records;
/**
* This class is generated by jOOQ.
*/
@java.lang.SuppressWarnings({ "all", "unchecked", "rawtypes" })
@javax.persistence.Entity
@javax.persistence.Table(name = "T_BOOK", schema = "TEST")
public class TBookRecord extends org.jooq.impl.UpdatableRecordImpl<org.jooq.test.oracle4.generatedclasses.tables.records.TBookRecord> implements org.jooq.Record2<java.lang.Integer, java.lang.Integer> {
private static final long serialVersionUID = -718526696;
/**
* Setter for <code>TEST.T_BOOK.ID</code>.
*/
public void setId(java.lang.Integer value) {
setValue(0, value);
}
/**
* Getter for <code>TEST.T_BOOK.ID</code>.
*/
@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);
}
/**
* Setter for <code>TEST.T_BOOK.AUTHOR_ID</code>.
*/
public void setAuthorId(java.lang.Integer value) {
setValue(1, value);
}
/**
* Getter for <code>TEST.T_BOOK.AUTHOR_ID</code>.
*/
@javax.persistence.Column(name = "AUTHOR_ID", nullable = false, precision = 7)
@javax.validation.constraints.NotNull
public java.lang.Integer getAuthorId() {
return (java.lang.Integer) getValue(1);
}
// -------------------------------------------------------------------------
// Primary key information
// -------------------------------------------------------------------------
/**
* {@inheritDoc}
*/
@Override
public org.jooq.Record1<java.lang.Integer> key() {
return (org.jooq.Record1) super.key();
}
// -------------------------------------------------------------------------
// Record2 type implementation
// -------------------------------------------------------------------------
/**
* {@inheritDoc}
*/
@Override
public org.jooq.Row2<java.lang.Integer, java.lang.Integer> fieldsRow() {
return (org.jooq.Row2) super.fieldsRow();
}
/**
* {@inheritDoc}
*/
@Override
public org.jooq.Row2<java.lang.Integer, java.lang.Integer> valuesRow() {
return (org.jooq.Row2) super.valuesRow();
}
/**
* {@inheritDoc}
*/
@Override
public org.jooq.Field<java.lang.Integer> field1() {
return org.jooq.test.oracle4.generatedclasses.tables.TBook.T_BOOK.ID;
}
/**
* {@inheritDoc}
*/
@Override
public org.jooq.Field<java.lang.Integer> field2() {
return org.jooq.test.oracle4.generatedclasses.tables.TBook.T_BOOK.AUTHOR_ID;
}
/**
* {@inheritDoc}
*/
@Override
public java.lang.Integer value1() {
return getId();
}
/**
* {@inheritDoc}
*/
@Override
public java.lang.Integer value2() {
return getAuthorId();
}
/**
* {@inheritDoc}
*/
@Override
public TBookRecord value1(java.lang.Integer value) {
setId(value);
return this;
}
/**
* {@inheritDoc}
*/
@Override
public TBookRecord value2(java.lang.Integer value) {
setAuthorId(value);
return this;
}
/**
* {@inheritDoc}
*/
@Override
public TBookRecord values(java.lang.Integer value1, java.lang.Integer value2) {
return this;
}
// -------------------------------------------------------------------------
// Constructors
// -------------------------------------------------------------------------
/**
* Create a detached TBookRecord
*/
public TBookRecord() {
super(org.jooq.test.oracle4.generatedclasses.tables.TBook.T_BOOK);
}
/**
* Create a detached, initialised TBookRecord
*/
public TBookRecord(java.lang.Integer id, java.lang.Integer authorId) {
super(org.jooq.test.oracle4.generatedclasses.tables.TBook.T_BOOK);
setValue(0, id);
setValue(1, authorId);
}
}