From f843043fc41890499782f2b1fdccf1e2b00b114d Mon Sep 17 00:00:00 2001 From: KinTrae Date: Fri, 31 Jan 2025 15:17:40 +0100 Subject: [PATCH] feature: add matching search task: 8697rfa6n --- .../MatchingProfileController.java | 8 +++ .../controllers/MatchingSearchController.java | 26 +++++++ .../dtos/MatchingProfilePreferencesDto.java | 6 +- .../matching/models/MatchingProfile.java | 72 ++++++++++--------- .../MatchingProfileRepository.java | 17 +++++ .../services/MatchingProfileQueryService.java | 2 + .../impl/MatchingProfileQueryServiceImpl.java | 6 ++ .../impl/MatchingProfileServiceImpl.java | 4 +- database/scripts/120_create_tables.sql | 3 +- database/scripts/130_grant_references.sql | 13 ++-- database/scripts/140_create_references.sql | 14 ++-- .../scripts/330_mh_matching_set_age_job.sql | 21 ++++++ .../scripts/400_create_audit_triggers.sql | 1 + 13 files changed, 143 insertions(+), 50 deletions(-) create mode 100644 backend/src/main/java/meowhub/backend/matching/controllers/MatchingSearchController.java create mode 100644 database/scripts/330_mh_matching_set_age_job.sql diff --git a/backend/src/main/java/meowhub/backend/matching/controllers/MatchingProfileController.java b/backend/src/main/java/meowhub/backend/matching/controllers/MatchingProfileController.java index 65648459..7b4fce9e 100644 --- a/backend/src/main/java/meowhub/backend/matching/controllers/MatchingProfileController.java +++ b/backend/src/main/java/meowhub/backend/matching/controllers/MatchingProfileController.java @@ -47,7 +47,15 @@ public ResponseEntity createMatchingProfileFromScratch(@Requ return ResponseEntity.ok(matchingProfileService.createMatchingProfileFromScratch(request, userDetails.getUsername())); } + /*** + * Gets all matching profiles including own profile. For developments purposes only. + * This method is deprecated and will be removed in the future. + * @deprecated + * @param pageable + * @return + */ @GetMapping("/all") + @Deprecated(forRemoval = true) public ResponseEntity> getAllMatchingProfiles(Pageable pageable) { return ResponseEntity.ok(matchingProfileQueryService.getAllMatchingProfiles(pageable)); } diff --git a/backend/src/main/java/meowhub/backend/matching/controllers/MatchingSearchController.java b/backend/src/main/java/meowhub/backend/matching/controllers/MatchingSearchController.java new file mode 100644 index 00000000..b6186254 --- /dev/null +++ b/backend/src/main/java/meowhub/backend/matching/controllers/MatchingSearchController.java @@ -0,0 +1,26 @@ +package meowhub.backend.matching.controllers; + +import lombok.Builder; +import lombok.RequiredArgsConstructor; +import meowhub.backend.matching.dtos.MatchingProfileDto; +import meowhub.backend.matching.services.MatchingProfileQueryService; +import org.springframework.data.domain.Page; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/matching-search") +@RequiredArgsConstructor +public class MatchingSearchController { + private final MatchingProfileQueryService queryService; + + @GetMapping + public ResponseEntity> searchMatchingProfiles(@RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "10") int size, @AuthenticationPrincipal UserDetails userDetails) { + return ResponseEntity.ok(queryService.search(page, size, userDetails.getUsername())); + } +} diff --git a/backend/src/main/java/meowhub/backend/matching/dtos/MatchingProfilePreferencesDto.java b/backend/src/main/java/meowhub/backend/matching/dtos/MatchingProfilePreferencesDto.java index 0c81a37f..005f0ff6 100644 --- a/backend/src/main/java/meowhub/backend/matching/dtos/MatchingProfilePreferencesDto.java +++ b/backend/src/main/java/meowhub/backend/matching/dtos/MatchingProfilePreferencesDto.java @@ -5,8 +5,8 @@ import jakarta.validation.constraints.Min; import lombok.Getter; import lombok.Setter; +import meowhub.backend.constants.Genders; import meowhub.backend.matching.constants.LookingFor; -import meowhub.backend.matching.constants.Sexuality; import meowhub.backend.matching.models.MatchingProfile; @Setter @@ -32,7 +32,7 @@ public class MatchingProfilePreferencesDto { @Nullable private Short ageTo; - private Sexuality sexuality; + private Genders gender; private LookingFor lookingFor; @@ -42,7 +42,7 @@ public static MatchingProfilePreferencesDto createFromMatchingProfilePreferences matchingProfilePreferencesDto.setHeightTo(matchingProfile.getPHeightTo()); matchingProfilePreferencesDto.setAgeFrom(matchingProfile.getPAgeFrom()); matchingProfilePreferencesDto.setAgeTo(matchingProfile.getPAgeTo()); - matchingProfilePreferencesDto.setSexuality(Sexuality.valueOf(matchingProfile.getPSexuality().getCode())); + matchingProfilePreferencesDto.setGender(Genders.valueOf(matchingProfile.getPGender().getCode())); matchingProfilePreferencesDto.setLookingFor(LookingFor.valueOf(matchingProfile.getPLookingFor().getCode())); return matchingProfilePreferencesDto; } diff --git a/backend/src/main/java/meowhub/backend/matching/models/MatchingProfile.java b/backend/src/main/java/meowhub/backend/matching/models/MatchingProfile.java index 361218b9..d1cb9a18 100644 --- a/backend/src/main/java/meowhub/backend/matching/models/MatchingProfile.java +++ b/backend/src/main/java/meowhub/backend/matching/models/MatchingProfile.java @@ -47,38 +47,6 @@ public class MatchingProfile { @Column(name = "PROFILE_DETAILS_HTML", length = 2000) private String profileDetailsHtml; - @Column(name = "CREATED_AT") - private LocalDateTime createdAt; - - @Size(max = 36) - @Column(name = "CREATED_BY", length = 36) - private String createdBy; - - @Column(name = "MODIFIED_AT") - private LocalDateTime modifiedAt; - - @Size(max = 36) - @Column(name = "MODIFIED_BY", length = 36) - private String modifiedBy; - - @OneToMany(mappedBy = "receiver") - private Set likedReceiver = new LinkedHashSet<>(); - - @OneToMany(mappedBy = "sender") - private Set likedSender = new LinkedHashSet<>(); - - @OneToMany(mappedBy = "sender") - private Set matchingChatsSender = new LinkedHashSet<>(); - - @OneToMany(mappedBy = "receiver") - private Set matchingChatsReceiver = new LinkedHashSet<>(); - - @OneToMany(mappedBy = "matchingProfile") - private Set matchingChatMessages = new LinkedHashSet<>(); - - @OneToMany(mappedBy = "matchingProfile") - private Set matchingProfilePictures = new LinkedHashSet<>(); - @Size(max = 40) @NotNull @Column(name = "NAME", nullable = false, length = 40) @@ -88,6 +56,10 @@ public class MatchingProfile { @Column(name = "BIRTHDATE", nullable = false) private LocalDate birthdate; + @NotNull + @Column(name = "AGE", nullable = false) + private Short age; + @NotNull @ManyToOne(fetch = FetchType.LAZY, optional = false) @OnDelete(action = OnDeleteAction.RESTRICT) @@ -134,8 +106,8 @@ public class MatchingProfile { @ManyToOne(fetch = FetchType.LAZY, optional = false) @OnDelete(action = OnDeleteAction.RESTRICT) - @JoinColumn(name = "P_SEXUALITY_ID") - private Sexuality pSexuality; + @JoinColumn(name = "P_GENDER_ID") + private Gender pGender; @ManyToOne(fetch = FetchType.LAZY) @OnDelete(action = OnDeleteAction.RESTRICT) @@ -162,6 +134,38 @@ public class MatchingProfile { @Column(name = "P_HEIGHT_TO") private Short pHeightTo; + @Column(name = "CREATED_AT") + private LocalDateTime createdAt; + + @Size(max = 36) + @Column(name = "CREATED_BY", length = 36) + private String createdBy; + + @Column(name = "MODIFIED_AT") + private LocalDateTime modifiedAt; + + @Size(max = 36) + @Column(name = "MODIFIED_BY", length = 36) + private String modifiedBy; + + @OneToMany(mappedBy = "receiver") + private Set likedReceiver = new LinkedHashSet<>(); + + @OneToMany(mappedBy = "sender") + private Set likedSender = new LinkedHashSet<>(); + + @OneToMany(mappedBy = "sender") + private Set matchingChatsSender = new LinkedHashSet<>(); + + @OneToMany(mappedBy = "receiver") + private Set matchingChatsReceiver = new LinkedHashSet<>(); + + @OneToMany(mappedBy = "matchingProfile") + private Set matchingChatMessages = new LinkedHashSet<>(); + + @OneToMany(mappedBy = "matchingProfile") + private Set matchingProfilePictures = new LinkedHashSet<>(); + /* TODO [Reverse Engineering] create field to map the 'GEOLOCALIZATION' column Available actions: Define target Java type | Uncomment as is | Remove column mapping diff --git a/backend/src/main/java/meowhub/backend/matching/repositories/MatchingProfileRepository.java b/backend/src/main/java/meowhub/backend/matching/repositories/MatchingProfileRepository.java index de0e1fa5..632ee442 100644 --- a/backend/src/main/java/meowhub/backend/matching/repositories/MatchingProfileRepository.java +++ b/backend/src/main/java/meowhub/backend/matching/repositories/MatchingProfileRepository.java @@ -1,7 +1,11 @@ package meowhub.backend.matching.repositories; import meowhub.backend.matching.models.MatchingProfile; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import java.util.Optional; @@ -9,4 +13,17 @@ public interface MatchingProfileRepository extends JpaRepository { boolean existsByUserLogin(String login); Optional findByUserLogin(String login); + + @Query(""" + SELECT mp + FROM MatchingProfile mp, + MatchingProfile filters + WHERE mp.user.login != :login + AND filters.user.login = :login + AND mp.height BETWEEN COALESCE(filters.pHeightFrom, mp.height) AND COALESCE(filters.pHeightTo, mp.height) + AND mp.age BETWEEN COALESCE(filters.pAgeFrom, mp.age) AND COALESCE(filters.pAgeTo, mp.age) + AND mp.lookingFor.id = COALESCE(filters.pLookingFor.id, mp.lookingFor.id) + AND mp.gender.id = COALESCE(filters.pGender.id, mp.gender.id) + """) + Page search(@Param("login") String login, Pageable pageable); } \ No newline at end of file diff --git a/backend/src/main/java/meowhub/backend/matching/services/MatchingProfileQueryService.java b/backend/src/main/java/meowhub/backend/matching/services/MatchingProfileQueryService.java index 8c3565ff..fc1378fd 100644 --- a/backend/src/main/java/meowhub/backend/matching/services/MatchingProfileQueryService.java +++ b/backend/src/main/java/meowhub/backend/matching/services/MatchingProfileQueryService.java @@ -19,4 +19,6 @@ public interface MatchingProfileQueryService { Optional findMatchingProfileByLogin(String login); MatchingProfilePreferencesDto getPreferences(String login); + + Page search(int page, int size, String login); } diff --git a/backend/src/main/java/meowhub/backend/matching/services/impl/MatchingProfileQueryServiceImpl.java b/backend/src/main/java/meowhub/backend/matching/services/impl/MatchingProfileQueryServiceImpl.java index fa1c58b3..e47b78b3 100644 --- a/backend/src/main/java/meowhub/backend/matching/services/impl/MatchingProfileQueryServiceImpl.java +++ b/backend/src/main/java/meowhub/backend/matching/services/impl/MatchingProfileQueryServiceImpl.java @@ -50,4 +50,10 @@ public MatchingProfilePreferencesDto getPreferences(String login) { .map(MatchingProfilePreferencesDto::createFromMatchingProfilePreferencesFromMatchingProfile) .orElseThrow(); } + + @Override + public Page search(int page, int size, String login) { + Pageable pageable = Pageable.ofSize(size).withPage(page); + return matchingProfileRepository.search(login, pageable).map(MatchingProfileDto::createFromMatchingProfile); + } } diff --git a/backend/src/main/java/meowhub/backend/matching/services/impl/MatchingProfileServiceImpl.java b/backend/src/main/java/meowhub/backend/matching/services/impl/MatchingProfileServiceImpl.java index 0dfafbf0..3101c5fd 100644 --- a/backend/src/main/java/meowhub/backend/matching/services/impl/MatchingProfileServiceImpl.java +++ b/backend/src/main/java/meowhub/backend/matching/services/impl/MatchingProfileServiceImpl.java @@ -161,8 +161,8 @@ public void updateMatchingProfilePreferences(MatchingProfilePreferencesDto prefe matchingProfile.setPHeightTo(preferences.getHeightTo()); matchingProfile.setPAgeFrom(preferences.getAgeFrom()); matchingProfile.setPAgeTo(preferences.getAgeTo()); - matchingProfile.setPSexuality(sexualityRepository.findByCode(preferences.getSexuality().name()) - .orElseThrow(() -> new IllegalArgumentException(String.format(AlertConstants.RESOURCE_NOT_FOUND, "Sexuality", "code", preferences.getSexuality().name())))); + matchingProfile.setPGender(genderRepository.findByCode(preferences.getGender().name()) + .orElseThrow(() -> new IllegalArgumentException(String.format(AlertConstants.RESOURCE_NOT_FOUND, "Gender", "code", preferences.getGender().name())))); matchingProfile.setPLookingFor(lookingForRepository.findByCode(preferences.getLookingFor().name()) .orElseThrow(() -> new IllegalArgumentException(String.format(AlertConstants.RESOURCE_NOT_FOUND, "Looking for", "code", preferences.getLookingFor().name())))); matchingProfileRepository.save(matchingProfile); diff --git a/database/scripts/120_create_tables.sql b/database/scripts/120_create_tables.sql index 3848b307..bc942cc8 100644 --- a/database/scripts/120_create_tables.sql +++ b/database/scripts/120_create_tables.sql @@ -344,6 +344,7 @@ CREATE TABLE mh_matching.Matching_Profiles profile_details_html varchar2(2000) NULL, name varchar2(40) NOT NULL, birthdate date NOT NULL, + age number(3) NOT NULL, --updated by UPDATE_AGE_JOB everyday at midnight Gender_id varchar2(36) NOT NULL, height number(3) NULL, Sexuality_id varchar2(36) NULL, @@ -359,7 +360,7 @@ CREATE TABLE mh_matching.Matching_Profiles p_age_from number(3) NULL, p_age_to number(3) NULL, p_looking_for_id varchar2(36) NULL, - p_sexuality_id varchar2(36) NULL, + p_gender_id varchar2(36) NULL, created_at date NOT NULL, created_by varchar2(36) NOT NULL, modified_at date NULL, diff --git a/database/scripts/130_grant_references.sql b/database/scripts/130_grant_references.sql index 60e1cd30..125423f9 100644 --- a/database/scripts/130_grant_references.sql +++ b/database/scripts/130_grant_references.sql @@ -1,7 +1,8 @@ -- grant references to users.users -GRANT REFERENCES ON mh_users.users TO mh_chats; -GRANT REFERENCES ON mh_users.users TO mh_posts; -GRANT REFERENCES ON mh_users.users TO mh_groups; -GRANT REFERENCES ON mh_users.users TO mh_user_relations; -GRANT REFERENCES ON mh_users.users TO mh_matching; -GRANT REFERENCES ON mh_users.users TO mh_profiles; \ No newline at end of file +GRANT REFERENCES ON mh_users.users TO mh_chats; +GRANT REFERENCES ON mh_users.users TO mh_posts; +GRANT REFERENCES ON mh_users.users TO mh_groups; +GRANT REFERENCES ON mh_users.users TO mh_user_relations; +GRANT REFERENCES ON mh_users.users TO mh_matching; +GRANT REFERENCES ON mh_users.genders TO mh_matching; +GRANT REFERENCES ON mh_users.users TO mh_profiles; \ No newline at end of file diff --git a/database/scripts/140_create_references.sql b/database/scripts/140_create_references.sql index 1ad00296..c8afb01a 100644 --- a/database/scripts/140_create_references.sql +++ b/database/scripts/140_create_references.sql @@ -122,11 +122,17 @@ ALTER TABLE mh_matching.Matching_Profiles REFERENCES mh_users.Users (id) ON DELETE CASCADE; --- Reference: p_sexuality_Profile_Users (table: Matching_Profiles) +-- Reference: gender_Profile_Users (table: Matching_Profiles) ALTER TABLE mh_matching.Matching_Profiles - ADD CONSTRAINT p_sexuality_matching_profiles - FOREIGN KEY (p_sexuality_id) - REFERENCES mh_matching.sexuality (id); + ADD CONSTRAINT gender_matching_profiles + FOREIGN KEY (gender_id) + REFERENCES mh_users.Genders (id); + +-- Reference: p_gender_Profile_Users (table: Matching_Profiles) +ALTER TABLE mh_matching.Matching_Profiles + ADD CONSTRAINT p_gender_matching_profiles + FOREIGN KEY (p_gender_id) + REFERENCES mh_users.Genders (id); -- Reference: sexuality_matching_profiles (table: sexuality) ALTER TABLE mh_matching.matching_profiles diff --git a/database/scripts/330_mh_matching_set_age_job.sql b/database/scripts/330_mh_matching_set_age_job.sql new file mode 100644 index 00000000..3ff9d375 --- /dev/null +++ b/database/scripts/330_mh_matching_set_age_job.sql @@ -0,0 +1,21 @@ +BEGIN + DBMS_SCHEDULER.create_job ( + job_name => 'UPDATE_AGE_JOB', + job_type => 'PLSQL_BLOCK', + job_action => 'BEGIN + UPDATE mh_matching.Matching_Profiles + SET age = TRUNC(MONTHS_BETWEEN(SYSDATE, birthdate) / 12); + END;', + start_date => SYSTIMESTAMP, + repeat_interval => 'FREQ=DAILY; BYHOUR=0;', + enabled => TRUE + ); +END; +/ + +--tu run the job manually use the following command: +-- BEGIN +-- DBMS_SCHEDULER.run_job('UPDATE_AGE_JOB'); +-- END; +-- / + diff --git a/database/scripts/400_create_audit_triggers.sql b/database/scripts/400_create_audit_triggers.sql index 9696cd25..2bfdeaf2 100644 --- a/database/scripts/400_create_audit_triggers.sql +++ b/database/scripts/400_create_audit_triggers.sql @@ -252,6 +252,7 @@ CREATE OR REPLACE TRIGGER mh_matching.matching_profiles_audit_trg FOR EACH ROW BEGIN IF INSERTING THEN + :NEW.age := TRUNC(MONTHS_BETWEEN(SYSDATE, :NEW.birthdate) / 12); :NEW.created_at := CURRENT_TIMESTAMP; :NEW.created_by := mh_meowhub.get_user_id; ELSIF UPDATING THEN