pass only changes for logging datatables updates

This commit is contained in:
John Woodlock
2013-01-04 16:26:25 +00:00
parent b61ab594e4
commit 6177e41e70
4 changed files with 832 additions and 663 deletions
@@ -1,5 +1,7 @@
package org.mifosplatform.infrastructure.dataqueries.handler;
import java.util.Map;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
@@ -24,9 +26,9 @@ public class UpdateOneToManyDatatableEntryCommandHandler implements
@Override
public EntityIdentifier processCommand(final JsonCommand command) {
this.writePlatformService.updateDatatableEntryOneToMany(command.entityName(), command.resourceId(), command.subResourceId(), command);
Map<String, Object> changes = this.writePlatformService.updateDatatableEntryOneToMany(command.entityName(), command.resourceId(), command.subResourceId(), command);
return EntityIdentifier.subResourceResult(command.resourceId(), command.subResourceId(),
command.commandId());
command.commandId(), changes);
}
}
@@ -24,7 +24,6 @@ public class UpdateOneToOneDatatableEntryCommandHandler implements NewCommandSou
@Override
public EntityIdentifier processCommand(final JsonCommand command) {
// TODO - return only detected changes
Map<String, Object> changes = this.writePlatformService.updateDatatableEntryOneToOne(command.entityName(), command.resourceId(), command);
return EntityIdentifier.resourceResult(command.resourceId(), command.commandId(), changes);
@@ -24,7 +24,7 @@ public interface ReadWriteNonCoreDataService {
Map<String, Object> updateDatatableEntryOneToOne(String datatable, Long appTableId, JsonCommand command);
void updateDatatableEntryOneToMany(String datatable, Long appTableId, Long datatableId, JsonCommand command);
Map<String, Object> updateDatatableEntryOneToMany(String datatable, Long appTableId, Long datatableId, JsonCommand command);
void deleteDatatableEntries(String datatable, Long appTableId);
@@ -5,7 +5,6 @@ import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -36,15 +35,19 @@ import org.springframework.stereotype.Service;
import com.google.gson.reflect.TypeToken;
@Service
public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataService {
public class ReadWriteNonCoreDataServiceImpl implements
ReadWriteNonCoreDataService {
private final static Logger logger = LoggerFactory.getLogger(ReadWriteNonCoreDataServiceImpl.class);
private final static Logger logger = LoggerFactory
.getLogger(ReadWriteNonCoreDataServiceImpl.class);
private final PlatformSecurityContext context;
private final FromJsonHelper fromJsonHelper;
@Autowired
public ReadWriteNonCoreDataServiceImpl(final PlatformSecurityContext context, final FromJsonHelper fromJsonHelper) {
public ReadWriteNonCoreDataServiceImpl(
final PlatformSecurityContext context,
final FromJsonHelper fromJsonHelper) {
this.context = context;
this.fromJsonHelper = fromJsonHelper;
}
@@ -55,8 +58,6 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
@Override
public List<DatatableData> retrieveDatatableNames(final String appTable) {
// long startTime = System.currentTimeMillis();
String andClause;
if (appTable == null) {
andClause = "";
@@ -64,30 +65,38 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
andClause = " and application_table_name = '" + appTable + "'";
}
// PERMITTED datatables
String sql = "select application_table_name, registered_table_name" + " from x_registered_table " + " where exists"
+ " (select 'f'" + " from m_appuser_role ur " + " join m_role r on r.id = ur.role_id"
+ " left join m_role_permission rp on rp.role_id = r.id" + " left join m_permission p on p.id = rp.permission_id"
+ " where ur.appuser_id = " + context.authenticatedUser().getId()
String sql = "select application_table_name, registered_table_name"
+ " from x_registered_table "
+ " where exists"
+ " (select 'f'"
+ " from m_appuser_role ur "
+ " join m_role r on r.id = ur.role_id"
+ " left join m_role_permission rp on rp.role_id = r.id"
+ " left join m_permission p on p.id = rp.permission_id"
+ " where ur.appuser_id = "
+ context.authenticatedUser().getId()
+ " and (p.code in ('ALL_FUNCTIONS', 'ALL_FUNCTIONS_READ') or p.code = concat('READ_', registered_table_name))) "
+ andClause + " order by application_table_name, registered_table_name";
+ andClause
+ " order by application_table_name, registered_table_name";
String sqlErrorMsg = "Application Table Name: " + appTable + " sql: " + sql;
CachedRowSet rs = genericDataService.getCachedResultSet(sql, sqlErrorMsg);
String sqlErrorMsg = "Application Table Name: " + appTable + " sql: "
+ sql;
CachedRowSet rs = genericDataService.getCachedResultSet(sql,
sqlErrorMsg);
List<DatatableData> datatables = new ArrayList<DatatableData>();
try {
while (rs.next()) {
datatables.add(new DatatableData(rs.getString("application_table_name"), rs.getString("registered_table_name")));
datatables.add(new DatatableData(rs
.getString("application_table_name"), rs
.getString("registered_table_name")));
}
} catch (SQLException e) {
throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage(), sqlErrorMsg);
throw new PlatformDataIntegrityException("error.msg.sql.error",
e.getMessage(), sqlErrorMsg);
}
// long elapsed = System.currentTimeMillis() - startTime;
// logger.info("FINISHING retrieveDatatableNames: Elapsed Time: " +
// elapsed);
return datatables;
}
@@ -106,21 +115,49 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
String deletePermission = "'DELETE_" + datatable + "'";
String deletePermissionChecker = "'DELETE_" + datatable + "_CHECKER'";
// TODO - put in batch command later
String sql = "insert into x_registered_table (registered_table_name, application_table_name) values ('" + datatable + "', '"
+ appTable + "')";
String sql = "insert into x_registered_table (registered_table_name, application_table_name) values ('"
+ datatable + "', '" + appTable + "')";
genericDataService.updateSQL(sql, "SQL: " + sql);
/*
* add all permissions, including checker permissions for maintenance
* tasks
*/
sql = "insert into m_permission (grouping, code, action_name, entity_name, can_maker_checker) values " + "('datatable', "
+ createPermission + ", 'CREATE', '" + datatable + "', true)," + "('datatable', " + createPermissionChecker
+ ", 'CREATE', '" + datatable + "', false)," + "('datatable', " + readPermission + ", 'READ', '" + datatable + "', false),"
+ "('datatable', " + updatePermission + ", 'UPDATE', '" + datatable + "', true)," + "('datatable', "
+ updatePermissionChecker + ", 'UPDATE', '" + datatable + "', false)," + "('datatable', " + deletePermission
+ ", 'DELETE', '" + datatable + "', true)," + "('datatable', " + deletePermissionChecker + ", 'DELETE', '" + datatable
+ "', false)";
sql = "insert into m_permission (grouping, code, action_name, entity_name, can_maker_checker) values "
+ "('datatable', "
+ createPermission
+ ", 'CREATE', '"
+ datatable
+ "', true),"
+ "('datatable', "
+ createPermissionChecker
+ ", 'CREATE', '"
+ datatable
+ "', false),"
+ "('datatable', "
+ readPermission
+ ", 'READ', '"
+ datatable
+ "', false),"
+ "('datatable', "
+ updatePermission
+ ", 'UPDATE', '"
+ datatable
+ "', true),"
+ "('datatable', "
+ updatePermissionChecker
+ ", 'UPDATE', '"
+ datatable
+ "', false),"
+ "('datatable', "
+ deletePermission
+ ", 'DELETE', '"
+ datatable
+ "', true),"
+ "('datatable', "
+ deletePermissionChecker
+ ", 'DELETE', '"
+ datatable + "', false)";
genericDataService.updateSQL(sql, "SQL: " + sql);
@@ -136,8 +173,10 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
// TODO - put in batch command later
String permissionList = "('CREATE_" + datatable + "', 'CREATE_" + datatable + "_CHECKER', 'READ_" + datatable + "', 'UPDATE_"
+ datatable + "', 'UPDATE_" + datatable + "_CHECKER', 'DELETE_" + datatable + "', 'DELETE_" + datatable + "_CHECKER')";
String permissionList = "('CREATE_" + datatable + "', 'CREATE_"
+ datatable + "_CHECKER', 'READ_" + datatable + "', 'UPDATE_"
+ datatable + "', 'UPDATE_" + datatable + "_CHECKER', 'DELETE_"
+ datatable + "', 'DELETE_" + datatable + "_CHECKER')";
String sql = "delete from m_role_permission where m_role_permission.permission_id in (select id from m_permission where code in "
+ permissionList + ")";
@@ -146,7 +185,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
sql = "delete from m_permission where code in " + permissionList;
genericDataService.updateSQL(sql, "SQL: " + sql);
sql = "delete from x_registered_table where registered_table_name = '" + datatable + "'";
sql = "delete from x_registered_table where registered_table_name = '"
+ datatable + "'";
genericDataService.updateSQL(sql, "SQL: " + sql);
// long elapsed = System.currentTimeMillis() - startTime;
@@ -155,17 +195,22 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
}
@Override
public void newDatatableEntry(final String datatable, final Long appTableId, final JsonCommand command) {
public void newDatatableEntry(final String datatable,
final Long appTableId, final JsonCommand command) {
// long startTime = System.currentTimeMillis();
String appTable = getWithinScopeApplicationTableName(datatable, appTableId);
String appTable = getWithinScopeApplicationTableName(datatable,
appTableId);
List<ResultsetColumnHeader> columnHeaders = getDatatableResultsetColumnHeaders(datatable);
final Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(typeOfMap, command.json());
final Type typeOfMap = new TypeToken<Map<String, String>>() {
}.getType();
Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(
typeOfMap, command.json());
String sql = getAddSql(columnHeaders, datatable, getFKField(appTable), appTableId, dataParams);
String sql = getAddSql(columnHeaders, datatable, getFKField(appTable),
appTableId, dataParams);
genericDataService.updateSQL(sql, "SQL: " + sql);
@@ -177,25 +222,36 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
}
@Override
public Map<String, Object> updateDatatableEntryOneToOne(final String datatable, final Long appTableId, final JsonCommand command) {
// long startTime = System.currentTimeMillis();
public Map<String, Object> updateDatatableEntryOneToOne(
final String datatable, final Long appTableId,
final JsonCommand command) {
Map<String, Object> changes = new LinkedHashMap<String, Object>();
GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable,
appTableId, null, null);
GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable, appTableId, null, null);
if (grs.getData().size() == 0) throw new DataTableNotFoundException(datatable, appTableId);
if (grs.getData().size() == 0)
throw new DataTableNotFoundException(datatable, appTableId);
if (grs.getData().size() > 1)
throw new PlatformDataIntegrityException("error.msg.attempting.multiple.update", "Application Table: " + datatable
+ " Foreign Key Id: " + appTableId);
throw new PlatformDataIntegrityException(
"error.msg.attempting.multiple.update",
"Application Table: " + datatable + " Foreign Key Id: "
+ appTableId);
String fkName = getFKField(getApplicationTableName(datatable));
final Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(typeOfMap, command.json());
final Type typeOfMap = new TypeToken<Map<String, String>>() {
}.getType();
Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(
typeOfMap, command.json());
String sql = getUpdateSql(grs, datatable, fkName, appTableId, dataParams);
final Map<String, Object> changes = getAffectedAndChangedColumns(grs,
dataParams, fkName);
if (changes.size() == 0)
return changes;
String sql = getUpdateSql(datatable, fkName, appTableId, changes);
if (sql != null) {
genericDataService.updateSQL(sql, "SQL: " + sql);
@@ -203,27 +259,32 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
logger.info("No Changes");
}
// long elapsed = System.currentTimeMillis() - startTime;
// logger.info("FINISHING updateDatatableEntryOnetoOne: Elapsed Time: "
// + elapsed + " - datatable: " + datatable + fkName
// + ": " + appTableId);
return changes;
}
@Override
public void updateDatatableEntryOneToMany(final String datatable, final Long appTableId, final Long datatableId,
final JsonCommand command) {
// long startTime = System.currentTimeMillis();
public Map<String, Object> updateDatatableEntryOneToMany(
final String datatable, final Long appTableId,
final Long datatableId, final JsonCommand command) {
GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable, appTableId, null, datatableId);
GenericResultsetData grs = retrieveDataTableGenericResultSet(datatable,
appTableId, null, datatableId);
if (grs.getData().size() == 0) throw new DataTableNotFoundException(datatable, appTableId);
if (grs.getData().size() == 0)
throw new DataTableNotFoundException(datatable, appTableId);
final Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(typeOfMap, command.json());
final Type typeOfMap = new TypeToken<Map<String, String>>() {
}.getType();
Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(
typeOfMap, command.json());
String sql = getUpdateSql(grs, datatable, "id", datatableId, dataParams);
final Map<String, Object> changes = getAffectedAndChangedColumns(grs,
dataParams, "id");
if (changes.size() == 0)
return changes;
String sql = getUpdateSql(datatable, "id", datatableId, changes);
if (sql != null) {
genericDataService.updateSQL(sql, "SQL: " + sql);
@@ -231,19 +292,19 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
logger.info("No Changes");
}
// long elapsed = System.currentTimeMillis() - startTime;
// logger.info("FINISHING updateDatatableEntryOnetoOne: Elapsed Time: "
// + elapsed + " - datatable: " + datatable + " id: "
// + datatableId);
return changes;
}
@Override
public void deleteDatatableEntries(final String datatable, final Long appTableId) {
public void deleteDatatableEntries(final String datatable,
final Long appTableId) {
// long startTime = System.currentTimeMillis();
String appTable = getWithinScopeApplicationTableName(datatable, appTableId);
String appTable = getWithinScopeApplicationTableName(datatable,
appTableId);
String sql = getDeleteEntriesSql(datatable, getFKField(appTable), appTableId);
String sql = getDeleteEntriesSql(datatable, getFKField(appTable),
appTableId);
genericDataService.updateSQL(sql, "SQL: " + sql);
@@ -255,7 +316,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
}
@Override
public void deleteDatatableEntry(final String datatable, final Long appTableId, final Long datatableId) {
public void deleteDatatableEntry(final String datatable,
final Long appTableId, final Long datatableId) {
// long startTime = System.currentTimeMillis();
getWithinScopeApplicationTableName(datatable, appTableId);
@@ -273,12 +335,14 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
}
@Override
public GenericResultsetData retrieveDataTableGenericResultSet(final String datatable, final Long appTableId, final String order,
public GenericResultsetData retrieveDataTableGenericResultSet(
final String datatable, final Long appTableId, final String order,
final Long id) {
// long startTime = System.currentTimeMillis();
String appTable = getWithinScopeApplicationTableName(datatable, appTableId);
String appTable = getWithinScopeApplicationTableName(datatable,
appTableId);
List<ResultsetColumnHeader> columnHeaders = getDatatableResultsetColumnHeaders(datatable);
@@ -287,12 +351,14 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
// id only used for reading a specific entry in a one to many datatable
// (when updating)
if (id == null) {
sql = sql + "select * from `" + datatable + "` where " + getFKField(appTable) + " = " + appTableId;
sql = sql + "select * from `" + datatable + "` where "
+ getFKField(appTable) + " = " + appTableId;
} else {
sql = sql + "select * from `" + datatable + "` where id = " + id;
}
if (order != null) sql = sql + " order by " + order;
if (order != null)
sql = sql + " order by " + order;
List<ResultsetDataRow> result = fillDatatableResultSetDataRows(sql);
@@ -304,15 +370,19 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
}
private void checkMainResourceExistsWithinScope(final String appTable, final Long appTableId) {
private void checkMainResourceExistsWithinScope(final String appTable,
final Long appTableId) {
String unscopedSql = "select t.id from `" + appTable + "` t ${dataScopeCriteria} where t.id = " + appTableId;
String unscopedSql = "select t.id from `" + appTable
+ "` t ${dataScopeCriteria} where t.id = " + appTableId;
String sql = dataScopedSQL(unscopedSql, appTable);
CachedRowSet rs = genericDataService.getCachedResultSet(sql, "SQL : " + sql);
CachedRowSet rs = genericDataService.getCachedResultSet(sql, "SQL : "
+ sql);
if (rs.size() == 0) throw new DataTableNotFoundException(appTable, appTableId);
if (rs.size() == 0)
throw new DataTableNotFoundException(appTable, appTableId);
}
private String dataScopedSQL(final String unscopedSQL, final String appTable) {
@@ -327,33 +397,45 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
AppUser currentUser = context.authenticatedUser();
if (appTable.equalsIgnoreCase("m_client")) {
dataScopeCriteria = " join m_office o on o.id = t.office_id and o.hierarchy like '" + currentUser.getOffice().getHierarchy()
+ "%'";
dataScopeCriteria = " join m_office o on o.id = t.office_id and o.hierarchy like '"
+ currentUser.getOffice().getHierarchy() + "%'";
}
if (appTable.equalsIgnoreCase("m_loan")) {
dataScopeCriteria = " join m_client c on c.id = t.client_id " + " join m_office o on o.id = c.office_id and o.hierarchy like '"
dataScopeCriteria = " join m_client c on c.id = t.client_id "
+ " join m_office o on o.id = c.office_id and o.hierarchy like '"
+ currentUser.getOffice().getHierarchy() + "%'";
}
if (dataScopeCriteria == null) { throw new PlatformDataIntegrityException("error.msg.invalid.dataScopeCriteria",
"Application Table: " + appTable + " not catered for in data Scoping"); }
if (dataScopeCriteria == null) {
throw new PlatformDataIntegrityException(
"error.msg.invalid.dataScopeCriteria",
"Application Table: " + appTable
+ " not catered for in data Scoping");
}
return genericDataService.replace(unscopedSQL, "${dataScopeCriteria}", dataScopeCriteria);
return genericDataService.replace(unscopedSQL, "${dataScopeCriteria}",
dataScopeCriteria);
}
private void validateAppTable(final String appTable) {
if (appTable.equalsIgnoreCase("m_client")) return;
if (appTable.equalsIgnoreCase("m_loan")) return;
if (appTable.equalsIgnoreCase("m_client"))
return;
if (appTable.equalsIgnoreCase("m_loan"))
return;
throw new PlatformDataIntegrityException("error.msg.invalid.application.table", "Invalid Application Table: " + appTable);
throw new PlatformDataIntegrityException(
"error.msg.invalid.application.table",
"Invalid Application Table: " + appTable);
}
private List<ResultsetDataRow> fillDatatableResultSetDataRows(final String sql) {
private List<ResultsetDataRow> fillDatatableResultSetDataRows(
final String sql) {
String sqlErrorMsg = "Sql: " + sql;
CachedRowSet rs = genericDataService.getCachedResultSet(sql, sqlErrorMsg);
CachedRowSet rs = genericDataService.getCachedResultSet(sql,
sqlErrorMsg);
List<ResultsetDataRow> resultsetDataRows = new ArrayList<ResultsetDataRow>();
@@ -379,16 +461,21 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
return resultsetDataRows;
} catch (SQLException e) {
throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage(), sqlErrorMsg);
throw new PlatformDataIntegrityException("error.msg.sql.error",
e.getMessage(), sqlErrorMsg);
}
}
private String getWithinScopeApplicationTableName(final String datatable, final Long appTableId) {
String sql = "SELECT application_table_name FROM x_registered_table where registered_table_name = '" + datatable + "'";
private String getWithinScopeApplicationTableName(final String datatable,
final Long appTableId) {
String sql = "SELECT application_table_name FROM x_registered_table where registered_table_name = '"
+ datatable + "'";
CachedRowSet rs = genericDataService.getCachedResultSet(sql, "SQL : " + sql);
CachedRowSet rs = genericDataService.getCachedResultSet(sql, "SQL : "
+ sql);
if (rs.size() == 0) throw new DataTableNotFoundException(datatable);
if (rs.size() == 0)
throw new DataTableNotFoundException(datatable);
try {
rs.next();
@@ -398,24 +485,29 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
return appTable;
} catch (SQLException e) {
throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage());
throw new PlatformDataIntegrityException("error.msg.sql.error",
e.getMessage());
}
}
private String getApplicationTableName(final String datatable) {
// TODO - only used for update... can probably remove this after as its
// a reread
String sql = "SELECT application_table_name FROM x_registered_table where registered_table_name = '" + datatable + "'";
String sql = "SELECT application_table_name FROM x_registered_table where registered_table_name = '"
+ datatable + "'";
CachedRowSet rs = genericDataService.getCachedResultSet(sql, "SQL : " + sql);
CachedRowSet rs = genericDataService.getCachedResultSet(sql, "SQL : "
+ sql);
if (rs.size() == 0) throw new DataTableNotFoundException(datatable);
if (rs.size() == 0)
throw new DataTableNotFoundException(datatable);
try {
rs.next();
return rs.getString("application_table_name");
} catch (SQLException e) {
throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage());
throw new PlatformDataIntegrityException("error.msg.sql.error",
e.getMessage());
}
}
@@ -427,17 +519,21 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
private CachedRowSet getDatatableMetaData(final String datatable) {
String sql = "select COLUMN_NAME, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, COLUMN_KEY"
+ " from INFORMATION_SCHEMA.COLUMNS " + " where TABLE_SCHEMA = schema() and TABLE_NAME = '" + datatable
+ "'order by ORDINAL_POSITION";
+ " from INFORMATION_SCHEMA.COLUMNS "
+ " where TABLE_SCHEMA = schema() and TABLE_NAME = '"
+ datatable + "'order by ORDINAL_POSITION";
CachedRowSet columnDefinitions = genericDataService.getCachedResultSet(sql, "SQL: " + sql);
CachedRowSet columnDefinitions = genericDataService.getCachedResultSet(
sql, "SQL: " + sql);
if (columnDefinitions.size() > 0) return columnDefinitions;
if (columnDefinitions.size() > 0)
return columnDefinitions;
throw new DataTableNotFoundException(datatable);
}
private List<ResultsetColumnHeader> getDatatableResultsetColumnHeaders(final String datatable) {
private List<ResultsetColumnHeader> getDatatableResultsetColumnHeaders(
final String datatable) {
CachedRowSet columnDefinitions = getDatatableMetaData(datatable);
@@ -462,15 +558,20 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
else
rsch.setColumnPrimaryKey(false);
Long columnLength = columnDefinitions.getLong("CHARACTER_MAXIMUM_LENGTH");
if (columnLength > 0) rsch.setColumnLength(columnDefinitions.getLong("CHARACTER_MAXIMUM_LENGTH"));
Long columnLength = columnDefinitions
.getLong("CHARACTER_MAXIMUM_LENGTH");
if (columnLength > 0)
rsch.setColumnLength(columnDefinitions
.getLong("CHARACTER_MAXIMUM_LENGTH"));
rsch.setColumnType(columnDefinitions.getString("DATA_TYPE"));
/* look for codes */
if (rsch.getColumnType().equalsIgnoreCase("varchar")) addCodesValueIfNecessary(rsch, "_cv");
if (rsch.getColumnType().equalsIgnoreCase("varchar"))
addCodesValueIfNecessary(rsch, "_cv");
if (rsch.getColumnType().equalsIgnoreCase("int")) addCodesValueIfNecessary(rsch, "_cd");
if (rsch.getColumnType().equalsIgnoreCase("int"))
addCodesValueIfNecessary(rsch, "_cd");
rsch.setColumnDisplayType();
@@ -480,36 +581,46 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
return columnHeaders;
} catch (SQLException e) {
throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage());
throw new PlatformDataIntegrityException("error.msg.sql.error",
e.getMessage());
}
}
private void addCodesValueIfNecessary(final ResultsetColumnHeader rsch, final String code_suffix) {
private void addCodesValueIfNecessary(final ResultsetColumnHeader rsch,
final String code_suffix) {
int codePosition = rsch.getColumnName().indexOf(code_suffix);
if (codePosition > 0) {
String codeName = rsch.getColumnName().substring(0, codePosition);
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";
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";
CachedRowSet rsValues = genericDataService.getCachedResultSet(sql, "SQL: " + sql);
CachedRowSet rsValues = genericDataService.getCachedResultSet(sql,
"SQL: " + sql);
try {
while (rsValues.next()) {
rsch.getColumnValues().add(new ResultsetColumnValue(rsValues.getInt("id"), rsValues.getString("code_value")));
rsch.getColumnValues().add(
new ResultsetColumnValue(rsValues.getInt("id"),
rsValues.getString("code_value")));
}
} catch (SQLException e) {
throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage());
throw new PlatformDataIntegrityException("error.msg.sql.error",
e.getMessage());
}
}
}
private String getAddSql(final List<ResultsetColumnHeader> columnHeaders, final String datatable, final String fkName,
final Long appTableId, final Map<String, String> queryParams) {
private String getAddSql(final List<ResultsetColumnHeader> columnHeaders,
final String datatable, final String fkName, final Long appTableId,
final Map<String, String> queryParams) {
final Map<String, String> affectedColumns = getAffectedColumns(columnHeaders, queryParams, fkName);
final Map<String, String> affectedColumns = getAffectedColumns(
columnHeaders, queryParams, fkName);
String pValueWrite = "";
String addSql = "";
@@ -525,23 +636,25 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
if (StringUtils.isEmpty(pValue)) {
pValueWrite = "null";
} else {
pValueWrite = singleQuote + genericDataService.replace(pValue, singleQuote, singleQuote + singleQuote) + singleQuote;
pValueWrite = singleQuote
+ genericDataService.replace(pValue, singleQuote,
singleQuote + singleQuote) + singleQuote;
}
columnName = "`" + key + "`";
insertColumns += ", " + columnName;
selectColumns += "," + pValueWrite + " as " + columnName;
}
addSql = "insert into `" + datatable + "` (`" + fkName + "` " + insertColumns + ")" + " select " + appTableId + " as id"
addSql = "insert into `" + datatable + "` (`" + fkName + "` "
+ insertColumns + ")" + " select " + appTableId + " as id"
+ selectColumns;
return addSql;
}
private String getUpdateSql(final GenericResultsetData grs, final String datatable, final String keyFieldName,
final Long keyFieldValue, final Map<String, String> queryParams) {
final Map<String, String> affectedAndChangedColumns = getAffectedAndChangedColumns(grs, queryParams, keyFieldName);
private String getUpdateSql(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
@@ -550,7 +663,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
// completeness but its okay to take this risk with additional fields
// data
if (affectedAndChangedColumns.size() == 0) return null;
if (changedColumns.size() == 0)
return null;
String pValue = null;
String pValueWrite = "";
@@ -558,7 +672,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
boolean firstColumn = true;
String sql = "update `" + datatable + "` ";
for (String key : affectedAndChangedColumns.keySet()) {
for (String key : changedColumns.keySet()) {
if (firstColumn) {
sql += " set ";
firstColumn = false;
@@ -566,11 +680,13 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
sql += ", ";
}
pValue = affectedAndChangedColumns.get(key);
pValue = (String) changedColumns.get(key);
if (StringUtils.isEmpty(pValue)) {
pValueWrite = "null";
} else {
pValueWrite = singleQuote + genericDataService.replace(pValue, singleQuote, singleQuote + singleQuote) + singleQuote;
pValueWrite = singleQuote
+ genericDataService.replace(pValue, singleQuote,
singleQuote + singleQuote) + singleQuote;
}
sql += "`" + key + "` = " + pValueWrite;
}
@@ -580,11 +696,13 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
return sql;
}
private Map<String, String> getAffectedAndChangedColumns(final GenericResultsetData grs, final Map<String, String> queryParams,
final String fkName) {
private Map<String, Object> getAffectedAndChangedColumns(
final GenericResultsetData grs,
final Map<String, String> queryParams, final String fkName) {
Map<String, String> affectedColumns = getAffectedColumns(grs.getColumnHeaders(), queryParams, fkName);
Map<String, String> affectedAndChangedColumns = new HashMap<String, String>();
Map<String, String> affectedColumns = getAffectedColumns(
grs.getColumnHeaders(), queryParams, fkName);
Map<String, Object> affectedAndChangedColumns = new HashMap<String, Object>();
String columnValue;
for (String key : affectedColumns.keySet()) {
@@ -597,7 +715,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
return affectedAndChangedColumns;
}
private boolean columnChanged(final String key, final String keyValue, final GenericResultsetData grs) {
private boolean columnChanged(final String key, final String keyValue,
final GenericResultsetData grs) {
List<String> columnValues = grs.getData().get(0).getRow();
@@ -608,7 +727,9 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
columnValue = columnValues.get(i);
if (notTheSame(columnValue, keyValue)) {
logger.info("Difference - Column: " + key + "- Current Value: " + columnValue + " New Value: " + keyValue);
logger.info("Difference - Column: " + key
+ "- Current Value: " + columnValue
+ " New Value: " + keyValue);
return true;
}
@@ -616,16 +737,20 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
}
}
throw new PlatformDataIntegrityException("error.msg.invalid.columnName", "Parameter Column Name: " + key + " not found");
throw new PlatformDataIntegrityException(
"error.msg.invalid.columnName", "Parameter Column Name: " + key
+ " not found");
}
private Map<String, String> getAffectedColumns(final List<ResultsetColumnHeader> columnHeaders, final Map<String, String> queryParams,
final String keyFieldName) {
private Map<String, String> getAffectedColumns(
final List<ResultsetColumnHeader> columnHeaders,
final Map<String, String> queryParams, final String keyFieldName) {
String dateFormat = queryParams.get("dateFormat");
Locale clientApplicationLocale = null;
String localeQueryParam = queryParams.get("locale");
if (!(StringUtils.isBlank(localeQueryParam))) clientApplicationLocale = new Locale(queryParams.get("locale"));
if (!(StringUtils.isBlank(localeQueryParam)))
clientApplicationLocale = new Locale(queryParams.get("locale"));
String underscore = "_";
String space = " ";
@@ -640,88 +765,124 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
// ignores id and foreign key fields
// also ignores locale and dateformat fields that are used for
// validating numeric and date data
if (!((key.equalsIgnoreCase("id")) || (key.equalsIgnoreCase(keyFieldName)) || (key.equals("locale")) || (key
.equals("dateFormat")))) {
if (!((key.equalsIgnoreCase("id"))
|| (key.equalsIgnoreCase(keyFieldName))
|| (key.equals("locale")) || (key.equals("dateFormat")))) {
notFound = true;
// matches incoming fields with and without underscores (spaces
// and underscores considered the same)
queryParamColumnUnderscored = genericDataService.replace(key, space, underscore);
queryParamColumnUnderscored = genericDataService.replace(key,
space, underscore);
for (ResultsetColumnHeader columnHeader : columnHeaders) {
if (notFound) {
columnHeaderUnderscored = genericDataService.replace(columnHeader.getColumnName(), space, underscore);
if (queryParamColumnUnderscored.equalsIgnoreCase(columnHeaderUnderscored)) {
columnHeaderUnderscored = genericDataService
.replace(columnHeader.getColumnName(), space,
underscore);
if (queryParamColumnUnderscored
.equalsIgnoreCase(columnHeaderUnderscored)) {
pValue = queryParams.get(key);
pValue = validateColumn(columnHeader, pValue, dateFormat, clientApplicationLocale);
affectedColumns.put(columnHeader.getColumnName(), pValue);
pValue = validateColumn(columnHeader, pValue,
dateFormat, clientApplicationLocale);
affectedColumns.put(columnHeader.getColumnName(),
pValue);
notFound = false;
}
}
}
if (notFound) { throw new PlatformDataIntegrityException("error.msg.column.not.found", "Column: " + key + " Not Found"); }
if (notFound) {
throw new PlatformDataIntegrityException(
"error.msg.column.not.found", "Column: " + key
+ " Not Found");
}
}
}
return affectedColumns;
}
private String validateColumn(final ResultsetColumnHeader columnHeader, final String pValue, final String dateFormat,
private String validateColumn(final ResultsetColumnHeader columnHeader,
final String pValue, final String dateFormat,
final Locale clientApplicationLocale) {
String paramValue = pValue;
if ((StringUtils.isEmpty(paramValue)) && (!(columnHeader.isColumnNullable()))) {
if ((StringUtils.isEmpty(paramValue))
&& (!(columnHeader.isColumnNullable()))) {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
ApiParameterError error = ApiParameterError.parameterError("error.msg.column.mandatory", "Mandatory",
ApiParameterError error = ApiParameterError.parameterError(
"error.msg.column.mandatory", "Mandatory",
columnHeader.getColumnName());
dataValidationErrors.add(error);
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
dataValidationErrors);
throw new PlatformApiDataValidationException(
"validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors);
}
if (!StringUtils.isEmpty(paramValue)) {
if (columnHeader.getColumnValues().size() > 0) {
// match code value or id
List<ResultsetColumnValue> allowedValues = columnHeader.getColumnValues();
List<ResultsetColumnValue> allowedValues = columnHeader
.getColumnValues();
if (columnHeader.getColumnDisplayType().equals("CODEVALUE")) {
for (ResultsetColumnValue allowedValue : allowedValues) {
if (paramValue.equalsIgnoreCase(allowedValue.getValue())) return paramValue;
if (paramValue
.equalsIgnoreCase(allowedValue.getValue()))
return paramValue;
}
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
ApiParameterError error = ApiParameterError.parameterError("error.msg.invalid.columnValue",
"Value not found in Allowed Value list", columnHeader.getColumnName(), paramValue);
ApiParameterError error = ApiParameterError.parameterError(
"error.msg.invalid.columnValue",
"Value not found in Allowed Value list",
columnHeader.getColumnName(), paramValue);
dataValidationErrors.add(error);
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
dataValidationErrors);
throw new PlatformApiDataValidationException(
"validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors);
}
if (columnHeader.getColumnDisplayType().equals("CODELOOKUP")) {
for (ResultsetColumnValue allowedValue : allowedValues) {
if (paramValue.equals(Integer.toString(allowedValue.getId()))) return paramValue;
if (paramValue.equals(Integer.toString(allowedValue
.getId())))
return paramValue;
}
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
ApiParameterError error = ApiParameterError.parameterError("error.msg.invalid.columnValue",
"Value not found in Allowed Value list", columnHeader.getColumnName(), paramValue);
ApiParameterError error = ApiParameterError.parameterError(
"error.msg.invalid.columnValue",
"Value not found in Allowed Value list",
columnHeader.getColumnName(), paramValue);
dataValidationErrors.add(error);
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
dataValidationErrors);
throw new PlatformApiDataValidationException(
"validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors);
}
throw new PlatformDataIntegrityException("error.msg.invalid.columnType.", "Code: " + columnHeader.getColumnName()
+ " - Invalid Type " + columnHeader.getColumnType() + " (neither varchar nor int)");
throw new PlatformDataIntegrityException(
"error.msg.invalid.columnType.", "Code: "
+ columnHeader.getColumnName()
+ " - Invalid Type "
+ columnHeader.getColumnType()
+ " (neither varchar nor int)");
}
JsonParserHelper helper = new JsonParserHelper();
if (columnHeader.getColumnDisplayType().equals("DATE"))
paramValue = helper.convertFrom(paramValue, columnHeader.getColumnName(), dateFormat, clientApplicationLocale).toString();
paramValue = helper.convertFrom(paramValue,
columnHeader.getColumnName(), dateFormat,
clientApplicationLocale).toString();
if (columnHeader.getColumnDisplayType().equals("INTEGER"))
paramValue = helper.convertToInteger(paramValue, columnHeader.getColumnName(), clientApplicationLocale).toString();
paramValue = helper.convertToInteger(paramValue,
columnHeader.getColumnName(), clientApplicationLocale)
.toString();
if (columnHeader.getColumnDisplayType().equals("DECIMAL"))
paramValue = helper.convertFrom(paramValue, columnHeader.getColumnName(), clientApplicationLocale).toString();
paramValue = helper.convertFrom(paramValue,
columnHeader.getColumnName(), clientApplicationLocale)
.toString();
// logger.info("Converted Value: " + paramValue + " - was: " +
// pValue);
@@ -730,26 +891,33 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
return paramValue;
}
private String getDeleteEntriesSql(final String datatable, final String FKField, final Long appTableId) {
private String getDeleteEntriesSql(final String datatable,
final String FKField, final Long appTableId) {
return "delete from `" + datatable + "` where `" + FKField + "` = " + appTableId;
return "delete from `" + datatable + "` where `" + FKField + "` = "
+ appTableId;
}
private String getDeleteEntrySql(final String datatable, final Long datatableId) {
private String getDeleteEntrySql(final String datatable,
final Long datatableId) {
return "delete from `" + datatable + "` where `id` = " + datatableId;
}
private boolean notTheSame(final String currValue, final String pValue) {
if (StringUtils.isEmpty(currValue) && StringUtils.isEmpty(pValue)) return false;
if (StringUtils.isEmpty(currValue) && StringUtils.isEmpty(pValue))
return false;
if (StringUtils.isEmpty(currValue)) return true;
if (StringUtils.isEmpty(currValue))
return true;
if (StringUtils.isEmpty(pValue)) return true;
if (StringUtils.isEmpty(pValue))
return true;
if (currValue.equals(pValue)) return false;
if (currValue.equals(pValue))
return false;
return true;
}