From 1416126a00d7ce8d60d2a2edaff3300e5a3ad2c2 Mon Sep 17 00:00:00 2001 From: brmeyer Date: Tue, 11 Dec 2012 14:00:48 -0500 Subject: [PATCH] HHH-7797 Finished first take on UniqueDelegate and rolled into .cfg and .mapping --- .../java/org/hibernate/cfg/Configuration.java | 14 ++-- .../org/hibernate/dialect/DB2Dialect.java | 5 -- .../dialect/unique/DefaultUniqueDelegate.java | 82 ++++++++++++++---- .../dialect/unique/UniqueDelegate.java | 55 +++++++++++- .../java/org/hibernate/mapping/Table.java | 13 +-- .../java/org/hibernate/mapping/UniqueKey.java | 83 +++++-------------- 6 files changed, 154 insertions(+), 98 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java b/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java index 873f0f2670..ee41efd18e 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java @@ -1045,17 +1045,15 @@ public class Configuration implements Serializable { Table table = (Table) iter.next(); if ( table.isPhysicalTable() ) { - if ( !dialect.supportsUniqueConstraintInCreateAlterTable() ) { - Iterator subIter = table.getUniqueKeyIterator(); - while ( subIter.hasNext() ) { - UniqueKey uk = (UniqueKey) subIter.next(); - String constraintString = uk.sqlCreateString( dialect, mapping, defaultCatalog, defaultSchema ); - if (constraintString != null) script.add( constraintString ); - } + Iterator subIter = table.getUniqueKeyIterator(); + while ( subIter.hasNext() ) { + UniqueKey uk = (UniqueKey) subIter.next(); + String constraintString = uk.sqlCreateString( dialect, mapping, defaultCatalog, defaultSchema ); + if (constraintString != null) script.add( constraintString ); } - Iterator subIter = table.getIndexIterator(); + subIter = table.getIndexIterator(); while ( subIter.hasNext() ) { Index index = (Index) subIter.next(); script.add( diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/DB2Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/DB2Dialect.java index 3bfa7a7695..01f13b7883 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/DB2Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/DB2Dialect.java @@ -30,7 +30,6 @@ import java.sql.Types; import org.hibernate.JDBCException; import org.hibernate.cfg.Environment; -import org.hibernate.dialect.function.AnsiTrimEmulationFunction; import org.hibernate.dialect.function.AvgWithArgumentCastFunction; import org.hibernate.dialect.function.NoArgSQLFunction; import org.hibernate.dialect.function.SQLFunctionTemplate; @@ -279,10 +278,6 @@ public class DB2Dialect extends Dialect { return false; } @Override - public boolean supportsNotNullUnique() { - return false; - } - @Override public boolean supportsExistsInSelect() { return false; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/unique/DefaultUniqueDelegate.java b/hibernate-core/src/main/java/org/hibernate/dialect/unique/DefaultUniqueDelegate.java index dfcc88ae65..a9c8ac33fc 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/unique/DefaultUniqueDelegate.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/unique/DefaultUniqueDelegate.java @@ -21,7 +21,6 @@ package org.hibernate.dialect.unique; import java.util.Iterator; -import java.util.List; import org.hibernate.dialect.Dialect; import org.hibernate.mapping.Column; @@ -43,7 +42,7 @@ public class DefaultUniqueDelegate implements UniqueDelegate { } @Override - public void applyUnique( Table table, Column column, StringBuilder sb ) { + public String applyUniqueToColumn( Table table, Column column ) { // if ( column.isUnique() // && ( column.isNullable() // || dialect.supportsNotNullUnique() ) ) { @@ -61,29 +60,78 @@ public class DefaultUniqueDelegate implements UniqueDelegate { UniqueKey uk = table.getOrCreateUniqueKey( column.getQuotedName( dialect ) + '_' ); uk.addColumn( column ); + return ""; } @Override - public void createUniqueConstraint( Table table, StringBuilder sb ) { + public String applyUniquesToTable( Table table ) { + // TODO: Am I correct that this shouldn't be done unless the constraint + // isn't created in an alter table? +// Iterator uniqueKeyIterator = table.getUniqueKeyIterator(); +// while ( uniqueKeyIterator.hasNext() ) { +// UniqueKey uniqueKey = (UniqueKey) uniqueKeyIterator.next(); +// +// sb.append( ", " ).append( createUniqueConstraint( uniqueKey) ); +// } + return ""; + } + + @Override + public String applyUniquesOnAlter( UniqueKey uniqueKey, + String defaultCatalog, String defaultSchema ) { // if ( dialect.supportsUniqueConstraintInCreateAlterTable() ) { -// Iterator ukiter = getUniqueKeyIterator(); -// while ( ukiter.hasNext() ) { -// UniqueKey uk = (UniqueKey) ukiter.next(); -// String constraint = uk.sqlConstraintString( dialect ); -// if ( constraint != null ) { -// buf.append( ", " ).append( constraint ); -// } -// } +// return super.sqlCreateString( dialect, p, defaultCatalog, defaultSchema ); +// } +// else { +// return Index.buildSqlCreateIndexString( dialect, getName(), getTable(), getColumnIterator(), true, +// defaultCatalog, defaultSchema ); // } - Iterator ukiter = table.getUniqueKeyIterator(); - while ( ukiter.hasNext() ) { - UniqueKey uk = (UniqueKey) ukiter.next(); - String constraint = uk.sqlConstraintString( dialect ); - if ( constraint != null ) { - sb.append( ", " ).append( constraint ); + return new StringBuilder( "alter table " ) + .append( uniqueKey.getTable().getQualifiedName( + dialect, defaultCatalog, defaultSchema ) ) + .append( " add constraint " ) + .append( uniqueKey.getName() ) + .append( uniqueConstraintSql( uniqueKey ) ) + .toString(); + } + + @Override + public String dropUniquesOnAlter( UniqueKey uniqueKey, + String defaultCatalog, String defaultSchema ) { +// if ( dialect.supportsUniqueConstraintInCreateAlterTable() ) { +// return super.sqlDropString( dialect, defaultCatalog, defaultSchema ); +// } +// else { +// return Index.buildSqlDropIndexString( dialect, getTable(), getName(), defaultCatalog, defaultSchema ); +// } + + return new StringBuilder( "alter table " ) + .append( uniqueKey.getTable().getQualifiedName( + dialect, defaultCatalog, defaultSchema ) ) + .append( " drop constraint " ) + .append( dialect.quote( uniqueKey.getName() ) ) + .toString(); + } + + @Override + public String uniqueConstraintSql( UniqueKey uniqueKey ) { + // TODO: This may not be necessary, but not all callers currently + // check it on their own. Go through their logic. +// if ( !isGenerated( dialect ) ) return null; + + StringBuilder sb = new StringBuilder(); + sb.append( " unique (" ); + Iterator columnIterator = uniqueKey.getColumnIterator(); + while ( columnIterator.hasNext() ) { + Column column = (Column) columnIterator.next(); + sb.append( column.getQuotedName( dialect ) ); + if ( columnIterator.hasNext() ) { + sb.append( ", " ); } } + + return sb.append( ')' ).toString(); } } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/unique/UniqueDelegate.java b/hibernate-core/src/main/java/org/hibernate/dialect/unique/UniqueDelegate.java index a173c22c8c..cbe2e19667 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/unique/UniqueDelegate.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/unique/UniqueDelegate.java @@ -22,6 +22,7 @@ package org.hibernate.dialect.unique; import org.hibernate.mapping.Column; import org.hibernate.mapping.Table; +import org.hibernate.mapping.UniqueKey; /** * Dialect-level delegate in charge of applying "uniqueness" to a column. @@ -39,7 +40,57 @@ import org.hibernate.mapping.Table; */ public interface UniqueDelegate { - public void applyUnique( Table table, Column column, StringBuilder sb ); + /** + * If the delegate supports unique constraints, this method should simply + * create the UniqueKey on the Table. Otherwise, the constraint isn't + * supported and "unique" should be added to the column definition. + * + * @param table + * @param column + * @return String + */ + public String applyUniqueToColumn( Table table, Column column ); - public void createUniqueConstraint( Table table, StringBuilder sb ); + /** + * If creating unique constraints in separate alter statements are not + * supported, this method should return the syntax necessary to create + * the constraint on the original create table statement. + * + * @param table + * @return String + */ + public String applyUniquesToTable( Table table ); + + /** + * If creating unique constraints in separate alter statements is + * supported, generate the necessary "alter" syntax for the given key. + * + * @param uniqueKey + * @param defaultCatalog + * @param defaultSchema + * @return String + */ + public String applyUniquesOnAlter( UniqueKey uniqueKey, + String defaultCatalog, String defaultSchema ); + + /** + * If dropping unique constraints in separate alter statements is + * supported, generate the necessary "alter" syntax for the given key. + * + * @param uniqueKey + * @param defaultCatalog + * @param defaultSchema + * @return String + */ + public String dropUniquesOnAlter( UniqueKey uniqueKey, + String defaultCatalog, String defaultSchema ); + + /** + * Generates the syntax necessary to create the unique constraint (reused + * by all methods). Ex: "unique (column1, column2, ...)" + * + * @param uniqueKey + * @return String + */ + public String uniqueConstraintSql( UniqueKey uniqueKey ); } diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Table.java b/hibernate-core/src/main/java/org/hibernate/mapping/Table.java index 3e5d996988..76908b0f1e 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Table.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Table.java @@ -26,7 +26,6 @@ package org.hibernate.mapping; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; @@ -423,7 +422,9 @@ public class Table implements RelationalModel, Serializable { alter.append( " not null" ); } - dialect.getUniqueDelegate().applyUnique( this, column, alter ); + if ( column.isUnique() ) { + alter.append( dialect.getUniqueDelegate().applyUniqueToColumn( this, column ) ); + } if ( column.hasCheckConstraint() && dialect.supportsColumnCheck() ) { alter.append( " check(" ) @@ -520,8 +521,10 @@ public class Table implements RelationalModel, Serializable { } - dialect.getUniqueDelegate().applyUnique( this, col, buf ); - + if ( col.isUnique() ) { + buf.append( dialect.getUniqueDelegate().applyUniqueToColumn( this, col ) ); + } + if ( col.hasCheckConstraint() && dialect.supportsColumnCheck() ) { buf.append( " check (" ) .append( col.getCheckConstraint() ) @@ -543,7 +546,7 @@ public class Table implements RelationalModel, Serializable { .append( getPrimaryKey().sqlConstraintString( dialect ) ); } - dialect.getUniqueDelegate().createUniqueConstraint( this, buf ); + buf.append( dialect.getUniqueDelegate().applyUniquesToTable( this ) ); if ( dialect.supportsTableCheck() ) { Iterator chiter = checkConstraints.iterator(); diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/UniqueKey.java b/hibernate-core/src/main/java/org/hibernate/mapping/UniqueKey.java index 36cd559c6b..4368c7e293 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/UniqueKey.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/UniqueKey.java @@ -22,89 +22,50 @@ * Boston, MA 02110-1301 USA */ package org.hibernate.mapping; -import java.util.Iterator; - import org.hibernate.dialect.Dialect; import org.hibernate.engine.spi.Mapping; /** * A relational unique key constraint * - * @author Gavin King + * @author Brett Meyer */ public class UniqueKey extends Constraint { - public String sqlConstraintString(Dialect dialect) { - // TODO: This may not be necessary, but not all callers currently - // check it on their own. Go through their logic. - if ( !isGenerated( dialect ) ) return null; - - StringBuilder buf = new StringBuilder( "unique (" ); - Iterator iter = getColumnIterator(); - while ( iter.hasNext() ) { - Column column = (Column) iter.next(); - buf.append( column.getQuotedName( dialect ) ); - if ( iter.hasNext() ) { - buf.append( ", " ); - } - } - - return buf.append( ')' ).toString(); - } - @Override public String sqlConstraintString( Dialect dialect, String constraintName, String defaultCatalog, String defaultSchema) { - // TODO: This may not be necessary, but not all callers currently - // check it on their own. Go through their logic. - if ( !isGenerated( dialect ) ) return null; - - StringBuilder buf = new StringBuilder( - dialect.getAddUniqueConstraintString( constraintName ) ).append( '(' ); - Iterator iter = getColumnIterator(); - while ( iter.hasNext() ) { - Column column = (Column) iter.next(); - buf.append( column.getQuotedName( dialect ) ); - if ( iter.hasNext() ) buf.append( ", " ); - } - return buf.append( ')' ).toString(); + return dialect.getUniqueDelegate().uniqueConstraintSql( this ); } @Override - public String sqlCreateString(Dialect dialect, Mapping p, String defaultCatalog, String defaultSchema) { - if ( dialect.supportsUniqueConstraintInCreateAlterTable() ) { - return super.sqlCreateString( dialect, p, defaultCatalog, defaultSchema ); - } - else { - return Index.buildSqlCreateIndexString( dialect, getName(), getTable(), getColumnIterator(), true, - defaultCatalog, defaultSchema ); - } + public String sqlCreateString(Dialect dialect, Mapping p, + String defaultCatalog, String defaultSchema) { + return dialect.getUniqueDelegate().applyUniquesOnAlter( + this, defaultCatalog, defaultSchema ); } @Override - public String sqlDropString(Dialect dialect, String defaultCatalog, String defaultSchema) { - if ( dialect.supportsUniqueConstraintInCreateAlterTable() ) { - return super.sqlDropString( dialect, defaultCatalog, defaultSchema ); - } - else { - return Index.buildSqlDropIndexString( dialect, getTable(), getName(), defaultCatalog, defaultSchema ); - } + public String sqlDropString(Dialect dialect, String defaultCatalog, + String defaultSchema) { + return dialect.getUniqueDelegate().dropUniquesOnAlter( + this, defaultCatalog, defaultSchema ); } - @Override - public boolean isGenerated(Dialect dialect) { - if ( !dialect.supportsUniqueConstraintInCreateAlterTable() ) return false; - if ( dialect.supportsNotNullUnique() ) return true; - - Iterator iter = getColumnIterator(); - while ( iter.hasNext() ) { - // Dialect does not support "not null unique" and this column is not null. - if ( ! ( (Column) iter.next() ).isNullable() ) return false; - } - return true; - } +// @Override +// public boolean isGenerated(Dialect dialect) { +// if ( !dialect.supportsUniqueConstraintInCreateAlterTable() ) return false; +// if ( dialect.supportsNotNullUnique() ) return true; +// +// Iterator iter = getColumnIterator(); +// while ( iter.hasNext() ) { +// // Dialect does not support "not null unique" and this column is not null. +// if ( ! ( (Column) iter.next() ).isNullable() ) return false; +// } +// return true; +// } }