FINERACT-1911: Alter datatable - column update, delete fix

This commit is contained in:
jmarta
2023-08-25 10:56:09 +02:00
committed by Adam Saghy
parent 2f4705952b
commit ee31ff0ed8
6 changed files with 235 additions and 205 deletions
@@ -78,12 +78,12 @@ public enum JdbcJavaType {
// seconds field, but by default, there is no explicit bound on precision
TIME(JavaType.LOCAL_TIME, new DialectType(JDBCType.TIME), new DialectType(JDBCType.TIME, null, "TIME WITHOUT TIME ZONE")), //
TIME_WITH_TIMEZONE(JavaType.OFFSET_TIME, new DialectType(JDBCType.TIME_WITH_TIMEZONE, "TIME"),
new DialectType(JDBCType.TIME_WITH_TIMEZONE, null, "TIME WITH TIME ZONE")), //
new DialectType(JDBCType.TIME_WITH_TIMEZONE, "TIME WITH TIME ZONE")), //
TIMESTAMP(JavaType.LOCAL_DATETIME, new DialectType(JDBCType.TIMESTAMP),
new DialectType(JDBCType.TIMESTAMP, null, "TIMESTAMP WITHOUT TIME ZONE")), //
DATETIME(JavaType.LOCAL_DATETIME, new DialectType(JDBCType.TIMESTAMP, "DATETIME"), new DialectType(JDBCType.TIMESTAMP)), //
TIMESTAMP_WITH_TIMEZONE(JavaType.OFFSET_DATETIME, new DialectType(JDBCType.TIMESTAMP_WITH_TIMEZONE, null, "DATETIME"),
new DialectType(JDBCType.TIMESTAMP_WITH_TIMEZONE, null, "TIMESTAMP WITH TIME ZONE", "TIMESTAMPTZ")), //
TIMESTAMP_WITH_TIMEZONE(JavaType.OFFSET_DATETIME, new DialectType(JDBCType.TIMESTAMP_WITH_TIMEZONE, "DATETIME"),
new DialectType(JDBCType.TIMESTAMP_WITH_TIMEZONE, "TIMESTAMP WITH TIME ZONE", "TIMESTAMPTZ")), //
INTERVAL(JavaType.TIME, new DialectType(JDBCType.TIME), new DialectType(JDBCType.TIME, "INTERVAL")), //
BINARY(JavaType.BINARY, new DialectType(JDBCType.BINARY, true), new DialectType(JDBCType.BINARY, "BYTEA")), //
VARBINARY(JavaType.BINARY, new DialectType(JDBCType.VARBINARY, true), new DialectType(JDBCType.VARBINARY, "BYTEA")), //
@@ -54,8 +54,10 @@ public class PostgreSQLQueryService implements DatabaseQueryService {
@Override
public SqlRowSet getTableColumns(DataSource dataSource, String tableName) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String sql = "SELECT attname AS COLUMN_NAME, not attnotnull AS IS_NULLABLE, atttypid::regtype AS DATATYPE, attlen AS CHARACTER_MAXIMUM_LENGTH, attnum = 1 AS COLUMN_KEY FROM pg_attribute WHERE attrelid = '\""
+ tableName + "\"'::regclass AND attnum > 0 AND NOT attisdropped ORDER BY attnum";
String sql = "SELECT column_name, is_nullable, data_type,"
+ " coalesce(character_maximum_length, numeric_precision, datetime_precision) AS max_length, ordinal_position = 1 AS column_key"
+ " FROM information_schema.columns WHERE table_catalog = current_catalog AND table_schema = current_schema AND table_name = '"
+ tableName + "' ORDER BY ordinal_position";
final SqlRowSet columnDefinitions = jdbcTemplate.queryForRowSet(sql); // NOSONAR
if (columnDefinitions.next()) {
return columnDefinitions;
@@ -520,7 +520,6 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
}
private String datatableColumnNameToCodeValueName(final String columnName, final String code) {
return code + "_cd_" + columnName;
}
@@ -537,17 +536,17 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
String name = column.has(API_FIELD_NAME) ? column.get(API_FIELD_NAME).getAsString() : null;
final String type = column.has(API_FIELD_TYPE) ? column.get(API_FIELD_TYPE).getAsString().toLowerCase() : null;
final Integer length = column.has(API_FIELD_LENGTH) ? column.get(API_FIELD_LENGTH).getAsInt() : null;
final Boolean mandatory = column.has(API_FIELD_MANDATORY) ? column.get(API_FIELD_MANDATORY).getAsBoolean() : false;
final Boolean unique = column.has(API_FIELD_UNIQUE) ? column.get(API_FIELD_UNIQUE).getAsBoolean() : false;
final boolean mandatory = column.has(API_FIELD_MANDATORY) && column.get(API_FIELD_MANDATORY).getAsBoolean();
final boolean unique = column.has(API_FIELD_UNIQUE) && column.get(API_FIELD_UNIQUE).getAsBoolean();
final String code = column.has(API_FIELD_CODE) ? column.get(API_FIELD_CODE).getAsString() : null;
if (StringUtils.isNotBlank(code)) {
if (isConstraintApproach) {
codeMappings.put(dataTableNameAlias + "_" + name, this.codeReadPlatformService.retriveCode(code).getId());
String fkName = "fk_" + dataTableNameAlias + "_" + name;
constrainBuilder.append(", CONSTRAINT ").append(sqlGenerator.escape(fkName)).append(" ")
.append("FOREIGN KEY (" + sqlGenerator.escape(name) + ") ").append("REFERENCES ")
.append(sqlGenerator.escape(CODE_VALUES_TABLE)).append(" (id)");
constrainBuilder.append(", CONSTRAINT ").append(sqlGenerator.escape(fkName)).append(" ").append("FOREIGN KEY (")
.append(sqlGenerator.escape(name)).append(") ").append("REFERENCES ").append(sqlGenerator.escape(CODE_VALUES_TABLE))
.append(" (id)");
} else {
name = datatableColumnNameToCodeValueName(name, code);
}
@@ -602,7 +601,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
final String dataTableNameAlias = datatableName.toLowerCase().replaceAll("\\s", "_");
final String fkName = dataTableNameAlias + "_" + fkColumnName;
StringBuilder sqlBuilder = new StringBuilder();
sqlBuilder.append("CREATE TABLE " + sqlGenerator.escape(datatableName) + " (");
sqlBuilder.append("CREATE TABLE ").append(sqlGenerator.escape(datatableName)).append(" (");
if (multiRow) {
if (databaseTypeResolver.isMySQL()) {
@@ -614,7 +613,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
throw new IllegalStateException("Current database is not supported");
}
}
sqlBuilder.append(sqlGenerator.escape(fkColumnName) + " BIGINT NOT NULL, ");
sqlBuilder.append(sqlGenerator.escape(fkColumnName)).append(" BIGINT NOT NULL, ");
// Add Created At and Updated At
columns.add(addColumn(DataTableApiConstant.CREATEDAT_FIELD_NAME, DATETIME, false, null, false, false));
@@ -628,25 +627,23 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
}
// Remove trailing comma and space
sqlBuilder = sqlBuilder.delete(sqlBuilder.length() - 2, sqlBuilder.length());
sqlBuilder.delete(sqlBuilder.length() - 2, sqlBuilder.length());
String fullFkName = "fk_" + fkName;
if (multiRow) {
sqlBuilder.append(", PRIMARY KEY (").append(TABLE_FIELD_ID).append(")");
if (databaseTypeResolver.isMySQL()) {
sqlBuilder
.append(", KEY " + sqlGenerator.escape("fk_" + fkColumnName) + " (" + sqlGenerator.escape(fkColumnName) + ")");
sqlBuilder.append(", KEY ").append(sqlGenerator.escape("fk_" + fkColumnName)).append(" (")
.append(sqlGenerator.escape(fkColumnName)).append(")");
}
sqlBuilder.append(", CONSTRAINT " + sqlGenerator.escape(fullFkName) + " ")
.append("FOREIGN KEY (" + sqlGenerator.escape(fkColumnName) + ") ")
.append("REFERENCES " + sqlGenerator.escape(entityTable.getApptableName()) + " (").append(TABLE_FIELD_ID)
.append(")");
sqlBuilder.append(", CONSTRAINT ").append(sqlGenerator.escape(fullFkName)).append(" FOREIGN KEY (")
.append(sqlGenerator.escape(fkColumnName)).append(") ").append("REFERENCES ")
.append(sqlGenerator.escape(entityTable.getApptableName())).append(" (").append(TABLE_FIELD_ID).append(")");
} else {
sqlBuilder.append(", PRIMARY KEY (" + sqlGenerator.escape(fkColumnName) + ")")
.append(", CONSTRAINT " + sqlGenerator.escape(fullFkName) + " ")
.append("FOREIGN KEY (" + sqlGenerator.escape(fkColumnName) + ") ")
.append("REFERENCES " + sqlGenerator.escape(entityTable.getApptableName()) + " (").append(TABLE_FIELD_ID)
.append(")");
sqlBuilder.append(", PRIMARY KEY (").append(sqlGenerator.escape(fkColumnName)).append(")").append(", CONSTRAINT ")
.append(sqlGenerator.escape(fullFkName)).append(" FOREIGN KEY (").append(sqlGenerator.escape(fkColumnName))
.append(") ").append("REFERENCES ").append(sqlGenerator.escape(entityTable.getApptableName())).append(" (")
.append(TABLE_FIELD_ID).append(")");
}
sqlBuilder.append(constrainBuilder);
@@ -661,12 +658,10 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
// create indexes
if (multiRow) {
createFkIndex(datatableName, fkColumnName);
} else {
/*
* in case of non-multirow, the primary key of the table is the FK and MySQL and PostgreSQL
* automatically puts an index onto it so no need to create it explicitly
*/
}
// in case of non-multirow, the primary key of the table is the FK and MySQL and PostgreSQL
// automatically puts an index onto it so no need to create it explicitly
createIndexesForTable(datatableName, columns);
registerDatatable(datatableName, entityName, entitySubType);
registerColumnCodeMapping(codeMappings);
@@ -705,13 +700,11 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
private void createIndexForColumn(String datatableName, JsonObject column) {
String name = column.has(API_FIELD_NAME) ? column.get(API_FIELD_NAME).getAsString() : null;
final Boolean unique = column.has(API_FIELD_UNIQUE) ? column.get(API_FIELD_UNIQUE).getAsBoolean() : false;
final Boolean indexed = column.has(API_FIELD_INDEXED) ? column.get(API_FIELD_INDEXED).getAsBoolean() : false;
if (indexed) {
if (!unique) {
String indexName = datatableKeywordGenerator.generateIndexName(datatableName, name);
createIndex(indexName, datatableName, name);
}
final boolean unique = column.has(API_FIELD_UNIQUE) && column.get(API_FIELD_UNIQUE).getAsBoolean();
final boolean indexed = column.has(API_FIELD_INDEXED) && column.get(API_FIELD_INDEXED).getAsBoolean();
if (!unique && indexed) {
String indexName = datatableKeywordGenerator.generateIndexName(datatableName, name);
createIndex(indexName, datatableName, name);
}
}
@@ -719,7 +712,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
KeyHolder keyHolder = new GeneratedKeyHolder();
int insertsCount = this.jdbcTemplate.update(c -> c.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS), keyHolder);
if (insertsCount == 1) {
Number assignedKey = null;
Number assignedKey;
if (keyHolder.getKeys().size() > 1) {
assignedKey = (Long) keyHolder.getKeys().get(TABLE_FIELD_ID);
} else {
@@ -734,48 +727,52 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
}
private void parseDatatableColumnForUpdate(final JsonObject column,
final Map<String, ResultsetColumnHeaderData> mapColumnNameDefinition, StringBuilder sqlBuilder, final String datatableName,
final StringBuilder constrainBuilder, final Map<String, Long> codeMappings, final List<String> removeMappings,
final boolean isConstraintApproach) {
String name = column.has(API_FIELD_NAME) ? column.get(API_FIELD_NAME).getAsString() : null;
final Map<String, ResultsetColumnHeaderData> mapColumnNameDefinition, final String datatableName, StringBuilder renameBuilder,
StringBuilder changeBuilder, final StringBuilder constrainBuilder, final Map<String, Long> codeMappings,
final List<String> removeMappings, final boolean isConstraintApproach) {
String oldName = column.has(API_FIELD_NAME) ? column.get(API_FIELD_NAME).getAsString() : null;
if (!mapColumnNameDefinition.containsKey(oldName)) {
throw new PlatformDataIntegrityException("error.msg.datatable.column.missing.update.parse",
"Column " + oldName + " does not exist.", oldName);
}
final String lengthStr = column.has(API_FIELD_LENGTH) ? column.get(API_FIELD_LENGTH).getAsString() : null;
Integer length = StringUtils.isNotBlank(lengthStr) ? Integer.parseInt(lengthStr) : null;
String newName = column.has(API_FIELD_NEWNAME) ? column.get(API_FIELD_NEWNAME).getAsString() : name;
final Boolean mandatory = column.has(API_FIELD_MANDATORY) ? column.get(API_FIELD_MANDATORY).getAsBoolean() : false;
Long length = StringUtils.isNotBlank(lengthStr) ? Long.parseLong(lengthStr) : null;
String newName = column.has(API_FIELD_NEWNAME) ? column.get(API_FIELD_NEWNAME).getAsString() : null;
final Boolean newMandatory = column.has(API_FIELD_MANDATORY) ? column.get(API_FIELD_MANDATORY).getAsBoolean() : null;
final String after = column.has(API_FIELD_AFTER) ? column.get(API_FIELD_AFTER).getAsString() : null;
final String code = column.has(API_FIELD_CODE) ? column.get(API_FIELD_CODE).getAsString() : null;
final String newCode = column.has(API_FIELD_NEWCODE) ? column.get(API_FIELD_NEWCODE).getAsString() : null;
final String dataTableNameAlias = datatableName.toLowerCase().replaceAll("\\s", "_");
if (isConstraintApproach) {
if (StringUtils.isBlank(newName)) {
newName = name;
newName = oldName;
}
String fkName = "fk_" + dataTableNameAlias + "_" + name;
String fkName = "fk_" + dataTableNameAlias + "_" + oldName;
String newFkName = "fk_" + dataTableNameAlias + "_" + newName;
if (!StringUtils.equalsIgnoreCase(code, newCode) || !StringUtils.equalsIgnoreCase(name, newName)) {
if (!StringUtils.equalsIgnoreCase(code, newCode) || !StringUtils.equalsIgnoreCase(oldName, newName)) {
if (StringUtils.equalsIgnoreCase(code, newCode)) {
final int codeId = getCodeIdForColumn(dataTableNameAlias, name);
final int codeId = getCodeIdForColumn(dataTableNameAlias, oldName);
if (codeId > 0) {
removeMappings.add(dataTableNameAlias + "_" + name);
constrainBuilder.append(", DROP FOREIGN KEY ").append(sqlGenerator.escape(fkName)).append(" ");
removeMappings.add(dataTableNameAlias + "_" + oldName);
constrainBuilder.append(", DROP CONSTRAINT ").append(sqlGenerator.escape(fkName)).append(" ");
codeMappings.put(dataTableNameAlias + "_" + newName, (long) codeId);
constrainBuilder.append(",ADD CONSTRAINT ").append(sqlGenerator.escape(newFkName)).append(" ")
.append("FOREIGN KEY (" + sqlGenerator.escape(newName) + ") ").append("REFERENCES ")
constrainBuilder.append(", ADD CONSTRAINT ").append(sqlGenerator.escape(newFkName)).append(" ")
.append("FOREIGN KEY (").append(sqlGenerator.escape(newName)).append(") ").append("REFERENCES ")
.append(sqlGenerator.escape(CODE_VALUES_TABLE)).append(" (").append(TABLE_FIELD_ID).append(")");
}
} else {
if (code != null) {
removeMappings.add(dataTableNameAlias + "_" + name);
if (newCode == null || !StringUtils.equalsIgnoreCase(name, newName)) {
constrainBuilder.append(", DROP FOREIGN KEY ").append(sqlGenerator.escape(fkName)).append(" ");
removeMappings.add(dataTableNameAlias + "_" + oldName);
if (newCode == null || !StringUtils.equalsIgnoreCase(oldName, newName)) {
constrainBuilder.append(", DROP CONSTRAINT ").append(sqlGenerator.escape(fkName)).append(" ");
}
}
if (newCode != null) {
codeMappings.put(dataTableNameAlias + "_" + newName, this.codeReadPlatformService.retriveCode(newCode).getId());
if (code == null || !StringUtils.equalsIgnoreCase(name, newName)) {
constrainBuilder.append(",ADD CONSTRAINT ").append(sqlGenerator.escape(newFkName)).append(" ")
.append("FOREIGN KEY (" + sqlGenerator.escape(newName) + ") ").append("REFERENCES ")
if (code == null || !StringUtils.equalsIgnoreCase(oldName, newName)) {
constrainBuilder.append(", ADD CONSTRAINT ").append(sqlGenerator.escape(newFkName)).append(" ")
.append("FOREIGN KEY (").append(sqlGenerator.escape(newName)).append(") ").append("REFERENCES ")
.append(sqlGenerator.escape(CODE_VALUES_TABLE)).append(" (").append(TABLE_FIELD_ID).append(")");
}
}
@@ -783,7 +780,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
}
} else {
if (StringUtils.isNotBlank(code)) {
name = datatableColumnNameToCodeValueName(name, code);
oldName = datatableColumnNameToCodeValueName(oldName, code);
if (StringUtils.isNotBlank(newCode)) {
newName = datatableColumnNameToCodeValueName(newName, newCode);
} else {
@@ -791,37 +788,44 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
}
}
}
if (!mapColumnNameDefinition.containsKey(name)) {
throw new PlatformDataIntegrityException("error.msg.datatable.column.missing.update.parse",
"Column " + name + " does not exist.", name);
}
final JdbcJavaType type = mapColumnNameDefinition.get(name).getColumnType();
DatabaseType dialect = databaseTypeResolver.databaseType();
if (length == null && type.hasPrecision(dialect)) {
Long columnLength = mapColumnNameDefinition.get(name).getColumnLength();
length = columnLength == null ? null : columnLength.intValue();
}
if (databaseTypeResolver.isMySQL()) {
sqlBuilder.append(", CHANGE ").append(sqlGenerator.escape(name)).append(" ").append(sqlGenerator.escape(newName)).append(" ")
.append(type);
} else if (databaseTypeResolver.isPostgreSQL()) {
sqlBuilder.append(", RENAME ").append(sqlGenerator.escape(name)).append(" TO ").append(sqlGenerator.escape(newName));
}
if (length != null && length > 0) {
ResultsetColumnHeaderData columnHeader = mapColumnNameDefinition.get(oldName);
final JdbcJavaType type = columnHeader.getColumnType();
boolean nameChanged = !StringUtils.isBlank(newName) && !newName.equals(oldName);
boolean lengthChanged = length != null && !length.equals(columnHeader.getColumnLength()) && type.hasPrecision(dialect);
boolean nullityChanged = newMandatory != null && newMandatory != columnHeader.isMandatory();
boolean afterChanged = after != null && databaseTypeResolver.isMySQL();
if (nameChanged || lengthChanged || nullityChanged || afterChanged) {
Integer precision = length == null ? null : length.intValue();
Integer scale = null;
if (type.isDecimalType()) {
sqlBuilder.append(" ").append(type.formatSql(dialect, 19, 6));
precision = 19;
scale = 6;
}
String colName = StringUtils.isBlank(newName) ? oldName : newName;
boolean mandatory = newMandatory == null ? columnHeader.isMandatory() : newMandatory;
if (databaseTypeResolver.isMySQL()) {
String modifySql = nameChanged ? ("CHANGE " + sqlGenerator.escape(oldName) + " " + sqlGenerator.escape(colName))
: (" MODIFY " + sqlGenerator.escape(colName));
changeBuilder.append(", ").append(modifySql).append(" ").append(type.formatSql(dialect, precision, scale))
.append(mandatory ? " NOT NULL" : " DEFAULT NULL");
if (after != null) {
changeBuilder.append(" AFTER ").append(sqlGenerator.escape(after));
}
} else {
sqlBuilder.append(" ").append(type.formatSql(dialect, length));
if (nameChanged) {
renameBuilder.append("ALTER TABLE ").append(sqlGenerator.escape(datatableName)).append(" RENAME COLUMN ")
.append(sqlGenerator.escape(oldName)).append(" TO ").append(sqlGenerator.escape(newName)).append("; ");
}
if (lengthChanged) {
changeBuilder.append(", ALTER ").append(sqlGenerator.escape(colName)).append(" type ")
.append(type.formatSql(dialect, precision, scale));
}
if (nullityChanged) {
changeBuilder.append(", ALTER ").append(sqlGenerator.escape(colName))
.append(mandatory ? " set not null" : " drop not null");
}
}
}
if (databaseTypeResolver.isMySQL()) {
sqlBuilder.append(mandatory ? " NOT NULL" : " DEFAULT NULL");
}
if (after != null) {
sqlBuilder.append(" AFTER " + sqlGenerator.escape(after));
}
}
@@ -844,8 +848,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
String name = column.has(API_FIELD_NAME) ? column.get(API_FIELD_NAME).getAsString() : null;
final String type = column.has(API_FIELD_TYPE) ? column.get(API_FIELD_TYPE).getAsString().toLowerCase() : null;
final Integer length = column.has(API_FIELD_LENGTH) ? column.get(API_FIELD_LENGTH).getAsInt() : null;
final Boolean mandatory = column.has(API_FIELD_MANDATORY) ? column.get(API_FIELD_MANDATORY).getAsBoolean() : false;
final Boolean unique = column.has(API_FIELD_UNIQUE) ? column.get(API_FIELD_UNIQUE).getAsBoolean() : false;
final boolean mandatory = column.has(API_FIELD_MANDATORY) && column.get(API_FIELD_MANDATORY).getAsBoolean();
final boolean unique = column.has(API_FIELD_UNIQUE) && column.get(API_FIELD_UNIQUE).getAsBoolean();
final String after = column.has(API_FIELD_AFTER) ? column.get(API_FIELD_AFTER).getAsString() : null;
final String code = column.has(API_FIELD_CODE) ? column.get(API_FIELD_CODE).getAsString() : null;
@@ -853,9 +857,9 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
if (isConstraintApproach) {
String fkName = "fk_" + dataTableNameAlias + "_" + name;
codeMappings.put(dataTableNameAlias + "_" + name, this.codeReadPlatformService.retriveCode(code).getId());
constrainBuilder.append(",ADD CONSTRAINT ").append(sqlGenerator.escape(fkName)).append(" ")
.append("FOREIGN KEY (" + sqlGenerator.escape(name) + ") ").append("REFERENCES ")
.append(sqlGenerator.escape(CODE_VALUES_TABLE)).append(" (").append(TABLE_FIELD_ID).append(")");
constrainBuilder.append(",ADD CONSTRAINT ").append(sqlGenerator.escape(fkName)).append(" ").append("FOREIGN KEY (")
.append(sqlGenerator.escape(name)).append(") ").append("REFERENCES ").append(sqlGenerator.escape(CODE_VALUES_TABLE))
.append(" (").append(TABLE_FIELD_ID).append(")");
} else {
name = datatableColumnNameToCodeValueName(name, code);
}
@@ -864,8 +868,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
if (unique) {
String uniqueKeyName = datatableKeywordGenerator.generateUniqueKeyName(dataTableNameAlias, name);
constrainBuilder.append(",ADD CONSTRAINT ").append(sqlGenerator.escape(uniqueKeyName)).append(" ")
.append("UNIQUE (" + sqlGenerator.escape(name) + ")");
constrainBuilder.append(",ADD CONSTRAINT ").append(sqlGenerator.escape(uniqueKeyName)).append(" ").append("UNIQUE (")
.append(sqlGenerator.escape(name)).append(")");
}
if (mandatory) {
@@ -875,7 +879,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
}
if (after != null) {
sqlBuilder.append(" AFTER " + sqlGenerator.escape(after));
sqlBuilder.append(" AFTER ").append(sqlGenerator.escape(after));
}
}
@@ -883,14 +887,20 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
final StringBuilder constrainBuilder, final List<String> codeMappings) {
final String datatableAlias = datatableName.toLowerCase().replaceAll("\\s", "_");
final String name = column.has(API_FIELD_NAME) ? column.get(API_FIELD_NAME).getAsString() : null;
final 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("' ");
final int count = this.jdbcTemplate.queryForObject(findFKSql.toString(), Integer.class);
if (name == null) {
throw new GeneralPlatformDomainRuleException("error.msg.missing.datatable.column.name",
"Datatable column name to drop is missing.");
}
sqlBuilder.append(", DROP COLUMN ").append(sqlGenerator.escape(name)).append(" ");
String fkName = "fk_" + datatableAlias + "_" + name;
String schemaSql = databaseTypeResolver.isMySQL() ? "i.TABLE_SCHEMA = SCHEMA()"
: "i.table_catalog = current_catalog AND i.table_schema = current_schema";
String findFKSql = "SELECT count(*) FROM information_schema.TABLE_CONSTRAINTS i" + " WHERE i.CONSTRAINT_TYPE = 'FOREIGN KEY' AND "
+ schemaSql + " AND i.TABLE_NAME = '" + datatableName + "' AND i.CONSTRAINT_NAME = '" + fkName + "' ";
final int count = this.jdbcTemplate.queryForObject(findFKSql, Integer.class);
if (count > 0) {
String fkName = "fk_" + datatableAlias + "_" + name;
codeMappings.add(datatableAlias + "_" + name);
constrainBuilder.append(", DROP FOREIGN KEY ").append(sqlGenerator.escape(fkName)).append(" ");
}
@@ -985,25 +995,22 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
String fullNewFk = "fk_" + newFKName;
String fullNewConstraint = "fk_" + newConstraintName;
if (mapColumnNameDefinition.containsKey(TABLE_FIELD_ID)) {
sqlBuilder.append("ALTER TABLE " + sqlGenerator.escape(datatableName) + " ")
.append("DROP KEY " + sqlGenerator.escape(fullOldFk) + ",")
.append("DROP FOREIGN KEY " + sqlGenerator.escape(fullOldConstraint) + ",")
.append("CHANGE COLUMN " + sqlGenerator.escape(oldFKName) + " " + sqlGenerator.escape(newFKName)
+ " BIGINT NOT NULL,")
.append("ADD KEY " + sqlGenerator.escape(fullNewFk) + " (" + sqlGenerator.escape(newFKName) + "),")
.append("ADD CONSTRAINT " + sqlGenerator.escape(fullNewConstraint) + " ")
.append("FOREIGN KEY (" + sqlGenerator.escape(newFKName) + ") ")
.append("REFERENCES " + sqlGenerator.escape(entityTable.getApptableName()) + " (").append(TABLE_FIELD_ID)
.append(")");
sqlBuilder.append("ALTER TABLE ").append(sqlGenerator.escape(datatableName)).append(" DROP KEY ")
.append(sqlGenerator.escape(fullOldFk)).append(",").append("DROP FOREIGN KEY ")
.append(sqlGenerator.escape(fullOldConstraint)).append(",").append("CHANGE COLUMN ")
.append(sqlGenerator.escape(oldFKName)).append(" ").append(sqlGenerator.escape(newFKName))
.append(" BIGINT NOT NULL,").append("ADD KEY ").append(sqlGenerator.escape(fullNewFk)).append(" (")
.append(sqlGenerator.escape(newFKName)).append("),").append("ADD CONSTRAINT ")
.append(sqlGenerator.escape(fullNewConstraint)).append(" FOREIGN KEY (")
.append(sqlGenerator.escape(newFKName)).append(") ").append("REFERENCES ")
.append(sqlGenerator.escape(entityTable.getApptableName())).append(" (").append(TABLE_FIELD_ID).append(")");
} else {
sqlBuilder.append("ALTER TABLE " + sqlGenerator.escape(datatableName) + " ")
.append("DROP FOREIGN KEY " + sqlGenerator.escape(fullOldConstraint) + ",")
.append("CHANGE COLUMN " + sqlGenerator.escape(oldFKName) + " " + sqlGenerator.escape(newFKName)
+ " BIGINT NOT NULL,")
.append("ADD CONSTRAINT " + sqlGenerator.escape(fullNewConstraint) + " ")
.append("FOREIGN KEY (" + sqlGenerator.escape(newFKName) + ") ")
.append("REFERENCES " + sqlGenerator.escape(entityTable.getApptableName()) + " (").append(TABLE_FIELD_ID)
.append(")");
sqlBuilder.append("ALTER TABLE ").append(sqlGenerator.escape(datatableName)).append(" DROP FOREIGN KEY ")
.append(sqlGenerator.escape(fullOldConstraint)).append(",").append("CHANGE COLUMN ")
.append(sqlGenerator.escape(oldFKName)).append(" ").append(sqlGenerator.escape(newFKName))
.append(" BIGINT NOT NULL,").append("ADD CONSTRAINT ").append(sqlGenerator.escape(fullNewConstraint))
.append(" FOREIGN KEY (").append(sqlGenerator.escape(newFKName)).append(") ").append("REFERENCES ")
.append(sqlGenerator.escape(entityTable.getApptableName())).append(" (").append(TABLE_FIELD_ID).append(")");
}
this.jdbcTemplate.execute(sqlBuilder.toString());
@@ -1032,14 +1039,13 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
// Remove the first comma, right after ALTER TABLE datatable
final int indexOfFirstComma = sqlBuilder.indexOf(",");
if (indexOfFirstComma != -1) {
sqlBuilder = sqlBuilder.deleteCharAt(indexOfFirstComma);
sqlBuilder.deleteCharAt(indexOfFirstComma);
}
sqlBuilder.append(constrainBuilder);
this.jdbcTemplate.execute(sqlBuilder.toString());
deleteColumnCodeMapping(codeMappings);
}
if (addColumns != null) {
StringBuilder sqlBuilder = new StringBuilder("ALTER TABLE " + sqlGenerator.escape(datatableName));
final StringBuilder constrainBuilder = new StringBuilder();
final Map<String, Long> codeMappings = new HashMap<>();
@@ -1056,7 +1062,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
// Remove the first comma, right after ALTER TABLE datatable
final int indexOfFirstComma = sqlBuilder.indexOf(",");
if (indexOfFirstComma != -1) {
sqlBuilder = sqlBuilder.deleteCharAt(indexOfFirstComma);
sqlBuilder.deleteCharAt(indexOfFirstComma);
}
sqlBuilder.append(constrainBuilder);
jdbcTemplate.execute(sqlBuilder.toString());
@@ -1064,26 +1070,34 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
registerColumnCodeMapping(codeMappings);
}
if (changeColumns != null) {
StringBuilder sqlBuilder = new StringBuilder("ALTER TABLE " + sqlGenerator.escape(datatableName));
final StringBuilder renameBuilder = new StringBuilder();
StringBuilder changeBuilder = new StringBuilder();
final StringBuilder constrainBuilder = new StringBuilder();
final Map<String, Long> codeMappings = new HashMap<>();
final List<String> removeMappings = new ArrayList<>();
for (final JsonElement column : changeColumns) {
// remove NULL values from column where mandatory is true
removeNullValuesFromStringColumn(datatableName, column.getAsJsonObject(), mapColumnNameDefinition);
parseDatatableColumnForUpdate(column.getAsJsonObject(), mapColumnNameDefinition, sqlBuilder, datatableName,
constrainBuilder, codeMappings, removeMappings, isConstraintApproach);
parseDatatableColumnForUpdate(column.getAsJsonObject(), mapColumnNameDefinition, datatableName, renameBuilder,
changeBuilder, constrainBuilder, codeMappings, removeMappings, isConstraintApproach);
}
// Remove the first comma, right after ALTER TABLE datatable
final int indexOfFirstComma = sqlBuilder.indexOf(",");
if (indexOfFirstComma != -1) {
sqlBuilder = sqlBuilder.deleteCharAt(indexOfFirstComma);
StringBuilder sqlBuilder = renameBuilder;
if (!changeBuilder.isEmpty() || !constrainBuilder.isEmpty()) {
int idx = changeBuilder.indexOf(",");
if (idx > -1) {
changeBuilder.deleteCharAt(idx);
} else if ((idx = constrainBuilder.indexOf(",")) > -1) {
constrainBuilder.deleteCharAt(idx);
}
sqlBuilder.append("ALTER TABLE " + sqlGenerator.escape(datatableName)).append(changeBuilder).append(constrainBuilder);
}
sqlBuilder.append(constrainBuilder);
try {
jdbcTemplate.execute(sqlBuilder.toString());
if (!sqlBuilder.isEmpty()) {
jdbcTemplate.execute(sqlBuilder.toString());
}
deleteColumnCodeMapping(removeMappings);
registerColumnCodeMapping(codeMappings);
// update unique constraint
@@ -1160,8 +1174,9 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
// check for unique constraint update
String name = column.has(API_FIELD_NAME) ? column.get(API_FIELD_NAME).getAsString() : null;
String columnNewName = column.has(API_FIELD_NEWNAME) ? column.get(API_FIELD_NEWNAME).getAsString() : null;
final Boolean setUnique = column.has(API_FIELD_UNIQUE) ? column.get(API_FIELD_UNIQUE).getAsBoolean() : false;
final Boolean isAlreadyUnique = genericDataService.isExplicitlyUnique(datatableName, name);
final boolean isAlreadyUnique = genericDataService.isExplicitlyUnique(datatableName, name);
boolean setUnique = column.has(API_FIELD_UNIQUE) ? column.get(API_FIELD_UNIQUE).getAsBoolean() : isAlreadyUnique;
String uniqueKeyName = datatableKeywordGenerator.generateUniqueKeyName(datatableName, name);
if (isAlreadyUnique) {
@@ -1172,10 +1187,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
// if columnname changed
checkColumnRenameAndModifyUniqueConstraint(datatableName, columnNewName, uniqueKeyName);
}
} else {
if (setUnique) {
checkColumnRenameAndCreateUniqueConstraint(datatableName, name, columnNewName, uniqueKeyName);
}
} else if (setUnique) {
checkColumnRenameAndCreateUniqueConstraint(datatableName, name, columnNewName, uniqueKeyName);
}
}
@@ -1201,17 +1214,14 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
}
private void createUniqueConstraint(String datatableName, String columnName, String uniqueKeyName) {
StringBuilder constrainBuilder = new StringBuilder();
constrainBuilder.append("ALTER TABLE ").append(sqlGenerator.escape(datatableName)).append(" ADD CONSTRAINT ")
.append(sqlGenerator.escape(uniqueKeyName)).append(" UNIQUE (" + sqlGenerator.escape(columnName) + ");");
this.jdbcTemplate.execute(constrainBuilder.toString());
String sql = "ALTER TABLE " + sqlGenerator.escape(datatableName) + " ADD CONSTRAINT " + sqlGenerator.escape(uniqueKeyName)
+ " UNIQUE (" + sqlGenerator.escape(columnName) + ");";
this.jdbcTemplate.execute(sql);
}
private void dropUniqueConstraint(String datatableName, String uniqueKeyName) {
StringBuilder constrainBuilder = new StringBuilder();
constrainBuilder.append("ALTER TABLE ").append(sqlGenerator.escape(datatableName)).append(" DROP CONSTRAINT ")
.append(sqlGenerator.escape(uniqueKeyName)).append(";");
this.jdbcTemplate.execute(constrainBuilder.toString());
String sql = "ALTER TABLE " + sqlGenerator.escape(datatableName) + " DROP CONSTRAINT " + sqlGenerator.escape(uniqueKeyName) + ";";
this.jdbcTemplate.execute(sql);
}
private void updateIndexesForTable(String datatableName, JsonArray changeColumns,
@@ -1230,24 +1240,24 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
private void updateIndexForColumn(String datatableName, JsonObject column, ResultsetColumnHeaderData columnMetaData) {
String name = column.has(API_FIELD_NAME) ? column.get(API_FIELD_NAME).getAsString() : null;
String columnNewName = column.has(API_FIELD_NEWNAME) ? column.get(API_FIELD_NEWNAME).getAsString() : null;
final Boolean setForUnique = column.has(API_FIELD_UNIQUE) ? column.get(API_FIELD_UNIQUE).getAsBoolean() : false;
final Boolean setForIndexed = column.has(API_FIELD_INDEXED) ? column.get(API_FIELD_INDEXED).getAsBoolean() : false;
if (!setForUnique) {
final Boolean isAlreadyIndexed = genericDataService.isExplicitlyIndexed(datatableName, name);
String indexName = datatableKeywordGenerator.generateIndexName(datatableName, name);
if (isAlreadyIndexed) {
if (!setForIndexed) {
// drop index
dropIndex(datatableName, indexName);
} else { // if column name changed
checkColumnRenameAndModifyIndex(datatableName, columnNewName, indexName);
}
final boolean isAlreadyUnique = genericDataService.isExplicitlyUnique(datatableName, name);
final boolean setForUnique = column.has(API_FIELD_UNIQUE) ? column.get(API_FIELD_UNIQUE).getAsBoolean() : isAlreadyUnique;
if (setForUnique) {
return;
}
final boolean isAlreadyIndexed = genericDataService.isExplicitlyIndexed(datatableName, name);
boolean setForIndexed = column.has(API_FIELD_INDEXED) ? column.get(API_FIELD_INDEXED).getAsBoolean() : isAlreadyIndexed;
} else {
if (setForIndexed) {
checkColumnRenameAndCreateIndex(datatableName, name, columnNewName, indexName);
}
String indexName = datatableKeywordGenerator.generateIndexName(datatableName, name);
if (isAlreadyIndexed) {
if (!setForIndexed) {
// drop index
dropIndex(datatableName, indexName);
} else { // if column name changed
checkColumnRenameAndModifyIndex(datatableName, columnNewName, indexName);
}
} else if (setForIndexed) {
checkColumnRenameAndCreateIndex(datatableName, name, columnNewName, indexName);
}
}
@@ -1297,7 +1307,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
validateDatatableRegistered(datatableName);
assertDataTableEmpty(datatableName);
deregisterDatatable(datatableName);
String[] sqlArray = null;
String[] sqlArray;
if (this.configurationDomainService.isConstraintApproachEnabledForDatatables()) {
final String deleteColumnCodeSql = "delete from x_table_column_code_mappings where column_alias_name like'"
+ datatableName.toLowerCase().replaceAll("\\s", "_") + "_%'";
@@ -1600,7 +1610,6 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
private String getAddSql(final List<ResultsetColumnHeaderData> columnHeaders, final String datatable, final String fkName,
final Long appTableId, final Map<String, String> queryParams) {
final Map<String, Object> affectedColumns = getAffectedColumns(columnHeaders, queryParams, fkName);
String pValueWrite = "";
@@ -1626,12 +1635,10 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
} else {
throw new IllegalStateException("Current database is not supported");
}
} else {
pValueWrite = singleQuote + this.genericDataService.replace(pValue, singleQuote, singleQuote + singleQuote)
+ singleQuote;
}
}
columnName = sqlGenerator.escape(key);
insertColumns += ", " + columnName;
@@ -1645,12 +1652,10 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
}
}
}
addSql = "insert into " + sqlGenerator.escape(datatable) + " (" + sqlGenerator.escape(fkName) + " " + insertColumns + ")"
+ " select " + appTableId + " as id" + selectColumns;
log.debug("{}", addSql);
return addSql;
}
@@ -1666,7 +1671,6 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
*/
public String getAddSqlWithScore(final List<ResultsetColumnHeaderData> columnHeaders, final String datatable, final String fkName,
final Long appTableId, final Map<String, String> queryParams) {
final Map<String, Object> affectedColumns = getAffectedColumns(columnHeaders, queryParams, fkName);
String pValueWrite = "";
@@ -1700,13 +1704,11 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
+ " , ( SELECT SUM( code_score ) FROM m_code_value WHERE m_code_value.id IN (" + scoresId + " ) ) as score";
log.debug("{}", vaddSql);
return vaddSql;
}
private String getUpdateSql(List<ResultsetColumnHeaderData> columnHeaders, final String datatable, final String keyFieldName,
final Long keyFieldValue, final Map<String, Object> changedColumns) {
// just updating fields that have changed since pre-update read - though
// its possible these values are different from the page the user was
// looking at and even different from the current db values (if some
@@ -1765,7 +1767,6 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
}
sql += " where " + keyFieldName + " = " + keyFieldValue;
return sql;
}
@@ -1780,21 +1781,17 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
affectedAndChangedColumns.put(key, columnValue);
}
}
return affectedAndChangedColumns;
}
private boolean columnChanged(final String key, final Object value, final GenericResultsetData grs) {
final List<Object> columnValues = grs.getData().get(0).getRow();
Object columnValue = null;
for (int i = 0; i < grs.getColumnHeaders().size(); i++) {
if (key.equals(grs.getColumnHeaders().get(i).getColumnName())) {
columnValue = columnValues.get(i);
return notTheSame(columnValue, value);
return notTheSame(columnValues.get(i), value);
}
}
throw new PlatformDataIntegrityException("error.msg.invalid.columnName", "Parameter Column Name: " + key + " not found");
}
@@ -1885,26 +1882,23 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
@Override
public Long countDatatableEntries(final String datatableName, final Long appTableId, String foreignKeyColumn) {
final String sqlString = "SELECT COUNT(" + sqlGenerator.escape(foreignKeyColumn) + ") FROM " + sqlGenerator.escape(datatableName)
+ " WHERE " + sqlGenerator.escape(foreignKeyColumn) + "=" + appTableId;
final Long count = this.jdbcTemplate.queryForObject(sqlString, Long.class); // NOSONAR
return count;
+ " WHERE " + sqlGenerator.escape(foreignKeyColumn) + " = " + appTableId;
return this.jdbcTemplate.queryForObject(sqlString, Long.class); // NOSONAR
}
public boolean isDatatableAttachedToEntityDatatableCheck(final String datatableName) {
StringBuilder builder = new StringBuilder();
builder.append(" SELECT COUNT(edc.x_registered_table_name) FROM x_registered_table xrt");
builder.append(" JOIN m_entity_datatable_check edc ON edc.x_registered_table_name = xrt.registered_table_name");
builder.append(" WHERE edc.x_registered_table_name = '" + datatableName + "'");
final Long count = this.jdbcTemplate.queryForObject(builder.toString(), Long.class);
String sql = "SELECT COUNT(edc.x_registered_table_name) FROM x_registered_table xrt"
+ " JOIN m_entity_datatable_check edc ON edc.x_registered_table_name = xrt.registered_table_name"
+ " WHERE edc.x_registered_table_name = '" + datatableName + "'";
final Long count = this.jdbcTemplate.queryForObject(sql, Long.class);
return count > 0;
}
// --- DbUtils ---
@NotNull
private String mapApiTypeToDbType(@NotNull String apiType, Integer length) {
private String mapApiTypeToDbType(String apiType, Integer length) {
if (StringUtils.isEmpty(apiType)) {
return "";
}
@@ -231,11 +231,12 @@ public class DatatableHelper extends IntegrationTest {
public static List<HashMap<String, Object>> addDatatableColumns(List<HashMap<String, Object>> datatableColumnsList, String columnName,
String columnType, boolean isMandatory, Integer length, String codeName) {
final HashMap<String, Object> datatableColumnMap = new HashMap<>();
datatableColumnMap.put("name", columnName);
datatableColumnMap.put("type", columnType);
if (columnType != null) {
datatableColumnMap.put("type", columnType);
}
datatableColumnMap.put("mandatory", isMandatory);
if (length != null) {
datatableColumnMap.put("length", length);
@@ -37,14 +37,17 @@ import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.fineract.client.models.GetDataTablesResponse;
import org.apache.fineract.client.models.PostDataTablesAppTableIdResponse;
import org.apache.fineract.client.models.PostDataTablesResponse;
import org.apache.fineract.client.models.PutDataTablesAppTableIdDatatableIdResponse;
import org.apache.fineract.client.models.PutDataTablesResponse;
import org.apache.fineract.client.models.ResultsetColumnHeaderData;
import org.apache.fineract.client.util.Calls;
import org.apache.fineract.integrationtests.client.IntegrationTest;
import org.apache.fineract.integrationtests.common.ClientHelper;
@@ -311,7 +314,6 @@ public class DatatableIntegrationTest extends IntegrationTest {
@Test
public void validateCreateReadDeleteDatatableWithCaseSensitive() throws ParseException {
// creating datatable for client entity
final HashMap<String, Object> columnMap = new HashMap<>();
final List<HashMap<String, Object>> datatableColumnsList = new ArrayList<>();
@@ -546,7 +548,7 @@ public class DatatableIntegrationTest extends IntegrationTest {
final boolean genericResultSet = true;
HashMap<String, Object> columnMap = new HashMap<>();
List<HashMap<String, Object>> datatableColumnsList = new ArrayList<>();
ArrayList<HashMap<String, Object>> datatableColumnsList = new ArrayList<>();
columnMap.put("datatableName", datatableName);
columnMap.put("apptableName", CLIENT_APP_TABLE_NAME);
columnMap.put("entitySubType", CLIENT_PERSON_SUBTYPE_NAME);
@@ -562,10 +564,10 @@ public class DatatableIntegrationTest extends IntegrationTest {
DatatableHelper.verifyDatatableCreatedOnServer(this.requestSpec, this.responseSpec, datatableName);
// Insert first values
final String value = Utils.randomStringGenerator("Q", 8);
final String randomString = Utils.randomStringGenerator("Q", 8);
HashMap<String, Object> datatableEntryMap = new HashMap<>();
datatableEntryMap.put("itsANumber", randomNumber);
datatableEntryMap.put("itsAString", value);
datatableEntryMap.put("itsAString", randomString);
datatableEntryMap.put("locale", "en");
datatableEntryMap.put("dateFormat", "yyyy-MM-dd");
@@ -578,12 +580,14 @@ public class DatatableIntegrationTest extends IntegrationTest {
// Read the Datatable entry generated with genericResultSet in true (default)
HashMap<String, Object> items = this.datatableHelper.readDatatableEntry(datatableName, clientId, genericResultSet, null, "");
assertNotNull(items);
assertEquals(1, ((List) items.get("data")).size());
LOG.info("Record created at {}", ((List) ((Map) ((List) items.get("data")).get(0)).get("row")).get(3));
LOG.info("Record updated at {}", ((List) ((Map) ((List) items.get("data")).get(0)).get("row")).get(4));
List data = (List) items.get("data");
assertEquals(1, data.size());
List records = (List) ((Map) data.get(0)).get("row");
LOG.info("Record created at {}", records.get(3));
LOG.info("Record updated at {}", records.get(4));
assertEquals(clientId, ((List) ((Map) ((List) items.get("data")).get(0)).get("row")).get(0));
assertEquals(value, ((List) ((Map) ((List) items.get("data")).get(0)).get("row")).get(2));
assertEquals(clientId, records.get(0));
assertEquals(randomString, records.get(2));
// Update DataTable
columnMap = new HashMap<>();
@@ -600,7 +604,7 @@ public class DatatableIntegrationTest extends IntegrationTest {
// Update DataTable Entry after Update DataTable schema
datatableEntryMap = new HashMap<>();
final String textValue = Utils.randomStringGenerator(value, 120);
final String textValue = Utils.randomStringGenerator(randomString, 120);
datatableEntryMap.put("itsAText", textValue);
datatableEntryMap.put("locale", "en");
datatableEntryMap.put("dateFormat", "yyyy-MM-dd");
@@ -615,13 +619,41 @@ public class DatatableIntegrationTest extends IntegrationTest {
// Read the Datatable entry generated with genericResultSet in true (default)
items = this.datatableHelper.readDatatableEntry(datatableName, clientId, genericResultSet, null, "");
assertNotNull(items);
assertEquals(1, ((List) items.get("data")).size());
LOG.info("Record created at {}", ((List) ((Map) ((List) items.get("data")).get(0)).get("row")).get(3));
LOG.info("Record updated at {}", ((List) ((Map) ((List) items.get("data")).get(0)).get("row")).get(4));
data = (List) items.get("data");
assertEquals(1, data.size());
assertEquals(clientId, ((List) ((Map) ((List) items.get("data")).get(0)).get("row")).get(0));
assertEquals(value, ((List) ((Map) ((List) items.get("data")).get(0)).get("row")).get(2));
assertEquals(textValue, ((List) ((Map) ((List) items.get("data")).get(0)).get("row")).get(5));
records = (List) ((Map) data.get(0)).get("row");
LOG.info("Record created at {}", records.get(3));
LOG.info("Record updated at {}", records.get(4));
assertEquals(clientId, records.get(0));
assertEquals(randomString, records.get(2));
assertEquals(textValue, records.get(5));
Integer resourceId = this.datatableHelper.deleteDatatableEntries(datatableName, clientId, "resourceId");
assertEquals(clientId, resourceId, "ERROR IN DELETING THE DATATABLE ENTRIES");
// Update - update, delete DataTable columns
columnMap = new HashMap<>();
columnMap.put("apptableName", CLIENT_APP_TABLE_NAME);
columnMap.put("entitySubType", CLIENT_PERSON_SUBTYPE_NAME);
List<Map<String, Object>> dropColumnsList = Collections.singletonList(Collections.singletonMap("name", "itsANumber"));
columnMap.put("dropColumns", dropColumnsList);
ArrayList<HashMap<String, Object>> changeColumnsList = new ArrayList<>();
DatatableHelper.addDatatableColumns(changeColumnsList, "itsAString", null, false, 100, null);
columnMap.put("changeColumns", changeColumnsList);
datatabelRequestJsonString = new Gson().toJson(columnMap);
LOG.info("map to update : {}", datatabelRequestJsonString);
datatableUpdateResponse = this.datatableHelper.updateDatatable(datatableName, datatabelRequestJsonString);
assertNotNull(datatableUpdateResponse);
assertEquals(datatableName, datatableUpdateResponse.getResourceIdentifier());
GetDataTablesResponse dataTable = datatableHelper.getDataTableDetails(datatableName);
List<ResultsetColumnHeaderData> columnHeaders = dataTable.getColumnHeaderData();
assertEquals(5, columnHeaders.size());
ResultsetColumnHeaderData stringColumn = columnHeaders.get(1);
assertEquals("itsAString", stringColumn.getColumnName());
assertEquals(100, stringColumn.getColumnLength());
}
@Test
@@ -176,6 +176,7 @@ public class DatatableUniqueAndIndexColumnTest {
changeColumns.setName(column1Name);
String newColumnName = column1Name + "new";
changeColumns.setNewName(newColumnName);
changeColumns.setUnique(false);
changeColumns.setIndexed(true);
updateRequest.addChangeColumnsItem(changeColumns);