Skip to content

Commit

Permalink
Issue #39: Save Comic id on Characters Entity & Save Character id on …
Browse files Browse the repository at this point in the history
…Comics Entity. (#46)

- Created strategy to save the comics id on the Characters entity.

Signed-off-by: Diego Recalde <difereto89@gmail.com>
  • Loading branch information
recaldev authored and jamacado committed Jan 10, 2020
1 parent 920735e commit 4ab4d90
Show file tree
Hide file tree
Showing 27 changed files with 123 additions and 106 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.architect.coders.mu8.data.characters

import com.architect.coders.mu8.data.response.common.MarvelItemResponse
import com.architect.codes.mu8.utils.EMPTY_STRING

data class CharactersComicsResponse(
val available: Int = 0,
val collectionURI: String = EMPTY_STRING,
val items: List<MarvelItemResponse> = emptyList()
)
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import androidx.room.Query
@Dao
interface CharactersDAO {

@Query("SELECT * FROM CharactersEntity")
@Query(value = "SELECT * FROM CharactersEntity")
fun getAllCharacters(): List<CharactersEntity>

@Query("SELECT COUNT(id) FROM CharactersEntity")
@Query(value = "SELECT COUNT(id) FROM CharactersEntity")
fun charactersCount(): Int

@Insert(onConflict = IGNORE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@ package com.architect.coders.mu8.data.characters

import androidx.room.Entity
import androidx.room.PrimaryKey
import com.architect.coders.mu8.data.response.common.ThumbnailEntity
import com.architect.coders.mu8.data.response.common.UrlsEntity
import com.architect.coders.mu8.data.response.common.UrlsResponse
import com.architect.coders.mu8.data.response.common.toDomainEntity
import com.architect.codes.mu8.characters.Character
import com.architect.codes.mu8.utils.EMPTY_STRING

@Entity
data class CharactersEntity(
@PrimaryKey(autoGenerate = false) val id: Long = 0L,
val name: String = EMPTY_STRING,
val description: String = EMPTY_STRING,
val thumbnail: ThumbnailEntity,
val urls: List<UrlsEntity>
)
val thumbnailUrl: String = EMPTY_STRING,
val urls: List<UrlsResponse> = emptyList(),
val comicIds: List<String> = emptyList()
)

fun CharactersEntity.toDomainEntity() = Character(id, name, description, thumbnailUrl, urls.map { it.toDomainEntity() }, comicIds)

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,21 @@ import com.architect.codes.mu8.characters.CharactersRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

class CharactersRepositoryImpl(
private val mapper: CharactersMapper,
application: DataApp
) : CharactersRepository {
class CharactersRepositoryImpl(application: DataApp) : CharactersRepository {

private val database = application.database

override suspend fun invoke(): List<Character> = withContext(Dispatchers.IO) {
with(database.getCharactersDao()) {
if (charactersCount() <= 0) {
val response = service.getAllCharacters(
TIME_STAMP,
MARVEL_PUBLIC_KEY,
hashcode,
DEFAULT_OFFSET,
LIMIT
)

val response = service.getAllCharacters(TIME_STAMP, MARVEL_PUBLIC_KEY, hashcode, DEFAULT_OFFSET, LIMIT)
if (response.isSuccessful) {
response.body()?.data?.results?.run { insertCharacters(this) }
response.body()?.data?.results?.run {
map { it.toDatabaseEntity() }.also { insertCharacters(it) }
}
}
}
return@withContext getAllCharacters().map { mapper.transform(it) }
return@withContext getAllCharacters().map { it.toDomainEntity() }
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.architect.coders.mu8.data.characters

import com.architect.coders.mu8.data.response.common.ThumbnailResponse
import com.architect.coders.mu8.data.response.common.UrlsResponse
import com.architect.coders.mu8.data.utils.replaceHttps
import com.architect.codes.mu8.utils.COMICS_REGEX
import com.architect.codes.mu8.utils.EMPTY_STRING

data class CharactersResponse(
val id: Long = 0L,
val name: String = EMPTY_STRING,
val description: String = EMPTY_STRING,
val thumbnail: ThumbnailResponse = ThumbnailResponse(),
val urls: List<UrlsResponse> = emptyList(),
val comics: CharactersComicsResponse = CharactersComicsResponse()
)

fun CharactersResponse.toDatabaseEntity() = CharactersEntity(
id, name, description, "${thumbnail.path}.${thumbnail.extension}".replaceHttps(), urls,
comics.items.filter { comic ->
comic.resourceURI.contains(COMICS_REGEX)
}.map { comics ->
comics.resourceURI.substringAfter(delimiter = COMICS_REGEX)
}
)
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.architect.coders.mu8.data.comics

import com.architect.coders.mu8.data.service.MarvelServiceManager
import com.architect.coders.mu8.data.service.MarvelServiceManager.service
import com.architect.coders.mu8.data.utils.DEFAULT_OFFSET
import com.architect.coders.mu8.data.utils.LIMIT
import com.architect.coders.mu8.data.utils.MARVEL_PUBLIC_KEY
import com.architect.coders.mu8.data.utils.TIME_STAMP
import com.architect.codes.mu8.callback.ComicRepository
Expand All @@ -9,9 +12,7 @@ import com.architect.codes.mu8.comics.Comic
class ComicRepositoryImpl(private val mapper: ComicsMapper) : ComicRepository {

override suspend fun invoke(): List<Comic> {
val response = MarvelServiceManager.service
.getAllComics(TIME_STAMP, MARVEL_PUBLIC_KEY, MarvelServiceManager.hashcode)

val response = service.getAllComics(TIME_STAMP, MARVEL_PUBLIC_KEY, MarvelServiceManager.hashcode, DEFAULT_OFFSET, LIMIT)
response.body()?.apply {
return data.results.map { comicResponse -> mapper.transform(comicResponse) }
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.architect.coders.mu8.data.comics

import com.architect.coders.mu8.data.response.common.ThumbnailEntity
import com.architect.coders.mu8.data.response.common.ThumbnailResponse
import com.google.gson.annotations.SerializedName

data class ComicResponse(
Expand All @@ -17,5 +17,5 @@ data class ComicResponse(
val format: String,

@SerializedName("thumbnail")
val thumbnail: ThumbnailEntity
val thumbnail: ThumbnailResponse
)
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import com.architect.coders.mu8.data.characters.CharactersDAO
import com.architect.coders.mu8.data.characters.CharactersEntity
import com.architect.coders.mu8.data.database.converter.ListStringTypeConverters
import com.architect.coders.mu8.data.database.converter.ThumbnailTypeConverters
import com.architect.coders.mu8.data.database.converter.UrlsTypeConverters

private const val DATABASE_VERSION = 1

@Database(entities = [CharactersEntity::class], version = DATABASE_VERSION)
@TypeConverters(UrlsTypeConverters::class, ThumbnailTypeConverters::class)
@TypeConverters(UrlsTypeConverters::class, ThumbnailTypeConverters::class, ListStringTypeConverters::class)
abstract class MU8Database : RoomDatabase() {
abstract fun getCharactersDao(): CharactersDAO
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.architect.coders.mu8.data.database.converter

import androidx.room.TypeConverter
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken

class ListStringTypeConverters {

private val gson = Gson()

@TypeConverter
fun stringToListOfStrings(data: String?): List<String> {
if (data == null || data == "null") {
return emptyList()
}
val type = object : TypeToken<List<String>>() {}.type
return gson.fromJson(data, type)
}

@TypeConverter
fun listOfStringsToString(urls: List<String>?): String {
if (urls.isNullOrEmpty()) {
gson.toJson(emptyList<String>())
}
return gson.toJson(urls)
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.architect.coders.mu8.data.database.converter

import androidx.room.TypeConverter
import com.architect.coders.mu8.data.response.common.ThumbnailEntity
import com.architect.coders.mu8.data.response.common.ThumbnailResponse
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken

Expand All @@ -10,18 +10,18 @@ class ThumbnailTypeConverters {
private val gson = Gson()

@TypeConverter
fun stringToThumbnail(data: String?): ThumbnailEntity {
fun stringToThumbnail(data: String?): ThumbnailResponse {
if (data == null) {
return ThumbnailEntity()
return ThumbnailResponse()
}
val type = object : TypeToken<ThumbnailEntity>() {}.type
val type = object : TypeToken<ThumbnailResponse>() {}.type
return gson.fromJson(data, type)
}

@TypeConverter
fun thumbnailToString(thumbnail: ThumbnailEntity?): String {
fun thumbnailToString(thumbnail: ThumbnailResponse?): String {
if (thumbnail == null) {
return gson.toJson(ThumbnailEntity())
return gson.toJson(ThumbnailResponse())
}
return gson.toJson(thumbnail)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.architect.coders.mu8.data.database.converter

import androidx.room.TypeConverter
import com.architect.coders.mu8.data.response.common.UrlsEntity
import com.architect.coders.mu8.data.response.common.UrlsResponse
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken

Expand All @@ -10,18 +10,18 @@ class UrlsTypeConverters {
private val gson = Gson()

@TypeConverter
fun stringToUrls(data: String?): List<UrlsEntity> {
fun stringToUrls(data: String?): List<UrlsResponse> {
if (data == null) {
return emptyList()
}
val type = object : TypeToken<List<UrlsEntity>>() {}.type
val type = object : TypeToken<List<UrlsResponse>>() {}.type
return gson.fromJson(data, type)
}

@TypeConverter
fun urlsToString(urls: List<UrlsEntity>?): String {
fun urlsToString(urls: List<UrlsResponse>?): String {
if (urls.isNullOrEmpty()) {
gson.toJson(emptyList<UrlsEntity>())
gson.toJson(emptyList<UrlsResponse>())
}
return gson.toJson(urls)
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package com.architect.coders.mu8.data.response.common

data class MarvelItemResponse(val resourceURI: String, val name: String)
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ package com.architect.coders.mu8.data.response.common

import com.architect.codes.mu8.utils.EMPTY_STRING

data class ThumbnailEntity(val path: String = EMPTY_STRING, val extension: String = EMPTY_STRING)
data class ThumbnailResponse(val path: String = EMPTY_STRING, val extension: String = EMPTY_STRING)

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.architect.coders.mu8.data.response.common

import com.architect.codes.mu8.common.Urls

data class UrlsResponse(val type: String, val url: String)

fun UrlsResponse.toDomainEntity() = Urls(type, url)
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.architect.coders.mu8.data.service

import com.architect.coders.mu8.data.characters.CharactersEntity
import com.architect.coders.mu8.data.characters.CharactersResponse
import com.architect.coders.mu8.data.comics.ComicResponse
import com.architect.coders.mu8.data.response.BaseResponse
import retrofit2.Response
Expand All @@ -22,7 +22,9 @@ interface MarvelServiceAPI {
suspend fun getAllComics(
@Query(TIME_STAMP) timeStamp: String,
@Query(API_KEY) apiKey: String,
@Query(HASH) hash: String
@Query(HASH) hash: String,
@Query(OFFSET) offset: Int,
@Query(LIMIT) limit: Int
): Response<BaseResponse<ComicResponse>>

@GET("/v1/public/characters")
Expand All @@ -32,5 +34,5 @@ interface MarvelServiceAPI {
@Query(HASH) hash: String,
@Query(OFFSET) offset: Int,
@Query(LIMIT) limit: Int
): Response<BaseResponse<CharactersEntity>>
): Response<BaseResponse<CharactersResponse>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ data class Character(
val name: String,
val description: String,
val thumbnailUrl: String,
val urls: List<Urls>
val urls: List<Urls> = emptyList(),
val comicIds: List<String> = emptyList()
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ const val EMPTY_STRING = ""
const val NOT_FOUND = "Not Found"
const val CHARACTERS = "Characters"
const val COMICS = "Comics"
const val EVENTS = "Events"
const val EVENTS = "Events"
const val COMICS_REGEX = "comics/"
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class CategoriesAdapter(

fun showData(category: Category) {
categoryTitle.text = category.title
categoryImage.loadUrl(category.image, R.drawable.logo_marvel, R.drawable.error_image)
categoryImage.loadUrl(category.image)
}
}
}
Loading

0 comments on commit 4ab4d90

Please sign in to comment.