Skip to content

Commit

Permalink
refactor/#60: Room -> Proto DataStore
Browse files Browse the repository at this point in the history
  • Loading branch information
jinukeu committed Feb 1, 2025
1 parent bf974d4 commit 8ff3856
Show file tree
Hide file tree
Showing 15 changed files with 109 additions and 152 deletions.
17 changes: 0 additions & 17 deletions app/src/test/java/com/yapp/official/ExampleUnitTest.kt

This file was deleted.

21 changes: 17 additions & 4 deletions core/data/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import com.yapp.app.setNamespace
import org.gradle.internal.extensions.stdlib.capitalized
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
id("yapp.android.library")
Expand All @@ -20,6 +22,21 @@ protobuf {
register("java") {
option("lite")
}
register("kotlin") {
option("lite")
}
}
}
}
}

// https://stackoverflow.com/questions/78634960/ksp-error-when-upgrading-android-project-to-compose-compiler-2-0-0
androidComponents {
onVariants(selector().all()) { variant ->
afterEvaluate {
val capName = variant.name.capitalized()
tasks.getByName<KotlinCompile>("ksp${capName}Kotlin") {
setSource(tasks.getByName("generate${capName}Proto").outputs)
}
}
}
Expand All @@ -37,10 +54,6 @@ dependencies {
implementation(libs.encrypted.datastore.preference.ksp.annotations)
implementation(libs.encrypted.datastore.preference.security)

ksp(libs.room.compiler)
implementation(libs.room.runtime)
implementation(libs.room.ktx)

implementation(libs.androidx.core.ktx)
implementation(libs.retrofit.core)
implementation(libs.retrofit.kotlin.serialization)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,43 @@
package com.yapp.core.data.data.repository

import androidx.datastore.core.DataStore
import com.yapp.core.data.PositionConfigs
import com.yapp.core.data.data.Dispatcher
import com.yapp.core.data.data.YappDispatchers
import com.yapp.core.data.local.PositionConfigDao
import com.yapp.core.data.local.SecurityPreferences
import com.yapp.core.data.remote.api.ConfigApi
import com.yapp.core.data.remote.api.UnAuthorizedUserApi
import com.yapp.core.data.remote.model.request.toData
import com.yapp.core.data.remote.model.response.toModel
import com.yapp.core.data.remote.model.response.PositionConfigResponse
import com.yapp.dataapi.ConfigRepository
import com.yapp.dataapi.UnAuthorizedUserRepository
import com.yapp.model.SignUpInfo
import com.yapp.model.SignUpResult
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import javax.inject.Inject
import kotlin.jvm.optionals.getOrNull

internal class ConfigRepositoryImpl @Inject constructor(
private val configApi: ConfigApi,
private val positionConfigDao: PositionConfigDao,
private val dataStore: DataStore<PositionConfigs>,
@Dispatcher(YappDispatchers.IO) private val ioDispatcher: CoroutineDispatcher,
) : ConfigRepository {

override fun getPositionConfigs(): Flow<List<String>> = flow {
emit(positionConfigDao.getPositionConfigs().map { it.label })
val localPositionConfigs = dataStore.data.firstOrNull()
if (localPositionConfigs != null) {
emit(localPositionConfigs.configsList.map { it.label })
}

val remotePositionConfigs = configApi.getPositionConfigs()
positionConfigDao.replacePositionConfigs(remotePositionConfigs.toEntity())
emit(remotePositionConfigs.positions.map { it.label })

emit(positionConfigDao.getPositionConfigs().map { it.label })
updatePositionConfigs(remotePositionConfigs)
}.flowOn(ioDispatcher)

private suspend fun updatePositionConfigs(positionConfigs: PositionConfigResponse) {
dataStore.updateData { currentData ->
currentData.toBuilder()
.clearConfigs()
.addAllConfigs(positionConfigs.toProto())
.build()
}
}
}
Original file line number Diff line number Diff line change
@@ -1,31 +1,26 @@
package com.yapp.core.data.data.repository

import com.yapp.core.data.data.Dispatcher
import com.yapp.core.data.data.YappDispatchers
import com.yapp.core.data.local.PositionConfigDao
import androidx.datastore.core.DataStore
import com.yapp.core.data.PositionConfigs
import com.yapp.core.data.local.SecurityPreferences
import com.yapp.core.data.remote.api.UnAuthorizedUserApi
import com.yapp.core.data.remote.model.request.toData
import com.yapp.core.data.remote.model.response.toModel
import com.yapp.dataapi.UnAuthorizedUserRepository
import com.yapp.model.SignUpInfo
import com.yapp.model.SignUpResult
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.withContext
import kotlinx.coroutines.flow.firstOrNull
import javax.inject.Inject
import kotlin.jvm.optionals.getOrNull

internal class UnAuthorizedUserRepositoryImpl @Inject constructor(
private val api: UnAuthorizedUserApi,
private val securityPreferences: SecurityPreferences,
private val dao: PositionConfigDao,
@Dispatcher(YappDispatchers.IO) private val ioDispatcher: CoroutineDispatcher,
private val dataStore: DataStore<PositionConfigs>,
): UnAuthorizedUserRepository {

override suspend fun signUp(request: SignUpInfo): SignUpResult {
val positionConfigs = withContext(ioDispatcher) {
dao.getPositionConfigs()
}
val positionConfigs = dataStore.data.firstOrNull() ?: PositionConfigs.getDefaultInstance()

val response = api.signUp(
request.toData(positionConfigs)
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

14 changes: 0 additions & 14 deletions core/data/src/main/java/com/yapp/core/data/local/RoomDataBase.kt

This file was deleted.

17 changes: 0 additions & 17 deletions core/data/src/main/java/com/yapp/core/data/local/di/DaoModule.kt

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@ package com.yapp.core.data.local.di

import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.core.DataStoreFactory
import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler
import androidx.datastore.dataStoreFile
import androidx.datastore.preferences.core.PreferenceDataStoreFactory
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.emptyPreferences
import androidx.datastore.preferences.preferencesDataStoreFile
import com.yapp.core.data.PositionConfigs
import com.yapp.core.data.local.proto.PositionConfigSerializer
import com.yapp.core.data.local.SecurityPreferences
import com.yapp.core.data.local.generateSecurityPreferences
import dagger.Module
Expand All @@ -33,6 +37,18 @@ internal object DataStoreModule {
)
}

@Provides
@Singleton
fun providesPositionConfigPreferencesDataStore(
@ApplicationContext context: Context,
serializer: PositionConfigSerializer,
): DataStore<PositionConfigs> =
DataStoreFactory.create(
serializer = serializer,
) {
context.dataStoreFile(POSITION_CONFIG_NAME)
}

@EncryptedDataStore
@Singleton
@Provides
Expand All @@ -53,6 +69,7 @@ internal object DataStoreModule {

private const val DATASTORE_NAME = "yapp-datastore"
private const val ENCRYPTED_DATASTORE_NAME = "yapp-datastore-encrypted"
private const val POSITION_CONFIG_NAME = "position_config.pb"
}

@Qualifier
Expand Down
28 changes: 0 additions & 28 deletions core/data/src/main/java/com/yapp/core/data/local/di/RoomModule.kt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.yapp.core.data.local.proto

import androidx.datastore.core.CorruptionException
import androidx.datastore.core.Serializer
import com.google.protobuf.InvalidProtocolBufferException
import com.yapp.core.data.PositionConfigs
import java.io.InputStream
import java.io.OutputStream
import javax.inject.Inject

class PositionConfigSerializer @Inject constructor() : Serializer<PositionConfigs> {
override val defaultValue: PositionConfigs = PositionConfigs.getDefaultInstance()

override suspend fun readFrom(input: InputStream): PositionConfigs {
return try {
PositionConfigs.parseFrom(input)
} catch (e: InvalidProtocolBufferException) {
throw CorruptionException("Cannot read proto.", e)
}
}

override suspend fun writeTo(t: PositionConfigs, output: OutputStream) {
t.writeTo(output)
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.yapp.core.data.remote.model.request

import com.yapp.core.data.local.PositionConfigEntity
import com.yapp.core.data.PositionConfigs
import com.yapp.model.SignUpInfo
import kotlinx.serialization.Serializable

Expand All @@ -19,15 +19,15 @@ internal data class ActivityUnit(
val position: String
)

internal fun SignUpInfo.toData(positionConfigs: List<PositionConfigEntity>) = SignUpRequest(
internal fun SignUpInfo.toData(positionConfigs: PositionConfigs) = SignUpRequest(
email = email.trim(),
password = password.trim(),
name = name.trim(),
activityUnits = activityUnits.map { it.toData(positionConfigs) },
signUpCode = signUpCode.trim()
)

internal fun com.yapp.model.ActivityUnit.toData(positionConfigs: List<PositionConfigEntity>) = ActivityUnit(
internal fun com.yapp.model.ActivityUnit.toData(positionConfigs: PositionConfigs) = ActivityUnit(
generation = generation ?: throw IllegalArgumentException("Generation must not be null"),
position = positionConfigs.find { it.label == position }?.name ?: throw IllegalArgumentException("Invalid position: must not be null or undefined"),
position = positionConfigs.configsList.find { it.label == position }?.name ?: throw IllegalArgumentException("Invalid position: must not be null or undefined"),
)
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
package com.yapp.core.data.remote.model.response

import com.yapp.core.data.local.PositionConfigEntity
import kotlinx.serialization.Serializable

@Serializable
internal data class PositionConfigResponse(
val positions: List<PositionConfig>,
) {
fun toEntity() = positions.map { PositionConfigEntity(name = it.name, label = it.label) }
fun toProto() = positions.map { it.toProto() }
}

@Serializable
internal data class PositionConfig(
val name: String,
val label: String,
)
) {
fun toProto(): com.yapp.core.data.PositionConfig = com.yapp.core.data.PositionConfig
.newBuilder()
.setName(name)
.setLabel(label)
.build()
}
Loading

0 comments on commit 8ff3856

Please sign in to comment.