-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature: Integrate Room DB to store and fetch the LabResponse
- Loading branch information
1 parent
a6ae7e8
commit e03297e
Showing
18 changed files
with
240 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 25 additions & 2 deletions
27
app/src/main/java/com/nagpal/shivam/vtucslab/VTUCSLabApplication.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,42 @@ | ||
package com.nagpal.shivam.vtucslab | ||
|
||
import androidx.multidex.MultiDexApplication | ||
import androidx.room.Room | ||
import com.google.firebase.crashlytics.FirebaseCrashlytics | ||
import com.nagpal.shivam.vtucslab.data.local.AppDatabase | ||
import com.nagpal.shivam.vtucslab.repositories.VtuCsLabRepository | ||
import com.nagpal.shivam.vtucslab.repositories.VtuCsLabRepositoryImpl | ||
import com.nagpal.shivam.vtucslab.services.VtuCsLabService | ||
import com.nagpal.shivam.vtucslab.utilities.Constants.VTU_CS_LAB | ||
import com.nagpal.shivam.vtucslab.utilities.StaticMethods | ||
|
||
class VTUCSLabApplication : MultiDexApplication() { | ||
val vtuCsLabRepository: VtuCsLabRepository = | ||
VtuCsLabRepositoryImpl(this, VtuCsLabService.instance) | ||
private lateinit var _db: AppDatabase | ||
val db: AppDatabase | ||
get() = _db | ||
|
||
private lateinit var _vtuCsLabRepository: VtuCsLabRepository | ||
val vtuCsLabRepository: VtuCsLabRepository | ||
get() = _vtuCsLabRepository | ||
|
||
override fun onCreate() { | ||
super.onCreate() | ||
if (BuildConfig.DEBUG) { | ||
FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(false) | ||
} | ||
|
||
_db = Room.databaseBuilder( | ||
applicationContext, | ||
AppDatabase::class.java, | ||
VTU_CS_LAB | ||
).build() | ||
|
||
val vtuCsLabService = VtuCsLabService.instance | ||
_vtuCsLabRepository = VtuCsLabRepositoryImpl( | ||
this, | ||
vtuCsLabService, | ||
_db.labResponseDao(), | ||
StaticMethods.jsonMapper | ||
) | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
app/src/main/java/com/nagpal/shivam/vtucslab/data/local/AppDatabase.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.nagpal.shivam.vtucslab.data.local | ||
|
||
import androidx.room.Database | ||
import androidx.room.RoomDatabase | ||
import androidx.room.TypeConverters | ||
|
||
@Database(entities = [LabResponse::class], version = 1) | ||
@TypeConverters(Converters::class) | ||
abstract class AppDatabase : RoomDatabase() { | ||
abstract fun labResponseDao(): LabResponseDao | ||
} |
16 changes: 16 additions & 0 deletions
16
app/src/main/java/com/nagpal/shivam/vtucslab/data/local/Converters.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.nagpal.shivam.vtucslab.data.local | ||
|
||
import androidx.room.TypeConverter | ||
import java.util.* | ||
|
||
class Converters { | ||
@TypeConverter | ||
fun dateFromTimestamp(value: Long?): Date? { | ||
return value?.let { Date(it) } | ||
} | ||
|
||
@TypeConverter | ||
fun dateToTimestamp(date: Date?): Long? { | ||
return date?.time | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
app/src/main/java/com/nagpal/shivam/vtucslab/data/local/DBConstants.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.nagpal.shivam.vtucslab.data.local | ||
|
||
object Tables { | ||
const val LAB_RESPONSE = "lab_response" | ||
} | ||
|
||
object LabResponseAttributes { | ||
const val URL = "url" | ||
const val RESPONSE = "response" | ||
const val RESPONSE_TYPE = "response_type" | ||
const val FETCHED_AT = "fetched_at" | ||
} |
19 changes: 19 additions & 0 deletions
19
app/src/main/java/com/nagpal/shivam/vtucslab/data/local/LabResponse.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package com.nagpal.shivam.vtucslab.data.local | ||
|
||
import androidx.room.ColumnInfo | ||
import androidx.room.Entity | ||
import androidx.room.PrimaryKey | ||
import com.nagpal.shivam.vtucslab.data.local.LabResponseAttributes.FETCHED_AT | ||
import com.nagpal.shivam.vtucslab.data.local.LabResponseAttributes.RESPONSE | ||
import com.nagpal.shivam.vtucslab.data.local.LabResponseAttributes.RESPONSE_TYPE | ||
import com.nagpal.shivam.vtucslab.data.local.LabResponseAttributes.URL | ||
import com.nagpal.shivam.vtucslab.data.local.Tables.LAB_RESPONSE | ||
import java.util.* | ||
|
||
@Entity(LAB_RESPONSE) | ||
data class LabResponse( | ||
@PrimaryKey @ColumnInfo(name = URL) val url: String, | ||
@ColumnInfo(name = RESPONSE) val response: String, | ||
@ColumnInfo(name = RESPONSE_TYPE) val responseType: LabResponseType, | ||
@ColumnInfo(name = FETCHED_AT) val fetchedAt: Date, | ||
) |
16 changes: 16 additions & 0 deletions
16
app/src/main/java/com/nagpal/shivam/vtucslab/data/local/LabResponseDao.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.nagpal.shivam.vtucslab.data.local | ||
|
||
import androidx.room.Dao | ||
import androidx.room.Query | ||
import androidx.room.Upsert | ||
import com.nagpal.shivam.vtucslab.data.local.LabResponseAttributes.URL | ||
import com.nagpal.shivam.vtucslab.data.local.Tables.LAB_RESPONSE | ||
|
||
@Dao | ||
interface LabResponseDao { | ||
@Upsert | ||
fun upsert(labResponse: LabResponse) | ||
|
||
@Query("SELECT * FROM $LAB_RESPONSE where $URL = :url") | ||
fun findByUrl(url: String): LabResponse? | ||
} |
7 changes: 7 additions & 0 deletions
7
app/src/main/java/com/nagpal/shivam/vtucslab/data/local/LabResponseType.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.nagpal.shivam.vtucslab.data.local | ||
|
||
enum class LabResponseType { | ||
LABORATORY, | ||
EXPERIMENT, | ||
CONTENT, | ||
} |
117 changes: 101 additions & 16 deletions
117
app/src/main/java/com/nagpal/shivam/vtucslab/repositories/VtuCsLabRepositoryImpl.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,65 +1,150 @@ | ||
package com.nagpal.shivam.vtucslab.repositories | ||
|
||
import android.app.Application | ||
import com.fasterxml.jackson.core.JsonParseException | ||
import com.fasterxml.jackson.databind.json.JsonMapper | ||
import com.nagpal.shivam.vtucslab.core.ErrorType | ||
import com.nagpal.shivam.vtucslab.core.Resource | ||
import com.nagpal.shivam.vtucslab.data.local.LabResponse | ||
import com.nagpal.shivam.vtucslab.data.local.LabResponseDao | ||
import com.nagpal.shivam.vtucslab.data.local.LabResponseType | ||
import com.nagpal.shivam.vtucslab.models.LaboratoryExperimentResponse | ||
import com.nagpal.shivam.vtucslab.models.LaboratoryResponse | ||
import com.nagpal.shivam.vtucslab.retrofit.ApiResult | ||
import com.nagpal.shivam.vtucslab.services.VtuCsLabService | ||
import com.nagpal.shivam.vtucslab.utilities.Configurations | ||
import com.nagpal.shivam.vtucslab.utilities.NetworkUtils | ||
import com.nagpal.shivam.vtucslab.utilities.StaticMethods | ||
import kotlinx.coroutines.flow.Flow | ||
import kotlinx.coroutines.flow.FlowCollector | ||
import kotlinx.coroutines.flow.flow | ||
import java.util.Date | ||
|
||
private val LOG_TAG: String = VtuCsLabRepositoryImpl::class.java.name | ||
|
||
class VtuCsLabRepositoryImpl( | ||
private val application: Application, | ||
private val vtuCsLabService: VtuCsLabService | ||
private val vtuCsLabService: VtuCsLabService, | ||
private val labResponseDao: LabResponseDao, | ||
private val jsonMapper: JsonMapper, | ||
) : VtuCsLabRepository { | ||
override fun fetchLaboratories(url: String): Flow<Resource<LaboratoryResponse, ErrorType>> = | ||
flow { | ||
fetch(url) { | ||
vtuCsLabService.getLaboratoryResponse(it) | ||
fetch( | ||
flow = this, | ||
url, | ||
LabResponseType.LABORATORY, | ||
vtuCsLabService::getLaboratoryResponse, | ||
{ data -> jsonMapper.writeValueAsString(data) } | ||
) { stringContent -> | ||
jsonMapper.readValue( | ||
stringContent, | ||
LaboratoryResponse::class.java | ||
) | ||
} | ||
} | ||
|
||
override fun fetchExperiments(url: String): Flow<Resource<LaboratoryExperimentResponse, ErrorType>> = | ||
flow { | ||
fetch(url) { | ||
vtuCsLabService.getLaboratoryExperimentsResponse(it) | ||
fetch( | ||
flow = this, | ||
url, | ||
LabResponseType.EXPERIMENT, | ||
vtuCsLabService::getLaboratoryExperimentsResponse, | ||
{ data -> jsonMapper.writeValueAsString(data) } | ||
) { stringContent -> | ||
jsonMapper.readValue( | ||
stringContent, | ||
LaboratoryExperimentResponse::class.java | ||
) | ||
} | ||
} | ||
|
||
override fun fetchContent(url: String): Flow<Resource<String, ErrorType>> = flow { | ||
fetch(url) { | ||
vtuCsLabService.fetchRawResponse(it) | ||
} | ||
fetch( | ||
flow = this, | ||
url, | ||
LabResponseType.CONTENT, | ||
vtuCsLabService::fetchRawResponse, | ||
{ stringContent -> stringContent } | ||
) { stringContent -> stringContent } | ||
} | ||
|
||
private suspend fun <D : Any> FlowCollector<Resource<D, ErrorType>>.fetch( | ||
private suspend fun <D : Any> fetch( | ||
flow: FlowCollector<Resource<D, ErrorType>>, | ||
url: String, | ||
executable: suspend (String) -> ApiResult<D> | ||
labResponseType: LabResponseType, | ||
fetchFromNetwork: suspend (String) -> ApiResult<D>, | ||
encodeToString: (D) -> String, | ||
decodeFromString: (String) -> D, | ||
) { | ||
emit(Resource.Loading()) | ||
flow.emit(Resource.Loading()) | ||
|
||
val labResponse = labResponseDao.findByUrl(url) | ||
var foundInDB = false | ||
labResponse?.let { | ||
try { | ||
flow.emit(Resource.Success(decodeFromString.invoke(it.response))) | ||
foundInDB = true | ||
if (it.fetchedAt.after( | ||
StaticMethods.getCurrentDateMinusSeconds(Configurations.RESPONSE_FRESHNESS_TIME) | ||
) | ||
) { | ||
return | ||
} | ||
} catch (_: JsonParseException) { | ||
} | ||
} | ||
|
||
if (!NetworkUtils.isNetworkConnected(application)) { | ||
emit(Resource.Error(ErrorType.NoActiveInternetConnection)) | ||
emitNetworkErrors( | ||
flow, | ||
foundInDB, | ||
Resource.Error(ErrorType.NoActiveInternetConnection), | ||
) | ||
return | ||
} | ||
when (val apiResult = executable.invoke(url)) { | ||
when (val apiResult = fetchFromNetwork.invoke(url)) { | ||
is ApiResult.ApiSuccess -> { | ||
emit(Resource.Success(apiResult.data)) | ||
val data = apiResult.data | ||
labResponseDao.upsert( | ||
LabResponse( | ||
url, | ||
encodeToString(data), | ||
labResponseType, | ||
Date(), | ||
) | ||
) | ||
flow.emit(Resource.Success(data)) | ||
} | ||
|
||
is ApiResult.ApiError -> { | ||
StaticMethods.logNetworkResultError(LOG_TAG, url, apiResult.code, apiResult.message) | ||
emit(Resource.Error(ErrorType.SomeErrorOccurred)) | ||
emitNetworkErrors( | ||
flow, | ||
foundInDB, | ||
Resource.Error(ErrorType.SomeErrorOccurred), | ||
) | ||
} | ||
|
||
is ApiResult.ApiException -> { | ||
StaticMethods.logNetworkResultException(LOG_TAG, url, apiResult.throwable) | ||
emit(Resource.Error(ErrorType.SomeErrorOccurred)) | ||
emitNetworkErrors( | ||
flow, | ||
foundInDB, | ||
Resource.Error(ErrorType.SomeErrorOccurred), | ||
) | ||
} | ||
} | ||
} | ||
|
||
private suspend fun <D : Any> emitNetworkErrors( | ||
flow: FlowCollector<Resource<D, ErrorType>>, | ||
foundInDB: Boolean, | ||
errorResource: Resource.Error<D, ErrorType> | ||
) { | ||
if (!foundInDB) { | ||
flow.emit(errorResource) | ||
} | ||
} | ||
} |
5 changes: 5 additions & 0 deletions
5
app/src/main/java/com/nagpal/shivam/vtucslab/utilities/Configurations.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package com.nagpal.shivam.vtucslab.utilities | ||
|
||
object Configurations { | ||
const val RESPONSE_FRESHNESS_TIME = 3 * 60 * 60 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.