diff --git a/migration/i6.2/oracle/201908011127_IDEMPIERE-4017.sql b/migration/i6.2/oracle/201908011127_IDEMPIERE-4017.sql new file mode 100644 index 0000000000..56d87e4567 --- /dev/null +++ b/migration/i6.2/oracle/201908011127_IDEMPIERE-4017.sql @@ -0,0 +1,83 @@ +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- IDEMPIERE-4017 Create a Unique Key case/accent insensitive to AD_Table.TableName (FHCA-1005) +-- Aug 1, 2019, 10:56:57 AM CEST +UPDATE AD_Column SET IsUpdateable='Y',Updated=TO_DATE('2019-08-01 10:56:57','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=210545 +; + +-- Aug 1, 2019, 10:57:57 AM CEST +UPDATE AD_IndexColumn SET AD_Column_ID=NULL, ColumnSQL='UPPER(TableName)',Updated=TO_DATE('2019-08-01 10:57:57','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_IndexColumn_ID=200242 +; + +-- Aug 1, 2019, 10:58:35 AM CEST +DROP INDEX ad_table_name +; + +-- Aug 1, 2019, 10:58:35 AM CEST +CREATE UNIQUE INDEX ad_table_name ON AD_Table (UPPER(TableName)) +; + +-- Aug 1, 2019, 11:44:05 AM CEST +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Invalid identifier: empty',0,0,'Y',TO_DATE('2019-08-01 11:44:04','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2019-08-01 11:44:04','YYYY-MM-DD HH24:MI:SS'),100,200515,'InvalidIdentifierEmpty','D','b590389d-3397-40be-9b8d-46546c50ba47') +; + +-- Aug 1, 2019, 11:44:26 AM CEST +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Invalid identifier: must not contain spaces',0,0,'Y',TO_DATE('2019-08-01 11:44:25','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2019-08-01 11:44:25','YYYY-MM-DD HH24:MI:SS'),100,200516,'InvalidIdentifierSpaces','D','6c46585b-8a0d-410e-a0d8-5eb588bdfee5') +; + +-- Aug 1, 2019, 11:44:39 AM CEST +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Invalid identifier: first character must be alphabetic',0,0,'Y',TO_DATE('2019-08-01 11:44:39','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2019-08-01 11:44:39','YYYY-MM-DD HH24:MI:SS'),100,200517,'InvalidIdentifierFirstCharAlpha','D','c83578cb-5af4-427b-aab2-224b45b65620') +; + +-- Aug 1, 2019, 11:45:06 AM CEST +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Invalid identifier: just alphanumeric and underscore characters are allowed',0,0,'Y',TO_DATE('2019-08-01 11:45:06','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2019-08-01 11:45:06','YYYY-MM-DD HH24:MI:SS'),100,200518,'InvalidIdentifierJustAlpha','D','f87e4c12-ce8d-464f-a1f7-201529ffa7a8') +; + +-- Aug 1, 2019, 11:59:00 AM CEST +UPDATE AD_IndexColumn SET AD_Column_ID=NULL, ColumnSQL='UPPER(ColumnName)',Updated=TO_DATE('2019-08-01 11:59:00','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_IndexColumn_ID=200068 +; + +-- Aug 1, 2019, 11:59:04 AM CEST +DROP INDEX ad_column_name +; + +-- Aug 1, 2019, 11:59:04 AM CEST +CREATE UNIQUE INDEX ad_column_name ON AD_Column (AD_Table_ID,UPPER(ColumnName)) +; + +-- Aug 1, 2019, 12:00:09 PM CEST +INSERT INTO AD_TableIndex (AD_Client_ID,AD_Org_ID,AD_TableIndex_ID,AD_TableIndex_UU,Created,CreatedBy,EntityType,IsActive,Name,Updated,UpdatedBy,AD_Table_ID,IsCreateConstraint,IsUnique,Processing,IsKey) VALUES (0,0,201073,'f4182255-8184-4cfd-9fc1-fb8b19d3aaf6',TO_DATE('2019-08-01 12:00:09','YYYY-MM-DD HH24:MI:SS'),100,'D','Y','ad_column_fkconstraintname',TO_DATE('2019-08-01 12:00:09','YYYY-MM-DD HH24:MI:SS'),100,101,'N','Y','N','N') +; + +-- Aug 1, 2019, 12:00:37 PM CEST +INSERT INTO AD_IndexColumn (AD_Client_ID,AD_Org_ID,AD_IndexColumn_ID,AD_IndexColumn_UU,Created,CreatedBy,EntityType,IsActive,Updated,UpdatedBy,AD_TableIndex_ID,ColumnSQL,SeqNo) VALUES (0,0,201388,'928de5aa-4a1c-4aed-aaea-86109ba81219',TO_DATE('2019-08-01 12:00:36','YYYY-MM-DD HH24:MI:SS'),100,'D','Y',TO_DATE('2019-08-01 12:00:36','YYYY-MM-DD HH24:MI:SS'),100,201073,'UPPER(FKConstraintName)',1) +; + +-- Aug 1, 2019, 12:00:44 PM CEST +CREATE UNIQUE INDEX ad_column_fkconstraintname ON AD_Column (UPPER(FKConstraintName)) +; + +-- Aug 1, 2019, 12:32:28 PM CEST +UPDATE AD_Tab SET IsSingleRow='Y',Updated=TO_DATE('2019-08-01 12:32:28','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tab_ID=200096 +; + +-- Aug 1, 2019, 12:32:31 PM CEST +UPDATE AD_Tab SET IsSingleRow='Y',Updated=TO_DATE('2019-08-01 12:32:31','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tab_ID=200097 +; + +-- Aug 1, 2019, 12:33:20 PM CEST +INSERT INTO AD_TableIndex (AD_Client_ID,AD_Org_ID,AD_TableIndex_ID,AD_TableIndex_UU,Created,CreatedBy,EntityType,IsActive,Name,Updated,UpdatedBy,AD_Table_ID,IsCreateConstraint,IsUnique,Processing,TableIndexDrop,IsKey) VALUES (0,0,201074,'ed01f300-0824-4497-84b5-4bcfd4c88db9',TO_DATE('2019-08-01 12:33:20','YYYY-MM-DD HH24:MI:SS'),100,'D','Y','ad_tableindex_name',TO_DATE('2019-08-01 12:33:20','YYYY-MM-DD HH24:MI:SS'),100,200085,'N','Y','N','N','N') +; + +-- Aug 1, 2019, 12:33:35 PM CEST +INSERT INTO AD_IndexColumn (AD_Client_ID,AD_Org_ID,AD_IndexColumn_ID,AD_IndexColumn_UU,Created,CreatedBy,EntityType,IsActive,Updated,UpdatedBy,AD_TableIndex_ID,ColumnSQL,SeqNo) VALUES (0,0,201389,'a163915d-a5ba-45f9-9411-144d499af1fd',TO_DATE('2019-08-01 12:33:35','YYYY-MM-DD HH24:MI:SS'),100,'D','Y',TO_DATE('2019-08-01 12:33:35','YYYY-MM-DD HH24:MI:SS'),100,201074,'UPPER(Name)',1) +; + +-- Aug 1, 2019, 12:33:43 PM CEST +CREATE UNIQUE INDEX ad_tableindex_name ON AD_TableIndex (UPPER(Name)) +; + +SELECT register_migration_script('201908011127_IDEMPIERE-4017.sql') FROM dual +; + diff --git a/migration/i6.2/postgresql/201908011127_IDEMPIERE-4017.sql b/migration/i6.2/postgresql/201908011127_IDEMPIERE-4017.sql new file mode 100644 index 0000000000..9fe0805366 --- /dev/null +++ b/migration/i6.2/postgresql/201908011127_IDEMPIERE-4017.sql @@ -0,0 +1,80 @@ +-- IDEMPIERE-4017 Create a Unique Key case/accent insensitive to AD_Table.TableName (FHCA-1005) +-- Aug 1, 2019, 10:56:57 AM CEST +UPDATE AD_Column SET IsUpdateable='Y',Updated=TO_TIMESTAMP('2019-08-01 10:56:57','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=210545 +; + +-- Aug 1, 2019, 10:57:57 AM CEST +UPDATE AD_IndexColumn SET AD_Column_ID=NULL, ColumnSQL='UPPER(TableName)',Updated=TO_TIMESTAMP('2019-08-01 10:57:57','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_IndexColumn_ID=200242 +; + +-- Aug 1, 2019, 10:58:35 AM CEST +DROP INDEX ad_table_name +; + +-- Aug 1, 2019, 10:58:35 AM CEST +CREATE UNIQUE INDEX ad_table_name ON AD_Table (UPPER(TableName)) +; + +-- Aug 1, 2019, 11:44:05 AM CEST +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Invalid identifier: empty',0,0,'Y',TO_TIMESTAMP('2019-08-01 11:44:04','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2019-08-01 11:44:04','YYYY-MM-DD HH24:MI:SS'),100,200515,'InvalidIdentifierEmpty','D','b590389d-3397-40be-9b8d-46546c50ba47') +; + +-- Aug 1, 2019, 11:44:26 AM CEST +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Invalid identifier: must not contain spaces',0,0,'Y',TO_TIMESTAMP('2019-08-01 11:44:25','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2019-08-01 11:44:25','YYYY-MM-DD HH24:MI:SS'),100,200516,'InvalidIdentifierSpaces','D','6c46585b-8a0d-410e-a0d8-5eb588bdfee5') +; + +-- Aug 1, 2019, 11:44:39 AM CEST +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Invalid identifier: first character must be alphabetic',0,0,'Y',TO_TIMESTAMP('2019-08-01 11:44:39','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2019-08-01 11:44:39','YYYY-MM-DD HH24:MI:SS'),100,200517,'InvalidIdentifierFirstCharAlpha','D','c83578cb-5af4-427b-aab2-224b45b65620') +; + +-- Aug 1, 2019, 11:45:06 AM CEST +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Invalid identifier: just alphanumeric and underscore characters are allowed',0,0,'Y',TO_TIMESTAMP('2019-08-01 11:45:06','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2019-08-01 11:45:06','YYYY-MM-DD HH24:MI:SS'),100,200518,'InvalidIdentifierJustAlpha','D','f87e4c12-ce8d-464f-a1f7-201529ffa7a8') +; + +-- Aug 1, 2019, 11:59:00 AM CEST +UPDATE AD_IndexColumn SET AD_Column_ID=NULL, ColumnSQL='UPPER(ColumnName)',Updated=TO_TIMESTAMP('2019-08-01 11:59:00','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_IndexColumn_ID=200068 +; + +-- Aug 1, 2019, 11:59:04 AM CEST +DROP INDEX ad_column_name +; + +-- Aug 1, 2019, 11:59:04 AM CEST +CREATE UNIQUE INDEX ad_column_name ON AD_Column (AD_Table_ID,UPPER(ColumnName)) +; + +-- Aug 1, 2019, 12:00:09 PM CEST +INSERT INTO AD_TableIndex (AD_Client_ID,AD_Org_ID,AD_TableIndex_ID,AD_TableIndex_UU,Created,CreatedBy,EntityType,IsActive,Name,Updated,UpdatedBy,AD_Table_ID,IsCreateConstraint,IsUnique,Processing,IsKey) VALUES (0,0,201073,'f4182255-8184-4cfd-9fc1-fb8b19d3aaf6',TO_TIMESTAMP('2019-08-01 12:00:09','YYYY-MM-DD HH24:MI:SS'),100,'D','Y','ad_column_fkconstraintname',TO_TIMESTAMP('2019-08-01 12:00:09','YYYY-MM-DD HH24:MI:SS'),100,101,'N','Y','N','N') +; + +-- Aug 1, 2019, 12:00:37 PM CEST +INSERT INTO AD_IndexColumn (AD_Client_ID,AD_Org_ID,AD_IndexColumn_ID,AD_IndexColumn_UU,Created,CreatedBy,EntityType,IsActive,Updated,UpdatedBy,AD_TableIndex_ID,ColumnSQL,SeqNo) VALUES (0,0,201388,'928de5aa-4a1c-4aed-aaea-86109ba81219',TO_TIMESTAMP('2019-08-01 12:00:36','YYYY-MM-DD HH24:MI:SS'),100,'D','Y',TO_TIMESTAMP('2019-08-01 12:00:36','YYYY-MM-DD HH24:MI:SS'),100,201073,'UPPER(FKConstraintName)',1) +; + +-- Aug 1, 2019, 12:00:44 PM CEST +CREATE UNIQUE INDEX ad_column_fkconstraintname ON AD_Column (UPPER(FKConstraintName)) +; + +-- Aug 1, 2019, 12:32:28 PM CEST +UPDATE AD_Tab SET IsSingleRow='Y',Updated=TO_TIMESTAMP('2019-08-01 12:32:28','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tab_ID=200096 +; + +-- Aug 1, 2019, 12:32:31 PM CEST +UPDATE AD_Tab SET IsSingleRow='Y',Updated=TO_TIMESTAMP('2019-08-01 12:32:31','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tab_ID=200097 +; + +-- Aug 1, 2019, 12:33:20 PM CEST +INSERT INTO AD_TableIndex (AD_Client_ID,AD_Org_ID,AD_TableIndex_ID,AD_TableIndex_UU,Created,CreatedBy,EntityType,IsActive,Name,Updated,UpdatedBy,AD_Table_ID,IsCreateConstraint,IsUnique,Processing,TableIndexDrop,IsKey) VALUES (0,0,201074,'ed01f300-0824-4497-84b5-4bcfd4c88db9',TO_TIMESTAMP('2019-08-01 12:33:20','YYYY-MM-DD HH24:MI:SS'),100,'D','Y','ad_tableindex_name',TO_TIMESTAMP('2019-08-01 12:33:20','YYYY-MM-DD HH24:MI:SS'),100,200085,'N','Y','N','N','N') +; + +-- Aug 1, 2019, 12:33:35 PM CEST +INSERT INTO AD_IndexColumn (AD_Client_ID,AD_Org_ID,AD_IndexColumn_ID,AD_IndexColumn_UU,Created,CreatedBy,EntityType,IsActive,Updated,UpdatedBy,AD_TableIndex_ID,ColumnSQL,SeqNo) VALUES (0,0,201389,'a163915d-a5ba-45f9-9411-144d499af1fd',TO_TIMESTAMP('2019-08-01 12:33:35','YYYY-MM-DD HH24:MI:SS'),100,'D','Y',TO_TIMESTAMP('2019-08-01 12:33:35','YYYY-MM-DD HH24:MI:SS'),100,201074,'UPPER(Name)',1) +; + +-- Aug 1, 2019, 12:33:43 PM CEST +CREATE UNIQUE INDEX ad_tableindex_name ON AD_TableIndex (UPPER(Name)) +; + +SELECT register_migration_script('201908011127_IDEMPIERE-4017.sql') FROM dual +; + diff --git a/org.adempiere.base/src/org/compiere/db/Database.java b/org.adempiere.base/src/org/compiere/db/Database.java index 57121e2d05..05aab5ed6e 100644 --- a/org.adempiere.base/src/org/compiere/db/Database.java +++ b/org.adempiere.base/src/org/compiere/db/Database.java @@ -22,6 +22,7 @@ import java.util.List; import org.adempiere.base.Service; import org.adempiere.base.ServiceQuery; import org.compiere.util.CLogger; +import org.compiere.util.Util; /** * General Database Constants and Utilities @@ -94,4 +95,25 @@ public class Database return null; } + /** + * Apply common validations for database object names + * @param String identifier + * @return String error-code - null if not error + */ + public static String isValidIdentifier(String identifier) + { + if (Util.isEmpty(identifier)) + return "InvalidIdentifierEmpty"; + // unquoted identifiers cannot contain spaces + if (identifier.contains(" ")) + return "InvalidIdentifierSpaces"; + // first character of identifier must be alphabetic + if (! identifier.substring(0, 1).matches("[a-zA-Z]")) + return "InvalidIdentifierFirstCharAlpha"; + // names must contain just alphanumeric and underscore + if (! identifier.matches("^[a-zA-Z0-9_]*$")) + return "InvalidIdentifierJustAlpha"; + return null; + } + } // Database diff --git a/org.adempiere.base/src/org/compiere/model/MColumn.java b/org.adempiere.base/src/org/compiere/model/MColumn.java index 5e67a8922e..2f3b3f5045 100644 --- a/org.adempiere.base/src/org/compiere/model/MColumn.java +++ b/org.adempiere.base/src/org/compiere/model/MColumn.java @@ -32,6 +32,7 @@ import java.util.Properties; import java.util.logging.Level; import org.adempiere.exceptions.DBException; +import org.compiere.db.Database; import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; @@ -254,6 +255,20 @@ public class MColumn extends X_AD_Column */ protected boolean beforeSave (boolean newRecord) { + String error = Database.isValidIdentifier(getColumnName()); + if (!Util.isEmpty(error)) { + log.saveError("Error", Msg.getMsg(getCtx(), error) + " [ColumnName]"); + return false; + } + + if (! Util.isEmpty(getFKConstraintName())) { + error = Database.isValidIdentifier(getFKConstraintName()); + if (!Util.isEmpty(error)) { + log.saveError("Error", Msg.getMsg(getCtx(), error) + " [FKConstraintName]"); + return false; + } + } + int displayType = getAD_Reference_ID(); if (DisplayType.isLOB(displayType)) // LOBs are 0 { diff --git a/org.adempiere.base/src/org/compiere/model/MInfoColumn.java b/org.adempiere.base/src/org/compiere/model/MInfoColumn.java index 338707f465..92f42b6a1a 100644 --- a/org.adempiere.base/src/org/compiere/model/MInfoColumn.java +++ b/org.adempiere.base/src/org/compiere/model/MInfoColumn.java @@ -21,11 +21,14 @@ import java.util.Properties; import java.util.logging.Level; import org.adempiere.model.IInfoColumn; +import org.compiere.db.Database; import org.compiere.model.AccessSqlParser.TableInfo; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Evaluatee; import org.compiere.util.Evaluator; +import org.compiere.util.Msg; +import org.compiere.util.Util; /** * Info Window Column Model @@ -137,6 +140,11 @@ public class MInfoColumn extends X_AD_InfoColumn implements IInfoColumn @Override protected boolean beforeSave(boolean newRecord) { + String error = Database.isValidIdentifier(getColumnName()); + if (!Util.isEmpty(error)) { + log.saveError("Error", Msg.getMsg(getCtx(), error) + " [ColumnName]"); + return false; + } // Sync Terminology if ((newRecord || is_ValueChanged ("AD_Element_ID")) && getAD_Element_ID() != 0 && isCentrallyMaintained()) diff --git a/org.adempiere.base/src/org/compiere/model/MTable.java b/org.adempiere.base/src/org/compiere/model/MTable.java index 486ddb18b3..9c55ca94b1 100644 --- a/org.adempiere.base/src/org/compiere/model/MTable.java +++ b/org.adempiere.base/src/org/compiere/model/MTable.java @@ -32,10 +32,13 @@ import java.util.logging.Level; import org.adempiere.base.IModelFactory; import org.adempiere.base.Service; import org.adempiere.model.GenericPO; +import org.compiere.db.Database; import org.compiere.util.CCache; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.KeyNamePair; +import org.compiere.util.Msg; +import org.compiere.util.Util; /** * Persistent Table Model @@ -525,6 +528,11 @@ public class MTable extends X_AD_Table if (isView() && isDeleteable()) setIsDeleteable(false); // + String error = Database.isValidIdentifier(getTableName()); + if (!Util.isEmpty(error)) { + log.saveError("Error", Msg.getMsg(getCtx(), error) + " [TableName]"); + return false; + } return true; } // beforeSave diff --git a/org.adempiere.base/src/org/compiere/model/MTableIndex.java b/org.adempiere.base/src/org/compiere/model/MTableIndex.java index f54008ab3e..499aa796a8 100644 --- a/org.adempiere.base/src/org/compiere/model/MTableIndex.java +++ b/org.adempiere.base/src/org/compiere/model/MTableIndex.java @@ -21,13 +21,15 @@ import java.util.List; import java.util.Properties; import org.adempiere.exceptions.AdempiereException; +import org.compiere.db.Database; import org.compiere.util.Msg; +import org.compiere.util.Util; public class MTableIndex extends X_AD_TableIndex { /** * */ - private static final long serialVersionUID = 5312095272014146977L; + private static final long serialVersionUID = 1433937879086456196L; /** * Get active indexes from table @@ -218,6 +220,21 @@ public class MTableIndex extends X_AD_TableIndex { return sql; } + /** + * Before Save + * @param newRecord new + * @return true + */ + @Override + protected boolean beforeSave(boolean newRecord) { + String error = Database.isValidIdentifier(getName()); + if (!Util.isEmpty(error)) { + log.saveError("Error", Msg.getMsg(getCtx(), error) + " [Name]"); + return false; + } + return true; + } + /** * String representation * @return info diff --git a/org.adempiere.base/src/org/compiere/model/MViewColumn.java b/org.adempiere.base/src/org/compiere/model/MViewColumn.java index 4816d4798d..a712acfdd8 100644 --- a/org.adempiere.base/src/org/compiere/model/MViewColumn.java +++ b/org.adempiere.base/src/org/compiere/model/MViewColumn.java @@ -19,13 +19,16 @@ package org.compiere.model; import java.sql.ResultSet; import java.util.Properties; +import org.compiere.db.Database; +import org.compiere.util.Msg; +import org.compiere.util.Util; + public class MViewColumn extends X_AD_ViewColumn { - /** * */ - private static final long serialVersionUID = 1497519704377959238L; + private static final long serialVersionUID = -7325808411400037317L; /** * Standard constructor @@ -73,4 +76,20 @@ public class MViewColumn extends X_AD_ViewColumn { .append("]"); return sb.toString(); } + + /** + * Before Save + * @param newRecord new + * @return true + */ + @Override + protected boolean beforeSave(boolean newRecord) { + String error = Database.isValidIdentifier(getColumnName()); + if (!Util.isEmpty(error)) { + log.saveError("Error", Msg.getMsg(getCtx(), error) + " [ColumnName]"); + return false; + } + return true; + } + } diff --git a/org.adempiere.base/src/org/compiere/model/MViewComponent.java b/org.adempiere.base/src/org/compiere/model/MViewComponent.java index 4bdbbab4d6..bd93e39d15 100644 --- a/org.adempiere.base/src/org/compiere/model/MViewComponent.java +++ b/org.adempiere.base/src/org/compiere/model/MViewComponent.java @@ -20,6 +20,8 @@ import java.sql.ResultSet; import java.util.List; import java.util.Properties; +import org.adempiere.exceptions.AdempiereException; + public class MViewComponent extends X_AD_ViewComponent { @@ -115,6 +117,9 @@ public class MViewComponent extends X_AD_ViewComponent { break; } } + if (vc == null) { + throw new AdempiereException("Cannot find element for " + colName + ". Tip: all components must have the same number and names of columns"); + } if (i>0) sb.append(", "); String colSQL = vc.getColumnSQL(); diff --git a/org.adempiere.base/src/org/compiere/model/M_Element.java b/org.adempiere.base/src/org/compiere/model/M_Element.java index ebf130aa7e..607a72a60f 100644 --- a/org.adempiere.base/src/org/compiere/model/M_Element.java +++ b/org.adempiere.base/src/org/compiere/model/M_Element.java @@ -21,9 +21,11 @@ import java.util.Properties; import java.util.logging.Level; import org.adempiere.exceptions.DBException; +import org.compiere.db.Database; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Msg; +import org.compiere.util.Util; /** @@ -197,6 +199,11 @@ public class M_Element extends X_AD_Element return false; } } + String error = Database.isValidIdentifier(getColumnName()); + if (!Util.isEmpty(error)) { + log.saveError("Error", Msg.getMsg(getCtx(), error) + " [ColumnName]"); + return false; + } return true; } diff --git a/org.adempiere.base/src/org/compiere/model/PO.java b/org.adempiere.base/src/org/compiere/model/PO.java index 7569d54205..a62b4e32e1 100644 --- a/org.adempiere.base/src/org/compiere/model/PO.java +++ b/org.adempiere.base/src/org/compiere/model/PO.java @@ -2721,12 +2721,24 @@ public abstract class PO ok = lobSave(); else { - if (m_trxName == null) - log.saveError("SaveError", "Update return " + no + " instead of 1" - + " - " + p_info.getTableName() + "." + where); - else - log.saveError("SaveError", "Update return " + no + " instead of 1" - + " - [" + m_trxName + "] - " + p_info.getTableName() + "." + where); + if (CLogger.peekError() == null) { + if (m_trxName == null) + log.saveError("SaveError", "Update return " + no + " instead of 1" + + " - " + p_info.getTableName() + "." + where); + else + log.saveError("SaveError", "Update return " + no + " instead of 1" + + " - [" + m_trxName + "] - " + p_info.getTableName() + "." + where); + } else { + String msg = "Not updated - "; + if (CLogMgt.isLevelFiner()) + msg += sql.toString(); + else + msg += get_TableName(); + if (m_trxName == null) + log.log(Level.WARNING, msg); + else + log.log(Level.WARNING, "[" + m_trxName + "]" + msg); + } } return ok; }