MIFOSX-237: api doc changes and ensure error handling supported is added back in for datatables api.

This commit is contained in:
Keith Woodlock
2013-03-11 19:42:44 +00:00
parent b3c77fe045
commit 84747cb109
11 changed files with 319 additions and 160 deletions
+142 -49
View File
@@ -8126,21 +8126,20 @@ GET https://DomainName/api/v1/datatables
POST https://DomainName/api/v1/datatables/register/{datatable}/{apptable}
</code>
<code class="method-request">
POST datatables/register/userDefinedTableName/m_client
POST datatables/register/extra_client_details/m_client
Content-Type: application/json
Request Body:
{}
</code>
<code class="method-response">
{
"resourceId": null
{
"resourceIdentifier": "extra_client_details"
}
</code>
</div>
</div>
<a id="datatables_deregister" name="datatables_deregister"
class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
@@ -8154,7 +8153,7 @@ Request Body:
POST https://DomainName/api/v1/datatables/deregister/{datatable}
</code>
<code class="method-request">
POST datatables/deregister/userDefinedTableName
POST datatables/deregister/extra_client_details
Content-Type: application/json
Request Body:
@@ -8162,8 +8161,8 @@ Request Body:
</code>
<code class="method-response">
{
"resourceId": null
}
"resourceIdentifier": "extra_client_details"
}
</code>
</div>
</div>
@@ -8186,20 +8185,20 @@ Request Body:
POST https://DomainName/api/v1/datatables/{datatable}/{apptableId}
</code>
<code class="method-request">
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"
}
</code>
<code class="method-response">
@@ -8235,46 +8234,142 @@ Request Body:
<dd>
<span>optional</span>
</dd>
<dd>If 'true' a Generic Result Set JSON format is returned.
<dd>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.</dd>
</dl>
<p>Example Requests:</p>
<div class=apiClick>datatables/Additional Client Fields
Data/1</div>
<div class=apiClick>datatables/extra_client_details/1</div>
<br>
<br>
<div class=apiClick>datatables/Extra Family Details
Data/1?order=`Date of Birth` desc</div>
<div class=apiClick>datatables/extra_family_details/1?order=`Date of Birth` desc</div>
<br>
<br>
<div class=apiClick>datatables/Additional Client Fields
Data/1?genericResultSet=true</div>
<div class=apiClick>datatables/extra_client_details/1?genericResultSet=true</div>
</div>
<div class="method-example">
<code class="method-declaration">
GET https://DomainName/api/v1/datatables/{datatable}/{apptableId}
GET https://DomainName/api/v1/datatables/{datatable}/{apptableId}?genericResultSet=true
</code>
<code class="method-response">
[
{
"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"
]
}
]
}
</code>
</div>
</div>
<a id="datatables_update" name="datatables_update"
class="old-syle-anchor">&nbsp;</a>
<a id="datatables_update" name="datatables_update" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Update Entry in Data Table (One to One)</h4>
@@ -8285,23 +8380,22 @@ GET https://DomainName/api/v1/datatables/{datatable}/{apptableId}
PUT https://DomainName/api/v1/datatables/{datatable}/{apptableId}
</code>
<code class="method-request">
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",
}
</code>
<code class="method-response">
{
"resourceId": 1,
"changes": {
"Business Description": "Livestock sales updated"
}
}
</code>
<code class="method-response">{ "resourceId": 1 } </code>
</div>
</div>
@@ -8385,8 +8479,7 @@ Request Body:
<code class="method-response">{ "resourceId": 1 } </code>
</div>
</div>
<!-- start of datatables api docs -->
<!-- end of datatables api docs -->
<!-- start of Notes api docs -->
<a id="notes" name="notes" class="old-syle-anchor">&nbsp;</a>
@@ -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<String, Object> changes;
private final Map<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> changesOnly) {
final String resourceIdentifier, final Long resourceId, final String transactionId, final Map<String, Object> 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<String, Object> 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;
}
@@ -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<String, Object> 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;
@@ -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<GenericResultsetData> 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)
@@ -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);
}
}
@@ -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);
}
}
@@ -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()) //
@@ -20,7 +20,5 @@ public interface GenericDataService {
String wrapSQL(String sql);
String getDatabaseName();
List<ResultsetColumnHeaderData> fillResultsetColumnHeaders(String datatable);
}
@@ -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<ResultsetColumnHeaderData> 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);
}
}
@@ -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<String, Object> updateDatatableEntryOneToOne(String datatable, Long appTableId, JsonCommand command);
@@ -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<ResultsetColumnHeaderData> columnHeaders = this.genericDataService.fillResultsetColumnHeaders(datatable);
try {
final String appTable = getWithinScopeApplicationTableName(dataTableName, appTableId);
final Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
final Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(typeOfMap, command.json());
final List<ResultsetColumnHeaderData> columnHeaders = this.genericDataService.fillResultsetColumnHeaders(dataTableName);
final String sql = getAddSql(columnHeaders, datatable, getFKField(appTable), appTableId, dataParams);
final Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
final Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(typeOfMap, command.json());
this.jdbcTemplate.update(sql);
final String sql = getAddSql(columnHeaders, dataTableName, getFKField(appTable), appTableId, dataParams);
this.jdbcTemplate.update(sql);
} catch (ConstraintViolationException dve) {
// NOTE: jdbctemplate throws a
// org.hibernate.exception.ConstraintViolationException even though
// it should be a DataAccessException?
Throwable realCause = dve.getCause();
if (realCause.getMessage().contains("Duplicate entry")) { throw new PlatformDataIntegrityException(
"error.msg.datatable.entry.duplicate", "An entry already exists for datatable `" + dataTableName
+ "` and application table with identifier `" + appTableId + "`.", "dataTableName", dataTableName, appTableId); }
logAsErrorUnexpectedDataIntegrityException(dve);
throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue",
"Unknown data integrity issue with resource.");
} catch (DataAccessException dve) {
Throwable realCause = dve.getMostSpecificCause();
if (realCause.getMessage().contains("Duplicate entry")) { throw new PlatformDataIntegrityException(
"error.msg.datatable.entry.duplicate", "An entry already exists for datatable `" + dataTableName
+ "` and application table with identifier `" + appTableId + "`.", "dataTableName", dataTableName, appTableId); }
logAsErrorUnexpectedDataIntegrityException(dve);
throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue",
"Unknown data integrity issue with resource.");
}
}
@Override
@@ -191,7 +244,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
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
@@ -223,7 +276,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
final 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 Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(typeOfMap, command.json());
@@ -296,7 +349,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
final SqlRowSet rs = this.jdbcTemplate.queryForRowSet(sql);
if (!rs.next()) { throw new DataTableNotFoundException(appTable, appTableId); }
if (!rs.next()) { throw new DatatableNotFoundException(appTable, appTableId); }
}
private String dataScopedSQL(final String unscopedSQL, final String appTable) {
@@ -374,7 +427,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
if (rs.next()) {
applicationTableName = rs.getString("application_table_name");
} else {
throw new DataTableNotFoundException(datatable);
throw new DatatableNotFoundException(datatable);
}
return applicationTableName;