From 657f10fcc7f9ccd4beba17792c3bccf2d3af9260 Mon Sep 17 00:00:00 2001 From: Daniel Gerhardt <code@dgerhardt.net> Date: Sat, 17 Aug 2019 14:29:45 +0200 Subject: [PATCH] Refactor legacy code for /v2 to support content groups Use updated content group handling and remove all references to the old `variant` property of contents/answers. The following /v2 endpoints are now fully implemented: * Deleting all contents of a group (/) * Retrieving ids of unanswered content in a group (/unanswered) * Deleting all answers of contents in a group (/answers) * Counting answers of a group (/answercount) --- .../controller/v2/ContentController.java | 47 +++--- .../arsnova/persistence/AnswerRepository.java | 9 +- .../persistence/ContentRepository.java | 29 +--- .../couchdb/CouchDbAnswerRepository.java | 30 ++-- .../couchdb/CouchDbContentRepository.java | 142 ++---------------- .../arsnova/service/AnswerServiceImpl.java | 31 ++-- .../arsnova/service/ContentGroupService.java | 6 +- .../arsnova/service/ContentServiceImpl.java | 45 +++--- src/main/resources/couchdb/Answer.design.js | 25 +-- src/main/resources/couchdb/Content.design.js | 4 +- 10 files changed, 111 insertions(+), 257 deletions(-) diff --git a/src/main/java/de/thm/arsnova/controller/v2/ContentController.java b/src/main/java/de/thm/arsnova/controller/v2/ContentController.java index cd26dbbd7..ad1ea3d6f 100644 --- a/src/main/java/de/thm/arsnova/controller/v2/ContentController.java +++ b/src/main/java/de/thm/arsnova/controller/v2/ContentController.java @@ -356,14 +356,16 @@ public class ContentController extends PaginationController { nickname = "deleteContents") @DeleteMapping("/") public void deleteContents( - @RequestParam(value = "sessionkey") final String roomShortId, - @RequestParam(value = "lecturequestionsonly", defaultValue = "false") boolean lectureContentsOnly, - @RequestParam(value = "flashcardsonly", defaultValue = "false") boolean flashcardsOnly, - @RequestParam(value = "preparationquestionsonly", defaultValue = "false") boolean preparationContentsOnly, + @RequestParam(value = "sessionkey") + final String roomShortId, + @RequestParam(value = "lecturequestionsonly", defaultValue = "false") + final boolean lectureContentsOnly, + @RequestParam(value = "flashcardsonly", defaultValue = "false") + final boolean flashcardsOnly, + @RequestParam(value = "preparationquestionsonly", defaultValue = "false") + final boolean preparationContentsOnly, final HttpServletResponse response) { final String roomId = roomService.getIdByShortId(roomShortId); - /* FIXME: Content variant is ignored for now */ - lectureContentsOnly = preparationContentsOnly = flashcardsOnly = false; if (lectureContentsOnly) { contentService.deleteLectureContents(roomId); } else if (preparationContentsOnly) { @@ -414,13 +416,14 @@ public class ContentController extends PaginationController { @Deprecated @GetMapping("/unanswered") public List<String> getUnAnsweredContentIds( - @RequestParam(value = "sessionkey") final String roomShortId, - @RequestParam(value = "lecturequestionsonly", defaultValue = "false") boolean lectureContentsOnly, - @RequestParam(value = "preparationquestionsonly", defaultValue = "false") boolean preparationContentsOnly) { + @RequestParam(value = "sessionkey") + final String roomShortId, + @RequestParam(value = "lecturequestionsonly", defaultValue = "false") + final boolean lectureContentsOnly, + @RequestParam(value = "preparationquestionsonly", defaultValue = "false") + final boolean preparationContentsOnly) { final String roomId = roomService.getIdByShortId(roomShortId); final List<String> answers; - /* FIXME: Content variant is ignored for now */ - lectureContentsOnly = preparationContentsOnly = false; if (lectureContentsOnly) { answers = contentService.getUnAnsweredLectureContentIds(roomId); } else if (preparationContentsOnly) { @@ -589,13 +592,14 @@ public class ContentController extends PaginationController { nickname = "deleteAllContentsAnswers") @DeleteMapping("/answers") public void deleteAllContentsAnswers( - @RequestParam(value = "sessionkey") final String roomShortId, - @RequestParam(value = "lecturequestionsonly", defaultValue = "false") boolean lectureContentsOnly, - @RequestParam(value = "preparationquestionsonly", defaultValue = "false") boolean preparationContentsOnly, + @RequestParam(value = "sessionkey") + final String roomShortId, + @RequestParam(value = "lecturequestionsonly", defaultValue = "false") + final boolean lectureContentsOnly, + @RequestParam(value = "preparationquestionsonly", defaultValue = "false") + final boolean preparationContentsOnly, final HttpServletResponse response) { final String roomId = roomService.getIdByShortId(roomShortId); - /* FIXME: Content variant is ignored for now */ - lectureContentsOnly = preparationContentsOnly = false; if (lectureContentsOnly) { contentService.deleteAllLectureAnswers(roomId); } else if (preparationContentsOnly) { @@ -685,13 +689,14 @@ public class ContentController extends PaginationController { @Deprecated @GetMapping(value = "/answercount", produces = MediaType.TEXT_PLAIN_VALUE) public String getTotalAnswerCount( - @RequestParam(value = "sessionkey") final String roomShortId, - @RequestParam(value = "lecturequestionsonly", defaultValue = "false") boolean lectureContentsOnly, - @RequestParam(value = "preparationquestionsonly", defaultValue = "false") boolean preparationContentsOnly) { + @RequestParam(value = "sessionkey") + final String roomShortId, + @RequestParam(value = "lecturequestionsonly", defaultValue = "false") + final boolean lectureContentsOnly, + @RequestParam(value = "preparationquestionsonly", defaultValue = "false") + final boolean preparationContentsOnly) { final String roomId = roomService.getIdByShortId(roomShortId); int count = 0; - /* FIXME: Content variant is ignored for now */ - lectureContentsOnly = preparationContentsOnly = false; if (lectureContentsOnly) { count = answerService.countLectureContentAnswers(roomId); } else if (preparationContentsOnly) { diff --git a/src/main/java/de/thm/arsnova/persistence/AnswerRepository.java b/src/main/java/de/thm/arsnova/persistence/AnswerRepository.java index f7260fe56..eebde69a8 100644 --- a/src/main/java/de/thm/arsnova/persistence/AnswerRepository.java +++ b/src/main/java/de/thm/arsnova/persistence/AnswerRepository.java @@ -18,6 +18,7 @@ package de.thm.arsnova.persistence; +import java.util.Collection; import java.util.List; import de.thm.arsnova.model.Answer; @@ -32,17 +33,15 @@ public interface AnswerRepository extends CrudRepository<Answer, String> { int countByContentId(String contentId); + int countByContentIds(Collection<String> contentIds); + <T extends Answer> List<T> findByContentId(String contentId, Class<T> type, int start, int limit); List<Answer> findByUserIdRoomId(String userId, String roomId); Iterable<Answer> findStubsByContentId(String contentId); - Iterable<Answer> findStubsByContentIds(List<String> contentId); + Iterable<Answer> findStubsByContentIds(Collection<String> contentId); int countByRoomId(String roomId); - - int countByRoomIdOnlyLectureVariant(String roomId); - - int countByRoomIdOnlyPreparationVariant(String roomId); } diff --git a/src/main/java/de/thm/arsnova/persistence/ContentRepository.java b/src/main/java/de/thm/arsnova/persistence/ContentRepository.java index 9b2ca2558..320d031f0 100644 --- a/src/main/java/de/thm/arsnova/persistence/ContentRepository.java +++ b/src/main/java/de/thm/arsnova/persistence/ContentRepository.java @@ -1,6 +1,7 @@ package de.thm.arsnova.persistence; import java.util.List; +import java.util.Set; import de.thm.arsnova.model.Content; @@ -15,37 +16,13 @@ public interface ContentRepository extends CrudRepository<Content, String> { List<String> findIdsByRoomId(String roomId); - Iterable<Content> findStubsByRoomId(final String roomId); + Iterable<Content> findStubsByIds(Set<String> ids); - Iterable<Content> findStubsByRoomIdAndVariant(String roomId, String variant); + Iterable<Content> findStubsByRoomId(final String roomId); List<String> findUnansweredIdsByRoomIdAndUser(String roomId, String userId); - List<Content> findByRoomIdOnlyLectureVariantAndActive(String roomId); - - List<Content> findByRoomIdOnlyLectureVariant(String roomId); - List<Content> findByRoomIdOnlyFlashcardVariantAndActive(String roomId); - List<Content> findByRoomIdOnlyFlashcardVariant(String roomId); - - List<Content> findByRoomIdOnlyPreparationVariantAndActive(String roomId); - - List<Content> findByRoomIdOnlyPreparationVariant(String roomId); - List<Content> findByRoomId(String roomId); - - int countLectureVariantByRoomId(String roomId); - - int countFlashcardVariantRoomId(String roomId); - - int countPreparationVariantByRoomId(String roomId); - - List<String> findIdsByRoomIdAndVariantAndSubject(String roomId, String questionVariant, String subject); - - List<String> findSubjectsByRoomIdAndVariant(String roomId, String questionVariant); - - List<String> findUnansweredIdsByRoomIdAndUserOnlyLectureVariant(String roomId, String userId); - - List<String> findUnansweredIdsByRoomIdAndUserOnlyPreparationVariant(String roomId, String userId); } diff --git a/src/main/java/de/thm/arsnova/persistence/couchdb/CouchDbAnswerRepository.java b/src/main/java/de/thm/arsnova/persistence/couchdb/CouchDbAnswerRepository.java index a6b70c5d3..17773478d 100644 --- a/src/main/java/de/thm/arsnova/persistence/couchdb/CouchDbAnswerRepository.java +++ b/src/main/java/de/thm/arsnova/persistence/couchdb/CouchDbAnswerRepository.java @@ -21,6 +21,7 @@ package de.thm.arsnova.persistence.couchdb; import com.fasterxml.jackson.databind.JsonNode; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -67,7 +68,7 @@ public class CouchDbAnswerRepository extends CouchDbCrudRepository<Answer> } @Override - public Iterable<Answer> findStubsByContentIds(final List<String> contentIds) { + public Iterable<Answer> findStubsByContentIds(final Collection<String> contentIds) { return createEntityStubs(db.queryView(createQuery("by_contentid").keys(contentIds))); } @@ -144,6 +145,16 @@ public class CouchDbAnswerRepository extends CouchDbCrudRepository<Answer> return result.isEmpty() ? 0 : result.getRows().get(0).getValueAsInt(); } + @Override + public int countByContentIds(final Collection<String> contentIds) { + final ViewResult result = db.queryView(createQuery("by_contentid") + .reduce(true) + .group(true) + .keys(contentIds)); + + return result.isEmpty() ? 0 : result.getRows().get(0).getValueAsInt(); + } + @Override public <T extends Answer> List<T> findByContentId( final String contentId, final Class<T> type, final int start, final int limit) { @@ -175,21 +186,4 @@ public class CouchDbAnswerRepository extends CouchDbCrudRepository<Answer> return result.isEmpty() ? 0 : result.getRows().get(0).getValueAsInt(); } - - @Override - public int countByRoomIdOnlyLectureVariant(final String roomId) { - return countBySessionIdVariant(roomId, "lecture"); - } - - @Override - public int countByRoomIdOnlyPreparationVariant(final String roomId) { - return countBySessionIdVariant(roomId, "preparation"); - } - - private int countBySessionIdVariant(final String sessionId, final String variant) { - final ViewResult result = db.queryView(createQuery("by_roomid_variant") - .key(ComplexKey.of(sessionId, variant))); - - return result.isEmpty() ? 0 : result.getRows().get(0).getValueAsInt(); - } } diff --git a/src/main/java/de/thm/arsnova/persistence/couchdb/CouchDbContentRepository.java b/src/main/java/de/thm/arsnova/persistence/couchdb/CouchDbContentRepository.java index b1eabaf7b..0fea9e856 100644 --- a/src/main/java/de/thm/arsnova/persistence/couchdb/CouchDbContentRepository.java +++ b/src/main/java/de/thm/arsnova/persistence/couchdb/CouchDbContentRepository.java @@ -20,8 +20,6 @@ package de.thm.arsnova.persistence.couchdb; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -66,7 +64,7 @@ public class CouchDbContentRepository extends CouchDbCrudRepository<Content> imp @Override public int countByRoomId(final String roomId) { - final ViewResult result = db.queryView(createQuery("by_roomid_group_locked") + final ViewResult result = db.queryView(createQuery("by_roomid_locked") .startKey(ComplexKey.of(roomId)) .endKey(ComplexKey.of(roomId, ComplexKey.emptyObject())) .reduce(true)); @@ -76,25 +74,24 @@ public class CouchDbContentRepository extends CouchDbCrudRepository<Content> imp @Override public List<String> findIdsByRoomId(final String roomId) { - return collectQuestionIds(db.queryView(createQuery("by_roomid_group_locked") + return collectQuestionIds(db.queryView(createQuery("by_roomid_locked") .startKey(ComplexKey.of(roomId)) .endKey(ComplexKey.of(roomId, ComplexKey.emptyObject())) .reduce(false))); } @Override - public Iterable<Content> findStubsByRoomId(final String roomId) { - return createEntityStubs(db.queryView(createQuery("by_roomid_group_locked") - .startKey(ComplexKey.of(roomId)) - .endKey(ComplexKey.of(roomId, ComplexKey.emptyObject())) + public Iterable<Content> findStubsByIds(final Set<String> ids) { + return createEntityStubs(db.queryView(createQuery("by_id") + .keys(ids) .reduce(false))); } @Override - public Iterable<Content> findStubsByRoomIdAndVariant(final String roomId, final String variant) { - return createEntityStubs(db.queryView(createQuery("by_roomid_group_locked") - .startKey(ComplexKey.of(roomId, variant)) - .endKey(ComplexKey.of(roomId, variant, ComplexKey.emptyObject())) + public Iterable<Content> findStubsByRoomId(final String roomId) { + return createEntityStubs(db.queryView(createQuery("by_roomid_locked") + .startKey(ComplexKey.of(roomId)) + .endKey(ComplexKey.of(roomId, ComplexKey.emptyObject())) .reduce(false))); } @@ -104,7 +101,7 @@ public class CouchDbContentRepository extends CouchDbCrudRepository<Content> imp @Override public List<String> findUnansweredIdsByRoomIdAndUser(final String roomId, final String userId) { - final ViewResult result = db.queryView(createQuery("contentid_by_creatorid_roomid_variant") + final ViewResult result = db.queryView(createQuery("contentid_by_creatorid_roomid") .designDocId("_design/Answer") .startKey(ComplexKey.of(userId, roomId)) .endKey(ComplexKey.of(userId, roomId, ComplexKey.emptyObject()))); @@ -112,45 +109,8 @@ public class CouchDbContentRepository extends CouchDbCrudRepository<Content> imp for (final ViewResult.Row row : result.getRows()) { answeredIds.add(row.getId()); } - return collectUnansweredQuestionIds(findIdsByRoomId(roomId), answeredIds); - } - - @Override - public List<String> findUnansweredIdsByRoomIdAndUserOnlyLectureVariant(final String roomId, final String userId) { - final ViewResult result = db.queryView(createQuery("contentid_round_by_creatorid_roomid_variant") - .designDocId("_design/Answer") - .key(ComplexKey.of(userId, roomId, "lecture"))); - final Map<String, Integer> answeredQuestions = new HashMap<>(); - for (final ViewResult.Row row : result.getRows()) { - answeredQuestions.put(row.getId(), row.getKeyAsNode().get(2).asInt()); - } - - return collectUnansweredQuestionIdsByPiRound(findByRoomIdOnlyLectureVariantAndActive(roomId), answeredQuestions); - } - - @Override - public List<String> findUnansweredIdsByRoomIdAndUserOnlyPreparationVariant( - final String roomId, final String userId) { - final ViewResult result = db.queryView(createQuery("contentid_round_by_creatorid_roomid_variant") - .designDocId("_design/Answer") - .key(ComplexKey.of(userId, roomId, "preparation"))); - final Map<String, Integer> answeredQuestions = new HashMap<>(); - for (final ViewResult.Row row : result.getRows()) { - answeredQuestions.put(row.getId(), row.getKeyAsNode().get(2).asInt()); - } - - return collectUnansweredQuestionIdsByPiRound( - findByRoomIdOnlyPreparationVariantAndActive(roomId), answeredQuestions); - } - @Override - public List<Content> findByRoomIdOnlyLectureVariantAndActive(final String roomId) { - return findByRoomIdAndVariantAndActive(roomId, "lecture", true); - } - - @Override - public List<Content> findByRoomIdOnlyLectureVariant(final String roomId) { - return findByRoomIdAndVariantAndActive(roomId, "lecture"); + return collectUnansweredQuestionIds(findIdsByRoomId(roomId), answeredIds); } @Override @@ -158,21 +118,6 @@ public class CouchDbContentRepository extends CouchDbCrudRepository<Content> imp return findByRoomIdAndVariantAndActive(roomId, "flashcard", true); } - @Override - public List<Content> findByRoomIdOnlyFlashcardVariant(final String roomId) { - return findByRoomIdAndVariantAndActive(roomId, "flashcard"); - } - - @Override - public List<Content> findByRoomIdOnlyPreparationVariantAndActive(final String roomId) { - return findByRoomIdAndVariantAndActive(roomId, "preparation", true); - } - - @Override - public List<Content> findByRoomIdOnlyPreparationVariant(final String roomId) { - return findByRoomIdAndVariantAndActive(roomId, "preparation"); - } - @Override public List<Content> findByRoomId(final String roomId) { return findByRoomIdAndVariantAndActive(roomId); @@ -183,7 +128,7 @@ public class CouchDbContentRepository extends CouchDbCrudRepository<Content> imp final Object[] endKeys = Arrays.copyOf(keys, keys.length + 1); endKeys[keys.length] = ComplexKey.emptyObject(); - return db.queryView(createQuery("by_roomid_group_locked") + return db.queryView(createQuery("by_roomid_locked") .includeDocs(true) .reduce(false) .startKey(ComplexKey.of(keys)) @@ -191,36 +136,6 @@ public class CouchDbContentRepository extends CouchDbCrudRepository<Content> imp Content.class); } - @Override - public int countLectureVariantByRoomId(final String roomId) { - /* TODO: reduce code duplication */ - final ViewResult result = db.queryView(createQuery("by_roomid_group_locked") - .startKey(ComplexKey.of(roomId, "lecture")) - .endKey(ComplexKey.of(roomId, "lecture", ComplexKey.emptyObject()))); - - return result.isEmpty() ? 0 : result.getRows().get(0).getValueAsInt(); - } - - @Override - public int countFlashcardVariantRoomId(final String roomId) { - /* TODO: reduce code duplication */ - final ViewResult result = db.queryView(createQuery("by_roomid_group_locked") - .startKey(ComplexKey.of(roomId, "flashcard")) - .endKey(ComplexKey.of(roomId, "flashcard", ComplexKey.emptyObject()))); - - return result.isEmpty() ? 0 : result.getRows().get(0).getValueAsInt(); - } - - @Override - public int countPreparationVariantByRoomId(final String roomId) { - /* TODO: reduce code duplication */ - final ViewResult result = db.queryView(createQuery("by_roomid_group_locked") - .startKey(ComplexKey.of(roomId, "preparation")) - .endKey(ComplexKey.of(roomId, "preparation", ComplexKey.emptyObject()))); - - return result.isEmpty() ? 0 : result.getRows().get(0).getValueAsInt(); - } - private List<String> collectUnansweredQuestionIds( final List<String> contentIds, final List<String> answeredContentIds) { @@ -257,37 +172,4 @@ public class CouchDbContentRepository extends CouchDbCrudRepository<Content> imp } return ids; } - - /* TODO: remove if this method is no longer used */ - @Override - public List<String> findIdsByRoomIdAndVariantAndSubject( - final String roomId, final String questionVariant, final String subject) { - final ViewResult result = db.queryView(createQuery("by_roomid_group_locked") - .startKey(ComplexKey.of(roomId, questionVariant, false, subject)) - .endKey(ComplexKey.of(roomId, questionVariant, false, subject, ComplexKey.emptyObject()))); - - final List<String> qids = new ArrayList<>(); - - for (final ViewResult.Row row : result.getRows()) { - final String s = row.getId(); - qids.add(s); - } - - return qids; - } - - @Override - public List<String> findSubjectsByRoomIdAndVariant(final String roomId, final String questionVariant) { - final ViewResult result = db.queryView(createQuery("by_roomid_group_locked") - .startKey(ComplexKey.of(roomId, questionVariant)) - .endKey(ComplexKey.of(roomId, questionVariant, ComplexKey.emptyObject()))); - - final Set<String> uniqueSubjects = new HashSet<>(); - - for (final ViewResult.Row row : result.getRows()) { - uniqueSubjects.add(row.getKeyAsNode().get(3).asText()); - } - - return new ArrayList<>(uniqueSubjects); - } } diff --git a/src/main/java/de/thm/arsnova/service/AnswerServiceImpl.java b/src/main/java/de/thm/arsnova/service/AnswerServiceImpl.java index c231d311b..db181211c 100644 --- a/src/main/java/de/thm/arsnova/service/AnswerServiceImpl.java +++ b/src/main/java/de/thm/arsnova/service/AnswerServiceImpl.java @@ -23,6 +23,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Queue; +import java.util.Set; import java.util.concurrent.ConcurrentLinkedQueue; import org.ektorp.DbAccessException; import org.slf4j.Logger; @@ -62,6 +63,7 @@ public class AnswerServiceImpl extends DefaultEntityServiceImpl<Answer> implemen private RoomService roomService; private ContentService contentService; + private ContentGroupService contentGroupService; private AnswerRepository answerRepository; private UserService userService; @@ -83,6 +85,11 @@ public class AnswerServiceImpl extends DefaultEntityServiceImpl<Answer> implemen this.contentService = contentService; } + @Autowired + public void setContentGroupService(final ContentGroupService contentGroupService) { + this.contentGroupService = contentGroupService; + } + @Scheduled(fixedDelay = 5000) public void flushAnswerQueue() { if (answerQueue.isEmpty()) { @@ -377,15 +384,6 @@ public class AnswerServiceImpl extends DefaultEntityServiceImpl<Answer> implemen answer.setRoomId(room.getId()); } - /* - * The "internal" suffix means it is called by internal services that have no authentication! - * TODO: Find a better way of doing this... - */ - @Override - public int countLectureQuestionAnswersInternal(final String roomId) { - return answerRepository.countByRoomIdOnlyLectureVariant(roomService.get(roomId).getId()); - } - @Override public Map<String, Object> countAnswersAndAbstentionsInternal(final String contentId) { final Content content = contentService.get(contentId); @@ -414,13 +412,26 @@ public class AnswerServiceImpl extends DefaultEntityServiceImpl<Answer> implemen return this.countPreparationQuestionAnswersInternal(roomId); } + /* + * The "internal" suffix means it is called by internal services that have no authentication! + * TODO: Find a better way of doing this... + */ + @Override + public int countLectureQuestionAnswersInternal(final String roomId) { + final Set<String> contentIds = + contentGroupService.getByRoomIdAndName(roomId, "lecture").getContentIds(); + return answerRepository.countByContentIds(contentIds); + } + /* * The "internal" suffix means it is called by internal services that have no authentication! * TODO: Find a better way of doing this... */ @Override public int countPreparationQuestionAnswersInternal(final String roomId) { - return answerRepository.countByRoomIdOnlyPreparationVariant(roomService.get(roomId).getId()); + final Set<String> contentIds = + contentGroupService.getByRoomIdAndName(roomId, "preparation").getContentIds(); + return answerRepository.countByContentIds(contentIds); } @EventListener diff --git a/src/main/java/de/thm/arsnova/service/ContentGroupService.java b/src/main/java/de/thm/arsnova/service/ContentGroupService.java index a227a984f..74b6e84e8 100644 --- a/src/main/java/de/thm/arsnova/service/ContentGroupService.java +++ b/src/main/java/de/thm/arsnova/service/ContentGroupService.java @@ -22,6 +22,7 @@ import java.util.List; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.StreamSupport; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.event.EventListener; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; @@ -42,12 +43,15 @@ public class ContentGroupService extends DefaultEntityServiceImpl<ContentGroup> public ContentGroupService( final ContentGroupRepository repository, - final ContentService contentService, @Qualifier("defaultJsonMessageConverter") final MappingJackson2HttpMessageConverter jackson2HttpMessageConverter, final Validator validator) { super(ContentGroup.class, repository, jackson2HttpMessageConverter.getObjectMapper(), validator); this.contentGroupRepository = repository; + } + + @Autowired + public void setContentService(final ContentService contentService) { this.contentService = contentService; } diff --git a/src/main/java/de/thm/arsnova/service/ContentServiceImpl.java b/src/main/java/de/thm/arsnova/service/ContentServiceImpl.java index 78208b53d..898cc636c 100644 --- a/src/main/java/de/thm/arsnova/service/ContentServiceImpl.java +++ b/src/main/java/de/thm/arsnova/service/ContentServiceImpl.java @@ -239,43 +239,42 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem } @PreAuthorize("isAuthenticated()") - private void deleteBySessionAndVariant(final Room room, final String variant) { + private void deleteByRoomAndGroupName(final Room room, final String groupName) { final Iterable<Content> contents; - if ("all".equals(variant)) { - contents = contentRepository.findStubsByRoomId(room.getId()); + if ("all".equals(groupName)) { + delete(contentRepository.findStubsByRoomId(room.getId())); } else { - contents = contentRepository.findStubsByRoomIdAndVariant(room.getId(), variant); + final Set<String> ids = contentGroupService.getByRoomIdAndName(room.getId(), groupName).getContentIds(); + delete(contentRepository.findStubsByIds(ids)); } - - delete(contents); } @Override @PreAuthorize("isAuthenticated()") public void deleteAllContents(final String roomId) { final Room room = getRoomWithAuthCheck(roomId); - deleteBySessionAndVariant(room, "all"); + deleteByRoomAndGroupName(room, "all"); } @Override @PreAuthorize("isAuthenticated()") public void deleteLectureContents(final String roomId) { final Room room = getRoomWithAuthCheck(roomId); - deleteBySessionAndVariant(room, "lecture"); + deleteByRoomAndGroupName(room, "lecture"); } @Override @PreAuthorize("isAuthenticated()") public void deletePreparationContents(final String roomId) { final Room room = getRoomWithAuthCheck(roomId); - deleteBySessionAndVariant(room, "preparation"); + deleteByRoomAndGroupName(room, "preparation"); } @Override @PreAuthorize("isAuthenticated()") public void deleteFlashcards(final String roomId) { final Room room = getRoomWithAuthCheck(roomId); - deleteBySessionAndVariant(room, "flashcard"); + deleteByRoomAndGroupName(room, "flashcard"); } @Override @@ -358,7 +357,10 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem @Override public List<String> getUnAnsweredLectureContentIds(final String roomId, final String userId) { - return contentRepository.findUnansweredIdsByRoomIdAndUserOnlyLectureVariant(roomId, userId); + final List<String> ids = contentRepository.findUnansweredIdsByRoomIdAndUser(roomId, userId); + ids.retainAll(contentGroupService.getByRoomIdAndName(roomId, "lecture").getContentIds()); + + return ids; } @Override @@ -370,7 +372,10 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem @Override public List<String> getUnAnsweredPreparationContentIds(final String roomId, final String userId) { - return contentRepository.findUnansweredIdsByRoomIdAndUserOnlyPreparationVariant(roomId, userId); + final List<String> ids = contentRepository.findUnansweredIdsByRoomIdAndUser(roomId, userId); + ids.retainAll(contentGroupService.getByRoomIdAndName(roomId, "preparation").getContentIds()); + + return ids; } @Override @@ -422,10 +427,9 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem @PreAuthorize("isAuthenticated()") public void deleteAllPreparationAnswers(final String roomId) { final Room room = roomService.get(roomId); - - final List<Content> contents = contentRepository.findByRoomIdAndVariantAndActive(room.getId(), "preparation"); - resetContentsRoundState(room.getId(), contents); - final List<String> contentIds = contents.stream().map(Content::getId).collect(Collectors.toList()); + contentGroupService.getByRoomIdAndName(roomId, "preparation").getContentIds(); + final Set<String> contentIds = contentGroupService.getByRoomIdAndName(roomId, "preparation").getContentIds(); + resetContentsRoundState(room.getId(), get(contentIds)); answerService.delete(answerRepository.findStubsByContentIds(contentIds)); } @@ -433,10 +437,9 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem @PreAuthorize("isAuthenticated()") public void deleteAllLectureAnswers(final String roomId) { final Room room = roomService.get(roomId); - - final List<Content> contents = contentRepository.findByRoomIdAndVariantAndActive(room.getId(), "lecture"); - resetContentsRoundState(room.getId(), contents); - final List<String> contentIds = contents.stream().map(Content::getId).collect(Collectors.toList()); + contentGroupService.getByRoomIdAndName(roomId, "lecture").getContentIds(); + final Set<String> contentIds = contentGroupService.getByRoomIdAndName(roomId, "lecture").getContentIds(); + resetContentsRoundState(room.getId(), get(contentIds)); answerService.delete(answerRepository.findStubsByContentIds(contentIds)); } @@ -446,7 +449,7 @@ public class ContentServiceImpl extends DefaultEntityServiceImpl<Content> implem @CacheEvict(value = "lecturecontentlists", key = "#roomId"), @CacheEvict(value = "preparationcontentlists", key = "#roomId"), @CacheEvict(value = "flashcardcontentlists", key = "#roomId") }) - private void resetContentsRoundState(final String roomId, final List<Content> contents) { + private void resetContentsRoundState(final String roomId, final Iterable<Content> contents) { for (final Content q : contents) { /* TODO: Check if setting the sessionId is necessary. */ q.setRoomId(roomId); diff --git a/src/main/resources/couchdb/Answer.design.js b/src/main/resources/couchdb/Answer.design.js index 3e89d47b1..ba5814d6a 100644 --- a/src/main/resources/couchdb/Answer.design.js +++ b/src/main/resources/couchdb/Answer.design.js @@ -15,7 +15,8 @@ var designDoc = { if (doc.type === "Answer") { emit(doc.contentId, {_rev: doc._rev}); } - } + }, + "reduce": "_count" }, "by_contentid_round_body_subject": { "map": function (doc) { @@ -55,34 +56,12 @@ var designDoc = { }, "reduce": "_count" }, - "by_roomid_variant": { - "map": function (doc) { - if (doc.type === "Answer") { - emit([doc.roomId, doc.questionVariant], {_rev: doc._rev}); - } - }, - "reduce": "_count" - }, "by_creatorid_roomid": { "map": function (doc) { if (doc.type === "Answer") { emit([doc.creatorId, doc.roomId], {_rev: doc._rev}); } } - }, - "contentid_by_creatorid_roomid_variant": { - "map": function (doc) { - if (doc.type === "Answer") { - emit([doc.user, doc.roomId, doc.questionVariant], doc.contentId); - } - } - }, - "contentid_round_by_creatorid_roomid_variant": { - "map": function (doc) { - if (doc.type === "Answer") { - emit([doc.creatorId, doc.roomId, doc.questionVariant], [doc.contentId, doc.round]); - } - } } } }; diff --git a/src/main/resources/couchdb/Content.design.js b/src/main/resources/couchdb/Content.design.js index 5b09c23f6..82b773ef6 100644 --- a/src/main/resources/couchdb/Content.design.js +++ b/src/main/resources/couchdb/Content.design.js @@ -18,10 +18,10 @@ var designDoc = { }, "reduce": "_count" }, - "by_roomid_group_locked": { + "by_roomid_locked": { "map": function (doc) { if (doc.type === "Content") { - emit([doc.roomId, doc.group, doc.locked, doc.subject, doc.body.substr(0, 16)], {_rev: doc._rev}); + emit([doc.roomId, doc.locked, doc.subject, doc.body.substr(0, 16)], {_rev: doc._rev}); } }, "reduce": "_count" -- GitLab