Added component search endpoint.

This commit is contained in:
Andrew Lalis 2022-05-17 22:31:53 +02:00
parent 08fb892cc5
commit 4abd39cbe1
4 changed files with 32 additions and 2 deletions

View File

@ -3,7 +3,9 @@ package nl.andrewl.railsignalapi.dao;
import nl.andrewl.railsignalapi.model.RailSystem; import nl.andrewl.railsignalapi.model.RailSystem;
import nl.andrewl.railsignalapi.model.component.Component; import nl.andrewl.railsignalapi.model.component.Component;
import nl.andrewl.railsignalapi.model.component.Position; import nl.andrewl.railsignalapi.model.component.Position;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
@ -11,7 +13,7 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
@Repository @Repository
public interface ComponentRepository<T extends Component> extends JpaRepository<T, Long> { public interface ComponentRepository<T extends Component> extends JpaRepository<T, Long>, JpaSpecificationExecutor<T> {
Optional<T> findByIdAndRailSystemId(long id, long rsId); Optional<T> findByIdAndRailSystemId(long id, long rsId);
boolean existsByNameAndRailSystem(String name, RailSystem rs); boolean existsByNameAndRailSystem(String name, RailSystem rs);

View File

@ -4,12 +4,15 @@ import lombok.RequiredArgsConstructor;
import nl.andrewl.railsignalapi.rest.dto.PathNodeUpdatePayload; import nl.andrewl.railsignalapi.rest.dto.PathNodeUpdatePayload;
import nl.andrewl.railsignalapi.rest.dto.component.in.ComponentPayload; import nl.andrewl.railsignalapi.rest.dto.component.in.ComponentPayload;
import nl.andrewl.railsignalapi.rest.dto.component.out.ComponentResponse; import nl.andrewl.railsignalapi.rest.dto.component.out.ComponentResponse;
import nl.andrewl.railsignalapi.rest.dto.component.out.SimpleComponentResponse;
import nl.andrewl.railsignalapi.service.ComponentCreationService; import nl.andrewl.railsignalapi.service.ComponentCreationService;
import nl.andrewl.railsignalapi.service.ComponentService; import nl.andrewl.railsignalapi.service.ComponentService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List; import java.util.List;
@RestController @RestController
@ -24,6 +27,15 @@ public class ComponentsApiController {
return componentService.getComponents(rsId); return componentService.getComponents(rsId);
} }
@GetMapping(path = "/search")
public Page<SimpleComponentResponse> searchComponents(
@RequestParam(name = "q", required = false) String searchQuery,
@PageableDefault(sort = "name")
Pageable pageable
) {
return componentService.search(searchQuery, pageable);
}
@GetMapping(path = "/{cId}") @GetMapping(path = "/{cId}")
public ComponentResponse getComponent(@PathVariable long rsId, @PathVariable long cId) { public ComponentResponse getComponent(@PathVariable long rsId, @PathVariable long cId) {
return componentService.getComponent(rsId, cId); return componentService.getComponent(rsId, cId);

View File

@ -8,6 +8,9 @@ import nl.andrewl.railsignalapi.model.component.Component;
import nl.andrewl.railsignalapi.model.component.PathNode; import nl.andrewl.railsignalapi.model.component.PathNode;
import nl.andrewl.railsignalapi.rest.dto.PathNodeUpdatePayload; import nl.andrewl.railsignalapi.rest.dto.PathNodeUpdatePayload;
import nl.andrewl.railsignalapi.rest.dto.component.out.ComponentResponse; import nl.andrewl.railsignalapi.rest.dto.component.out.ComponentResponse;
import nl.andrewl.railsignalapi.rest.dto.component.out.SimpleComponentResponse;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -38,6 +41,16 @@ public class ComponentService {
return ComponentResponse.of(c); return ComponentResponse.of(c);
} }
@Transactional(readOnly = true)
public Page<SimpleComponentResponse> search(String searchQuery, Pageable pageable) {
return componentRepository.findAll((root, query, cb) -> {
if (searchQuery != null && !searchQuery.isBlank()) {
return cb.like(cb.lower(root.get("name")), '%' + searchQuery.toLowerCase() + '%');
}
return cb.and();
}, pageable).map(SimpleComponentResponse::new);
}
@Transactional @Transactional
public void removeComponent(long rsId, long componentId) { public void removeComponent(long rsId, long componentId) {
var c = componentRepository.findByIdAndRailSystemId(componentId, rsId) var c = componentRepository.findByIdAndRailSystemId(componentId, rsId)

View File

@ -9,6 +9,9 @@ import nl.andrewl.railsignalapi.model.component.Switch;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
/**
* Service for managing switches.
*/
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
public class SwitchService { public class SwitchService {