Skip to content

Commit ca7f84a

Browse files
committed
Added filtering collections by tag value [#1863]
* Removed the frontend TagType interface, replaced with ComicTagType.
1 parent 4f9b8ee commit ca7f84a

File tree

54 files changed

+459
-414
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+459
-414
lines changed

comixed-app/src/main/resources/application.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ comixed.plugins.location=${user.home}/.comixed/plugins
3333
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
3434
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
3535
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
36-
spring.jpa.show-sql=false
36+
spring.jpa.show-sql=true
3737
spring.jpa.generate-ddl=false
3838
spring.jpa.hibernate.ddl-auto=none
3939

comixed-model/src/main/java/org/comixedproject/model/collections/CollectionEntry.java

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,49 @@
2020

2121
import com.fasterxml.jackson.annotation.JsonProperty;
2222
import com.fasterxml.jackson.annotation.JsonView;
23-
import lombok.AllArgsConstructor;
23+
import jakarta.persistence.*;
24+
import java.util.Objects;
2425
import lombok.Getter;
26+
import lombok.NoArgsConstructor;
27+
import org.comixedproject.model.comicbooks.ComicTagType;
2528
import org.comixedproject.views.View;
2629

2730
/**
2831
* <code>CollectionEntry</code> represents a single entry in a collection list.
2932
*
3033
* @author Darryl L. Pierce
3134
*/
32-
@AllArgsConstructor
35+
@Entity
36+
@Table(name = "collections_view")
3337
@JsonView(View.CollectionEntryList.class)
38+
@NoArgsConstructor
3439
public class CollectionEntry {
35-
@JsonProperty("tagValue")
36-
@Getter
37-
private String tagValue;
40+
@EmbeddedId @Getter private CollectionEntryId id;
3841

42+
@Column(name = "comic_count")
3943
@JsonProperty("comicCount")
4044
@Getter
4145
private long comicCount;
46+
47+
public ComicTagType getTagType() {
48+
return id.getTagType();
49+
}
50+
51+
public String getTagValue() {
52+
return id.getTagValue();
53+
}
54+
55+
@Override
56+
public boolean equals(final Object o) {
57+
if (o == null || getClass() != o.getClass()) return false;
58+
final CollectionEntry that = (CollectionEntry) o;
59+
return getComicCount() == that.getComicCount()
60+
&& getTagType() == that.getTagType()
61+
&& Objects.equals(getTagValue(), that.getTagValue());
62+
}
63+
64+
@Override
65+
public int hashCode() {
66+
return Objects.hash(getTagType(), getTagValue(), getComicCount());
67+
}
4268
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package org.comixedproject.model.collections;
2+
3+
import jakarta.persistence.Column;
4+
import jakarta.persistence.Embeddable;
5+
import jakarta.persistence.EnumType;
6+
import jakarta.persistence.Enumerated;
7+
import java.io.Serializable;
8+
import lombok.Getter;
9+
import lombok.Setter;
10+
import org.comixedproject.model.comicbooks.ComicTagType;
11+
12+
@Embeddable
13+
public class CollectionEntryId implements Serializable {
14+
@Column(name = "tag_type")
15+
@Enumerated(EnumType.STRING)
16+
@Getter
17+
@Setter
18+
private ComicTagType tagType;
19+
20+
@Column(name = "tag_value")
21+
@Getter
22+
@Setter
23+
private String tagValue;
24+
}

comixed-model/src/main/java/org/comixedproject/model/net/collections/LoadCollectionListRequest.java renamed to comixed-model/src/main/java/org/comixedproject/model/net/collections/LoadComicsForCollectionRequest.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,18 @@
2424
import lombok.NoArgsConstructor;
2525

2626
/**
27-
* <code>LoadCollectionListRequest</code> represents the request body when loading collection
27+
* <code>LoadComicsForCollectionRequest</code> represents the request body when loading collection
2828
* entries.
2929
*
3030
* @author Darryl L. Pierce
3131
*/
3232
@NoArgsConstructor
3333
@AllArgsConstructor
34-
public class LoadCollectionListRequest {
34+
public class LoadComicsForCollectionRequest {
35+
@JsonProperty("searchText")
36+
@Getter
37+
String searchText;
38+
3539
@JsonProperty("pageSize")
3640
@Getter
3741
int pageSize;

comixed-model/src/main/java/org/comixedproject/model/net/collections/LoadCollectionListResponse.java renamed to comixed-model/src/main/java/org/comixedproject/model/net/collections/LoadComicsForCollectionResponse.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@
2727
import org.comixedproject.views.View;
2828

2929
/**
30-
* <code>LoadCollectionListResponse</code> represents the response body when loading collection
30+
* <code>LoadComicsForCollectionResponse</code> represents the response body when loading collection
3131
* entries.
3232
*
3333
* @author Darryl L. Pierce
3434
*/
3535
@AllArgsConstructor
3636
@JsonView(View.CollectionEntryList.class)
37-
public class LoadCollectionListResponse {
37+
public class LoadComicsForCollectionResponse {
3838
@JsonProperty("entries")
3939
@Getter
4040
private List<CollectionEntry> entries;

comixed-model/src/main/java/org/comixedproject/model/net/library/LoadComicsForCollectionRequest.java

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import lombok.AllArgsConstructor;
2323
import lombok.Getter;
2424
import lombok.NoArgsConstructor;
25-
import org.comixedproject.model.comicbooks.ComicTagType;
2625

2726
/**
2827
* <code>LoadComicsForCollectionRequest</code> represents a request to load comics for collection.
@@ -40,14 +39,6 @@ public class LoadComicsForCollectionRequest {
4039
@Getter
4140
private int pageIndex;
4241

43-
@JsonProperty("tagType")
44-
@Getter
45-
private ComicTagType tagType;
46-
47-
@JsonProperty("tagValue")
48-
@Getter
49-
private String tagValue;
50-
5142
@JsonProperty("sortBy")
5243
@Getter
5344
private String sortBy;
@@ -63,12 +54,6 @@ public String toString() {
6354
+ pageSize
6455
+ ", pageIndex="
6556
+ pageIndex
66-
+ ", tagType='"
67-
+ tagType
68-
+ '\''
69-
+ ", tagValue='"
70-
+ tagValue
71-
+ '\''
7257
+ ", sortBy='"
7358
+ sortBy
7459
+ '\''
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
5+
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
6+
<changeSet id="015_1863_added_collections_view.xml" author="mcpierce">
7+
8+
<preConditions onFail="MARK_RAN">
9+
<not>
10+
<viewExists viewName="collections_view"/>
11+
</not>
12+
</preConditions>
13+
14+
<createView viewName="collections_view">
15+
SELECT tag_type, tag_value, count(*) as comic_count
16+
FROM comic_tags
17+
GROUP BY tag_type, tag_value;
18+
</createView>
19+
20+
</changeSet>
21+
</databaseChangeLog>

comixed-model/src/main/resources/db/migrations/2.3/changelog-2.3.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@
2020
<include file="/db/migrations/2.3/012_2025_added_duplicate_pages_view.xml"/>
2121
<include file="/db/migrations/2.3/013_2292_added_displayable_comics_view.xml"/>
2222
<include file="/db/migrations/2.3/014_2318_add_comic_details_filtered_index.xml"/>
23+
<include file="/db/migrations/2.3/015_1863_added_collections_view.xml"/>
2324

2425
</databaseChangeLog>

comixed-repositories/src/main/java/org/comixedproject/repositories/comicbooks/ComicDetailRepository.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,12 +309,33 @@ List<ComicDetail> getAllComicsForTagType(
309309
* @param pageable the page request
310310
* @return the values
311311
*/
312-
@Query("SELECT DISTINCT t.value FROM ComicTag t WHERE t.type = :tagType")
313-
List<String> loadCollectionEntries(@Param("tagType") ComicTagType tagType, Pageable pageable);
312+
@Query("SELECT DISTINCT c FROM CollectionEntry c WHERE c.id.tagType = :tagType")
313+
List<CollectionEntry> loadCollectionEntries(
314+
@Param("tagType") ComicTagType tagType, Pageable pageable);
315+
316+
/**
317+
* Returns a display page of {@link CollectionEntry} values using filter text.
318+
*
319+
* @param tagType the tag type
320+
* @param filterText the filter text
321+
* @param pageable the page request
322+
* @return the values
323+
*/
324+
@Query(
325+
"SELECT c FROM CollectionEntry c WHERE c.id.tagType = :tagType AND c.id.tagValue ILIKE :filterText")
326+
List<CollectionEntry> loadCollectionEntriesWithFiltering(
327+
@Param("tagType") ComicTagType tagType,
328+
@Param("filterText") String filterText,
329+
Pageable pageable);
314330

315331
@Query("SELECT COUNT(DISTINCT t.value) FROM ComicTag t WHERE t.type = :tagType")
316332
long getFilterCount(@Param("tagType") ComicTagType tag);
317333

334+
@Query(
335+
"SELECT COUNT(DISTINCT t.value) FROM ComicTag t WHERE t.type = :tagType AND t.value ILIKE :filterText")
336+
long getFilterCountWithFiltering(
337+
@Param("tagType") ComicTagType tag, @Param("filterText") String filterText);
338+
318339
@Query(
319340
"SELECT sum(total) FROM (SELECT count(*) AS total FROM ComicDetail d WHERE d.publisher IS NOT NULL AND LENGTH(d.publisher) > 0 AND d.series IS NOT NULL AND LENGTH(d.series) > 0 AND d.volume IS NOT NULL AND LENGTH(d.volume) > 0 AND d.issueNumber IS NOT NULL AND LENGTH(d.issueNumber) > 0 AND d.coverDate IS NOT NULL GROUP BY d.publisher, d.series, d.volume, d.issueNumber, d.coverDate HAVING count(*) > 1)")
320341
Long getDuplicateComicBookCount();

comixed-rest/src/main/java/org/comixedproject/rest/collections/TagController.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
import io.micrometer.core.annotation.Timed;
2323
import lombok.extern.log4j.Log4j2;
2424
import org.comixedproject.model.comicbooks.ComicTagType;
25-
import org.comixedproject.model.net.collections.LoadCollectionListRequest;
26-
import org.comixedproject.model.net.collections.LoadCollectionListResponse;
25+
import org.comixedproject.model.net.collections.LoadComicsForCollectionRequest;
26+
import org.comixedproject.model.net.collections.LoadComicsForCollectionResponse;
2727
import org.comixedproject.service.comicbooks.ComicDetailService;
2828
import org.comixedproject.views.View;
2929
import org.springframework.beans.factory.annotation.Autowired;
@@ -51,18 +51,18 @@ public class TagController {
5151
@PreAuthorize("hasRole('READER')")
5252
@Timed(value = "comixed.collection.load-list")
5353
@JsonView(View.CollectionEntryList.class)
54-
public LoadCollectionListResponse loadCollectionList(
55-
@RequestBody final LoadCollectionListRequest request,
56-
@PathVariable("tagType") final String tagType) {
57-
final ComicTagType tag = ComicTagType.forValue(tagType);
58-
log.info("Loading collection list entries: type={}", tag);
59-
return new LoadCollectionListResponse(
54+
public LoadComicsForCollectionResponse loadCollectionList(
55+
@RequestBody final LoadComicsForCollectionRequest request,
56+
@PathVariable("tagType") final ComicTagType tagType) {
57+
log.info("Loading collection list entries: type={}", tagType);
58+
return new LoadComicsForCollectionResponse(
6059
this.comicDetailService.loadCollectionEntries(
61-
tag,
60+
tagType,
61+
request.getSearchText(),
6262
request.getPageSize(),
6363
request.getPageIndex(),
6464
request.getSortBy(),
6565
request.getSortDirection()),
66-
this.comicDetailService.loadCollectionTotalEntries(tag));
66+
this.comicDetailService.loadCollectionTotalEntries(tagType, request.getSearchText()));
6767
}
6868
}

0 commit comments

Comments
 (0)