datatable and code value mappings
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
CREATE TABLE `x_table_cloumn_code_mappings` (
|
||||
`column_alias_name` VARCHAR(50) NOT NULL,
|
||||
`code_id` INT(10) NOT NULL,
|
||||
PRIMARY KEY (`column_alias_name`),
|
||||
INDEX `FK_x_code_id` (`code_id`),
|
||||
CONSTRAINT `FK_x_code_id` FOREIGN KEY (`code_id`) REFERENCES `m_code` (`id`)
|
||||
)
|
||||
COLLATE='utf8_general_ci'
|
||||
ENGINE=InnoDB;
|
||||
|
||||
INSERT INTO `c_configuration` (`name`, `enabled`) VALUES ('constraint_approach_for_datatables', 1);
|
||||
+4
-1
@@ -10,7 +10,6 @@ package org.mifosplatform.infrastructure.codes.data;
|
||||
*/
|
||||
public class CodeData {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private final Long id;
|
||||
@SuppressWarnings("unused")
|
||||
private final String name;
|
||||
@@ -26,4 +25,8 @@ public class CodeData {
|
||||
this.name = name;
|
||||
this.systemDefined = systemDefined;
|
||||
}
|
||||
|
||||
public Long getCodeId(){
|
||||
return this.id;
|
||||
}
|
||||
}
|
||||
+2
@@ -14,4 +14,6 @@ public interface CodeReadPlatformService {
|
||||
Collection<CodeData> retrieveAllCodes();
|
||||
|
||||
CodeData retrieveCode(Long codeId);
|
||||
|
||||
CodeData retriveCode(String codeName);
|
||||
}
|
||||
|
||||
+14
@@ -71,4 +71,18 @@ public class CodeReadPlatformServiceImpl implements CodeReadPlatformService {
|
||||
throw new CodeNotFoundException(codeId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeData retriveCode(String codeName) {
|
||||
try {
|
||||
context.authenticatedUser();
|
||||
|
||||
final CodeMapper rm = new CodeMapper();
|
||||
final String sql = "select " + rm.schema() + " where c.code_name = ?";
|
||||
|
||||
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { codeName });
|
||||
} catch (EmptyResultDataAccessException e) {
|
||||
throw new CodeNotFoundException(codeName);
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
-2
@@ -96,8 +96,13 @@ public class CodeWritePlatformServiceJpaRepositoryImpl implements CodeWritePlatf
|
||||
final Code code = retrieveCodeBy(codeId);
|
||||
if (code.isSystemDefined()) { throw new SystemDefinedCodeCannotBeChangedException(); }
|
||||
|
||||
this.codeRepository.delete(code);
|
||||
|
||||
try {
|
||||
this.codeRepository.delete(code);
|
||||
this.codeRepository.flush();
|
||||
} catch (DataIntegrityViolationException e) {
|
||||
throw new PlatformDataIntegrityException("error.msg.cund.unknown.data.integrity.issue",
|
||||
"Unknown data integrity issue with resource: " + e.getMostSpecificCause());
|
||||
}
|
||||
return new CommandProcessingResultBuilder().withEntityId(codeId).build();
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -13,4 +13,5 @@ public interface ConfigurationDomainService {
|
||||
boolean isRescheduleRepaymentsOnHolidaysEnabled();
|
||||
boolean allowTransactionsOnHolidayEnabled();
|
||||
boolean allowTransactionsOnNonWorkingDayEnabled();
|
||||
boolean isConstraintApproachEnabledForDatatables();
|
||||
}
|
||||
+7
@@ -80,4 +80,11 @@ public class ConfigurationDomainServiceJpa implements ConfigurationDomainService
|
||||
return property.isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConstraintApproachEnabledForDatatables() {
|
||||
final String colunnValue = "constraint_approach_for_datatables";
|
||||
final GlobalConfigurationProperty property = this.globalConfigurationRepository.findOneByName(colunnValue);
|
||||
if (property == null) { throw new GlobalConfigurationPropertyNotFoundException(colunnValue); }
|
||||
return property.isEnabled();
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -20,7 +20,7 @@ public class PlatformDataIntegrityException extends RuntimeException {
|
||||
final Object... defaultUserMessageArgs) {
|
||||
this.globalisationMessageCode = globalisationMessageCode;
|
||||
this.defaultUserMessage = defaultUserMessage;
|
||||
this.parameterName = "";
|
||||
this.parameterName = null;
|
||||
this.defaultUserMessageArgs = defaultUserMessageArgs;
|
||||
}
|
||||
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package org.mifosplatform.infrastructure.core.exception;
|
||||
|
||||
public class PlatformServiceUnavailableException extends AbstractPlatformServiceUnavailableException {
|
||||
|
||||
public PlatformServiceUnavailableException(String globalisationMessageCode, String defaultUserMessage,
|
||||
Object... defaultUserMessageArgs) {
|
||||
super(globalisationMessageCode, defaultUserMessage, defaultUserMessageArgs);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+16
-5
@@ -24,6 +24,7 @@ public final class ResultsetColumnHeaderData {
|
||||
private final boolean isColumnPrimaryKey;
|
||||
|
||||
private final List<ResultsetColumnValueData> columnValues;
|
||||
private final String columnCode;
|
||||
|
||||
public static ResultsetColumnHeaderData basic(final String columnName, final String columnType) {
|
||||
|
||||
@@ -31,25 +32,31 @@ public final class ResultsetColumnHeaderData {
|
||||
final boolean columnNullable = false;
|
||||
final boolean columnIsPrimaryKey = false;
|
||||
final List<ResultsetColumnValueData> columnValues = new ArrayList<ResultsetColumnValueData>();
|
||||
return new ResultsetColumnHeaderData(columnName, columnType, columnLength, columnNullable, columnIsPrimaryKey, columnValues);
|
||||
final String columnCode = null;
|
||||
return new ResultsetColumnHeaderData(columnName, columnType, columnLength, columnNullable, columnIsPrimaryKey, columnValues,
|
||||
columnCode);
|
||||
}
|
||||
|
||||
public static ResultsetColumnHeaderData detailed(final String columnName, final String columnType, final Long columnLength,
|
||||
final boolean columnNullable, final boolean columnIsPrimaryKey, final List<ResultsetColumnValueData> columnValues) {
|
||||
return new ResultsetColumnHeaderData(columnName, columnType, columnLength, columnNullable, columnIsPrimaryKey, columnValues);
|
||||
final boolean columnNullable, final boolean columnIsPrimaryKey, final List<ResultsetColumnValueData> columnValues,
|
||||
String columnCode) {
|
||||
return new ResultsetColumnHeaderData(columnName, columnType, columnLength, columnNullable, columnIsPrimaryKey, columnValues,
|
||||
columnCode);
|
||||
}
|
||||
|
||||
private ResultsetColumnHeaderData(final String columnName, final String columnType, final Long columnLength,
|
||||
final boolean columnNullable, final boolean columnIsPrimaryKey, final List<ResultsetColumnValueData> columnValues) {
|
||||
final boolean columnNullable, final boolean columnIsPrimaryKey, final List<ResultsetColumnValueData> columnValues,
|
||||
String columnCode) {
|
||||
this.columnName = columnName;
|
||||
this.columnType = columnType;
|
||||
this.columnLength = columnLength;
|
||||
this.isColumnNullable = columnNullable;
|
||||
this.isColumnPrimaryKey = columnIsPrimaryKey;
|
||||
this.columnValues = columnValues;
|
||||
this.columnCode = columnCode;
|
||||
|
||||
String displayType = null;
|
||||
if (this.columnValues.isEmpty()) {
|
||||
if (this.columnCode == null) {
|
||||
if (isString()) {
|
||||
displayType = "STRING";
|
||||
} else if (isAnyInteger()) {
|
||||
@@ -228,4 +235,8 @@ public final class ResultsetColumnHeaderData {
|
||||
}
|
||||
return allowed;
|
||||
}
|
||||
|
||||
public String getColumnCode() {
|
||||
return this.columnCode;
|
||||
}
|
||||
}
|
||||
+50
-8
@@ -185,14 +185,34 @@ public class GenericDataServiceImpl implements GenericDataService {
|
||||
boolean columnIsPrimaryKey = "PRI".equalsIgnoreCase(isPrimaryKey);
|
||||
|
||||
List<ResultsetColumnValueData> columnValues = new ArrayList<ResultsetColumnValueData>();
|
||||
String codeName = null;
|
||||
if ("varchar".equalsIgnoreCase(columnType)) {
|
||||
columnValues = retreiveColumnValues(columnName, "_cv");
|
||||
int codePosition = columnName.indexOf("_cv");
|
||||
if (codePosition > 0) {
|
||||
codeName = columnName.substring(0, codePosition);
|
||||
columnValues = retreiveColumnValues(codeName);
|
||||
}
|
||||
|
||||
} else if ("int".equalsIgnoreCase(columnType)) {
|
||||
columnValues = retreiveColumnValues(columnName, "_cd");
|
||||
int codePosition = columnName.indexOf("_cd");
|
||||
if (codePosition > 0) {
|
||||
codeName = columnName.substring(0, codePosition);
|
||||
columnValues = retreiveColumnValues(codeName);
|
||||
}
|
||||
}
|
||||
if(codeName == null){
|
||||
final SqlRowSet rsValues = getDatatableCodeData(datatable, columnName);
|
||||
Integer codeId = null;
|
||||
while (rsValues.next()) {
|
||||
codeId = rsValues.getInt("id");
|
||||
codeName = rsValues.getString("code_name");
|
||||
}
|
||||
columnValues = retreiveColumnValues(codeId);
|
||||
|
||||
}
|
||||
|
||||
final ResultsetColumnHeaderData rsch = ResultsetColumnHeaderData.detailed(columnName, columnType, columnLength, columnNullable,
|
||||
columnIsPrimaryKey, columnValues);
|
||||
columnIsPrimaryKey, columnValues,codeName);
|
||||
|
||||
columnHeaders.add(rsch);
|
||||
}
|
||||
@@ -204,14 +224,10 @@ public class GenericDataServiceImpl implements GenericDataService {
|
||||
* Candidate for using caching there to get allowed 'column values' from
|
||||
* code/codevalue tables
|
||||
*/
|
||||
private List<ResultsetColumnValueData> retreiveColumnValues(final String columnName, final String code_suffix) {
|
||||
private List<ResultsetColumnValueData> retreiveColumnValues(final String codeName) {
|
||||
|
||||
final List<ResultsetColumnValueData> columnValues = new ArrayList<ResultsetColumnValueData>();
|
||||
|
||||
int codePosition = columnName.indexOf(code_suffix);
|
||||
if (codePosition > 0) {
|
||||
final String codeName = columnName.substring(0, codePosition);
|
||||
|
||||
final String sql = "select v.id, v.code_value from m_code m " + " join m_code_value v on v.code_id = m.id "
|
||||
+ " where m.code_name = '" + codeName + "' order by v.order_position, v.id";
|
||||
|
||||
@@ -224,6 +240,23 @@ public class GenericDataServiceImpl implements GenericDataService {
|
||||
|
||||
columnValues.add(new ResultsetColumnValueData(id, codeValue));
|
||||
}
|
||||
|
||||
return columnValues;
|
||||
}
|
||||
|
||||
private List<ResultsetColumnValueData> retreiveColumnValues(final Integer codeId) {
|
||||
|
||||
final List<ResultsetColumnValueData> columnValues = new ArrayList<ResultsetColumnValueData>();
|
||||
if (codeId != null) {
|
||||
final String sql = "select v.id, v.code_value from m_code_value v where v.code_id =" + codeId
|
||||
+ " order by v.order_position, v.id";
|
||||
final SqlRowSet rsValues = this.jdbcTemplate.queryForRowSet(sql);
|
||||
rsValues.beforeFirst();
|
||||
while (rsValues.next()) {
|
||||
final Integer id = rsValues.getInt("id");
|
||||
final String codeValue = rsValues.getString("code_value");
|
||||
columnValues.add(new ResultsetColumnValueData(id, codeValue));
|
||||
}
|
||||
}
|
||||
|
||||
return columnValues;
|
||||
@@ -240,4 +273,13 @@ public class GenericDataServiceImpl implements GenericDataService {
|
||||
|
||||
throw new DatatableNotFoundException(datatable);
|
||||
}
|
||||
|
||||
private SqlRowSet getDatatableCodeData(final String datatable, String columnName) {
|
||||
|
||||
final String sql = "select mc.id,mc.code_name from m_code mc join x_table_cloumn_code_mappings xcc on xcc.code_id = mc.id where xcc.column_alias_name='"
|
||||
+ datatable.toLowerCase().replaceAll("\\s", "_") + "_" + columnName + "'";
|
||||
final SqlRowSet rsValues = this.jdbcTemplate.queryForRowSet(sql);
|
||||
|
||||
return rsValues;
|
||||
}
|
||||
}
|
||||
+178
-32
@@ -18,8 +18,11 @@ import javax.sql.DataSource;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.hibernate.exception.ConstraintViolationException;
|
||||
import org.hibernate.exception.GenericJDBCException;
|
||||
import org.hibernate.exception.SQLGrammarException;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.mifosplatform.infrastructure.codes.service.CodeReadPlatformService;
|
||||
import org.mifosplatform.infrastructure.configuration.domain.ConfigurationDomainService;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
@@ -27,6 +30,7 @@ import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder
|
||||
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||
import org.mifosplatform.infrastructure.core.exception.PlatformServiceUnavailableException;
|
||||
import org.mifosplatform.infrastructure.core.serialization.DatatableCommandFromApiJsonDeserializer;
|
||||
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
|
||||
import org.mifosplatform.infrastructure.core.serialization.JsonParserHelper;
|
||||
@@ -44,6 +48,7 @@ import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.dao.EmptyResultDataAccessException;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.support.rowset.SqlRowSet;
|
||||
import org.springframework.jdbc.support.rowset.SqlRowSetMetaData;
|
||||
@@ -60,6 +65,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
|
||||
private final static String DATATABLE_NAME_REGEX_PATTERN = "^[a-zA-Z][a-zA-Z0-9\\-_\\s]{0,48}[a-zA-Z0-9]$";
|
||||
|
||||
private final static String CODE_VALUES_TABLE = "m_code_value";
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(ReadWriteNonCoreDataServiceImpl.class);
|
||||
private final static HashMap<String, String> apiTypeToMySQL = new HashMap<String, String>() {
|
||||
|
||||
@@ -80,11 +87,14 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
private final JsonParserHelper helper;
|
||||
private final GenericDataService genericDataService;
|
||||
private final DatatableCommandFromApiJsonDeserializer fromApiJsonDeserializer;
|
||||
private final ConfigurationDomainService configurationDomainService;
|
||||
private final CodeReadPlatformService codeReadPlatformService;
|
||||
|
||||
@Autowired
|
||||
public ReadWriteNonCoreDataServiceImpl(final RoutingDataSource dataSource, final PlatformSecurityContext context,
|
||||
final FromJsonHelper fromJsonHelper, final GenericDataService genericDataService,
|
||||
final DatatableCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
|
||||
final DatatableCommandFromApiJsonDeserializer fromApiJsonDeserializer, final CodeReadPlatformService codeReadPlatformService,
|
||||
final ConfigurationDomainService configurationDomainService) {
|
||||
this.dataSource = dataSource;
|
||||
this.jdbcTemplate = new JdbcTemplate(this.dataSource);
|
||||
this.context = context;
|
||||
@@ -92,6 +102,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
this.helper = new JsonParserHelper();
|
||||
this.genericDataService = genericDataService;
|
||||
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
|
||||
this.codeReadPlatformService = codeReadPlatformService;
|
||||
this.configurationDomainService = configurationDomainService;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -253,7 +265,19 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
|
||||
final String deleteRegisteredDatatableSql = "delete from x_registered_table where registered_table_name = '" + datatable + "'";
|
||||
|
||||
String[] sqlArray = { deleteRolePermissionsSql, deletePermissionsSql, deleteRegisteredDatatableSql };
|
||||
String[] sqlArray = null;
|
||||
if (configurationDomainService.isConstraintApproachEnabledForDatatables()) {
|
||||
final String deleteColumnCodeSql = "delete from x_table_cloumn_code_mappings where column_alias_name like'"
|
||||
+ datatable.toLowerCase().replaceAll("\\s", "_") + "%'";
|
||||
sqlArray = new String[4];
|
||||
sqlArray[3] = deleteColumnCodeSql;
|
||||
} else {
|
||||
sqlArray = new String[3];
|
||||
}
|
||||
sqlArray[0] = deleteRolePermissionsSql;
|
||||
sqlArray[1] = deletePermissionsSql;
|
||||
sqlArray[2] = deleteRegisteredDatatableSql;
|
||||
|
||||
this.jdbcTemplate.batchUpdate(sqlArray);
|
||||
}
|
||||
|
||||
@@ -333,7 +357,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
|
||||
private void parseDatatableColumnObjectForCreate(final JsonObject column, StringBuilder sqlBuilder) {
|
||||
private void parseDatatableColumnObjectForCreate(final JsonObject column, StringBuilder sqlBuilder, StringBuilder constrainBuilder,
|
||||
String dataTableNameAlias, Map<String, Long> codeMappings, boolean isConstraintApproach) {
|
||||
|
||||
String name = (column.has("name")) ? column.get("name").getAsString() : null;
|
||||
String type = (column.has("type")) ? column.get("type").getAsString() : null;
|
||||
@@ -342,7 +367,13 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
String code = (column.has("code")) ? column.get("code").getAsString() : null;
|
||||
|
||||
if (StringUtils.isNotBlank(code)) {
|
||||
name = datatableColumnNameToCodeValueName(name, code);
|
||||
if (isConstraintApproach) {
|
||||
codeMappings.put(dataTableNameAlias + "_" + name, codeReadPlatformService.retriveCode(code).getCodeId());
|
||||
constrainBuilder.append(", CONSTRAINT `fk_").append(dataTableNameAlias).append("_").append(name).append("` ")
|
||||
.append("FOREIGN KEY (`" + name + "`) ").append("REFERENCES `").append(CODE_VALUES_TABLE).append("` (`id`)");
|
||||
} else {
|
||||
name = datatableColumnNameToCodeValueName(name, code);
|
||||
}
|
||||
}
|
||||
|
||||
String mysqlType = apiTypeToMySQL.get(type);
|
||||
@@ -399,10 +430,13 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
|
||||
validateDatatableName(datatableName);
|
||||
validateAppTable(apptableName);
|
||||
|
||||
boolean isConstraintApproach = configurationDomainService.isConstraintApproachEnabledForDatatables();
|
||||
String fkColumnName = apptableName.substring(2) + "_id";
|
||||
String fkName = datatableName.toLowerCase().replaceAll("\\s", "_") + "_" + fkColumnName;
|
||||
final String dataTableNameAlias = datatableName.toLowerCase().replaceAll("\\s", "_");
|
||||
String fkName = dataTableNameAlias + "_" + fkColumnName;
|
||||
StringBuilder sqlBuilder = new StringBuilder();
|
||||
StringBuilder constrainBuilder = new StringBuilder();
|
||||
Map<String, Long> codeMappings = new HashMap<String, Long>();
|
||||
sqlBuilder = sqlBuilder.append("CREATE TABLE `" + datatableName + "` (");
|
||||
|
||||
if (multiRow) {
|
||||
@@ -413,7 +447,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
}
|
||||
|
||||
for (JsonElement column : columns) {
|
||||
parseDatatableColumnObjectForCreate(column.getAsJsonObject(), sqlBuilder);
|
||||
parseDatatableColumnObjectForCreate(column.getAsJsonObject(), sqlBuilder, constrainBuilder, dataTableNameAlias,
|
||||
codeMappings, isConstraintApproach);
|
||||
}
|
||||
|
||||
// Remove trailing comma and space
|
||||
@@ -429,10 +464,13 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
.append("FOREIGN KEY (`" + fkColumnName + "`) ").append("REFERENCES `" + actualAppTableName + "` (`id`)");
|
||||
}
|
||||
|
||||
sqlBuilder.append(constrainBuilder);
|
||||
|
||||
sqlBuilder = sqlBuilder.append(") ENGINE=InnoDB DEFAULT CHARSET=utf8;");
|
||||
this.jdbcTemplate.execute(sqlBuilder.toString());
|
||||
|
||||
registerDatatable(datatableName, apptableName);
|
||||
registerColumnCodeMapping(codeMappings);
|
||||
} catch (SQLGrammarException e) {
|
||||
Throwable realCause = e.getCause();
|
||||
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
@@ -455,7 +493,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
}
|
||||
|
||||
private void parseDatatableColumnForUpdate(final JsonObject column,
|
||||
final Map<String, ResultsetColumnHeaderData> mapColumnNameDefinition, StringBuilder sqlBuilder) {
|
||||
final Map<String, ResultsetColumnHeaderData> mapColumnNameDefinition, StringBuilder sqlBuilder, String datatableName,
|
||||
StringBuilder constrainBuilder, Map<String, Long> codeMappings, List<String> removeMappings, boolean isConstraintApproach) {
|
||||
|
||||
String name = (column.has("name")) ? column.get("name").getAsString() : null;
|
||||
String lengthStr = (column.has("length")) ? column.get("length").getAsString() : null;
|
||||
@@ -465,20 +504,53 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
String after = (column.has("after")) ? column.get("after").getAsString() : null;
|
||||
String code = (column.has("code")) ? column.get("code").getAsString() : null;
|
||||
String newCode = (column.has("newCode")) ? column.get("newCode").getAsString() : null;
|
||||
String dataTableNameAlias = datatableName.toLowerCase().replaceAll("\\s", "_");
|
||||
if (isConstraintApproach) {
|
||||
if (StringUtils.isBlank(newName)) {
|
||||
newName = name;
|
||||
}
|
||||
if (!StringUtils.equalsIgnoreCase(code, newCode) || !StringUtils.equalsIgnoreCase(name, newName)) {
|
||||
if (StringUtils.equalsIgnoreCase(code, newCode)) {
|
||||
int codeId = getCodeIdForColumn(dataTableNameAlias, name);
|
||||
if (codeId > 0) {
|
||||
removeMappings.add(dataTableNameAlias + "_" + name);
|
||||
constrainBuilder.append(", DROP FOREIGN KEY `fk_").append(dataTableNameAlias).append("_").append(name).append("` ");
|
||||
codeMappings.put(dataTableNameAlias + "_" + newName, (long) codeId);
|
||||
constrainBuilder.append(",ADD CONSTRAINT `fk_").append(dataTableNameAlias).append("_").append(newName)
|
||||
.append("` ").append("FOREIGN KEY (`" + newName + "`) ").append("REFERENCES `").append(CODE_VALUES_TABLE)
|
||||
.append("` (`id`)");
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(code)) {
|
||||
name = datatableColumnNameToCodeValueName(name, code);
|
||||
|
||||
if (StringUtils.isNotBlank(newCode)) {
|
||||
newName = datatableColumnNameToCodeValueName(newName, newCode);
|
||||
} else {
|
||||
newName = datatableColumnNameToCodeValueName(newName, code);
|
||||
} else {
|
||||
if (code != null) {
|
||||
removeMappings.add(dataTableNameAlias + "_" + name);
|
||||
if (newCode == null) {
|
||||
constrainBuilder.append(", DROP FOREIGN KEY `fk_").append(dataTableNameAlias).append("_").append(name)
|
||||
.append("` ");
|
||||
}
|
||||
}
|
||||
if (newCode != null) {
|
||||
codeMappings.put(dataTableNameAlias + "_" + newName, codeReadPlatformService.retriveCode(newCode).getCodeId());
|
||||
if (code == null) {
|
||||
constrainBuilder.append(",ADD CONSTRAINT `fk_").append(dataTableNameAlias).append("_").append(newName)
|
||||
.append("` ").append("FOREIGN KEY (`" + newName + "`) ").append("REFERENCES `")
|
||||
.append(CODE_VALUES_TABLE).append("` (`id`)");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (StringUtils.isNotBlank(code)) {
|
||||
name = datatableColumnNameToCodeValueName(name, code);
|
||||
if (StringUtils.isNotBlank(newCode)) {
|
||||
newName = datatableColumnNameToCodeValueName(newName, newCode);
|
||||
} else {
|
||||
newName = datatableColumnNameToCodeValueName(newName, code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!mapColumnNameDefinition.containsKey(name)) { throw new PlatformDataIntegrityException(
|
||||
"error.msg.datatable.column.missing.update.parse", "Column " + name + " does not exist.", name); }
|
||||
|
||||
String type = mapColumnNameDefinition.get(name).getColumnType();
|
||||
if (length == null && type.toLowerCase().equals("varchar")) {
|
||||
length = mapColumnNameDefinition.get(name).getColumnLength().intValue();
|
||||
@@ -505,7 +577,22 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
}
|
||||
}
|
||||
|
||||
private void parseDatatableColumnForAdd(final JsonObject column, StringBuilder sqlBuilder) {
|
||||
private int getCodeIdForColumn(String dataTableNameAlias, String name) {
|
||||
StringBuilder checkColumnCodeMapping = new StringBuilder();
|
||||
checkColumnCodeMapping.append("select ccm.code_id from x_table_cloumn_code_mappings ccm where ccm.column_alias_name='")
|
||||
.append(dataTableNameAlias).append("_").append(name).append("'");
|
||||
int codeId = 0;
|
||||
try {
|
||||
codeId = this.jdbcTemplate.queryForInt(checkColumnCodeMapping.toString());
|
||||
} catch (EmptyResultDataAccessException e) {
|
||||
logger.info(e.getMessage());
|
||||
}
|
||||
return codeId;
|
||||
}
|
||||
|
||||
|
||||
private void parseDatatableColumnForAdd(final JsonObject column, StringBuilder sqlBuilder, String dataTableNameAlias,
|
||||
StringBuilder constrainBuilder, Map<String, Long> codeMappings, boolean isConstraintApproach) {
|
||||
|
||||
String name = (column.has("name")) ? column.get("name").getAsString() : null;
|
||||
String type = (column.has("type")) ? column.get("type").getAsString() : null;
|
||||
@@ -515,7 +602,13 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
String code = (column.has("code")) ? column.get("code").getAsString() : null;
|
||||
|
||||
if (StringUtils.isNotBlank(code)) {
|
||||
name = datatableColumnNameToCodeValueName(name, code);
|
||||
if (isConstraintApproach) {
|
||||
codeMappings.put(dataTableNameAlias + "_" + name, codeReadPlatformService.retriveCode(code).getCodeId());
|
||||
constrainBuilder.append(",ADD CONSTRAINT `fk_").append(dataTableNameAlias).append("_").append(name).append("` ")
|
||||
.append("FOREIGN KEY (`" + name + "`) ").append("REFERENCES `").append(CODE_VALUES_TABLE).append("` (`id`)");
|
||||
} else {
|
||||
name = datatableColumnNameToCodeValueName(name, code);
|
||||
}
|
||||
}
|
||||
|
||||
String mysqlType = apiTypeToMySQL.get(type);
|
||||
@@ -542,11 +635,47 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
}
|
||||
}
|
||||
|
||||
private void parseDatatableColumnForDrop(final JsonObject column, StringBuilder sqlBuilder) {
|
||||
|
||||
private void parseDatatableColumnForDrop(final JsonObject column, StringBuilder sqlBuilder, String datatableName,
|
||||
StringBuilder constrainBuilder, List<String> codeMappings) {
|
||||
String datatableAlias = datatableName.toLowerCase().replaceAll("\\s", "_");
|
||||
String name = (column.has("name")) ? column.get("name").getAsString() : null;
|
||||
|
||||
sqlBuilder = sqlBuilder.append(", DROP COLUMN `" + name + "`");
|
||||
StringBuilder findFKSql = new StringBuilder();
|
||||
findFKSql.append("SELECT count(*)").append("FROM information_schema.TABLE_CONSTRAINTS i")
|
||||
.append(" WHERE i.CONSTRAINT_TYPE = 'FOREIGN KEY'").append(" AND i.TABLE_SCHEMA = DATABASE()")
|
||||
.append(" AND i.TABLE_NAME = '").append(datatableName).append("' AND i.CONSTRAINT_NAME = 'fk_").append(datatableAlias)
|
||||
.append("_").append(name).append("' ");
|
||||
int count = this.jdbcTemplate.queryForInt(findFKSql.toString());
|
||||
if (count > 0) {
|
||||
codeMappings.add(datatableAlias + "_" + name);
|
||||
constrainBuilder.append(", DROP FOREIGN KEY `fk_").append(datatableAlias).append("_").append(name).append("` ");
|
||||
}
|
||||
}
|
||||
|
||||
private void registerColumnCodeMapping(Map<String, Long> codeMappings) {
|
||||
if (codeMappings != null && !codeMappings.isEmpty()) {
|
||||
String[] addSqlList = new String[codeMappings.size()];
|
||||
int i = 0;
|
||||
for (Map.Entry<String, Long> mapEntry : codeMappings.entrySet()) {
|
||||
addSqlList[i++] = "insert into x_table_cloumn_code_mappings (column_alias_name, code_id) values ('" + mapEntry.getKey()
|
||||
+ "'," + mapEntry.getValue() + ");";
|
||||
}
|
||||
|
||||
this.jdbcTemplate.batchUpdate(addSqlList);
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteColumnCodeMapping(List<String> columnNames) {
|
||||
if (columnNames != null && !columnNames.isEmpty()) {
|
||||
String[] deleteSqlList = new String[columnNames.size()];
|
||||
int i = 0;
|
||||
for (String columnName : columnNames) {
|
||||
deleteSqlList[i++] = "DELETE FROM x_table_cloumn_code_mappings WHERE column_alias_name='" + columnName + "';";
|
||||
}
|
||||
|
||||
this.jdbcTemplate.batchUpdate(deleteSqlList);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -571,6 +700,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
mapColumnNameDefinition.put(columnHeader.getColumnName(), columnHeader);
|
||||
}
|
||||
|
||||
boolean isConstraintApproach = configurationDomainService.isConstraintApproachEnabledForDatatables();
|
||||
|
||||
if (!StringUtils.isBlank(apptableName)) {
|
||||
validateAppTable(apptableName);
|
||||
|
||||
@@ -610,9 +741,10 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
if (dropColumns != null) {
|
||||
|
||||
StringBuilder sqlBuilder = new StringBuilder("ALTER TABLE `" + datatableName + "`");
|
||||
|
||||
StringBuilder constrainBuilder = new StringBuilder();
|
||||
List<String> codeMappings = new ArrayList<String>();
|
||||
for (JsonElement column : dropColumns) {
|
||||
parseDatatableColumnForDrop(column.getAsJsonObject(), sqlBuilder);
|
||||
parseDatatableColumnForDrop(column.getAsJsonObject(), sqlBuilder, datatableName, constrainBuilder, codeMappings);
|
||||
}
|
||||
|
||||
// Remove the first comma, right after ALTER TABLE `datatable`
|
||||
@@ -620,15 +752,18 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
if (indexOfFirstComma != -1) {
|
||||
sqlBuilder = sqlBuilder.deleteCharAt(indexOfFirstComma);
|
||||
}
|
||||
|
||||
sqlBuilder.append(constrainBuilder);
|
||||
this.jdbcTemplate.execute(sqlBuilder.toString());
|
||||
deleteColumnCodeMapping(codeMappings);
|
||||
}
|
||||
if (addColumns != null) {
|
||||
|
||||
StringBuilder sqlBuilder = new StringBuilder("ALTER TABLE `" + datatableName + "`");
|
||||
|
||||
StringBuilder constrainBuilder = new StringBuilder();
|
||||
Map<String, Long> codeMappings = new HashMap<String, Long>();
|
||||
for (JsonElement column : addColumns) {
|
||||
parseDatatableColumnForAdd(column.getAsJsonObject(), sqlBuilder);
|
||||
parseDatatableColumnForAdd(column.getAsJsonObject(), sqlBuilder, datatableName.toLowerCase().replaceAll("\\s", "_"),
|
||||
constrainBuilder, codeMappings, isConstraintApproach);
|
||||
}
|
||||
|
||||
// Remove the first comma, right after ALTER TABLE `datatable`
|
||||
@@ -636,15 +771,19 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
if (indexOfFirstComma != -1) {
|
||||
sqlBuilder = sqlBuilder.deleteCharAt(indexOfFirstComma);
|
||||
}
|
||||
|
||||
sqlBuilder.append(constrainBuilder);
|
||||
this.jdbcTemplate.execute(sqlBuilder.toString());
|
||||
registerColumnCodeMapping(codeMappings);
|
||||
}
|
||||
if (changeColumns != null) {
|
||||
|
||||
StringBuilder sqlBuilder = new StringBuilder("ALTER TABLE `" + datatableName + "`");
|
||||
|
||||
StringBuilder constrainBuilder = new StringBuilder();
|
||||
Map<String, Long> codeMappings = new HashMap<String, Long>();
|
||||
List<String> removeMappings = new ArrayList<String>();
|
||||
for (JsonElement column : changeColumns) {
|
||||
parseDatatableColumnForUpdate(column.getAsJsonObject(), mapColumnNameDefinition, sqlBuilder);
|
||||
parseDatatableColumnForUpdate(column.getAsJsonObject(), mapColumnNameDefinition, sqlBuilder, datatableName,
|
||||
constrainBuilder, codeMappings, removeMappings, isConstraintApproach);
|
||||
}
|
||||
|
||||
// Remove the first comma, right after ALTER TABLE `datatable`
|
||||
@@ -652,8 +791,15 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
if (indexOfFirstComma != -1) {
|
||||
sqlBuilder = sqlBuilder.deleteCharAt(indexOfFirstComma);
|
||||
}
|
||||
|
||||
this.jdbcTemplate.execute(sqlBuilder.toString());
|
||||
sqlBuilder.append(constrainBuilder);
|
||||
try {
|
||||
this.jdbcTemplate.execute(sqlBuilder.toString());
|
||||
deleteColumnCodeMapping(removeMappings);
|
||||
registerColumnCodeMapping(codeMappings);
|
||||
} catch (GenericJDBCException e) {
|
||||
if (e.getMessage().contains("Error on rename")) { throw new PlatformServiceUnavailableException(
|
||||
"error.msg.datatable.column.update.not.allowed", "One of the column name modification not allowed"); }
|
||||
}
|
||||
}
|
||||
} catch (SQLGrammarException e) {
|
||||
Throwable realCause = e.getCause();
|
||||
|
||||
Reference in New Issue
Block a user