Skip to content

Commit

Permalink
Merge pull request #431 from Shikkanime/dev
Browse files Browse the repository at this point in the history
Fetch lazy
  • Loading branch information
Ziedelth authored May 2, 2024
2 parents 9a85d55 + 0401446 commit 2c4dba8
Show file tree
Hide file tree
Showing 14 changed files with 214 additions and 66 deletions.
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
package fr.shikkanime.converters.anime

import com.google.inject.Inject
import fr.shikkanime.converters.AbstractConverter
import fr.shikkanime.dtos.AnimeDto
import fr.shikkanime.dtos.SimulcastDto
import fr.shikkanime.entities.Anime
import fr.shikkanime.entities.enums.LangType
import fr.shikkanime.services.SimulcastService.Companion.sortBySeasonAndYear
import fr.shikkanime.services.caches.EpisodeVariantCacheService
import fr.shikkanime.utils.StringUtils
import fr.shikkanime.utils.withUTCString

class AnimeToAnimeDtoConverter : AbstractConverter<Anime, AnimeDto>() {
@Inject
private lateinit var episodeVariantCacheService: EpisodeVariantCacheService

override fun convert(from: Anime): AnimeDto {
val audioLocales = from.mappings.flatMap { it.variants }.mapNotNull { it.audioLocale }.toSet()
val audioLocales = episodeVariantCacheService.findAllAudioLocalesByAnime(from)!!

return AnimeDto(
uuid = from.uuid,
Expand All @@ -28,8 +33,8 @@ class AnimeToAnimeDtoConverter : AbstractConverter<Anime, AnimeDto>() {
from.simulcasts.sortBySeasonAndYear(),
SimulcastDto::class.java
)?.toList(),
audioLocales = audioLocales.toList(),
langTypes = audioLocales.map { LangType.fromAudioLocale(from.countryCode, it) }.sorted().toSet(),
audioLocales = audioLocales,
langTypes = audioLocales.map { LangType.fromAudioLocale(from.countryCode, it) }.sorted(),
status = from.status,
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
package fr.shikkanime.converters.episode_mapping

import com.google.inject.Inject
import fr.shikkanime.converters.AbstractConverter
import fr.shikkanime.dtos.AnimeDto
import fr.shikkanime.dtos.EpisodeMappingDto
import fr.shikkanime.dtos.PlatformDto
import fr.shikkanime.dtos.variants.EpisodeVariantWithoutMappingDto
import fr.shikkanime.entities.EpisodeMapping
import fr.shikkanime.entities.enums.LangType
import fr.shikkanime.services.EpisodeVariantService
import fr.shikkanime.utils.withUTCString

class EpisodeMappingToEpisodeMappingDtoConverter : AbstractConverter<EpisodeMapping, EpisodeMappingDto>() {
@Inject
private lateinit var episodeVariantService: EpisodeVariantService

override fun convert(from: EpisodeMapping): EpisodeMappingDto {
val variants = from.variants.sortedBy { it.releaseDateTime }
val variants = episodeVariantService.findAllByMapping(from).sortedBy { it.releaseDateTime }

return EpisodeMappingDto(
uuid = from.uuid!!,
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/fr/shikkanime/dtos/AnimeDto.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ data class AnimeDto(
val description: String?,
val simulcasts: List<SimulcastDto>?,
val audioLocales: List<String>? = null,
val langTypes: Set<LangType>? = null,
val langTypes: List<LangType>? = null,
val status: Status? = null,
)
3 changes: 1 addition & 2 deletions src/main/kotlin/fr/shikkanime/entities/Anime.kt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class Anime(
joinColumns = [JoinColumn(name = "anime_uuid")],
inverseJoinColumns = [JoinColumn(name = "simulcast_uuid")]
)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
var simulcasts: MutableSet<Simulcast> = mutableSetOf(),
@Column(nullable = false)
var slug: String? = null,
Expand All @@ -52,6 +53,4 @@ class Anime(
@Column(nullable = true, name = "status")
@Enumerated(EnumType.STRING)
var status: Status = Status.VALID,
@OneToMany(mappedBy = "anime", fetch = FetchType.EAGER)
var mappings: MutableSet<EpisodeMapping> = mutableSetOf(),
) : ShikkEntity(uuid)
5 changes: 2 additions & 3 deletions src/main/kotlin/fr/shikkanime/entities/EpisodeMapping.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ import java.util.*
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
class EpisodeMapping(
override val uuid: UUID? = null,
@ManyToOne(optional = false)
@ManyToOne(optional = false, fetch = FetchType.LAZY)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
var anime: Anime? = null,
@Column(nullable = false, name = "release_date_time")
var releaseDateTime: ZonedDateTime = ZonedDateTime.now(),
Expand All @@ -46,8 +47,6 @@ class EpisodeMapping(
var description: String? = null,
@Column(nullable = false, columnDefinition = "VARCHAR(1000)")
var image: String? = null,
@OneToMany(mappedBy = "mapping", fetch = FetchType.EAGER)
var variants: MutableSet<EpisodeVariant> = mutableSetOf(),
@Column(nullable = true, name = "status")
@Enumerated(EnumType.STRING)
var status: Status = Status.VALID,
Expand Down
3 changes: 2 additions & 1 deletion src/main/kotlin/fr/shikkanime/entities/EpisodeVariant.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import java.util.*
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
class EpisodeVariant(
override val uuid: UUID? = null,
@ManyToOne(optional = false)
@ManyToOne(optional = false, fetch = FetchType.LAZY)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
var mapping: EpisodeMapping? = null,
@Column(nullable = false, name = "release_date_time")
var releaseDateTime: ZonedDateTime = ZonedDateTime.now(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,19 @@ class EpisodeMappingRepository : AbstractRepository<EpisodeMapping>() {
}
}

fun findAllByAnime(anime: Anime): List<EpisodeMapping> {
return inTransaction {
val cb = it.criteriaBuilder
val query = cb.createQuery(getEntityClass())
val root = query.from(getEntityClass())

query.where(cb.equal(root[EpisodeMapping_.anime], anime))

it.createQuery(query)
.resultList
}
}

fun findByAnimeEpisodeTypeSeasonNumber(
anime: Anime,
episodeType: EpisodeType,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package fr.shikkanime.repositories

import fr.shikkanime.entities.Anime_
import fr.shikkanime.entities.EpisodeMapping_
import fr.shikkanime.entities.EpisodeVariant
import fr.shikkanime.entities.EpisodeVariant_
import fr.shikkanime.entities.*
import fr.shikkanime.entities.enums.CountryCode
import fr.shikkanime.entities.enums.EpisodeType
import jakarta.persistence.Tuple
import java.time.ZonedDateTime
import java.util.*
Expand Down Expand Up @@ -58,6 +56,83 @@ class EpisodeVariantRepository : AbstractRepository<EpisodeVariant>() {
}
}

fun findAllAudioLocalesByAnime(anime: Anime): List<String> {
return inTransaction { entityManager ->
val cb = entityManager.criteriaBuilder
val query = cb.createQuery(String::class.java)
val root = query.from(getEntityClass())

query.select(root[EpisodeVariant_.audioLocale])
.where(cb.equal(root[EpisodeVariant_.mapping][EpisodeMapping_.anime], anime))
.distinct(true)

createReadOnlyQuery(entityManager, query)
.resultList
}
}

fun findAllAudioLocalesByMapping(mapping: EpisodeMapping): List<String> {
return inTransaction { entityManager ->
val cb = entityManager.criteriaBuilder
val query = cb.createQuery(String::class.java)
val root = query.from(getEntityClass())

query.select(root[EpisodeVariant_.audioLocale])
.where(cb.equal(root[EpisodeVariant_.mapping], mapping))
.distinct(true)

createReadOnlyQuery(entityManager, query)
.resultList
}
}

fun findAllByAnime(anime: Anime): List<EpisodeVariant> {
return inTransaction { entityManager ->
val cb = entityManager.criteriaBuilder
val query = cb.createQuery(getEntityClass())
val root = query.from(getEntityClass())

query.where(cb.equal(root[EpisodeVariant_.mapping][EpisodeMapping_.anime], anime))

createReadOnlyQuery(entityManager, query)
.resultList
}
}

fun findAllByMapping(mapping: EpisodeMapping): List<EpisodeVariant> {
return inTransaction { entityManager ->
val cb = entityManager.criteriaBuilder
val query = cb.createQuery(getEntityClass())
val root = query.from(getEntityClass())

query.where(cb.equal(root[EpisodeVariant_.mapping], mapping))

createReadOnlyQuery(entityManager, query)
.resultList
}
}

fun findAllSimulcasted(countryCode: CountryCode): List<EpisodeMapping> {
return inTransaction { entityManager ->
val cb = entityManager.criteriaBuilder
val query = cb.createQuery(EpisodeMapping::class.java)
val root = query.from(getEntityClass())

query.distinct(true)
.select(root[EpisodeVariant_.mapping])
.where(
cb.and(
cb.notEqual(root[EpisodeVariant_.audioLocale], countryCode.locale),
cb.notEqual(root[EpisodeVariant_.mapping][EpisodeMapping_.episodeType], EpisodeType.FILM)
)
)
.orderBy(cb.asc(root[EpisodeVariant_.mapping][EpisodeMapping_.releaseDateTime]))

createReadOnlyQuery(entityManager, query)
.resultList
}
}

fun findByIdentifier(identifier: String): EpisodeVariant? {
return inTransaction { entityManager ->
val cb = entityManager.criteriaBuilder
Expand Down
40 changes: 21 additions & 19 deletions src/main/kotlin/fr/shikkanime/services/AnimeService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import fr.shikkanime.entities.EpisodeVariant
import fr.shikkanime.entities.Simulcast
import fr.shikkanime.entities.SortParameter
import fr.shikkanime.entities.enums.CountryCode
import fr.shikkanime.entities.enums.EpisodeType
import fr.shikkanime.entities.enums.LangType
import fr.shikkanime.repositories.AnimeRepository
import fr.shikkanime.utils.MapCache
Expand Down Expand Up @@ -63,34 +62,39 @@ class AnimeService : AbstractService<Anime, AnimeRepository>() {

fun getWeeklyAnimes(startOfWeekDay: LocalDate, countryCode: CountryCode): List<WeeklyAnimesDto> {
val zoneId = ZoneId.of(countryCode.timezone)
val start = startOfWeekDay.minusDays(7).atStartOfDay(zoneId)
val end = startOfWeekDay.plusDays(7).atTime(23, 59, 59).atZone(zoneId)
val list = episodeVariantService.findAllByDateRange(countryCode, start, end)
val pattern = DateTimeFormatter.ofPattern("EEEE", Locale.forLanguageTag(countryCode.locale))

val list = episodeVariantService.findAllByDateRange(
countryCode,
startOfWeekDay.minusDays(7).atStartOfDay(zoneId),
startOfWeekDay.plusDays(7).atTime(23, 59, 59).atZone(zoneId)
)

return startOfWeekDay.datesUntil(startOfWeekDay.plusDays(7)).toList().map { date ->
val zonedDate = date.atStartOfDay(zoneId)
val dateTitle = date.format(pattern).capitalizeWords()
val episodeVariants =
list.filter { it.releaseDateTime.withZoneSameInstant(zoneId).dayOfWeek == zonedDate.dayOfWeek }

val episodeVariants = list.filter {
it.releaseDateTime.withZoneSameInstant(zoneId).dayOfWeek == zonedDate.dayOfWeek
}

WeeklyAnimesDto(
dateTitle,
date.format(DateTimeFormatter.ofPattern("EEEE", Locale.forLanguageTag(countryCode.locale)))
.capitalizeWords(),
episodeVariants.distinctBy { episodeVariant ->
val anime = episodeVariant.mapping!!.anime!!
anime.uuid.toString() + LangType.fromAudioLocale(anime.countryCode!!, episodeVariant.audioLocale!!)
}.map { distinctVariant ->
val anime = distinctVariant.mapping!!.anime!!
val platforms = episodeVariants.filter { it.mapping == distinctVariant.mapping }
.mapNotNull(EpisodeVariant::platform)
.sorted()
.distinct()

WeeklyAnimeDto(
AbstractConverter.convert(anime, AnimeDto::class.java),
distinctVariant.releaseDateTime.withUTCString(),
LangType.fromAudioLocale(anime.countryCode!!, distinctVariant.audioLocale!!),
AbstractConverter.convert(platforms, PlatformDto::class.java)!!
AbstractConverter.convert(
episodeVariants.filter { it.mapping == distinctVariant.mapping }
.mapNotNull(EpisodeVariant::platform)
.sorted()
.distinct(),
PlatformDto::class.java
)!!
)
}.sortedWith(compareBy({
ZonedDateTime.parse(it.releaseDateTime).withZoneSameInstant(zoneId).toLocalTime()
Expand Down Expand Up @@ -124,9 +128,7 @@ class AnimeService : AbstractService<Anime, AnimeRepository>() {
update(anime)
}

episodeMappingService.findAll()
.filter { it.variants.any { variant -> variant.audioLocale != CountryCode.FR.locale } && it.episodeType != EpisodeType.FILM }
.sortedBy { it.releaseDateTime }
episodeVariantService.findAllSimulcasted(CountryCode.FR)
.forEach { episodeMapping ->
val anime = find(episodeMapping.anime!!.uuid!!)!!
addSimulcastToAnime(anime, episodeVariantService.getSimulcast(anime, episodeMapping))
Expand Down Expand Up @@ -209,7 +211,7 @@ class AnimeService : AbstractService<Anime, AnimeRepository>() {
}

override fun delete(entity: Anime) {
entity.mappings.forEach { episodeMappingService.delete(it) }
episodeMappingService.findAllByAnime(entity).forEach { episodeMappingService.delete(it) }
super.delete(entity)
MapCache.invalidate(Anime::class.java)
}
Expand Down
Loading

0 comments on commit 2c4dba8

Please sign in to comment.