Skip to content

Commit

Permalink
feat: implement background fetch worker (cont.)
Browse files Browse the repository at this point in the history
  • Loading branch information
kabirnayeem99 committed Jan 26, 2024
1 parent b4c39cb commit 1b68d43
Show file tree
Hide file tree
Showing 30 changed files with 355 additions and 778 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package io.github.kabirnayeem99.islamqaorg.common.utility

import io.github.kabirnayeem99.islamqaorg.data.dto.room.QuestionDetailEntity
import io.github.kabirnayeem99.islamqaorg.data.dto.room.QuestionEntity
import io.github.kabirnayeem99.islamqaorg.domain.entity.Fiqh
import io.github.kabirnayeem99.islamqaorg.domain.entity.Question
Expand Down Expand Up @@ -78,20 +77,20 @@ fun createMockQuestionEntityList(amount: Int, query: String): List<QuestionEntit
}

/**
* Creates a mock `QuestionDetailEntity` object with the given `id` and `randomText` and `fiqh`
* Creates a mock `QuestionEntity` object with the given `id` and `randomText` and `fiqh`
* values
*
* @param id The id of the question.
* @param randomText A random string that will be used to fill in the question and answer text.
* @param fiqh This is the fiqh that the question belongs to.
* @return QuestionDetailEntity
* @return QuestionEntity
*/
fun createMockQuestionDetailEntityWithId(
id: String,
randomText: String,
fiqh: Fiqh
): QuestionDetailEntity {
return QuestionDetailEntity(
): QuestionEntity {
return QuestionEntity(
questionTitle = randomText,
detailedQuestion = "$randomText $randomText",
detailedAnswer = "$randomText $randomText",
Expand All @@ -105,16 +104,16 @@ fun createMockQuestionDetailEntityWithId(


/**
* Creates a mock `QuestionDetailEntity` object with a given link
* Creates a mock `QuestionEntity` object with a given link
*
* @param link The link to the question detail page.
* @return A QuestionDetailEntity
* @return A QuestionEntity
*/
fun createMockQuestionDetailEntityWithId(
link: String
): QuestionDetailEntity {
): QuestionEntity {
val randomText = "lorem_ispum"
return QuestionDetailEntity(
return QuestionEntity(
questionTitle = randomText,
detailedQuestion = "$randomText $randomText",
detailedAnswer = "$randomText $randomText",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ import org.junit.Before
import org.junit.Test
import java.util.*

class QuestionDetailDaoTesting {
class QuestionAnswerDaoTesting {

private lateinit var db: IslamQaDatabase
private lateinit var dao: QuestionDetailDao
private lateinit var dao: QuestionAnswerDao

@Before
fun createDb() {
val context = ApplicationProvider.getApplicationContext<Context>()
db = Room.inMemoryDatabaseBuilder(context, IslamQaDatabase::class.java).build()
dao = db.getQuestionDetailDao()
dao = db.getQuestionAnswerDao()
}

@After
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import dagger.hilt.components.SingletonComponent
import io.github.kabirnayeem99.islamqaorg.data.dataSource.IslamQaLocalDataSource
import io.github.kabirnayeem99.islamqaorg.data.dataSource.IslamQaRemoteDataSource
import io.github.kabirnayeem99.islamqaorg.data.dataSource.PreferenceDataSource
import io.github.kabirnayeem99.islamqaorg.data.dataSource.localDb.QuestionDetailDao
import io.github.kabirnayeem99.islamqaorg.data.dataSource.localDb.QuestionListDao
import io.github.kabirnayeem99.islamqaorg.data.dataSource.localDb.QuestionAnswerDao
import io.github.kabirnayeem99.islamqaorg.data.dataSource.service.ScrapingService
import javax.inject.Singleton

Expand All @@ -31,12 +30,8 @@ object DataSourceModule {

@Provides
@Singleton
fun provideIslamQaLocalDataSource(
dao: QuestionListDao,
detailDao: QuestionDetailDao
): IslamQaLocalDataSource {
return IslamQaLocalDataSource(dao, detailDao)
}
fun provideIslamQaLocalDataSource(detailDao: QuestionAnswerDao) =
IslamQaLocalDataSource(detailDao)

@Provides
@Singleton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import io.github.kabirnayeem99.islamqaorg.data.dataSource.localDb.IslamQaDatabase
import io.github.kabirnayeem99.islamqaorg.data.dataSource.localDb.QuestionDetailDao
import io.github.kabirnayeem99.islamqaorg.data.dataSource.localDb.QuestionListDao
import javax.inject.Singleton

@Module
Expand All @@ -20,19 +18,11 @@ object DatabaseModule {
@Singleton
fun provideIslamQaDatabase(@ApplicationContext context: Context): IslamQaDatabase {
return Room.databaseBuilder(
context,
IslamQaDatabase::class.java,
"islam_qa_local_caching"
context, IslamQaDatabase::class.java, "islam_qa_local_caching"
).fallbackToDestructiveMigration().build()
}

@Provides
fun provideQuestionListDao(db: IslamQaDatabase): QuestionListDao {
return db.getQuestionListDao()
}
fun provideQuestionDetailDao(db: IslamQaDatabase) = db.getQuestionAnswerDao()

@Provides
fun provideQuestionDetailDao(db: IslamQaDatabase): QuestionDetailDao {
return db.getQuestionDetailDao()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import io.github.kabirnayeem99.islamqaorg.common.utility.NetworkUtil
import io.github.kabirnayeem99.islamqaorg.data.dataSource.IslamQaLocalDataSource
import io.github.kabirnayeem99.islamqaorg.data.dataSource.IslamQaRemoteDataSource
import io.github.kabirnayeem99.islamqaorg.data.dataSource.PreferenceDataSource
Expand All @@ -23,13 +22,11 @@ object RepositoryModule {
remoteDataSource: IslamQaRemoteDataSource,
localDataSource: IslamQaLocalDataSource,
preferenceDataSource: PreferenceDataSource,
networkUtil: NetworkUtil,
): QuestionAnswerRepository {
return QuestionAnswerRepositoryImpl(
remoteDataSource,
localDataSource,
preferenceDataSource,
networkUtil
preferenceDataSource
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ object UseCaseModule {
}

@Provides
fun provideFetchAndSavePeriodically(workManager: WorkManager) =
FetchAndSavePeriodically(workManager)
fun provideFetchAndSavePeriodically(
workManager: WorkManager,
questionAnswerRepository: QuestionAnswerRepository,
) = FetchAndSavePeriodically(workManager, questionAnswerRepository)
}
Original file line number Diff line number Diff line change
@@ -1,51 +1,43 @@
package io.github.kabirnayeem99.islamqaorg.data.dataSource

import io.github.kabirnayeem99.islamqaorg.common.EmptyCacheException
import io.github.kabirnayeem99.islamqaorg.data.dataSource.localDb.QuestionDetailDao
import io.github.kabirnayeem99.islamqaorg.data.dataSource.localDb.QuestionListDao
import io.github.kabirnayeem99.islamqaorg.data.dataSource.localDb.QuestionAnswerDao
import io.github.kabirnayeem99.islamqaorg.data.dataSource.localDb.generateSearchQuery
import io.github.kabirnayeem99.islamqaorg.data.mappers.toQuestionDetail
import io.github.kabirnayeem99.islamqaorg.data.mappers.toQuestionDetailEntity
import io.github.kabirnayeem99.islamqaorg.data.mappers.toQuestionEntities
import io.github.kabirnayeem99.islamqaorg.data.mappers.toQuestionEntity
import io.github.kabirnayeem99.islamqaorg.data.mappers.toQuestions
import io.github.kabirnayeem99.islamqaorg.domain.entity.Fiqh
import io.github.kabirnayeem99.islamqaorg.domain.entity.Question
import io.github.kabirnayeem99.islamqaorg.domain.entity.QuestionDetail
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import timber.log.Timber
import javax.inject.Inject

class IslamQaLocalDataSource @Inject constructor(
private val questionListDao: QuestionListDao,
private val questionDetailDao: QuestionDetailDao,
private val questionAnswerDao: QuestionAnswerDao,
) {

suspend fun getRandomQuestionList(): List<Question> {
try {
val randomQuestions = questionListDao.getRandomQuestions().toQuestions()
if (randomQuestions.isEmpty()) throw EmptyCacheException()
return randomQuestions
} catch (e: Exception) {
Timber.e(e, "getRandomQuestionList: ${e.localizedMessage}")
throw EmptyCacheException()
}
fun getRandomQuestionList(): Flow<List<Question>> {
return questionAnswerDao.getRandomQuestions().map { qs -> qs.toQuestions() }
}

suspend fun getFiqhBasedQuestionList(fiqh: Fiqh): List<Question> {
try {
val questions = questionListDao.getFiqhBasedQuestions(fiqh.paramName).toQuestions()
if (questions.isEmpty()) throw EmptyCacheException()
return questions
} catch (e: Exception) {
Timber.e(e, "getFiqhBasedQuestionList: " + e.localizedMessage)
throw EmptyCacheException()
}
suspend fun getRandomQuestionListByFiqhAsync(fiqh: String): List<Question> {
return questionAnswerDao.getRandomQuestionListByFiqhAsync(fiqh).toQuestions()
}

fun getFiqhBasedQuestionListByPage(fiqh: Fiqh, pageNumber: Int): Flow<List<Question>> {
val limit = 10
val offset = if (pageNumber != 0) pageNumber * limit else 0
return questionAnswerDao.getFiqhBasedQuestions(fiqh.paramName, limit, offset)
.map { qs -> qs.toQuestions() }
}


suspend fun searchFiqhBasedQuestionList(query: List<String>): List<Question> {
try {
val searchQuery = generateSearchQuery(query)
val questions = questionListDao.searchQuestions(searchQuery).toQuestions()
val questions = questionAnswerDao.searchQuestions(searchQuery).toQuestions()
if (questions.isEmpty()) throw EmptyCacheException()
return questions
} catch (e: Exception) {
Expand All @@ -54,21 +46,11 @@ class IslamQaLocalDataSource @Inject constructor(
}
}

suspend fun cacheQuestionList(questions: List<Question>, fiqh: Fiqh = Fiqh.UNKNOWN) {
try {
val questionEntities = questions.toQuestionEntities(fiqh)
questionListDao.insertAllQuestions(questionEntities)
} catch (e: Exception) {
Timber.e(e, "failed to cache home screen data -> ${e.localizedMessage}.")
}
}


suspend fun cacheQuestionDetail(questionDetail: QuestionDetail) {
try {
val questionDetailEntity = questionDetail.toQuestionDetailEntity()
questionDetailDao.insertQuestion(questionDetailEntity)
cacheQuestionList(questionDetail.relevantQuestions)
val questionDetailEntity = questionDetail.toQuestionEntity()
questionAnswerDao.insertQuestion(questionDetailEntity)
} catch (e: Exception) {
Timber.e(e, "failed to cache home screen data -> ${e.localizedMessage}.")
}
Expand All @@ -77,7 +59,8 @@ class IslamQaLocalDataSource @Inject constructor(

suspend fun getDetailedQuestionAndAnswer(url: String): QuestionDetail {
return try {
questionDetailDao.getQuestionByLink(url)?.toQuestionDetail { getRandomQuestionList() }
questionAnswerDao.getQuestionByLink(url)
?.toQuestionDetail { f -> getRandomQuestionListByFiqhAsync(f) }
?: throw EmptyCacheException()
} catch (e: Exception) {
Timber.e(e, "Failed to get cached detail answer.")
Expand Down
Loading

0 comments on commit 1b68d43

Please sign in to comment.