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