fr.ouestfrance.querydsl.postgrest.PostgrestRepository Maven / Gradle / Ivy
The newest version!
package fr.ouestfrance.querydsl.postgrest;
import fr.ouestfrance.querydsl.postgrest.annotations.Header;
import fr.ouestfrance.querydsl.postgrest.annotations.OnConflict;
import fr.ouestfrance.querydsl.postgrest.annotations.PostgrestConfiguration;
import fr.ouestfrance.querydsl.postgrest.model.*;
import fr.ouestfrance.querydsl.postgrest.model.exceptions.MissingConfigurationException;
import fr.ouestfrance.querydsl.postgrest.model.exceptions.PostgrestRequestException;
import fr.ouestfrance.querydsl.postgrest.model.impl.CountFilter;
import fr.ouestfrance.querydsl.postgrest.model.impl.OrderFilter;
import fr.ouestfrance.querydsl.postgrest.model.impl.SelectFilter;
import fr.ouestfrance.querydsl.postgrest.services.BulkExecutorService;
import fr.ouestfrance.querydsl.postgrest.services.ext.PostgrestQueryProcessorService;
import fr.ouestfrance.querydsl.postgrest.utils.FilterUtils;
import fr.ouestfrance.querydsl.service.ext.QueryDslProcessorService;
import java.lang.reflect.ParameterizedType;
import java.util.*;
import static fr.ouestfrance.querydsl.postgrest.annotations.Header.Method.*;
import static fr.ouestfrance.querydsl.postgrest.utils.FilterUtils.toMap;
/**
* Postgrest repository implementation
*
* @param type of returned entity
*/
public class PostgrestRepository implements Repository {
public static final String ON_CONFLICT_QUERY_PARAMS = "on_conflict";
private final QueryDslProcessorService processorService = new PostgrestQueryProcessorService();
private final BulkExecutorService bulkService = new BulkExecutorService();
private final PostgrestConfiguration annotation;
private final Map>> headersMap = new EnumMap<>(Header.Method.class);
private final PostgrestClient client;
private Class clazz;
/**
* Postgrest Repository constructor
*
* @param client webClient adapter
*/
public PostgrestRepository(PostgrestClient client) {
this.client = client;
if (!getClass().isAnnotationPresent(PostgrestConfiguration.class)) {
throw new MissingConfigurationException(getClass(),
"Missing annotation " + PostgrestConfiguration.class.getSimpleName());
}
annotation = getClass().getAnnotation(PostgrestConfiguration.class);
// Create headerMap
Arrays.stream(getClass().getAnnotationsByType(Header.class))
.forEach(header -> Arrays.stream(header.methods())
.forEach(method ->
headersMap.computeIfAbsent(method, x -> new LinkedHashMap<>())
.computeIfAbsent(header.key(), x -> new ArrayList<>())
.addAll(Arrays.asList(header.value()))
)
);
if (getClass().getGenericSuperclass() instanceof ParameterizedType type) {
//noinspection unchecked
clazz = (Class) type.getActualTypeArguments()[0];
}
}
@Override
public Page search(Object criteria, Pageable pageable) {
List queryParams = processorService.process(criteria);
Map> headers = headerMap(Header.Method.GET);
// Add pageable if present
if (pageable.getPageSize() > 0) {
headers.put("Range-Unit", List.of("items"));
headers.put("Range", List.of(pageable.toRange()));
}
headers.computeIfAbsent(Prefer.HEADER, x -> new ArrayList<>())
.add("count=" + annotation.countStrategy().name().toLowerCase());
// Add sort if present
if (pageable.getSort() != null) {
queryParams.add(OrderFilter.of(pageable.getSort()));
}
// Add select criteria
getSelects(criteria).ifPresent(queryParams::add);
RangeResponse response = client.search(annotation.resource(), toMap(queryParams), headers, clazz);
int pageSize = Optional.of(pageable)
.filter(Pageable::hasSize)
.map(Pageable::getPageSize)
.orElse(response.getPageSize());
// Compute PageResponse
return new PageImpl<>(response.data(), pageable, response.getTotalElements(), (int) Math.ceil((double) response.getTotalElements() / pageSize));
}
@Override
public long count(Object criteria) {
List queryParams = processorService.process(criteria);
queryParams.add(CountFilter.of());
List response = client.count(annotation.resource(), toMap(queryParams));
// Retrieve result headers
return response.stream().findFirst().map(x -> x.get("count")).map(Long::valueOf).orElse(0L);
}
@Override
public BulkResponse post(List