mirror of
https://github.com/gotson/komga.git
synced 2025-12-20 15:34:17 +01:00
fix: use spring transactions instead of jooq transactions
This commit is contained in:
parent
75ecbe15ba
commit
73931f0bf8
24 changed files with 592 additions and 528 deletions
|
|
@ -16,4 +16,6 @@ interface BookMetadataRepository {
|
|||
|
||||
fun delete(bookId: String)
|
||||
fun delete(bookIds: Collection<String>)
|
||||
|
||||
fun count(): Long
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,4 +15,6 @@ interface MediaRepository {
|
|||
|
||||
fun delete(bookId: String)
|
||||
fun deleteByBookIds(bookIds: Collection<String>)
|
||||
|
||||
fun count(): Long
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import org.gotson.komga.domain.persistence.BookRepository
|
|||
import org.gotson.komga.domain.persistence.LibraryRepository
|
||||
import org.gotson.komga.domain.persistence.MediaRepository
|
||||
import org.springframework.stereotype.Service
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import java.io.FileNotFoundException
|
||||
import java.nio.file.FileAlreadyExistsException
|
||||
import java.util.zip.Deflater
|
||||
|
|
@ -54,6 +55,7 @@ class BookConverter(
|
|||
fun getConvertibleBookIds(library: Library): Collection<String> =
|
||||
bookRepository.findAllIdsByLibraryIdAndMediaTypes(library.id, convertibleTypes)
|
||||
|
||||
@Transactional
|
||||
fun convertToCbz(book: Book) {
|
||||
if (!libraryRepository.findById(book.libraryId).convertToCbz)
|
||||
return logger.info { "Book conversion is disabled for the library, it may have changed since the task was submitted, skipping" }
|
||||
|
|
@ -134,6 +136,7 @@ class BookConverter(
|
|||
bookRepository.findAllIdsByLibraryIdAndMismatchedExtension(library.id, mediaType, extension)
|
||||
}
|
||||
|
||||
@Transactional
|
||||
fun repairExtension(book: Book) {
|
||||
if (!libraryRepository.findById(book.libraryId).repairExtensions)
|
||||
return logger.info { "Repair extensions is disabled for the library, it may have changed since the task was submitted, skipping" }
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import org.gotson.komga.domain.persistence.ThumbnailBookRepository
|
|||
import org.gotson.komga.infrastructure.image.ImageConverter
|
||||
import org.gotson.komga.infrastructure.image.ImageType
|
||||
import org.springframework.stereotype.Service
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Paths
|
||||
|
|
@ -40,6 +41,7 @@ class BookLifecycle(
|
|||
private val eventPublisher: EventPublisher,
|
||||
) {
|
||||
|
||||
@Transactional
|
||||
fun analyzeAndPersist(book: Book): Boolean {
|
||||
logger.info { "Analyze and persist book: $book" }
|
||||
val media = bookAnalyzer.analyze(book)
|
||||
|
|
@ -58,6 +60,7 @@ class BookLifecycle(
|
|||
return media.status == Media.Status.READY
|
||||
}
|
||||
|
||||
@Transactional
|
||||
fun generateThumbnailAndPersist(book: Book) {
|
||||
logger.info { "Generate thumbnail and persist for book: $book" }
|
||||
try {
|
||||
|
|
@ -67,6 +70,7 @@ class BookLifecycle(
|
|||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
fun addThumbnailForBook(thumbnail: ThumbnailBook) {
|
||||
when (thumbnail.type) {
|
||||
ThumbnailBook.Type.GENERATED -> {
|
||||
|
|
@ -93,6 +97,7 @@ class BookLifecycle(
|
|||
thumbnailsHouseKeeping(thumbnail.bookId)
|
||||
}
|
||||
|
||||
@Transactional
|
||||
fun getThumbnail(bookId: String): ThumbnailBook? {
|
||||
val selected = thumbnailBookRepository.findSelectedByBookIdOrNull(bookId)
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import org.springframework.security.core.userdetails.UserDetailsService
|
|||
import org.springframework.security.core.userdetails.UsernameNotFoundException
|
||||
import org.springframework.security.crypto.password.PasswordEncoder
|
||||
import org.springframework.stereotype.Service
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
|
||||
private val logger = KotlinLogging.logger {}
|
||||
|
||||
|
|
@ -54,6 +55,7 @@ class KomgaUserLifecycle(
|
|||
return createdUser
|
||||
}
|
||||
|
||||
@Transactional
|
||||
fun deleteUser(user: KomgaUser) {
|
||||
logger.info { "Deleting user: $user" }
|
||||
readProgressRepository.deleteByUserId(user.id)
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import org.gotson.komga.domain.persistence.SidecarRepository
|
|||
import org.gotson.komga.infrastructure.configuration.KomgaProperties
|
||||
import org.gotson.komga.infrastructure.language.notEquals
|
||||
import org.springframework.stereotype.Service
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import java.nio.file.Paths
|
||||
import kotlin.time.measureTime
|
||||
|
||||
|
|
@ -34,6 +35,7 @@ class LibraryContentLifecycle(
|
|||
private val taskReceiver: TaskReceiver,
|
||||
) {
|
||||
|
||||
@Transactional
|
||||
fun scanRootFolder(library: Library) {
|
||||
logger.info { "Updating library: $library" }
|
||||
measureTime {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import org.gotson.komga.domain.persistence.LibraryRepository
|
|||
import org.gotson.komga.domain.persistence.SeriesRepository
|
||||
import org.gotson.komga.domain.persistence.SidecarRepository
|
||||
import org.springframework.stereotype.Service
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import java.io.FileNotFoundException
|
||||
import java.nio.file.Files
|
||||
|
||||
|
|
@ -77,6 +78,7 @@ class LibraryLifecycle(
|
|||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
fun deleteLibrary(library: Library) {
|
||||
logger.info { "Deleting library: $library" }
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import org.gotson.komga.infrastructure.metadata.barcode.IsbnBarcodeProvider
|
|||
import org.gotson.komga.infrastructure.metadata.comicrack.ComicInfoProvider
|
||||
import org.gotson.komga.infrastructure.metadata.epub.EpubMetadataProvider
|
||||
import org.springframework.stereotype.Service
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
|
||||
private val logger = KotlinLogging.logger {}
|
||||
|
||||
|
|
@ -47,6 +48,7 @@ class MetadataLifecycle(
|
|||
private val eventPublisher: EventPublisher,
|
||||
) {
|
||||
|
||||
@Transactional
|
||||
fun refreshMetadata(book: Book, capabilities: List<BookMetadataPatchCapability>) {
|
||||
logger.info { "Refresh metadata for book: $book with capabilities: $capabilities" }
|
||||
val media = mediaRepository.findById(book.id)
|
||||
|
|
@ -141,6 +143,7 @@ class MetadataLifecycle(
|
|||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
fun refreshMetadata(series: Series) {
|
||||
logger.info { "Refresh metadata for series: $series" }
|
||||
|
||||
|
|
@ -230,6 +233,7 @@ class MetadataLifecycle(
|
|||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
fun aggregateMetadata(series: Series) {
|
||||
logger.info { "Aggregate book metadata for series: $series" }
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import org.gotson.komga.domain.persistence.SeriesMetadataRepository
|
|||
import org.gotson.komga.domain.persistence.SeriesRepository
|
||||
import org.gotson.komga.domain.persistence.ThumbnailSeriesRepository
|
||||
import org.springframework.stereotype.Service
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Paths
|
||||
|
|
@ -89,6 +90,7 @@ class SeriesLifecycle(
|
|||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
fun addBooks(series: Series, booksToAdd: Collection<Book>) {
|
||||
booksToAdd.forEach {
|
||||
check(it.libraryId == series.libraryId) { "Cannot add book to series if they don't share the same libraryId" }
|
||||
|
|
@ -113,6 +115,7 @@ class SeriesLifecycle(
|
|||
toAdd.forEach { eventPublisher.publishEvent(DomainEvent.BookAdded(it)) }
|
||||
}
|
||||
|
||||
@Transactional
|
||||
fun createSeries(series: Series): Series {
|
||||
seriesRepository.insert(series)
|
||||
|
||||
|
|
@ -133,6 +136,7 @@ class SeriesLifecycle(
|
|||
return seriesRepository.findByIdOrNull(series.id)!!
|
||||
}
|
||||
|
||||
@Transactional
|
||||
fun deleteMany(series: Collection<Series>) {
|
||||
val seriesIds = series.map { it.id }
|
||||
logger.info { "Delete series ids: $seriesIds" }
|
||||
|
|
@ -167,6 +171,7 @@ class SeriesLifecycle(
|
|||
progresses.forEach { eventPublisher.publishEvent(DomainEvent.ReadProgressDeleted(it)) }
|
||||
}
|
||||
|
||||
@Transactional
|
||||
fun getThumbnail(seriesId: String): ThumbnailSeries? {
|
||||
val selected = thumbnailsSeriesRepository.findSelectedBySeriesIdOrNull(seriesId)
|
||||
|
||||
|
|
@ -189,6 +194,7 @@ class SeriesLifecycle(
|
|||
return null
|
||||
}
|
||||
|
||||
@Transactional
|
||||
fun addThumbnailForSeries(thumbnail: ThumbnailSeries) {
|
||||
// delete existing thumbnail with the same url
|
||||
thumbnailsSeriesRepository.findAllBySeriesId(thumbnail.seriesId)
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import org.springframework.data.domain.PageRequest
|
|||
import org.springframework.data.domain.Pageable
|
||||
import org.springframework.data.domain.Sort
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import java.net.URL
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneId
|
||||
|
|
@ -176,54 +177,54 @@ class BookDao(
|
|||
.and(b.URL.notLike("%.$extension"))
|
||||
.fetch(b.ID)
|
||||
|
||||
@Transactional
|
||||
override fun insert(book: Book) {
|
||||
insert(listOf(book))
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun insert(books: Collection<Book>) {
|
||||
if (books.isNotEmpty()) {
|
||||
dsl.transaction { config ->
|
||||
config.dsl().batch(
|
||||
config.dsl().insertInto(
|
||||
b,
|
||||
b.ID,
|
||||
b.NAME,
|
||||
b.URL,
|
||||
b.NUMBER,
|
||||
b.FILE_LAST_MODIFIED,
|
||||
b.FILE_SIZE,
|
||||
b.LIBRARY_ID,
|
||||
b.SERIES_ID
|
||||
).values(null as String?, null, null, null, null, null, null, null)
|
||||
).also { step ->
|
||||
books.forEach {
|
||||
step.bind(
|
||||
it.id,
|
||||
it.name,
|
||||
it.url,
|
||||
it.number,
|
||||
it.fileLastModified,
|
||||
it.fileSize,
|
||||
it.libraryId,
|
||||
it.seriesId
|
||||
)
|
||||
}
|
||||
}.execute()
|
||||
}
|
||||
dsl.batch(
|
||||
dsl.insertInto(
|
||||
b,
|
||||
b.ID,
|
||||
b.NAME,
|
||||
b.URL,
|
||||
b.NUMBER,
|
||||
b.FILE_LAST_MODIFIED,
|
||||
b.FILE_SIZE,
|
||||
b.LIBRARY_ID,
|
||||
b.SERIES_ID
|
||||
).values(null as String?, null, null, null, null, null, null, null)
|
||||
).also { step ->
|
||||
books.forEach {
|
||||
step.bind(
|
||||
it.id,
|
||||
it.name,
|
||||
it.url,
|
||||
it.number,
|
||||
it.fileLastModified,
|
||||
it.fileSize,
|
||||
it.libraryId,
|
||||
it.seriesId
|
||||
)
|
||||
}
|
||||
}.execute()
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun update(book: Book) {
|
||||
update(dsl, book)
|
||||
updateBook(book)
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun update(books: Collection<Book>) {
|
||||
dsl.transaction { config ->
|
||||
books.map { update(config.dsl(), it) }
|
||||
}
|
||||
books.map { updateBook(it) }
|
||||
}
|
||||
|
||||
private fun update(dsl: DSLContext, book: Book) {
|
||||
private fun updateBook(book: Book) {
|
||||
dsl.update(b)
|
||||
.set(b.NAME, book.name)
|
||||
.set(b.URL, book.url.toString())
|
||||
|
|
@ -237,28 +238,19 @@ class BookDao(
|
|||
.execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun delete(bookId: String) {
|
||||
dsl.transaction { config ->
|
||||
with(config.dsl()) {
|
||||
deleteFrom(b).where(b.ID.eq(bookId)).execute()
|
||||
}
|
||||
}
|
||||
dsl.deleteFrom(b).where(b.ID.eq(bookId)).execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun delete(bookIds: Collection<String>) {
|
||||
dsl.transaction { config ->
|
||||
with(config.dsl()) {
|
||||
deleteFrom(b).where(b.ID.`in`(bookIds)).execute()
|
||||
}
|
||||
}
|
||||
dsl.deleteFrom(b).where(b.ID.`in`(bookIds)).execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun deleteAll() {
|
||||
dsl.transaction { config ->
|
||||
with(config.dsl()) {
|
||||
deleteFrom(b).execute()
|
||||
}
|
||||
}
|
||||
dsl.deleteFrom(b).execute()
|
||||
}
|
||||
|
||||
override fun count(): Long = dsl.fetchCount(b).toLong()
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import org.gotson.komga.jooq.tables.records.BookMetadataAggregationAuthorRecord
|
|||
import org.gotson.komga.jooq.tables.records.BookMetadataAggregationRecord
|
||||
import org.jooq.DSLContext
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneId
|
||||
|
||||
|
|
@ -39,38 +40,36 @@ class BookMetadataAggregationDao(
|
|||
dr.toDomain(ar.filterNot { it.name == null }.map { it.toDomain() })
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun insert(metadata: BookMetadataAggregation) {
|
||||
dsl.transaction { config ->
|
||||
config.dsl().insertInto(d)
|
||||
.set(d.SERIES_ID, metadata.seriesId)
|
||||
.set(d.RELEASE_DATE, metadata.releaseDate)
|
||||
.set(d.SUMMARY, metadata.summary)
|
||||
.set(d.SUMMARY_NUMBER, metadata.summaryNumber)
|
||||
.execute()
|
||||
dsl.insertInto(d)
|
||||
.set(d.SERIES_ID, metadata.seriesId)
|
||||
.set(d.RELEASE_DATE, metadata.releaseDate)
|
||||
.set(d.SUMMARY, metadata.summary)
|
||||
.set(d.SUMMARY_NUMBER, metadata.summaryNumber)
|
||||
.execute()
|
||||
|
||||
insertAuthors(config.dsl(), metadata)
|
||||
}
|
||||
insertAuthors(metadata)
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun update(metadata: BookMetadataAggregation) {
|
||||
dsl.transaction { config ->
|
||||
config.dsl().update(d)
|
||||
.set(d.SUMMARY, metadata.summary)
|
||||
.set(d.SUMMARY_NUMBER, metadata.summaryNumber)
|
||||
.set(d.RELEASE_DATE, metadata.releaseDate)
|
||||
.set(d.LAST_MODIFIED_DATE, LocalDateTime.now(ZoneId.of("Z")))
|
||||
.where(d.SERIES_ID.eq(metadata.seriesId))
|
||||
.execute()
|
||||
dsl.update(d)
|
||||
.set(d.SUMMARY, metadata.summary)
|
||||
.set(d.SUMMARY_NUMBER, metadata.summaryNumber)
|
||||
.set(d.RELEASE_DATE, metadata.releaseDate)
|
||||
.set(d.LAST_MODIFIED_DATE, LocalDateTime.now(ZoneId.of("Z")))
|
||||
.where(d.SERIES_ID.eq(metadata.seriesId))
|
||||
.execute()
|
||||
|
||||
config.dsl().deleteFrom(a)
|
||||
.where(a.SERIES_ID.eq(metadata.seriesId))
|
||||
.execute()
|
||||
dsl.deleteFrom(a)
|
||||
.where(a.SERIES_ID.eq(metadata.seriesId))
|
||||
.execute()
|
||||
|
||||
insertAuthors(config.dsl(), metadata)
|
||||
}
|
||||
insertAuthors(metadata)
|
||||
}
|
||||
|
||||
private fun insertAuthors(dsl: DSLContext, metadata: BookMetadataAggregation) {
|
||||
private fun insertAuthors(metadata: BookMetadataAggregation) {
|
||||
if (metadata.authors.isNotEmpty()) {
|
||||
dsl.batch(
|
||||
dsl.insertInto(a, a.SERIES_ID, a.NAME, a.ROLE)
|
||||
|
|
@ -83,22 +82,16 @@ class BookMetadataAggregationDao(
|
|||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun delete(seriesId: String) {
|
||||
dsl.transaction { config ->
|
||||
with(config.dsl()) {
|
||||
deleteFrom(a).where(a.SERIES_ID.eq(seriesId)).execute()
|
||||
deleteFrom(d).where(d.SERIES_ID.eq(seriesId)).execute()
|
||||
}
|
||||
}
|
||||
dsl.deleteFrom(a).where(a.SERIES_ID.eq(seriesId)).execute()
|
||||
dsl.deleteFrom(d).where(d.SERIES_ID.eq(seriesId)).execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun delete(seriesIds: Collection<String>) {
|
||||
dsl.transaction { config ->
|
||||
with(config.dsl()) {
|
||||
deleteFrom(a).where(a.SERIES_ID.`in`(seriesIds)).execute()
|
||||
deleteFrom(d).where(d.SERIES_ID.`in`(seriesIds)).execute()
|
||||
}
|
||||
}
|
||||
dsl.deleteFrom(a).where(a.SERIES_ID.`in`(seriesIds)).execute()
|
||||
dsl.deleteFrom(d).where(d.SERIES_ID.`in`(seriesIds)).execute()
|
||||
}
|
||||
|
||||
override fun count(): Long = dsl.fetchCount(d).toLong()
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import org.gotson.komga.jooq.tables.records.BookMetadataAuthorRecord
|
|||
import org.gotson.komga.jooq.tables.records.BookMetadataRecord
|
||||
import org.jooq.DSLContext
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneId
|
||||
|
||||
|
|
@ -51,108 +52,102 @@ class BookMetadataDao(
|
|||
.mapNotNull { it.tag }
|
||||
.toSet()
|
||||
|
||||
@Transactional
|
||||
override fun insert(metadata: BookMetadata) {
|
||||
insert(listOf(metadata))
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun insert(metadatas: Collection<BookMetadata>) {
|
||||
if (metadatas.isNotEmpty()) {
|
||||
dsl.transaction { config ->
|
||||
config.dsl().batch(
|
||||
config.dsl().insertInto(
|
||||
d,
|
||||
d.BOOK_ID,
|
||||
d.TITLE,
|
||||
d.TITLE_LOCK,
|
||||
d.SUMMARY,
|
||||
d.SUMMARY_LOCK,
|
||||
d.NUMBER,
|
||||
d.NUMBER_LOCK,
|
||||
d.NUMBER_SORT,
|
||||
d.NUMBER_SORT_LOCK,
|
||||
d.RELEASE_DATE,
|
||||
d.RELEASE_DATE_LOCK,
|
||||
d.AUTHORS_LOCK,
|
||||
d.TAGS_LOCK,
|
||||
d.ISBN,
|
||||
d.ISBN_LOCK
|
||||
).values(null as String?, null, null, null, null, null, null, null, null, null, null, null, null, null, null)
|
||||
).also { step ->
|
||||
metadatas.forEach {
|
||||
step.bind(
|
||||
it.bookId,
|
||||
it.title,
|
||||
it.titleLock,
|
||||
it.summary,
|
||||
it.summaryLock,
|
||||
it.number,
|
||||
it.numberLock,
|
||||
it.numberSort,
|
||||
it.numberSortLock,
|
||||
it.releaseDate,
|
||||
it.releaseDateLock,
|
||||
it.authorsLock,
|
||||
it.tagsLock,
|
||||
it.isbn,
|
||||
it.isbnLock
|
||||
)
|
||||
}
|
||||
}.execute()
|
||||
dsl.batch(
|
||||
dsl.insertInto(
|
||||
d,
|
||||
d.BOOK_ID,
|
||||
d.TITLE,
|
||||
d.TITLE_LOCK,
|
||||
d.SUMMARY,
|
||||
d.SUMMARY_LOCK,
|
||||
d.NUMBER,
|
||||
d.NUMBER_LOCK,
|
||||
d.NUMBER_SORT,
|
||||
d.NUMBER_SORT_LOCK,
|
||||
d.RELEASE_DATE,
|
||||
d.RELEASE_DATE_LOCK,
|
||||
d.AUTHORS_LOCK,
|
||||
d.TAGS_LOCK,
|
||||
d.ISBN,
|
||||
d.ISBN_LOCK
|
||||
).values(null as String?, null, null, null, null, null, null, null, null, null, null, null, null, null, null)
|
||||
).also { step ->
|
||||
metadatas.forEach {
|
||||
step.bind(
|
||||
it.bookId,
|
||||
it.title,
|
||||
it.titleLock,
|
||||
it.summary,
|
||||
it.summaryLock,
|
||||
it.number,
|
||||
it.numberLock,
|
||||
it.numberSort,
|
||||
it.numberSortLock,
|
||||
it.releaseDate,
|
||||
it.releaseDateLock,
|
||||
it.authorsLock,
|
||||
it.tagsLock,
|
||||
it.isbn,
|
||||
it.isbnLock
|
||||
)
|
||||
}
|
||||
}.execute()
|
||||
|
||||
insertAuthors(config.dsl(), metadatas)
|
||||
insertTags(config.dsl(), metadatas)
|
||||
}
|
||||
insertAuthors(metadatas)
|
||||
insertTags(metadatas)
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun update(metadata: BookMetadata) {
|
||||
dsl.transaction { config ->
|
||||
updateMetadata(config.dsl(), metadata)
|
||||
}
|
||||
updateMetadata(metadata)
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun update(metadatas: Collection<BookMetadata>) {
|
||||
dsl.transaction { config ->
|
||||
metadatas.forEach { updateMetadata(config.dsl(), it) }
|
||||
}
|
||||
metadatas.forEach { updateMetadata(it) }
|
||||
}
|
||||
|
||||
private fun updateMetadata(dsl: DSLContext, metadata: BookMetadata) {
|
||||
dsl.transaction { config ->
|
||||
with(config.dsl()) {
|
||||
update(d)
|
||||
.set(d.TITLE, metadata.title)
|
||||
.set(d.TITLE_LOCK, metadata.titleLock)
|
||||
.set(d.SUMMARY, metadata.summary)
|
||||
.set(d.SUMMARY_LOCK, metadata.summaryLock)
|
||||
.set(d.NUMBER, metadata.number)
|
||||
.set(d.NUMBER_LOCK, metadata.numberLock)
|
||||
.set(d.NUMBER_SORT, metadata.numberSort)
|
||||
.set(d.NUMBER_SORT_LOCK, metadata.numberSortLock)
|
||||
.set(d.RELEASE_DATE, metadata.releaseDate)
|
||||
.set(d.RELEASE_DATE_LOCK, metadata.releaseDateLock)
|
||||
.set(d.AUTHORS_LOCK, metadata.authorsLock)
|
||||
.set(d.TAGS_LOCK, metadata.tagsLock)
|
||||
.set(d.ISBN, metadata.isbn)
|
||||
.set(d.ISBN_LOCK, metadata.isbnLock)
|
||||
.set(d.LAST_MODIFIED_DATE, LocalDateTime.now(ZoneId.of("Z")))
|
||||
.where(d.BOOK_ID.eq(metadata.bookId))
|
||||
.execute()
|
||||
private fun updateMetadata(metadata: BookMetadata) {
|
||||
dsl.update(d)
|
||||
.set(d.TITLE, metadata.title)
|
||||
.set(d.TITLE_LOCK, metadata.titleLock)
|
||||
.set(d.SUMMARY, metadata.summary)
|
||||
.set(d.SUMMARY_LOCK, metadata.summaryLock)
|
||||
.set(d.NUMBER, metadata.number)
|
||||
.set(d.NUMBER_LOCK, metadata.numberLock)
|
||||
.set(d.NUMBER_SORT, metadata.numberSort)
|
||||
.set(d.NUMBER_SORT_LOCK, metadata.numberSortLock)
|
||||
.set(d.RELEASE_DATE, metadata.releaseDate)
|
||||
.set(d.RELEASE_DATE_LOCK, metadata.releaseDateLock)
|
||||
.set(d.AUTHORS_LOCK, metadata.authorsLock)
|
||||
.set(d.TAGS_LOCK, metadata.tagsLock)
|
||||
.set(d.ISBN, metadata.isbn)
|
||||
.set(d.ISBN_LOCK, metadata.isbnLock)
|
||||
.set(d.LAST_MODIFIED_DATE, LocalDateTime.now(ZoneId.of("Z")))
|
||||
.where(d.BOOK_ID.eq(metadata.bookId))
|
||||
.execute()
|
||||
|
||||
deleteFrom(a)
|
||||
.where(a.BOOK_ID.eq(metadata.bookId))
|
||||
.execute()
|
||||
deleteFrom(bt)
|
||||
.where(bt.BOOK_ID.eq(metadata.bookId))
|
||||
.execute()
|
||||
dsl.deleteFrom(a)
|
||||
.where(a.BOOK_ID.eq(metadata.bookId))
|
||||
.execute()
|
||||
dsl.deleteFrom(bt)
|
||||
.where(bt.BOOK_ID.eq(metadata.bookId))
|
||||
.execute()
|
||||
|
||||
insertAuthors(this, listOf(metadata))
|
||||
insertTags(config.dsl(), listOf(metadata))
|
||||
}
|
||||
}
|
||||
insertAuthors(listOf(metadata))
|
||||
insertTags(listOf(metadata))
|
||||
}
|
||||
|
||||
private fun insertAuthors(dsl: DSLContext, metadatas: Collection<BookMetadata>) {
|
||||
private fun insertAuthors(metadatas: Collection<BookMetadata>) {
|
||||
if (metadatas.any { it.authors.isNotEmpty() }) {
|
||||
dsl.batch(
|
||||
dsl.insertInto(a, a.BOOK_ID, a.NAME, a.ROLE)
|
||||
|
|
@ -167,7 +162,7 @@ class BookMetadataDao(
|
|||
}
|
||||
}
|
||||
|
||||
private fun insertTags(dsl: DSLContext, metadatas: Collection<BookMetadata>) {
|
||||
private fun insertTags(metadatas: Collection<BookMetadata>) {
|
||||
if (metadatas.any { it.tags.isNotEmpty() }) {
|
||||
dsl.batch(
|
||||
dsl.insertInto(bt, bt.BOOK_ID, bt.TAG)
|
||||
|
|
@ -182,26 +177,22 @@ class BookMetadataDao(
|
|||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun delete(bookId: String) {
|
||||
dsl.transaction { config ->
|
||||
with(config.dsl()) {
|
||||
deleteFrom(a).where(a.BOOK_ID.eq(bookId)).execute()
|
||||
deleteFrom(bt).where(bt.BOOK_ID.eq(bookId)).execute()
|
||||
deleteFrom(d).where(d.BOOK_ID.eq(bookId)).execute()
|
||||
}
|
||||
}
|
||||
dsl.deleteFrom(a).where(a.BOOK_ID.eq(bookId)).execute()
|
||||
dsl.deleteFrom(bt).where(bt.BOOK_ID.eq(bookId)).execute()
|
||||
dsl.deleteFrom(d).where(d.BOOK_ID.eq(bookId)).execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun delete(bookIds: Collection<String>) {
|
||||
dsl.transaction { config ->
|
||||
with(config.dsl()) {
|
||||
deleteFrom(a).where(a.BOOK_ID.`in`(bookIds)).execute()
|
||||
deleteFrom(bt).where(bt.BOOK_ID.`in`(bookIds)).execute()
|
||||
deleteFrom(d).where(d.BOOK_ID.`in`(bookIds)).execute()
|
||||
}
|
||||
}
|
||||
dsl.deleteFrom(a).where(a.BOOK_ID.`in`(bookIds)).execute()
|
||||
dsl.deleteFrom(bt).where(bt.BOOK_ID.`in`(bookIds)).execute()
|
||||
dsl.deleteFrom(d).where(d.BOOK_ID.`in`(bookIds)).execute()
|
||||
}
|
||||
|
||||
override fun count(): Long = dsl.fetchCount(d).toLong()
|
||||
|
||||
private fun BookMetadataRecord.toDomain(authors: List<Author>, tags: Set<String>) =
|
||||
BookMetadata(
|
||||
title = title,
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import org.jooq.DSLContext
|
|||
import org.jooq.Record
|
||||
import org.jooq.ResultQuery
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneId
|
||||
|
||||
|
|
@ -54,73 +55,61 @@ class KomgaUserDao(
|
|||
)
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun insert(user: KomgaUser) {
|
||||
dsl.transaction { config ->
|
||||
with(config.dsl()) {
|
||||
insertInto(u)
|
||||
.set(u.ID, user.id)
|
||||
.set(u.EMAIL, user.email)
|
||||
.set(u.PASSWORD, user.password)
|
||||
.set(u.ROLE_ADMIN, user.roleAdmin)
|
||||
.set(u.ROLE_FILE_DOWNLOAD, user.roleFileDownload)
|
||||
.set(u.ROLE_PAGE_STREAMING, user.rolePageStreaming)
|
||||
.set(u.SHARED_ALL_LIBRARIES, user.sharedAllLibraries)
|
||||
.execute()
|
||||
dsl.insertInto(u)
|
||||
.set(u.ID, user.id)
|
||||
.set(u.EMAIL, user.email)
|
||||
.set(u.PASSWORD, user.password)
|
||||
.set(u.ROLE_ADMIN, user.roleAdmin)
|
||||
.set(u.ROLE_FILE_DOWNLOAD, user.roleFileDownload)
|
||||
.set(u.ROLE_PAGE_STREAMING, user.rolePageStreaming)
|
||||
.set(u.SHARED_ALL_LIBRARIES, user.sharedAllLibraries)
|
||||
.execute()
|
||||
|
||||
user.sharedLibrariesIds.forEach {
|
||||
insertInto(ul)
|
||||
.columns(ul.USER_ID, ul.LIBRARY_ID)
|
||||
.values(user.id, it)
|
||||
.execute()
|
||||
}
|
||||
}
|
||||
user.sharedLibrariesIds.forEach {
|
||||
dsl.insertInto(ul)
|
||||
.columns(ul.USER_ID, ul.LIBRARY_ID)
|
||||
.values(user.id, it)
|
||||
.execute()
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun update(user: KomgaUser) {
|
||||
dsl.transaction { config ->
|
||||
with(config.dsl()) {
|
||||
update(u)
|
||||
.set(u.EMAIL, user.email)
|
||||
.set(u.PASSWORD, user.password)
|
||||
.set(u.ROLE_ADMIN, user.roleAdmin)
|
||||
.set(u.ROLE_FILE_DOWNLOAD, user.roleFileDownload)
|
||||
.set(u.ROLE_PAGE_STREAMING, user.rolePageStreaming)
|
||||
.set(u.SHARED_ALL_LIBRARIES, user.sharedAllLibraries)
|
||||
.set(u.LAST_MODIFIED_DATE, LocalDateTime.now(ZoneId.of("Z")))
|
||||
.where(u.ID.eq(user.id))
|
||||
.execute()
|
||||
dsl.update(u)
|
||||
.set(u.EMAIL, user.email)
|
||||
.set(u.PASSWORD, user.password)
|
||||
.set(u.ROLE_ADMIN, user.roleAdmin)
|
||||
.set(u.ROLE_FILE_DOWNLOAD, user.roleFileDownload)
|
||||
.set(u.ROLE_PAGE_STREAMING, user.rolePageStreaming)
|
||||
.set(u.SHARED_ALL_LIBRARIES, user.sharedAllLibraries)
|
||||
.set(u.LAST_MODIFIED_DATE, LocalDateTime.now(ZoneId.of("Z")))
|
||||
.where(u.ID.eq(user.id))
|
||||
.execute()
|
||||
|
||||
deleteFrom(ul)
|
||||
.where(ul.USER_ID.eq(user.id))
|
||||
.execute()
|
||||
dsl.deleteFrom(ul)
|
||||
.where(ul.USER_ID.eq(user.id))
|
||||
.execute()
|
||||
|
||||
user.sharedLibrariesIds.forEach {
|
||||
insertInto(ul)
|
||||
.columns(ul.USER_ID, ul.LIBRARY_ID)
|
||||
.values(user.id, it)
|
||||
.execute()
|
||||
}
|
||||
}
|
||||
user.sharedLibrariesIds.forEach {
|
||||
dsl.insertInto(ul)
|
||||
.columns(ul.USER_ID, ul.LIBRARY_ID)
|
||||
.values(user.id, it)
|
||||
.execute()
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun delete(userId: String) {
|
||||
dsl.transaction { config ->
|
||||
with(config.dsl()) {
|
||||
deleteFrom(ul).where(ul.USER_ID.equal(userId)).execute()
|
||||
deleteFrom(u).where(u.ID.equal(userId)).execute()
|
||||
}
|
||||
}
|
||||
dsl.deleteFrom(ul).where(ul.USER_ID.equal(userId)).execute()
|
||||
dsl.deleteFrom(u).where(u.ID.equal(userId)).execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun deleteAll() {
|
||||
dsl.transaction { config ->
|
||||
with(config.dsl()) {
|
||||
deleteFrom(ul).execute()
|
||||
deleteFrom(u).execute()
|
||||
}
|
||||
}
|
||||
dsl.deleteFrom(ul).execute()
|
||||
dsl.deleteFrom(u).execute()
|
||||
}
|
||||
|
||||
override fun existsByEmailIgnoreCase(email: String): Boolean =
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import org.gotson.komga.jooq.Tables
|
|||
import org.gotson.komga.jooq.tables.records.LibraryRecord
|
||||
import org.jooq.DSLContext
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import java.net.URL
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneId
|
||||
|
|
@ -42,24 +43,19 @@ class LibraryDao(
|
|||
.fetchInto(l)
|
||||
.map { it.toDomain() }
|
||||
|
||||
@Transactional
|
||||
override fun delete(libraryId: String) {
|
||||
dsl.transaction { config ->
|
||||
with(config.dsl()) {
|
||||
deleteFrom(ul).where(ul.LIBRARY_ID.eq(libraryId)).execute()
|
||||
deleteFrom(l).where(l.ID.eq(libraryId)).execute()
|
||||
}
|
||||
}
|
||||
dsl.deleteFrom(ul).where(ul.LIBRARY_ID.eq(libraryId)).execute()
|
||||
dsl.deleteFrom(l).where(l.ID.eq(libraryId)).execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun deleteAll() {
|
||||
dsl.transaction { config ->
|
||||
with(config.dsl()) {
|
||||
deleteFrom(ul).execute()
|
||||
deleteFrom(l).execute()
|
||||
}
|
||||
}
|
||||
dsl.deleteFrom(ul).execute()
|
||||
dsl.deleteFrom(l).execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun insert(library: Library) {
|
||||
dsl.insertInto(l)
|
||||
.set(l.ID, library.id)
|
||||
|
|
@ -80,6 +76,7 @@ class LibraryDao(
|
|||
.execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun update(library: Library) {
|
||||
dsl.update(l)
|
||||
.set(l.NAME, library.name)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import org.gotson.komga.jooq.tables.records.MediaPageRecord
|
|||
import org.gotson.komga.jooq.tables.records.MediaRecord
|
||||
import org.jooq.DSLContext
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneId
|
||||
|
||||
|
|
@ -58,41 +59,41 @@ class MediaDao(
|
|||
mr.toDomain(pr.filterNot { it.bookId == null }.map { it.toDomain() }, files)
|
||||
}.first()
|
||||
|
||||
@Transactional
|
||||
override fun insert(media: Media) {
|
||||
insert(listOf(media))
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun insert(medias: Collection<Media>) {
|
||||
if (medias.isNotEmpty()) {
|
||||
dsl.transaction { config ->
|
||||
config.dsl().batch(
|
||||
config.dsl().insertInto(
|
||||
m,
|
||||
m.BOOK_ID,
|
||||
m.STATUS,
|
||||
m.MEDIA_TYPE,
|
||||
m.COMMENT,
|
||||
m.PAGE_COUNT
|
||||
).values(null as String?, null, null, null, null)
|
||||
).also { step ->
|
||||
medias.forEach {
|
||||
step.bind(
|
||||
it.bookId,
|
||||
it.status,
|
||||
it.mediaType,
|
||||
it.comment,
|
||||
it.pages.size
|
||||
)
|
||||
}
|
||||
}.execute()
|
||||
dsl.batch(
|
||||
dsl.insertInto(
|
||||
m,
|
||||
m.BOOK_ID,
|
||||
m.STATUS,
|
||||
m.MEDIA_TYPE,
|
||||
m.COMMENT,
|
||||
m.PAGE_COUNT
|
||||
).values(null as String?, null, null, null, null)
|
||||
).also { step ->
|
||||
medias.forEach {
|
||||
step.bind(
|
||||
it.bookId,
|
||||
it.status,
|
||||
it.mediaType,
|
||||
it.comment,
|
||||
it.pages.size
|
||||
)
|
||||
}
|
||||
}.execute()
|
||||
|
||||
insertPages(config.dsl(), medias)
|
||||
insertFiles(config.dsl(), medias)
|
||||
}
|
||||
insertPages(medias)
|
||||
insertFiles(medias)
|
||||
}
|
||||
}
|
||||
|
||||
private fun insertPages(dsl: DSLContext, medias: Collection<Media>) {
|
||||
private fun insertPages(medias: Collection<Media>) {
|
||||
if (medias.any { it.pages.isNotEmpty() }) {
|
||||
dsl.batch(
|
||||
dsl.insertInto(
|
||||
|
|
@ -121,7 +122,7 @@ class MediaDao(
|
|||
}
|
||||
}
|
||||
|
||||
private fun insertFiles(dsl: DSLContext, medias: Collection<Media>) {
|
||||
private fun insertFiles(medias: Collection<Media>) {
|
||||
if (medias.any { it.files.isNotEmpty() }) {
|
||||
dsl.batch(
|
||||
dsl.insertInto(
|
||||
|
|
@ -142,52 +143,45 @@ class MediaDao(
|
|||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun update(media: Media) {
|
||||
dsl.transaction { config ->
|
||||
with(config.dsl()) {
|
||||
update(m)
|
||||
.set(m.STATUS, media.status.toString())
|
||||
.set(m.MEDIA_TYPE, media.mediaType)
|
||||
.set(m.COMMENT, media.comment)
|
||||
.set(m.PAGE_COUNT, media.pages.size)
|
||||
.set(m.LAST_MODIFIED_DATE, LocalDateTime.now(ZoneId.of("Z")))
|
||||
.where(m.BOOK_ID.eq(media.bookId))
|
||||
.execute()
|
||||
dsl.update(m)
|
||||
.set(m.STATUS, media.status.toString())
|
||||
.set(m.MEDIA_TYPE, media.mediaType)
|
||||
.set(m.COMMENT, media.comment)
|
||||
.set(m.PAGE_COUNT, media.pages.size)
|
||||
.set(m.LAST_MODIFIED_DATE, LocalDateTime.now(ZoneId.of("Z")))
|
||||
.where(m.BOOK_ID.eq(media.bookId))
|
||||
.execute()
|
||||
|
||||
deleteFrom(p)
|
||||
.where(p.BOOK_ID.eq(media.bookId))
|
||||
.execute()
|
||||
dsl.deleteFrom(p)
|
||||
.where(p.BOOK_ID.eq(media.bookId))
|
||||
.execute()
|
||||
|
||||
deleteFrom(f)
|
||||
.where(f.BOOK_ID.eq(media.bookId))
|
||||
.execute()
|
||||
dsl.deleteFrom(f)
|
||||
.where(f.BOOK_ID.eq(media.bookId))
|
||||
.execute()
|
||||
|
||||
insertPages(this, listOf(media))
|
||||
insertFiles(this, listOf(media))
|
||||
}
|
||||
}
|
||||
insertPages(listOf(media))
|
||||
insertFiles(listOf(media))
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun delete(bookId: String) {
|
||||
dsl.transaction { config ->
|
||||
with(config.dsl()) {
|
||||
deleteFrom(p).where(p.BOOK_ID.eq(bookId)).execute()
|
||||
deleteFrom(f).where(f.BOOK_ID.eq(bookId)).execute()
|
||||
deleteFrom(m).where(m.BOOK_ID.eq(bookId)).execute()
|
||||
}
|
||||
}
|
||||
dsl.deleteFrom(p).where(p.BOOK_ID.eq(bookId)).execute()
|
||||
dsl.deleteFrom(f).where(f.BOOK_ID.eq(bookId)).execute()
|
||||
dsl.deleteFrom(m).where(m.BOOK_ID.eq(bookId)).execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun deleteByBookIds(bookIds: Collection<String>) {
|
||||
dsl.transaction { config ->
|
||||
with(config.dsl()) {
|
||||
deleteFrom(p).where(p.BOOK_ID.`in`(bookIds)).execute()
|
||||
deleteFrom(f).where(f.BOOK_ID.`in`(bookIds)).execute()
|
||||
deleteFrom(m).where(m.BOOK_ID.`in`(bookIds)).execute()
|
||||
}
|
||||
}
|
||||
dsl.deleteFrom(p).where(p.BOOK_ID.`in`(bookIds)).execute()
|
||||
dsl.deleteFrom(f).where(f.BOOK_ID.`in`(bookIds)).execute()
|
||||
dsl.deleteFrom(m).where(m.BOOK_ID.`in`(bookIds)).execute()
|
||||
}
|
||||
|
||||
override fun count(): Long = dsl.fetchCount(m).toLong()
|
||||
|
||||
private fun MediaRecord.toDomain(pages: List<BookPage>, files: List<String>) =
|
||||
Media(
|
||||
status = Media.Status.valueOf(status),
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import org.springframework.data.domain.PageRequest
|
|||
import org.springframework.data.domain.Pageable
|
||||
import org.springframework.data.domain.Sort
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneId
|
||||
import java.util.SortedMap
|
||||
|
|
@ -140,19 +141,18 @@ class ReadListDao(
|
|||
rr.toDomain(bookIds)
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun insert(readList: ReadList) {
|
||||
dsl.transaction { config ->
|
||||
config.dsl().insertInto(rl)
|
||||
.set(rl.ID, readList.id)
|
||||
.set(rl.NAME, readList.name)
|
||||
.set(rl.BOOK_COUNT, readList.bookIds.size)
|
||||
.execute()
|
||||
dsl.insertInto(rl)
|
||||
.set(rl.ID, readList.id)
|
||||
.set(rl.NAME, readList.name)
|
||||
.set(rl.BOOK_COUNT, readList.bookIds.size)
|
||||
.execute()
|
||||
|
||||
insertBooks(config.dsl(), readList)
|
||||
}
|
||||
insertBooks(readList)
|
||||
}
|
||||
|
||||
private fun insertBooks(dsl: DSLContext, readList: ReadList) {
|
||||
private fun insertBooks(readList: ReadList) {
|
||||
readList.bookIds.map { (index, id) ->
|
||||
dsl.insertInto(rlb)
|
||||
.set(rlb.READLIST_ID, readList.id)
|
||||
|
|
@ -162,53 +162,47 @@ class ReadListDao(
|
|||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun update(readList: ReadList) {
|
||||
dsl.transaction { config ->
|
||||
with(config.dsl()) {
|
||||
update(rl)
|
||||
.set(rl.NAME, readList.name)
|
||||
.set(rl.BOOK_COUNT, readList.bookIds.size)
|
||||
.set(rl.LAST_MODIFIED_DATE, LocalDateTime.now(ZoneId.of("Z")))
|
||||
.where(rl.ID.eq(readList.id))
|
||||
.execute()
|
||||
dsl.update(rl)
|
||||
.set(rl.NAME, readList.name)
|
||||
.set(rl.BOOK_COUNT, readList.bookIds.size)
|
||||
.set(rl.LAST_MODIFIED_DATE, LocalDateTime.now(ZoneId.of("Z")))
|
||||
.where(rl.ID.eq(readList.id))
|
||||
.execute()
|
||||
|
||||
deleteFrom(rlb).where(rlb.READLIST_ID.eq(readList.id)).execute()
|
||||
dsl.deleteFrom(rlb).where(rlb.READLIST_ID.eq(readList.id)).execute()
|
||||
|
||||
insertBooks(config.dsl(), readList)
|
||||
}
|
||||
}
|
||||
insertBooks(readList)
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun removeBookFromAll(bookId: String) {
|
||||
dsl.deleteFrom(rlb)
|
||||
.where(rlb.BOOK_ID.eq(bookId))
|
||||
.execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun removeBooksFromAll(bookIds: Collection<String>) {
|
||||
dsl.deleteFrom(rlb)
|
||||
.where(rlb.BOOK_ID.`in`(bookIds))
|
||||
.execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun delete(readListId: String) {
|
||||
dsl.transaction { config ->
|
||||
with(config.dsl()) {
|
||||
deleteFrom(rlb).where(rlb.READLIST_ID.eq(readListId)).execute()
|
||||
deleteFrom(rl).where(rl.ID.eq(readListId)).execute()
|
||||
}
|
||||
}
|
||||
dsl.deleteFrom(rlb).where(rlb.READLIST_ID.eq(readListId)).execute()
|
||||
dsl.deleteFrom(rl).where(rl.ID.eq(readListId)).execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun deleteAll() {
|
||||
dsl.transaction { config ->
|
||||
with(config.dsl()) {
|
||||
deleteFrom(rlb).execute()
|
||||
deleteFrom(rl).execute()
|
||||
}
|
||||
}
|
||||
dsl.deleteFrom(rlb).execute()
|
||||
dsl.deleteFrom(rl).execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun deleteEmpty() {
|
||||
dsl.deleteFrom(rl)
|
||||
.where(
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import org.jooq.DSLContext
|
|||
import org.jooq.Query
|
||||
import org.jooq.impl.DSL
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneId
|
||||
|
||||
|
|
@ -49,93 +50,85 @@ class ReadProgressDao(
|
|||
.fetchInto(r)
|
||||
.map { it.toDomain() }
|
||||
|
||||
@Transactional
|
||||
override fun save(readProgress: ReadProgress) {
|
||||
dsl.transaction { config ->
|
||||
config.dsl().saveQuery(readProgress).execute()
|
||||
config.dsl().aggregateSeriesProgress(listOf(readProgress.bookId), readProgress.userId)
|
||||
}
|
||||
saveQuery(readProgress).execute()
|
||||
aggregateSeriesProgress(listOf(readProgress.bookId), readProgress.userId)
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun save(readProgresses: Collection<ReadProgress>) {
|
||||
dsl.transaction { config ->
|
||||
val queries = readProgresses.map { config.dsl().saveQuery(it) }
|
||||
config.dsl().batch(queries).execute()
|
||||
val queries = readProgresses.map { saveQuery(it) }
|
||||
dsl.batch(queries).execute()
|
||||
|
||||
readProgresses.groupBy { it.userId }
|
||||
.forEach { (userId, readProgresses) ->
|
||||
config.dsl().aggregateSeriesProgress(readProgresses.map { it.bookId }, userId)
|
||||
}
|
||||
}
|
||||
readProgresses.groupBy { it.userId }
|
||||
.forEach { (userId, readProgresses) ->
|
||||
aggregateSeriesProgress(readProgresses.map { it.bookId }, userId)
|
||||
}
|
||||
}
|
||||
|
||||
private fun DSLContext.saveQuery(readProgress: ReadProgress): Query =
|
||||
this.insertInto(r, r.BOOK_ID, r.USER_ID, r.PAGE, r.COMPLETED)
|
||||
private fun saveQuery(readProgress: ReadProgress): Query =
|
||||
dsl.insertInto(r, r.BOOK_ID, r.USER_ID, r.PAGE, r.COMPLETED)
|
||||
.values(readProgress.bookId, readProgress.userId, readProgress.page, readProgress.completed)
|
||||
.onDuplicateKeyUpdate()
|
||||
.set(r.PAGE, readProgress.page)
|
||||
.set(r.COMPLETED, readProgress.completed)
|
||||
.set(r.LAST_MODIFIED_DATE, LocalDateTime.now(ZoneId.of("Z")))
|
||||
|
||||
@Transactional
|
||||
override fun delete(bookId: String, userId: String) {
|
||||
dsl.transaction { config ->
|
||||
config.dsl().deleteFrom(r).where(r.BOOK_ID.eq(bookId).and(r.USER_ID.eq(userId))).execute()
|
||||
config.dsl().aggregateSeriesProgress(listOf(bookId), userId)
|
||||
}
|
||||
dsl.deleteFrom(r).where(r.BOOK_ID.eq(bookId).and(r.USER_ID.eq(userId))).execute()
|
||||
aggregateSeriesProgress(listOf(bookId), userId)
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun deleteByUserId(userId: String) {
|
||||
dsl.transaction { config ->
|
||||
config.dsl().deleteFrom(r).where(r.USER_ID.eq(userId)).execute()
|
||||
config.dsl().deleteFrom(rs).where(rs.USER_ID.eq(userId)).execute()
|
||||
}
|
||||
dsl.deleteFrom(r).where(r.USER_ID.eq(userId)).execute()
|
||||
dsl.deleteFrom(rs).where(rs.USER_ID.eq(userId)).execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun deleteByBookId(bookId: String) {
|
||||
dsl.transaction { config ->
|
||||
config.dsl().deleteFrom(r).where(r.BOOK_ID.eq(bookId)).execute()
|
||||
config.dsl().aggregateSeriesProgress(listOf(bookId))
|
||||
}
|
||||
dsl.deleteFrom(r).where(r.BOOK_ID.eq(bookId)).execute()
|
||||
aggregateSeriesProgress(listOf(bookId))
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun deleteByBookIds(bookIds: Collection<String>) {
|
||||
dsl.transaction { config ->
|
||||
config.dsl().deleteFrom(r).where(r.BOOK_ID.`in`(bookIds)).execute()
|
||||
config.dsl().aggregateSeriesProgress(bookIds)
|
||||
}
|
||||
dsl.deleteFrom(r).where(r.BOOK_ID.`in`(bookIds)).execute()
|
||||
aggregateSeriesProgress(bookIds)
|
||||
}
|
||||
|
||||
override fun deleteBySeriesIds(seriesIds: Collection<String>) {
|
||||
dsl.deleteFrom(rs).where(rs.SERIES_ID.`in`(seriesIds)).execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun deleteByBookIdsAndUserId(bookIds: Collection<String>, userId: String) {
|
||||
dsl.transaction { config ->
|
||||
config.dsl().deleteFrom(r).where(r.BOOK_ID.`in`(bookIds)).and(r.USER_ID.eq(userId)).execute()
|
||||
config.dsl().aggregateSeriesProgress(bookIds, userId)
|
||||
}
|
||||
dsl.deleteFrom(r).where(r.BOOK_ID.`in`(bookIds)).and(r.USER_ID.eq(userId)).execute()
|
||||
aggregateSeriesProgress(bookIds, userId)
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun deleteAll() {
|
||||
dsl.transaction { config ->
|
||||
config.dsl().deleteFrom(r).execute()
|
||||
config.dsl().deleteFrom(rs).execute()
|
||||
}
|
||||
dsl.deleteFrom(r).execute()
|
||||
dsl.deleteFrom(rs).execute()
|
||||
}
|
||||
|
||||
private fun DSLContext.aggregateSeriesProgress(bookIds: Collection<String>, userId: String? = null) {
|
||||
val seriesIds = this.select(b.SERIES_ID)
|
||||
private fun aggregateSeriesProgress(bookIds: Collection<String>, userId: String? = null) {
|
||||
val seriesIds = dsl.select(b.SERIES_ID)
|
||||
.from(b)
|
||||
.where(b.ID.`in`(bookIds))
|
||||
.fetch(b.SERIES_ID)
|
||||
|
||||
this.deleteFrom(rs)
|
||||
dsl.deleteFrom(rs)
|
||||
.where(rs.SERIES_ID.`in`(seriesIds))
|
||||
.apply { userId?.let { and(rs.USER_ID.eq(it)) } }
|
||||
.execute()
|
||||
|
||||
this.insertInto(rs)
|
||||
dsl.insertInto(rs)
|
||||
.select(
|
||||
this.select(b.SERIES_ID, r.USER_ID)
|
||||
dsl.select(b.SERIES_ID, r.USER_ID)
|
||||
.select(DSL.sum(DSL.`when`(r.COMPLETED.isTrue, 1).otherwise(0)))
|
||||
.select(DSL.sum(DSL.`when`(r.COMPLETED.isFalse, 1).otherwise(0)))
|
||||
.from(b)
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import org.springframework.data.domain.PageRequest
|
|||
import org.springframework.data.domain.Pageable
|
||||
import org.springframework.data.domain.Sort
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneId
|
||||
|
||||
|
|
@ -138,20 +139,19 @@ class SeriesCollectionDao(
|
|||
cr.toDomain(seriesIds)
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun insert(collection: SeriesCollection) {
|
||||
dsl.transaction { config ->
|
||||
config.dsl().insertInto(c)
|
||||
.set(c.ID, collection.id)
|
||||
.set(c.NAME, collection.name)
|
||||
.set(c.ORDERED, collection.ordered)
|
||||
.set(c.SERIES_COUNT, collection.seriesIds.size)
|
||||
.execute()
|
||||
dsl.insertInto(c)
|
||||
.set(c.ID, collection.id)
|
||||
.set(c.NAME, collection.name)
|
||||
.set(c.ORDERED, collection.ordered)
|
||||
.set(c.SERIES_COUNT, collection.seriesIds.size)
|
||||
.execute()
|
||||
|
||||
insertSeries(config.dsl(), collection)
|
||||
}
|
||||
insertSeries(collection)
|
||||
}
|
||||
|
||||
private fun insertSeries(dsl: DSLContext, collection: SeriesCollection) {
|
||||
private fun insertSeries(collection: SeriesCollection) {
|
||||
collection.seriesIds.forEachIndexed { index, id ->
|
||||
dsl.insertInto(cs)
|
||||
.set(cs.COLLECTION_ID, collection.id)
|
||||
|
|
@ -161,54 +161,48 @@ class SeriesCollectionDao(
|
|||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun update(collection: SeriesCollection) {
|
||||
dsl.transaction { config ->
|
||||
with(config.dsl()) {
|
||||
update(c)
|
||||
.set(c.NAME, collection.name)
|
||||
.set(c.ORDERED, collection.ordered)
|
||||
.set(c.SERIES_COUNT, collection.seriesIds.size)
|
||||
.set(c.LAST_MODIFIED_DATE, LocalDateTime.now(ZoneId.of("Z")))
|
||||
.where(c.ID.eq(collection.id))
|
||||
.execute()
|
||||
dsl.update(c)
|
||||
.set(c.NAME, collection.name)
|
||||
.set(c.ORDERED, collection.ordered)
|
||||
.set(c.SERIES_COUNT, collection.seriesIds.size)
|
||||
.set(c.LAST_MODIFIED_DATE, LocalDateTime.now(ZoneId.of("Z")))
|
||||
.where(c.ID.eq(collection.id))
|
||||
.execute()
|
||||
|
||||
deleteFrom(cs).where(cs.COLLECTION_ID.eq(collection.id)).execute()
|
||||
dsl.deleteFrom(cs).where(cs.COLLECTION_ID.eq(collection.id)).execute()
|
||||
|
||||
insertSeries(config.dsl(), collection)
|
||||
}
|
||||
}
|
||||
insertSeries(collection)
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun removeSeriesFromAll(seriesId: String) {
|
||||
dsl.deleteFrom(cs)
|
||||
.where(cs.SERIES_ID.eq(seriesId))
|
||||
.execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun removeSeriesFromAll(seriesIds: Collection<String>) {
|
||||
dsl.deleteFrom(cs)
|
||||
.where(cs.SERIES_ID.`in`(seriesIds))
|
||||
.execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun delete(collectionId: String) {
|
||||
dsl.transaction { config ->
|
||||
with(config.dsl()) {
|
||||
deleteFrom(cs).where(cs.COLLECTION_ID.eq(collectionId)).execute()
|
||||
deleteFrom(c).where(c.ID.eq(collectionId)).execute()
|
||||
}
|
||||
}
|
||||
dsl.deleteFrom(cs).where(cs.COLLECTION_ID.eq(collectionId)).execute()
|
||||
dsl.deleteFrom(c).where(c.ID.eq(collectionId)).execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun deleteAll() {
|
||||
dsl.transaction { config ->
|
||||
with(config.dsl()) {
|
||||
deleteFrom(cs).execute()
|
||||
deleteFrom(c).execute()
|
||||
}
|
||||
}
|
||||
dsl.deleteFrom(cs).execute()
|
||||
dsl.deleteFrom(c).execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun deleteEmpty() {
|
||||
dsl.deleteFrom(c)
|
||||
.where(
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import org.jooq.Condition
|
|||
import org.jooq.DSLContext
|
||||
import org.jooq.impl.DSL
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import java.net.URL
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneId
|
||||
|
|
@ -83,6 +84,7 @@ class SeriesDao(
|
|||
.map { it.toDomain() }
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun insert(series: Series) {
|
||||
dsl.insertInto(s)
|
||||
.set(s.ID, series.id)
|
||||
|
|
@ -93,6 +95,7 @@ class SeriesDao(
|
|||
.execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun update(series: Series) {
|
||||
dsl.update(s)
|
||||
.set(s.NAME, series.name)
|
||||
|
|
@ -105,28 +108,19 @@ class SeriesDao(
|
|||
.execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun delete(seriesId: String) {
|
||||
dsl.transaction { config ->
|
||||
with(config.dsl()) {
|
||||
deleteFrom(s).where(s.ID.eq(seriesId)).execute()
|
||||
}
|
||||
}
|
||||
dsl.deleteFrom(s).where(s.ID.eq(seriesId)).execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun deleteAll() {
|
||||
dsl.transaction { config ->
|
||||
with(config.dsl()) {
|
||||
deleteFrom(s).execute()
|
||||
}
|
||||
}
|
||||
dsl.deleteFrom(s).execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun delete(seriesIds: Collection<String>) {
|
||||
dsl.transaction { config ->
|
||||
with(config.dsl()) {
|
||||
deleteFrom(s).where(s.ID.`in`(seriesIds)).execute()
|
||||
}
|
||||
}
|
||||
dsl.deleteFrom(s).where(s.ID.`in`(seriesIds)).execute()
|
||||
}
|
||||
|
||||
override fun count(): Long = dsl.fetchCount(s).toLong()
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import org.gotson.komga.jooq.Tables
|
|||
import org.gotson.komga.jooq.tables.records.SeriesMetadataRecord
|
||||
import org.jooq.DSLContext
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneId
|
||||
|
||||
|
|
@ -45,74 +46,72 @@ class SeriesMetadataDao(
|
|||
.mapNotNull { it.tag }
|
||||
.toSet()
|
||||
|
||||
@Transactional
|
||||
override fun insert(metadata: SeriesMetadata) {
|
||||
dsl.transaction { config ->
|
||||
config.dsl().insertInto(d)
|
||||
.set(d.SERIES_ID, metadata.seriesId)
|
||||
.set(d.STATUS, metadata.status.toString())
|
||||
.set(d.TITLE, metadata.title)
|
||||
.set(d.TITLE_SORT, metadata.titleSort)
|
||||
.set(d.SUMMARY, metadata.summary)
|
||||
.set(d.READING_DIRECTION, metadata.readingDirection?.toString())
|
||||
.set(d.PUBLISHER, metadata.publisher)
|
||||
.set(d.AGE_RATING, metadata.ageRating)
|
||||
.set(d.LANGUAGE, metadata.language)
|
||||
.set(d.STATUS_LOCK, metadata.statusLock)
|
||||
.set(d.TITLE_LOCK, metadata.titleLock)
|
||||
.set(d.TITLE_SORT_LOCK, metadata.titleSortLock)
|
||||
.set(d.SUMMARY_LOCK, metadata.summaryLock)
|
||||
.set(d.READING_DIRECTION_LOCK, metadata.readingDirectionLock)
|
||||
.set(d.PUBLISHER_LOCK, metadata.publisherLock)
|
||||
.set(d.AGE_RATING_LOCK, metadata.ageRatingLock)
|
||||
.set(d.LANGUAGE_LOCK, metadata.languageLock)
|
||||
.set(d.GENRES_LOCK, metadata.genresLock)
|
||||
.set(d.TAGS_LOCK, metadata.tagsLock)
|
||||
.execute()
|
||||
dsl.insertInto(d)
|
||||
.set(d.SERIES_ID, metadata.seriesId)
|
||||
.set(d.STATUS, metadata.status.toString())
|
||||
.set(d.TITLE, metadata.title)
|
||||
.set(d.TITLE_SORT, metadata.titleSort)
|
||||
.set(d.SUMMARY, metadata.summary)
|
||||
.set(d.READING_DIRECTION, metadata.readingDirection?.toString())
|
||||
.set(d.PUBLISHER, metadata.publisher)
|
||||
.set(d.AGE_RATING, metadata.ageRating)
|
||||
.set(d.LANGUAGE, metadata.language)
|
||||
.set(d.STATUS_LOCK, metadata.statusLock)
|
||||
.set(d.TITLE_LOCK, metadata.titleLock)
|
||||
.set(d.TITLE_SORT_LOCK, metadata.titleSortLock)
|
||||
.set(d.SUMMARY_LOCK, metadata.summaryLock)
|
||||
.set(d.READING_DIRECTION_LOCK, metadata.readingDirectionLock)
|
||||
.set(d.PUBLISHER_LOCK, metadata.publisherLock)
|
||||
.set(d.AGE_RATING_LOCK, metadata.ageRatingLock)
|
||||
.set(d.LANGUAGE_LOCK, metadata.languageLock)
|
||||
.set(d.GENRES_LOCK, metadata.genresLock)
|
||||
.set(d.TAGS_LOCK, metadata.tagsLock)
|
||||
.execute()
|
||||
|
||||
insertGenres(config.dsl(), metadata)
|
||||
insertTags(config.dsl(), metadata)
|
||||
}
|
||||
insertGenres(metadata)
|
||||
insertTags(metadata)
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun update(metadata: SeriesMetadata) {
|
||||
dsl.transaction { config ->
|
||||
config.dsl().update(d)
|
||||
.set(d.STATUS, metadata.status.toString())
|
||||
.set(d.TITLE, metadata.title)
|
||||
.set(d.TITLE_SORT, metadata.titleSort)
|
||||
.set(d.SUMMARY, metadata.summary)
|
||||
.set(d.READING_DIRECTION, metadata.readingDirection?.toString())
|
||||
.set(d.PUBLISHER, metadata.publisher)
|
||||
.set(d.AGE_RATING, metadata.ageRating)
|
||||
.set(d.LANGUAGE, metadata.language)
|
||||
.set(d.STATUS_LOCK, metadata.statusLock)
|
||||
.set(d.TITLE_LOCK, metadata.titleLock)
|
||||
.set(d.TITLE_SORT_LOCK, metadata.titleSortLock)
|
||||
.set(d.SUMMARY_LOCK, metadata.summaryLock)
|
||||
.set(d.READING_DIRECTION_LOCK, metadata.readingDirectionLock)
|
||||
.set(d.PUBLISHER_LOCK, metadata.publisherLock)
|
||||
.set(d.AGE_RATING_LOCK, metadata.ageRatingLock)
|
||||
.set(d.LANGUAGE_LOCK, metadata.languageLock)
|
||||
.set(d.GENRES_LOCK, metadata.genresLock)
|
||||
.set(d.TAGS_LOCK, metadata.tagsLock)
|
||||
.set(d.LAST_MODIFIED_DATE, LocalDateTime.now(ZoneId.of("Z")))
|
||||
.where(d.SERIES_ID.eq(metadata.seriesId))
|
||||
.execute()
|
||||
dsl.update(d)
|
||||
.set(d.STATUS, metadata.status.toString())
|
||||
.set(d.TITLE, metadata.title)
|
||||
.set(d.TITLE_SORT, metadata.titleSort)
|
||||
.set(d.SUMMARY, metadata.summary)
|
||||
.set(d.READING_DIRECTION, metadata.readingDirection?.toString())
|
||||
.set(d.PUBLISHER, metadata.publisher)
|
||||
.set(d.AGE_RATING, metadata.ageRating)
|
||||
.set(d.LANGUAGE, metadata.language)
|
||||
.set(d.STATUS_LOCK, metadata.statusLock)
|
||||
.set(d.TITLE_LOCK, metadata.titleLock)
|
||||
.set(d.TITLE_SORT_LOCK, metadata.titleSortLock)
|
||||
.set(d.SUMMARY_LOCK, metadata.summaryLock)
|
||||
.set(d.READING_DIRECTION_LOCK, metadata.readingDirectionLock)
|
||||
.set(d.PUBLISHER_LOCK, metadata.publisherLock)
|
||||
.set(d.AGE_RATING_LOCK, metadata.ageRatingLock)
|
||||
.set(d.LANGUAGE_LOCK, metadata.languageLock)
|
||||
.set(d.GENRES_LOCK, metadata.genresLock)
|
||||
.set(d.TAGS_LOCK, metadata.tagsLock)
|
||||
.set(d.LAST_MODIFIED_DATE, LocalDateTime.now(ZoneId.of("Z")))
|
||||
.where(d.SERIES_ID.eq(metadata.seriesId))
|
||||
.execute()
|
||||
|
||||
config.dsl().deleteFrom(g)
|
||||
.where(g.SERIES_ID.eq(metadata.seriesId))
|
||||
.execute()
|
||||
dsl.deleteFrom(g)
|
||||
.where(g.SERIES_ID.eq(metadata.seriesId))
|
||||
.execute()
|
||||
|
||||
config.dsl().deleteFrom(st)
|
||||
.where(st.SERIES_ID.eq(metadata.seriesId))
|
||||
.execute()
|
||||
dsl.deleteFrom(st)
|
||||
.where(st.SERIES_ID.eq(metadata.seriesId))
|
||||
.execute()
|
||||
|
||||
insertGenres(config.dsl(), metadata)
|
||||
insertTags(config.dsl(), metadata)
|
||||
}
|
||||
insertGenres(metadata)
|
||||
insertTags(metadata)
|
||||
}
|
||||
|
||||
private fun insertGenres(dsl: DSLContext, metadata: SeriesMetadata) {
|
||||
private fun insertGenres(metadata: SeriesMetadata) {
|
||||
if (metadata.genres.isNotEmpty()) {
|
||||
dsl.batch(
|
||||
dsl.insertInto(g, g.SERIES_ID, g.GENRE)
|
||||
|
|
@ -125,7 +124,7 @@ class SeriesMetadataDao(
|
|||
}
|
||||
}
|
||||
|
||||
private fun insertTags(dsl: DSLContext, metadata: SeriesMetadata) {
|
||||
private fun insertTags(metadata: SeriesMetadata) {
|
||||
if (metadata.tags.isNotEmpty()) {
|
||||
dsl.batch(
|
||||
dsl.insertInto(st, st.SERIES_ID, st.TAG)
|
||||
|
|
@ -138,24 +137,18 @@ class SeriesMetadataDao(
|
|||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun delete(seriesId: String) {
|
||||
dsl.transaction { config ->
|
||||
with(config.dsl()) {
|
||||
deleteFrom(g).where(g.SERIES_ID.eq(seriesId)).execute()
|
||||
deleteFrom(st).where(st.SERIES_ID.eq(seriesId)).execute()
|
||||
deleteFrom(d).where(d.SERIES_ID.eq(seriesId)).execute()
|
||||
}
|
||||
}
|
||||
dsl.deleteFrom(g).where(g.SERIES_ID.eq(seriesId)).execute()
|
||||
dsl.deleteFrom(st).where(st.SERIES_ID.eq(seriesId)).execute()
|
||||
dsl.deleteFrom(d).where(d.SERIES_ID.eq(seriesId)).execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun delete(seriesIds: Collection<String>) {
|
||||
dsl.transaction { config ->
|
||||
with(config.dsl()) {
|
||||
deleteFrom(g).where(g.SERIES_ID.`in`(seriesIds)).execute()
|
||||
deleteFrom(st).where(st.SERIES_ID.`in`(seriesIds)).execute()
|
||||
deleteFrom(d).where(d.SERIES_ID.`in`(seriesIds)).execute()
|
||||
}
|
||||
}
|
||||
dsl.deleteFrom(g).where(g.SERIES_ID.`in`(seriesIds)).execute()
|
||||
dsl.deleteFrom(st).where(st.SERIES_ID.`in`(seriesIds)).execute()
|
||||
dsl.deleteFrom(d).where(d.SERIES_ID.`in`(seriesIds)).execute()
|
||||
}
|
||||
|
||||
override fun count(): Long = dsl.fetchCount(d).toLong()
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import org.gotson.komga.jooq.Tables
|
|||
import org.gotson.komga.jooq.tables.records.SidecarRecord
|
||||
import org.jooq.DSLContext
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import java.net.URL
|
||||
|
||||
@Component
|
||||
|
|
@ -19,6 +20,7 @@ class SidecarDao(
|
|||
override fun findAll(): Collection<SidecarStored> =
|
||||
dsl.selectFrom(sc).fetch().map { it.toDomain() }
|
||||
|
||||
@Transactional
|
||||
override fun save(libraryId: String, sidecar: Sidecar) {
|
||||
dsl.insertInto(sc)
|
||||
.values(
|
||||
|
|
@ -34,6 +36,7 @@ class SidecarDao(
|
|||
.execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun deleteByLibraryIdAndUrls(libraryId: String, urls: Collection<URL>) {
|
||||
dsl.deleteFrom(sc)
|
||||
.where(sc.LIBRARY_ID.eq(libraryId))
|
||||
|
|
@ -41,6 +44,7 @@ class SidecarDao(
|
|||
.execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun deleteByLibraryId(libraryId: String) {
|
||||
dsl.deleteFrom(sc)
|
||||
.where(sc.LIBRARY_ID.eq(libraryId))
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import org.gotson.komga.jooq.Tables
|
|||
import org.gotson.komga.jooq.tables.records.ThumbnailBookRecord
|
||||
import org.jooq.DSLContext
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import java.net.URL
|
||||
|
||||
@Component
|
||||
|
|
@ -36,6 +37,7 @@ class ThumbnailBookDao(
|
|||
.map { it.toDomain() }
|
||||
.firstOrNull()
|
||||
|
||||
@Transactional
|
||||
override fun insert(thumbnail: ThumbnailBook) {
|
||||
dsl.insertInto(tb)
|
||||
.set(tb.ID, thumbnail.id)
|
||||
|
|
@ -47,6 +49,7 @@ class ThumbnailBookDao(
|
|||
.execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun update(thumbnail: ThumbnailBook) {
|
||||
dsl.update(tb)
|
||||
.set(tb.BOOK_ID, thumbnail.bookId)
|
||||
|
|
@ -58,34 +61,37 @@ class ThumbnailBookDao(
|
|||
.execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun markSelected(thumbnail: ThumbnailBook) {
|
||||
dsl.transaction { config ->
|
||||
config.dsl().update(tb)
|
||||
.set(tb.SELECTED, false)
|
||||
.where(tb.BOOK_ID.eq(thumbnail.bookId))
|
||||
.and(tb.ID.ne(thumbnail.id))
|
||||
.execute()
|
||||
dsl.update(tb)
|
||||
.set(tb.SELECTED, false)
|
||||
.where(tb.BOOK_ID.eq(thumbnail.bookId))
|
||||
.and(tb.ID.ne(thumbnail.id))
|
||||
.execute()
|
||||
|
||||
config.dsl().update(tb)
|
||||
.set(tb.SELECTED, true)
|
||||
.where(tb.BOOK_ID.eq(thumbnail.bookId))
|
||||
.and(tb.ID.eq(thumbnail.id))
|
||||
.execute()
|
||||
}
|
||||
dsl.update(tb)
|
||||
.set(tb.SELECTED, true)
|
||||
.where(tb.BOOK_ID.eq(thumbnail.bookId))
|
||||
.and(tb.ID.eq(thumbnail.id))
|
||||
.execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun delete(thumbnailBookId: String) {
|
||||
dsl.deleteFrom(tb).where(tb.ID.eq(thumbnailBookId)).execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun deleteByBookId(bookId: String) {
|
||||
dsl.deleteFrom(tb).where(tb.BOOK_ID.eq(bookId)).execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun deleteByBookIds(bookIds: Collection<String>) {
|
||||
dsl.deleteFrom(tb).where(tb.BOOK_ID.`in`(bookIds)).execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun deleteByBookIdAndType(bookId: String, type: ThumbnailBook.Type) {
|
||||
dsl.deleteFrom(tb)
|
||||
.where(tb.BOOK_ID.eq(bookId))
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import org.gotson.komga.jooq.Tables
|
|||
import org.gotson.komga.jooq.tables.records.ThumbnailSeriesRecord
|
||||
import org.jooq.DSLContext
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import java.net.URL
|
||||
|
||||
@Component
|
||||
|
|
@ -29,6 +30,7 @@ class ThumbnailSeriesDao(
|
|||
.map { it.toDomain() }
|
||||
.firstOrNull()
|
||||
|
||||
@Transactional
|
||||
override fun insert(thumbnail: ThumbnailSeries) {
|
||||
dsl.insertInto(ts)
|
||||
.set(ts.ID, thumbnail.id)
|
||||
|
|
@ -38,30 +40,32 @@ class ThumbnailSeriesDao(
|
|||
.execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun markSelected(thumbnail: ThumbnailSeries) {
|
||||
dsl.transaction { config ->
|
||||
config.dsl().update(ts)
|
||||
.set(ts.SELECTED, false)
|
||||
.where(ts.SERIES_ID.eq(thumbnail.seriesId))
|
||||
.and(ts.ID.ne(thumbnail.id))
|
||||
.execute()
|
||||
dsl.update(ts)
|
||||
.set(ts.SELECTED, false)
|
||||
.where(ts.SERIES_ID.eq(thumbnail.seriesId))
|
||||
.and(ts.ID.ne(thumbnail.id))
|
||||
.execute()
|
||||
|
||||
config.dsl().update(ts)
|
||||
.set(ts.SELECTED, true)
|
||||
.where(ts.SERIES_ID.eq(thumbnail.seriesId))
|
||||
.and(ts.ID.eq(thumbnail.id))
|
||||
.execute()
|
||||
}
|
||||
dsl.update(ts)
|
||||
.set(ts.SELECTED, true)
|
||||
.where(ts.SERIES_ID.eq(thumbnail.seriesId))
|
||||
.and(ts.ID.eq(thumbnail.id))
|
||||
.execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun delete(thumbnailSeriesId: String) {
|
||||
dsl.deleteFrom(ts).where(ts.ID.eq(thumbnailSeriesId)).execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun deleteBySeriesId(seriesId: String) {
|
||||
dsl.deleteFrom(ts).where(ts.SERIES_ID.eq(seriesId)).execute()
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun deleteBySeriesIds(seriesIds: Collection<String>) {
|
||||
dsl.deleteFrom(ts).where(ts.SERIES_ID.`in`(seriesIds)).execute()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,26 @@
|
|||
package org.gotson.komga.domain.service
|
||||
|
||||
import com.ninjasquad.springmockk.SpykBean
|
||||
import io.mockk.every
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.core.api.Assertions.catchThrowable
|
||||
import org.gotson.komga.domain.model.BookMetadata
|
||||
import org.gotson.komga.domain.model.Media
|
||||
import org.gotson.komga.domain.model.makeBook
|
||||
import org.gotson.komga.domain.model.makeLibrary
|
||||
import org.gotson.komga.domain.model.makeSeries
|
||||
import org.gotson.komga.domain.persistence.BookMetadataAggregationRepository
|
||||
import org.gotson.komga.domain.persistence.BookMetadataRepository
|
||||
import org.gotson.komga.domain.persistence.BookRepository
|
||||
import org.gotson.komga.domain.persistence.LibraryRepository
|
||||
import org.gotson.komga.domain.persistence.MediaRepository
|
||||
import org.gotson.komga.domain.persistence.SeriesMetadataRepository
|
||||
import org.gotson.komga.domain.persistence.SeriesRepository
|
||||
import org.jooq.exception.DataAccessException
|
||||
import org.junit.jupiter.api.AfterAll
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.BeforeAll
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.extension.ExtendWith
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
|
|
@ -23,11 +33,22 @@ class SeriesLifecycleTest(
|
|||
@Autowired private val seriesLifecycle: SeriesLifecycle,
|
||||
@Autowired private val bookLifecycle: BookLifecycle,
|
||||
@Autowired private val seriesRepository: SeriesRepository,
|
||||
@Autowired private val seriesMetadataRepository: SeriesMetadataRepository,
|
||||
@Autowired private val bookRepository: BookRepository,
|
||||
@Autowired private val libraryRepository: LibraryRepository
|
||||
) {
|
||||
|
||||
@SpykBean
|
||||
private lateinit var seriesMetadataRepository: SeriesMetadataRepository
|
||||
|
||||
@SpykBean
|
||||
private lateinit var bookMetadataAggregationRepository: BookMetadataAggregationRepository
|
||||
|
||||
@SpykBean
|
||||
private lateinit var mediaRepository: MediaRepository
|
||||
|
||||
@SpykBean
|
||||
private lateinit var bookMetadataRepository: BookMetadataRepository
|
||||
|
||||
private val library = makeLibrary()
|
||||
|
||||
@BeforeAll
|
||||
|
|
@ -155,4 +176,81 @@ class SeriesLifecycleTest(
|
|||
assertThat(titleSort).isEqualTo("Ecarlate")
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class Transactions {
|
||||
@Test
|
||||
fun `given series when saving and an exception occur while saving metadata then series is not saved`() {
|
||||
// given
|
||||
val series = makeSeries(name = "series", libraryId = library.id)
|
||||
every { seriesMetadataRepository.insert(any()) } throws DataAccessException("")
|
||||
|
||||
// when
|
||||
val thrown = catchThrowable { seriesLifecycle.createSeries(series) }
|
||||
|
||||
// then
|
||||
assertThat(thrown).isInstanceOf(RuntimeException::class.java)
|
||||
assertThat(bookMetadataAggregationRepository.count()).isEqualTo(0)
|
||||
assertThat(seriesMetadataRepository.count()).isEqualTo(0)
|
||||
assertThat(seriesRepository.count()).isEqualTo(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given series when saving and an exception occur while saving metadata aggregation then series is not saved`() {
|
||||
// given
|
||||
val series = makeSeries(name = "series", libraryId = library.id)
|
||||
every { bookMetadataAggregationRepository.insert(any()) } throws DataAccessException("")
|
||||
|
||||
// when
|
||||
val thrown = catchThrowable { seriesLifecycle.createSeries(series) }
|
||||
|
||||
// then
|
||||
assertThat(thrown).isInstanceOf(RuntimeException::class.java)
|
||||
assertThat(bookMetadataAggregationRepository.count()).isEqualTo(0)
|
||||
assertThat(seriesMetadataRepository.count()).isEqualTo(0)
|
||||
assertThat(seriesRepository.count()).isEqualTo(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given series when adding books and an exception occur while saving media then books are not saved`() {
|
||||
val books = listOf(
|
||||
makeBook("book 1", libraryId = library.id),
|
||||
)
|
||||
val createdSeries = makeSeries(name = "series", libraryId = library.id).let {
|
||||
seriesLifecycle.createSeries(it)
|
||||
}
|
||||
|
||||
every { mediaRepository.insert(any<Collection<Media>>()) } throws DataAccessException("")
|
||||
|
||||
// when
|
||||
val thrown = catchThrowable { seriesLifecycle.addBooks(createdSeries, books) }
|
||||
|
||||
// then
|
||||
assertThat(thrown).isInstanceOf(Exception::class.java)
|
||||
assertThat(mediaRepository.count()).isEqualTo(0)
|
||||
assertThat(bookMetadataRepository.count()).isEqualTo(0)
|
||||
assertThat(bookRepository.count()).isEqualTo(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given series when adding books and an exception occur while saving metadata then books are not saved`() {
|
||||
val books = listOf(
|
||||
makeBook("book 1", libraryId = library.id),
|
||||
)
|
||||
val createdSeries = makeSeries(name = "series", libraryId = library.id).let {
|
||||
seriesLifecycle.createSeries(it)
|
||||
}
|
||||
|
||||
every { bookMetadataRepository.insert(any<Collection<BookMetadata>>()) } throws DataAccessException("")
|
||||
|
||||
// when
|
||||
val thrown = catchThrowable { seriesLifecycle.addBooks(createdSeries, books) }
|
||||
|
||||
// then
|
||||
assertThat(thrown).isInstanceOf(Exception::class.java)
|
||||
assertThat(mediaRepository.count()).isEqualTo(0)
|
||||
assertThat(bookMetadataRepository.count()).isEqualTo(0)
|
||||
assertThat(bookRepository.count()).isEqualTo(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue