Feature Request: ON UPDATE CASCADE

View: New views
8 Messages — Rating Filter:   Alert me  

Feature Request: ON UPDATE CASCADE

by Sky Splawn :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

not sure if this belongs in devel or user, my apologies in advance if I am in error.

Sky:~/Desktop/downloads/liquibase-1.5.2/src inverse$ grep -r 'CASCADE' *
liquibase/core/src/java/liquibase/database/sql/.svn/text-base/AddForeignKeyConstraintStatement.java.svn-base:            sql += " ON DELETE CASCADE";
liquibase/core/src/java/liquibase/database/sql/.svn/text-base/CreateTableStatement.java.svn-base:                buffer.append(" ON DELETE CASCADE");
liquibase/core/src/java/liquibase/database/sql/.svn/text-base/DropSequenceStatement.java.svn-base:            sql += " CASCADE";
liquibase/core/src/java/liquibase/database/sql/.svn/text-base/DropTableStatement.java.svn-base:                buffer.append(" CASCADE CONSTRAINTS");
liquibase/core/src/java/liquibase/database/sql/.svn/text-base/DropTableStatement.java.svn-base:                buffer.append(" CASCADE");
liquibase/core/src/java/liquibase/database/sql/AddForeignKeyConstraintStatement.java:            sql += " ON DELETE CASCADE";
liquibase/core/src/java/liquibase/database/sql/CreateTableStatement.java:                buffer.append(" ON DELETE CASCADE");
liquibase/core/src/java/liquibase/database/sql/DropSequenceStatement.java:            sql += " CASCADE";
liquibase/core/src/java/liquibase/database/sql/DropTableStatement.java:                buffer.append(" CASCADE CONSTRAINTS");
liquibase/core/src/java/liquibase/database/sql/DropTableStatement.java:                buffer.append(" CASCADE");            

Are there any plans to support "ON UPDATE CASCADE"?
We use this in a lot of our foreign key constraints, and I am currently evaluating liquibase for use in our processes.

Thank you.







-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Liquibase-devel mailing list
Liquibase-devel@...
https://lists.sourceforge.net/lists/listinfo/liquibase-devel

Re: Feature Request: ON UPDATE CASCADE

by Voxland, Nathan :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Some parts of this message have been removed. Learn more about Nabble's security policy.

I think either list would be fine.

 

There currently is no plan to add ON UPDATE CASCADE, but that is mainly due to a lack of requests, it would not be difficult to add.  I’ll add it to the tracker so it doesn’t get lost. 

 

I can probably have it added in 1.6 (currently unknown release date, probably mid-late march).  Until then you can always use the <sql> tag to specify sql features not currently supported by LiquiBase.

 

Nathan

 

From: liquibase-devel-bounces@... [mailto:liquibase-devel-bounces@...] On Behalf Of Sky Splawn
Sent: Friday, February 29, 2008 11:29 AM
To: liquibase-devel@...
Subject: [Liquibase-devel] Feature Request: ON UPDATE CASCADE

 

not sure if this belongs in devel or user, my apologies in advance if I am in error.

 

Sky:~/Desktop/downloads/liquibase-1.5.2/src inverse$ grep -r 'CASCADE' *

liquibase/core/src/java/liquibase/database/sql/.svn/text-base/AddForeignKeyConstraintStatement.java.svn-base:            sql += " ON DELETE CASCADE";

liquibase/core/src/java/liquibase/database/sql/.svn/text-base/CreateTableStatement.java.svn-base:                buffer.append(" ON DELETE CASCADE");

liquibase/core/src/java/liquibase/database/sql/.svn/text-base/DropSequenceStatement.java.svn-base:            sql += " CASCADE";

liquibase/core/src/java/liquibase/database/sql/.svn/text-base/DropTableStatement.java.svn-base:                buffer.append(" CASCADE CONSTRAINTS");

liquibase/core/src/java/liquibase/database/sql/.svn/text-base/DropTableStatement.java.svn-base:                buffer.append(" CASCADE");

liquibase/core/src/java/liquibase/database/sql/AddForeignKeyConstraintStatement.java:            sql += " ON DELETE CASCADE";

liquibase/core/src/java/liquibase/database/sql/CreateTableStatement.java:                buffer.append(" ON DELETE CASCADE");

liquibase/core/src/java/liquibase/database/sql/DropSequenceStatement.java:            sql += " CASCADE";

liquibase/core/src/java/liquibase/database/sql/DropTableStatement.java:                buffer.append(" CASCADE CONSTRAINTS");

liquibase/core/src/java/liquibase/database/sql/DropTableStatement.java:                buffer.append(" CASCADE");            

 

Are there any plans to support "ON UPDATE CASCADE"?

We use this in a lot of our foreign key constraints, and I am currently evaluating liquibase for use in our processes.

 

Thank you.

 

 

 

 

 

 


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Liquibase-devel mailing list
Liquibase-devel@...
https://lists.sourceforge.net/lists/listinfo/liquibase-devel

Re: Feature Request: ON UPDATE CASCADE

by Christian Maslen :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Voxland, Nathan wrote:
There currently is no plan to add ON UPDATE CASCADE, but that is mainly
due to a lack of requests, it would not be difficult to add.  I'll add
it to the tracker so it doesn't get lost.  
Are there any plans for restrict? I target DB2. Our FKs are generally done as follows:

ALTER TABLE schema.base_table_name
  ADD CONSTRAINT FK_constraint_name FOREIGN KEY
    (base table column list)
  REFERENCES schema.ref_table_name
    (ref table column list)
    ON DELETE RESTRICT
    ON UPDATE RESTRICT

If not supported now should I use a custom SQL for this?

Regards,
Christian

Re: Feature Request: ON UPDATE CASCADE

by Voxland, Nathan :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

