Coding History/Team Project

팀플) 캘린더 DB 저장.

BlackBirdIT 2024. 11. 27. 14:15

우선은 리포지토리와 엔티티를 생성하고 그에 맞게끔 연결은 했는데.

DB를 추가 한 이유가 사용자 UI 개선의 목적도 있지만 결국 결론은

이제 DB저장을 하면 고유한 ID 번호가 생김 -> 복잡한 형태의 고유 ID를 입력하기 싫음.

이거임.

그래서 지금 작성한 로직을 DB ID 번호로 돌아가게끔 해야됨. 지금은 googleEventId를 내가 입력을 해줘야지 찾는데, 그게 아니고 고유 번호를 따라서 googleEventId를 찾아서 캘린더까지 접근해서 수정 삭제 읽기가 가능하게끔.


현재 코드는

@Service
@RequiredArgsConstructor
public class PublicCalendarEventService {
    private final CalendarEventManager calendarEventManager;
    private final PublicCalendarRepository publicCalendarRepository;

    // Create
    @Transactional
    public void addEvent(EventRequest request) throws IOException {
        // Google Calendar에 이벤트 추가하고, 생성된 ID를 반환받음
        String googleEventId = calendarEventManager.addEvent(
                request.getSummary(),
                request.getLocation(),
                request.getDescription(),
                request.getStartDateTime(),
                request.getEndDateTime(),
                request.getTimeZone()
        );

        // DB에 이벤트 추가
        PublicCalendar publicCalendar = new PublicCalendar();
        publicCalendar.setGoogleEventId(googleEventId);
        publicCalendar.setSummary(request.getSummary());
        publicCalendar.setLocation(request.getLocation());
        publicCalendar.setDescription(request.getDescription());
        publicCalendar.setStartDateTime(LocalDateTime.parse(request.getStartDateTime()));
        publicCalendar.setEndDateTime(LocalDateTime.parse(request.getEndDateTime()));
        publicCalendar.setTimeZone(request.getTimeZone());
        publicCalendarRepository.save(publicCalendar); // DB 추가
    }

    // Read (구글 캘린더 이벤트 조회)
    public List<Event> getPublicEvents(String calendarId) throws IOException {
        return calendarEventManager.getPublicEvents(calendarId);
    }

    // Read (DB에서 이벤트 조회)
    public List<PublicCalendar> getAllEventsFromDB() {
        return publicCalendarRepository.findAll();
    }

    // Read (DB에서 특정 Google Event ID로 이벤트 조회)
    public PublicCalendar getEventByGoogleEventId(String googleEventId) {
        return publicCalendarRepository.findByGoogleEventId(googleEventId)
                .orElseThrow(() -> new IllegalArgumentException("Event not found: " + googleEventId));
    }


    // Update
    @Transactional
    public void updateEvent(String calendarId, String googleEventId, EventRequest request) throws IOException {
        // Google Calendar에서 이벤트 업데이트
        calendarEventManager.updateEvent(
                calendarId,  // 여기서 calendarId 추가
                request.getGoogleEventId(),
                request.getSummary(),
                request.getLocation(),
                request.getDescription(),
                request.getStartDateTime(),
                request.getEndDateTime(),
                request.getTimeZone()
        );

        // DB에서도 이벤트 업데이트
        PublicCalendar publicCalendar = publicCalendarRepository.findByGoogleEventId(googleEventId)
                .orElseThrow(() -> new IllegalArgumentException("Event not found: " + googleEventId));
        publicCalendar.setSummary(request.getSummary());
        publicCalendar.setLocation(request.getLocation());
        publicCalendar.setDescription(request.getDescription());
        publicCalendar.setStartDateTime(LocalDateTime.parse(request.getStartDateTime()));
        publicCalendar.setEndDateTime(LocalDateTime.parse(request.getEndDateTime()));
        publicCalendar.setTimeZone(request.getTimeZone());

        publicCalendarRepository.save(publicCalendar); // DB 업데이트

        // 구글 캘린더 업데이트된 이벤트 링크 출력
        System.out.printf("Event updated: https://www.google.com/calendar/event?eid=%s\n", googleEventId);
    }

    // Delete
    @Transactional
    public void deleteEvent(String calendarId, String googleEventId) throws IOException {
        // Google Calendar에서 이벤트 삭제
        calendarEventManager.deleteEvent(calendarId, googleEventId);

        // DB에서도 이벤트 삭제
        PublicCalendar publicCalendar = publicCalendarRepository.findByGoogleEventId(googleEventId)
                .orElseThrow(() -> new IllegalArgumentException("Event not found: " + googleEventId));
        publicCalendarRepository.delete(publicCalendar);
    }
}

이렇고, @Transactional을 통해서 둘중 하나라도 실패하면 실패처리하게끔 함.

