From 2eb7a4beb2249b3c3c792f39b87dc8a55e71dfae Mon Sep 17 00:00:00 2001 From: Harry Andreolas Date: Fri, 30 Jan 2026 23:35:46 +0200 Subject: [PATCH 1/3] feat: rename person entity table to person details entity --- .../details/mapper/PersonDetailsApiToEntityMapper.kt | 4 ++-- .../details/mapper/PersonDetailsEntityMapper.kt | 4 ++-- core/database/build.gradle.kts | 2 +- .../com/divinelink/core/database/person/PersonDao.kt | 4 ++-- .../divinelink/core/database/person/ProdPersonDao.kt | 12 ++++++------ .../{PersonEntity.sq => PersonDetailsEntity.sq} | 10 +++++----- .../src/commonMain/sqldelight/migrations/8.sqm | 1 + 7 files changed, 19 insertions(+), 18 deletions(-) rename core/database/src/commonMain/sqldelight/com/divinelink/core/database/person/{PersonEntity.sq => PersonDetailsEntity.sq} (93%) create mode 100644 core/database/src/commonMain/sqldelight/migrations/8.sqm diff --git a/core/data/src/commonMain/kotlin/com/divinelink/core/data/person/details/mapper/PersonDetailsApiToEntityMapper.kt b/core/data/src/commonMain/kotlin/com/divinelink/core/data/person/details/mapper/PersonDetailsApiToEntityMapper.kt index e73772ce1..c4fddcd6e 100644 --- a/core/data/src/commonMain/kotlin/com/divinelink/core/data/person/details/mapper/PersonDetailsApiToEntityMapper.kt +++ b/core/data/src/commonMain/kotlin/com/divinelink/core/data/person/details/mapper/PersonDetailsApiToEntityMapper.kt @@ -1,9 +1,9 @@ package com.divinelink.core.data.person.details.mapper -import com.divinelink.core.database.person.PersonEntity +import com.divinelink.core.database.person.PersonDetailsEntity import com.divinelink.core.network.details.person.model.PersonDetailsApi -fun PersonDetailsApi.mapToEntity(timestamp: String) = PersonEntity( +fun PersonDetailsApi.mapToEntity(timestamp: String) = PersonDetailsEntity( id = id, biography = biography, birthday = birthday, diff --git a/core/data/src/commonMain/kotlin/com/divinelink/core/data/person/details/mapper/PersonDetailsEntityMapper.kt b/core/data/src/commonMain/kotlin/com/divinelink/core/data/person/details/mapper/PersonDetailsEntityMapper.kt index e291961c9..f8eee4c32 100644 --- a/core/data/src/commonMain/kotlin/com/divinelink/core/data/person/details/mapper/PersonDetailsEntityMapper.kt +++ b/core/data/src/commonMain/kotlin/com/divinelink/core/data/person/details/mapper/PersonDetailsEntityMapper.kt @@ -1,12 +1,12 @@ package com.divinelink.core.data.person.details.mapper -import com.divinelink.core.database.person.PersonEntity +import com.divinelink.core.database.person.PersonDetailsEntity import com.divinelink.core.model.credits.PersonRole import com.divinelink.core.model.details.Person import com.divinelink.core.model.details.person.PersonDetails import com.divinelink.core.model.person.Gender -fun PersonEntity.map() = PersonDetails( +fun PersonDetailsEntity.map() = PersonDetails( person = Person( id = id, name = name, diff --git a/core/database/build.gradle.kts b/core/database/build.gradle.kts index aa1a1848a..b7a279646 100644 --- a/core/database/build.gradle.kts +++ b/core/database/build.gradle.kts @@ -29,7 +29,7 @@ sqldelight { create("Database") { packageName.set("com.divinelink.core.database") migrationOutputDirectory.set(file("src/main/sqldelight/migrations")) - version = 7 + version = 8 } } } diff --git a/core/database/src/commonMain/kotlin/com/divinelink/core/database/person/PersonDao.kt b/core/database/src/commonMain/kotlin/com/divinelink/core/database/person/PersonDao.kt index ccce51ef7..a6b0ceac4 100644 --- a/core/database/src/commonMain/kotlin/com/divinelink/core/database/person/PersonDao.kt +++ b/core/database/src/commonMain/kotlin/com/divinelink/core/database/person/PersonDao.kt @@ -7,9 +7,9 @@ import kotlinx.coroutines.flow.Flow interface PersonDao { - fun fetchPersonById(id: Long): Flow + fun fetchPersonById(id: Long): Flow - fun insertPerson(person: PersonEntity): QueryResult + fun insertPerson(person: PersonDetailsEntity): QueryResult fun updatePerson( biography: String? = null, diff --git a/core/database/src/commonMain/kotlin/com/divinelink/core/database/person/ProdPersonDao.kt b/core/database/src/commonMain/kotlin/com/divinelink/core/database/person/ProdPersonDao.kt index d342316ec..126b05b14 100644 --- a/core/database/src/commonMain/kotlin/com/divinelink/core/database/person/ProdPersonDao.kt +++ b/core/database/src/commonMain/kotlin/com/divinelink/core/database/person/ProdPersonDao.kt @@ -21,14 +21,14 @@ class ProdPersonDao( private val dispatcher: DispatcherProvider, ) : PersonDao { - override fun fetchPersonById(id: Long): Flow = database - .personEntityQueries + override fun fetchPersonById(id: Long): Flow = database + .personDetailsEntityQueries .fetchPersonById(id) .asFlow() .mapToOneOrNull(context = dispatcher.io) - override fun insertPerson(person: PersonEntity) = database - .personEntityQueries + override fun insertPerson(person: PersonDetailsEntity) = database + .personDetailsEntityQueries .insertPerson(person) override fun updatePerson( @@ -45,7 +45,7 @@ class ProdPersonDao( insertedAt: String?, id: Long, ) = database - .personEntityQueries + .personDetailsEntityQueries .updatePerson( biography = biography, name = name, @@ -64,7 +64,7 @@ class ProdPersonDao( override fun deleteFromPerson( id: Long, field: PersonChangeField, - ) = database.personEntityQueries.deleteFromPerson( + ) = database.personDetailsEntityQueries.deleteFromPerson( biography = field == PersonChangeField.BIOGRAPHY, name = field == PersonChangeField.NAME, birthday = field == PersonChangeField.BIRTHDAY, diff --git a/core/database/src/commonMain/sqldelight/com/divinelink/core/database/person/PersonEntity.sq b/core/database/src/commonMain/sqldelight/com/divinelink/core/database/person/PersonDetailsEntity.sq similarity index 93% rename from core/database/src/commonMain/sqldelight/com/divinelink/core/database/person/PersonEntity.sq rename to core/database/src/commonMain/sqldelight/com/divinelink/core/database/person/PersonDetailsEntity.sq index 7135b3d38..ef4591a78 100644 --- a/core/database/src/commonMain/sqldelight/com/divinelink/core/database/person/PersonEntity.sq +++ b/core/database/src/commonMain/sqldelight/com/divinelink/core/database/person/PersonDetailsEntity.sq @@ -1,4 +1,4 @@ -CREATE TABLE PersonEntity ( +CREATE TABLE PersonDetailsEntity ( id INTEGER NOT NULL PRIMARY KEY, biography TEXT, birthday TEXT, @@ -15,7 +15,7 @@ CREATE TABLE PersonEntity ( ); insertPerson: -INSERT OR REPLACE INTO PersonEntity( +INSERT OR REPLACE INTO PersonDetailsEntity( id, biography, birthday, @@ -33,7 +33,7 @@ INSERT OR REPLACE INTO PersonEntity( VALUES ?; updatePerson: -UPDATE PersonEntity +UPDATE PersonDetailsEntity SET biography = CASE WHEN :biography IS NOT NULL THEN :biography ELSE biography END, name = CASE WHEN :name IS NOT NULL THEN :name ELSE name END, @@ -49,7 +49,7 @@ SET WHERE id = :id; deleteFromPerson: -UPDATE PersonEntity +UPDATE PersonDetailsEntity SET biography = CASE WHEN :biography THEN NULL ELSE biography END, name = CASE WHEN :name THEN "" ELSE name END, @@ -66,5 +66,5 @@ WHERE id = :id; fetchPersonById: SELECT * -FROM PersonEntity +FROM PersonDetailsEntity WHERE id = ?; diff --git a/core/database/src/commonMain/sqldelight/migrations/8.sqm b/core/database/src/commonMain/sqldelight/migrations/8.sqm new file mode 100644 index 000000000..725e6f278 --- /dev/null +++ b/core/database/src/commonMain/sqldelight/migrations/8.sqm @@ -0,0 +1 @@ +ALTER TABLE PersonEntity RENAME TO PersonDetailsEntity; From 473dd1d3b313eea5c785f9ba21f1d47ff7929754 Mon Sep 17 00:00:00 2001 From: Harry Andreolas Date: Sun, 1 Feb 2026 18:11:11 +0200 Subject: [PATCH 2/3] feat: update and clean up series cast database schema --- .../person/ProdPersonRepositoryTest.kt | 8 +- .../mapper/AggregateCreditsEntityMapper.kt | 27 ++- .../api/AggregateCreditsApiToEntityMapper.kt | 22 +-- .../details/mapper/entity/CastEntityMapper.kt | 23 --- .../details/mapper/entity/CrewEntityMapper.kt | 37 ---- .../repository/ProdDetailsRepository.kt | 12 +- .../credits/dao/ProdCreditsDaoTest.kt | 166 +++++++++++------- .../database/person/dao/ProdPersonDaoTest.kt | 14 +- .../core/database/credits/dao/CreditsDao.kt | 16 +- .../database/credits/dao/ProdCreditsDao.kt | 61 ++++--- .../credits/mapper/SeriesCastMapper.kt | 14 +- .../credits/mapper/SeriesCrewMapper.kt | 19 +- .../credits/model/AggregateCreditsEntity.kt | 6 +- .../core/database/credits/model/CastEntity.kt | 13 -- .../core/database/credits/model/CrewEntity.kt | 14 -- .../core/database/cast/PersonEntity.sq | 20 +++ .../core/database/cast/PersonRoleEntity.sq | 9 + .../core/database/credits/ShowCastRole.sq | 17 ++ .../core/database/credits/cast/SeriesCast.sq | 29 --- .../database/credits/cast/SeriesCastRole.sq | 17 -- .../domain/change/person/ChangeHandlerTest.kt | 4 +- .../fixtures/details/person/PersonFactory.kt | 49 +++++- .../mapper/PersonCreditsApiMapperTest.kt | 4 +- .../mapper/PersonDetailsApiMapperTest.kt | 6 +- .../credits/cast/SeriesCastFactory.kt | 34 ---- .../credits/cast/SeriesCastRoleFactory.kt | 28 --- .../credits/AggregateCreditsEntityFactory.kt | 8 +- .../entity/credits/CastEntityFactory.kt | 48 ----- .../entity/credits/CrewEntityFactory.kt | 95 ---------- .../person/PersonDetailsEntityFactory.kt | 40 +++++ .../entity/person/PersonEntityFactory.kt | 48 ++--- .../entity/person/PersonRoleEntityFactory.kt | 18 ++ .../person/ShowCastRoleEntityFactory.kt | 20 +++ 33 files changed, 433 insertions(+), 513 deletions(-) delete mode 100644 core/data/src/commonMain/kotlin/com/divinelink/core/data/details/mapper/entity/CastEntityMapper.kt delete mode 100644 core/data/src/commonMain/kotlin/com/divinelink/core/data/details/mapper/entity/CrewEntityMapper.kt delete mode 100644 core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/model/CastEntity.kt delete mode 100644 core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/model/CrewEntity.kt create mode 100644 core/database/src/commonMain/sqldelight/com/divinelink/core/database/cast/PersonEntity.sq create mode 100644 core/database/src/commonMain/sqldelight/com/divinelink/core/database/cast/PersonRoleEntity.sq create mode 100644 core/database/src/commonMain/sqldelight/com/divinelink/core/database/credits/ShowCastRole.sq delete mode 100644 core/database/src/commonMain/sqldelight/com/divinelink/core/database/credits/cast/SeriesCast.sq delete mode 100644 core/database/src/commonMain/sqldelight/com/divinelink/core/database/credits/cast/SeriesCastRole.sq delete mode 100644 core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/database/credits/cast/SeriesCastFactory.kt delete mode 100644 core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/database/credits/cast/SeriesCastRoleFactory.kt delete mode 100644 core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/entity/credits/CastEntityFactory.kt delete mode 100644 core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/entity/credits/CrewEntityFactory.kt create mode 100644 core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/entity/person/PersonDetailsEntityFactory.kt create mode 100644 core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/entity/person/PersonRoleEntityFactory.kt create mode 100644 core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/entity/person/ShowCastRoleEntityFactory.kt diff --git a/core/data/src/androidHostTest/kotlin/com/divinelink/core/data/details/person/ProdPersonRepositoryTest.kt b/core/data/src/androidHostTest/kotlin/com/divinelink/core/data/details/person/ProdPersonRepositoryTest.kt index 2758fccf1..9bc1cf3c9 100644 --- a/core/data/src/androidHostTest/kotlin/com/divinelink/core/data/details/person/ProdPersonRepositoryTest.kt +++ b/core/data/src/androidHostTest/kotlin/com/divinelink/core/data/details/person/ProdPersonRepositoryTest.kt @@ -25,7 +25,7 @@ import com.divinelink.core.network.media.model.changes.ChangesParameters import com.divinelink.core.testing.MainDispatcherRule import com.divinelink.core.testing.database.TestDatabaseFactory import com.divinelink.core.testing.factories.api.details.person.PersonDetailsApiFactory -import com.divinelink.core.testing.factories.entity.person.PersonEntityFactory +import com.divinelink.core.testing.factories.entity.person.PersonDetailsEntityFactory import com.divinelink.core.testing.factories.entity.person.credits.PersonCastCreditEntityFactory import com.divinelink.core.testing.factories.entity.person.credits.PersonCrewCreditEntityFactory import com.divinelink.core.testing.factories.model.change.ChangeSample @@ -78,10 +78,10 @@ class ProdPersonRepositoryTest { @Test fun `test fetchPersonDetails with local data only fetches from database`() = runTest { - dao.insertPerson(PersonEntityFactory.steveCarell()) + dao.insertPerson(PersonDetailsEntityFactory.steveCarell()) repository.fetchPersonDetails(id = 4495).test { - assertThat(awaitItem().getOrNull()).isEqualTo(PersonEntityFactory.steveCarell().map()) + assertThat(awaitItem().getOrNull()).isEqualTo(PersonDetailsEntityFactory.steveCarell().map()) expectNoEvents() } } @@ -91,7 +91,7 @@ class ProdPersonRepositoryTest { service.mockFetchPersonDetails(response = PersonDetailsApiFactory.steveCarell()) repository.fetchPersonDetails(id = 4495).test { - assertThat(awaitItem().getOrNull()).isEqualTo(PersonEntityFactory.steveCarell().map()) + assertThat(awaitItem().getOrNull()).isEqualTo(PersonDetailsEntityFactory.steveCarell().map()) expectNoEvents() } } diff --git a/core/data/src/commonMain/kotlin/com/divinelink/core/data/details/mapper/AggregateCreditsEntityMapper.kt b/core/data/src/commonMain/kotlin/com/divinelink/core/data/details/mapper/AggregateCreditsEntityMapper.kt index fdcf10992..57c0d80c9 100644 --- a/core/data/src/commonMain/kotlin/com/divinelink/core/data/details/mapper/AggregateCreditsEntityMapper.kt +++ b/core/data/src/commonMain/kotlin/com/divinelink/core/data/details/mapper/AggregateCreditsEntityMapper.kt @@ -1,11 +1,34 @@ package com.divinelink.core.data.details.mapper -import com.divinelink.core.data.details.mapper.entity.map import com.divinelink.core.database.credits.model.AggregateCreditsEntity import com.divinelink.core.model.credits.AggregateCredits +import com.divinelink.core.model.credits.PersonRole +import com.divinelink.core.model.credits.SeriesCrewDepartment +import com.divinelink.core.model.details.Person fun AggregateCreditsEntity.map() = AggregateCredits( - cast = cast.map(), + cast = cast, crewDepartments = crew.map(), id = id, ) + +/** + * Maps every crew department to its persons. + */ +fun List.map(): List = this + .flatMap { person -> + person.role + .filterIsInstance() + .map { crewRole -> person to crewRole } + } + .groupBy( + keySelector = { (_, crewRole) -> crewRole.department }, + valueTransform = { (person, _) -> person }, + ) + .mapNotNull { (department, people) -> + if (department == null) { + null + } else { + SeriesCrewDepartment(department, people) + } + } diff --git a/core/data/src/commonMain/kotlin/com/divinelink/core/data/details/mapper/api/AggregateCreditsApiToEntityMapper.kt b/core/data/src/commonMain/kotlin/com/divinelink/core/data/details/mapper/api/AggregateCreditsApiToEntityMapper.kt index 92a48dff9..271dab837 100644 --- a/core/data/src/commonMain/kotlin/com/divinelink/core/data/details/mapper/api/AggregateCreditsApiToEntityMapper.kt +++ b/core/data/src/commonMain/kotlin/com/divinelink/core/data/details/mapper/api/AggregateCreditsApiToEntityMapper.kt @@ -1,34 +1,36 @@ package com.divinelink.core.data.details.mapper.api -import com.divinelink.core.database.credits.cast.SeriesCast -import com.divinelink.core.database.credits.cast.SeriesCastRole +import com.divinelink.core.database.cast.PersonEntity +import com.divinelink.core.database.cast.PersonRoleEntity +import com.divinelink.core.database.credits.ShowCastRoleEntity import com.divinelink.core.database.credits.crew.SeriesCrew import com.divinelink.core.database.credits.crew.SeriesCrewJob import com.divinelink.core.network.media.model.credits.AggregateCreditsApi -fun AggregateCreditsApi.toSeriesCastEntity() = cast.map { cast -> - SeriesCast( +fun AggregateCreditsApi.toPersonsEntity() = cast.map { cast -> + PersonEntity( id = cast.id, name = cast.name, profilePath = cast.profilePath, originalName = cast.name, - totalEpisodeCount = cast.totalEpisodeCount.toLong(), knownForDepartment = cast.knownForDepartment, gender = cast.gender, - aggregateCreditId = id, ) } -fun AggregateCreditsApi.toSeriesCastRoleEntity() = cast +fun AggregateCreditsApi.toRolesEntity(): List> = cast .filter { it.roles.isNotEmpty() } .flatMap { cast -> cast.roles.map { role -> - SeriesCastRole( - aggregateCreditId = id, + PersonRoleEntity( creditId = role.creditId, character = role.character, - episodeCount = role.episodeCount.toLong(), castId = cast.id, + ) to ShowCastRoleEntity( + showId = id, + creditId = role.creditId, + episodeCount = role.episodeCount.toLong(), + creditOrder = cast.order.toLong(), ) } } diff --git a/core/data/src/commonMain/kotlin/com/divinelink/core/data/details/mapper/entity/CastEntityMapper.kt b/core/data/src/commonMain/kotlin/com/divinelink/core/data/details/mapper/entity/CastEntityMapper.kt deleted file mode 100644 index 3df993b51..000000000 --- a/core/data/src/commonMain/kotlin/com/divinelink/core/data/details/mapper/entity/CastEntityMapper.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.divinelink.core.data.details.mapper.entity - -import com.divinelink.core.database.credits.model.CastEntity -import com.divinelink.core.model.credits.PersonRole -import com.divinelink.core.model.details.Person -import com.divinelink.core.model.person.Gender - -fun List.map() = map { it.map() } - -fun CastEntity.map() = Person( - id = id, - name = name, - profilePath = profilePath, - knownForDepartment = knownForDepartment, - gender = Gender.from(gender.toInt()), - role = roles.map { - PersonRole.SeriesActor( - character = it.character, - totalEpisodes = it.episodeCount?.toInt(), - creditId = it.creditId, - ) - }, -) diff --git a/core/data/src/commonMain/kotlin/com/divinelink/core/data/details/mapper/entity/CrewEntityMapper.kt b/core/data/src/commonMain/kotlin/com/divinelink/core/data/details/mapper/entity/CrewEntityMapper.kt deleted file mode 100644 index 302921c0e..000000000 --- a/core/data/src/commonMain/kotlin/com/divinelink/core/data/details/mapper/entity/CrewEntityMapper.kt +++ /dev/null @@ -1,37 +0,0 @@ -package com.divinelink.core.data.details.mapper.entity - -import com.divinelink.core.database.credits.model.CrewEntity -import com.divinelink.core.model.credits.PersonRole -import com.divinelink.core.model.credits.SeriesCrewDepartment -import com.divinelink.core.model.details.Person -import com.divinelink.core.model.person.Gender - -fun List.map(): List { - val crewList = mutableListOf() - val departments = this.map { it.department }.distinct() - - departments.forEach { department -> - val crew = this.filter { it.department == department }.map { - it.map() - } - crewList.add(SeriesCrewDepartment(department, crew)) - } - - return crewList -} - -fun CrewEntity.map() = Person( - id = id, - name = name, - profilePath = profilePath, - knownForDepartment = knownForDepartment, - gender = Gender.from(gender.toInt()), - role = roles.map { - PersonRole.Crew( - job = it.job, - creditId = it.creditId, - totalEpisodes = it.episodeCount, - department = department, - ) - }, -) diff --git a/core/data/src/commonMain/kotlin/com/divinelink/core/data/details/repository/ProdDetailsRepository.kt b/core/data/src/commonMain/kotlin/com/divinelink/core/data/details/repository/ProdDetailsRepository.kt index 842fd7913..6feb7e526 100644 --- a/core/data/src/commonMain/kotlin/com/divinelink/core/data/details/repository/ProdDetailsRepository.kt +++ b/core/data/src/commonMain/kotlin/com/divinelink/core/data/details/repository/ProdDetailsRepository.kt @@ -3,8 +3,8 @@ package com.divinelink.core.data.details.repository import com.divinelink.core.commons.domain.DispatcherProvider import com.divinelink.core.data.details.mapper.api.map import com.divinelink.core.data.details.mapper.api.reviews.map -import com.divinelink.core.data.details.mapper.api.toSeriesCastEntity -import com.divinelink.core.data.details.mapper.api.toSeriesCastRoleEntity +import com.divinelink.core.data.details.mapper.api.toPersonsEntity +import com.divinelink.core.data.details.mapper.api.toRolesEntity import com.divinelink.core.data.details.mapper.api.toSeriesCrewEntity import com.divinelink.core.data.details.mapper.api.toSeriesCrewJobEntity import com.divinelink.core.data.details.mapper.map @@ -212,10 +212,10 @@ class ProdDetailsRepository( } }.flowOn(dispatcher.io) - private suspend fun insertLocalAggregateCredits(aggregateCredits: AggregateCreditsApi) { + private fun insertLocalAggregateCredits(aggregateCredits: AggregateCreditsApi) { creditsDao.insertAggregateCredits(aggregateCredits.id) - creditsDao.insertCastRoles(aggregateCredits.toSeriesCastRoleEntity()) - creditsDao.insertCast(aggregateCredits.toSeriesCastEntity()) + creditsDao.insertPersons(aggregateCredits.toPersonsEntity()) + creditsDao.insertRoles(aggregateCredits.toRolesEntity()) creditsDao.insertCrewJobs(aggregateCredits.toSeriesCrewJobEntity()) creditsDao.insertCrew(aggregateCredits.toSeriesCrewEntity()) } @@ -226,7 +226,7 @@ class ProdDetailsRepository( Result.success(localCredits.map()) } - private suspend fun fetchRemoteAggregateCredits(id: Long): Flow> = + private fun fetchRemoteAggregateCredits(id: Long): Flow> = mediaRemote.fetchAggregatedCredits(id) .onEach { apiResponse -> val duration = measureTime { diff --git a/core/database/src/androidHostTest/kotlin/com/divinelink/core/database/credits/dao/ProdCreditsDaoTest.kt b/core/database/src/androidHostTest/kotlin/com/divinelink/core/database/credits/dao/ProdCreditsDaoTest.kt index 297f48c9f..b4adbe237 100644 --- a/core/database/src/androidHostTest/kotlin/com/divinelink/core/database/credits/dao/ProdCreditsDaoTest.kt +++ b/core/database/src/androidHostTest/kotlin/com/divinelink/core/database/credits/dao/ProdCreditsDaoTest.kt @@ -2,23 +2,24 @@ package com.divinelink.core.database.credits.dao import app.cash.turbine.test import com.divinelink.core.database.Database -import com.divinelink.core.database.credits.cast.SeriesCast -import com.divinelink.core.database.credits.cast.SeriesCastRole import com.divinelink.core.database.credits.crew.SeriesCrew import com.divinelink.core.database.credits.crew.SeriesCrewJob -import com.divinelink.core.database.credits.model.CrewEntity import com.divinelink.core.fixtures.core.commons.ClockFactory +import com.divinelink.core.fixtures.details.person.PersonFactory +import com.divinelink.core.model.credits.PersonRole +import com.divinelink.core.model.details.Person +import com.divinelink.core.model.person.Gender import com.divinelink.core.testing.MainDispatcherRule import com.divinelink.core.testing.database.TestDatabaseFactory import com.divinelink.core.testing.factories.database.credits.AggregateCreditsFactory -import com.divinelink.core.testing.factories.database.credits.cast.SeriesCastFactory -import com.divinelink.core.testing.factories.database.credits.cast.SeriesCastRoleFactory import com.divinelink.core.testing.factories.database.credits.crew.SeriesCrewFactory import com.divinelink.core.testing.factories.database.credits.crew.SeriesCrewJobFactory import com.divinelink.core.testing.factories.entity.credits.AggregateCreditsEntityFactory -import com.divinelink.core.testing.factories.entity.credits.CastEntityFactory -import com.divinelink.core.testing.factories.entity.credits.CrewEntityFactory +import com.divinelink.core.testing.factories.entity.person.PersonEntityFactory +import com.divinelink.core.testing.factories.entity.person.PersonRoleEntityFactory +import com.divinelink.core.testing.factories.entity.person.ShowCastRoleEntityFactory import com.google.common.truth.Truth.assertThat +import io.kotest.matchers.shouldBe import kotlinx.coroutines.flow.first import kotlinx.coroutines.test.runTest import org.junit.Before @@ -131,23 +132,29 @@ class ProdCreditsDaoTest { fun `test fetchAllCastWithRoles with empty roles does not bring any data`() = runTest { dao.insertAggregateCredits(1) - dao.insertCast(cast = SeriesCastFactory.allCast()) + dao.insertPersons(PersonEntityFactory.officeCast) val result = dao.fetchAllCastWithRoles(id = 1).first() - assertThat(result).isEqualTo(emptyList()) + result shouldBe emptyList() } @Test fun `test fetchAllCastWithRoles with roles does successfully gets cast`() = runTest { dao.insertAggregateCredits(AggregateCreditsFactory.theOffice().id) - dao.insertCast(SeriesCastFactory.allCast()) - dao.insertCastRoles(listOf(SeriesCastRoleFactory.kevinMalone())) + dao.insertPersons(PersonEntityFactory.officeCast) + dao.insertRoles( + listOf( + PersonRoleEntityFactory.kevinMalone to ShowCastRoleEntityFactory.kevinMalone, + ), + ) val result = dao.fetchAllCastWithRoles(id = 2316).first() - assertThat(result).isEqualTo(listOf(CastEntityFactory.brianBaumgartner())) + result shouldBe listOf( + PersonFactory.SeriesActor.brianBaumgartner, + ) } @Test @@ -174,15 +181,20 @@ class ProdCreditsDaoTest { aggregateCreditId = AggregateCreditsFactory.theOffice().id, ).first() - assertThat(result).isEqualTo(CrewEntityFactory.cameraDepartment()) + assertThat(result).isEqualTo(PersonFactory.cameraDepartment()) } @Test fun `test fetchAllCredits successfully fetches all credits`() = runTest { dao.insertAggregateCredits(AggregateCreditsFactory.theOffice().id) - dao.insertCast(SeriesCastFactory.allCast()) - dao.insertCastRoles(SeriesCastRoleFactory.allCastRoles()) + dao.insertPersons(PersonEntityFactory.officeCast) + dao.insertRoles( + listOf( + PersonRoleEntityFactory.kevinMalone to ShowCastRoleEntityFactory.kevinMalone, + PersonRoleEntityFactory.angelaMartin to ShowCastRoleEntityFactory.angelaMartin, + ), + ) dao.insertCrew(SeriesCrewFactory.cameraDepartment()) dao.insertCrewJobs(SeriesCrewJobFactory.allCrewJobs()) @@ -196,8 +208,13 @@ class ProdCreditsDaoTest { fun `test fetchAllCredits with invalid crew job id does not bring crew`() = runTest { dao.insertAggregateCredits(AggregateCreditsFactory.theOffice().id) - dao.insertCast(SeriesCastFactory.allCast()) - dao.insertCastRoles(SeriesCastRoleFactory.allCastRoles()) + dao.insertPersons(PersonEntityFactory.officeCast) + dao.insertRoles( + listOf( + PersonRoleEntityFactory.kevinMalone to ShowCastRoleEntityFactory.kevinMalone, + PersonRoleEntityFactory.angelaMartin to ShowCastRoleEntityFactory.angelaMartin, + ), + ) dao.insertCrew(SeriesCrewFactory.cameraDepartment()) @@ -212,8 +229,12 @@ class ProdCreditsDaoTest { fun `test fetchAllCredits with partial valid cast`() = runTest { dao.insertAggregateCredits(AggregateCreditsFactory.theOffice().id) - dao.insertCast(SeriesCastFactory.allCast()) - dao.insertCastRoles(listOf(SeriesCastRoleFactory.kevinMalone())) + dao.insertPersons(PersonEntityFactory.officeCast) + dao.insertRoles( + listOf( + PersonRoleEntityFactory.kevinMalone to ShowCastRoleEntityFactory.kevinMalone, + ), + ) dao.insertCrew(SeriesCrewFactory.cameraDepartment()) @@ -223,7 +244,7 @@ class ProdCreditsDaoTest { AggregateCreditsEntityFactory .theOffice() .copy( - cast = listOf(CastEntityFactory.brianBaumgartner()), + cast = listOf(PersonFactory.SeriesActor.brianBaumgartner), crew = emptyList(), ), ) @@ -233,8 +254,13 @@ class ProdCreditsDaoTest { fun `test fetchAllCredits with partial valid crew`() = runTest { dao.insertAggregateCredits(AggregateCreditsFactory.theOffice().id) - dao.insertCast(SeriesCastFactory.allCast()) - dao.insertCastRoles(SeriesCastRoleFactory.allCastRoles()) + dao.insertPersons(PersonEntityFactory.officeCast) + dao.insertRoles( + listOf( + PersonRoleEntityFactory.kevinMalone to ShowCastRoleEntityFactory.kevinMalone, + PersonRoleEntityFactory.angelaMartin to ShowCastRoleEntityFactory.angelaMartin, + ), + ) dao.insertCrew(SeriesCrewFactory.cameraDepartment()) dao.insertCrewJobs( @@ -250,8 +276,11 @@ class ProdCreditsDaoTest { AggregateCreditsEntityFactory .theOffice() .copy( - cast = CastEntityFactory.allCast(), - crew = listOf(CrewEntityFactory.daleAlexander(), CrewEntityFactory.randallEinhorn()), + cast = PersonFactory.officeCast, + crew = listOf( + PersonFactory.Camera.daleAlexander(), + PersonFactory.Camera.randallEinhorn(), + ), ), ) } @@ -274,30 +303,34 @@ class ProdCreditsDaoTest { fun `test fetchCast does not bring data with null character`() = runTest { dao.insertAggregateCredits(AggregateCreditsFactory.theOffice().id) - dao.insertCast(SeriesCastFactory.allCast()) - dao.insertCastRoles( - listOf(SeriesCastRoleFactory.kevinMalone()), + dao.insertPersons(PersonEntityFactory.officeCast) + dao.insertRoles( + listOf( + PersonRoleEntityFactory.kevinMalone to ShowCastRoleEntityFactory.kevinMalone, + ), ) val result = dao.fetchAllCastWithRoles(id = AggregateCreditsFactory.theOffice().id).first() - assertThat(result).isEqualTo(listOf((CastEntityFactory.brianBaumgartner()))) + assertThat(result).isEqualTo(listOf((PersonFactory.SeriesActor.brianBaumgartner))) } @Test fun `test fetchCast for actors with multiple roles`() = runTest { dao.insertAggregateCredits(AggregateCreditsFactory.theOffice().id) - dao.insertCast(SeriesCastFactory.allCast()) - dao.insertCastRoles( + dao.insertPersons(PersonEntityFactory.officeCast) + dao.insertRoles( listOf( - SeriesCastRoleFactory.kevinMalone(), - SeriesCastRole( + PersonRoleEntityFactory.kevinMalone to ShowCastRoleEntityFactory.kevinMalone, + PersonRoleEntityFactory.kevinMalone.copy( creditId = "Some Credit Id", character = "Some Character", + ) to ShowCastRoleEntityFactory.kevinMalone.copy( + showId = 2316, + creditId = "Some Credit Id", episodeCount = 3, - castId = 94622, - aggregateCreditId = AggregateCreditsFactory.theOffice().id, + creditOrder = 216, ), ), ) @@ -306,15 +339,17 @@ class ProdCreditsDaoTest { assertThat(result).isEqualTo( listOf( - CastEntityFactory.brianBaumgartner().copy( - roles = listOf( - SeriesCastRoleFactory.kevinMalone(), - SeriesCastRole( + PersonFactory.SeriesActor.brianBaumgartner.copy( + role = listOf( + PersonRole.SeriesActor( + character = "Kevin Malone", + creditId = "525730a9760ee3776a3447f1", + totalEpisodes = 217, + ), + PersonRole.SeriesActor( creditId = "Some Credit Id", character = "Some Character", - episodeCount = 3, - castId = 94622, - aggregateCreditId = AggregateCreditsFactory.theOffice().id, + totalEpisodes = 3, ), ), ), @@ -345,16 +380,19 @@ class ProdCreditsDaoTest { assertThat(result).isEqualTo( listOf( - CrewEntityFactory.daleAlexander().copy( - roles = listOf( - SeriesCrewJobFactory.daleAlexander(), - SeriesCrewJob( + PersonFactory.Camera.daleAlexander().copy( + role = listOf( + PersonRole.Crew( + job = "Key Grip", + creditId = "5bdaa7d90e0a2603c60086d9", + totalEpisodes = 3, + department = "Camera", + ), + PersonRole.Crew( creditId = "5bdaa7d90e0a", job = "Key Grip 2", - episodeCount = 4, - crewId = 1879373, + totalEpisodes = 4, department = "Camera", - aggregateCreditId = AggregateCreditsFactory.theOffice().id, ), ), ), @@ -408,28 +446,36 @@ class ProdCreditsDaoTest { assertThat(result).isEqualTo( listOf( - CrewEntityFactory.daleAlexander().copy( - roles = listOf( - SeriesCrewJobFactory.daleAlexander(), - SeriesCrewJob( + PersonFactory.Camera.daleAlexander().copy( + role = listOf( + PersonRole.Crew( + job = "Key Grip", + creditId = "5bdaa7d90e0a2603c60086d9", + totalEpisodes = 3, + department = "Camera", + ), + PersonRole.Crew( creditId = "5bdaa7d90e0a", job = "Key Grip 2", - episodeCount = 4, - crewId = 1879373, + totalEpisodes = 4, department = "Camera", - aggregateCreditId = AggregateCreditsFactory.theOffice().id, ), ), ), - CrewEntity( + Person( id = 1879373, name = "Dale Alexander", - originalName = "Dale Alexander", profilePath = null, - department = "Production", + gender = Gender.NOT_SET, knownForDepartment = "Camera", - gender = 0, - roles = listOf(daleAlexanderWritingJob), + role = listOf( + PersonRole.Crew( + creditId = "5bda7d90e0a56bcas", + job = "Writer", + totalEpisodes = 3, + department = "Production", + ), + ), ), ), ) diff --git a/core/database/src/androidHostTest/kotlin/com/divinelink/core/database/person/dao/ProdPersonDaoTest.kt b/core/database/src/androidHostTest/kotlin/com/divinelink/core/database/person/dao/ProdPersonDaoTest.kt index 4050d5333..26d94fd2b 100644 --- a/core/database/src/androidHostTest/kotlin/com/divinelink/core/database/person/dao/ProdPersonDaoTest.kt +++ b/core/database/src/androidHostTest/kotlin/com/divinelink/core/database/person/dao/ProdPersonDaoTest.kt @@ -10,7 +10,7 @@ import com.divinelink.core.fixtures.core.commons.ClockFactory import com.divinelink.core.fixtures.model.media.MediaItemFactory import com.divinelink.core.testing.MainDispatcherRule import com.divinelink.core.testing.database.TestDatabaseFactory -import com.divinelink.core.testing.factories.entity.person.PersonEntityFactory +import com.divinelink.core.testing.factories.entity.person.PersonDetailsEntityFactory import com.divinelink.core.testing.factories.entity.person.credits.CastCreditsWithMediaFactory import com.divinelink.core.testing.factories.entity.person.credits.CrewCreditsWithMediaFactory import com.divinelink.core.testing.factories.entity.person.credits.PersonCastCreditEntityFactory @@ -46,7 +46,7 @@ class ProdPersonDaoTest { @Test fun `test fetch person by id`() = runTest { - val person = PersonEntityFactory.steveCarell() + val person = PersonDetailsEntityFactory.steveCarell() dao.insertPerson(person) @@ -58,7 +58,7 @@ class ProdPersonDaoTest { @Test fun `test inserting existing person replaces the person`() = runTest { - val person = PersonEntityFactory.steveCarell() + val person = PersonDetailsEntityFactory.steveCarell() dao.insertPerson(person) @@ -76,7 +76,7 @@ class ProdPersonDaoTest { @Test fun `test fetch person combined credits by id without initial credits`() = runTest { - val person = PersonEntityFactory.steveCarell() + val person = PersonDetailsEntityFactory.steveCarell() val cast = PersonCastCreditEntityFactory.despicableMe() val crew = PersonCrewCreditEntityFactory.riot() @@ -107,7 +107,7 @@ class ProdPersonDaoTest { @Test fun `test fetch person combined credits by id without initial credits and inserted media`() = runTest { - val person = PersonEntityFactory.steveCarell() + val person = PersonDetailsEntityFactory.steveCarell() val cast = PersonCastCreditEntityFactory.despicableMe() val crew = PersonCrewCreditEntityFactory.riot() @@ -133,7 +133,7 @@ class ProdPersonDaoTest { @Test fun `test fetch person combined credits are sorted by date`() = runTest { - val person = PersonEntityFactory.steveCarell() + val person = PersonDetailsEntityFactory.steveCarell() val cast = PersonCastCreditEntityFactory.all() val crew = PersonCrewCreditEntityFactory.all() @@ -163,7 +163,7 @@ class ProdPersonDaoTest { @Test fun `test fetch person combined credits without inserted media returns empty`() = runTest { - val person = PersonEntityFactory.steveCarell() + val person = PersonDetailsEntityFactory.steveCarell() val cast = PersonCastCreditEntityFactory.all() val crew = PersonCrewCreditEntityFactory.all() diff --git a/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/dao/CreditsDao.kt b/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/dao/CreditsDao.kt index 19416eda6..310923b42 100644 --- a/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/dao/CreditsDao.kt +++ b/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/dao/CreditsDao.kt @@ -1,12 +1,12 @@ package com.divinelink.core.database.credits.dao -import com.divinelink.core.database.credits.cast.SeriesCast -import com.divinelink.core.database.credits.cast.SeriesCastRole +import com.divinelink.core.database.cast.PersonEntity +import com.divinelink.core.database.cast.PersonRoleEntity +import com.divinelink.core.database.credits.ShowCastRoleEntity import com.divinelink.core.database.credits.crew.SeriesCrew import com.divinelink.core.database.credits.crew.SeriesCrewJob import com.divinelink.core.database.credits.model.AggregateCreditsEntity -import com.divinelink.core.database.credits.model.CastEntity -import com.divinelink.core.database.credits.model.CrewEntity +import com.divinelink.core.model.details.Person import kotlinx.coroutines.flow.Flow interface CreditsDao { @@ -16,13 +16,13 @@ interface CreditsDao { fun insertAggregateCredits(aggregateCreditsId: Long) - fun insertCast(cast: List) - fun insertCastRoles(roles: List) + fun insertPersons(persons: List) + fun insertRoles(roles: List>) - fun fetchAllCastWithRoles(id: Long): Flow> + fun fetchAllCastWithRoles(id: Long): Flow> fun insertCrew(crew: List) fun insertCrewJobs(jobs: List) - fun fetchAllCrewJobs(aggregateCreditId: Long): Flow> + fun fetchAllCrewJobs(aggregateCreditId: Long): Flow> } diff --git a/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/dao/ProdCreditsDao.kt b/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/dao/ProdCreditsDao.kt index b9574bc01..cccead7a0 100644 --- a/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/dao/ProdCreditsDao.kt +++ b/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/dao/ProdCreditsDao.kt @@ -6,16 +6,17 @@ import app.cash.sqldelight.coroutines.mapToOneOrDefault import com.divinelink.core.commons.domain.DispatcherProvider import com.divinelink.core.database.Database import com.divinelink.core.database.cacheExpiresAtToEpochSeconds +import com.divinelink.core.database.cast.PersonEntity +import com.divinelink.core.database.cast.PersonRoleEntity import com.divinelink.core.database.credits.AggregateCredits -import com.divinelink.core.database.credits.cast.SeriesCast -import com.divinelink.core.database.credits.cast.SeriesCastRole +import com.divinelink.core.database.credits.ShowCastRoleEntity import com.divinelink.core.database.credits.crew.SeriesCrew import com.divinelink.core.database.credits.crew.SeriesCrewJob -import com.divinelink.core.database.credits.mapper.toEntity +import com.divinelink.core.database.credits.mapper.toPerson import com.divinelink.core.database.credits.model.AggregateCreditsEntity -import com.divinelink.core.database.credits.model.CastEntity -import com.divinelink.core.database.credits.model.CrewEntity import com.divinelink.core.database.currentEpochSeconds +import com.divinelink.core.model.credits.PersonRole +import com.divinelink.core.model.details.Person import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.map @@ -53,12 +54,20 @@ class ProdCreditsDao( ) } - override fun insertCast(cast: List) = database.transaction { - cast.forEach { castMember -> - database.seriesCastQueries.insertSeriesCast(castMember) + override fun insertPersons(persons: List) = database.transaction { + persons.forEach { person -> + database.personEntityQueries.insertPerson(person) } } + override fun insertRoles(roles: List>) = + database.transaction { + roles.forEach { role -> + database.personRoleEntityQueries.insertRole(role.first) + database.showCastRoleQueries.insertShowCastRole(role.second) + } + } + override fun fetchAllCredits(id: Long): Flow { val cast = fetchAllCastWithRoles(id) val crew = fetchAllCrewJobs(id) @@ -72,31 +81,35 @@ class ProdCreditsDao( } } - override fun insertCastRoles(roles: List) = database.transaction { - roles.forEach { role -> - database.seriesCastRoleQueries.insertRole(seriesCastRole = role) - } - } - - override fun fetchAllCastWithRoles(id: Long): Flow> = database + override fun fetchAllCastWithRoles(id: Long): Flow> = database .transactionWithResult { - val rolesByCastId = database.seriesCastRoleQueries - .fetchRoles(aggregateCreditId = id) + val rolesByCastId = database + .showCastRoleQueries + .fetchCastRoles(showId = id) .executeAsList() .groupBy { it.castId } database - .seriesCastQueries - .fetchSeriesCast(id) + .personEntityQueries + .fetchShowCast(id) .asFlow() .mapToList(dispatcher.io) .map { listOfCast -> listOfCast .map { cast -> val roles = rolesByCastId[cast.id] ?: emptyList() - cast.toEntity(roles = roles) + cast.toPerson( + roles = roles.map { + PersonRole.SeriesActor( + character = it.character, + creditId = it.creditId, + totalEpisodes = it.episodeCount.toInt(), + ) + }, + ) } - .filter { it.roles.isNotEmpty() } + .filter { it.role.isNotEmpty() } + .distinctBy { it.id } } } @@ -112,7 +125,7 @@ class ProdCreditsDao( } } - override fun fetchAllCrewJobs(aggregateCreditId: Long): Flow> = + override fun fetchAllCrewJobs(aggregateCreditId: Long): Flow> = database.transactionWithResult { val crewJobs = database.seriesCrewJobQueries .fetchCrewJobs(aggregateCreditId) @@ -128,9 +141,9 @@ class ProdCreditsDao( listOfCrew .map { crew -> val jobs = crewJobs[Pair(crew.id, crew.department)] ?: emptyList() - crew.toEntity(roles = jobs) + crew.toPerson(roles = jobs) } - .filter { it.roles.isNotEmpty() } + .filter { it.role.isNotEmpty() } } } } diff --git a/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/mapper/SeriesCastMapper.kt b/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/mapper/SeriesCastMapper.kt index 6d60cdec7..078167e0d 100644 --- a/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/mapper/SeriesCastMapper.kt +++ b/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/mapper/SeriesCastMapper.kt @@ -1,15 +1,15 @@ package com.divinelink.core.database.credits.mapper -import com.divinelink.core.database.credits.cast.SeriesCast -import com.divinelink.core.database.credits.cast.SeriesCastRole -import com.divinelink.core.database.credits.model.CastEntity +import com.divinelink.core.database.cast.FetchShowCast +import com.divinelink.core.model.credits.PersonRole +import com.divinelink.core.model.details.Person +import com.divinelink.core.model.person.Gender -fun SeriesCast.toEntity(roles: List): CastEntity = CastEntity( +fun FetchShowCast.toPerson(roles: List): Person = Person( id = id, name = name, - originalName = originalName, profilePath = profilePath, knownForDepartment = knownForDepartment, - gender = gender, - roles = roles, + gender = Gender.from(gender.toInt()), + role = roles, ) diff --git a/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/mapper/SeriesCrewMapper.kt b/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/mapper/SeriesCrewMapper.kt index 2721a2254..651a5091d 100644 --- a/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/mapper/SeriesCrewMapper.kt +++ b/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/mapper/SeriesCrewMapper.kt @@ -2,15 +2,22 @@ package com.divinelink.core.database.credits.mapper import com.divinelink.core.database.credits.crew.SeriesCrew import com.divinelink.core.database.credits.crew.SeriesCrewJob -import com.divinelink.core.database.credits.model.CrewEntity +import com.divinelink.core.model.credits.PersonRole +import com.divinelink.core.model.details.Person +import com.divinelink.core.model.person.Gender -fun SeriesCrew.toEntity(roles: List) = CrewEntity( +fun SeriesCrew.toPerson(roles: List) = Person( id = id, name = name, - originalName = originalName, profilePath = profilePath, - department = department, knownForDepartment = knownForDepartment, - gender = gender, - roles = roles, + gender = Gender.from(gender.toInt()), + role = roles.map { role -> + PersonRole.Crew( + job = role.job, + creditId = role.creditId, + totalEpisodes = role.episodeCount, + department = department, + ) + }, ) diff --git a/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/model/AggregateCreditsEntity.kt b/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/model/AggregateCreditsEntity.kt index 8757842eb..171793e2a 100644 --- a/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/model/AggregateCreditsEntity.kt +++ b/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/model/AggregateCreditsEntity.kt @@ -1,7 +1,9 @@ package com.divinelink.core.database.credits.model +import com.divinelink.core.model.details.Person + data class AggregateCreditsEntity( val id: Long, - val crew: List, - val cast: List, + val crew: List, + val cast: List, ) diff --git a/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/model/CastEntity.kt b/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/model/CastEntity.kt deleted file mode 100644 index b3f2d6312..000000000 --- a/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/model/CastEntity.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.divinelink.core.database.credits.model - -import com.divinelink.core.database.credits.cast.SeriesCastRole - -data class CastEntity( - val id: Long, - val name: String, - val originalName: String, - val profilePath: String?, - val knownForDepartment: String?, - val gender: Long, - val roles: List, -) diff --git a/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/model/CrewEntity.kt b/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/model/CrewEntity.kt deleted file mode 100644 index e5fa3dde4..000000000 --- a/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/model/CrewEntity.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.divinelink.core.database.credits.model - -import com.divinelink.core.database.credits.crew.SeriesCrewJob - -data class CrewEntity( - val id: Long, - val name: String, - val originalName: String, - val profilePath: String?, - val department: String, - val gender: Long, - val knownForDepartment: String?, - val roles: List, -) diff --git a/core/database/src/commonMain/sqldelight/com/divinelink/core/database/cast/PersonEntity.sq b/core/database/src/commonMain/sqldelight/com/divinelink/core/database/cast/PersonEntity.sq new file mode 100644 index 000000000..031f4cd6c --- /dev/null +++ b/core/database/src/commonMain/sqldelight/com/divinelink/core/database/cast/PersonEntity.sq @@ -0,0 +1,20 @@ +CREATE TABLE PersonEntity( + id INTEGER PRIMARY KEY NOT NULL, + name TEXT NOT NULL, + originalName TEXT NOT NULL, + profilePath TEXT, + knownForDepartment TEXT, + gender INTEGER NOT NULL +); + +insertPerson: +INSERT OR REPLACE INTO PersonEntity(id, name, originalName, profilePath, knownForDepartment, gender) +VALUES ?; + +fetchShowCast: +SELECT person.*, role.creditId, role.character, creditRole.episodeCount, creditRole.creditOrder +FROM PersonEntity person +JOIN PersonRoleEntity role ON person.id = role.castId +JOIN ShowCastRoleEntity creditRole ON role.creditId = creditRole.creditId +WHERE creditRole.showId = :showId +ORDER BY creditRole.episodeCount DESC, creditOrder ASC; \ No newline at end of file diff --git a/core/database/src/commonMain/sqldelight/com/divinelink/core/database/cast/PersonRoleEntity.sq b/core/database/src/commonMain/sqldelight/com/divinelink/core/database/cast/PersonRoleEntity.sq new file mode 100644 index 000000000..eca2787d1 --- /dev/null +++ b/core/database/src/commonMain/sqldelight/com/divinelink/core/database/cast/PersonRoleEntity.sq @@ -0,0 +1,9 @@ +CREATE TABLE PersonRoleEntity( + creditId TEXT PRIMARY KEY NOT NULL, + character TEXT NOT NULL, + castId INTEGER NOT NULL REFERENCES PersonEntity(id) +); + +insertRole: +INSERT OR REPLACE INTO PersonRoleEntity(creditId, character, castId) +VALUES ?; diff --git a/core/database/src/commonMain/sqldelight/com/divinelink/core/database/credits/ShowCastRole.sq b/core/database/src/commonMain/sqldelight/com/divinelink/core/database/credits/ShowCastRole.sq new file mode 100644 index 000000000..fee716aaa --- /dev/null +++ b/core/database/src/commonMain/sqldelight/com/divinelink/core/database/credits/ShowCastRole.sq @@ -0,0 +1,17 @@ +CREATE TABLE ShowCastRoleEntity( + showId INTEGER NOT NULL, + creditId TEXT NOT NULL REFERENCES PersonRoleEntity(creditId), + episodeCount INTEGER NOT NULL, + creditOrder INTEGER NOT NULL, + PRIMARY KEY (showId, creditId) +); + +insertShowCastRole: +INSERT OR REPLACE INTO ShowCastRoleEntity(showId, creditId, episodeCount, creditOrder) +VALUES ?; + +fetchCastRoles: +SELECT role.*, creditRole.episodeCount +FROM PersonRoleEntity role +JOIN ShowCastRoleEntity creditRole ON role.creditId = creditRole.creditId +WHERE creditRole.showId = :showId; \ No newline at end of file diff --git a/core/database/src/commonMain/sqldelight/com/divinelink/core/database/credits/cast/SeriesCast.sq b/core/database/src/commonMain/sqldelight/com/divinelink/core/database/credits/cast/SeriesCast.sq deleted file mode 100644 index 6371345c2..000000000 --- a/core/database/src/commonMain/sqldelight/com/divinelink/core/database/credits/cast/SeriesCast.sq +++ /dev/null @@ -1,29 +0,0 @@ -CREATE TABLE seriesCast( - id INTEGER NOT NULL, - name TEXT NOT NULL, - originalName TEXT NOT NULL, - profilePath TEXT, - totalEpisodeCount INTEGER NOT NULL, - knownForDepartment TEXT, - gender INTEGER NOT NULL, - aggregateCreditId INTEGER NOT NULL REFERENCES aggregateCredits(id), - PRIMARY KEY (id, aggregateCreditId) -); - -insertSeriesCast: -INSERT OR REPLACE INTO seriesCast( - id, - name, - originalName, - profilePath, - totalEpisodeCount, - knownForDepartment, - gender, - aggregateCreditId -) -VALUES ?; - -fetchSeriesCast: -SELECT * -FROM seriesCast -WHERE aggregateCreditId = ?; \ No newline at end of file diff --git a/core/database/src/commonMain/sqldelight/com/divinelink/core/database/credits/cast/SeriesCastRole.sq b/core/database/src/commonMain/sqldelight/com/divinelink/core/database/credits/cast/SeriesCastRole.sq deleted file mode 100644 index 5b70e339c..000000000 --- a/core/database/src/commonMain/sqldelight/com/divinelink/core/database/credits/cast/SeriesCastRole.sq +++ /dev/null @@ -1,17 +0,0 @@ -CREATE TABLE seriesCastRole( - creditId TEXT PRIMARY KEY, - character TEXT NOT NULL, - episodeCount INTEGER, - castId INTEGER NOT NULL, - aggregateCreditId INTEGER NOT NULL, - FOREIGN KEY (castId, aggregateCreditId) REFERENCES seriesCast(id, aggregateCreditId) -); - -insertRole: -INSERT OR REPLACE INTO seriesCastRole(creditId, character, episodeCount, castId, aggregateCreditId) -VALUES ?; - -fetchRoles: -SELECT * -FROM seriesCastRole -WHERE aggregateCreditId = :aggregateCreditId; diff --git a/core/domain/src/androidHostTest/kotlin/com/divinelink/core/domain/change/person/ChangeHandlerTest.kt b/core/domain/src/androidHostTest/kotlin/com/divinelink/core/domain/change/person/ChangeHandlerTest.kt index fbaa7b556..27661b0fe 100644 --- a/core/domain/src/androidHostTest/kotlin/com/divinelink/core/domain/change/person/ChangeHandlerTest.kt +++ b/core/domain/src/androidHostTest/kotlin/com/divinelink/core/domain/change/person/ChangeHandlerTest.kt @@ -12,7 +12,7 @@ import com.divinelink.core.model.person.Gender import com.divinelink.core.testing.MainDispatcherRule import com.divinelink.core.testing.dao.TestMediaDao import com.divinelink.core.testing.database.TestDatabaseFactory -import com.divinelink.core.testing.factories.entity.person.PersonEntityFactory +import com.divinelink.core.testing.factories.entity.person.PersonDetailsEntityFactory import com.divinelink.core.testing.factories.model.change.PersonChangeItemSample import com.divinelink.core.testing.factories.model.change.PersonChangeItemSample.toWizard import com.divinelink.core.testing.service.TestPersonService @@ -49,7 +49,7 @@ class ChangeHandlerTest { dispatcher = testDispatcher, ) mediaDao = TestMediaDao() - dao.insertPerson(PersonEntityFactory.empty()) + dao.insertPerson(PersonDetailsEntityFactory.empty()) repository = ProdPersonRepository( service = TestPersonService().mock, diff --git a/core/fixtures/src/commonMain/kotlin/com/divinelink/core/fixtures/details/person/PersonFactory.kt b/core/fixtures/src/commonMain/kotlin/com/divinelink/core/fixtures/details/person/PersonFactory.kt index ed55a3575..e6a23c624 100644 --- a/core/fixtures/src/commonMain/kotlin/com/divinelink/core/fixtures/details/person/PersonFactory.kt +++ b/core/fixtures/src/commonMain/kotlin/com/divinelink/core/fixtures/details/person/PersonFactory.kt @@ -1,13 +1,48 @@ package com.divinelink.core.fixtures.details.person +import com.divinelink.core.fixtures.details.person.PersonFactory.Camera.daleAlexander +import com.divinelink.core.fixtures.details.person.PersonFactory.Camera.peterSmokler +import com.divinelink.core.fixtures.details.person.PersonFactory.Camera.randallEinhorn +import com.divinelink.core.fixtures.details.person.PersonFactory.Camera.ronNichols import com.divinelink.core.model.credits.PersonRole import com.divinelink.core.model.details.Person import com.divinelink.core.model.person.Gender object PersonFactory { - object Camera { + object SeriesActor { + val brianBaumgartner = Person( + id = 94622, + name = "Brian Baumgartner", + profilePath = "/1O7ECkD4mOKAgMAbQADBpTKBzOP.jpg", + gender = Gender.MALE, + knownForDepartment = "Acting", + role = listOf( + PersonRole.SeriesActor( + character = "Kevin Malone", + creditId = "525730a9760ee3776a3447f1", + totalEpisodes = 217, + ), + ), + ) + val angelaKinsey = Person( + id = 113867, + name = "Angela Kinsey", + profilePath = "/qHFidnMcFqUWdMFyjmXufBlYckd.jpg", + knownForDepartment = "Acting", + gender = Gender.FEMALE, + role = listOf( + PersonRole.SeriesActor( + character = "Angela Martin", + creditId = "525730ab760ee3776a344a0b", + totalEpisodes = 210, + ), + ), + ) + } + + object Camera { fun randallEinhorn() = Person( id = 1215572, name = "Randall Einhorn", @@ -137,4 +172,16 @@ object PersonFactory { ), ) } + + val officeCast = listOf( + SeriesActor.brianBaumgartner, + SeriesActor.angelaKinsey, + ) + + fun cameraDepartment() = listOf( + daleAlexander(), + peterSmokler(), + randallEinhorn(), + ronNichols(), + ) } diff --git a/core/network/src/androidHostTest/kotlin/com/divinelink/core/network/details/person/mapper/PersonCreditsApiMapperTest.kt b/core/network/src/androidHostTest/kotlin/com/divinelink/core/network/details/person/mapper/PersonCreditsApiMapperTest.kt index 1c38f345a..b11efe0fe 100644 --- a/core/network/src/androidHostTest/kotlin/com/divinelink/core/network/details/person/mapper/PersonCreditsApiMapperTest.kt +++ b/core/network/src/androidHostTest/kotlin/com/divinelink/core/network/details/person/mapper/PersonCreditsApiMapperTest.kt @@ -7,7 +7,7 @@ import com.divinelink.core.data.person.details.mapper.mapToEntity import com.divinelink.core.network.client.localJson import com.divinelink.core.network.details.person.model.PersonCreditsApi import com.divinelink.core.network.details.person.model.PersonDetailsApi -import com.divinelink.core.testing.factories.entity.person.PersonEntityFactory +import com.divinelink.core.testing.factories.entity.person.PersonDetailsEntityFactory import com.divinelink.core.testing.factories.entity.person.credits.PersonCastCreditEntityFactory import com.divinelink.core.testing.factories.entity.person.credits.PersonCrewCreditEntityFactory import com.google.common.truth.Truth.assertThat @@ -42,6 +42,6 @@ class PersonCreditsApiMapperTest { val mappedToEntity = personDetailsApi.mapToEntity("1628995200") - assertThat(mappedToEntity).isEqualTo(PersonEntityFactory.steveCarell()) + assertThat(mappedToEntity).isEqualTo(PersonDetailsEntityFactory.steveCarell()) } } diff --git a/core/network/src/androidHostTest/kotlin/com/divinelink/core/network/details/person/mapper/PersonDetailsApiMapperTest.kt b/core/network/src/androidHostTest/kotlin/com/divinelink/core/network/details/person/mapper/PersonDetailsApiMapperTest.kt index d24443dc5..7c4b56769 100644 --- a/core/network/src/androidHostTest/kotlin/com/divinelink/core/network/details/person/mapper/PersonDetailsApiMapperTest.kt +++ b/core/network/src/androidHostTest/kotlin/com/divinelink/core/network/details/person/mapper/PersonDetailsApiMapperTest.kt @@ -6,7 +6,7 @@ import com.divinelink.core.data.person.details.mapper.mapToEntity import com.divinelink.core.fixtures.details.person.PersonDetailsFactory import com.divinelink.core.network.client.localJson import com.divinelink.core.network.details.person.model.PersonDetailsApi -import com.divinelink.core.testing.factories.entity.person.PersonEntityFactory +import com.divinelink.core.testing.factories.entity.person.PersonDetailsEntityFactory import com.google.common.truth.Truth.assertThat import kotlin.test.Test @@ -21,7 +21,7 @@ class PersonDetailsApiMapperTest { val mappedToEntity = personDetailsApi.mapToEntity("1628995200") val domain = mappedToEntity.map() - assertThat(mappedToEntity).isEqualTo(PersonEntityFactory.steveCarell()) + assertThat(mappedToEntity).isEqualTo(PersonDetailsEntityFactory.steveCarell()) assertThat(domain).isEqualTo(PersonDetailsFactory.steveCarell().copy(alsoKnownAs = emptyList())) } @@ -36,6 +36,6 @@ class PersonDetailsApiMapperTest { val mappedToEntity = personDetailsApi.mapToEntity("1628995200") - assertThat(mappedToEntity).isEqualTo(PersonEntityFactory.steveCarell()) + assertThat(mappedToEntity).isEqualTo(PersonDetailsEntityFactory.steveCarell()) } } diff --git a/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/database/credits/cast/SeriesCastFactory.kt b/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/database/credits/cast/SeriesCastFactory.kt deleted file mode 100644 index 54ab167de..000000000 --- a/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/database/credits/cast/SeriesCastFactory.kt +++ /dev/null @@ -1,34 +0,0 @@ -package com.divinelink.core.testing.factories.database.credits.cast - -import com.divinelink.core.database.credits.cast.SeriesCast -import com.divinelink.core.testing.factories.database.credits.AggregateCreditsFactory - -object SeriesCastFactory { - - fun brianBaumgartner() = SeriesCast( - id = 94622, - name = "Brian Baumgartner", - originalName = "Brian Baumgartner", - profilePath = "/1O7ECkD4mOKAgMAbQADBpTKBzOP.jpg", - totalEpisodeCount = 217, - knownForDepartment = "Acting", - gender = 2, - aggregateCreditId = AggregateCreditsFactory.theOffice().id, - ) - - fun angelaKinsey() = SeriesCast( - id = 113867, - name = "Angela Kinsey", - originalName = "Angela Kinsey", - profilePath = "/qHFidnMcFqUWdMFyjmXufBlYckd.jpg", - totalEpisodeCount = 210, - knownForDepartment = "Acting", - gender = 1, - aggregateCreditId = AggregateCreditsFactory.theOffice().id, - ) - - fun allCast() = listOf( - brianBaumgartner(), - angelaKinsey(), - ) -} diff --git a/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/database/credits/cast/SeriesCastRoleFactory.kt b/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/database/credits/cast/SeriesCastRoleFactory.kt deleted file mode 100644 index 78a5a43cb..000000000 --- a/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/database/credits/cast/SeriesCastRoleFactory.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.divinelink.core.testing.factories.database.credits.cast - -import com.divinelink.core.database.credits.cast.SeriesCastRole -import com.divinelink.core.testing.factories.database.credits.AggregateCreditsFactory - -object SeriesCastRoleFactory { - - fun kevinMalone() = SeriesCastRole( - castId = 94622, - creditId = "525730a9760ee3776a3447f1", - character = "Kevin Malone", - episodeCount = 217, - aggregateCreditId = AggregateCreditsFactory.theOffice().id, - ) - - fun angelaMartin() = SeriesCastRole( - castId = 113867, - creditId = "525730ab760ee3776a344a0b", - character = "Angela Martin", - episodeCount = 210, - aggregateCreditId = AggregateCreditsFactory.theOffice().id, - ) - - fun allCastRoles() = listOf( - kevinMalone(), - angelaMartin(), - ) -} diff --git a/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/entity/credits/AggregateCreditsEntityFactory.kt b/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/entity/credits/AggregateCreditsEntityFactory.kt index c73db8ee1..2c7cc46c9 100644 --- a/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/entity/credits/AggregateCreditsEntityFactory.kt +++ b/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/entity/credits/AggregateCreditsEntityFactory.kt @@ -1,13 +1,17 @@ package com.divinelink.core.testing.factories.entity.credits import com.divinelink.core.database.credits.model.AggregateCreditsEntity +import com.divinelink.core.fixtures.details.person.PersonFactory import com.divinelink.core.testing.factories.database.credits.AggregateCreditsFactory object AggregateCreditsEntityFactory { fun theOffice() = AggregateCreditsEntity( id = AggregateCreditsFactory.theOffice().id, - cast = CastEntityFactory.allCast(), - crew = CrewEntityFactory.cameraDepartment(), + cast = listOf( + PersonFactory.SeriesActor.brianBaumgartner, + PersonFactory.SeriesActor.angelaKinsey, + ), + crew = PersonFactory.cameraDepartment(), ) } diff --git a/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/entity/credits/CastEntityFactory.kt b/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/entity/credits/CastEntityFactory.kt deleted file mode 100644 index 6d2509a4d..000000000 --- a/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/entity/credits/CastEntityFactory.kt +++ /dev/null @@ -1,48 +0,0 @@ -package com.divinelink.core.testing.factories.entity.credits - -import com.divinelink.core.database.credits.cast.SeriesCastRole -import com.divinelink.core.database.credits.model.CastEntity - -object CastEntityFactory { - - fun brianBaumgartner() = CastEntity( - id = 94622, - name = "Brian Baumgartner", - originalName = "Brian Baumgartner", - profilePath = "/1O7ECkD4mOKAgMAbQADBpTKBzOP.jpg", - gender = 2, - knownForDepartment = "Acting", - roles = listOf( - SeriesCastRole( - character = "Kevin Malone", - creditId = "525730a9760ee3776a3447f1", - episodeCount = 217, - castId = 94622, - aggregateCreditId = 2316, - ), - ), - ) - - fun angelaKinsey() = CastEntity( - id = 113867, - name = "Angela Kinsey", - originalName = "Angela Kinsey", - profilePath = "/qHFidnMcFqUWdMFyjmXufBlYckd.jpg", - knownForDepartment = "Acting", - gender = 1, - roles = listOf( - SeriesCastRole( - character = "Angela Martin", - creditId = "525730ab760ee3776a344a0b", - episodeCount = 210, - castId = 113867, - aggregateCreditId = 2316, - ), - ), - ) - - fun allCast() = listOf( - brianBaumgartner(), - angelaKinsey(), - ) -} diff --git a/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/entity/credits/CrewEntityFactory.kt b/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/entity/credits/CrewEntityFactory.kt deleted file mode 100644 index 355d3969f..000000000 --- a/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/entity/credits/CrewEntityFactory.kt +++ /dev/null @@ -1,95 +0,0 @@ -package com.divinelink.core.testing.factories.entity.credits - -import com.divinelink.core.database.credits.crew.SeriesCrewJob -import com.divinelink.core.database.credits.model.CrewEntity -import com.divinelink.core.testing.factories.database.credits.AggregateCreditsFactory - -object CrewEntityFactory { - - fun randallEinhorn() = CrewEntity( - id = 1215572, - name = "Randall Einhorn", - originalName = "Randall Einhorn", - profilePath = null, - department = "Camera", - gender = 2, - knownForDepartment = "Directing", - roles = listOf( - SeriesCrewJob( - creditId = "5bdaa68f92514153f500859f", - job = "Director of Photography", - episodeCount = 3, - crewId = 1215572, - department = "Camera", - aggregateCreditId = AggregateCreditsFactory.theOffice().id, - ), - ), - ) - - fun daleAlexander() = CrewEntity( - id = 1879373, - name = "Dale Alexander", - originalName = "Dale Alexander", - profilePath = null, - department = "Camera", - knownForDepartment = "Camera", - gender = 0, - roles = listOf( - SeriesCrewJob( - creditId = "5bdaa7d90e0a2603c60086d9", - job = "Key Grip", - episodeCount = 3, - crewId = 1879373, - department = "Camera", - aggregateCreditId = AggregateCreditsFactory.theOffice().id, - ), - ), - ) - - fun ronNichols() = CrewEntity( - id = 2166021, - name = "Ron Nichols", - originalName = "Ron Nichols", - profilePath = null, - department = "Camera", - knownForDepartment = "Camera", - gender = 0, - roles = listOf( - SeriesCrewJob( - creditId = "5bdaa3e40e0a2603b1008d3f", - job = "Key Grip", - episodeCount = 1, - crewId = 2166021, - department = "Camera", - aggregateCreditId = AggregateCreditsFactory.theOffice().id, - ), - ), - ) - - fun peterSmokler() = CrewEntity( - id = 67864, - name = "Peter Smokler", - originalName = "Peter Smokler", - profilePath = null, - department = "Camera", - knownForDepartment = "Camera", - gender = 2, - roles = listOf( - SeriesCrewJob( - creditId = "5bdaa2d4c3a368078f007f5c", - job = "Director of Photography", - episodeCount = 1, - crewId = 67864, - department = "Camera", - aggregateCreditId = AggregateCreditsFactory.theOffice().id, - ), - ), - ) - - fun cameraDepartment() = listOf( - daleAlexander(), - peterSmokler(), - randallEinhorn(), - ronNichols(), - ) -} diff --git a/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/entity/person/PersonDetailsEntityFactory.kt b/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/entity/person/PersonDetailsEntityFactory.kt new file mode 100644 index 000000000..ee67c17bb --- /dev/null +++ b/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/entity/person/PersonDetailsEntityFactory.kt @@ -0,0 +1,40 @@ +package com.divinelink.core.testing.factories.entity.person + +import com.divinelink.core.database.person.PersonDetailsEntity +import com.divinelink.core.fixtures.details.person.PersonDetailsFactory +import com.divinelink.core.model.person.Gender + +object PersonDetailsEntityFactory { + + fun empty() = PersonDetailsEntity( + id = 4495, + biography = null, + birthday = null, + deathday = null, + gender = Gender.NOT_SET.value.toLong(), + homepage = null, + imdbId = null, + knownForDepartment = null, + name = "", + placeOfBirth = null, + popularity = 0.0, + profilePath = null, + insertedAt = "1628995200", + ) + + fun steveCarell(): PersonDetailsEntity = PersonDetailsEntity( + id = 4495, + biography = PersonDetailsFactory.BIOGRAPHY, + birthday = "1962-08-16", + deathday = null, + gender = 2, + homepage = null, + imdbId = "nm0136797", + knownForDepartment = "Acting", + name = "Steve Carell", + placeOfBirth = "Concord, Massachusetts, USA", + popularity = 77.108, + profilePath = "/dzJtsLspH5Bf8Tvw7OQC47ETNfJ.jpg", + insertedAt = "1628995200", // GMT: Sunday, 15 August 2021 02:40:00 + ) +} diff --git a/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/entity/person/PersonEntityFactory.kt b/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/entity/person/PersonEntityFactory.kt index 8e38d288a..073efc72a 100644 --- a/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/entity/person/PersonEntityFactory.kt +++ b/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/entity/person/PersonEntityFactory.kt @@ -1,40 +1,30 @@ package com.divinelink.core.testing.factories.entity.person -import com.divinelink.core.database.person.PersonEntity -import com.divinelink.core.fixtures.details.person.PersonDetailsFactory +import com.divinelink.core.database.cast.PersonEntity import com.divinelink.core.model.person.Gender object PersonEntityFactory { - fun empty() = PersonEntity( - id = 4495, - biography = null, - birthday = null, - deathday = null, - gender = Gender.NOT_SET.value.toLong(), - homepage = null, - imdbId = null, - knownForDepartment = null, - name = "", - placeOfBirth = null, - popularity = 0.0, - profilePath = null, - insertedAt = "1628995200", + val brianBaumgartner = PersonEntity( + id = 94622, + name = "Brian Baumgartner", + originalName = "Brian Baumgartner", + profilePath = "/1O7ECkD4mOKAgMAbQADBpTKBzOP.jpg", + gender = Gender.MALE.value.toLong(), + knownForDepartment = "Acting", ) - fun steveCarell(): PersonEntity = PersonEntity( - id = 4495, - biography = PersonDetailsFactory.BIOGRAPHY, - birthday = "1962-08-16", - deathday = null, - gender = 2, - homepage = null, - imdbId = "nm0136797", + val angelaKinsey = PersonEntity( + id = 113867, + name = "Angela Kinsey", + originalName = "Angela Kinsey", + profilePath = "/qHFidnMcFqUWdMFyjmXufBlYckd.jpg", knownForDepartment = "Acting", - name = "Steve Carell", - placeOfBirth = "Concord, Massachusetts, USA", - popularity = 77.108, - profilePath = "/dzJtsLspH5Bf8Tvw7OQC47ETNfJ.jpg", - insertedAt = "1628995200", // GMT: Sunday, 15 August 2021 02:40:00 + gender = Gender.FEMALE.value.toLong(), + ) + + val officeCast = listOf( + brianBaumgartner, + angelaKinsey, ) } diff --git a/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/entity/person/PersonRoleEntityFactory.kt b/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/entity/person/PersonRoleEntityFactory.kt new file mode 100644 index 000000000..a28c59187 --- /dev/null +++ b/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/entity/person/PersonRoleEntityFactory.kt @@ -0,0 +1,18 @@ +package com.divinelink.core.testing.factories.entity.person + +import com.divinelink.core.database.cast.PersonRoleEntity + +object PersonRoleEntityFactory { + + val kevinMalone = PersonRoleEntity( + character = "Kevin Malone", + creditId = "525730a9760ee3776a3447f1", + castId = 94622, + ) + + val angelaMartin = PersonRoleEntity( + character = "Angela Martin", + creditId = "525730ab760ee3776a344a0b", + castId = 113867, + ) +} diff --git a/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/entity/person/ShowCastRoleEntityFactory.kt b/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/entity/person/ShowCastRoleEntityFactory.kt new file mode 100644 index 000000000..39e63e9a4 --- /dev/null +++ b/core/testing/src/commonMain/kotlin/com/divinelink/core/testing/factories/entity/person/ShowCastRoleEntityFactory.kt @@ -0,0 +1,20 @@ +package com.divinelink.core.testing.factories.entity.person + +import com.divinelink.core.database.credits.ShowCastRoleEntity + +object ShowCastRoleEntityFactory { + + val kevinMalone = ShowCastRoleEntity( + showId = 2316, + creditId = "525730a9760ee3776a3447f1", + episodeCount = 217, + creditOrder = 16, + ) + + val angelaMartin = ShowCastRoleEntity( + showId = 2316, + creditId = "525730ab760ee3776a344a0b", + episodeCount = 210, + creditOrder = 20, + ) +} From d37e858e4d562ddffd679d68db160f1ca47db6c4 Mon Sep 17 00:00:00 2001 From: Harry Andreolas Date: Sun, 1 Feb 2026 18:28:49 +0200 Subject: [PATCH 3/3] fix: migrations after schema updates --- .../database/credits/dao/ProdCreditsDao.kt | 4 +-- ...{ShowCastRole.sq => ShowCastRoleEntity.sq} | 0 .../commonMain/sqldelight/migrations/8.sqm | 28 +++++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) rename core/database/src/commonMain/sqldelight/com/divinelink/core/database/credits/{ShowCastRole.sq => ShowCastRoleEntity.sq} (100%) diff --git a/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/dao/ProdCreditsDao.kt b/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/dao/ProdCreditsDao.kt index cccead7a0..3812a38af 100644 --- a/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/dao/ProdCreditsDao.kt +++ b/core/database/src/commonMain/kotlin/com/divinelink/core/database/credits/dao/ProdCreditsDao.kt @@ -64,7 +64,7 @@ class ProdCreditsDao( database.transaction { roles.forEach { role -> database.personRoleEntityQueries.insertRole(role.first) - database.showCastRoleQueries.insertShowCastRole(role.second) + database.showCastRoleEntityQueries.insertShowCastRole(role.second) } } @@ -84,7 +84,7 @@ class ProdCreditsDao( override fun fetchAllCastWithRoles(id: Long): Flow> = database .transactionWithResult { val rolesByCastId = database - .showCastRoleQueries + .showCastRoleEntityQueries .fetchCastRoles(showId = id) .executeAsList() .groupBy { it.castId } diff --git a/core/database/src/commonMain/sqldelight/com/divinelink/core/database/credits/ShowCastRole.sq b/core/database/src/commonMain/sqldelight/com/divinelink/core/database/credits/ShowCastRoleEntity.sq similarity index 100% rename from core/database/src/commonMain/sqldelight/com/divinelink/core/database/credits/ShowCastRole.sq rename to core/database/src/commonMain/sqldelight/com/divinelink/core/database/credits/ShowCastRoleEntity.sq diff --git a/core/database/src/commonMain/sqldelight/migrations/8.sqm b/core/database/src/commonMain/sqldelight/migrations/8.sqm index 725e6f278..4903d5844 100644 --- a/core/database/src/commonMain/sqldelight/migrations/8.sqm +++ b/core/database/src/commonMain/sqldelight/migrations/8.sqm @@ -1 +1,29 @@ ALTER TABLE PersonEntity RENAME TO PersonDetailsEntity; + +DROP TABLE seriesCast; +DROP TABLE seriesCastRole; + +DELETE FROM aggregateCredits; + +CREATE TABLE PersonRoleEntity( + creditId TEXT PRIMARY KEY NOT NULL, + character TEXT NOT NULL, + castId INTEGER NOT NULL REFERENCES PersonEntity(id) +); + +CREATE TABLE PersonEntity( + id INTEGER PRIMARY KEY NOT NULL, + name TEXT NOT NULL, + originalName TEXT NOT NULL, + profilePath TEXT, + knownForDepartment TEXT, + gender INTEGER NOT NULL +); + +CREATE TABLE ShowCastRoleEntity( + showId INTEGER NOT NULL, + creditId TEXT NOT NULL REFERENCES PersonRoleEntity(creditId), + episodeCount INTEGER NOT NULL, + creditOrder INTEGER NOT NULL, + PRIMARY KEY (showId, creditId) +); \ No newline at end of file