From fda126474cb18b8ed0da7213a4d4c790261dc59d Mon Sep 17 00:00:00 2001 From: Vishwas Babu AJ Date: Tue, 25 Jun 2013 15:23:45 +0530 Subject: [PATCH] datatable delete apis should only delete registered datatables --- .../ReadWriteNonCoreDataServiceImpl.java | 604 +++++++++--------- 1 file changed, 296 insertions(+), 308 deletions(-) diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java index d19c35c46..f79c73b85 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java @@ -58,13 +58,20 @@ import com.google.gson.reflect.TypeToken; @Service public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataService { - 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 DATATABLE_NAME_REGEX_PATTERN = "^[a-zA-Z][a-zA-Z0-9\\-_\\s]{0,48}[a-zA-Z0-9]$"; private final static Logger logger = LoggerFactory.getLogger(ReadWriteNonCoreDataServiceImpl.class); - private final static HashMap apiTypeToMySQL = new HashMap() {{ - put("String", "VARCHAR"); put("Number", "INT"); put("Decimal", "DECIMAL"); put("Date", "DATE"); - put("Text", "TEXT"); put ("Dropdown", "INT"); - }}; + private final static HashMap apiTypeToMySQL = new HashMap() { + + { + put("String", "VARCHAR"); + put("Number", "INT"); + put("Decimal", "DECIMAL"); + put("Date", "DATE"); + put("Text", "TEXT"); + put("Dropdown", "INT"); + } + }; private final JdbcTemplate jdbcTemplate; private final DataSource dataSource; @@ -282,396 +289,377 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ } } + private boolean isRegisteredDataTable(final String name) { + // PERMITTED datatables + final String sql = "select if((exists (select 1 from x_registered_table where registered_table_name = ?)) = 1, 'true', 'false')"; + final String isRegisteredDataTable = this.jdbcTemplate.queryForObject(sql, String.class, new Object[] { name }); + return new Boolean(isRegisteredDataTable); + } + private void validateDatatableName(final String name) { - - if (name == null || name.isEmpty()) { - throw new PlatformDataIntegrityException("error.msg.datatables.datatable.null.name", - "Data table name must not be blank."); - } else if (!name.matches(DATATABLE_NAME_REGEX_PATTERN)) { - throw new PlatformDataIntegrityException("error.msg.datatables.datatable.invalid.name.regex", - "Invalid data table name.", name); - } + + if (name == null || name.isEmpty()) { + throw new PlatformDataIntegrityException("error.msg.datatables.datatable.null.name", "Data table name must not be blank."); + } else if (!name.matches(DATATABLE_NAME_REGEX_PATTERN)) { throw new PlatformDataIntegrityException( + "error.msg.datatables.datatable.invalid.name.regex", "Invalid data table name.", name); } } private String datatableColumnNameToCodeValueName(final String columnName, final String code) { - return (code + "_cd_" + columnName); + return (code + "_cd_" + columnName); } private void throwExceptionIfValidationWarningsExist(final List dataValidationErrors) { if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); } } - + private void parseDatatableColumnObjectForCreate(final JsonObject column, StringBuilder sqlBuilder) { - - String name = (column.has("name")) ? column.get("name").getAsString() : null; - String type = (column.has("type")) ? column.get("type").getAsString() : null; - Integer length = (column.has("length")) ? column.get("length").getAsInt() : null; - Boolean mandatory = (column.has("mandatory")) ? column.get("mandatory").getAsBoolean() : false; - String code = (column.has("code")) ? column.get("code").getAsString() : null; - if (StringUtils.isNotBlank(code)) { - name = datatableColumnNameToCodeValueName(name, code); - } + String name = (column.has("name")) ? column.get("name").getAsString() : null; + String type = (column.has("type")) ? column.get("type").getAsString() : null; + Integer length = (column.has("length")) ? column.get("length").getAsInt() : null; + Boolean mandatory = (column.has("mandatory")) ? column.get("mandatory").getAsBoolean() : false; + String code = (column.has("code")) ? column.get("code").getAsString() : null; - String mysqlType = apiTypeToMySQL.get(type); - sqlBuilder = sqlBuilder.append("`" + name + "` " + mysqlType); + if (StringUtils.isNotBlank(code)) { + name = datatableColumnNameToCodeValueName(name, code); + } - if (type != null) - { - if (type.equals("String")) { - sqlBuilder = sqlBuilder.append("(" + length + ")"); - } else if (type.equals("Decimal")) { - sqlBuilder = sqlBuilder.append("(19,6)"); - } else if (type.equals("Dropdown")) { - sqlBuilder = sqlBuilder.append("(11)"); - } - } - if (mandatory != null) { - if (mandatory) { - sqlBuilder = sqlBuilder.append(" NOT NULL"); - } else { - sqlBuilder = sqlBuilder.append(" DEFAULT NULL"); - } - } + String mysqlType = apiTypeToMySQL.get(type); + sqlBuilder = sqlBuilder.append("`" + name + "` " + mysqlType); - sqlBuilder = sqlBuilder.append(", "); + if (type != null) { + if (type.equals("String")) { + sqlBuilder = sqlBuilder.append("(" + length + ")"); + } else if (type.equals("Decimal")) { + sqlBuilder = sqlBuilder.append("(19,6)"); + } else if (type.equals("Dropdown")) { + sqlBuilder = sqlBuilder.append("(11)"); + } + } + if (mandatory != null) { + if (mandatory) { + sqlBuilder = sqlBuilder.append(" NOT NULL"); + } else { + sqlBuilder = sqlBuilder.append(" DEFAULT NULL"); + } + } + + sqlBuilder = sqlBuilder.append(", "); } @Transactional @Override public CommandProcessingResult createDatatable(final JsonCommand command) { - String datatableName = null; + String datatableName = null; - try { - context.authenticatedUser(); - this.fromApiJsonDeserializer.validateForCreate(command.json()); + try { + context.authenticatedUser(); + this.fromApiJsonDeserializer.validateForCreate(command.json()); - JsonElement element = this.fromJsonHelper.parse(command.json()); - JsonArray columns = this.fromJsonHelper.extractJsonArrayNamed("columns", element); - datatableName = this.fromJsonHelper.extractStringNamed("datatableName", element); - String apptableName = this.fromJsonHelper.extractStringNamed("apptableName", element); - Boolean multiRow = this.fromJsonHelper.extractBooleanNamed("multiRow", element); + JsonElement element = this.fromJsonHelper.parse(command.json()); + JsonArray columns = this.fromJsonHelper.extractJsonArrayNamed("columns", element); + datatableName = this.fromJsonHelper.extractStringNamed("datatableName", element); + String apptableName = this.fromJsonHelper.extractStringNamed("apptableName", element); + Boolean multiRow = this.fromJsonHelper.extractBooleanNamed("multiRow", element); - if (multiRow == null) { - multiRow = false; - } + if (multiRow == null) { + multiRow = false; + } - validateDatatableName(datatableName); - validateAppTable(apptableName); + validateDatatableName(datatableName); + validateAppTable(apptableName); - String fkColumnName = apptableName.substring(2) + "_id"; - String fkName = datatableName.toLowerCase().replaceAll("\\s", "_") + "_" + fkColumnName; - StringBuilder sqlBuilder = new StringBuilder(); - sqlBuilder = sqlBuilder.append("CREATE TABLE `" + datatableName + "` ("); + String fkColumnName = apptableName.substring(2) + "_id"; + String fkName = datatableName.toLowerCase().replaceAll("\\s", "_") + "_" + fkColumnName; + StringBuilder sqlBuilder = new StringBuilder(); + sqlBuilder = sqlBuilder.append("CREATE TABLE `" + datatableName + "` ("); - if (multiRow) { - sqlBuilder = sqlBuilder - .append("`id` BIGINT(20) NOT NULL AUTO_INCREMENT, ") - .append("`" + fkColumnName + "` BIGINT(20) NOT NULL, "); - } else { - sqlBuilder = sqlBuilder - .append("`" + fkColumnName + "` BIGINT(20) NOT NULL, "); - } + if (multiRow) { + sqlBuilder = sqlBuilder.append("`id` BIGINT(20) NOT NULL AUTO_INCREMENT, ").append( + "`" + fkColumnName + "` BIGINT(20) NOT NULL, "); + } else { + sqlBuilder = sqlBuilder.append("`" + fkColumnName + "` BIGINT(20) NOT NULL, "); + } - for (JsonElement column : columns) { - parseDatatableColumnObjectForCreate(column.getAsJsonObject(), sqlBuilder); - } + for (JsonElement column : columns) { + parseDatatableColumnObjectForCreate(column.getAsJsonObject(), sqlBuilder); + } - // Remove trailing comma and space - sqlBuilder = sqlBuilder.delete(sqlBuilder.length() - 2, sqlBuilder.length()); + // Remove trailing comma and space + sqlBuilder = sqlBuilder.delete(sqlBuilder.length() - 2, sqlBuilder.length()); - if (multiRow) { - sqlBuilder = sqlBuilder - .append(", PRIMARY KEY (`id`)") - .append(", KEY `fk_" + apptableName.substring(2) + "_id` (`" + fkColumnName + "`)") - .append(", CONSTRAINT `fk_" + fkName + "` ") - .append("FOREIGN KEY (`" + fkColumnName + "`) ") - .append("REFERENCES `" + apptableName + "` (`id`)"); - } else { - sqlBuilder = sqlBuilder - .append(", PRIMARY KEY (`" + fkColumnName + "`)") - .append(", CONSTRAINT `fk_" + fkName + "` ") - .append("FOREIGN KEY (`" + fkColumnName + "`) ") - .append("REFERENCES `" + apptableName + "` (`id`)"); - } + if (multiRow) { + sqlBuilder = sqlBuilder.append(", PRIMARY KEY (`id`)") + .append(", KEY `fk_" + apptableName.substring(2) + "_id` (`" + fkColumnName + "`)") + .append(", CONSTRAINT `fk_" + fkName + "` ").append("FOREIGN KEY (`" + fkColumnName + "`) ") + .append("REFERENCES `" + apptableName + "` (`id`)"); + } else { + sqlBuilder = sqlBuilder.append(", PRIMARY KEY (`" + fkColumnName + "`)").append(", CONSTRAINT `fk_" + fkName + "` ") + .append("FOREIGN KEY (`" + fkColumnName + "`) ").append("REFERENCES `" + apptableName + "` (`id`)"); + } - sqlBuilder = sqlBuilder.append(") ENGINE=InnoDB DEFAULT CHARSET=utf8;"); - this.jdbcTemplate.execute(sqlBuilder.toString()); + sqlBuilder = sqlBuilder.append(") ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + this.jdbcTemplate.execute(sqlBuilder.toString()); + + registerDatatable(datatableName, apptableName); + } catch (SQLGrammarException e) { + Throwable realCause = e.getCause(); + List dataValidationErrors = new ArrayList(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("datatable"); + + if (realCause.getMessage().toLowerCase().contains("duplicate column name")) { + baseDataValidator.reset().parameter("name").failWithCode("duplicate.column.name"); + } else if (realCause.getMessage().contains("Table") && realCause.getMessage().contains("already exists")) { + baseDataValidator.reset().parameter("datatableName").value(datatableName).failWithCode("datatable.already.exists"); + } - registerDatatable(datatableName, apptableName); - } catch (SQLGrammarException e) { - Throwable realCause = e.getCause(); - List dataValidationErrors = new ArrayList(); - final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("datatable"); - - if (realCause.getMessage().toLowerCase().contains("duplicate column name")) { - baseDataValidator.reset().parameter("name").failWithCode("duplicate.column.name"); - } else if (realCause.getMessage().contains("Table") && realCause.getMessage().contains("already exists")) { - baseDataValidator.reset().parameter("datatableName").value(datatableName) - .failWithCode("datatable.already.exists"); - } - throwExceptionIfValidationWarningsExist(dataValidationErrors); - } + } - return new CommandProcessingResultBuilder() - .withCommandId(command.commandId()) - .withResourceIdAsString(datatableName) - .build(); + return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withResourceIdAsString(datatableName).build(); } private void parseDatatableColumnForUpdate(final JsonObject column, - final Map mapColumnNameDefinition, StringBuilder sqlBuilder) { + final Map mapColumnNameDefinition, StringBuilder sqlBuilder) { - String name = (column.has("name")) ? column.get("name").getAsString() : null; - String lengthStr = (column.has("length")) ? column.get("length").getAsString() : null; - Integer length = (StringUtils.isNotBlank(lengthStr)) ? Integer.parseInt(lengthStr) : null; - String newName = (column.has("newName")) ? column.get("newName").getAsString() : name; - Boolean mandatory = (column.has("mandatory")) ? column.get("mandatory").getAsBoolean() : false; - 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 name = (column.has("name")) ? column.get("name").getAsString() : null; + String lengthStr = (column.has("length")) ? column.get("length").getAsString() : null; + Integer length = (StringUtils.isNotBlank(lengthStr)) ? Integer.parseInt(lengthStr) : null; + String newName = (column.has("newName")) ? column.get("newName").getAsString() : name; + Boolean mandatory = (column.has("mandatory")) ? column.get("mandatory").getAsBoolean() : false; + 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; - if (StringUtils.isNotBlank(code)) { - name = datatableColumnNameToCodeValueName(name, code); + if (StringUtils.isNotBlank(code)) { + name = datatableColumnNameToCodeValueName(name, code); - if (StringUtils.isNotBlank(newCode)) { - newName = datatableColumnNameToCodeValueName(newName, newCode); - } else { - newName = datatableColumnNameToCodeValueName(newName, 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); - } + 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(); - } + String type = mapColumnNameDefinition.get(name).getColumnType(); + if (length == null && type.toLowerCase().equals("varchar")) { + length = mapColumnNameDefinition.get(name).getColumnLength().intValue(); + } - sqlBuilder = sqlBuilder.append(", CHANGE `" + name + "` `" + newName + "` " + type); - if (length != null && length > 0) { - if (type.toLowerCase().equals("decimal")) { - sqlBuilder.append("(19,6)"); - } else if (type.toLowerCase().equals("varchar")) { - sqlBuilder.append("(" + length + ")"); - } - } + sqlBuilder = sqlBuilder.append(", CHANGE `" + name + "` `" + newName + "` " + type); + if (length != null && length > 0) { + if (type.toLowerCase().equals("decimal")) { + sqlBuilder.append("(19,6)"); + } else if (type.toLowerCase().equals("varchar")) { + sqlBuilder.append("(" + length + ")"); + } + } - if (mandatory != null) { - if (mandatory) { - sqlBuilder = sqlBuilder.append(" NOT NULL"); - } else { - sqlBuilder = sqlBuilder.append(" DEFAULT NULL"); - } - } - if (after != null) { - sqlBuilder = sqlBuilder.append(" AFTER `" + after + "`"); - } + if (mandatory != null) { + if (mandatory) { + sqlBuilder = sqlBuilder.append(" NOT NULL"); + } else { + sqlBuilder = sqlBuilder.append(" DEFAULT NULL"); + } + } + if (after != null) { + sqlBuilder = sqlBuilder.append(" AFTER `" + after + "`"); + } } private void parseDatatableColumnForAdd(final JsonObject column, StringBuilder sqlBuilder) { - String name = (column.has("name")) ? column.get("name").getAsString() : null; - String type = (column.has("type")) ? column.get("type").getAsString() : null; - Integer length = (column.has("length")) ? column.get("length").getAsInt() : null; - Boolean mandatory = (column.has("mandatory")) ? column.get("mandatory").getAsBoolean() : false; - String after = (column.has("after")) ? column.get("after").getAsString() : null; - String code = (column.has("code")) ? column.get("code").getAsString() : null; + String name = (column.has("name")) ? column.get("name").getAsString() : null; + String type = (column.has("type")) ? column.get("type").getAsString() : null; + Integer length = (column.has("length")) ? column.get("length").getAsInt() : null; + Boolean mandatory = (column.has("mandatory")) ? column.get("mandatory").getAsBoolean() : false; + String after = (column.has("after")) ? column.get("after").getAsString() : null; + String code = (column.has("code")) ? column.get("code").getAsString() : null; - if (StringUtils.isNotBlank(code)) { - name = datatableColumnNameToCodeValueName(name, code); - } + if (StringUtils.isNotBlank(code)) { + name = datatableColumnNameToCodeValueName(name, code); + } - String mysqlType = apiTypeToMySQL.get(type); - sqlBuilder = sqlBuilder.append(", ADD `" + name + "` " + mysqlType); + String mysqlType = apiTypeToMySQL.get(type); + sqlBuilder = sqlBuilder.append(", ADD `" + name + "` " + mysqlType); - if (type != null) { - if (type.equals("String") && length != null) { - sqlBuilder = sqlBuilder.append("(" + length + ")"); - } else if (type.equals("Decimal")) { - sqlBuilder = sqlBuilder.append("(19,6)"); - } else if (type.equals("Dropdown")) { - sqlBuilder = sqlBuilder.append("(11)"); - } - } - if (mandatory != null) { - if (mandatory) { - sqlBuilder = sqlBuilder.append(" NOT NULL"); - } else { - sqlBuilder = sqlBuilder.append(" DEFAULT NULL"); - } - } - if (after != null) { - sqlBuilder = sqlBuilder.append(" AFTER `" + after + "`"); - } + if (type != null) { + if (type.equals("String") && length != null) { + sqlBuilder = sqlBuilder.append("(" + length + ")"); + } else if (type.equals("Decimal")) { + sqlBuilder = sqlBuilder.append("(19,6)"); + } else if (type.equals("Dropdown")) { + sqlBuilder = sqlBuilder.append("(11)"); + } + } + if (mandatory != null) { + if (mandatory) { + sqlBuilder = sqlBuilder.append(" NOT NULL"); + } else { + sqlBuilder = sqlBuilder.append(" DEFAULT NULL"); + } + } + if (after != null) { + sqlBuilder = sqlBuilder.append(" AFTER `" + after + "`"); + } } - private void parseDatatableColumnForDrop(final JsonObject column, StringBuilder sqlBuilder) { + private void parseDatatableColumnForDrop(final JsonObject column, StringBuilder sqlBuilder) { - String name = (column.has("name")) ? column.get("name").getAsString() : null; + String name = (column.has("name")) ? column.get("name").getAsString() : null; - sqlBuilder = sqlBuilder.append(", DROP COLUMN `" + name + "`"); - } + sqlBuilder = sqlBuilder.append(", DROP COLUMN `" + name + "`"); + } @Transactional @Override public void updateDatatable(final String datatableName, final JsonCommand command) { - try { - context.authenticatedUser(); - this.fromApiJsonDeserializer.validateForUpdate(command.json()); + try { + context.authenticatedUser(); + this.fromApiJsonDeserializer.validateForUpdate(command.json()); - JsonElement element = this.fromJsonHelper.parse(command.json()); - JsonArray changeColumns = this.fromJsonHelper.extractJsonArrayNamed("changeColumns", element); - JsonArray addColumns = this.fromJsonHelper.extractJsonArrayNamed("addColumns", element); - JsonArray dropColumns = this.fromJsonHelper.extractJsonArrayNamed("dropColumns", element); - String apptableName = this.fromJsonHelper.extractStringNamed("apptableName", element); + JsonElement element = this.fromJsonHelper.parse(command.json()); + JsonArray changeColumns = this.fromJsonHelper.extractJsonArrayNamed("changeColumns", element); + JsonArray addColumns = this.fromJsonHelper.extractJsonArrayNamed("addColumns", element); + JsonArray dropColumns = this.fromJsonHelper.extractJsonArrayNamed("dropColumns", element); + String apptableName = this.fromJsonHelper.extractStringNamed("apptableName", element); - validateDatatableName(datatableName); - - List columnHeaderData = this.genericDataService.fillResultsetColumnHeaders(datatableName); - Map mapColumnNameDefinition = new HashMap(); - for (ResultsetColumnHeaderData columnHeader : columnHeaderData) { - mapColumnNameDefinition.put(columnHeader.getColumnName(), columnHeader); - } + validateDatatableName(datatableName); - if (!StringUtils.isBlank(apptableName)) { - validateAppTable(apptableName); + List columnHeaderData = this.genericDataService.fillResultsetColumnHeaders(datatableName); + Map mapColumnNameDefinition = new HashMap(); + for (ResultsetColumnHeaderData columnHeader : columnHeaderData) { + mapColumnNameDefinition.put(columnHeader.getColumnName(), columnHeader); + } - String oldApptableName = this.queryForApplicationTableName(datatableName); - if (!StringUtils.equals(oldApptableName, apptableName)) { - String oldFKName = oldApptableName.substring(2) + "_id"; - String newFKName = apptableName.substring(2) + "_id"; - String oldConstraintName = datatableName.toLowerCase().replaceAll("\\s", "_") + "_" + oldFKName; - String newConstraintName = datatableName.toLowerCase().replaceAll("\\s", "_") + "_" + newFKName; - StringBuilder sqlBuilder = new StringBuilder(); - - if (mapColumnNameDefinition.containsKey("id")) { - sqlBuilder = sqlBuilder - .append("ALTER TABLE `" + datatableName + "` ") - .append("DROP KEY `fk_" + oldFKName + "`,") - .append("DROP FOREIGN KEY `fk_" + oldConstraintName + "`,") - .append("CHANGE COLUMN `" + oldFKName + "` `" + newFKName + "` BIGINT(20) NOT NULL,") - .append("ADD KEY `fk_" + newFKName + "` (`" + newFKName + "`),") - .append("ADD CONSTRAINT `fk_" + newConstraintName + "` ") - .append("FOREIGN KEY (`" + newFKName + "`) ") - .append("REFERENCES `" + apptableName + "` (`id`)"); - } else { - sqlBuilder = sqlBuilder - .append("ALTER TABLE `" + datatableName + "` ") - .append("DROP FOREIGN KEY `fk_" + oldConstraintName + "`,") - .append("CHANGE COLUMN `" + oldFKName + "` `" + newFKName + "` BIGINT(20) NOT NULL,") - .append("ADD CONSTRAINT `fk_" + newConstraintName + "` ") - .append("FOREIGN KEY (`" + newFKName + "`) ") - .append("REFERENCES `" + apptableName + "` (`id`)"); - } - - this.jdbcTemplate.execute(sqlBuilder.toString()); - - deregisterDatatable(datatableName); - registerDatatable(datatableName, apptableName); - } - } + if (!StringUtils.isBlank(apptableName)) { + validateAppTable(apptableName); - if (changeColumns == null && addColumns == null && dropColumns == null) { - return; - } + String oldApptableName = this.queryForApplicationTableName(datatableName); + if (!StringUtils.equals(oldApptableName, apptableName)) { + String oldFKName = oldApptableName.substring(2) + "_id"; + String newFKName = apptableName.substring(2) + "_id"; + String oldConstraintName = datatableName.toLowerCase().replaceAll("\\s", "_") + "_" + oldFKName; + String newConstraintName = datatableName.toLowerCase().replaceAll("\\s", "_") + "_" + newFKName; + StringBuilder sqlBuilder = new StringBuilder(); - if (dropColumns != null) { + if (mapColumnNameDefinition.containsKey("id")) { + sqlBuilder = sqlBuilder.append("ALTER TABLE `" + datatableName + "` ").append("DROP KEY `fk_" + oldFKName + "`,") + .append("DROP FOREIGN KEY `fk_" + oldConstraintName + "`,") + .append("CHANGE COLUMN `" + oldFKName + "` `" + newFKName + "` BIGINT(20) NOT NULL,") + .append("ADD KEY `fk_" + newFKName + "` (`" + newFKName + "`),") + .append("ADD CONSTRAINT `fk_" + newConstraintName + "` ").append("FOREIGN KEY (`" + newFKName + "`) ") + .append("REFERENCES `" + apptableName + "` (`id`)"); + } else { + sqlBuilder = sqlBuilder.append("ALTER TABLE `" + datatableName + "` ") + .append("DROP FOREIGN KEY `fk_" + oldConstraintName + "`,") + .append("CHANGE COLUMN `" + oldFKName + "` `" + newFKName + "` BIGINT(20) NOT NULL,") + .append("ADD CONSTRAINT `fk_" + newConstraintName + "` ").append("FOREIGN KEY (`" + newFKName + "`) ") + .append("REFERENCES `" + apptableName + "` (`id`)"); + } - StringBuilder sqlBuilder = new StringBuilder("ALTER TABLE `" + datatableName + "`"); + this.jdbcTemplate.execute(sqlBuilder.toString()); - for (JsonElement column : dropColumns) { - parseDatatableColumnForDrop(column.getAsJsonObject(), sqlBuilder); - } + deregisterDatatable(datatableName); + registerDatatable(datatableName, apptableName); + } + } - // Remove the first comma, right after ALTER TABLE `datatable` - int indexOfFirstComma = sqlBuilder.indexOf(","); - if (indexOfFirstComma != -1) { - sqlBuilder = sqlBuilder.deleteCharAt(indexOfFirstComma); - } + if (changeColumns == null && addColumns == null && dropColumns == null) { return; } - this.jdbcTemplate.execute(sqlBuilder.toString()); - } - if (addColumns != null) { + if (dropColumns != null) { - StringBuilder sqlBuilder = new StringBuilder("ALTER TABLE `" + datatableName + "`"); + StringBuilder sqlBuilder = new StringBuilder("ALTER TABLE `" + datatableName + "`"); - for (JsonElement column : addColumns) { - parseDatatableColumnForAdd(column.getAsJsonObject(), sqlBuilder); - } + for (JsonElement column : dropColumns) { + parseDatatableColumnForDrop(column.getAsJsonObject(), sqlBuilder); + } - // Remove the first comma, right after ALTER TABLE `datatable` - int indexOfFirstComma = sqlBuilder.indexOf(","); - if (indexOfFirstComma != -1) { - sqlBuilder = sqlBuilder.deleteCharAt(indexOfFirstComma); - } - - this.jdbcTemplate.execute(sqlBuilder.toString()); - } - if (changeColumns != null) { + // Remove the first comma, right after ALTER TABLE `datatable` + int indexOfFirstComma = sqlBuilder.indexOf(","); + if (indexOfFirstComma != -1) { + sqlBuilder = sqlBuilder.deleteCharAt(indexOfFirstComma); + } - StringBuilder sqlBuilder = new StringBuilder("ALTER TABLE `" + datatableName + "`"); + this.jdbcTemplate.execute(sqlBuilder.toString()); + } + if (addColumns != null) { - for (JsonElement column : changeColumns) { - parseDatatableColumnForUpdate(column.getAsJsonObject(), mapColumnNameDefinition, sqlBuilder); - } + StringBuilder sqlBuilder = new StringBuilder("ALTER TABLE `" + datatableName + "`"); - // Remove the first comma, right after ALTER TABLE `datatable` - int indexOfFirstComma = sqlBuilder.indexOf(","); - if (indexOfFirstComma != -1) { - sqlBuilder = sqlBuilder.deleteCharAt(indexOfFirstComma); - } + for (JsonElement column : addColumns) { + parseDatatableColumnForAdd(column.getAsJsonObject(), sqlBuilder); + } - this.jdbcTemplate.execute(sqlBuilder.toString()); - } - } catch (SQLGrammarException e) { - Throwable realCause = e.getCause(); - List dataValidationErrors = new ArrayList(); - final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("datatable"); + // Remove the first comma, right after ALTER TABLE `datatable` + int indexOfFirstComma = sqlBuilder.indexOf(","); + if (indexOfFirstComma != -1) { + sqlBuilder = sqlBuilder.deleteCharAt(indexOfFirstComma); + } - if (realCause.getMessage().toLowerCase().contains("unknown column")) { - baseDataValidator.reset().parameter("name").failWithCode("does.not.exist"); - } else if (realCause.getMessage().toLowerCase().contains("can't drop")) { - baseDataValidator.reset().parameter("name").failWithCode("does.not.exist"); - } else if (realCause.getMessage().toLowerCase().contains("duplicate column")) { - baseDataValidator.reset().parameter("name").failWithCode("column.already.exists"); - } + this.jdbcTemplate.execute(sqlBuilder.toString()); + } + if (changeColumns != null) { - throwExceptionIfValidationWarningsExist(dataValidationErrors); - } + StringBuilder sqlBuilder = new StringBuilder("ALTER TABLE `" + datatableName + "`"); + + for (JsonElement column : changeColumns) { + parseDatatableColumnForUpdate(column.getAsJsonObject(), mapColumnNameDefinition, sqlBuilder); + } + + // Remove the first comma, right after ALTER TABLE `datatable` + int indexOfFirstComma = sqlBuilder.indexOf(","); + if (indexOfFirstComma != -1) { + sqlBuilder = sqlBuilder.deleteCharAt(indexOfFirstComma); + } + + this.jdbcTemplate.execute(sqlBuilder.toString()); + } + } catch (SQLGrammarException e) { + Throwable realCause = e.getCause(); + List dataValidationErrors = new ArrayList(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("datatable"); + + if (realCause.getMessage().toLowerCase().contains("unknown column")) { + baseDataValidator.reset().parameter("name").failWithCode("does.not.exist"); + } else if (realCause.getMessage().toLowerCase().contains("can't drop")) { + baseDataValidator.reset().parameter("name").failWithCode("does.not.exist"); + } else if (realCause.getMessage().toLowerCase().contains("duplicate column")) { + baseDataValidator.reset().parameter("name").failWithCode("column.already.exists"); + } + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } } @Transactional @Override public void deleteDatatable(final String datatableName) { - try { - context.authenticatedUser(); + try { + context.authenticatedUser(); + if (!isRegisteredDataTable(datatableName)) { throw new DatatableNotFoundException(datatableName); } + validateDatatableName(datatableName); + deregisterDatatable(datatableName); + String sql = "DROP TABLE `" + datatableName + "`"; + this.jdbcTemplate.execute(sql); + } catch (SQLGrammarException e) { + Throwable realCause = e.getCause(); + List dataValidationErrors = new ArrayList(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("datatable"); + if (realCause.getMessage().contains("Unknown table")) { + baseDataValidator.reset().parameter("datatableName").failWithCode("does.not.exist"); + } - validateDatatableName(datatableName); - deregisterDatatable(datatableName); - - String sql = "DROP TABLE `" + datatableName + "`"; - this.jdbcTemplate.execute(sql); - } catch (SQLGrammarException e) { - Throwable realCause = e.getCause(); - List dataValidationErrors = new ArrayList(); - final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("datatable"); - - if (realCause.getMessage().contains("Unknown table")) { - baseDataValidator.reset().parameter("datatableName").failWithCode("does.not.exist"); - } - - throwExceptionIfValidationWarningsExist(dataValidationErrors); - } + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } } @Transactional