diff --git a/api-docs/apiLive.htm b/api-docs/apiLive.htm
index 282155441..cdef2fb9d 100644
--- a/api-docs/apiLive.htm
+++ b/api-docs/apiLive.htm
@@ -8126,21 +8126,20 @@ GET https://DomainName/api/v1/datatables
POST https://DomainName/api/v1/datatables/register/{datatable}/{apptable}
-POST datatables/register/userDefinedTableName/m_client
+POST datatables/register/extra_client_details/m_client
Content-Type: application/json
Request Body:
{}
-{
- "resourceId": null
+{
+ "resourceIdentifier": "extra_client_details"
}
-
-POST datatables/deregister/userDefinedTableName
+POST datatables/deregister/extra_client_details
Content-Type: application/json
Request Body:
@@ -8162,8 +8161,8 @@ Request Body:
{
- "resourceId": null
-}
+ "resourceIdentifier": "extra_client_details"
+}
-POST datatables/Additional Client Fields Data/1
+POST datatables/extra_client_details/1
Content-Type: application/json
Request Body:
{
"Business Description": "Livestock sales",
- Comment: "First comment\nmade",
- Education_cv: "Trade",
- Gender_cd: "21",
+ "Comment": "First comment made",
+ "Education_cv": "Primary",
+ "Gender_cd": "6",
"Highest Rate Paid": "8.5",
"Next Visit": "01 October 2012",
"Years in Business": "5",
- dateFormat: "dd MMMM yyyy",
- locale: "en"
+ "dateFormat": "dd MMMM yyyy",
+ "locale": "en"
}
@@ -8235,46 +8234,142 @@ Request Body:
optional
- If 'true' a Generic Result Set JSON format is returned.
+ If 'true' an optimised JSON format is returned suitable for tabular display of data.
This format is used by the default data tables UI functionality.
Example Requests:
- datatables/Additional Client Fields
- Data/1
+ datatables/extra_client_details/1
- datatables/Extra Family Details
- Data/1?order=`Date of Birth` desc
+ datatables/extra_family_details/1?order=`Date of Birth` desc
- datatables/Additional Client Fields
- Data/1?genericResultSet=true
+ datatables/extra_client_details/1?genericResultSet=true
-GET https://DomainName/api/v1/datatables/{datatable}/{apptableId}
+GET https://DomainName/api/v1/datatables/{datatable}/{apptableId}?genericResultSet=true
-[
{
- "client_id": 1,
- "Business Description": "Livestock sales",
- "Years in Business": 5,
- "Gender_cd": "21",
- "Education_cv": "Trade",
- "Next Visit": [2012, 10, 1],
- "Highest Rate Paid": 8.500000,
- "Comment": "First comment made"
-}
-]
+ "columnHeaders": [
+ {
+ "columnName": "client_id",
+ "columnType": "bigint",
+ "columnLength": 0,
+ "columnDisplayType": "INTEGER",
+ "isColumnNullable": false,
+ "isColumnPrimaryKey": true,
+ "columnValues": []
+ },
+ {
+ "columnName": "Business Description",
+ "columnType": "varchar",
+ "columnLength": 100,
+ "columnDisplayType": "STRING",
+ "isColumnNullable": true,
+ "isColumnPrimaryKey": false,
+ "columnValues": []
+ },
+ {
+ "columnName": "Years in Business",
+ "columnType": "int",
+ "columnLength": 0,
+ "columnDisplayType": "INTEGER",
+ "isColumnNullable": true,
+ "isColumnPrimaryKey": false,
+ "columnValues": []
+ },
+ {
+ "columnName": "Gender_cd",
+ "columnType": "int",
+ "columnLength": 0,
+ "columnDisplayType": "CODELOOKUP",
+ "isColumnNullable": true,
+ "isColumnPrimaryKey": false,
+ "columnValues": [
+ {
+ "id": 5,
+ "value": "option.Male"
+ },
+ {
+ "id": 6,
+ "value": "option.Female"
+ }
+ ]
+ },
+ {
+ "columnName": "Education_cv",
+ "columnType": "varchar",
+ "columnLength": 60,
+ "columnDisplayType": "CODEVALUE",
+ "isColumnNullable": true,
+ "isColumnPrimaryKey": false,
+ "columnValues": [
+ {
+ "id": 9,
+ "value": "Primary"
+ },
+ {
+ "id": 10,
+ "value": "Secondary"
+ },
+ {
+ "id": 11,
+ "value": "University"
+ }
+ ]
+ },
+ {
+ "columnName": "Next Visit",
+ "columnType": "date",
+ "columnLength": 0,
+ "columnDisplayType": "DATE",
+ "isColumnNullable": true,
+ "isColumnPrimaryKey": false,
+ "columnValues": []
+ },
+ {
+ "columnName": "Highest Rate Paid",
+ "columnType": "decimal",
+ "columnLength": 0,
+ "columnDisplayType": "DECIMAL",
+ "isColumnNullable": true,
+ "isColumnPrimaryKey": false,
+ "columnValues": []
+ },
+ {
+ "columnName": "Comment",
+ "columnType": "text",
+ "columnLength": 65535,
+ "columnDisplayType": "TEXT",
+ "isColumnNullable": true,
+ "isColumnPrimaryKey": false,
+ "columnValues": []
+ }
+ ],
+ "data": [
+ {
+ "row": [
+ "1",
+ "Livestock sales",
+ "5",
+ "6",
+ "Primary",
+ "2012-10-01",
+ "8.500000",
+ "First\tcomment made"
+ ]
+ }
+ ]
+}
-
+
Update Entry in Data Table (One to One)
@@ -8285,23 +8380,22 @@ GET https://DomainName/api/v1/datatables/{datatable}/{apptableId}
PUT https://DomainName/api/v1/datatables/{datatable}/{apptableId}
-PUT datatables/Additional Client Fields Data/1
+PUT datatables/extra_client_details/1
Content-Type: application/json
Request Body:
-{
- "Business Description": "Livestock sales updated",
- Comment: "First comment\nmade",
- Education_cv: "Trade",
- Gender_cd: "21",
- "Highest Rate Paid": "8.5",
- "Next Visit": "01 October 2012",
- "Years in Business": "5",
- dateFormat: "dd MMMM yyyy",
- locale: "en"
-}
+{
+ "Business Description": "Livestock sales updated",
+}
+
+
+{
+ "resourceId": 1,
+ "changes": {
+ "Business Description": "Livestock sales updated"
+ }
+}
- { "resourceId": 1 }
@@ -8385,8 +8479,7 @@ Request Body:
{ "resourceId": 1 }
-
-
+
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/data/CommandProcessingResult.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/data/CommandProcessingResult.java
index 7f2c7372f..c47864cae 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/data/CommandProcessingResult.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/data/CommandProcessingResult.java
@@ -19,13 +19,17 @@ public class CommandProcessingResult {
private final Long groupId;
private final Long clientId;
private final Long loanId;
- private Long resourceId;
+ private final Long resourceId;
private final String transactionId;
- private Map changes;
+ private final Map changes;
+ @SuppressWarnings("unused")
+ private final String resourceIdentifier;
public static CommandProcessingResult fromDetails(final Long commandId, final Long officeId, final Long groupId, final Long clientId,
- final Long loanId, final Long entityId, final String transactionId, final Map changes) {
- return new CommandProcessingResult(commandId, officeId, groupId, clientId, loanId, entityId, transactionId, changes);
+ final Long loanId, final String resourceIdentifier, final Long entityId, final String transactionId,
+ final Map changes) {
+ return new CommandProcessingResult(commandId, officeId, groupId, clientId, loanId, resourceIdentifier, entityId, transactionId,
+ changes);
}
public static CommandProcessingResult commandOnlyResult(final Long commandId) {
@@ -54,10 +58,18 @@ public class CommandProcessingResult {
}
public static CommandProcessingResult empty() {
- return new CommandProcessingResult(Long.valueOf(-1), Long.valueOf(-1), Long.valueOf(-1), null);
+ return new CommandProcessingResult(null, null, null, null);
}
+ /*
+ * Deprecated
+ */
public CommandProcessingResult(final Long entityId) {
+ if (entityId != null) {
+ this.resourceIdentifier = entityId.toString();
+ } else {
+ this.resourceIdentifier = null;
+ }
this.resourceId = entityId;
this.officeId = null;
this.groupId = null;
@@ -68,18 +80,24 @@ public class CommandProcessingResult {
}
private CommandProcessingResult(final Long commandId, final Long officeId, final Long groupId, final Long clientId, final Long loanId,
- final Long resourceId, final String transactionId, final Map changesOnly) {
+ final String resourceIdentifier, final Long resourceId, final String transactionId, final Map changesOnly) {
this.commandId = commandId;
this.officeId = officeId;
this.groupId = groupId;
this.clientId = clientId;
this.loanId = loanId;
+ this.resourceIdentifier = resourceIdentifier;
this.resourceId = resourceId;
this.changes = changesOnly;
this.transactionId = transactionId;
}
private CommandProcessingResult(final Long resourceId, final Long officeId, final Long commandId, final Map changesOnly) {
+ if (resourceId != null) {
+ this.resourceIdentifier = resourceId.toString();
+ } else {
+ this.resourceIdentifier = null;
+ }
this.resourceId = resourceId;
this.officeId = officeId;
this.groupId = null;
@@ -102,7 +120,7 @@ public class CommandProcessingResult {
return this.officeId;
}
- public void setOfficeId(Long officeId) {
+ public void setOfficeId(final Long officeId) {
this.officeId = officeId;
}
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/data/CommandProcessingResultBuilder.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/data/CommandProcessingResultBuilder.java
index fe0664c11..227e425ac 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/data/CommandProcessingResultBuilder.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/data/CommandProcessingResultBuilder.java
@@ -18,12 +18,14 @@ public class CommandProcessingResultBuilder {
private Long groupId;
private Long clientId;
private Long loanId;
+ private String resourceIdentifier;
private Long entityId;
private String transactionId;
private Map changes;
public CommandProcessingResult build() {
- return CommandProcessingResult.fromDetails(commandId, officeId, groupId, clientId, loanId, entityId, transactionId, changes);
+ return CommandProcessingResult.fromDetails(commandId, officeId, groupId, clientId, loanId, resourceIdentifier, entityId,
+ transactionId, changes);
}
public CommandProcessingResultBuilder withCommandId(final Long withCommandId) {
@@ -36,6 +38,11 @@ public class CommandProcessingResultBuilder {
return this;
}
+ public CommandProcessingResultBuilder withResourceIdAsString(final String withResourceIdentifier) {
+ this.resourceIdentifier = withResourceIdentifier;
+ return this;
+ }
+
public CommandProcessingResultBuilder withEntityId(final Long withEntityId) {
this.entityId = withEntityId;
return this;
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/api/DataTableApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/api/DatatablesApiResource.java
similarity index 92%
rename from mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/api/DataTableApiResource.java
rename to mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/api/DatatablesApiResource.java
index 6d7bbe946..f8eea1764 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/api/DataTableApiResource.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/api/DatatablesApiResource.java
@@ -25,6 +25,7 @@ import org.mifosplatform.commands.service.CommandWrapperBuilder;
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
+import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
import org.mifosplatform.infrastructure.core.serialization.ToApiJsonSerializer;
import org.mifosplatform.infrastructure.dataqueries.data.DatatableData;
import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData;
@@ -38,7 +39,7 @@ import org.springframework.stereotype.Component;
@Path("/datatables")
@Component
@Scope("singleton")
-public class DataTableApiResource {
+public class DatatablesApiResource {
private final PlatformSecurityContext context;
private final GenericDataService genericDataService;
@@ -47,7 +48,7 @@ public class DataTableApiResource {
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
@Autowired
- public DataTableApiResource(final PlatformSecurityContext context, final GenericDataService genericDataService,
+ public DatatablesApiResource(final PlatformSecurityContext context, final GenericDataService genericDataService,
final ReadWriteNonCoreDataService readWriteNonCoreDataService,
final ToApiJsonSerializer toApiJsonSerializer,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
@@ -77,7 +78,9 @@ public class DataTableApiResource {
this.readWriteNonCoreDataService.registerDatatable(datatable, apptable);
- return this.toApiJsonSerializer.serialize(CommandProcessingResult.empty());
+ final CommandProcessingResult result = new CommandProcessingResultBuilder().withResourceIdAsString(datatable).build();
+
+ return this.toApiJsonSerializer.serialize(result);
}
@POST
@@ -88,7 +91,9 @@ public class DataTableApiResource {
this.readWriteNonCoreDataService.deregisterDatatable(datatable);
- return this.toApiJsonSerializer.serialize(CommandProcessingResult.empty());
+ final CommandProcessingResult result = new CommandProcessingResultBuilder().withResourceIdAsString(datatable).build();
+
+ return this.toApiJsonSerializer.serialize(result);
}
@GET
@@ -143,7 +148,7 @@ public class DataTableApiResource {
@Path("{datatable}/{apptableId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
- public String newDatatableEntry(@PathParam("datatable") final String datatable, @PathParam("apptableId") final Long apptableId,
+ public String createDatatableEntry(@PathParam("datatable") final String datatable, @PathParam("apptableId") final Long apptableId,
final String apiRequestBodyAsJson) {
final CommandWrapper commandRequest = new CommandWrapperBuilder().createDatatable(datatable, apptableId, null)
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/exception/DataTableNotFoundException.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/exception/DataTableNotFoundException.java
index a9ca13175..a82da4fb6 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/exception/DataTableNotFoundException.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/exception/DataTableNotFoundException.java
@@ -10,15 +10,13 @@ import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceN
/**
* A {@link RuntimeException} thrown when client resources are not found.
*/
-public class DataTableNotFoundException extends AbstractPlatformResourceNotFoundException {
+public class DatatableNotFoundException extends AbstractPlatformResourceNotFoundException {
- public DataTableNotFoundException(final String datatable, Long id) {
- super("error.msg.datatable.data.not.found", "Data Not Found for Data Table: ",
- datatable + " Id:" + id);
- }
-
- public DataTableNotFoundException(final String datatable) {
- super("error.msg.datatable.not.found", "Data Table Not Found",
- datatable);
- }
+ public DatatableNotFoundException(final String datatable, final Long id) {
+ super("error.msg.datatable.data.not.found", "Data not found for datatable: ", datatable + " Id:" + id);
+ }
+
+ public DatatableNotFoundException(final String datatable) {
+ super("error.msg.datatable.not.found", "Datatable not found.", datatable);
+ }
}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/exception/ReportNotFoundException.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/exception/ReportNotFoundException.java
index a93005f46..29595da0e 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/exception/ReportNotFoundException.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/exception/ReportNotFoundException.java
@@ -13,6 +13,6 @@ import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceN
public class ReportNotFoundException extends AbstractPlatformResourceNotFoundException {
public ReportNotFoundException(final String reportSql) {
- super("error.msg.report.name.not.found", "Reporting Meta Data Entry Not Found", "Input Sql: " + reportSql);
+ super("error.msg.report.name.not.found", "Reporting meta-data entry not found.", "Input sql: " + reportSql);
}
}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/handler/CreateDatatableEntryCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/handler/CreateDatatableEntryCommandHandler.java
index 46c23f017..a91c10f2c 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/handler/CreateDatatableEntryCommandHandler.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/handler/CreateDatatableEntryCommandHandler.java
@@ -12,7 +12,6 @@ import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder
import org.mifosplatform.infrastructure.dataqueries.service.ReadWriteNonCoreDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
@Service
public class CreateDatatableEntryCommandHandler implements NewCommandSourceHandler {
@@ -24,11 +23,10 @@ public class CreateDatatableEntryCommandHandler implements NewCommandSourceHandl
this.writePlatformService = writePlatformService;
}
- @Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
- this.writePlatformService.newDatatableEntry(command.entityName(), command.getApptableId(), command);
+ this.writePlatformService.createNewDatatableEntry(command.entityName(), command.getApptableId(), command);
return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/GenericDataService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/GenericDataService.java
index 7d0a43d1c..9296855d6 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/GenericDataService.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/GenericDataService.java
@@ -20,7 +20,5 @@ public interface GenericDataService {
String wrapSQL(String sql);
- String getDatabaseName();
-
List fillResultsetColumnHeaders(String datatable);
}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/GenericDataServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/GenericDataServiceImpl.java
index 62825f6f1..af062e423 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/GenericDataServiceImpl.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/GenericDataServiceImpl.java
@@ -5,20 +5,18 @@
*/
package org.mifosplatform.infrastructure.dataqueries.service;
-import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.sql.DataSource;
import org.joda.time.LocalDate;
-import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData;
import org.mifosplatform.infrastructure.dataqueries.data.ResultsetColumnHeaderData;
import org.mifosplatform.infrastructure.dataqueries.data.ResultsetColumnValueData;
import org.mifosplatform.infrastructure.dataqueries.data.ResultsetRowData;
-import org.mifosplatform.infrastructure.dataqueries.exception.DataTableNotFoundException;
+import org.mifosplatform.infrastructure.dataqueries.exception.DatatableNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.rowset.SqlRowSet;
@@ -168,15 +166,6 @@ public class GenericDataServiceImpl implements GenericDataService {
}
- @Override
- public String getDatabaseName() {
- try {
- return dataSource.getConnection().getCatalog();
- } catch (SQLException e) {
- throw new PlatformDataIntegrityException("error.msg.sql.error", e.getMessage(), "Error Accessing Database Name");
- }
- }
-
@Override
public List fillResultsetColumnHeaders(final String datatable) {
@@ -249,6 +238,6 @@ public class GenericDataServiceImpl implements GenericDataService {
final SqlRowSet columnDefinitions = this.jdbcTemplate.queryForRowSet(sql);
if (columnDefinitions.next()) { return columnDefinitions; }
- throw new DataTableNotFoundException(datatable);
+ throw new DatatableNotFoundException(datatable);
}
}
\ No newline at end of file
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReadWriteNonCoreDataService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReadWriteNonCoreDataService.java
index c6215f1a8..acccce265 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReadWriteNonCoreDataService.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReadWriteNonCoreDataService.java
@@ -25,7 +25,7 @@ public interface ReadWriteNonCoreDataService {
GenericResultsetData retrieveDataTableGenericResultSet(String datatable, Long appTableId, String order, Long id);
- void newDatatableEntry(String datatable, Long appTableId, JsonCommand command);
+ void createNewDatatableEntry(String datatable, Long appTableId, JsonCommand command);
Map updateDatatableEntryOneToOne(String datatable, Long appTableId, JsonCommand command);
diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java
index b2fe582aa..bd0d3a12e 100644
--- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java
+++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java
@@ -17,6 +17,7 @@ import java.util.Set;
import javax.sql.DataSource;
import org.apache.commons.lang.StringUtils;
+import org.hibernate.exception.ConstraintViolationException;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
@@ -29,12 +30,14 @@ import org.mifosplatform.infrastructure.dataqueries.data.DatatableData;
import org.mifosplatform.infrastructure.dataqueries.data.GenericResultsetData;
import org.mifosplatform.infrastructure.dataqueries.data.ResultsetColumnHeaderData;
import org.mifosplatform.infrastructure.dataqueries.data.ResultsetRowData;
-import org.mifosplatform.infrastructure.dataqueries.exception.DataTableNotFoundException;
+import org.mifosplatform.infrastructure.dataqueries.exception.DatatableNotFoundException;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.useradministration.domain.AppUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataAccessException;
+import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.rowset.SqlRowSet;
import org.springframework.jdbc.support.rowset.SqlRowSetMetaData;
@@ -96,63 +99,89 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
return datatables;
}
+ private void logAsErrorUnexpectedDataIntegrityException(final Exception dve) {
+ logger.error(dve.getMessage(), dve);
+ }
+
@Override
- public void registerDatatable(final String datatable, final String appTable) {
+ public void registerDatatable(final String dataTableName, final String applicationTableName) {
- validateAppTable(appTable);
+ // FIXME - KW - hardcoded supported app tables are m_loan or m_client?
+ validateAppTable(applicationTableName);
- final String createPermission = "'CREATE_" + datatable + "'";
- final String createPermissionChecker = "'CREATE_" + datatable + "_CHECKER'";
- final String readPermission = "'READ_" + datatable + "'";
- final String updatePermission = "'UPDATE_" + datatable + "'";
- final String updatePermissionChecker = "'UPDATE_" + datatable + "_CHECKER'";
- final String deletePermission = "'DELETE_" + datatable + "'";
- final String deletePermissionChecker = "'DELETE_" + datatable + "_CHECKER'";
+ try {
+ // TODO - JW - put in batch command later
+ final String registerDatatableSql = "insert into x_registered_table (registered_table_name, application_table_name) values ('"
+ + dataTableName + "', '" + applicationTableName + "')";
- // TODO - JW - put in batch command later
- final String registerDatatableSql = "insert into x_registered_table (registered_table_name, application_table_name) values ('"
- + datatable + "', '" + appTable + "')";
+ this.jdbcTemplate.update(registerDatatableSql);
+ } catch (DataIntegrityViolationException dve) {
+ Throwable realCause = dve.getMostSpecificCause();
+ if (realCause.getMessage().contains("Duplicate entry")) { throw new PlatformDataIntegrityException(
+ "error.msg.datatable.registered", "Datatable `" + dataTableName
+ + "` is already registered against an application table.", "dataTableName", dataTableName); }
- this.jdbcTemplate.update(registerDatatableSql);
+ logAsErrorUnexpectedDataIntegrityException(dve);
+ throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue",
+ "Unknown data integrity issue with resource.");
+ }
- final String permissionsSql = "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)";
+ try {
+ final String createPermission = "'CREATE_" + dataTableName + "'";
+ final String createPermissionChecker = "'CREATE_" + dataTableName + "_CHECKER'";
+ final String readPermission = "'READ_" + dataTableName + "'";
+ final String updatePermission = "'UPDATE_" + dataTableName + "'";
+ final String updatePermissionChecker = "'UPDATE_" + dataTableName + "_CHECKER'";
+ final String deletePermission = "'DELETE_" + dataTableName + "'";
+ final String deletePermissionChecker = "'DELETE_" + dataTableName + "_CHECKER'";
- this.jdbcTemplate.update(permissionsSql);
+ final String permissionsSql = "insert into m_permission (grouping, code, action_name, entity_name, can_maker_checker) values "
+ + "('datatable', "
+ + createPermission
+ + ", 'CREATE', '"
+ + dataTableName
+ + "', true),"
+ + "('datatable', "
+ + createPermissionChecker
+ + ", 'CREATE', '"
+ + dataTableName
+ + "', false),"
+ + "('datatable', "
+ + readPermission
+ + ", 'READ', '"
+ + dataTableName
+ + "', false),"
+ + "('datatable', "
+ + updatePermission
+ + ", 'UPDATE', '"
+ + dataTableName
+ + "', true),"
+ + "('datatable', "
+ + updatePermissionChecker
+ + ", 'UPDATE', '"
+ + dataTableName
+ + "', false),"
+ + "('datatable', "
+ + deletePermission
+ + ", 'DELETE', '"
+ + dataTableName
+ + "', true),"
+ + "('datatable', "
+ + deletePermissionChecker
+ + ", 'DELETE', '"
+ + dataTableName + "', false)";
+
+ this.jdbcTemplate.update(permissionsSql);
+ } catch (DataIntegrityViolationException dve) {
+ Throwable realCause = dve.getMostSpecificCause();
+ if (realCause.getMessage().contains("Duplicate entry")) { throw new PlatformDataIntegrityException(
+ "error.msg.permissions.datatable.duplicate", "Permissions for datatable `" + dataTableName + "` already exist.",
+ "dataTableName", dataTableName); }
+
+ logAsErrorUnexpectedDataIntegrityException(dve);
+ throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue",
+ "Unknown data integrity issue with resource.");
+ }
}
@Override
@@ -161,29 +190,53 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
final 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 "
+ final String deleteRolePermissionsSql = "delete from m_role_permission where m_role_permission.permission_id in (select id from m_permission where code in "
+ permissionList + ")";
- this.jdbcTemplate.update(sql);
+ this.jdbcTemplate.update(deleteRolePermissionsSql);
- sql = "delete from m_permission where code in " + permissionList;
- this.jdbcTemplate.update(sql);
+ final String deletePermissionsSql = "delete from m_permission where code in " + permissionList;
+ this.jdbcTemplate.update(deletePermissionsSql);
- sql = "delete from x_registered_table where registered_table_name = '" + datatable + "'";
- this.jdbcTemplate.update(sql);
+ final String deleteRegisteredDatatableSql = "delete from x_registered_table where registered_table_name = '" + datatable + "'";
+ this.jdbcTemplate.update(deleteRegisteredDatatableSql);
}
@Override
- public void newDatatableEntry(final String datatable, final Long appTableId, final JsonCommand command) {
- String appTable = getWithinScopeApplicationTableName(datatable, appTableId);
+ public void createNewDatatableEntry(final String dataTableName, final Long appTableId, final JsonCommand command) {
- final List columnHeaders = this.genericDataService.fillResultsetColumnHeaders(datatable);
+ try {
+ final String appTable = getWithinScopeApplicationTableName(dataTableName, appTableId);
- final Type typeOfMap = new TypeToken