From 1d982987e5aa4a7a05b40d68141fefd2e56c8414 Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Wed, 29 Jul 2015 11:26:32 -0500 Subject: [PATCH] IDEMPIERE-2745 2Pack is not creating foreign keys --- .../src/org/compiere/process/ColumnSync.java | 146 +----------------- .../src/org/compiere/model/MColumn.java | 145 ++++++++++++++++- .../pipo2/handler/ColumnElementHandler.java | 23 +++ 3 files changed, 168 insertions(+), 146 deletions(-) diff --git a/org.adempiere.base.process/src/org/compiere/process/ColumnSync.java b/org.adempiere.base.process/src/org/compiere/process/ColumnSync.java index 5ba2df5619..2c2d9b88eb 100644 --- a/org.adempiere.base.process/src/org/compiere/process/ColumnSync.java +++ b/org.adempiere.base.process/src/org/compiere/process/ColumnSync.java @@ -20,18 +20,13 @@ import java.math.BigDecimal; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.ResultSet; -import java.util.Enumeration; -import java.util.Hashtable; import java.util.logging.Level; -import org.compiere.model.DatabaseKey; import org.compiere.model.MColumn; import org.compiere.model.MTable; -import org.compiere.model.PO; import org.compiere.util.AdempiereUserError; import org.compiere.util.CLogger; import org.compiere.util.DB; -import org.compiere.util.DisplayType; import org.compiere.util.ValueNamePair; /** @@ -133,14 +128,14 @@ public class ColumnSync extends SvrProcess MColumn[] cols = table.getColumns(false); for (MColumn col : cols) { - String fkConstraintSql = getForeignKeyConstraintSql(md, catalog, schema, tableName, table, col); + String fkConstraintSql = MColumn.getForeignKeyConstraintSql(md, catalog, schema, tableName, table, col); if (fkConstraintSql != null && fkConstraintSql.length() > 0) sql += fkConstraintSql; } } else { - String fkConstraintSql = getForeignKeyConstraintSql(md, catalog, schema, tableName, table, column); + String fkConstraintSql = MColumn.getForeignKeyConstraintSql(md, catalog, schema, tableName, table, column); if (fkConstraintSql != null && fkConstraintSql.length() > 0) sql += fkConstraintSql; } @@ -183,141 +178,4 @@ public class ColumnSync extends SvrProcess } } // doIt - private String getForeignKeyConstraintSql(DatabaseMetaData md, String catalog, String schema, String tableName, MTable table, MColumn column) throws Exception - { - StringBuilder fkConstraintSql = new StringBuilder(); - - if (!column.isKey() && !column.getColumnName().equals(PO.getUUIDColumnName(table.getTableName()))) - { - int refid = column.getAD_Reference_ID(); - if (refid != DisplayType.List && refid != DisplayType.Payment) - { - String referenceTableName = column.getReferenceTableName(); - if (referenceTableName != null) - { - Hashtable htForeignKeys = new Hashtable(); - - if (md.storesUpperCaseIdentifiers()) - referenceTableName = referenceTableName.toUpperCase(); - else if (md.storesLowerCaseIdentifiers()) - referenceTableName = referenceTableName.toLowerCase(); - - ResultSet rs = md.getCrossReference(catalog, schema, referenceTableName, catalog, schema, tableName); - while (rs.next()) - { - String dbFKName = rs.getString("FK_NAME"); - if (dbFKName == null) - continue; - - String dbFKTable = rs.getString("FKTABLE_NAME"); - short deleteRule = rs.getShort("DELETE_RULE"); - - String key = dbFKName.toLowerCase(); - DatabaseKey dbForeignKey = htForeignKeys.get(key); - if (dbForeignKey == null) - dbForeignKey = new DatabaseKey(dbFKName, dbFKTable, new String[30], deleteRule); - - String columnName = rs.getString("FKCOLUMN_NAME"); - int pos = (rs.getShort("KEY_SEQ")); - if (pos > 0) - dbForeignKey.getKeyColumns()[pos-1] = columnName; - - htForeignKeys.put(key, dbForeignKey); - } - rs.close(); - - Enumeration en = htForeignKeys.keys(); - while (en.hasMoreElements()) - { - String key = en.nextElement(); - DatabaseKey dbForeignKey = htForeignKeys.get(key); - if (dbForeignKey.getKeyColumns()[1] != null) - htForeignKeys.remove(key); - } - - boolean modified = false; - en = htForeignKeys.keys(); - while (en.hasMoreElements()) - { - String key = en.nextElement(); - DatabaseKey dbForeignKey = htForeignKeys.get(key); - if (dbForeignKey.getKeyColumns()[0].equalsIgnoreCase(column.getColumnName())) - { - DatabaseKey primaryKey = CreateForeignKey.getPrimaryKey(md, referenceTableName); - if (primaryKey != null) - { - fkConstraintSql.append(DB.SQLSTATEMENT_SEPARATOR); - fkConstraintSql.append("ALTER TABLE ").append(table.getTableName()); - fkConstraintSql.append(" DROP CONSTRAINT ").append(dbForeignKey.getKeyName()); - - String dbDeleteRule = MColumn.FKCONSTRAINTTYPE_NoAction; - if (dbForeignKey.getDeleteRule() == DatabaseMetaData.importedKeyCascade) - dbDeleteRule = MColumn.FKCONSTRAINTTYPE_Cascade; - else if (dbForeignKey.getDeleteRule() == DatabaseMetaData.importedKeySetNull) - dbDeleteRule = MColumn.FKCONSTRAINTTYPE_SetNull; - - String fkConstraintType = column.getFKConstraintType(); - if (fkConstraintType == null) - fkConstraintType = dbDeleteRule; - if (fkConstraintType == null) - fkConstraintType = MColumn.FKCONSTRAINTTYPE_NoAction; - if (!fkConstraintType.equals(MColumn.FKCONSTRAINTTYPE_DoNotCreate)) - { - String fkConstraintName = column.getFKConstraintName(); - if (fkConstraintName == null || fkConstraintName.trim().length() == 0) - fkConstraintName = dbForeignKey.getKeyName(); - - StringBuilder fkConstraint = new StringBuilder(); - fkConstraint.append("CONSTRAINT ").append(fkConstraintName); - fkConstraint.append(" FOREIGN KEY (").append(column.getColumnName()).append(") REFERENCES "); - fkConstraint.append(primaryKey.getKeyTable()).append("(").append(primaryKey.getKeyColumns()[0]); - for (int i = 1; i < primaryKey.getKeyColumns().length; i++) - { - if (primaryKey.getKeyColumns()[i] == null) - break; - fkConstraint.append(", ").append(primaryKey.getKeyColumns()[i]); - } - fkConstraint.append(")"); - - if (fkConstraintType.equals(MColumn.FKCONSTRAINTTYPE_NoAction)) - ; - else if (fkConstraintType.equals(MColumn.FKCONSTRAINTTYPE_Cascade)) - fkConstraint.append(" ON DELETE CASCADE"); - else if (fkConstraintType.equals(MColumn.FKCONSTRAINTTYPE_SetNull)) - fkConstraint.append(" ON DELETE SET NULL"); - - fkConstraint.append(" DEFERRABLE INITIALLY DEFERRED"); - - fkConstraintSql.append(DB.SQLSTATEMENT_SEPARATOR); - fkConstraintSql.append("ALTER TABLE ").append(table.getTableName()); - fkConstraintSql.append(" ADD "); - fkConstraintSql.append(fkConstraint); - - column.setFKConstraintName(fkConstraintName); - column.setFKConstraintType(fkConstraintType); - column.saveEx(); - } - } - modified = true; - break; - } - } - - if (!modified) - { - String fkConstraint = CreateForeignKey.getForeignKeyConstraint(md, table, column); - if (fkConstraint != null && fkConstraint.length() > 0) - { - fkConstraintSql.append(DB.SQLSTATEMENT_SEPARATOR); - fkConstraintSql.append("ALTER TABLE ").append(table.getTableName()); - fkConstraintSql.append(" ADD "); - fkConstraintSql.append(fkConstraint); - } - } - } - } - } - return fkConstraintSql.toString(); - } - } // ColumnSync diff --git a/org.adempiere.base/src/org/compiere/model/MColumn.java b/org.adempiere.base/src/org/compiere/model/MColumn.java index 8e9338a3b5..10c95e5986 100644 --- a/org.adempiere.base/src/org/compiere/model/MColumn.java +++ b/org.adempiere.base/src/org/compiere/model/MColumn.java @@ -17,6 +17,7 @@ package org.compiere.model; import java.math.BigDecimal; +import java.sql.DatabaseMetaData; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @@ -24,11 +25,14 @@ import java.text.DateFormat; import java.text.DecimalFormat; import java.text.NumberFormat; import java.text.SimpleDateFormat; +import java.util.Enumeration; +import java.util.Hashtable; import java.util.Locale; import java.util.Properties; import java.util.logging.Level; import org.adempiere.exceptions.DBException; +import org.compiere.process.CreateForeignKey; import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; @@ -48,7 +52,7 @@ public class MColumn extends X_AD_Column /** * */ - private static final long serialVersionUID = -7470893214933465732L; + private static final long serialVersionUID = -3735608010271317406L; /** * Get MColumn from Cache @@ -835,5 +839,142 @@ public class MColumn extends X_AD_Column MTable table = MTable.get(getCtx(), getAD_Table_ID()); return table; } - + + public static String getForeignKeyConstraintSql(DatabaseMetaData md, String catalog, String schema, String tableName, MTable table, MColumn column) throws Exception + { + StringBuilder fkConstraintSql = new StringBuilder(); + + if (!column.isKey() && !column.getColumnName().equals(PO.getUUIDColumnName(table.getTableName()))) + { + int refid = column.getAD_Reference_ID(); + if (refid != DisplayType.List && refid != DisplayType.Payment) + { + String referenceTableName = column.getReferenceTableName(); + if (referenceTableName != null) + { + Hashtable htForeignKeys = new Hashtable(); + + if (md.storesUpperCaseIdentifiers()) + referenceTableName = referenceTableName.toUpperCase(); + else if (md.storesLowerCaseIdentifiers()) + referenceTableName = referenceTableName.toLowerCase(); + + ResultSet rs = md.getCrossReference(catalog, schema, referenceTableName, catalog, schema, tableName); + while (rs.next()) + { + String dbFKName = rs.getString("FK_NAME"); + if (dbFKName == null) + continue; + + String dbFKTable = rs.getString("FKTABLE_NAME"); + short deleteRule = rs.getShort("DELETE_RULE"); + + String key = dbFKName.toLowerCase(); + DatabaseKey dbForeignKey = htForeignKeys.get(key); + if (dbForeignKey == null) + dbForeignKey = new DatabaseKey(dbFKName, dbFKTable, new String[30], deleteRule); + + String columnName = rs.getString("FKCOLUMN_NAME"); + int pos = (rs.getShort("KEY_SEQ")); + if (pos > 0) + dbForeignKey.getKeyColumns()[pos-1] = columnName; + + htForeignKeys.put(key, dbForeignKey); + } + rs.close(); + + Enumeration en = htForeignKeys.keys(); + while (en.hasMoreElements()) + { + String key = en.nextElement(); + DatabaseKey dbForeignKey = htForeignKeys.get(key); + if (dbForeignKey.getKeyColumns()[1] != null) + htForeignKeys.remove(key); + } + + boolean modified = false; + en = htForeignKeys.keys(); + while (en.hasMoreElements()) + { + String key = en.nextElement(); + DatabaseKey dbForeignKey = htForeignKeys.get(key); + if (dbForeignKey.getKeyColumns()[0].equalsIgnoreCase(column.getColumnName())) + { + DatabaseKey primaryKey = CreateForeignKey.getPrimaryKey(md, referenceTableName); + if (primaryKey != null) + { + fkConstraintSql.append(DB.SQLSTATEMENT_SEPARATOR); + fkConstraintSql.append("ALTER TABLE ").append(table.getTableName()); + fkConstraintSql.append(" DROP CONSTRAINT ").append(dbForeignKey.getKeyName()); + + String dbDeleteRule = MColumn.FKCONSTRAINTTYPE_NoAction; + if (dbForeignKey.getDeleteRule() == DatabaseMetaData.importedKeyCascade) + dbDeleteRule = MColumn.FKCONSTRAINTTYPE_Cascade; + else if (dbForeignKey.getDeleteRule() == DatabaseMetaData.importedKeySetNull) + dbDeleteRule = MColumn.FKCONSTRAINTTYPE_SetNull; + + String fkConstraintType = column.getFKConstraintType(); + if (fkConstraintType == null) + fkConstraintType = dbDeleteRule; + if (fkConstraintType == null) + fkConstraintType = MColumn.FKCONSTRAINTTYPE_NoAction; + if (!fkConstraintType.equals(MColumn.FKCONSTRAINTTYPE_DoNotCreate)) + { + String fkConstraintName = column.getFKConstraintName(); + if (fkConstraintName == null || fkConstraintName.trim().length() == 0) + fkConstraintName = dbForeignKey.getKeyName(); + + StringBuilder fkConstraint = new StringBuilder(); + fkConstraint.append("CONSTRAINT ").append(fkConstraintName); + fkConstraint.append(" FOREIGN KEY (").append(column.getColumnName()).append(") REFERENCES "); + fkConstraint.append(primaryKey.getKeyTable()).append("(").append(primaryKey.getKeyColumns()[0]); + for (int i = 1; i < primaryKey.getKeyColumns().length; i++) + { + if (primaryKey.getKeyColumns()[i] == null) + break; + fkConstraint.append(", ").append(primaryKey.getKeyColumns()[i]); + } + fkConstraint.append(")"); + + if (fkConstraintType.equals(MColumn.FKCONSTRAINTTYPE_NoAction)) + ; + else if (fkConstraintType.equals(MColumn.FKCONSTRAINTTYPE_Cascade)) + fkConstraint.append(" ON DELETE CASCADE"); + else if (fkConstraintType.equals(MColumn.FKCONSTRAINTTYPE_SetNull)) + fkConstraint.append(" ON DELETE SET NULL"); + + fkConstraint.append(" DEFERRABLE INITIALLY DEFERRED"); + + fkConstraintSql.append(DB.SQLSTATEMENT_SEPARATOR); + fkConstraintSql.append("ALTER TABLE ").append(table.getTableName()); + fkConstraintSql.append(" ADD "); + fkConstraintSql.append(fkConstraint); + + column.setFKConstraintName(fkConstraintName); + column.setFKConstraintType(fkConstraintType); + column.saveEx(); + } + } + modified = true; + break; + } + } + + if (!modified) + { + String fkConstraint = CreateForeignKey.getForeignKeyConstraint(md, table, column); + if (fkConstraint != null && fkConstraint.length() > 0) + { + fkConstraintSql.append(DB.SQLSTATEMENT_SEPARATOR); + fkConstraintSql.append("ALTER TABLE ").append(table.getTableName()); + fkConstraintSql.append(" ADD "); + fkConstraintSql.append(fkConstraint); + } + } + } + } + } + return fkConstraintSql.toString(); + } + } // MColumn diff --git a/org.adempiere.pipo.handlers/src/org/adempiere/pipo2/handler/ColumnElementHandler.java b/org.adempiere.pipo.handlers/src/org/adempiere/pipo2/handler/ColumnElementHandler.java index c2b33416d4..22bb37f791 100644 --- a/org.adempiere.pipo.handlers/src/org/adempiere/pipo2/handler/ColumnElementHandler.java +++ b/org.adempiere.pipo.handlers/src/org/adempiere/pipo2/handler/ColumnElementHandler.java @@ -25,6 +25,7 @@ import java.util.logging.Level; import javax.xml.transform.sax.TransformerHandler; +import org.adempiere.exceptions.AdempiereException; import org.adempiere.pipo2.AbstractElementHandler; import org.adempiere.pipo2.Element; import org.adempiere.pipo2.PIPOContext; @@ -228,6 +229,18 @@ public class ColumnElementHandler extends AbstractElementHandler { if (!rst.next()) { // table doesn't exist sql = table.getSQLCreate(); + MColumn[] cols = table.getColumns(false); + for (MColumn col : cols) + { + String fkConstraintSql; + try { + fkConstraintSql = MColumn.getForeignKeyConstraintSql(md, catalog, schema, tableName, table, col); + } catch (Exception e) { + throw new AdempiereException(e); + } + if (fkConstraintSql != null && fkConstraintSql.length() > 0) + sql += fkConstraintSql; + } } else { // rsc = md.getColumns(catalog, schema, tableName, columnName); @@ -243,6 +256,14 @@ public class ColumnElementHandler extends AbstractElementHandler { // No existing column sql = column.getSQLAdd(table); } + String fkConstraintSql; + try { + fkConstraintSql = MColumn.getForeignKeyConstraintSql(md, catalog, schema, tableName, table, column); + } catch (Exception e) { + throw new AdempiereException(e); + } + if (fkConstraintSql != null && fkConstraintSql.length() > 0) + sql += fkConstraintSql; } //execute modify or add if needed @@ -260,6 +281,8 @@ public class ColumnElementHandler extends AbstractElementHandler { } else { String statements[] = sql.split(DB.SQLSTATEMENT_SEPARATOR); for (int i = 0; i < statements.length; i++) { + if ("null".equals(statements[i])) + continue; int ret = DB.executeUpdate(statements[i], false, trx.getTrxName()); if (ret == -1) {