No plans for restrict either.  There are so many options and variations
that it is impossible to cover them all.  The custom sql will work just
fine for you, though.  The fact that we can't cover everything in the
general statement tags is a big reason why there is an <sql> tag.

An option I thought of the other day is to add an additional tag option
to most of the sql to allow you to put whatever you want.

For example:

<addForeignKeyConstraint foreignKeyName="fk_constraint_name"
tableName="base_table_name" baseColumnNames="ref_id"
referencedTableName="ref_table_name" referencedColumnNames="id">
        <append dbms="db2">ON DELETE RESTRICT ON UPDATE
RESTRICT</append>
        <append dbms="oracle">ON UPDATE CASCADE</append>
</addForeignKeyConstraint>

Or

<createTable tableName="sample">
        <column name="id" dataType="int"/>
        <column name="name" dataType="int>
                <append>on delete cascade</append>
        </column>
        <append dbms="mysql">ENGINE MYISAM</append>
</createTable>

Anyone have thoughts on this features?

Nathan

-----Original Message-----
From: liquibase-devel-bounces@...
[mailto:liquibase-devel-bounces@...] On Behalf Of
Christian Maslen
Sent: Monday, June 30, 2008 8:47 PM
To: liquibase-devel@...
Subject: Re: [Liquibase-devel] Feature Request: ON UPDATE CASCADE



Voxland, Nathan wrote:
>
> There currently is no plan to add ON UPDATE CASCADE, but that is
mainly
> due to a lack of requests, it would not be difficult to add.  I'll add
> it to the tracker so it doesn't get lost.  
>

Are there any plans for restrict? I target DB2. Our FKs are generally
done
as follows:

ALTER TABLE schema.base_table_name
  ADD CONSTRAINT FK_constraint_name FOREIGN KEY
    (base table column list)
  REFERENCES schema.ref_table_name
    (ref table column list)
    ON DELETE RESTRICT
    ON UPDATE RESTRICT

If not supported now should I use a custom SQL for this?

Regards,
Christian

--
View this message in context:
http://www.nabble.com/Feature-Request%3A-ON-UPDATE-CASCADE-tp15763444p18
207735.html
Sent from the LiquiBase - Development mailing list archive at
Nabble.com.


------------------------------------------------------------------------
-
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
Liquibase-devel mailing list
Liquibase-devel@...
https://lists.sourceforge.net/lists/listinfo/liquibase-devel

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
Liquibase-devel mailing list
Liquibase-devel@...
https://lists.sourceforge.net/lists/listinfo/liquibase-devel

Parent Message unknown Re: Feature Request: ON UPDATE CASCADE

by Alexandr Popov-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Voxland, Nathan wrote:
> No plans for restrict either.  There are so many options and variations
> that it is impossible to cover them all.  The custom sql will work just
> fine for you, though.  The fact that we can't cover everything in the
> general statement tags is a big reason why there is an <sql> tag.
>
> An option I thought of the other day is to add an additional tag option
> to most of the sql to allow you to put whatever you want.
>

There is a "small" problem. If it's forward script it's ok but if it's a reverse ? current
version does not read any info about "on update" and "on delete" actions.

I've almost finished implementation of "on update" and "on delete" functionality hope
within 2 week to post changes so they can be added to liquibase.


--
Alexandr Popov

-------------------------------------------------------------------------
Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW!
Studies have shown that voting for your favorite open source project,
along with a healthy diet, reduces your potential for chronic lameness
and boredom. Vote Now at http://www.sourceforge.net/community/cca08
_______________________________________________
Liquibase-devel mailing list
Liquibase-devel@...
https://lists.sourceforge.net/lists/listinfo/liquibase-devel

Re: Feature Request: ON UPDATE CASCADE

by Christian Maslen :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Voxland, Nathan wrote:
No plans for restrict either.  There are so many options and variations
that it is impossible to cover them all.  The custom sql will work just
fine for you, though.  The fact that we can't cover everything in the
general statement tags is a big reason why there is an <sql> tag.

An option I thought of the other day is to add an additional tag option
to most of the sql to allow you to put whatever you want.

For example:

<addForeignKeyConstraint foreignKeyName="fk_constraint_name"
tableName="base_table_name" baseColumnNames="ref_id"
referencedTableName="ref_table_name" referencedColumnNames="id">
        <append dbms="db2">ON DELETE RESTRICT ON UPDATE
RESTRICT</append>
        <append dbms="oracle">ON UPDATE CASCADE</append>
</addForeignKeyConstraint>

Or

<createTable tableName="sample">
        <column name="id" dataType="int"/>
        <column name="name" dataType="int>
                <append>on delete cascade</append>
        </column>
        <append dbms="mysql">ENGINE MYISAM</append>
</createTable>

Anyone have thoughts on this features?
I like both of these samples. I can see the append option at the column level to be a very handy way for me to save even more custom sql. An immediate example (again from DB2) is being able to add generated column values inside the CreateTable's column tag. In a create table statement all you need to generate is the following:

create table tbl_name(
  col1 varchar(100) not null,
  col1_upper varchar(100) not null generated always as ( upper( col1 ) )
...
);

If you had to do this as a later script you end up with...
create table tbl_name(
  col1 varchar(100) not null,
  col1_upper varchar(100) not null
...
);

set integrity for tbl_name off;

alter table tbl_name
alter column col1_upper set
generated always as ( upper ( broker_name ) );

set integrity for tbl_name immediate checked
force generated;

Regards,
Christian Maslen

Re: Feature Request: ON UPDATE CASCADE

by Voxland, Nathan :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

You are right that auto-generated rollback script would not know what to do.  The best option is always to add direct support for functionality in the XML itself, but there will always be SQL oddities that we will not (and should not) handle.  On update and on delete are examples of things that should be supported in the XML, the "generated always as ( upper( col1 ) )" example is an example of something we should probably not add direct support for.

To be safe, we may want to turn off auto-rollback statement generation for statements that have custom SQL blocks appended.

Nathan

-----Original Message-----
From: liquibase-devel-bounces@... [mailto:liquibase-devel-bounces@...] On Behalf Of Alexandr Popov
Sent: Tuesday, July 01, 2008 11:46 AM
To: liquibase-devel@...
Subject: Re: [Liquibase-devel] Feature Request: ON UPDATE CASCADE

Voxland, Nathan wrote:
> No plans for restrict either.  There are so many options and variations
> that it is impossible to cover them all.  The custom sql will work just
> fine for you, though.  The fact that we can't cover everything in the
> general statement tags is a big reason why there is an <sql> tag.
>
> An option I thought of the other day is to add an additional tag option
> to most of the sql to allow you to put whatever you want.
>

There is a "small" problem. If it's forward script it's ok but if it's a reverse ? current
version does not read any info about "on update" and "on delete" actions.

I've almost finished implementation of "on update" and "on delete" functionality hope
within 2 week to post changes so they can be added to liquibase.


--
Alexandr Popov

-------------------------------------------------------------------------
Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW!
Studies have shown that voting for your favorite open source project,
along with a healthy diet, reduces your potential for chronic lameness
and boredom. Vote Now at http://www.sourceforge.net/community/cca08
_______________________________________________
Liquibase-devel mailing list
Liquibase-devel@...
https://lists.sourceforge.net/lists/listinfo/liquibase-devel
-------------------------------------------------------------------------
Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW!
Studies have shown that voting for your favorite open source project,
along with a healthy diet, reduces your potential for chronic lameness
and boredom. Vote Now at http://www.sourceforge.net/community/cca08
_______________________________________________
Liquibase-devel mailing list
Liquibase-devel@...
https://lists.sourceforge.net/lists/listinfo/liquibase-devel

Re: Feature Request: ON UPDATE CASCADE

by Alexandr Popov-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wednesday 02 July 2008 19:58:29 Voxland, Nathan wrote:

Finally i found time to finish adding "ON UPDATE" and "ON DELETE" to foreign key statement details can be found in attached patch.

In this patch.
1. added on delete and on update statements for FK constraints.
2. added unique for "createIndex" (before was missing).

Also was found some minor problems.
1. There is no support for unique constraints. (in the source code i found some implementation but is was commented out).
2. There is no support for escaping constraints name, indexes name.

And now some questions.
May be it will be more reasonable to move methods that read DDL (readIndexes, readFK,etc..) from SqlDatabaseSnapshot  to AbstractDatabase and allow
in implementation to write specific procedures for reading DDL specific to each DB.


--
With best regards,
Alexandr Popov

[liquibase_20080711.patch]

Index: src/java-test/liquibase/database/sql/DropIndexStatementTest.java
===================================================================
--- src/java-test/liquibase/database/sql/DropIndexStatementTest.java (revision 690)
+++ src/java-test/liquibase/database/sql/DropIndexStatementTest.java (working copy)
@@ -14,6 +14,7 @@
     private static final String COLUMN_NAME = "colName";
     private static final String IDX_NAME = "idx_dropindextest";
     private static final String ALT_IDX_NAME = "idx_altdindextest";
+    private static final Boolean IS_UNIQUE = true;
 
     protected void setupDatabase(Database database) throws Exception {
         dropAndCreateTable(new CreateTableStatement(null, TABLE_NAME)
@@ -21,7 +22,7 @@
                 .addColumn(COLUMN_NAME, "varchar(50)", new NotNullConstraint())
                 , database);
 
-        new JdbcTemplate(database).execute(new CreateIndexStatement(IDX_NAME, null, TABLE_NAME, COLUMN_NAME));
+        new JdbcTemplate(database).execute(new CreateIndexStatement(IDX_NAME, null, TABLE_NAME, IS_UNIQUE, COLUMN_NAME));
 
         dropAndCreateTable(new CreateTableStatement(TestContext.ALT_SCHEMA, TABLE_NAME)
                 .addPrimaryKeyColumn("id", "int", null)
@@ -29,7 +30,7 @@
                 , database);
 
         if (database.supportsSchemas()) {
-            new JdbcTemplate(database).execute(new CreateIndexStatement(ALT_IDX_NAME, TestContext.ALT_SCHEMA, TABLE_NAME, COLUMN_NAME));
+            new JdbcTemplate(database).execute(new CreateIndexStatement(ALT_IDX_NAME, TestContext.ALT_SCHEMA, TABLE_NAME, IS_UNIQUE, COLUMN_NAME));
         }
     }
 
Index: src/java-test/liquibase/database/sql/CreateIndexStatementTest.java
===================================================================
--- src/java-test/liquibase/database/sql/CreateIndexStatementTest.java (revision 690)
+++ src/java-test/liquibase/database/sql/CreateIndexStatementTest.java (working copy)
@@ -13,6 +13,7 @@
     private static final String INDEX_NAME = "IDX_CreateIndexTest";
     private static final String COLUMN_NAME = "testCol";
     private static final String COLUMN_NAME2 = "testCol2";