Manager도 기존 void에서 String으로 받게끔 바꿔줌.

일단은 기존 로직이 제대로 돌아가는가 테스트 해보고 번호로 돌아가게끔 바꿀 예정.

add 테스트중에 createBy를 가져오는데 실패해서 로직을 좀 바꿈

    // Create
    @Transactional
    public void addEvent(EventRequest request) throws IOException {
        // Google Calendar에 이벤트 추가하고, 생성된 ID를 반환받음
        Event event = calendarEventManager.addEvent(
                request.getSummary(),
                request.getLocation(),
                request.getDescription(),
                request.getStartDateTime(),
                request.getEndDateTime(),
                request.getTimeZone()
        );

        OffsetDateTime offsetDateTime = OffsetDateTime.parse(request.getStartDateTime());
        OffsetDateTime offsetEndDateTime = OffsetDateTime.parse(request.getEndDateTime());

        // Google Calendar에서 반환된 이벤트의 `creator` 정보를 사용하여 createdBy 설정
        String createdBy = event.getCreator().getEmail();

        // DB에 이벤트 추가
        PublicCalendar publicCalendar = new PublicCalendar();
        publicCalendar.setGoogleEventId(event.getId());
        publicCalendar.setSummary(request.getSummary());
        publicCalendar.setLocation(request.getLocation());
        publicCalendar.setDescription(request.getDescription());
        publicCalendar.setStartDateTime(offsetDateTime.toLocalDateTime());
        publicCalendar.setEndDateTime(offsetEndDateTime.toLocalDateTime());
        publicCalendar.setTimeZone(request.getTimeZone());
        publicCalendar.setCreatedBy(request.getCreatedBy());
        publicCalendarRepository.save(publicCalendar); // DB 추가
    }

OffsetDateTime 변환은 덤. ManagerString을 받는게 아닌

    public Event addEvent(String summary, String location, String description,
                          String startDateTimeStr, String endDateTimeStr, String timeZone) throws IOException {
        Event event = new Event()
                .setSummary(summary)
                .setLocation(location)
                .setDescription(description);

        DateTime startDateTime = new DateTime(startDateTimeStr);
        EventDateTime start = new EventDateTime()
                .setDateTime(startDateTime)
                .setTimeZone(timeZone);
        event.setStart(start);

        DateTime endDateTime = new DateTime(endDateTimeStr);
        EventDateTime end = new EventDateTime()
                .setDateTime(endDateTime)
                .setTimeZone(timeZone);
        event.setEnd(end);

        String calendarId = "primary";  // 기본 캘린더 사용
        event = service.events().insert(calendarId, event).execute();

        System.out.printf("Event created: %s\n", event.getHtmlLink());
        return event; // 생성된 Google Event 객체 반환
    }

Event 객체를 반환하게 함.

오케이 성공함!!

DB도 까보자고,

ㅇㅋ DB에도 잘 들어왔음.

이제는 읽기확인해보자.

일단 구글 캘린더에서 가져오는 놈은 잘 되고,

DB도 잘 됨.

다음은 수정.

수정도 OffsetDateTime 변환로직이 없어서 고쳐줌.

DB도 바뀌어있음.

PUT 요청도 잘 되고,,

삭제 테스트.

중에

이런 오류가 나타남.

매핑된 메소드의 매개변수에 이름이 지정되지 않아서 발생한 문제인데 이건

tasks.withType<JavaCompile> {
    options.compilerArgs.add("-parameters")
}

이걸 추가해줘서 알아서 하게끔 함.

굳,

DB도 지워짐. 이러면 이제 번호로 로직 돌아가게 하면 될듯.


그래서 일단은 이제 DB 아이디로 될 수 있게 최종 수정함.
근데 이제 여기 로직에서는 primary로, 그러니까 캘린더의 가장 기본으로만 데이터를 삽입중이였는데, 내가 여기서 제공할 정보는 유성우와 행성 대접근을 캘린더로 보여줄 예정이다.

그럼 여기서 primary로 들어갈게 아니라 두개로 나눠서 알아서 받을 수 있게끔 해주면 편할듯?

public enum EventCategory {
    METEOR("Meteor"),
    PLANET("Planet"),
    GENERAL("General");

    private final String displayName;

    EventCategory(String displayName) {
        this.displayName = displayName;
    }

    @JsonValue
    public String getDisplayName() {
        return displayName;
    }

    @JsonCreator
    public static EventCategory fromString(String text) {
        for (EventCategory category : EventCategory.values()) {
            if (category.displayName.equalsIgnoreCase(text)) {
                return category;
            }
        }
        throw new IllegalArgumentException("Invalid event category: " + text);
    }
}

그래서 enum 도입해서 처리함.

일단은 여기까지