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 javax.xml.transform.sax.TransformerHandler;
|
||||||
|
|
||||||
import org.adempiere.exceptions.AdempiereException;
|
|
||||||
import org.adempiere.pipo2.AbstractElementHandler;
|
import org.adempiere.pipo2.AbstractElementHandler;
|
||||||
import org.adempiere.pipo2.Element;
|
import org.adempiere.pipo2.Element;
|
||||||
import org.adempiere.pipo2.PIPOContext;
|
import org.adempiere.pipo2.PIPOContext;
|
||||||
|
@ -81,6 +80,7 @@ public class ColumnElementHandler extends AbstractElementHandler {
|
||||||
if (!mColumn.is_new() && !mColumn.is_Changed()) {
|
if (!mColumn.is_new() && !mColumn.is_Changed()) {
|
||||||
boolean syncDatabase = "Y".equalsIgnoreCase(getStringValue(element, "IsSyncDatabase"));
|
boolean syncDatabase = "Y".equalsIgnoreCase(getStringValue(element, "IsSyncDatabase"));
|
||||||
if (syncDatabase) {
|
if (syncDatabase) {
|
||||||
|
deferFK(element, mColumn);
|
||||||
syncColumn(ctx, mColumn, "Sync", false);
|
syncColumn(ctx, mColumn, "Sync", false);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -111,10 +111,12 @@ public class ColumnElementHandler extends AbstractElementHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean recreateColumn = (mColumn.is_new()
|
boolean recreateColumn = (mColumn.is_new()
|
||||||
|| mColumn.is_ValueChanged("AD_Reference_ID")
|
|| mColumn.is_ValueChanged(X_AD_Column.COLUMNNAME_AD_Reference_ID)
|
||||||
|| mColumn.is_ValueChanged("FieldLength")
|
|| mColumn.is_ValueChanged(X_AD_Column.COLUMNNAME_FieldLength)
|
||||||
|| mColumn.is_ValueChanged("ColumnName") || mColumn
|
|| mColumn.is_ValueChanged(X_AD_Column.COLUMNNAME_ColumnName)
|
||||||
.is_ValueChanged("IsMandatory"));
|
|| 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
|
//ignore fieldlength change for clob and lob
|
||||||
if (!mColumn.is_ValueChanged("AD_Reference_ID") && mColumn.is_ValueChanged("FieldLength")) {
|
if (!mColumn.is_ValueChanged("AD_Reference_ID") && mColumn.is_ValueChanged("FieldLength")) {
|
||||||
|
@ -161,6 +163,7 @@ public class ColumnElementHandler extends AbstractElementHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (recreateColumn || syncDatabase) {
|
if (recreateColumn || syncDatabase) {
|
||||||
|
deferFK(element, mColumn);
|
||||||
syncColumn(ctx, mColumn, action, recreateColumn);
|
syncColumn(ctx, mColumn, action, recreateColumn);
|
||||||
}
|
}
|
||||||
} else {
|
} 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,
|
private void syncColumn(PIPOContext ctx, MColumn mColumn, String action,
|
||||||
boolean recreateColumn) throws SAXException {
|
boolean recreateColumn) throws SAXException {
|
||||||
int success = 0;
|
int success = 0;
|
||||||
|
@ -229,11 +238,6 @@ public class ColumnElementHandler extends AbstractElementHandler {
|
||||||
if (!rst.next()) {
|
if (!rst.next()) {
|
||||||
// table doesn't exist
|
// table doesn't exist
|
||||||
sql = table.getSQLCreate();
|
sql = table.getSQLCreate();
|
||||||
MColumn[] cols = table.getColumns(false);
|
|
||||||
for (MColumn col : cols)
|
|
||||||
{
|
|
||||||
sql += addConstraint(table, md, catalog, schema, tableName, col);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
//
|
//
|
||||||
rsc = md.getColumns(catalog, schema, tableName, columnName);
|
rsc = md.getColumns(catalog, schema, tableName, columnName);
|
||||||
|
@ -249,7 +253,6 @@ public class ColumnElementHandler extends AbstractElementHandler {
|
||||||
// No existing column
|
// No existing column
|
||||||
sql = column.getSQLAdd(table);
|
sql = column.getSQLAdd(table);
|
||||||
}
|
}
|
||||||
sql += addConstraint(table, md, catalog, schema, tableName, column);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//execute modify or add if needed
|
//execute modify or add if needed
|
||||||
|
@ -296,19 +299,6 @@ public class ColumnElementHandler extends AbstractElementHandler {
|
||||||
return 1;
|
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 {
|
public void endElement(PIPOContext ctx, Element element) throws SAXException {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,8 @@ public class Element {
|
||||||
public Attributes attributes;
|
public Attributes attributes;
|
||||||
//defer for later reprocessing
|
//defer for later reprocessing
|
||||||
public boolean defer = false;
|
public boolean defer = false;
|
||||||
|
//defer for post packin foreign key processing
|
||||||
|
public int deferFKColumnID = 0;
|
||||||
//parent element
|
//parent element
|
||||||
public Element parent;
|
public Element parent;
|
||||||
//resolved db recordid, store for reference by child element
|
//resolved db recordid, store for reference by child element
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
package org.adempiere.pipo2;
|
package org.adempiere.pipo2;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DatabaseMetaData;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -27,13 +29,17 @@ import java.util.Set;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import org.adempiere.exceptions.AdempiereException;
|
||||||
import org.adempiere.pipo2.exception.DatabaseAccessException;
|
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;
|
||||||
import org.compiere.model.X_AD_Package_Imp_Inst;
|
import org.compiere.model.X_AD_Package_Imp_Inst;
|
||||||
import org.compiere.util.CLogger;
|
import org.compiere.util.CLogger;
|
||||||
import org.compiere.util.DB;
|
import org.compiere.util.DB;
|
||||||
import org.compiere.util.Env;
|
import org.compiere.util.Env;
|
||||||
import org.compiere.util.Trx;
|
import org.compiere.util.Trx;
|
||||||
|
import org.compiere.util.Util;
|
||||||
import org.xml.sax.Attributes;
|
import org.xml.sax.Attributes;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
import org.xml.sax.helpers.AttributesImpl;
|
import org.xml.sax.helpers.AttributesImpl;
|
||||||
|
@ -68,6 +74,7 @@ public class PackInHandler extends DefaultHandler {
|
||||||
|
|
||||||
private IHandlerRegistry handlerRegistry = null;
|
private IHandlerRegistry handlerRegistry = null;
|
||||||
private List<DeferEntry> defer = new ArrayList<DeferEntry>();
|
private List<DeferEntry> defer = new ArrayList<DeferEntry>();
|
||||||
|
private List<Integer> deferFK = new ArrayList<Integer>();
|
||||||
private Stack<Element> stack = new Stack<Element>();
|
private Stack<Element> stack = new Stack<Element>();
|
||||||
private PackIn packIn;
|
private PackIn packIn;
|
||||||
private int elementProcessed = 0;
|
private int elementProcessed = 0;
|
||||||
|
@ -228,6 +235,11 @@ public class PackInHandler extends DefaultHandler {
|
||||||
{
|
{
|
||||||
defer.add(new DeferEntry(element, true));
|
defer.add(new DeferEntry(element, true));
|
||||||
}
|
}
|
||||||
|
if (element.deferFKColumnID > 0)
|
||||||
|
{
|
||||||
|
if (! deferFK.contains(element.deferFKColumnID))
|
||||||
|
deferFK.add(element.deferFKColumnID);
|
||||||
|
}
|
||||||
|
|
||||||
for (Element childElement : element.childrens)
|
for (Element childElement : element.childrens)
|
||||||
{
|
{
|
||||||
|
@ -280,6 +292,9 @@ public class PackInHandler extends DefaultHandler {
|
||||||
|
|
||||||
if (elementValue.equals("idempiere")){
|
if (elementValue.equals("idempiere")){
|
||||||
processDeferElements();
|
processDeferElements();
|
||||||
|
|
||||||
|
processDeferFKElements();
|
||||||
|
|
||||||
if (!packageStatus.equals("Completed with errors"))
|
if (!packageStatus.equals("Completed with errors"))
|
||||||
packageStatus = "Completed successfully";
|
packageStatus = "Completed successfully";
|
||||||
|
|
||||||
|
@ -368,6 +383,40 @@ public class PackInHandler extends DefaultHandler {
|
||||||
} while (defer.size() > 0);
|
} 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) {
|
public void setCtx(PIPOContext ctx) {
|
||||||
m_ctx = ctx;
|
m_ctx = ctx;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue