From 0e0589d8be5732a851f54b9163f6a8649ca63362 Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Mon, 17 Aug 2015 20:47:03 -0500 Subject: [PATCH] IDEMPIERE-2745 2Pack is not creating foreign keys - foreign key processing needs to be done at the end as the primary keys of related tables can be inexistent when processing columns --- .../pipo2/handler/ColumnElementHandler.java | 38 ++++++-------- .../src/org/adempiere/pipo2/Element.java | 2 + .../org/adempiere/pipo2/PackInHandler.java | 49 +++++++++++++++++++ 3 files changed, 65 insertions(+), 24 deletions(-) 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 84dbae6dcb..89cc6b344a 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,7 +25,6 @@ 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; @@ -81,6 +80,7 @@ public class ColumnElementHandler extends AbstractElementHandler { if (!mColumn.is_new() && !mColumn.is_Changed()) { boolean syncDatabase = "Y".equalsIgnoreCase(getStringValue(element, "IsSyncDatabase")); if (syncDatabase) { + deferFK(element, mColumn); syncColumn(ctx, mColumn, "Sync", false); } return; @@ -111,10 +111,12 @@ public class ColumnElementHandler extends AbstractElementHandler { } boolean recreateColumn = (mColumn.is_new() - || mColumn.is_ValueChanged("AD_Reference_ID") - || mColumn.is_ValueChanged("FieldLength") - || mColumn.is_ValueChanged("ColumnName") || mColumn - .is_ValueChanged("IsMandatory")); + || mColumn.is_ValueChanged(X_AD_Column.COLUMNNAME_AD_Reference_ID) + || mColumn.is_ValueChanged(X_AD_Column.COLUMNNAME_FieldLength) + || mColumn.is_ValueChanged(X_AD_Column.COLUMNNAME_ColumnName) + || mColumn.is_ValueChanged(X_AD_Column.COLUMNNAME_FKConstraintName) + || mColumn.is_ValueChanged(X_AD_Column.COLUMNNAME_FKConstraintType) + || mColumn.is_ValueChanged(X_AD_Column.COLUMNNAME_IsMandatory)); //ignore fieldlength change for clob and lob if (!mColumn.is_ValueChanged("AD_Reference_ID") && mColumn.is_ValueChanged("FieldLength")) { @@ -161,6 +163,7 @@ public class ColumnElementHandler extends AbstractElementHandler { } if (recreateColumn || syncDatabase) { + deferFK(element, mColumn); syncColumn(ctx, mColumn, action, recreateColumn); } } else { @@ -168,6 +171,12 @@ public class ColumnElementHandler extends AbstractElementHandler { } } + private void deferFK(Element element, MColumn mColumn) { + String foreignTable = mColumn.getReferenceTableName(); + if (foreignTable != null && ! "AD_Ref_List".equals(foreignTable)) + element.deferFKColumnID = mColumn.getAD_Column_ID(); + } + private void syncColumn(PIPOContext ctx, MColumn mColumn, String action, boolean recreateColumn) throws SAXException { int success = 0; @@ -229,11 +238,6 @@ public class ColumnElementHandler extends AbstractElementHandler { if (!rst.next()) { // table doesn't exist sql = table.getSQLCreate(); - MColumn[] cols = table.getColumns(false); - for (MColumn col : cols) - { - sql += addConstraint(table, md, catalog, schema, tableName, col); - } } else { // rsc = md.getColumns(catalog, schema, tableName, columnName); @@ -249,7 +253,6 @@ public class ColumnElementHandler extends AbstractElementHandler { // No existing column sql = column.getSQLAdd(table); } - sql += addConstraint(table, md, catalog, schema, tableName, column); } //execute modify or add if needed @@ -296,19 +299,6 @@ public class ColumnElementHandler extends AbstractElementHandler { return 1; } - private String addConstraint(MTable table, DatabaseMetaData md, - String catalog, String schema, String tableName, MColumn col) { - String fkConstraintSql; - try { - fkConstraintSql = MColumn.getForeignKeyConstraintSql(md, catalog, schema, tableName, table, col, false); - } catch (Exception e) { - throw new AdempiereException(e); - } - if (fkConstraintSql != null && fkConstraintSql.length() > 0) - fkConstraintSql = ""; - return fkConstraintSql; - } - public void endElement(PIPOContext ctx, Element element) throws SAXException { } diff --git a/org.adempiere.pipo/src/org/adempiere/pipo2/Element.java b/org.adempiere.pipo/src/org/adempiere/pipo2/Element.java index 98e9b3b802..7526facd00 100644 --- a/org.adempiere.pipo/src/org/adempiere/pipo2/Element.java +++ b/org.adempiere.pipo/src/org/adempiere/pipo2/Element.java @@ -37,6 +37,8 @@ public class Element { public Attributes attributes; //defer for later reprocessing public boolean defer = false; + //defer for post packin foreign key processing + public int deferFKColumnID = 0; //parent element public Element parent; //resolved db recordid, store for reference by child element diff --git a/org.adempiere.pipo/src/org/adempiere/pipo2/PackInHandler.java b/org.adempiere.pipo/src/org/adempiere/pipo2/PackInHandler.java index a1e8f65ef7..6660d28300 100644 --- a/org.adempiere.pipo/src/org/adempiere/pipo2/PackInHandler.java +++ b/org.adempiere.pipo/src/org/adempiere/pipo2/PackInHandler.java @@ -19,6 +19,8 @@ package org.adempiere.pipo2; +import java.sql.Connection; +import java.sql.DatabaseMetaData; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; @@ -27,13 +29,17 @@ import java.util.Set; import java.util.Stack; import java.util.logging.Level; +import org.adempiere.exceptions.AdempiereException; import org.adempiere.pipo2.exception.DatabaseAccessException; +import org.compiere.model.MColumn; +import org.compiere.model.MTable; import org.compiere.model.X_AD_Package_Imp; import org.compiere.model.X_AD_Package_Imp_Inst; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Trx; +import org.compiere.util.Util; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; @@ -68,6 +74,7 @@ public class PackInHandler extends DefaultHandler { private IHandlerRegistry handlerRegistry = null; private List defer = new ArrayList(); + private List deferFK = new ArrayList(); private Stack stack = new Stack(); private PackIn packIn; private int elementProcessed = 0; @@ -228,6 +235,11 @@ public class PackInHandler extends DefaultHandler { { defer.add(new DeferEntry(element, true)); } + if (element.deferFKColumnID > 0) + { + if (! deferFK.contains(element.deferFKColumnID)) + deferFK.add(element.deferFKColumnID); + } for (Element childElement : element.childrens) { @@ -280,6 +292,9 @@ public class PackInHandler extends DefaultHandler { if (elementValue.equals("idempiere")){ processDeferElements(); + + processDeferFKElements(); + if (!packageStatus.equals("Completed with errors")) packageStatus = "Completed successfully"; @@ -368,6 +383,40 @@ public class PackInHandler extends DefaultHandler { } while (defer.size() > 0); } + private void processDeferFKElements() throws SAXException { + + if (deferFK.isEmpty()) + return; + + for (int columnID : deferFK) { + MColumn column = MColumn.get(m_ctx.ctx, columnID); + try { + Connection conn = m_ctx.trx.getConnection(); + DatabaseMetaData md = conn.getMetaData(); + String catalog = DB.getDatabase().getCatalog(); + String schema = DB.getDatabase().getSchema(); + MTable table = MTable.get(m_ctx.ctx, column.getAD_Table_ID()); + String tableName = table.getTableName(); + + String fkConstraintSql = MColumn.getForeignKeyConstraintSql(md, catalog, schema, tableName, table, column, false); + if (! Util.isEmpty(fkConstraintSql)) { + if (fkConstraintSql.indexOf(DB.SQLSTATEMENT_SEPARATOR) == -1) { + DB.executeUpdate(fkConstraintSql, false, m_ctx.trx.getTrxName()); + } else { + String statements[] = fkConstraintSql.split(DB.SQLSTATEMENT_SEPARATOR); + for (int i = 0; i < statements.length; i++) { + if (Util.isEmpty(statements[i])) + continue; + DB.executeUpdateEx(statements[i], m_ctx.trx.getTrxName()); + } + } + } + } catch (Exception e) { + throw new AdempiereException(e); + } + } + } + public void setCtx(PIPOContext ctx) { m_ctx = ctx; }