lab 5 refactoring

This commit is contained in:
Володя 2023-12-23 08:19:43 +03:00
parent 0c949919d8
commit e1e9ec07e1
25 changed files with 171 additions and 128 deletions

View File

@ -14,14 +14,14 @@ import com.example.pizza.Model.User.User
entity = Pizza::class, entity = Pizza::class,
parentColumns = ["uid"], parentColumns = ["uid"],
childColumns = ["pizza_id"], childColumns = ["pizza_id"],
onDelete = ForeignKey.RESTRICT, onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.RESTRICT), onUpdate = ForeignKey.CASCADE),
ForeignKey( ForeignKey(
entity = User::class, entity = User::class,
parentColumns = ["uid"], parentColumns = ["uid"],
childColumns = ["user_id"], childColumns = ["user_id"],
onDelete = ForeignKey.RESTRICT, onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.RESTRICT), onUpdate = ForeignKey.CASCADE),
], ],
primaryKeys = ["user_id", "pizza_id"]) primaryKeys = ["user_id", "pizza_id"])
data class Basket( data class Basket(

View File

@ -13,7 +13,7 @@ import io.reactivex.rxjava3.core.Flowable
@Dao @Dao
interface BasketDao { interface BasketDao {
@Query("select * from basket inner join pizzas on basket.pizza_id = pizzas.uid where basket.user_id = :uid") @Query("select * from basket inner join pizzas on basket.pizza_id = pizzas.uid where basket.user_id = :uid")
fun getUserBasket(uid: Int): RxPagingSource<Int, PizzaBasket> fun getUserBasket(uid: Int): Flowable<List<PizzaBasket>>
@Query("select * from basket inner join pizzas on basket.pizza_id = pizzas.uid where basket.user_id = :uid") @Query("select * from basket inner join pizzas on basket.pizza_id = pizzas.uid where basket.user_id = :uid")
fun getUserAllBasket(uid: Int): Flowable<List<PizzaBasket>> fun getUserAllBasket(uid: Int): Flowable<List<PizzaBasket>>
@Insert @Insert

View File

@ -3,15 +3,16 @@ package com.example.pizza.Model.Dto
import com.example.pizza.Model.Order.Order import com.example.pizza.Model.Order.Order
import com.example.pizza.Model.Pizza.Pizza import com.example.pizza.Model.Pizza.Pizza
import com.google.gson.annotations.SerializedName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import java.util.Date import java.util.Date
@Serializable @Serializable
data class OrderDto( data class OrderDto(
val uid : Int? = 0, @SerializedName("id") val uid : Int?,
val date: Long = 0, @SerializedName("date")val date: Long ,
val pizza: Int? = 0, @SerializedName("pizza")val pizza: Int,
val user: Int? = 0, @SerializedName("user")val user: Int ,
val price : Int = 0 @SerializedName("price")val price : Int
) )
fun OrderDto.toOrder(): Order = Order( fun OrderDto.toOrder(): Order = Order(
uid, Date(date), pizza, user, price) uid, Date(date), pizza, user, price)

View File

@ -17,14 +17,14 @@ import java.util.Date
entity = Pizza::class, entity = Pizza::class,
parentColumns = ["uid"], parentColumns = ["uid"],
childColumns = ["pizza_id"], childColumns = ["pizza_id"],
onDelete = ForeignKey.RESTRICT, onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.RESTRICT), onUpdate = ForeignKey.CASCADE),
ForeignKey( ForeignKey(
entity = User::class, entity = User::class,
parentColumns = ["uid"], parentColumns = ["uid"],
childColumns = ["user_id"], childColumns = ["user_id"],
onDelete = ForeignKey.RESTRICT, onDelete = ForeignKey.CASCADE,
onUpdate = ForeignKey.RESTRICT), onUpdate = ForeignKey.CASCADE),
]) ])
@TypeConverters(DateConverter::class) @TypeConverters(DateConverter::class)
class Order( class Order(
@ -33,9 +33,9 @@ class Order(
@ColumnInfo(name = "date") @ColumnInfo(name = "date")
val date: Date, val date: Date,
@ColumnInfo(name = "pizza_id", index = true) @ColumnInfo(name = "pizza_id", index = true)
val pizza: Int? , val pizza: Int ,
@ColumnInfo(name = "user_id", index = true) @ColumnInfo(name = "user_id", index = true)
val user: Int? , val user: Int ,
val price : Int ) { val price : Int ) {
@Ignore @Ignore
constructor( constructor(
@ -43,7 +43,7 @@ class Order(
Pizza : Pizza, Pizza : Pizza,
User : User, User : User,
Price : Int Price : Int
) : this(null , Date, Pizza.uid, User.uid, Price) ) : this(null , Date, Pizza.uid!!, User.uid!!, Price)
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (this === other) return true if (this === other) return true
if (javaClass != other?.javaClass) return false if (javaClass != other?.javaClass) return false

View File

@ -4,6 +4,7 @@ import androidx.paging.rxjava3.RxPagingSource
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete import androidx.room.Delete
import androidx.room.Insert import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query import androidx.room.Query
import androidx.room.Update import androidx.room.Update
import com.example.pizza.Model.Basket.Basket import com.example.pizza.Model.Basket.Basket
@ -12,18 +13,21 @@ import io.reactivex.rxjava3.core.Flowable
@Dao @Dao
interface OrderDao { interface OrderDao {
@Query("select orders.date as date, group_concat(pizzas.pizza_title) as pizzas, Sum(orders.price) as price from orders" +
" join pizzas on orders.pizza_id = pizzas.uid where orders.user_id = :uid group by orders.date order by orders.date desc") // @Query("select orders.date as date, group_concat(pizzas.pizza_title) as pizzas, Sum(orders.price) as price from orders" +
// " join pizzas on orders.pizza_id = pizzas.uid where orders.user_id = :uid group by orders.date order by orders.date desc")
@Query("select orders.uid as uid, orders.date as date, pizzas.pizza_title as pizzas, orders.price as price from orders" +
" join pizzas on orders.pizza_id = pizzas.uid where orders.user_id = :uid ")
fun getUserHistory(uid: Int): RxPagingSource<Int, PizzaOrder> fun getUserHistory(uid: Int): RxPagingSource<Int, PizzaOrder>
@Insert @Insert
fun insert(group: Order): Completable fun insert(group: Order): Completable
@Delete @Delete
fun delete(group: Order): Completable fun delete(group: Order): Completable
@Query("DELETE FROM pizzas") @Query("DELETE FROM orders")
fun deleteAll(): Completable fun deleteAll(): Completable
@Insert @Insert
fun insertMany(group: List<Order>): Completable fun insertAll(group: List<Order>): Completable
} }

View File

@ -2,5 +2,5 @@ package com.example.pizza.Model.Order
import java.util.Date import java.util.Date
class PizzaOrder(val date: Date, val pizzas : String, val price : Int) { class PizzaOrder(val uid: Int,val date: Date, val pizzas : String, val price : Int) {
} }

View File

@ -7,6 +7,9 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Button import android.widget.Button
import android.widget.TextView import android.widget.TextView
import androidx.lifecycle.LiveData
import androidx.lifecycle.map
import androidx.paging.PagingData
import androidx.paging.PagingDataAdapter import androidx.paging.PagingDataAdapter
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
@ -51,7 +54,7 @@ class OrderAdapter( var context: Context, val resSum: TextView, val basketVm : B
holder.count.text = it.count_pizza.toString() holder.count.text = it.count_pizza.toString()
holder.sum.text = it.pizza_price.toString() holder.sum.text = it.pizza_price.toString()
resSum.text = (resSum.text.toString().toInt() + it.pizza_price).toString() resSum.text = (resSum.text.toString().toInt() + it.pizza_price).toString()
holder.btnTrash.setOnClickListener{deleteFromBasket(holder,position)} holder.btnTrash.setOnClickListener{deleteFromBasket(holder,pizza.user_id,pizza.pizza_id,pizza.pizza_price)}
} }
@ -61,7 +64,8 @@ class OrderAdapter( var context: Context, val resSum: TextView, val basketVm : B
return getItem(position) return getItem(position)
} }
fun btnPlus(holder:MyViewHolder,position: Int){ @SuppressLint("SetTextI18n")
fun btnPlus(holder:MyViewHolder, position: Int){
val pizza = getItem(position) val pizza = getItem(position)
pizza?.let { pizza?.let {
var count = holder.count.text.toString().toInt() var count = holder.count.text.toString().toInt()
@ -85,15 +89,16 @@ class OrderAdapter( var context: Context, val resSum: TextView, val basketVm : B
} }
} }
@SuppressLint("CheckResult") @SuppressLint("CheckResult", "NotifyDataSetChanged")
fun deleteFromBasket(holder: OrderAdapter.MyViewHolder, position: Int){ fun deleteFromBasket(holder: OrderAdapter.MyViewHolder, uid:Int,pid:Int,price:Int){
val pizza = getItem(position)
val price = pizza!!.pizza_price
val count = holder.count.text.toString().toInt() val count = holder.count.text.toString().toInt()
val sum = price*count val sum = price*count
basketVm.deletePizza(pizza!!.user_id,pizza!!.pizza_id) basketVm.deletePizza(uid,pid)
{ val oldSum = resSum.text.toString().toInt() {
val oldSum = resSum.text.toString().toInt()
val newSum = oldSum - sum val newSum = oldSum - sum
resSum.text = newSum.toString()} resSum.text = newSum.toString()
}
} }
} }

View File

@ -7,7 +7,7 @@ import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Flowable import io.reactivex.rxjava3.core.Flowable
interface BasketRepository { interface BasketRepository {
fun getUserBasket(uid: Int): RxPagingSource<Int, PizzaBasket> fun getUserBasket(uid: Int): Flowable<List<PizzaBasket>>
fun insert(group: Basket): Completable fun insert(group: Basket): Completable
fun getUserAllBasket(uid: Int): Flowable<List<PizzaBasket>> fun getUserAllBasket(uid: Int): Flowable<List<PizzaBasket>>

View File

@ -9,7 +9,7 @@ import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Flowable import io.reactivex.rxjava3.core.Flowable
class OfflineBasketRepository(private val basketDao : BasketDao) : BasketRepository { class OfflineBasketRepository(private val basketDao : BasketDao) : BasketRepository {
override fun getUserBasket(uid: Int): RxPagingSource<Int, PizzaBasket> = basketDao.getUserBasket(uid) override fun getUserBasket(uid: Int): Flowable<List<PizzaBasket>> = basketDao.getUserBasket(uid)
override fun getUserAllBasket(uid: Int): Flowable<List<PizzaBasket>> = basketDao.getUserAllBasket(uid) override fun getUserAllBasket(uid: Int): Flowable<List<PizzaBasket>> = basketDao.getUserAllBasket(uid)
override fun insert(group: Basket): Completable = basketDao.insert(group) override fun insert(group: Basket): Completable = basketDao.insert(group)

View File

@ -12,7 +12,7 @@ class OfflineOrderRepository(private val orderDao: OrderDao) : OrderRepository {
override fun insert(group: Order): Completable = orderDao.insert(group) override fun insert(group: Order): Completable = orderDao.insert(group)
override fun insertMany(group: List<Order>): Completable = orderDao.insertMany(group) override fun insertAll(group: List<Order>): Completable = orderDao.insertAll(group)
fun delete(group: Order): Completable = orderDao.delete(group) fun delete(group: Order): Completable = orderDao.delete(group)
fun deleteAll(): Completable = orderDao.deleteAll() fun deleteAll(): Completable = orderDao.deleteAll()
} }

View File

@ -16,6 +16,7 @@ class OfflineUserRepository(private val userDao : UserDao) : UserRepository {
override fun getByLoginAndPassword(login: String, pass: String): Single<User> = userDao.getByLoginAndPassword(login,pass) override fun getByLoginAndPassword(login: String, pass: String): Single<User> = userDao.getByLoginAndPassword(login,pass)
override fun insert(group: User): Completable = userDao.insert(group) override fun insert(group: User): Completable = userDao.insert(group)
fun deleteAll(): Completable = userDao.deleteAll()
override fun update(group: User): Completable = userDao.update(group) override fun update(group: User): Completable = userDao.update(group)

View File

@ -11,5 +11,5 @@ interface OrderRepository {
fun insert(group: Order): Completable fun insert(group: Order): Completable
fun insertMany(group: List<Order>): Completable fun insertAll(group: List<Order>): Completable
} }

View File

@ -10,17 +10,22 @@ import androidx.paging.LoadType
import androidx.paging.PagingState import androidx.paging.PagingState
import androidx.paging.RemoteMediator import androidx.paging.RemoteMediator
import androidx.paging.rxjava3.RxRemoteMediator import androidx.paging.rxjava3.RxRemoteMediator
import com.example.pizza.Model.Dto.UserDto
import com.example.pizza.Model.Dto.toOrder import com.example.pizza.Model.Dto.toOrder
import com.example.pizza.Model.Dto.toPizza import com.example.pizza.Model.Dto.toPizza
import com.example.pizza.Model.Dto.toUser
import com.example.pizza.Model.Order.Order import com.example.pizza.Model.Order.Order
import com.example.pizza.Model.Order.PizzaOrder
import com.example.pizza.Model.Pizza.Pizza import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.Repository.OfflineOrderRepository import com.example.pizza.Model.Repository.OfflineOrderRepository
import com.example.pizza.Model.Repository.OfflinePizzaRepository import com.example.pizza.Model.Repository.OfflinePizzaRepository
import com.example.pizza.Model.Repository.OfflineUserRepository
import com.example.pizza.Model.Rest.MyServerService import com.example.pizza.Model.Rest.MyServerService
import com.example.pizza.RemoteKeys.OfflineRemoteKeyRepository import com.example.pizza.RemoteKeys.OfflineRemoteKeyRepository
import com.example.pizza.RemoteKeys.RemoteKeyType import com.example.pizza.RemoteKeys.RemoteKeyType
import com.example.pizza.RemoteKeys.RemoteKeys import com.example.pizza.RemoteKeys.RemoteKeys
import com.example.pizza.database.AppDatabase import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Maybe import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.core.Observable import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.Single import io.reactivex.rxjava3.core.Single
@ -36,11 +41,11 @@ class OrderRemoteMediator(
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository, private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
private val database: AppDatabase, private val database: AppDatabase,
private val id : Int private val id : Int
): RxRemoteMediator<Int, Order>() { ): RxRemoteMediator<Int, PizzaOrder>() {
@RequiresApi(Build.VERSION_CODES.O) @RequiresApi(Build.VERSION_CODES.O)
override fun loadSingle( override fun loadSingle(
loadType: LoadType, loadType: LoadType,
state: PagingState<Int, Order> state: PagingState<Int, PizzaOrder>
): Single<MediatorResult> { ): Single<MediatorResult> {
Log.d(this::class.simpleName, state.toString()) Log.d(this::class.simpleName, state.toString())
@ -86,26 +91,34 @@ class OrderRemoteMediator(
@SuppressLint("CheckResult") @SuppressLint("CheckResult")
@RequiresApi(Build.VERSION_CODES.O) @RequiresApi(Build.VERSION_CODES.O)
fun getMediatorResout(loadType: LoadType, page : AtomicInteger, state: PagingState<Int, Order>) fun getMediatorResout(loadType: LoadType, page : AtomicInteger, state: PagingState<Int, PizzaOrder>)
: Single<MediatorResult> { : Single<MediatorResult> {
Log.d(PizzaRemoteMediator::class.simpleName,"Load") Log.d(OrderRemoteMediator::class.simpleName,"Load")
service.getAllPizzas() return service.getAllPizzas()
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.map{ .map {
if(loadType == LoadType.REFRESH){
database.runInTransaction { database.runInTransaction {
dbPizzaRepository.deleteAll().blockingAwait() dbPizzaRepository.deleteAll().blockingAwait()
} Log.d(OrderRemoteMediator::class.simpleName,"pizzas deleted")
dbPizzaRepository.insertAll(it.map { it.toPizza() }).blockingAwait() dbPizzaRepository.insertAll(it.map { it.toPizza() }).blockingAwait()
Log.d(OrderRemoteMediator::class.simpleName,"pizzas loaded ${it.size}")
} }
return service.getUserOrders(id,state.config.pageSize,(page.get()-1)*state.config.pageSize)
.subscribeOn(Schedulers.io()) }
}
.flatMap { service.getUserOrders(id,state.config.pageSize,(page.get()-1)*state.config.pageSize) }
.map{ .map{
database.runInTransaction { database.runInTransaction {
if(loadType == LoadType.REFRESH) { if(loadType == LoadType.REFRESH) {
dbOrderRepository.deleteAll().blockingAwait() dbOrderRepository.deleteAll().blockingAwait()
dbRemoteKeyRepository.deleteRemoteKey(RemoteKeyType.ORDER).blockingAwait() dbRemoteKeyRepository.deleteRemoteKey(RemoteKeyType.ORDER).blockingAwait()
Log.d(OrderRemoteMediator::class.simpleName,"orders deleted")
} }
dbOrderRepository.insertMany(it.map { it.toOrder() }).blockingAwait() Log.d(OrderRemoteMediator::class.simpleName,"start load orders")
dbOrderRepository.insertAll(it.map { it.toOrder() }).blockingAwait()
val prevKey = if (page.get() == 1) null else page.get() - 1 val prevKey = if (page.get() == 1) null else page.get() - 1
val nextKey = if (it.isEmpty()) null else page.get() + 1 val nextKey = if (it.isEmpty()) null else page.get() + 1
val keys = it.map { val keys = it.map {
@ -125,21 +138,21 @@ class OrderRemoteMediator(
Single.just(MediatorResult.Error(e) as MediatorResult) Single.just(MediatorResult.Error(e) as MediatorResult)
} }
} }
private fun getRemoteKeyForLastItem(state: PagingState<Int, Order>): Maybe<RemoteKeys> { private fun getRemoteKeyForLastItem(state: PagingState<Int, PizzaOrder>): Maybe<RemoteKeys> {
return state.pages.lastOrNull { it.data.isNotEmpty() }?.data?.lastOrNull() return state.pages.lastOrNull { it.data.isNotEmpty() }?.data?.lastOrNull()
?.let { group -> ?.let { group ->
dbRemoteKeyRepository.getAllRemoteKeys(group.uid!!, RemoteKeyType.ORDER) dbRemoteKeyRepository.getAllRemoteKeys(group.uid!!, RemoteKeyType.ORDER)
} ?: Maybe.empty() } ?: Maybe.empty()
} }
private fun getRemoteKeyForFirstItem(state: PagingState<Int, Order>): Maybe<RemoteKeys> { private fun getRemoteKeyForFirstItem(state: PagingState<Int, PizzaOrder>): Maybe<RemoteKeys> {
return state.pages.firstOrNull { it.data.isNotEmpty() }?.data?.firstOrNull() return state.pages.firstOrNull { it.data.isNotEmpty() }?.data?.firstOrNull()
?.let { group -> ?.let { group ->
dbRemoteKeyRepository.getAllRemoteKeys(group.uid!!, RemoteKeyType.ORDER) dbRemoteKeyRepository.getAllRemoteKeys(group.uid!!, RemoteKeyType.ORDER)
}?: Maybe.empty() }?: Maybe.empty()
} }
private fun getRemoteKeyClosestToCurrentPosition( state: PagingState<Int, Order>): Maybe<RemoteKeys> { private fun getRemoteKeyClosestToCurrentPosition( state: PagingState<Int, PizzaOrder>): Maybe<RemoteKeys> {
return state.anchorPosition?.let { position -> return state.anchorPosition?.let { position ->
state.closestItemToPosition(position)?.uid?.let { studentUid -> state.closestItemToPosition(position)?.uid?.let { studentUid ->
dbRemoteKeyRepository.getAllRemoteKeys(studentUid, RemoteKeyType.ORDER) dbRemoteKeyRepository.getAllRemoteKeys(studentUid, RemoteKeyType.ORDER)

View File

@ -12,6 +12,7 @@ import com.example.pizza.Model.Dto.BasketDto
import com.example.pizza.Model.Dto.toBasket import com.example.pizza.Model.Dto.toBasket
import com.example.pizza.Model.Dto.toBasketDto import com.example.pizza.Model.Dto.toBasketDto
import com.example.pizza.Model.Dto.toPizza import com.example.pizza.Model.Dto.toPizza
import com.example.pizza.Model.Dto.toUser
import com.example.pizza.Model.Dto.toUserDto import com.example.pizza.Model.Dto.toUserDto
import com.example.pizza.Model.Pizza.Pizza import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.Repository.BasketRepository import com.example.pizza.Model.Repository.BasketRepository
@ -30,32 +31,35 @@ import okhttp3.internal.wait
class RestBasketRepository(private val service: MyServerService, class RestBasketRepository(private val service: MyServerService,
private val dbBasketRepository: OfflineBasketRepository, private val dbBasketRepository: OfflineBasketRepository,
private val dbPizzaRepository: OfflinePizzaRepository, private val dbPizzaRepository: OfflinePizzaRepository,
private val dbUserRepository: OfflineUserRepository,
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository, private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
private val database: AppDatabase private val database: AppDatabase
) : BasketRepository { ) : BasketRepository {
var AllBaskets : MutableLiveData<RxPagingSource<Int, PizzaBasket>?> = MutableLiveData()
@RequiresApi(Build.VERSION_CODES.O) @RequiresApi(Build.VERSION_CODES.O)
@SuppressLint("CheckResult") @SuppressLint("CheckResult")
override fun getUserBasket(uid: Int): RxPagingSource<Int, PizzaBasket> { override fun getUserBasket(uid: Int): Flowable<List<PizzaBasket>> {
insertAll(uid) Log.d("RestBasketRepository", "Insert All")
return AllBaskets.value!! var fff = service.getAllPizzas()
.map{data ->
val ps = data.map { it.toPizza() }
database.runInTransaction{
dbPizzaRepository.deleteAll().blockingAwait()
dbPizzaRepository.insertAll(ps).blockingAwait()
Log.d("RestBasketRepository", ps.toString())
} }
@RequiresApi(Build.VERSION_CODES.O) }
@SuppressLint("CheckResult") .flatMap { service.getUserBaskets(uid) }
fun insertAll(uid: Int){ .map{data ->
Log.d("RestBasketRepository", "Insert All") val bks = data.map { it.toBasket() }
Observable.zip(service.getUserBaskets(uid),service.getAllPizzas()){
baskets,pizzas ->
Log.d("RestBasketRepository", "Insert All")
val bks = baskets.map { it.toBasket() }
val ps = pizzas.map { it.toPizza() }
database.runInTransaction{ database.runInTransaction{
dbBasketRepository.deleteAll().blockingAwait() dbBasketRepository.deleteAll().blockingAwait()
dbPizzaRepository.deleteAll().blockingAwait()
dbBasketRepository.insertAll(bks).blockingAwait() dbBasketRepository.insertAll(bks).blockingAwait()
dbPizzaRepository.insertAll(ps).blockingAwait() Log.d("RestBasketRepository", bks.toString())
} }
}.map { dbBasketRepository.getUserBasket(uid) }.subscribe { data -> AllBaskets.postValue(data)} }
.flatMap { dbBasketRepository.getUserBasket(uid) }
return fff
} }
@SuppressLint("CheckResult") @SuppressLint("CheckResult")
@ -72,9 +76,15 @@ class RestBasketRepository(private val service: MyServerService,
throw Exception() throw Exception()
} }
override fun deleteByUser(uid: Int): Completable = Completable.fromObservable(service.deleteUserBaskets(uid)) @SuppressLint("CheckResult")
override fun deleteByUser(uid: Int): Completable {
override fun deleteByUserAndPizza(uid: Int, pid: Int): Completable = Completable.fromObservable(service.deleteBasket( return Completable.fromObservable(service.deleteUserBaskets(uid)).andThen { dbBasketRepository.deleteByUser(uid).blockingAwait() }
BasketDto(uid,pid,1) }
))
@SuppressLint("CheckResult")
override fun deleteByUserAndPizza(uid: Int, pid: Int): Completable {
return Completable.fromObservable( service.deleteBasket(uid, pid)).andThen {dbBasketRepository.deleteByUserAndPizza(uid, pid).blockingAwait() }
}
} }

View File

@ -1,14 +1,18 @@
package com.example.pizza.Model.Repository.Rest package com.example.pizza.Model.Repository.Rest
import android.database.Observable import android.annotation.SuppressLint
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.paging.rxjava3.RxPagingSource import androidx.paging.rxjava3.RxPagingSource
import androidx.room.Index import androidx.room.Index
import com.example.pizza.Model.Dto.OrderDto import com.example.pizza.Model.Dto.OrderDto
import com.example.pizza.Model.Dto.toOrderDto import com.example.pizza.Model.Dto.toOrderDto
import com.example.pizza.Model.Dto.toPizza
import com.example.pizza.Model.Order.Order import com.example.pizza.Model.Order.Order
import com.example.pizza.Model.Order.PizzaOrder import com.example.pizza.Model.Order.PizzaOrder
import com.example.pizza.Model.Repository.OfflineOrderRepository import com.example.pizza.Model.Repository.OfflineOrderRepository
import com.example.pizza.Model.Repository.OfflinePizzaRepository import com.example.pizza.Model.Repository.OfflinePizzaRepository
import com.example.pizza.Model.Repository.OfflineUserRepository
import com.example.pizza.Model.Repository.OrderRepository import com.example.pizza.Model.Repository.OrderRepository
import com.example.pizza.Model.Repository.Rest.Mediators.OrderRemoteMediator import com.example.pizza.Model.Repository.Rest.Mediators.OrderRemoteMediator
import com.example.pizza.Model.Repository.Rest.Mediators.PizzaRemoteMediator import com.example.pizza.Model.Repository.Rest.Mediators.PizzaRemoteMediator
@ -16,6 +20,7 @@ import com.example.pizza.Model.Rest.MyServerService
import com.example.pizza.RemoteKeys.OfflineRemoteKeyRepository import com.example.pizza.RemoteKeys.OfflineRemoteKeyRepository
import com.example.pizza.database.AppDatabase import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.core.Completable import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.schedulers.Schedulers
class RestOrderRepository(private val service: MyServerService, class RestOrderRepository(private val service: MyServerService,
private val dbOrderRepository: OfflineOrderRepository, private val dbOrderRepository: OfflineOrderRepository,
@ -24,8 +29,11 @@ class RestOrderRepository(private val service: MyServerService,
private val database: AppDatabase private val database: AppDatabase
) : OrderRepository { ) : OrderRepository {
var mediator: OrderRemoteMediator? = null var mediator: OrderRemoteMediator? = null
@RequiresApi(Build.VERSION_CODES.O)
@SuppressLint("CheckResult")
override fun getUserHistory(uid: Int): RxPagingSource<Int, PizzaOrder> { override fun getUserHistory(uid: Int): RxPagingSource<Int, PizzaOrder> {
if (mediator==null){ if (mediator==null){
mediator = OrderRemoteMediator( mediator = OrderRemoteMediator(
service, service,
dbOrderRepository, dbOrderRepository,
@ -34,6 +42,7 @@ class RestOrderRepository(private val service: MyServerService,
database, database,
uid uid
) )
} }
return dbOrderRepository.getUserHistory(uid) return dbOrderRepository.getUserHistory(uid)
@ -41,13 +50,9 @@ class RestOrderRepository(private val service: MyServerService,
override fun insert(group: Order): Completable = Completable.fromObservable(service.createOrder(group.toOrderDto())) override fun insert(group: Order): Completable = Completable.fromObservable(service.createOrder(group.toOrderDto()))
override fun insertMany(orders: List<Order>): Completable override fun insertAll(group: List<Order>): Completable
{ {
var list : MutableList <OrderDto> = mutableListOf<OrderDto>() var list = group.map{it.toOrderDto()}
for (order in orders){
list.add(order.toOrderDto())
}
return Completable.fromObservable(service.createOrders(list)) return Completable.fromObservable(service.createOrders(list))
} }

View File

@ -25,12 +25,22 @@ class RestUserRepository (
private val database: AppDatabase private val database: AppDatabase
) : UserRepository { ) : UserRepository {
@SuppressLint("CheckResult") @SuppressLint("CheckResult")
override fun getById(uid: Int): Single<User> = service.getUser(uid).map { it.toUser() } override fun getById(uid: Int): Single<User> = service.getUser(uid).map {
Log.d(RestUserRepository::class.simpleName ,"load user by id")
database.runInTransaction{
dbUserRepository.deleteAll().blockingAwait()
dbUserRepository.insert(it.toUser()).blockingAwait()
}
it.toUser() }
override fun getByLoginAndPassword(login: String, pass: String): Single<User> { override fun getByLoginAndPassword(login: String, pass: String): Single<User> {
return service.getUserLP(login, pass).map { return service.getUserLP(login, pass).map {
Log.d(RestUserRepository::class.simpleName ,it.toString()) Log.d(RestUserRepository::class.simpleName ,"load user by lp")
database.runInTransaction{
dbUserRepository.deleteAll().blockingAwait()
dbUserRepository.insert(it.toUser()).blockingAwait()
}
it.toUser() } it.toUser() }
} }
override fun insert(group: User): Completable = Completable.fromObservable(service.createUser(group.toUserDto())) override fun insert(group: User): Completable = Completable.fromObservable(service.createUser(group.toUserDto()))

View File

@ -34,12 +34,12 @@ interface MyServerService {
): Flowable<List<PizzaDto>> ): Flowable<List<PizzaDto>>
@GET("allpizzas") @GET("allpizzas")
fun getAllPizzas( fun getAllPizzas(
): Observable<List<PizzaDto>> ): Flowable<List<PizzaDto>>
@GET("baskets/{id}") @GET("baskets/{id}")
fun getUserBaskets( fun getUserBaskets(
@Path("id") id: Int, @Path("id") id: Int,
): Observable<List<BasketDto>> ): Flowable<List<BasketDto>>
@GET("pizza/{id}") @GET("pizza/{id}")
fun getPizza( fun getPizza(
@ -51,9 +51,9 @@ interface MyServerService {
@GET("orders/{id}") @GET("orders/{id}")
fun getUserOrders( fun getUserOrders(
@Path("id") id: Int, @Path("id") id: Int,
@Query("page") page: Int, @Query("limit") limit: Int,
@Query("size") limit: Int, @Query("offset") offset: Int,
): Observable<List<OrderDto>> ): Flowable<List<OrderDto>>
@GET("orders") @GET("orders")
fun getAllOrders( fun getAllOrders(
): Observable<List<OrderDto>> ): Observable<List<OrderDto>>
@ -110,11 +110,12 @@ interface MyServerService {
@DELETE("baskets/{id}") @DELETE("baskets/{id}")
fun deleteUserBaskets( fun deleteUserBaskets(
@Path("id") id: Int, @Path("id") id: Int,
): Observable<BasketDto> ): Observable<List<BasketDto>>
@DELETE("basket") @DELETE("basket")
fun deleteBasket( fun deleteBasket(
@Body user: BasketDto, @Query("uid") uid : Int ,
@Query("pid") pid : Int
): Observable<BasketDto> ): Observable<BasketDto>
companion object { companion object {

View File

@ -26,7 +26,8 @@ interface UserDao {
@Update @Update
fun update(group: User): Completable fun update(group: User): Completable
@Query("DELETE FROM users")
fun deleteAll(): Completable
@Delete @Delete
fun delete(group: User): Completable fun delete(group: User): Completable
} }

View File

@ -34,7 +34,7 @@ class BasketListViewModel(private val basketRepository: BasketRepository): ViewM
} }
@SuppressLint("CheckResult") @SuppressLint("CheckResult")
fun getAllBaskets(uid : Int, onLoad: (data : List<PizzaBasket>) -> Unit, onError: () -> Unit){ fun getAllBaskets(uid : Int, onLoad: (data : List<PizzaBasket>) -> Unit, onError: () -> Unit){
basketRepository.getUserAllBasket(uid) basketRepository.getUserBasket(uid)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe( { data -> .subscribe( { data ->
@ -42,31 +42,18 @@ class BasketListViewModel(private val basketRepository: BasketRepository): ViewM
},{onError()}) },{onError()})
} }
private fun createPagingConfig(): PagingConfig {
val pageSize = 5
val placeholders = true
return PagingConfig(
pageSize,
pageSize,
placeholders,
pageSize * 2,
pageSize + pageSize * 2, Int.MIN_VALUE
)
}
@OptIn(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class)
private fun loadPizzas(uid: Int) { private fun loadPizzas(uid: Int) {
val disposable = Pager( val disposable = basketRepository.getUserBasket(uid)
config = createPagingConfig(),
pagingSourceFactory = {basketRepository.getUserBasket(uid)}
).flowable
.cachedIn(viewModelScope)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.doOnError({pizzas.value = null}) .doOnError({pizzas.value = null})
.subscribe { data -> .subscribe { data ->
pizzas.postValue(data) val ps = PagingData.from<PizzaBasket>(data)
pizzas.postValue(ps)
} }
mDisposable.add(disposable) mDisposable.add(disposable)
} }
@ -75,7 +62,7 @@ class BasketListViewModel(private val basketRepository: BasketRepository): ViewM
val disposable = basketRepository.deleteByUserAndPizza(uid,pid) val disposable = basketRepository.deleteByUserAndPizza(uid,pid)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(onDelete) .subscribe { onDelete() }
mDisposable.add(disposable) mDisposable.add(disposable)
} }
fun deleteAllPizza(uid:Int) { fun deleteAllPizza(uid:Int) {

View File

@ -19,7 +19,7 @@ class OrderEditViewModel(
fun savePizza(pizzas: List<Order>, onSave: () -> Unit) { fun savePizza(pizzas: List<Order>, onSave: () -> Unit) {
val completable: Completable = orderRepository.insertMany(pizzas) val completable: Completable = orderRepository.insertAll(pizzas)
val disposable = completable val disposable = completable
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())

View File

@ -1,5 +1,7 @@
package com.example.pizza.ViewModels package com.example.pizza.ViewModels
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
@ -8,12 +10,9 @@ import androidx.paging.ExperimentalPagingApi
import androidx.paging.Pager import androidx.paging.Pager
import androidx.paging.PagingConfig import androidx.paging.PagingConfig
import androidx.paging.PagingData import androidx.paging.PagingData
import androidx.paging.PagingSource
import androidx.paging.rxjava3.cachedIn import androidx.paging.rxjava3.cachedIn
import androidx.paging.rxjava3.flowable import androidx.paging.rxjava3.flowable
import com.example.pizza.Model.Basket.PizzaBasket
import com.example.pizza.Model.Order.PizzaOrder import com.example.pizza.Model.Order.PizzaOrder
import com.example.pizza.Model.Repository.BasketRepository
import com.example.pizza.Model.Repository.OrderRepository import com.example.pizza.Model.Repository.OrderRepository
import com.example.pizza.Model.Repository.Rest.RestOrderRepository import com.example.pizza.Model.Repository.Rest.RestOrderRepository
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
@ -25,7 +24,7 @@ class OrderListViewModel(private val orderRepository: OrderRepository): ViewMode
private val mDisposable = CompositeDisposable() private val mDisposable = CompositeDisposable()
private val pizzas: MutableLiveData<PagingData<PizzaOrder>?> = MutableLiveData() private val pizzas: MutableLiveData<PagingData<PizzaOrder>?> = MutableLiveData()
@RequiresApi(Build.VERSION_CODES.O)
fun getPizzas(uid: Int): LiveData<PagingData<PizzaOrder>?> { fun getPizzas(uid: Int): LiveData<PagingData<PizzaOrder>?> {
loadPizzas(uid) loadPizzas(uid)
return pizzas return pizzas
@ -34,26 +33,28 @@ class OrderListViewModel(private val orderRepository: OrderRepository): ViewMode
@OptIn(ExperimentalCoroutinesApi::class, ExperimentalPagingApi::class) @OptIn(ExperimentalCoroutinesApi::class, ExperimentalPagingApi::class)
@RequiresApi(Build.VERSION_CODES.O)
private fun loadPizzas(uid: Int) { private fun loadPizzas(uid: Int) {
val pageSize = 3 val pageSize = 10
val placeholders = true val placeholders = true
var config = PagingConfig( var config = PagingConfig(
pageSize = pageSize, pageSize = pageSize,
enablePlaceholders =placeholders enablePlaceholders =placeholders
) )
// val disposable = Pager( val disposable = Pager(
// config = config, config = config,
// remoteMediator = (orderRepository as RestOrderRepository).mediator, pagingSourceFactory = {orderRepository.getUserHistory(uid)},
// pagingSourceFactory = { orderRepository.getUserHistory(uid) } remoteMediator = (orderRepository as RestOrderRepository).mediator
// ).flowable
// .cachedIn(viewModelScope) ).flowable
// .subscribeOn(Schedulers.io()) .cachedIn(viewModelScope)
// .observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.io())
// .doOnError({pizzas.value = null}) .observeOn(AndroidSchedulers.mainThread())
// .subscribe { data -> .doOnError({pizzas.value = null})
// pizzas.postValue(data) .subscribe { data ->
// } pizzas.postValue(data)
// mDisposable.add(disposable) }
mDisposable.add(disposable)
} }
override fun onCleared() { override fun onCleared() {

View File

@ -101,7 +101,7 @@ class crate : Fragment() {
val child = itemsList.getChildAt(i) val child = itemsList.getChildAt(i)
val price = child.findViewById<TextView>(R.id.order_sum).text.toString().toInt() val price = child.findViewById<TextView>(R.id.order_sum).text.toString().toInt()
list.add(Order(null, currentDate, listPizzas.get(i).pizza_id, list.add(Order(null, currentDate, listPizzas.get(i).pizza_id,
viewModel.getId(), price)) viewModel.getId()!!, price))
} }
basketVM!!.deleteAllPizza(viewModel.getId()!!) basketVM!!.deleteAllPizza(viewModel.getId()!!)
orderViewModel!!.savePizza(list){ orderViewModel!!.savePizza(list){

View File

@ -47,6 +47,7 @@ class AppDataContainer(private val context: Context) : AppContainer {
MyServerService.getInstance(), MyServerService.getInstance(),
OfflineBasketRepository(AppDatabase.getInstance(context).basketDao()), OfflineBasketRepository(AppDatabase.getInstance(context).basketDao()),
OfflinePizzaRepository(AppDatabase.getInstance(context).pizzaDao()), OfflinePizzaRepository(AppDatabase.getInstance(context).pizzaDao()),
OfflineUserRepository(AppDatabase.getInstance(context).userDao()),
OfflineRemoteKeyRepository(AppDatabase.getInstance(context).remoteKeysDao()), OfflineRemoteKeyRepository(AppDatabase.getInstance(context).remoteKeysDao()),
AppDatabase.getInstance(context)) AppDatabase.getInstance(context))
} }

View File

@ -49,7 +49,7 @@ abstract class AppDatabase : RoomDatabase() {
abstract fun orderDao(): OrderDao abstract fun orderDao(): OrderDao
abstract fun remoteKeysDao(): RemoteKeysDao abstract fun remoteKeysDao(): RemoteKeysDao
companion object { companion object {
private const val DB_NAME: String = "dp11" private const val DB_NAME: String = "dp14"
@Volatile @Volatile
private var INSTANCE: AppDatabase? = null private var INSTANCE: AppDatabase? = null

View File

@ -1,6 +1,7 @@
package com.example.pizza package com.example.pizza
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.os.Build
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import android.view.LayoutInflater import android.view.LayoutInflater
@ -9,6 +10,7 @@ import android.view.ViewGroup
import android.widget.Button import android.widget.Button
import android.widget.TextView import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
@ -51,6 +53,7 @@ class user : Fragment() {
) )
orderViewModel = viewModel2 orderViewModel = viewModel2
} }
@RequiresApi(Build.VERSION_CODES.O)
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
val pizzas: LiveData<PagingData<PizzaOrder>?>? = orderViewModel?.getPizzas(viewModel.getId()!!) val pizzas: LiveData<PagingData<PizzaOrder>?>? = orderViewModel?.getPizzas(viewModel.getId()!!)