Skip to content

Commit

Permalink
make it much faster and use boolean default values where possible
Browse files Browse the repository at this point in the history
  • Loading branch information
krusche committed Dec 27, 2024
1 parent d6a1b81 commit a223ccc
Show file tree
Hide file tree
Showing 21 changed files with 195 additions and 199 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,25 +57,22 @@ public class Channel extends Conversation {
* A channel is either public or private. Users need an invitation to join a private channel. Every user can join a public channel.
*/
@Column(name = "is_public")
@NotNull
private Boolean isPublic;
private boolean isPublic = false;

/**
* An announcement channel is a special type of channel where only channel moderators and instructors can start new posts.
* Answer posts are still possible so that students can ask questions concerning the announcement.
*/
@Column(name = "is_announcement")
@NotNull
private Boolean isAnnouncementChannel;
private boolean isAnnouncementChannel = false;

/**
* A channel that is no longer needed can be archived or deleted.
* Archived channels are closed to new activity, but the message history is retained and searchable.
* The channel can be unarchived at any time.
*/
@Column(name = "is_archived")
@NotNull
private Boolean isArchived;
private boolean isArchived = false;

/**
* Channels, that are meant to be seen by all course members by default, even if they haven't joined the channel yet, can be flagged with is_course_wide=true.
Expand All @@ -101,7 +98,7 @@ public class Channel extends Conversation {
private Exam exam;

public Channel(Long id, User creator, Set<ConversationParticipant> conversationParticipants, Set<Post> posts, Course course, ZonedDateTime creationDate,
ZonedDateTime lastMessageDate, String name, @Nullable String description, @Nullable String topic, Boolean isPublic, Boolean isAnnouncementChannel, Boolean isArchived,
ZonedDateTime lastMessageDate, String name, @Nullable String description, @Nullable String topic, boolean isPublic, boolean isAnnouncementChannel, boolean isArchived,
boolean isCourseWide, Lecture lecture, Exercise exercise, Exam exam) {
super(id, creator, conversationParticipants, posts, course, creationDate, lastMessageDate);
this.name = name;
Expand Down Expand Up @@ -138,11 +135,11 @@ public void setDescription(@Nullable String description) {
}

@Nullable
public Boolean getIsPublic() {
public boolean getIsPublic() {
return isPublic;
}

public void setIsPublic(@Nullable Boolean isPublic) {
public void setIsPublic(boolean isPublic) {
this.isPublic = isPublic;
}

Expand All @@ -155,19 +152,19 @@ public void setTopic(@Nullable String topic) {
this.topic = topic;
}

public Boolean getIsArchived() {
public boolean getIsArchived() {
return isArchived;
}

public void setIsArchived(Boolean archived) {
public void setIsArchived(boolean archived) {
isArchived = archived;
}

public Boolean getIsAnnouncementChannel() {
public boolean getIsAnnouncementChannel() {
return isAnnouncementChannel;
}

public void setIsAnnouncementChannel(Boolean announcementChannel) {
public void setIsAnnouncementChannel(boolean announcementChannel) {
isAnnouncementChannel = announcementChannel;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import de.tum.cit.aet.artemis.communication.domain.conversation.ChannelSubType;

@JsonInclude(JsonInclude.Include.NON_EMPTY)
// TODO: use record in the future
public class ChannelDTO extends ConversationDTO {

private String name;
Expand All @@ -14,25 +15,25 @@ public class ChannelDTO extends ConversationDTO {

private String topic;

private Boolean isPublic;
private boolean isPublic = false; // default value

private Boolean isAnnouncementChannel;
private boolean isAnnouncementChannel = false; // default value

private Boolean isArchived;
private boolean isArchived = false; // default value

private Boolean isCourseWide;
private boolean isCourseWide = false; // default value

// property not taken from entity
/**
* A course instructor has channel moderation rights but is not necessarily a moderator of the channel
*/
private Boolean hasChannelModerationRights;
private boolean hasChannelModerationRights = false; // default value

// property not taken from entity
/**
* Member of the channel that is also a moderator of the channel
*/
private Boolean isChannelModerator;
private boolean isChannelModerator = false; // default value

// property not taken from entity
/**
Expand Down Expand Up @@ -98,43 +99,43 @@ public void setTopic(String topic) {
this.topic = topic;
}

public Boolean getIsPublic() {
public boolean getIsPublic() {
return isPublic;
}

public void setIsPublic(Boolean isPublic) {
public void setIsPublic(boolean isPublic) {
this.isPublic = isPublic;
}

public Boolean getIsAnnouncementChannel() {
public boolean getIsAnnouncementChannel() {
return isAnnouncementChannel;
}

public void setIsAnnouncementChannel(Boolean announcementChannel) {
public void setIsAnnouncementChannel(boolean announcementChannel) {
isAnnouncementChannel = announcementChannel;
}

public Boolean getIsArchived() {
public boolean getIsArchived() {
return isArchived;
}

public void setIsArchived(Boolean archived) {
public void setIsArchived(boolean archived) {
isArchived = archived;
}

public Boolean getHasChannelModerationRights() {
public boolean getHasChannelModerationRights() {
return hasChannelModerationRights;
}

public void setHasChannelModerationRights(Boolean hasChannelModerationRights) {
public void setHasChannelModerationRights(boolean hasChannelModerationRights) {
this.hasChannelModerationRights = hasChannelModerationRights;
}

public Boolean getIsChannelModerator() {
public boolean getIsChannelModerator() {
return isChannelModerator;
}

public void setIsChannelModerator(Boolean isChannelModerator) {
public void setIsChannelModerator(boolean isChannelModerator) {
this.isChannelModerator = isChannelModerator;
}

Expand Down Expand Up @@ -162,11 +163,11 @@ public Long getSubTypeReferenceId() {
return subTypeReferenceId;
}

public Boolean getIsCourseWide() {
public boolean getIsCourseWide() {
return isCourseWide;
}

public void setIsCourseWide(Boolean courseWide) {
public void setIsCourseWide(boolean courseWide) {
isCourseWide = courseWide;
}

Expand Down Expand Up @@ -195,4 +196,16 @@ else if (channel.getExam() != null) {
this.subType = ChannelSubType.GENERAL;
}
}

public Channel toChannel() {
Channel channel = new Channel();
channel.setName(this.name);
channel.setDescription(this.description);
channel.setTopic(this.topic);
channel.setIsPublic(this.isPublic);
channel.setIsArchived(this.isArchived);
channel.setIsAnnouncementChannel(this.isAnnouncementChannel);
channel.setIsCourseWide(this.isCourseWide);
return channel;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ public class ConversationDTO {
// property not taken from entity
private Long unreadMessagesCount;

// TODO: use boolean where possible

// property not taken from entity
private Boolean isFavorite;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE;

import java.time.ZonedDateTime;
import java.util.List;
import java.util.Optional;
import java.util.Set;

Expand Down Expand Up @@ -60,8 +61,27 @@ public interface ConversationParticipantRepository extends ArtemisJpaRepository<
""")
void updateLastReadAsync(@Param("userId") Long userId, @Param("conversationId") Long conversationId, @Param("now") ZonedDateTime now);

@Async
@Transactional // ok because of modifying query
@Modifying
@Query("""
UPDATE ConversationParticipant p
SET p.lastRead = :now, p.unreadMessagesCount = 0
WHERE p.user.id = :userId
AND p.conversation.id IN :conversationIds
""")
void updateMultipleLastReadAsync(@Param("userId") Long userId, @Param("conversationIds") List<Long> conversationIds, @Param("now") ZonedDateTime now);

boolean existsByConversationIdAndUserId(Long conversationId, Long userId);

@Query("""
SELECT DISTINCT conversationParticipant.conversation.id
FROM ConversationParticipant conversationParticipant
WHERE conversationParticipant.user.id = :userId
AND conversationParticipant.conversation.course.id = :courseId
""")
List<Long> findConversationIdsByUserIdAndCourseId(@Param("userId") Long userId, @Param("courseId") Long courseId);

Optional<ConversationParticipant> findConversationParticipantByConversationIdAndUserId(Long conversationId, Long userId);

@Query("""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import de.tum.cit.aet.artemis.communication.domain.conversation.Channel;
import de.tum.cit.aet.artemis.communication.domain.conversation.Conversation;
import de.tum.cit.aet.artemis.communication.dto.GeneralConversationInfo;
import de.tum.cit.aet.artemis.communication.dto.UserConversationInfo;
Expand Down Expand Up @@ -90,11 +91,17 @@ SELECT COUNT(p.id) > 0
""")
boolean userHasUnreadMessageInCourse(@Param("courseId") Long courseId, @Param("userId") Long userId);

/**
* Retrieves a list of conversations for the given course
*
* @param courseId the course id
* @return a list of conversations for the given course
*/
List<Conversation> findAllByCourseId(Long courseId);
@Query("""
SELECT DISTINCT c
FROM Conversation c
WHERE c.course.id = :courseId
AND TYPE(c) = Channel
AND c.isCourseWide = TRUE
AND c.id NOT IN (
SELECT cp.conversation.id
FROM ConversationParticipant cp
WHERE cp.user.id = :userId
)
""")
List<Channel> findAllCourseWideChannelsByUserIdAndCourseIdWithoutConversationParticipant(@Param("courseId") Long courseId, @Param("userId") Long userId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -256,14 +256,12 @@ public void unarchiveChannel(Long channelId) {
*
* @param lecture the lecture to create the channel for
* @param channelName the name of the channel
* @return the created channel
*/
public Channel createLectureChannel(Lecture lecture, Optional<String> channelName) {
public void createLectureChannel(Lecture lecture, Optional<String> channelName) {
Channel channelToCreate = createDefaultChannel(channelName, "lecture-", lecture.getTitle());
channelToCreate.setLecture(lecture);
Channel createdChannel = createChannel(lecture.getCourse(), channelToCreate, Optional.of(userRepository.getUserWithGroupsAndAuthorities()));
lecture.setChannelName(createdChannel.getName());
return createdChannel;
}

/**
Expand All @@ -287,32 +285,29 @@ public Channel createExerciseChannel(Exercise exercise, Optional<String> channel
*
* @param exam the exam to create the channel for
* @param channelName the name of the channel
* @return the created channel
*/
public Channel createExamChannel(Exam exam, Optional<String> channelName) {
public void createExamChannel(Exam exam, Optional<String> channelName) {
Channel channelToCreate = createDefaultChannel(channelName, "exam-", exam.getTitle());
channelToCreate.setExam(exam);
Channel createdChannel = createChannel(exam.getCourse(), channelToCreate, Optional.of(userRepository.getUserWithGroupsAndAuthorities()));
exam.setChannelName(createdChannel.getName());
return createdChannel;
}

/**
* Update the channel of a lecture
*
* @param originalLecture the original lecture
* @param channelName the new channel name
* @return the updated channel
*/
public Channel updateLectureChannel(Lecture originalLecture, String channelName) {
public void updateLectureChannel(Lecture originalLecture, String channelName) {
if (channelName == null) {
return null;
return;
}
Channel channel = channelRepository.findChannelByLectureId(originalLecture.getId());
if (channel == null) {
return null;
return;
}
return updateChannelName(channel, channelName);
updateChannelName(channel, channelName);
}

/**
Expand Down Expand Up @@ -428,18 +423,11 @@ private static String generateChannelNameFromTitle(@NotNull String prefix, Optio
* @throws BadRequestAlertException if the channel name starts with an invalid prefix (e.g., "$").
*/
public Channel createFeedbackChannel(Course course, Long exerciseId, ChannelDTO channelDTO, List<String> feedbackDetailTexts, String testCaseName, User requestingUser) {
Channel channelToCreate = new Channel();
channelToCreate.setName(channelDTO.getName());
channelToCreate.setIsPublic(channelDTO.getIsPublic());
channelToCreate.setIsAnnouncementChannel(channelDTO.getIsAnnouncementChannel());
channelToCreate.setIsArchived(false);
channelToCreate.setDescription(channelDTO.getDescription());

if (channelToCreate.getName() != null && channelToCreate.getName().trim().startsWith("$")) {
if (channelDTO.getName() != null && channelDTO.getName().trim().startsWith("$")) {
throw new BadRequestAlertException("User generated channels cannot start with $", "channel", "channelNameInvalid");
}

Channel createdChannel = createChannel(course, channelToCreate, Optional.of(requestingUser));
Channel createdChannel = createChannel(course, channelDTO.toChannel(), Optional.of(requestingUser));

List<String> userLogins = studentParticipationRepository.findAffectedLoginsByFeedbackDetailText(exerciseId, feedbackDetailTexts, testCaseName);

Expand All @@ -451,14 +439,4 @@ public Channel createFeedbackChannel(Course course, Long exerciseId, ChannelDTO

return createdChannel;
}

/**
* Marks all channels of a course as read for the requesting user.
*
* @param course the course for which all channels should be marked as read.
* @param requestingUser the user requesting the marking of all channels as read.
*/
public void markAllChannelsOfCourseAsRead(Course course, User requestingUser) {
conversationService.markAllConversationOfAUserAsRead(course.getId(), requestingUser);
}
}
Loading

0 comments on commit a223ccc

Please sign in to comment.