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
This commit is contained in:
parent
ee4814b6ca
commit
0e0589d8be
|
@ -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 {
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<DeferEntry> defer = new ArrayList<DeferEntry>();
|
||||
private List<Integer> deferFK = new ArrayList<Integer>();
|
||||
private Stack<Element> stack = new Stack<Element>();
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue