Skip to content

Commit

Permalink
Merge pull request #168 from hieuwu/feature/error-exception-handling-…
Browse files Browse the repository at this point in the history
…with-supabase-and-each-layer

Exception handling with supabase and each layer
  • Loading branch information
hieuwu authored May 3, 2023
2 parents c7037e2 + 0c18176 commit eb1d6c3
Show file tree
Hide file tree
Showing 22 changed files with 218 additions and 172 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import kotlinx.coroutines.flow.Flow
@Dao
interface LineItemDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(lineItem: LineItem)
suspend fun insert(lineItem: LineItem)

@Query("SELECT * FROM $LINE_ITEM_TABLE WHERE lineItemId = :id")
fun getById(id: Long): Flow<LineItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.hieuwu.groceriesstore.utilities.CollectionNames
import com.hieuwu.groceriesstore.utilities.SupabaseMapper
import io.github.jan.supabase.postgrest.Postgrest
import kotlinx.coroutines.flow.map
import timber.log.Timber
import javax.inject.Inject

class CategoryRepositoryImpl @Inject constructor(
Expand All @@ -18,11 +19,15 @@ class CategoryRepositoryImpl @Inject constructor(
CategoryRepository {

override suspend fun refreshDatabase() {
val result = supabasePostgrest[CollectionNames.categories]
.select()
val res = result.decodeList<CategoriesDto>()
val categories = res.map { SupabaseMapper.mapToEntity(it) }
categoryDao.insertAll(categories)
try {
val result = supabasePostgrest[CollectionNames.categories]
.select()
val res = result.decodeList<CategoriesDto>()
val categories = res.map { SupabaseMapper.mapToEntity(it) }
categoryDao.insertAll(categories)
} catch (e: Exception) {
Timber.e(e.message)
}
}

override fun getFromLocal() = categoryDao.getAll().map { it.asDomainModel() }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.hieuwu.groceriesstore.data.repository.impl

import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
import com.hieuwu.groceriesstore.data.database.dao.LineItemDao
import com.hieuwu.groceriesstore.data.database.dao.OrderDao
import com.hieuwu.groceriesstore.data.database.entities.LineItem
Expand All @@ -12,16 +10,13 @@ import com.hieuwu.groceriesstore.domain.models.OrderModel
import com.hieuwu.groceriesstore.utilities.CollectionNames
import com.hieuwu.groceriesstore.utilities.OrderStatus
import com.hieuwu.groceriesstore.utilities.SupabaseMapper
import com.hieuwu.groceriesstore.utilities.convertOrderEntityToDocument
import io.github.jan.supabase.postgrest.Postgrest
import javax.inject.Inject
import javax.inject.Singleton
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.tasks.await
import kotlinx.coroutines.withContext
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class OrderRepositoryImpl @Inject constructor(
Expand All @@ -31,28 +26,43 @@ class OrderRepositoryImpl @Inject constructor(
) : OrderRepository {

override suspend fun createOrUpdate(order: Order) {
withContext(Dispatchers.IO) {
try {
orderDao.insert(order)
} catch (e: Exception) {
Timber.e(e.message)
}
}

override suspend fun addLineItem(lineItem: LineItem) {
withContext(Dispatchers.IO) {
try {
lineItemDao.insert(lineItem)
} catch (e: Exception) {
Timber.e(e.message)
}
}

override fun getOneOrderByStatus(status: OrderStatus): Flow<OrderModel?> =
orderDao.getCartWithLineItems(status.value).map {
it?.asDomainModel()
override fun getOneOrderByStatus(status: OrderStatus): Flow<OrderModel?> {
return try {
return orderDao.getCartWithLineItems(status.value).map {
it?.asDomainModel()
}
} catch (e: Exception) {
Timber.e(e.message)
flow {}
}
}

override suspend fun sendOrderToServer(order: OrderModel): Boolean {
val orderDto = SupabaseMapper.mapModelToDto(order)
val lineItems = SupabaseMapper.mapModelListToDto(order)
postgrest[CollectionNames.orders].insert(orderDto)
postgrest[CollectionNames.lineItems].insert(lineItems)
orderDao.clear()
return true
return try {
postgrest[CollectionNames.orders].insert(orderDto)
postgrest[CollectionNames.lineItems].insert(lineItems)
orderDao.clear()
true
} catch (e: Exception) {
Timber.e(e.message)
false
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import com.hieuwu.groceriesstore.domain.models.ProductModel
import com.hieuwu.groceriesstore.utilities.CollectionNames
import com.hieuwu.groceriesstore.utilities.SupabaseMapper
import io.github.jan.supabase.postgrest.Postgrest
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.withContext
import timber.log.Timber
import javax.inject.Inject

class ProductRepositoryImpl @Inject constructor(
Expand All @@ -27,37 +27,56 @@ class ProductRepositoryImpl @Inject constructor(
}

override suspend fun refreshDatabase() {
val result = supabasePostgrest[CollectionNames.products]
.select().decodeList<ProductDto>()
val products = result.map { SupabaseMapper.mapToEntity(it) }
productDao.insertAll(products)
try {
val result = supabasePostgrest[CollectionNames.products]
.select().decodeList<ProductDto>()
val products = result.map { SupabaseMapper.mapToEntity(it) }
productDao.insertAll(products)
} catch (e: Exception) {
Timber.e(e.message)
}
}

override suspend fun updateLineItemQuantityById(quantity: Int, id: Long) {
withContext(Dispatchers.IO) {
try {
lineItemDao.updateQuantityById(quantity, id)
} catch (e: Exception) {
Timber.e(e.message)
}
}

override suspend fun removeLineItemById(id: Long) {
withContext(Dispatchers.IO) {
try {
lineItemDao.removeLineItemById(id)
} catch (e: Exception) {
Timber.e(e.message)
}
}

override fun searchProductsListByName(name: String?) =
productDao.searchProductByName(name).map { it.asDomainModel() }

override fun getAllProductsByCategory(categoryId: String) =
productDao.getAllByCategory(categoryId).map {
it.asDomainModel()
override fun getAllProductsByCategory(categoryId: String): Flow<List<ProductModel>> {
return try {
productDao.getAllByCategory(categoryId).map {
it.asDomainModel()
}
} catch (e: Exception) {
Timber.e(e.message)
flow {}
}
}

override fun getProductById(productId: String): Flow<ProductModel> {
val productFlow = productDao.getById(productId)
return productFlow.map {
it.asDomainModel()
try {
val productFlow = productDao.getById(productId)
return productFlow.map {
it.asDomainModel()
}
} catch (e: Exception) {
Timber.e(e)
}
return flow {}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,22 @@ import com.hieuwu.groceriesstore.data.database.entities.asDomainModel
import com.hieuwu.groceriesstore.data.network.Api
import com.hieuwu.groceriesstore.data.network.dto.asEntity
import com.hieuwu.groceriesstore.data.repository.RecipeRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.withContext
import timber.log.Timber
import javax.inject.Inject

class RecipeRepositoryImpl @Inject constructor(
private val recipeDao: RecipeDao
) : RecipeRepository {
override suspend fun refreshDatabase() {
withContext(Dispatchers.IO) {
try {
val getRecipeDeferred = Api.retrofitService.getRecipesList()
try {
val listResult = getRecipeDeferred.await().recipesList.asEntity()
recipeDao.insertAll(listResult)
} catch (t: Throwable) {
var message = t.message
}
val listResult = getRecipeDeferred.await().recipesList.asEntity()
recipeDao.insertAll(listResult)
} catch (e: Exception) {
Timber.e(e.message)
}
}

override fun getFromLocal() = recipeDao.getAll().map { it.asDomainModel()}
override fun getFromLocal() = recipeDao.getAll().map { it.asDomainModel() }
}
Original file line number Diff line number Diff line change
@@ -1,64 +1,67 @@
package com.hieuwu.groceriesstore.data.repository.impl

import com.google.firebase.firestore.FirebaseFirestore
import com.hieuwu.groceriesstore.data.database.dao.UserDao
import com.hieuwu.groceriesstore.data.database.entities.User
import com.hieuwu.groceriesstore.data.database.entities.asDomainModel
import com.hieuwu.groceriesstore.data.network.dto.UserDto
import com.hieuwu.groceriesstore.data.repository.UserRepository
import com.hieuwu.groceriesstore.utilities.CollectionNames
import com.hieuwu.groceriesstore.utilities.SupabaseMapper
import com.hieuwu.groceriesstore.utilities.createUpdateUserRequest
import io.github.jan.supabase.gotrue.GoTrue
import io.github.jan.supabase.gotrue.providers.builtin.Email
import io.github.jan.supabase.postgrest.Postgrest
import java.util.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.tasks.await
import kotlinx.coroutines.withContext
import timber.log.Timber
import javax.inject.Inject

class UserRepositoryImpl @Inject constructor(
private val userDao: UserDao,
private val fireStore: FirebaseFirestore,
private val authService: GoTrue,
private val postgrest: Postgrest,
) : UserRepository {

override suspend fun createAccount(email: String, password: String, name: String): Boolean {
authService.signUpWith(Email) {
this.email = email
this.password = password
return try {
authService.signUpWith(Email) {
this.email = email
this.password = password
}
val userDto = UserDto(
id = UUID.randomUUID().toString(),
name = name,
email = email,
address = null,
phone = null,
isOrderCreatedNotiEnabled = false,
isPromotionNotiEnabled = false,
isDataRefreshedNotiEnabled = false
)
postgrest[CollectionNames.users].insert(value = userDto, upsert = true)
val user = SupabaseMapper.mapDtoToEntity(userDto)
userDao.insert(user)
true
} catch (e: Exception) {
Timber.e(e.message)
false
}
val userDto = UserDto(
id = UUID.randomUUID().toString(),
name = name,
email = email,
address = null,
phone = null,
isOrderCreatedNotiEnabled = false,
isPromotionNotiEnabled = false,
isDataRefreshedNotiEnabled = false
)
postgrest[CollectionNames.users].insert(value = userDto, upsert = true)
val user = SupabaseMapper.mapDtoToEntity(userDto)
userDao.insert(user)
return true
}

override suspend fun authenticate(email: String, password: String): Boolean {
authService.loginWith(Email) {
this.email = email
this.password = password
}

val userDto = postgrest[CollectionNames.users].select().decodeSingle<UserDto>()
val user = SupabaseMapper.mapDtoToEntity(userDto)
userDao.insert(user)
return true
return try {
authService.loginWith(Email) {
this.email = email
this.password = password
}

val userDto = postgrest[CollectionNames.users].select().decodeSingle<UserDto>()
val user = SupabaseMapper.mapDtoToEntity(userDto)
userDao.insert(user)
true
} catch (e: Exception) {
Timber.e(e.message)
false
}
}

override suspend fun updateUserProfile(
Expand Down Expand Up @@ -91,9 +94,7 @@ class UserRepositoryImpl @Inject constructor(
}

override suspend fun clearUser() {
withContext(Dispatchers.IO) {
userDao.clear()
}
userDao.clear()
}

override suspend fun updateUserSettings(
Expand All @@ -102,27 +103,24 @@ class UserRepositoryImpl @Inject constructor(
isDatabaseRefreshedEnabled: Boolean,
isPromotionEnabled: Boolean
) {
val updateRequest = createUpdateUserRequest(
isOrderCreatedEnabled,
isDatabaseRefreshedEnabled,
isPromotionEnabled
)
var isSuccess = false
fireStore.collection(CollectionNames.users).document(id)
.set(updateRequest)
.addOnSuccessListener {
isSuccess = true
}
.addOnFailureListener { e -> Timber.d("Error writing document%s", e) }.await()
if (isSuccess) {
withContext(Dispatchers.IO) {
userDao.updateUserSettings(
id,
isOrderCreatedEnabled,
isDatabaseRefreshedEnabled,
isPromotionEnabled
)
try {
postgrest[CollectionNames.users].update(
{
UserDto::isOrderCreatedNotiEnabled setTo isOrderCreatedEnabled
UserDto::isDataRefreshedNotiEnabled setTo isDatabaseRefreshedEnabled
UserDto::isPromotionNotiEnabled setTo isPromotionEnabled
}
) {
UserDto::id eq id
}
userDao.updateUserSettings(
id,
isOrderCreatedEnabled,
isDatabaseRefreshedEnabled,
isPromotionEnabled
)
} catch (e: Exception) {
Timber.e(e.message)
}
}

Expand Down
Loading

0 comments on commit eb1d6c3

Please sign in to comment.