From 6b2884724f364b57b9b38fcf064dfac803d1302e Mon Sep 17 00:00:00 2001 From: mutukuian Date: Mon, 13 May 2024 13:11:08 +0300 Subject: [PATCH] implement navigation feature --- .../data/local_data_source/ShipDao.kt | 15 +++++++ .../data/local_data_source/ShipDatabase.kt | 9 ++++ .../data/local_data_source/ShipEntity.kt | 32 ++++++++++++++ .../data/remote/dto/ShipDto.kt | 44 ++++++++++++------- .../data/repository/ShipRepositoryImpl.kt | 25 +++++++++-- .../kocelainterview/domain/model/Ship.kt | 7 --- .../use_case/get_ships/GetShipsUseCaseTest.kt | 1 - 7 files changed, 106 insertions(+), 27 deletions(-) create mode 100644 app/src/main/java/com/example/kocelainterview/data/local_data_source/ShipDao.kt create mode 100644 app/src/main/java/com/example/kocelainterview/data/local_data_source/ShipDatabase.kt create mode 100644 app/src/main/java/com/example/kocelainterview/data/local_data_source/ShipEntity.kt diff --git a/app/src/main/java/com/example/kocelainterview/data/local_data_source/ShipDao.kt b/app/src/main/java/com/example/kocelainterview/data/local_data_source/ShipDao.kt new file mode 100644 index 0000000..739b012 --- /dev/null +++ b/app/src/main/java/com/example/kocelainterview/data/local_data_source/ShipDao.kt @@ -0,0 +1,15 @@ +package com.example.kocelainterview.data.local_data_source + +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query + +@Dao +interface ShipDao { + @Query("SELECT * FROM ships") + fun getShips(): List + + @Insert(onConflict = OnConflictStrategy.REPLACE) + fun saveShips(ships: List) +} \ No newline at end of file diff --git a/app/src/main/java/com/example/kocelainterview/data/local_data_source/ShipDatabase.kt b/app/src/main/java/com/example/kocelainterview/data/local_data_source/ShipDatabase.kt new file mode 100644 index 0000000..9f214cc --- /dev/null +++ b/app/src/main/java/com/example/kocelainterview/data/local_data_source/ShipDatabase.kt @@ -0,0 +1,9 @@ +package com.example.kocelainterview.data.local_data_source + +import androidx.room.Database +import androidx.room.RoomDatabase + +@Database(entities = [ShipEntity::class], version = 1) +abstract class ShipDatabase:RoomDatabase (){ + abstract fun shipDao():ShipDao +} \ No newline at end of file diff --git a/app/src/main/java/com/example/kocelainterview/data/local_data_source/ShipEntity.kt b/app/src/main/java/com/example/kocelainterview/data/local_data_source/ShipEntity.kt new file mode 100644 index 0000000..45030b5 --- /dev/null +++ b/app/src/main/java/com/example/kocelainterview/data/local_data_source/ShipEntity.kt @@ -0,0 +1,32 @@ +package com.example.kocelainterview.data.local_data_source + +import androidx.room.Entity +import androidx.room.PrimaryKey +import com.example.kocelainterview.data.remote.dto.ShipDto + +@Entity(tableName = "ships") +data class ShipEntity( + @PrimaryKey val ship_id: String, + val active: Boolean, + val image: String?, + val ship_name: String, + val weight_kg: Int, + val year_built: Int +) + + +fun ShipEntity.toShipDto(): ShipDto { + return ShipDto( + ship_id = ship_id, + active = active, + image = image, + ship_name = ship_name, + weight_kg = weight_kg, + year_built = year_built + + ) +} + + + + diff --git a/app/src/main/java/com/example/kocelainterview/data/remote/dto/ShipDto.kt b/app/src/main/java/com/example/kocelainterview/data/remote/dto/ShipDto.kt index e9faa2b..48b5a40 100644 --- a/app/src/main/java/com/example/kocelainterview/data/remote/dto/ShipDto.kt +++ b/app/src/main/java/com/example/kocelainterview/data/remote/dto/ShipDto.kt @@ -1,34 +1,48 @@ package com.example.kocelainterview.data.remote.dto +import com.example.kocelainterview.data.local_data_source.ShipEntity import com.example.kocelainterview.domain.model.Ship data class ShipDto( - val abs: Int, + // val abs: Int, val active: Boolean, - val attempted_landings: Any, - val `class`: Int, - val course_deg: Any, - val home_port: String, +// val attempted_landings: Any?, +// val `class`: Int, +// val course_deg: Any, + // val home_port: String, val image: String, - val imo: Int, - val mmsi: Int, - val roles: List, +// val imo: Int, +// val mmsi: Int, +// val roles: List, val ship_id: String, - val ship_model: Any, + // val ship_model: Any?, val ship_name: String, - val ship_type: String, - val speed_kn: Int, - val status: String, - val successful_landings: Any, - val url: String, +// val ship_type: String, + // val speed_kn: Int, +// val status: String, +// val successful_landings: Any?, +// val url: String, val weight_kg: Int, - val weight_lbs: Int, + // val weight_lbs: Int, val year_built: Int ) +fun ShipDto.toEntity(): ShipEntity { + return ShipEntity( + ship_id = ship_id, + active = active, + image = image, + ship_name = ship_name, + weight_kg = weight_kg, + year_built = year_built + ) +} + + + fun ShipDto.toShip():Ship{ diff --git a/app/src/main/java/com/example/kocelainterview/data/repository/ShipRepositoryImpl.kt b/app/src/main/java/com/example/kocelainterview/data/repository/ShipRepositoryImpl.kt index ed686f0..27acb13 100644 --- a/app/src/main/java/com/example/kocelainterview/data/repository/ShipRepositoryImpl.kt +++ b/app/src/main/java/com/example/kocelainterview/data/repository/ShipRepositoryImpl.kt @@ -1,19 +1,36 @@ package com.example.kocelainterview.data.repository +import com.example.kocelainterview.data.local_data_source.ShipDao +import com.example.kocelainterview.data.local_data_source.toShipDto import com.example.kocelainterview.data.remote.api_service.ShipsApi import com.example.kocelainterview.data.remote.dto.ShipDetailDto import com.example.kocelainterview.data.remote.dto.ShipDto +import com.example.kocelainterview.data.remote.dto.toEntity import com.example.kocelainterview.domain.repository_interface.ShipRepository import javax.inject.Inject class ShipRepositoryImpl @Inject constructor( - private val api:ShipsApi -) :ShipRepository{ + private val api: ShipsApi, + private val shipDao: ShipDao +) : ShipRepository { + override suspend fun getShips(): List { - return api.getShips() + // Check Room database first + val cachedShips = shipDao.getShips() + if (cachedShips.isNotEmpty()) { + return cachedShips.map { it.toShipDto() } + } + + // Fetch from API if not found in cache + val ships = api.getShips() + + // Save to Room database + shipDao.saveShips(ships.map { it.toEntity() }) + + return ships } override suspend fun getShipById(shipId: String): ShipDetailDto { return api.getShipById(shipId) } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/example/kocelainterview/domain/model/Ship.kt b/app/src/main/java/com/example/kocelainterview/domain/model/Ship.kt index e97f0d4..f2462da 100644 --- a/app/src/main/java/com/example/kocelainterview/domain/model/Ship.kt +++ b/app/src/main/java/com/example/kocelainterview/domain/model/Ship.kt @@ -5,16 +5,9 @@ package com.example.kocelainterview.domain.model data class Ship( val active: Boolean, - // val home_port: String, val image: String?, val ship_id: String, - //val ship_model: Any, val ship_name: String, - //val ship_type: String, -// val speed_kn: Int, -// val status: String, val weight_kg: Int, - // val url: String, - //val weight_lbs: Int, val year_built: Int ) diff --git a/app/src/test/java/com/example/kocelainterview/domain/use_case/get_ships/GetShipsUseCaseTest.kt b/app/src/test/java/com/example/kocelainterview/domain/use_case/get_ships/GetShipsUseCaseTest.kt index fb2888e..44ff8c3 100644 --- a/app/src/test/java/com/example/kocelainterview/domain/use_case/get_ships/GetShipsUseCaseTest.kt +++ b/app/src/test/java/com/example/kocelainterview/domain/use_case/get_ships/GetShipsUseCaseTest.kt @@ -3,7 +3,6 @@ package com.example.kocelainterview.domain.use_case.get_ships import com.example.kocelainterview.common.core.Resource import com.example.kocelainterview.data.remote.dto.ShipDto import com.example.kocelainterview.data.remote.dto.toShip -import com.example.kocelainterview.domain.model.Ship import com.example.kocelainterview.domain.repository_interface.ShipRepository import kotlinx.coroutines.flow.toList import kotlinx.coroutines.runBlocking