Skip to content

Commit

Permalink
#296 - cleanup schema dependency and mybatis for update
Browse files Browse the repository at this point in the history
  • Loading branch information
grabdoc committed Feb 19, 2024
1 parent cd6b457 commit 2e01867
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 38 deletions.
4 changes: 3 additions & 1 deletion src/main/java/com/homihq/db2rest/dialect/Dialect.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ public interface Dialect {

default Object processValue(String value, Class<?> type, String format) {
if (String.class == type) {
return "'" + value + "'";
//return "'" + value + "'";

return value;
}
else if (Boolean.class == type || boolean.class == type) {
return Boolean.valueOf(value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public class DeleteContext{
DbTable table;
String where;
Map<String,Object> paramMap;
Map<String,Object> data;

public void createParamMap() {
if(Objects.isNull(paramMap)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@ public class UpdateController {
private final UpdateService updateService;
@PatchMapping("/{tableName}")
public UpdateResponse save(@PathVariable String tableName,
@RequestHeader(name = "Content-Profile") String schemaName,
@RequestBody Map<String,Object> data
, @RequestParam(name = "filter", required = false, defaultValue = "") String filter) {

int rows = updateService.patch(schemaName, tableName, data, filter);
int rows = updateService.patch(null, tableName, data, filter);
return new UpdateResponse(rows);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.homihq.db2rest.rest.update;

import com.homihq.db2rest.rest.delete.dto.DeleteContext;
import com.homihq.db2rest.rest.update.dto.UpdateContext;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring6.SpringTemplateEngine;

import java.util.HashMap;
import java.util.Map;


@Component
@Slf4j
@RequiredArgsConstructor
public class UpdateCreatorTemplate {


private final SpringTemplateEngine templateEngine;
public String updateQuery(UpdateContext updateContext) {

Map<String,Object> data = new HashMap<>();

data.put("rootTable", updateContext.getTable().render());
data.put("rootWhere", updateContext.getWhere());
data.put("columnSets", updateContext.renderSetColumns());

Context context = new Context();
context.setVariables(data);
return templateEngine.process("update", context);

}



}
85 changes: 52 additions & 33 deletions src/main/java/com/homihq/db2rest/rest/update/UpdateService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,25 @@

import com.homihq.db2rest.config.Db2RestConfigProperties;
import com.homihq.db2rest.exception.GenericDataAccessException;
import com.homihq.db2rest.mybatis.MyBatisTable;
import com.homihq.db2rest.rsql.v1.operators.SimpleRSQLOperators;
import com.homihq.db2rest.rsql.v1.parser.WhereFilterVisitor;
import com.homihq.db2rest.model.DbTable;
import com.homihq.db2rest.model.DbWhere;
import com.homihq.db2rest.rest.update.dto.UpdateContext;

import com.homihq.db2rest.rsql2.parser.RSQLParserBuilder;
import com.homihq.db2rest.rsql2.visitor.BaseRSQLVisitor;
import com.homihq.db2rest.schema.SchemaManager;
import cz.jirutka.rsql.parser.RSQLParser;
import cz.jirutka.rsql.parser.ast.Node;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.mybatis.dynamic.sql.SqlCriterion;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.mybatis.dynamic.sql.update.UpdateDSL;
import org.mybatis.dynamic.sql.update.UpdateModel;
import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import static org.mybatis.dynamic.sql.update.UpdateDSL.update;


@Service
@Slf4j
Expand All @@ -32,52 +30,73 @@ public class UpdateService {
private final Db2RestConfigProperties db2RestConfigProperties;
private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;
private final SchemaManager schemaManager;
private final UpdateCreatorTemplate updateCreatorTemplate;

@Transactional
public int patch(String schemaName, String tableName, Map<String,Object> data, String filter) {

MyBatisTable table;
DbTable dbTable;
if(db2RestConfigProperties.getMultiTenancy().isSchemaBased()) {
table = schemaManager.getOneTable(schemaName, tableName);
} else {
table = schemaManager.getTable(tableName);
//Only relevant for schema per tenant multi tenancy
//TODO - handle schema retrieval from request
dbTable = schemaManager.getOneTableV2(schemaName, tableName);
}
else{
//get a unique table
dbTable = schemaManager.getTableV2(tableName);
}

return executeUpdate(filter, data, table);
List<String> updatableColumns =
data.keySet().stream().toList();

}
this.schemaManager.getDialect().processTypes(dbTable, updatableColumns, data);

private int executeUpdate(String filter, Map<String, Object> data, MyBatisTable table) {
UpdateDSL<UpdateModel> updateDSL = update(table);
UpdateContext context = UpdateContext.builder()
.tableName(tableName)
.table(dbTable)
.updatableColumns(updatableColumns)
.build();

for(String key : data.keySet()) {
updateDSL.set(table.column(key)).equalToOrNull(data.get(key));
}
context.createParamMap(data);

addWhere(filter, table, updateDSL);
return executeUpdate(filter, dbTable, context);

UpdateStatementProvider updateStatement = updateDSL.build()
.render(RenderingStrategies.SPRING_NAMED_PARAMETER);

log.info("SQL - {}", updateStatement.getUpdateStatement());
log.info("Bind variables - {}", updateStatement.getParameters());
}

private int executeUpdate(String filter, DbTable table, UpdateContext context) {

addWhere(filter, table, context);
String sql =
updateCreatorTemplate.updateQuery(context);

log.info("{}", sql);
log.info("{}", context.getParamMap());

try {
return namedParameterJdbcTemplate.update(updateStatement.getUpdateStatement(),
updateStatement.getParameters());
return namedParameterJdbcTemplate.update(sql,
context.getParamMap());
} catch (DataAccessException e) {
log.error("Error in delete op : " , e);
throw new GenericDataAccessException(e.getMostSpecificCause().getMessage());
}
}

private void addWhere(String filter, MyBatisTable table, UpdateDSL<UpdateModel> updateDSL) {
private void addWhere(String filter, DbTable table, UpdateContext context) {

if(StringUtils.isNotBlank(filter)) {

Node rootNode = new RSQLParser(SimpleRSQLOperators.customOperators()).parse(filter);
DbWhere dbWhere = new DbWhere(
context.getTableName(),
table, null ,context.getParamMap());

Node rootNode = RSQLParserBuilder.newRSQLParser().parse(filter);

SqlCriterion condition = rootNode
.accept(new WhereFilterVisitor(table));
String where = rootNode
.accept(new BaseRSQLVisitor(
dbWhere, schemaManager.getDialect()));
context.setWhere(where);

updateDSL.where(condition);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.homihq.db2rest.rest.update.dto;

import com.homihq.db2rest.model.DbTable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;


@Builder
@AllArgsConstructor
@NoArgsConstructor
@Data
@Slf4j
public class UpdateContext {


String tableName;
DbTable table;
String where;
Map<String,Object> paramMap;
List<String> updatableColumns;


public String renderSetColumns() {
return StringUtils.join(
updatableColumns.stream().map(i -> i + " = " + ":set_" + i).toList(),
","
);
}

public void createParamMap(Map<String, Object> data) {
if(Objects.isNull(paramMap)) {
paramMap = new HashMap<>();
}

for(String key : data.keySet()) {
paramMap.put("set_" + key , data.get(key));
}
}
}
3 changes: 1 addition & 2 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,4 @@ logging:
jdbc:
datasource:
init: DEBUG
core:
JdbcTemplate: DEBUG
core.*: DEBUG
5 changes: 5 additions & 0 deletions src/main/resources/sql-templates/update.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
UPDATE [(${rootTable})]
SET [(${columnSets})]
[# th:if="${rootWhere}"]WHERE
[(${rootWhere})]
[/]

0 comments on commit 2e01867

Please sign in to comment.