+    private static final Boolean IS_UNIQUE = true;
 
     protected void setupDatabase(Database database) throws Exception {
             dropAndCreateTable(new CreateTableStatement(null, TABLE_NAME)
@@ -28,7 +29,7 @@
     }
 
     protected CreateIndexStatement generateTestStatement() {
-        return new CreateIndexStatement(null, null, null);
+        return new CreateIndexStatement(null, null, null, null);
     }
 
     @Test
@@ -34,7 +35,7 @@
     @Test
     public void execute_singleColumnDefaultSchema() throws Exception {
         new DatabaseTestTemplate().testOnAvailableDatabases(
-                new SqlStatementDatabaseTest(null, new CreateIndexStatement(INDEX_NAME, null, TABLE_NAME, COLUMN_NAME)) {
+                new SqlStatementDatabaseTest(null, new CreateIndexStatement(INDEX_NAME, null, TABLE_NAME, IS_UNIQUE, COLUMN_NAME)) {
 
                     protected void preExecuteAssert(DatabaseSnapshot snapshot) {
                         assertNull(snapshot.getIndex(INDEX_NAME));
@@ -50,7 +51,7 @@
     @Test
     public void execute_alternateSchema() throws Exception {
         new DatabaseTestTemplate().testOnAvailableDatabases(
-                new SqlStatementDatabaseTest(TestContext.ALT_SCHEMA, new CreateIndexStatement(INDEX_NAME, TestContext.ALT_SCHEMA, TABLE_NAME, COLUMN_NAME)) {
+                new SqlStatementDatabaseTest(TestContext.ALT_SCHEMA, new CreateIndexStatement(INDEX_NAME, TestContext.ALT_SCHEMA, TABLE_NAME, IS_UNIQUE, COLUMN_NAME)) {
 
                     protected void preExecuteAssert(DatabaseSnapshot snapshot) {
                         assertNull(snapshot.getIndex(INDEX_NAME));
@@ -68,7 +69,7 @@
     @Test
     public void execute_alternateTablespace() throws Exception {
         new DatabaseTestTemplate().testOnAvailableDatabases(
-                new SqlStatementDatabaseTest(null, new CreateIndexStatement(INDEX_NAME, null, TABLE_NAME, COLUMN_NAME).setTablespace(TestContext.ALT_TABLESPACE)) {
+                new SqlStatementDatabaseTest(null, new CreateIndexStatement(INDEX_NAME, null, TABLE_NAME, IS_UNIQUE, COLUMN_NAME).setTablespace(TestContext.ALT_TABLESPACE)) {
                     protected void preExecuteAssert(DatabaseSnapshot snapshot) {
                         assertNull(snapshot.getIndex(INDEX_NAME));
                     }
@@ -84,7 +85,7 @@
     @Test
     public void execute_multiColumnDefaultSchema() throws Exception {
         new DatabaseTestTemplate().testOnAvailableDatabases(
-                new SqlStatementDatabaseTest(null, new CreateIndexStatement(INDEX_NAME, null, TABLE_NAME, COLUMN_NAME, COLUMN_NAME2)) {
+                new SqlStatementDatabaseTest(null, new CreateIndexStatement(INDEX_NAME, null, TABLE_NAME, IS_UNIQUE, COLUMN_NAME, COLUMN_NAME2)) {
 
                     protected void preExecuteAssert(DatabaseSnapshot snapshot) {
                         assertNull(snapshot.getIndex(INDEX_NAME));
Index: src/java/liquibase/database/sql/AddForeignKeyConstraintStatement.java
===================================================================
--- src/java/liquibase/database/sql/AddForeignKeyConstraintStatement.java (revision 690)
+++ src/java/liquibase/database/sql/AddForeignKeyConstraintStatement.java (working copy)
@@ -1,5 +1,7 @@
 package liquibase.database.sql;
 
+import java.sql.DatabaseMetaData;
+
 import liquibase.database.Database;
 import liquibase.database.SQLiteDatabase;
 import liquibase.exception.StatementNotSupportedOnDatabaseException;
@@ -20,6 +22,8 @@
     private boolean initiallyDeferred;
 
     private boolean deleteCascade;
+    private Integer deleteRule;
+    private Integer updateRule;
 
     public AddForeignKeyConstraintStatement(String constraintName, String baseTableSchemaName, String baseTableName, String baseColumnNames, String referencedTableSchemaName, String referencedTableName, String referencedColumnNames) {
         this.baseTableSchemaName = baseTableSchemaName;
@@ -85,6 +89,16 @@
         this.deleteCascade = deleteCascade;
         return this;
     }
+    public AddForeignKeyConstraintStatement setUpdateRule(Integer updateRule)
+    {
+      this.updateRule = updateRule;
+      return this;
+    }
+    public AddForeignKeyConstraintStatement setDeleteRule(Integer deleteRule)
+    {
+      this.deleteRule = deleteRule;
+      return this;
+    }
 
     public String getSqlStatement(Database database) throws StatementNotSupportedOnDatabaseException {
      if (!supportsDatabase(database)) {
@@ -93,8 +107,54 @@
     
         String sql = "ALTER TABLE " + database.escapeTableName(getBaseTableSchemaName(), getBaseTableName()) + " ADD CONSTRAINT " + getConstraintName() + " FOREIGN KEY (" + database.escapeColumnNameList(getBaseColumnNames()) + ") REFERENCES " + database.escapeTableName(getReferencedTableSchemaName(), getReferencedTableName()) + "(" + database.escapeColumnNameList(getReferencedColumnNames()) + ")";
 
-        if (isDeleteCascade()) {
-            sql += " ON DELETE CASCADE";
+//        if (isDeleteCascade()) {
+//            sql += " ON DELETE CASCADE";
+//        }
+        if (this.updateRule != null)
+        {
+          switch (this.updateRule.intValue())
+          {
+            case DatabaseMetaData.importedKeyCascade :
+              sql += " ON UPDATE CASCADE";
+              break;
+            case DatabaseMetaData.importedKeySetNull :
+              sql += " ON UPDATE SET NULL";
+              break;
+            case DatabaseMetaData.importedKeySetDefault :
+              sql += " ON UPDATE SET DEFAULT";
+              break;
+            case DatabaseMetaData.importedKeyRestrict :
+              sql += " ON UPDATE RESTRICT";
+              break;
+            case DatabaseMetaData.importedKeyNoAction :
+              sql += " ON UPDATE NO ACTION";
+              break;
+            default :
+              break;
+          }
+        }
+        if (this.deleteRule != null)
+        {
+          switch (this.deleteRule.intValue())
+          {
+            case DatabaseMetaData.importedKeyCascade :
+              sql += " ON DELETE CASCADE";
+              break;
+            case DatabaseMetaData.importedKeySetNull :
+              sql += " ON DELETE SET NULL";
+              break;
+            case DatabaseMetaData.importedKeySetDefault :
+              sql += " ON DELETE SET DEFAULT";
+              break;
+            case DatabaseMetaData.importedKeyRestrict :
+              sql += " ON DELETE RESTRICT";
+              break;
+            case DatabaseMetaData.importedKeyNoAction :
+              sql += " ON DELETE NO ACTION";
+              break;
+            default :
+              break;
+          }
         }
 
         if (isDeferrable() || isInitiallyDeferred()) {
Index: src/java/liquibase/database/sql/CreateIndexStatement.java
===================================================================
--- src/java/liquibase/database/sql/CreateIndexStatement.java (revision 690)
+++ src/java/liquibase/database/sql/CreateIndexStatement.java (working copy)
@@ -16,8 +16,9 @@
     private String tableName;
     private String[] columns;
     private String tablespace;
+    private Boolean isUnique;
 
-    public CreateIndexStatement(String indexName, String tableSchemaName, String tableName, String... columns) {
+    public CreateIndexStatement(String indexName, String tableSchemaName, String tableName, Boolean isUnique, String... columns) {
         this.indexName = indexName;
         this.tableSchemaName = tableSchemaName;
         this.tableName = tableName;
@@ -22,6 +23,7 @@
         this.tableSchemaName = tableSchemaName;
         this.tableName = tableName;
         this.columns = columns;
+        this.isUnique = isUnique;
     }
 
     public String getTableSchemaName() {
@@ -52,7 +54,12 @@
 
     public String getSqlStatement(Database database) throws StatementNotSupportedOnDatabaseException {
    StringBuffer buffer = new StringBuffer();
-        buffer.append("CREATE INDEX ");
+        
+        buffer.append("CREATE ");
+        if (this.isUnique.booleanValue())
+          buffer.append("UNIQUE ");
+        buffer.append("INDEX ");
+        
         buffer.append(getIndexName()).append(" ON ");
         buffer.append(database.escapeTableName(getTableSchemaName(), getTableName())).append("(");
         Iterator<String> iterator = Arrays.asList(getColumns()).iterator();
Index: src/java/liquibase/database/structure/SqlDatabaseSnapshot.java
===================================================================
--- src/java/liquibase/database/structure/SqlDatabaseSnapshot.java (revision 690)
+++ src/java/liquibase/database/structure/SqlDatabaseSnapshot.java (working copy)
@@ -345,7 +345,19 @@
                 fkInfo.addForeignKeyColumn(fkColumn);
 
                 fkInfo.setName(rs.getString("FK_NAME"));
-
+                
+                Integer updateRule, deleteRule;
+                updateRule = new Integer(rs.getInt("UPDATE_RULE"));
+                if (rs.wasNull())
+                  updateRule = null;
+                deleteRule = new Integer(rs.getInt("DELETE_RULE"));
+                if (rs.wasNull())
+                {
+                  deleteRule = null;
+                }
+                fkInfo.setUpdateRule(updateRule);
+                fkInfo.setDeleteRule(deleteRule);
+                
                 if (database.supportsInitiallyDeferrableColumns()) {
                     short deferrablility = rs.getShort("DEFERRABILITY");
                     if (deferrablility == DatabaseMetaData.importedKeyInitiallyDeferred) {
@@ -389,6 +401,7 @@
                 String indexName = rs.getString("INDEX_NAME");
                 short type = rs.getShort("TYPE");
 //                String tableName = rs.getString("TABLE_NAME");
+                boolean nonUnique = rs.getBoolean("NON_UNIQUE");
                 String columnName = rs.getString("COLUMN_NAME");
                 short position = rs.getShort("ORDINAL_POSITION");
                 String filterCondition = rs.getString("FILTER_CONDITION");
@@ -411,6 +424,7 @@
                     indexInformation = new Index();
                     indexInformation.setTable(table);
                     indexInformation.setName(indexName);
+                    indexInformation.setIsUnique(new Boolean(!nonUnique));
                     indexInformation.setFilterCondition(filterCondition);
                     indexMap.put(indexName, indexInformation);
                 }
Index: src/java/liquibase/database/structure/ForeignKey.java
===================================================================
--- src/java/liquibase/database/structure/ForeignKey.java (revision 690)
+++ src/java/liquibase/database/structure/ForeignKey.java (working copy)
@@ -14,6 +14,9 @@
     private boolean deferrable;
     private boolean initiallyDeferred;
 
+    private Integer updateRule;
+    private Integer deleteRule;
+    
 
     public Table getPrimaryKeyTable() {
         return primaryKeyTable;
@@ -97,7 +100,26 @@
     public void setInitiallyDeferred(boolean initiallyDeferred) {
         this.initiallyDeferred = initiallyDeferred;
     }
+    
+    public void setUpdateRule (Integer rule)
+    {
+      this.updateRule = rule;
+    }
+    
+    public Integer getUpdateRule ()
+    {
+      return this.updateRule;
+    }
 
+    public void setDeleteRule (Integer rule)
+    {
+      this.deleteRule = rule;
+    }
+    public Integer getDeleteRule ()
+    {
+      return this.deleteRule;
+    }
+    
     public boolean equals(Object o) {
         if (this == o) return true;
         if (o == null || getClass() != o.getClass()) return false;
@@ -106,8 +128,11 @@
 
         return getForeignKeyColumns().equalsIgnoreCase(that.getForeignKeyColumns())
                 && foreignKeyTable.equals(that.foreignKeyTable)
+                && this.name.equalsIgnoreCase(that.getName())
                 && getPrimaryKeyColumns().equalsIgnoreCase(that.getPrimaryKeyColumns())
-                && primaryKeyTable.equals(that.primaryKeyTable);
+                && primaryKeyTable.equals(that.primaryKeyTable)
+                && this.updateRule.equals(that.getUpdateRule())
+                && this.deleteRule.equals(that.getDeleteRule());
 
     }
 
@@ -116,6 +141,9 @@
         if (primaryKeyTable != null) {
             result = primaryKeyTable.hashCode();
         }
+        if (this.name != null) {
+          result = 31 * result + this.name.toUpperCase().hashCode();
+        }
 
         if (primaryKeyColumns != null) {
             result = 31 * result + primaryKeyColumns.toUpperCase().hashCode();
@@ -128,7 +156,12 @@
         if (foreignKeyColumns != null) {
             result = 31 * result + foreignKeyColumns.toUpperCase().hashCode();
         }
-
+        if (this.updateRule != null)
+          result = 31*result +this.updateRule.hashCode();
+        if (this.deleteRule != null)
+          result = 31*result +this.deleteRule.hashCode();
+      
+        
         return result;
     }
 
@@ -138,11 +171,12 @@
         if (this.getForeignKeyTable() != null && o.getForeignKeyTable() != null) {
             returnValue = this.getForeignKeyTable().compareTo(o.getForeignKeyTable());
         }
-
         if (returnValue == 0 && this.getForeignKeyColumns() != null && o.getForeignKeyColumns() != null) {
             returnValue = this.getForeignKeyColumns().compareTo(o.getForeignKeyColumns());
         }
-
+        if (returnValue == 0 && this.getName() != null && o.getName() != null) {
+          returnValue = this.getName().compareTo(o.getName());
+        }
         if (returnValue == 0 && this.getPrimaryKeyTable() != null && o.getPrimaryKeyTable() != null) {
             returnValue = this.getPrimaryKeyTable().compareTo(o.getPrimaryKeyTable());
         }
@@ -150,7 +184,10 @@
         if (returnValue == 0 && this.getPrimaryKeyColumns() != null && o.getPrimaryKeyColumns() != null) {
             returnValue = this.getPrimaryKeyColumns().compareTo(o.getPrimaryKeyColumns());
         }
-
+        if (returnValue == 0 && this.updateRule != null && o.getUpdateRule() != null)
+          returnValue = this.updateRule.compareTo(o.getUpdateRule());
+        if (returnValue == 0 && this.deleteRule != null && o.getDeleteRule() != null)
+          returnValue = this.deleteRule.compareTo(o.getDeleteRule());
         return returnValue;
     }
     
Index: src/java/liquibase/database/structure/Index.java
===================================================================
--- src/java/liquibase/database/structure/Index.java (revision 690)
+++ src/java/liquibase/database/structure/Index.java (working copy)
@@ -8,6 +8,7 @@
 public class Index implements DatabaseObject, Comparable<Index> {
     private String name;
     private Table table;
+    private Boolean isUnique;
     private List<String> columns = new ArrayList<String>();
     private String filterCondition;
 
@@ -44,6 +45,16 @@
         this.filterCondition = filterCondition;
     }
 
+    public void setIsUnique (Boolean value)
+    {
+      this.isUnique = value;
+    }
+    
+    public Boolean getIsUnique()
+    {
+      return this.isUnique;
+    }
+    
     public boolean equals(Object o) {
         if (this == o) return true;
         if (o == null || getClass() != o.getClass()) return false;
@@ -55,7 +66,11 @@
                 equals = false;
             }
         }
-
+        if (this.isUnique != index.getIsUnique())
+        {
+          equals = false;
+        }
+          
         return equals && table.getName().equalsIgnoreCase(index.table.getName());
 
     }
@@ -64,6 +79,7 @@
         int result;
         result = table.getName().toUpperCase().hashCode();
         result = 31 * result + columns.hashCode();
+        result = 31 * result + (this.isUnique.booleanValue() ? 1 : 0);
         return result;
     }
 
@@ -85,7 +101,10 @@
 
     public String toString() {
         StringBuffer stringBuffer = new StringBuffer();
-        stringBuffer.append(getName()).append(" on ").append(table.getName()).append("(");
+        stringBuffer.append(getName());
+        if (!this.isUnique.booleanValue())
+          stringBuffer.append(" unique ");
+        stringBuffer.append(" on ").append(table.getName()).append("(");
         for (String column : columns) {
             stringBuffer.append(column).append(", ");
         }
Index: src/java/liquibase/database/SQLiteDatabase.java
===================================================================
--- src/java/liquibase/database/SQLiteDatabase.java (revision 690)
+++ src/java/liquibase/database/SQLiteDatabase.java (working copy)
@@ -226,6 +226,7 @@
  statements.add(new CreateIndexStatement(
  index_config.getName(),
  schemaName,tableName,
+ index_config.getIsUnique(),
  index_config.getColumns().
  toArray(new String[index_config.getColumns().size()])));
  }
Index: src/java/liquibase/dbchangelog-1.8.xsd
===================================================================
--- src/java/liquibase/dbchangelog-1.8.xsd (revision 690)
+++ src/java/liquibase/dbchangelog-1.8.xsd (working copy)
@@ -176,6 +176,7 @@
     <xsd:attributeGroup name="createIndex">
         <xsd:attributeGroup ref="tableNameAttribute"/>
         <xsd:attributeGroup ref="indexName"/>
+        <xsd:attribute name="isUnique" type="xsd:boolean"/>
     </xsd:attributeGroup>
 
 
@@ -291,6 +292,8 @@
         <xsd:attribute name="deferrable" type="xsd:boolean"/>
         <xsd:attribute name="initiallyDeferred" type="xsd:boolean"/>
         <xsd:attribute name="deleteCascade" type="xsd:boolean"/>
+        <xsd:attribute name="onDelete" type="xsd:string"/>
+        <xsd:attribute name="onUpdate" type="xsd:string"/>
     </xsd:attributeGroup>
 
     <xsd:attributeGroup name="addNotNullConstraintAttrib">
Index: src/java/liquibase/change/CreateIndexChange.java
===================================================================
--- src/java/liquibase/change/CreateIndexChange.java (revision 690)
+++ src/java/liquibase/change/CreateIndexChange.java (working copy)
@@ -20,6 +20,7 @@
     private String schemaName;
     private String tableName;
     private String indexName;
+    private Boolean isUnique;
     private String tablespace;
     private List<ColumnConfig> columns;
 
@@ -81,7 +82,7 @@
         }
 
         return new SqlStatement []{
-                new CreateIndexStatement(getIndexName(), getSchemaName() == null?database.getDefaultSchemaName():getSchemaName(), getTableName(), columns.toArray(new String[getColumns().size()])).setTablespace(getTablespace())
+                new CreateIndexStatement(getIndexName(), getSchemaName() == null?database.getDefaultSchemaName():getSchemaName(), getTableName(), this.isUnique, columns.toArray(new String[getColumns().size()])).setTablespace(getTablespace())
         };
     }
 
@@ -109,6 +110,10 @@
 
         element.setAttribute("tableName", getTableName());
 
+        if (this.isUnique.booleanValue())
+          element.setAttribute("isUnique", "true");
+        else
+          element.setAttribute("isUnique", "false");
         for (ColumnConfig column : getColumns()) {
             Element columnElement = currentChangeLogFileDOM.createElement("column");
             columnElement.setAttribute("name", column.getName());
@@ -122,6 +127,7 @@
         Index index = new Index();
         index.setTable(new Table(tableName));
         index.setName(indexName);
+        index.setIsUnique(this.isUnique);
 
         Table table= new Table(getTableName());
 
@@ -128,4 +134,20 @@
         return new HashSet<DatabaseObject>(Arrays.asList(index, table));
     }
 
+    /**
+     * @param isUnique the isUnique to set
+     */
+    public void setIsUnique (Boolean isUnique)
+    {
+      this.isUnique = isUnique;
+    }
+
+    /**
+     * @return the isUnique
+     */
+    public Boolean getIsUnique ()
+    {
+      return new Boolean(this.isUnique);
+    }
+
 }
Index: src/java/liquibase/change/AddForeignKeyConstraintChange.java
===================================================================
--- src/java/liquibase/change/AddForeignKeyConstraintChange.java (revision 690)
+++ src/java/liquibase/change/AddForeignKeyConstraintChange.java (working copy)
@@ -12,6 +12,7 @@
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
+import java.sql.DatabaseMetaData;
 import java.util.HashSet;
 import java.util.Set;
 
@@ -33,6 +34,8 @@
     private Boolean initiallyDeferred;
 
     private Boolean deleteCascade;
+    private Integer updateRule;
+    private Integer deleteRule;
 
     public AddForeignKeyConstraintChange() {
         super("addForeignKeyConstraint", "Add Foreign Key Constraint");
@@ -111,9 +114,9 @@
     }
 
 
-    public Boolean getDeleteCascade() {
-        return deleteCascade;
-    }
+//    public Boolean getDeleteCascade() {
+//        return deleteCascade;
+//    }
 
     public void setDeleteCascade(Boolean deleteCascade) {
         this.deleteCascade = deleteCascade;
@@ -118,6 +121,76 @@
     public void setDeleteCascade(Boolean deleteCascade) {
         this.deleteCascade = deleteCascade;
     }
+    
+    public void setUpdateRule (Integer rule)
+    {
+      this.updateRule = rule;
+    }
+    
+    public Integer getUpdateRule ()
+    {
+      return this.updateRule;
+    }
+    
+    public void setDeleteRule (Integer rule)
+    {
+      this.deleteRule = rule;
+    }
+
+    public Integer getDeleteRule ()
+    {
+      return this.deleteRule;
+    }
+    
+    public void setOnDelete (String onDelete)
+    {
+      if (onDelete != null && onDelete.equalsIgnoreCase("CASCADE"))
+      {
+        setDeleteRule(new Integer(DatabaseMetaData.importedKeyCascade));
+        return;
+      }
+      if (onDelete != null && onDelete.equalsIgnoreCase("SET NULL"))
+      {
+        setDeleteRule(new Integer(DatabaseMetaData.importedKeySetNull));
+        return;
+      }
+      if (onDelete != null && onDelete.equalsIgnoreCase("SET DEFAULT"))
+      {
+        setDeleteRule(new Integer(DatabaseMetaData.importedKeySetDefault));
+        return;
+      }
+      if (onDelete != null && onDelete.equalsIgnoreCase("RESTRICT"))
+      {
+        setDeleteRule(new Integer(DatabaseMetaData.importedKeyRestrict));
+        return;
+      }
+      setDeleteRule(new Integer(DatabaseMetaData.importedKeyNoAction));
+    }
+    
+    public void setOnUpdate (String onUpdate)
+    {
+      if (onUpdate != null && onUpdate.equalsIgnoreCase("CASCADE"))
+      {
+        setUpdateRule(new Integer(DatabaseMetaData.importedKeyCascade));
+        return;
+      }
+      if (onUpdate != null && onUpdate.equalsIgnoreCase("SET NULL"))
+      {
+        setUpdateRule(new Integer(DatabaseMetaData.importedKeySetNull));
+        return;
+      }
+      if (onUpdate != null && onUpdate.equalsIgnoreCase("SET DEFAULT"))
+      {
+        setUpdateRule(new Integer(DatabaseMetaData.importedKeySetDefault));
+        return;
+      }
+      if (onUpdate != null && onUpdate.equalsIgnoreCase("RESTRICT"))
+      {
+        setUpdateRule(new Integer(DatabaseMetaData.importedKeyRestrict));
+        return;
+      }
+      setUpdateRule(new Integer(DatabaseMetaData.importedKeyNoAction));
+    }
 
     public SqlStatement[] generateStatements(Database database) throws UnsupportedChangeException {
     
@@ -137,9 +210,9 @@
         }
 
         boolean deleteCascade = false;
-        if (getDeleteCascade() != null) {
-            deleteCascade = getDeleteCascade();
-        }
+//        if (getDeleteCascade() != null) {
+//            deleteCascade = getDeleteCascade();
+//        }
         
         return new SqlStatement[]{
                 new AddForeignKeyConstraintStatement(getConstraintName(),
@@ -151,7 +224,9 @@
                         getReferencedColumnNames())
                 .setDeferrable(deferrable)
                 .setInitiallyDeferred(initiallyDeferred)
-                .setDeleteCascade(deleteCascade)
+//                .setDeleteCascade(deleteCascade)
+                .setUpdateRule(updateRule)
+                .setDeleteRule(deleteRule)
         };
     }
     
@@ -203,8 +278,51 @@
             node.setAttribute("initiallyDeferred", getInitiallyDeferred().toString());
         }
 
-        if (getDeleteCascade() != null) {
-            node.setAttribute("deleteCascade", getDeleteCascade().toString());
+//        if (getDeleteCascade() != null) {
+//            node.setAttribute("deleteCascade", getDeleteCascade().toString());
+//        }
+        
+        if (getUpdateRule() != null)
+        {
+          switch (getUpdateRule().intValue())
+          {
+            case DatabaseMetaData.importedKeyCascade :
+              node.setAttribute("onUpdate", "CASCADE");
+              break;
+            case DatabaseMetaData.importedKeySetNull :
+              node.setAttribute("onUpdate", "SET NULL");
+              break;
+            case DatabaseMetaData.importedKeySetDefault :
+              node.setAttribute("onUpdate", "SET DEFAULT");
+              break;
+            case DatabaseMetaData.importedKeyRestrict :
+              node.setAttribute("onUpdate", "RESTRICT");
+              break;
+            default :
+              node.setAttribute("onUpdate", "NO ACTION");
+              break;
+          }
+        }
+        if (getDeleteRule() != null)
+        {
+          switch (getDeleteRule().intValue())
+          {
+            case DatabaseMetaData.importedKeyCascade :
+              node.setAttribute("onDelete", "CASCADE");
+              break;
+            case DatabaseMetaData.importedKeySetNull :
+              node.setAttribute("onDelete", "SET NULL");
+              break;
+            case DatabaseMetaData.importedKeySetDefault :
+              node.setAttribute("onDelete", "SET DEFAULT");
+              break;
+            case DatabaseMetaData.importedKeyRestrict :
+              node.setAttribute("onDelete", "RESTRICT");
+              break;
+            default :
+              node.setAttribute("onDelete", "NO ACTION");
+              break;
+          }
         }
         return node;
     }
@@ -240,6 +358,8 @@
         fk.setForeignKeyColumns(baseColumnNames);
         fk.setPrimaryKeyTable(referencedTable);
         fk.setPrimaryKeyColumns(referencedColumnNames);
+        fk.setDeleteRule(this.deleteRule);
+        fk.setUpdateRule(this.updateRule);
         returnSet.add(fk);
 
         return returnSet;
Index: src/java/liquibase/dbchangelog-1.7.xsd
===================================================================
--- src/java/liquibase/dbchangelog-1.7.xsd (revision 690)
+++ src/java/liquibase/dbchangelog-1.7.xsd (working copy)
@@ -176,6 +176,7 @@
     <xsd:attributeGroup name="createIndex">
         <xsd:attributeGroup ref="tableNameAttribute"/>
         <xsd:attributeGroup ref="indexName"/>
+        <xsd:attribute name="isUnique" type="xsd:boolean"/>
     </xsd:attributeGroup>
 
 
@@ -291,6 +292,8 @@
         <xsd:attribute name="deferrable" type="xsd:boolean"/>
         <xsd:attribute name="initiallyDeferred" type="xsd:boolean"/>
         <xsd:attribute name="deleteCascade" type="xsd:boolean"/>
+        <xsd:attribute name="onDelete" type="xsd:string"/>
+        <xsd:attribute name="onUpdate" type="xsd:string"/>
     </xsd:attributeGroup>
 
     <xsd:attributeGroup name="addNotNullConstraintAttrib">
Index: src/java/liquibase/diff/DiffResult.java
===================================================================
--- src/java/liquibase/diff/DiffResult.java (revision 690)
+++ src/java/liquibase/diff/DiffResult.java (working copy)
@@ -462,6 +462,7 @@
             CreateIndexChange change = new CreateIndexChange();
             change.setTableName(index.getTable().getName());
             change.setIndexName(index.getName());
+            change.setIsUnique(index.getIsUnique());
 
             for (String columnName : index.getColumns()) {
                 ColumnConfig column = new ColumnConfig();
@@ -522,6 +523,8 @@
 
             change.setDeferrable(fk.isDeferrable());
             change.setInitiallyDeferred(fk.isInitiallyDeferred());
+            change.setUpdateRule(fk.getUpdateRule());
+            change.setDeleteRule(fk.getDeleteRule());
 
             changes.add(change);
         }


-------------------------------------------------------------------------
Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW!
Studies have shown that voting for your favorite open source project,
along with a healthy diet, reduces your potential for chronic lameness
and boredom. Vote Now at http://www.sourceforge.net/community/cca08
_______________________________________________
Liquibase-devel mailing list
Liquibase-devel@...
https://lists.sourceforge.net/lists/listinfo/liquibase-devel
LightInTheBox - Buy quality products at wholesale price