Step 2.3 - Finalize Repositories with SqlDialectProvider Integration

This commit is contained in:
Jan 2026-01-25 19:30:45 +01:00
parent 1084c5b1cd
commit eff5d26ea3
10 changed files with 142 additions and 71 deletions

View file

@ -1,5 +1,6 @@
package de.avatic.lcc.repositories; package de.avatic.lcc.repositories;
import de.avatic.lcc.database.dialect.SqlDialectProvider;
import de.avatic.lcc.model.db.materials.Material; import de.avatic.lcc.model.db.materials.Material;
import de.avatic.lcc.repositories.pagination.SearchQueryPagination; import de.avatic.lcc.repositories.pagination.SearchQueryPagination;
import de.avatic.lcc.repositories.pagination.SearchQueryResult; import de.avatic.lcc.repositories.pagination.SearchQueryResult;
@ -18,10 +19,12 @@ import java.util.stream.Collectors;
public class MaterialRepository { public class MaterialRepository {
JdbcTemplate jdbcTemplate; JdbcTemplate jdbcTemplate;
SqlDialectProvider dialectProvider;
@Autowired @Autowired
public MaterialRepository(JdbcTemplate jdbcTemplate) { public MaterialRepository(JdbcTemplate jdbcTemplate, SqlDialectProvider dialectProvider) {
this.jdbcTemplate = jdbcTemplate; this.jdbcTemplate = jdbcTemplate;
this.dialectProvider = dialectProvider;
} }
private static String buildCountQuery(String filter, boolean excludeDeprecated) { private static String buildCountQuery(String filter, boolean excludeDeprecated) {
@ -39,7 +42,7 @@ public class MaterialRepository {
return queryBuilder.toString(); return queryBuilder.toString();
} }
private static String buildQuery(String filter, boolean excludeDeprecated) { private String buildQuery(String filter, boolean excludeDeprecated, SearchQueryPagination pagination) {
StringBuilder queryBuilder = new StringBuilder(""" StringBuilder queryBuilder = new StringBuilder("""
SELECT id, name, part_number, normalized_part_number, hs_code, is_deprecated SELECT id, name, part_number, normalized_part_number, hs_code, is_deprecated
FROM material WHERE 1=1"""); FROM material WHERE 1=1""");
@ -50,7 +53,8 @@ public class MaterialRepository {
if (filter != null) { if (filter != null) {
queryBuilder.append(" AND (name LIKE ? OR part_number LIKE ? ) "); queryBuilder.append(" AND (name LIKE ? OR part_number LIKE ? ) ");
} }
queryBuilder.append(" ORDER BY normalized_part_number LIMIT ? OFFSET ?"); queryBuilder.append(" ORDER BY normalized_part_number ");
queryBuilder.append(dialectProvider.buildPaginationClause(pagination.getLimit(), pagination.getOffset()));
return queryBuilder.toString(); return queryBuilder.toString();
} }
@ -102,13 +106,15 @@ public class MaterialRepository {
@Transactional @Transactional
public SearchQueryResult<Material> listMaterials(Optional<String> filter, boolean excludeDeprecated, SearchQueryPagination pagination) { public SearchQueryResult<Material> listMaterials(Optional<String> filter, boolean excludeDeprecated, SearchQueryPagination pagination) {
String query = buildQuery(filter.orElse(null), excludeDeprecated); String query = buildQuery(filter.orElse(null), excludeDeprecated, pagination);
Object[] paginationParams = dialectProvider.getPaginationParameters(pagination.getLimit(), pagination.getOffset());
var materials = filter.isPresent() ? var materials = filter.isPresent() ?
jdbcTemplate.query(query, new MaterialMapper(), jdbcTemplate.query(query, new MaterialMapper(),
filter.get() + "%", filter.get() + "%", pagination.getLimit(), pagination.getOffset()) : filter.get() + "%", filter.get() + "%", paginationParams[0], paginationParams[1]) :
jdbcTemplate.query(query, new MaterialMapper(), jdbcTemplate.query(query, new MaterialMapper(),
pagination.getLimit(), pagination.getOffset()); paginationParams[0], paginationParams[1]);
String countQuery = buildCountQuery(filter.orElse(null), excludeDeprecated); String countQuery = buildCountQuery(filter.orElse(null), excludeDeprecated);

View file

@ -1,5 +1,6 @@
package de.avatic.lcc.repositories; package de.avatic.lcc.repositories;
import de.avatic.lcc.database.dialect.SqlDialectProvider;
import de.avatic.lcc.service.api.EUTaxationApiService; import de.avatic.lcc.service.api.EUTaxationApiService;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
@ -10,19 +11,26 @@ import java.util.List;
public class NomenclatureRepository { public class NomenclatureRepository {
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
private final SqlDialectProvider dialectProvider;
private final EUTaxationApiService eUTaxationApiService; private final EUTaxationApiService eUTaxationApiService;
public NomenclatureRepository(JdbcTemplate jdbcTemplate, EUTaxationApiService eUTaxationApiService) { public NomenclatureRepository(JdbcTemplate jdbcTemplate, SqlDialectProvider dialectProvider, EUTaxationApiService eUTaxationApiService) {
this.jdbcTemplate = jdbcTemplate; this.jdbcTemplate = jdbcTemplate;
this.dialectProvider = dialectProvider;
this.eUTaxationApiService = eUTaxationApiService; this.eUTaxationApiService = eUTaxationApiService;
} }
public List<String> searchHsCode(String search) { public List<String> searchHsCode(String search) {
String sql = """ String concatExpression = dialectProvider.buildConcat("?", "'%'");
SELECT hs_code FROM nomenclature WHERE hs_code LIKE CONCAT(?, '%') LIMIT 10 String sql = String.format(
"""; "SELECT hs_code FROM nomenclature WHERE hs_code LIKE %s %s",
concatExpression,
dialectProvider.buildPaginationClause(10, 0)
);
return jdbcTemplate.queryForList (sql, String.class, search); Object[] paginationParams = dialectProvider.getPaginationParameters(10, 0);
return jdbcTemplate.queryForList(sql, String.class, search, paginationParams[0], paginationParams[1]);
} }
} }

View file

@ -1,5 +1,6 @@
package de.avatic.lcc.repositories.country; package de.avatic.lcc.repositories.country;
import de.avatic.lcc.database.dialect.SqlDialectProvider;
import de.avatic.lcc.dto.generic.PropertyDTO; import de.avatic.lcc.dto.generic.PropertyDTO;
import de.avatic.lcc.model.db.properties.CountryPropertyMappingId; import de.avatic.lcc.model.db.properties.CountryPropertyMappingId;
import de.avatic.lcc.model.db.rates.ValidityPeriodState; import de.avatic.lcc.model.db.rates.ValidityPeriodState;
@ -20,9 +21,11 @@ public class CountryPropertyRepository {
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
private final SqlDialectProvider dialectProvider;
public CountryPropertyRepository(JdbcTemplate jdbcTemplate) { public CountryPropertyRepository(JdbcTemplate jdbcTemplate, SqlDialectProvider dialectProvider) {
this.jdbcTemplate = jdbcTemplate; this.jdbcTemplate = jdbcTemplate;
this.dialectProvider = dialectProvider;
} }
@Transactional @Transactional
@ -44,11 +47,14 @@ public class CountryPropertyRepository {
return; return;
} }
String query = """ String query = dialectProvider.buildUpsertStatement(
INSERT INTO country_property (property_value, country_id, country_property_type_id, property_set_id) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE property_value = ? "country_property",
"""; List.of("property_set_id", "country_property_type_id", "country_id"),
List.of("property_value", "country_id", "country_property_type_id", "property_set_id"),
List.of("property_value")
);
int affectedRows = jdbcTemplate.update(query, value, countryId, typeId, setId, value); int affectedRows = jdbcTemplate.update(query, value, countryId, typeId, setId);
if(!(affectedRows > 0)) if(!(affectedRows > 0))
throw new DatabaseException("Could not update property value for country " + countryId + " and property type " + mappingId); throw new DatabaseException("Could not update property value for country " + countryId + " and property type " + mappingId);
@ -184,9 +190,12 @@ public class CountryPropertyRepository {
LEFT JOIN country_property AS property ON property.country_property_type_id = type.id LEFT JOIN country_property AS property ON property.country_property_type_id = type.id
LEFT JOIN property_set AS propertySet ON propertySet.id = property.property_set_id WHERE propertySet.state = 'VALID'"""; LEFT JOIN property_set AS propertySet ON propertySet.id = property.property_set_id WHERE propertySet.state = 'VALID'""";
String insertQuery = dialectProvider.buildInsertIgnoreStatement(
"country_property",
List.of("property_value", "country_id", "country_property_type_id", "property_set_id")
);
jdbcTemplate.query(query, (rs, rowNum) -> { jdbcTemplate.query(query, (rs, rowNum) -> {
String insertQuery = "INSERT IGNORE INTO country_property (property_value, country_id, country_property_type_id, property_set_id) VALUES (?, ?, ?, ?)";
jdbcTemplate.update(insertQuery, rs.getString("value"), rs.getInt("country_id"), rs.getInt("typeId"), setId); jdbcTemplate.update(insertQuery, rs.getString("value"), rs.getInt("country_id"), rs.getInt("typeId"), setId);
return null; return null;
}); });

View file

@ -1,5 +1,6 @@
package de.avatic.lcc.repositories.error; package de.avatic.lcc.repositories.error;
import de.avatic.lcc.database.dialect.SqlDialectProvider;
import de.avatic.lcc.dto.error.CalculationJobDumpDTO; import de.avatic.lcc.dto.error.CalculationJobDumpDTO;
import de.avatic.lcc.dto.error.CalculationJobDestinationDumpDTO; import de.avatic.lcc.dto.error.CalculationJobDestinationDumpDTO;
import de.avatic.lcc.dto.error.CalculationJobRouteSectionDumpDTO; import de.avatic.lcc.dto.error.CalculationJobRouteSectionDumpDTO;
@ -31,16 +32,17 @@ import java.util.Map;
public class DumpRepository { public class DumpRepository {
private final NamedParameterJdbcTemplate namedParameterJdbcTemplate; private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
private final PremiseRepository premiseRepository; private final PremiseRepository premiseRepository;
private final PremiseTransformer premiseTransformer; private final PremiseTransformer premiseTransformer;
private final SqlDialectProvider dialectProvider;
public DumpRepository(NamedParameterJdbcTemplate namedParameterJdbcTemplate, JdbcTemplate jdbcTemplate, PremiseRepository premiseRepository, PremiseTransformer premiseTransformer) { public DumpRepository(NamedParameterJdbcTemplate namedParameterJdbcTemplate, JdbcTemplate jdbcTemplate, PremiseRepository premiseRepository, PremiseTransformer premiseTransformer, SqlDialectProvider dialectProvider) {
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate; this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
this.jdbcTemplate = jdbcTemplate; this.jdbcTemplate = jdbcTemplate;
this.premiseRepository = premiseRepository; this.premiseRepository = premiseRepository;
this.premiseTransformer = premiseTransformer; this.premiseTransformer = premiseTransformer;
this.dialectProvider = dialectProvider;
} }
@Transactional(readOnly = true) @Transactional(readOnly = true)
@ -272,20 +274,17 @@ public class DumpRepository {
public SearchQueryResult<CalculationJobDumpDTO> listDumps(SearchQueryPagination searchQueryPagination) { public SearchQueryResult<CalculationJobDumpDTO> listDumps(SearchQueryPagination searchQueryPagination) {
String calculationJobQuery = """ String calculationJobQuery = String.format("""
SELECT cj.id, cj.premise_id, cj.calculation_date, cj.validity_period_id, SELECT cj.id, cj.premise_id, cj.calculation_date, cj.validity_period_id,
cj.property_set_id, cj.job_state, cj.error_id, cj.user_id cj.property_set_id, cj.job_state, cj.error_id, cj.user_id
FROM calculation_job cj FROM calculation_job cj
ORDER BY id DESC LIMIT :limit OFFSET :offset ORDER BY id DESC %s
"""; """, dialectProvider.buildPaginationClause(searchQueryPagination.getLimit(), searchQueryPagination.getOffset()));
MapSqlParameterSource params = new MapSqlParameterSource(); Object[] paginationParams = dialectProvider.getPaginationParameters(searchQueryPagination.getLimit(), searchQueryPagination.getOffset());
params.addValue("offset", searchQueryPagination.getOffset());
params.addValue("limit", searchQueryPagination.getLimit());
var dumps = namedParameterJdbcTemplate.query( var dumps = jdbcTemplate.query(
calculationJobQuery, calculationJobQuery,
params,
(rs, _) -> { (rs, _) -> {
CalculationJobDumpDTO dto = new CalculationJobDumpDTO(); CalculationJobDumpDTO dto = new CalculationJobDumpDTO();
dto.setId(rs.getInt("id")); dto.setId(rs.getInt("id"));
@ -308,7 +307,8 @@ public class DumpRepository {
} }
return dto; return dto;
}); },
paginationParams[0], paginationParams[1]);
for(var dump : dumps) { for(var dump : dumps) {
// Load premise details // Load premise details

View file

@ -1,6 +1,7 @@
package de.avatic.lcc.repositories.error; package de.avatic.lcc.repositories.error;
import de.avatic.lcc.database.dialect.SqlDialectProvider;
import de.avatic.lcc.model.db.error.SysError; import de.avatic.lcc.model.db.error.SysError;
import de.avatic.lcc.model.db.error.SysErrorTraceItem; import de.avatic.lcc.model.db.error.SysErrorTraceItem;
import de.avatic.lcc.model.db.error.SysErrorType; import de.avatic.lcc.model.db.error.SysErrorType;
@ -27,10 +28,12 @@ public class SysErrorRepository {
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
private final NamedParameterJdbcTemplate namedParameterJdbcTemplate; private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;
private final SqlDialectProvider dialectProvider;
public SysErrorRepository(JdbcTemplate jdbcTemplate, NamedParameterJdbcTemplate namedParameterJdbcTemplate) { public SysErrorRepository(JdbcTemplate jdbcTemplate, NamedParameterJdbcTemplate namedParameterJdbcTemplate, SqlDialectProvider dialectProvider) {
this.jdbcTemplate = jdbcTemplate; this.jdbcTemplate = jdbcTemplate;
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate; this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
this.dialectProvider = dialectProvider;
} }
@Transactional @Transactional
@ -114,35 +117,40 @@ public class SysErrorRepository {
@Transactional @Transactional
public SearchQueryResult<SysError> listErrors(Optional<String> filter, SearchQueryPagination pagination) { public SearchQueryResult<SysError> listErrors(Optional<String> filter, SearchQueryPagination pagination) {
StringBuilder whereClause = new StringBuilder(); StringBuilder whereClause = new StringBuilder();
MapSqlParameterSource parameters = new MapSqlParameterSource(); List<Object> params = new ArrayList<>();
// Build WHERE clause if filter is provided // Build WHERE clause if filter is provided
if (filter.isPresent() && !filter.get().trim().isEmpty()) { if (filter.isPresent() && !filter.get().trim().isEmpty()) {
String filterValue = "%" + filter.get().trim() + "%"; String filterValue = "%" + filter.get().trim() + "%";
whereClause.append(" WHERE (e.title LIKE :filter OR e.message LIKE :filter OR e.code LIKE :filter)"); whereClause.append(" WHERE (e.title LIKE ? OR e.message LIKE ? OR e.code LIKE ?)");
parameters.addValue("filter", filterValue); params.add(filterValue);
params.add(filterValue);
params.add(filterValue);
} }
// Count total elements // Count total elements
String countSql = "SELECT COUNT(*) FROM sys_error e" + whereClause; String countSql = "SELECT COUNT(*) FROM sys_error e" + whereClause;
Integer totalElements = namedParameterJdbcTemplate.queryForObject(countSql, parameters, Integer.class); Integer totalElements = params.isEmpty()
? jdbcTemplate.queryForObject(countSql, Integer.class)
: jdbcTemplate.queryForObject(countSql, Integer.class, params.toArray());
// Build main query with pagination // Build main query with pagination
String sql = """ String sql = String.format("""
SELECT e.id, e.user_id, e.title, e.code, e.message, e.pinia, SELECT e.id, e.user_id, e.title, e.code, e.message, e.pinia,
e.calculation_job_id, e.bulk_operation_id, e.type, e.created_at, e.request e.calculation_job_id, e.bulk_operation_id, e.type, e.created_at, e.request
FROM sys_error e FROM sys_error e
""" + whereClause + """ %s
ORDER BY e.created_at DESC ORDER BY e.created_at DESC
LIMIT :limit OFFSET :offset %s
"""; """, whereClause, dialectProvider.buildPaginationClause(pagination.getLimit(), pagination.getOffset()));
// Add pagination parameters // Add pagination parameters
parameters.addValue("limit", pagination.getLimit()); Object[] paginationParams = dialectProvider.getPaginationParameters(pagination.getLimit(), pagination.getOffset());
parameters.addValue("offset", pagination.getOffset()); params.add(paginationParams[0]);
params.add(paginationParams[1]);
// Execute query // Execute query
List<SysError> errors = namedParameterJdbcTemplate.query(sql, parameters, new SysErrorMapper()); List<SysError> errors = jdbcTemplate.query(sql, new SysErrorMapper(), params.toArray());
// Load trace items for each error // Load trace items for each error
if (!errors.isEmpty()) { if (!errors.isEmpty()) {

View file

@ -1,5 +1,6 @@
package de.avatic.lcc.repositories.packaging; package de.avatic.lcc.repositories.packaging;
import de.avatic.lcc.database.dialect.SqlDialectProvider;
import de.avatic.lcc.model.db.properties.PackagingProperty; import de.avatic.lcc.model.db.properties.PackagingProperty;
import de.avatic.lcc.model.db.properties.PropertyDataType; import de.avatic.lcc.model.db.properties.PropertyDataType;
import de.avatic.lcc.model.db.properties.PropertyType; import de.avatic.lcc.model.db.properties.PropertyType;
@ -16,9 +17,11 @@ import java.util.Optional;
public class PackagingPropertiesRepository { public class PackagingPropertiesRepository {
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
private final SqlDialectProvider dialectProvider;
public PackagingPropertiesRepository(JdbcTemplate jdbcTemplate) { public PackagingPropertiesRepository(JdbcTemplate jdbcTemplate, SqlDialectProvider dialectProvider) {
this.jdbcTemplate = jdbcTemplate; this.jdbcTemplate = jdbcTemplate;
this.dialectProvider = dialectProvider;
} }
public List<PackagingProperty> getByPackagingId(Integer id) { public List<PackagingProperty> getByPackagingId(Integer id) {
@ -94,11 +97,14 @@ public class PackagingPropertiesRepository {
public void update(Integer packagingId, Integer typeId, String value) { public void update(Integer packagingId, Integer typeId, String value) {
String query = """ String query = dialectProvider.buildUpsertStatement(
INSERT INTO packaging_property (property_value, packaging_id, packaging_property_type_id) VALUES (?, ?, ?) "packaging_property",
ON DUPLICATE KEY UPDATE property_value = ?"""; List.of("packaging_id", "packaging_property_type_id"),
List.of("property_value", "packaging_id", "packaging_property_type_id"),
List.of("property_value")
);
jdbcTemplate.update(query, value, packagingId, typeId, value); jdbcTemplate.update(query, value, packagingId, typeId);
} }
public Integer getTypeIdByMappingId(String mappingId) { public Integer getTypeIdByMappingId(String mappingId) {
@ -108,11 +114,14 @@ public class PackagingPropertiesRepository {
public void update(Integer packagingId, String typeId, String value) { public void update(Integer packagingId, String typeId, String value) {
String query = """ String query = dialectProvider.buildUpsertStatement(
INSERT INTO packaging_property (property_value, packaging_id, packaging_property_type_id) VALUES (?, ?, ?) "packaging_property",
ON DUPLICATE KEY UPDATE property_value = ?"""; List.of("packaging_id", "packaging_property_type_id"),
List.of("property_value", "packaging_id", "packaging_property_type_id"),
List.of("property_value")
);
jdbcTemplate.update(query, value, packagingId, typeId, value); jdbcTemplate.update(query, value, packagingId, typeId);
} }
} }

View file

@ -1,6 +1,7 @@
package de.avatic.lcc.repositories.properties; package de.avatic.lcc.repositories.properties;
import de.avatic.lcc.database.dialect.SqlDialectProvider;
import de.avatic.lcc.model.db.properties.PropertySet; import de.avatic.lcc.model.db.properties.PropertySet;
import de.avatic.lcc.model.db.rates.ValidityPeriodState; import de.avatic.lcc.model.db.rates.ValidityPeriodState;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
@ -23,9 +24,11 @@ import java.util.Optional;
public class PropertySetRepository { public class PropertySetRepository {
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
private final SqlDialectProvider dialectProvider;
public PropertySetRepository(JdbcTemplate jdbcTemplate) { public PropertySetRepository(JdbcTemplate jdbcTemplate, SqlDialectProvider dialectProvider) {
this.jdbcTemplate = jdbcTemplate; this.jdbcTemplate = jdbcTemplate;
this.dialectProvider = dialectProvider;
} }
/** /**
@ -155,16 +158,21 @@ public class PropertySetRepository {
} }
public Optional<PropertySet> getByDate(LocalDate date) { public Optional<PropertySet> getByDate(LocalDate date) {
String query = """ String query = String.format("""
SELECT id, start_date, end_date, state SELECT id, start_date, end_date, state
FROM property_set FROM property_set
WHERE DATE(start_date) <= ? WHERE %s <= ?
AND (end_date IS NULL OR DATE(end_date) >= ?) AND (end_date IS NULL OR %s >= ?)
ORDER BY start_date DESC ORDER BY start_date DESC
LIMIT 1 %s
"""; """,
dialectProvider.extractDate("start_date"),
dialectProvider.extractDate("end_date"),
dialectProvider.buildPaginationClause(1, 0)
);
var propertySets = jdbcTemplate.query(query, new PropertySetMapper(), date, date); Object[] paginationParams = dialectProvider.getPaginationParameters(1, 0);
var propertySets = jdbcTemplate.query(query, new PropertySetMapper(), date, date, paginationParams[0], paginationParams[1]);
return propertySets.isEmpty() ? Optional.empty() : Optional.of(propertySets.getFirst()); return propertySets.isEmpty() ? Optional.empty() : Optional.of(propertySets.getFirst());
} }

View file

@ -1,5 +1,6 @@
package de.avatic.lcc.repositories.users; package de.avatic.lcc.repositories.users;
import de.avatic.lcc.database.dialect.SqlDialectProvider;
import de.avatic.lcc.model.db.users.App; import de.avatic.lcc.model.db.users.App;
import de.avatic.lcc.model.db.users.Group; import de.avatic.lcc.model.db.users.Group;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
@ -31,16 +32,19 @@ public class AppRepository {
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
private final GroupRepository groupRepository; private final GroupRepository groupRepository;
private final SqlDialectProvider dialectProvider;
/** /**
* Creates a new AppRepository. * Creates a new AppRepository.
* *
* @param jdbcTemplate Spring JdbcTemplate used for executing SQL queries * @param jdbcTemplate Spring JdbcTemplate used for executing SQL queries
* @param groupRepository Repository used to resolve group identifiers * @param groupRepository Repository used to resolve group identifiers
* @param dialectProvider SQL dialect provider for database-specific SQL syntax
*/ */
public AppRepository(JdbcTemplate jdbcTemplate, GroupRepository groupRepository) { public AppRepository(JdbcTemplate jdbcTemplate, GroupRepository groupRepository, SqlDialectProvider dialectProvider) {
this.jdbcTemplate = jdbcTemplate; this.jdbcTemplate = jdbcTemplate;
this.groupRepository = groupRepository; this.groupRepository = groupRepository;
this.dialectProvider = dialectProvider;
} }
/** /**
@ -128,11 +132,13 @@ public class AppRepository {
jdbcTemplate.update("DELETE FROM sys_app_group_mapping WHERE app_id = ?", appId); jdbcTemplate.update("DELETE FROM sys_app_group_mapping WHERE app_id = ?", appId);
return; return;
} else { } else {
for (Integer groupId : groups) { String insertQuery = dialectProvider.buildInsertIgnoreStatement(
jdbcTemplate.update( "sys_app_group_mapping",
"INSERT IGNORE INTO sys_app_group_mapping (app_id, group_id) VALUES (?, ?)", List.of("app_id", "group_id")
appId, groupId
); );
for (Integer groupId : groups) {
jdbcTemplate.update(insertQuery, appId, groupId);
} }
} }

View file

@ -1,5 +1,6 @@
package de.avatic.lcc.repositories.users; package de.avatic.lcc.repositories.users;
import de.avatic.lcc.database.dialect.SqlDialectProvider;
import de.avatic.lcc.model.db.users.Group; import de.avatic.lcc.model.db.users.Group;
import de.avatic.lcc.repositories.pagination.SearchQueryPagination; import de.avatic.lcc.repositories.pagination.SearchQueryPagination;
import de.avatic.lcc.repositories.pagination.SearchQueryResult; import de.avatic.lcc.repositories.pagination.SearchQueryResult;
@ -16,21 +17,26 @@ import java.util.List;
@Repository @Repository
public class GroupRepository { public class GroupRepository {
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
private final SqlDialectProvider dialectProvider;
public GroupRepository(JdbcTemplate jdbcTemplate) { public GroupRepository(JdbcTemplate jdbcTemplate, SqlDialectProvider dialectProvider) {
this.jdbcTemplate = jdbcTemplate; this.jdbcTemplate = jdbcTemplate;
this.dialectProvider = dialectProvider;
} }
@Transactional @Transactional
public SearchQueryResult<Group> listGroups(SearchQueryPagination pagination) { public SearchQueryResult<Group> listGroups(SearchQueryPagination pagination) {
String query = "SELECT * FROM sys_group ORDER BY group_name LIMIT ? OFFSET ?"; String query = String.format("SELECT * FROM sys_group ORDER BY group_name %s",
dialectProvider.buildPaginationClause(pagination.getLimit(), pagination.getOffset()));
Object[] paginationParams = dialectProvider.getPaginationParameters(pagination.getLimit(), pagination.getOffset());
var groups = jdbcTemplate.query(query, new GroupMapper(), var groups = jdbcTemplate.query(query, new GroupMapper(),
pagination.getLimit(), pagination.getOffset()); paginationParams[0], paginationParams[1]);
Integer totalCount = jdbcTemplate.queryForObject( Integer totalCount = jdbcTemplate.queryForObject(
"SELECT COUNT(*) FROM sys_group ORDER BY group_name", "SELECT COUNT(*) FROM sys_group",
Integer.class Integer.class
); );
@ -63,8 +69,13 @@ public class GroupRepository {
@Transactional @Transactional
public void updateGroup(Group group) { public void updateGroup(Group group) {
String query = "INSERT INTO sys_group (group_name, group_description) VALUES (?, ?) ON DUPLICATE KEY UPDATE group_description = ?"; String query = dialectProvider.buildUpsertStatement(
jdbcTemplate.update(query, group.getName(), group.getDescription(), group.getDescription()); "sys_group",
List.of("group_name"),
List.of("group_name", "group_description"),
List.of("group_description")
);
jdbcTemplate.update(query, group.getName(), group.getDescription());
} }
private static class GroupMapper implements RowMapper<Group> { private static class GroupMapper implements RowMapper<Group> {

View file

@ -1,5 +1,6 @@
package de.avatic.lcc.repositories.users; package de.avatic.lcc.repositories.users;
import de.avatic.lcc.database.dialect.SqlDialectProvider;
import de.avatic.lcc.model.db.ValidityTuple; import de.avatic.lcc.model.db.ValidityTuple;
import de.avatic.lcc.model.db.nodes.Node; import de.avatic.lcc.model.db.nodes.Node;
import de.avatic.lcc.util.exception.base.ForbiddenException; import de.avatic.lcc.util.exception.base.ForbiddenException;
@ -22,9 +23,11 @@ public class UserNodeRepository {
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
private final SqlDialectProvider dialectProvider;
public UserNodeRepository(JdbcTemplate jdbcTemplate) { public UserNodeRepository(JdbcTemplate jdbcTemplate, SqlDialectProvider dialectProvider) {
this.jdbcTemplate = jdbcTemplate; this.jdbcTemplate = jdbcTemplate;
this.dialectProvider = dialectProvider;
} }
@Transactional @Transactional
@ -46,8 +49,11 @@ public class UserNodeRepository {
queryBuilder.append(" AND is_deprecated = FALSE"); queryBuilder.append(" AND is_deprecated = FALSE");
} }
queryBuilder.append(" LIMIT ?"); queryBuilder.append(" ").append(dialectProvider.buildPaginationClause(limit, 0));
params.add(limit);
Object[] paginationParams = dialectProvider.getPaginationParameters(limit, 0);
params.add(paginationParams[0]);
params.add(paginationParams[1]);
return jdbcTemplate.query(queryBuilder.toString(), new NodeMapper(), params.toArray()); return jdbcTemplate.query(queryBuilder.toString(), new NodeMapper(), params.toArray());
} }