mirror of
https://github.com/gotson/komga.git
synced 2025-12-07 17:13:59 +01:00
restore bidirectional relationship between Serie and Book
This commit is contained in:
parent
6087d312eb
commit
5dc73c268a
7 changed files with 45 additions and 41 deletions
|
|
@ -11,10 +11,12 @@ import javax.persistence.FetchType
|
||||||
import javax.persistence.GeneratedValue
|
import javax.persistence.GeneratedValue
|
||||||
import javax.persistence.Id
|
import javax.persistence.Id
|
||||||
import javax.persistence.JoinColumn
|
import javax.persistence.JoinColumn
|
||||||
|
import javax.persistence.ManyToOne
|
||||||
import javax.persistence.OneToOne
|
import javax.persistence.OneToOne
|
||||||
import javax.persistence.PrimaryKeyJoinColumn
|
import javax.persistence.PrimaryKeyJoinColumn
|
||||||
import javax.persistence.Table
|
import javax.persistence.Table
|
||||||
import javax.validation.constraints.NotBlank
|
import javax.validation.constraints.NotBlank
|
||||||
|
import javax.validation.constraints.NotNull
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "book")
|
@Table(name = "book")
|
||||||
|
|
@ -35,6 +37,11 @@ class Book(
|
||||||
@PrimaryKeyJoinColumn
|
@PrimaryKeyJoinColumn
|
||||||
var id: Long = 0
|
var id: Long = 0
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY, optional = false)
|
||||||
|
@JoinColumn(name = "serie_id", nullable = false)
|
||||||
|
lateinit var serie: Serie
|
||||||
|
|
||||||
@OneToOne(optional = false, orphanRemoval = true, cascade = [CascadeType.ALL], fetch = FetchType.LAZY)
|
@OneToOne(optional = false, orphanRemoval = true, cascade = [CascadeType.ALL], fetch = FetchType.LAZY)
|
||||||
@JoinColumn(name = "book_metadata_id", nullable = false)
|
@JoinColumn(name = "book_metadata_id", nullable = false)
|
||||||
var metadata: BookMetadata = BookMetadata().also { it.book = this }
|
var metadata: BookMetadata = BookMetadata().also { it.book = this }
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,7 @@ class BookMetadata(
|
||||||
@Lob
|
@Lob
|
||||||
var thumbnail: ByteArray? = null,
|
var thumbnail: ByteArray? = null,
|
||||||
|
|
||||||
@ElementCollection(fetch = FetchType.EAGER)
|
pages: Iterable<BookPage> = emptyList()
|
||||||
@CollectionTable(name = "book_metadata_page", joinColumns = [JoinColumn(name = "book_metadata_id")])
|
|
||||||
var pages: MutableList<BookPage> = mutableListOf()
|
|
||||||
) {
|
) {
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue
|
@GeneratedValue
|
||||||
|
|
@ -40,11 +38,23 @@ class BookMetadata(
|
||||||
@OneToOne(optional = false, fetch = FetchType.LAZY, mappedBy = "metadata")
|
@OneToOne(optional = false, fetch = FetchType.LAZY, mappedBy = "metadata")
|
||||||
lateinit var book: Book
|
lateinit var book: Book
|
||||||
|
|
||||||
|
@ElementCollection(fetch = FetchType.EAGER)
|
||||||
|
@CollectionTable(name = "book_metadata_page", joinColumns = [JoinColumn(name = "book_metadata_id")])
|
||||||
|
var pages: MutableList<BookPage> = mutableListOf()
|
||||||
|
set(value) {
|
||||||
|
pages.clear()
|
||||||
|
pages.addAll(value)
|
||||||
|
}
|
||||||
|
|
||||||
fun reset() {
|
fun reset() {
|
||||||
status = Status.UNKNOWN
|
status = Status.UNKNOWN
|
||||||
mediaType = null
|
mediaType = null
|
||||||
thumbnail = null
|
thumbnail = null
|
||||||
pages = mutableListOf()
|
pages.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
this.pages = pages.toMutableList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,6 @@ import javax.persistence.Entity
|
||||||
import javax.persistence.FetchType
|
import javax.persistence.FetchType
|
||||||
import javax.persistence.GeneratedValue
|
import javax.persistence.GeneratedValue
|
||||||
import javax.persistence.Id
|
import javax.persistence.Id
|
||||||
import javax.persistence.JoinColumn
|
|
||||||
import javax.persistence.JoinTable
|
|
||||||
import javax.persistence.OneToMany
|
import javax.persistence.OneToMany
|
||||||
import javax.persistence.Table
|
import javax.persistence.Table
|
||||||
import javax.validation.constraints.NotBlank
|
import javax.validation.constraints.NotBlank
|
||||||
|
|
@ -27,7 +25,7 @@ class Serie(
|
||||||
@Column(name = "file_last_modified", nullable = false)
|
@Column(name = "file_last_modified", nullable = false)
|
||||||
var fileLastModified: LocalDateTime,
|
var fileLastModified: LocalDateTime,
|
||||||
|
|
||||||
books: MutableList<Book>
|
books: Iterable<Book>
|
||||||
|
|
||||||
) : AuditableEntity() {
|
) : AuditableEntity() {
|
||||||
@Id
|
@Id
|
||||||
|
|
@ -35,15 +33,18 @@ class Serie(
|
||||||
@Column(name = "id", nullable = false, unique = true)
|
@Column(name = "id", nullable = false, unique = true)
|
||||||
var id: Long = 0
|
var id: Long = 0
|
||||||
|
|
||||||
@OneToMany(cascade = [CascadeType.ALL], fetch = FetchType.LAZY, orphanRemoval = true)
|
@OneToMany(cascade = [CascadeType.ALL], fetch = FetchType.LAZY, orphanRemoval = true, mappedBy = "serie")
|
||||||
@JoinTable(name = "serie_books_mapping", joinColumns = [JoinColumn(name = "serie_id")], inverseJoinColumns = [JoinColumn(name = "book_id")])
|
private var _books: MutableList<Book> = mutableListOf()
|
||||||
var books: MutableList<Book> = mutableListOf()
|
|
||||||
|
var books: List<Book>
|
||||||
|
get() = _books.toList()
|
||||||
set(value) {
|
set(value) {
|
||||||
books.clear()
|
_books.clear()
|
||||||
books.addAll(value)
|
value.forEach { it.serie = this }
|
||||||
|
_books.addAll(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
this.books = books
|
this.books = books.toMutableList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,16 +2,16 @@ package org.gotson.komga.domain.persistence
|
||||||
|
|
||||||
import org.gotson.komga.domain.model.Book
|
import org.gotson.komga.domain.model.Book
|
||||||
import org.gotson.komga.domain.model.Status
|
import org.gotson.komga.domain.model.Status
|
||||||
|
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.JpaRepository
|
||||||
import org.springframework.stereotype.Repository
|
import org.springframework.stereotype.Repository
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
interface BookRepository : JpaRepository<Book, Long> {
|
interface BookRepository : JpaRepository<Book, Long> {
|
||||||
// fun findAllBySerieId(serieId: Long, pageable: Pageable): Page<Book>
|
fun findAllBySerieId(serieId: Long, pageable: Pageable): Page<Book>
|
||||||
// fun findAllBySerieIdAndUrlNotIn(serieId: Long, urls: Iterable<URL>): List<Book>
|
|
||||||
fun findByUrl(url: URL): Book?
|
fun findByUrl(url: URL): Book?
|
||||||
fun findAllByMetadataStatus(status: Status): List<Book>
|
fun findAllByMetadataStatus(status: Status): List<Book>
|
||||||
// fun findAllByMetadataStatusAndSerieId(status: Status, serieId: Long, pageable: Pageable): Page<Book>
|
fun findAllByMetadataStatusAndSerieId(status: Status, serieId: Long, pageable: Pageable): Page<Book>
|
||||||
// fun deleteAllBySerieId(serieId: Long)
|
|
||||||
}
|
}
|
||||||
|
|
@ -8,7 +8,6 @@ import java.net.URL
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
interface SerieRepository : JpaRepository<Serie, Long>, JpaSpecificationExecutor<Serie> {
|
interface SerieRepository : JpaRepository<Serie, Long>, JpaSpecificationExecutor<Serie> {
|
||||||
// fun deleteAllByUrlNotIn(urls: Iterable<URL>)
|
|
||||||
fun findByUrlNotIn(urls: Iterable<URL>): List<Serie>
|
fun findByUrlNotIn(urls: Iterable<URL>): List<Serie>
|
||||||
fun findByUrl(url: URL): Serie?
|
fun findByUrl(url: URL): Serie?
|
||||||
}
|
}
|
||||||
|
|
@ -53,16 +53,14 @@ class SerieController(
|
||||||
@GetMapping("{id}/books")
|
@GetMapping("{id}/books")
|
||||||
fun getAllBooksBySerie(
|
fun getAllBooksBySerie(
|
||||||
@PathVariable id: Long,
|
@PathVariable id: Long,
|
||||||
@RequestParam(value = "readyonly", defaultValue = "true") readyFilter: Boolean
|
@RequestParam(value = "readyonly", defaultValue = "true") readyFilter: Boolean,
|
||||||
// page: Pageable
|
page: Pageable
|
||||||
): List<BookDto> {
|
): Page<BookDto> {
|
||||||
val serie = serieRepository.findByIdOrNull(id) ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
if (!serieRepository.existsById(id)) throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||||
return if (readyFilter) {
|
return if (readyFilter) {
|
||||||
// bookRepository.findAllByMetadataStatusAndSerieId(Status.READY, id, page)
|
bookRepository.findAllByMetadataStatusAndSerieId(Status.READY, id, page)
|
||||||
serie.books.filter { it.metadata.status == Status.READY }
|
|
||||||
} else {
|
} else {
|
||||||
// bookRepository.findAllBySerieId(id, page)
|
bookRepository.findAllBySerieId(id, page)
|
||||||
serie.books
|
|
||||||
}.map { it.toDto() }
|
}.map { it.toDto() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ create table book
|
||||||
name varchar not null,
|
name varchar not null,
|
||||||
url varchar not null,
|
url varchar not null,
|
||||||
book_metadata_id bigint not null,
|
book_metadata_id bigint not null,
|
||||||
|
serie_id bigint not null,
|
||||||
primary key (id)
|
primary key (id)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -39,26 +40,14 @@ create table serie
|
||||||
primary key (id)
|
primary key (id)
|
||||||
);
|
);
|
||||||
|
|
||||||
create table serie_books_mapping
|
|
||||||
(
|
|
||||||
serie_id bigint not null,
|
|
||||||
book_id bigint not null
|
|
||||||
);
|
|
||||||
|
|
||||||
alter table book
|
alter table book
|
||||||
add constraint uk_book_book_metadata_id unique (book_metadata_id);
|
add constraint uk_book_book_metadata_id unique (book_metadata_id);
|
||||||
|
|
||||||
alter table serie_books_mapping
|
|
||||||
add constraint UK_ya6l4fjcs4rlhwx1fwqwsmm unique (book_id);
|
|
||||||
|
|
||||||
alter table book
|
alter table book
|
||||||
add constraint fk_book_book_metadata_book_metadata_id foreign key (book_metadata_id) references book_metadata (id);
|
add constraint fk_book_book_metadata_book_metadata_id foreign key (book_metadata_id) references book_metadata (id);
|
||||||
|
|
||||||
|
alter table book
|
||||||
|
add constraint fk_book_serie_serie_id foreign key (serie_id) references serie (id);
|
||||||
|
|
||||||
alter table book_metadata_page
|
alter table book_metadata_page
|
||||||
add constraint fk_book_metadata_page_book_metadata_book_metadata_id foreign key (book_metadata_id) references book_metadata (id);
|
add constraint fk_book_metadata_page_book_metadata_book_metadata_id foreign key (book_metadata_id) references book_metadata (id);
|
||||||
|
|
||||||
alter table serie_books_mapping
|
|
||||||
add constraint fk_serie_books_mapping_book_book_id foreign key (book_id) references book (id);
|
|
||||||
|
|
||||||
alter table serie_books_mapping
|
|
||||||
add constraint fk_serie_books_mapping_serie_serie_id foreign key (serie_id) references serie (id);
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue