lab 5 work

This commit is contained in:
Володя 2023-12-20 19:45:20 +03:00
parent ef7a12a123
commit 0c949919d8
37 changed files with 1023 additions and 61 deletions

View File

@ -4,6 +4,7 @@ plugins {
id("org.jetbrains.kotlin.android")
id("androidx.navigation.safeargs.kotlin")
id("kotlin-kapt")
kotlin("plugin.serialization") version "1.4.21"
}
android {
@ -75,6 +76,16 @@ dependencies {
// optional - RxJava3 support
implementation("androidx.paging:paging-rxjava3:$paging_version")
//retrofit
val retrofitVersion = "2.9.0"
implementation("com.squareup.retrofit2:retrofit:$retrofitVersion")
implementation("com.squareup.retrofit2:adapter-rxjava3:$retrofitVersion")
implementation("com.squareup.retrofit2:converter-moshi:$retrofitVersion")
implementation("com.squareup.okhttp3:logging-interceptor:4.11.0")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1")
implementation("com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:1.0.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
// Test
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")

View File

@ -1,7 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:name=".PizzaApplication"
android:allowBackup="true"
@ -12,6 +16,8 @@
android:roundIcon="@drawable/icon"
android:supportsRtl="true"
android:theme="@style/Theme.Pizza"
android:usesCleartextTraffic="true"
android:networkSecurityConfig="@xml/network_security_config"
tools:targetApi="31">
<activity
android:name=".MainActivity"

View File

@ -2,6 +2,7 @@ package com.example.pizza
import android.annotation.SuppressLint
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@ -89,6 +90,10 @@ class Auth : Fragment() {
.actionNavigationAuthToNavigationReg(-1)
Navigation.findNavController(view).navigate(action)
}
fun openURL() {
val openURL = Intent(Intent.ACTION_VIEW)
openURL.data = Uri.parse("https://ulstu.ru/")
startActivity(openURL)
}
}

View File

@ -18,6 +18,8 @@ interface BasketDao {
fun getUserAllBasket(uid: Int): Flowable<List<PizzaBasket>>
@Insert
fun insert(group: Basket): Completable
@Insert
fun insertAll(group: List<Basket>): Completable
@Update
fun update(group: Basket): Completable
@ -26,6 +28,8 @@ interface BasketDao {
fun delete(group: Basket): Completable
@Query("delete from basket where basket.user_id = :uid")
fun deleteByUser(uid : Int): Completable
@Query("delete from basket ")
fun deleteAll(): Completable
@Query("delete from basket where basket.user_id = :uid and basket.pizza_id = :pid")
fun deleteByUserAndPizza(uid : Int, pid:Int): Completable
}

View File

@ -0,0 +1,22 @@
package com.example.pizza.Model.Dto
import com.example.pizza.Model.Basket.Basket
import com.example.pizza.Model.Pizza.Pizza
import com.google.gson.annotations.SerializedName
import kotlinx.serialization.Serializable
@Serializable
data class BasketDto(
@SerializedName("user")val user: Int,
@SerializedName("pizza")val pizza: Int,
@SerializedName("count")val countPizza: Int = 1
){
}
fun BasketDto.toBasket(): Basket = Basket(
user, pizza, countPizza)
fun Basket.toBasketDto(): BasketDto = BasketDto(
user, pizza, countPizza
)

View File

@ -0,0 +1,22 @@
package com.example.pizza.Model.Dto
import com.example.pizza.Model.Order.Order
import com.example.pizza.Model.Pizza.Pizza
import kotlinx.serialization.Serializable
import java.util.Date
@Serializable
data class OrderDto(
val uid : Int? = 0,
val date: Long = 0,
val pizza: Int? = 0,
val user: Int? = 0,
val price : Int = 0
)
fun OrderDto.toOrder(): Order = Order(
uid, Date(date), pizza, user, price)
fun Order.toOrderDto(): OrderDto = OrderDto(
uid, date.time, pizza, user, price
)

View File

@ -0,0 +1,45 @@
package com.example.pizza.Model.Dto
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.Build
import androidx.annotation.RequiresApi
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.User.User
import kotlinx.serialization.Serializable
import java.io.ByteArrayOutputStream
import java.util.Base64
@Serializable
data class PizzaDto(
val id : Int?,
val title : String,
val price : Int,
val image : String,
val ingredients : String
){
constructor(
title : String,
price : Int,
image : String,
ingredients : String
) : this(null, title,price, image, ingredients)
}
@RequiresApi(Build.VERSION_CODES.O)
fun PizzaDto.toPizza(): Pizza = Pizza(
id,
title, BitmapFactory.decodeByteArray(Base64.getDecoder().decode(image), 0, Base64.getDecoder().decode(image).size),ingredients,price)
@RequiresApi(Build.VERSION_CODES.O)
fun Pizza.toPizzaDto(): PizzaDto {
val outputStream = ByteArrayOutputStream()
image?.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
val encoded = Base64.getEncoder().encodeToString(outputStream.toByteArray())
return PizzaDto(uid, title,price, encoded, ingredients, )
}

View File

@ -0,0 +1,31 @@
package com.example.pizza.Model.Dto
import com.example.pizza.Model.User.User
import com.google.gson.annotations.SerializedName
import kotlinx.serialization.Serializable
@Serializable
data class UserDto(
@SerializedName("id")val id : Int?,
@SerializedName("login")val login : String?,
@SerializedName("email")val email : String?,
@SerializedName("password")val password : String?,
@SerializedName("role")val role : String?
){
constructor(
login: String,
email : String,
password: String,
role : String
) : this(null, login,email,password,role)
}
fun UserDto.toUser(): User = User(
id,
login?:"", email?:"", password?:"", role?:"")
fun User.toUserDto(): UserDto = UserDto(
uid,
login, email, password, role
)

View File

@ -18,6 +18,10 @@ interface OrderDao {
@Insert
fun insert(group: Order): Completable
@Delete
fun delete(group: Order): Completable
@Query("DELETE FROM pizzas")
fun deleteAll(): Completable
@Insert
fun insertMany(group: List<Order>): Completable

View File

@ -16,14 +16,20 @@ import io.reactivex.rxjava3.core.Single
interface PizzaDao {
@Query("select * from pizzas")
fun getAll(): RxPagingSource<Int, Pizza>
@Query("select * from pizzas where pizzas.uid = :uid")
fun getById(uid : Int): Single<Pizza>
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(group: Pizza): Completable
@Insert
fun insertAll(group: List<Pizza>): Completable
@Update
fun update(group: Pizza): Completable
@Delete
fun delete(group: Pizza): Completable
@Query("DELETE FROM pizzas")
fun deleteAll(): Completable
}

View File

@ -63,7 +63,7 @@ class PizzaAdapter(var context: Context,
holder.price.text = currentPizza.price.toString()
holder.image.setImageBitmap(currentPizza.image)
holder.btn.setOnClickListener { addToBasket(holder, position) }
holder.image.setOnClickListener{ onClick(position+1) }
holder.image.setOnClickListener{ onClick(pizza.uid!!) }
}
}
fun addToBasket(holder: PizzaAdapter.MyViewHolder, position: Int){

View File

@ -13,6 +13,7 @@ class OfflineBasketRepository(private val basketDao : BasketDao) : BasketReposit
override fun getUserAllBasket(uid: Int): Flowable<List<PizzaBasket>> = basketDao.getUserAllBasket(uid)
override fun insert(group: Basket): Completable = basketDao.insert(group)
fun insertAll(group: List<Basket>): Completable = basketDao.insertAll(group)
override fun update(group: Basket): Completable = basketDao.update(group)
@ -20,5 +21,6 @@ class OfflineBasketRepository(private val basketDao : BasketDao) : BasketReposit
override fun deleteByUser(uid: Int): Completable = basketDao.deleteByUser(uid)
fun deleteAll(): Completable = basketDao.deleteAll()
override fun deleteByUserAndPizza(uid: Int, pid: Int): Completable = basketDao.deleteByUserAndPizza(uid,pid)
}

View File

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

View File

@ -15,4 +15,7 @@ class OfflinePizzaRepository(private val pizzaDao : PizzaDao) : PizzaRepository
override fun update(group: Pizza): Completable = pizzaDao.update(group)
override fun delete(group: Pizza): Completable = pizzaDao.delete(group)
override fun deleteAll(): Completable = pizzaDao.deleteAll()
override fun insertAll(pizzas: List<Pizza>): Completable = pizzaDao.insertAll(pizzas)
}

View File

@ -11,7 +11,7 @@ import io.reactivex.rxjava3.core.Single
class OfflineUserRepository(private val userDao : UserDao) : UserRepository {
override fun getById(uid: Int): Single<User> = userDao.getById(uid)
override fun getAll(): Flowable<List<User>> = userDao.getAll()
fun getAll(): Flowable<List<User>> = throw Exception()
override fun getByLoginAndPassword(login: String, pass: String): Single<User> = userDao.getByLoginAndPassword(login,pass)

View File

@ -11,4 +11,6 @@ interface PizzaRepository {
fun insert(group: Pizza): Completable
fun update(group: Pizza): Completable
fun delete(group: Pizza): Completable
fun deleteAll() : Completable
fun insertAll(pizzas: List<Pizza>) : Completable
}

View File

@ -0,0 +1,150 @@
package com.example.pizza.Model.Repository.Rest.Mediators
import android.annotation.SuppressLint
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.lifecycle.LiveData
import androidx.paging.ExperimentalPagingApi
import androidx.paging.LoadType
import androidx.paging.PagingState
import androidx.paging.RemoteMediator
import androidx.paging.rxjava3.RxRemoteMediator
import com.example.pizza.Model.Dto.toOrder
import com.example.pizza.Model.Dto.toPizza
import com.example.pizza.Model.Order.Order
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.Repository.OfflineOrderRepository
import com.example.pizza.Model.Repository.OfflinePizzaRepository
import com.example.pizza.Model.Rest.MyServerService
import com.example.pizza.RemoteKeys.OfflineRemoteKeyRepository
import com.example.pizza.RemoteKeys.RemoteKeyType
import com.example.pizza.RemoteKeys.RemoteKeys
import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.schedulers.Schedulers
import java.io.InvalidObjectException
import java.util.concurrent.atomic.AtomicInteger
@OptIn(ExperimentalPagingApi::class)
class OrderRemoteMediator(
private val service: MyServerService,
private val dbOrderRepository: OfflineOrderRepository,
private val dbPizzaRepository: OfflinePizzaRepository,
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
private val database: AppDatabase,
private val id : Int
): RxRemoteMediator<Int, Order>() {
@RequiresApi(Build.VERSION_CODES.O)
override fun loadSingle(
loadType: LoadType,
state: PagingState<Int, Order>
): Single<MediatorResult> {
Log.d(this::class.simpleName, state.toString())
return when (loadType){
LoadType.REFRESH -> getRemoteKeyClosestToCurrentPosition(state).subscribeOn(Schedulers.io()).toSingle().map{
Log.d("StudentRemoteMediator", "Refresh" + it.toString())
val page = AtomicInteger(it?.nextKey?.minus(1)?:1)
getMediatorResout(loadType,page,state).blockingGet()
}.onErrorReturn {
data -> Log.d(this::class.simpleName, data.message?:"not message this")
getMediatorResout(loadType, AtomicInteger(1),state).blockingGet() }
LoadType.PREPEND ->
getRemoteKeyForFirstItem(state).subscribeOn(Schedulers.io()).toSingle().map {
Log.d("StudentRemoteMediator", "PREPEND" + it.toString())
if(it?.prevKey != null) {
getMediatorResout(loadType, AtomicInteger(it.prevKey),state).blockingGet()
}
else {
MediatorResult.Success(endOfPaginationReached = it != null)
}
}.onErrorReturn{
data ->Log.d("StudentRemoteMediator", data.message?:"not message this")
MediatorResult.Success(false)}
LoadType.APPEND ->
getRemoteKeyForLastItem(state).subscribeOn(Schedulers.io()).toSingle().map{
Log.d("StudentRemoteMediator", "APPEND" + it.toString())
Log.d(this::class.simpleName, "trying to load more")
if(it?.nextKey != null) {
getMediatorResout(loadType,AtomicInteger(it.nextKey),state).blockingGet()
}
else {
MediatorResult.Success(endOfPaginationReached = it != null)
}
}
.onErrorReturn{
data ->
Log.d(this::class.simpleName, data.message?:"not message this")
MediatorResult.Success(false)}
}
}
@SuppressLint("CheckResult")
@RequiresApi(Build.VERSION_CODES.O)
fun getMediatorResout(loadType: LoadType, page : AtomicInteger, state: PagingState<Int, Order>)
: Single<MediatorResult> {
Log.d(PizzaRemoteMediator::class.simpleName,"Load")
service.getAllPizzas()
.subscribeOn(Schedulers.io())
.map{
database.runInTransaction {
dbPizzaRepository.deleteAll().blockingAwait()
}
dbPizzaRepository.insertAll(it.map { it.toPizza() }).blockingAwait()
}
return service.getUserOrders(id,state.config.pageSize,(page.get()-1)*state.config.pageSize)
.subscribeOn(Schedulers.io())
.map{
database.runInTransaction {
if(loadType == LoadType.REFRESH) {
dbOrderRepository.deleteAll().blockingAwait()
dbRemoteKeyRepository.deleteRemoteKey(RemoteKeyType.ORDER).blockingAwait()
}
dbOrderRepository.insertMany(it.map { it.toOrder() }).blockingAwait()
val prevKey = if (page.get() == 1) null else page.get() - 1
val nextKey = if (it.isEmpty()) null else page.get() + 1
val keys = it.map {
RemoteKeys(
entityId = it.uid!!,
type = RemoteKeyType.ORDER,
prevKey = prevKey,
nextKey = nextKey
)
}
dbRemoteKeyRepository.createRemoteKeys(keys).blockingAwait()
}
MediatorResult.Success(it.isEmpty()) as MediatorResult
}.singleOrError()
.onErrorResumeNext {
e->
Single.just(MediatorResult.Error(e) as MediatorResult)
}
}
private fun getRemoteKeyForLastItem(state: PagingState<Int, Order>): Maybe<RemoteKeys> {
return state.pages.lastOrNull { it.data.isNotEmpty() }?.data?.lastOrNull()
?.let { group ->
dbRemoteKeyRepository.getAllRemoteKeys(group.uid!!, RemoteKeyType.ORDER)
} ?: Maybe.empty()
}
private fun getRemoteKeyForFirstItem(state: PagingState<Int, Order>): Maybe<RemoteKeys> {
return state.pages.firstOrNull { it.data.isNotEmpty() }?.data?.firstOrNull()
?.let { group ->
dbRemoteKeyRepository.getAllRemoteKeys(group.uid!!, RemoteKeyType.ORDER)
}?: Maybe.empty()
}
private fun getRemoteKeyClosestToCurrentPosition( state: PagingState<Int, Order>): Maybe<RemoteKeys> {
return state.anchorPosition?.let { position ->
state.closestItemToPosition(position)?.uid?.let { studentUid ->
dbRemoteKeyRepository.getAllRemoteKeys(studentUid, RemoteKeyType.ORDER)
}
}?: Maybe.empty()
}
}

View File

@ -0,0 +1,140 @@
package com.example.pizza.Model.Repository.Rest.Mediators
import android.annotation.SuppressLint
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.paging.ExperimentalPagingApi
import androidx.paging.LoadType
import androidx.paging.PagingState
import androidx.paging.RemoteMediator
import androidx.paging.rxjava3.RxRemoteMediator
import com.example.pizza.Model.Dto.PizzaDto
import com.example.pizza.Model.Dto.toPizza
import com.example.pizza.Model.Pizza.Pizza
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.User.User
import com.example.pizza.RemoteKeys.OfflineRemoteKeyRepository
import com.example.pizza.RemoteKeys.RemoteKeyType
import com.example.pizza.RemoteKeys.RemoteKeys
import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.schedulers.Schedulers
import java.io.InvalidObjectException
import java.util.concurrent.atomic.AtomicInteger
@OptIn(ExperimentalPagingApi::class)
class PizzaRemoteMediator(
private val service: MyServerService,
private val dbPizzaRepository: OfflinePizzaRepository,
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
private val database: AppDatabase
) : RxRemoteMediator<Int, Pizza>(){
@RequiresApi(Build.VERSION_CODES.O)
override fun loadSingle(
loadType: LoadType,
state: PagingState<Int, Pizza>
): Single<MediatorResult> {
Log.d(this::class.simpleName, state.toString())
return when (loadType){
LoadType.REFRESH -> getRemoteKeyClosestToCurrentPosition(state).subscribeOn(Schedulers.io()).toSingle().map{
Log.d("StudentRemoteMediator", "Refresh" + it.toString())
val page = AtomicInteger(it?.nextKey?.minus(1)?:1)
getMediatorResout(loadType,page,state).blockingGet()
}.onErrorReturn {
data -> Log.d(this::class.simpleName, data.message?:"not message this")
getMediatorResout(loadType, AtomicInteger(1),state).blockingGet() }
LoadType.PREPEND ->
getRemoteKeyForFirstItem(state).subscribeOn(Schedulers.io()).toSingle().map {
Log.d("StudentRemoteMediator", "PREPEND" + it.toString())
if(it?.prevKey != null) {
getMediatorResout(loadType, AtomicInteger(it.prevKey),state).blockingGet()
}
else {
MediatorResult.Success(endOfPaginationReached = it != null)
}
}.onErrorReturn{
data ->Log.d("StudentRemoteMediator", data.message?:"not message this")
MediatorResult.Success(false)}
LoadType.APPEND ->
getRemoteKeyForLastItem(state).subscribeOn(Schedulers.io()).toSingle().map{
Log.d("StudentRemoteMediator", "APPEND" + it.toString())
Log.d(this::class.simpleName, "trying to load more")
if(it?.nextKey != null) {
getMediatorResout(loadType,AtomicInteger(it.nextKey),state).blockingGet()
}
else {
MediatorResult.Success(endOfPaginationReached = it != null)
}
}
.onErrorReturn{
data ->
Log.d(this::class.simpleName, data.message?:"not message this")
MediatorResult.Success(false)}
}
}
@SuppressLint("CheckResult")
@RequiresApi(Build.VERSION_CODES.O)
fun getMediatorResout(loadType: LoadType, page : AtomicInteger, state: PagingState<Int, Pizza>)
: Single<MediatorResult> {
Log.d(PizzaRemoteMediator::class.simpleName,"Load")
return service.getPizzas(state.config.pageSize,(page.get()-1)*state.config.pageSize)
.subscribeOn(Schedulers.io())
.map{
database.runInTransaction {
if(loadType == LoadType.REFRESH) {
dbPizzaRepository.deleteAll().blockingAwait()
dbRemoteKeyRepository.deleteRemoteKey(RemoteKeyType.PIZZA).blockingAwait()
}
dbPizzaRepository.insertAll(it.map { it.toPizza() }).blockingAwait()
val prevKey = if (page.get() == 1) null else page.get() - 1
val nextKey = if (it.isEmpty()) null else page.get() + 1
val keys = it.map {
RemoteKeys(
entityId = it.id!!,
type = RemoteKeyType.PIZZA,
prevKey = prevKey,
nextKey = nextKey
)
}
dbRemoteKeyRepository.createRemoteKeys(keys).blockingAwait()
}
MediatorResult.Success(it.isEmpty()) as MediatorResult
}.singleOrError()
.onErrorResumeNext {
e->
Single.just(MediatorResult.Error(e) as MediatorResult)
}
}
private fun getRemoteKeyForLastItem(state: PagingState<Int, Pizza>): Maybe<RemoteKeys> {
return state.pages.lastOrNull { it.data.isNotEmpty() }?.data?.lastOrNull()
?.let { group ->
dbRemoteKeyRepository.getAllRemoteKeys(group.uid!!, RemoteKeyType.PIZZA)
} ?: Maybe.empty()
}
private fun getRemoteKeyForFirstItem(state: PagingState<Int, Pizza>): Maybe<RemoteKeys> {
return state.pages.firstOrNull { it.data.isNotEmpty() }?.data?.firstOrNull()
?.let { group ->
dbRemoteKeyRepository.getAllRemoteKeys(group.uid!!, RemoteKeyType.PIZZA)
}?: Maybe.empty()
}
private fun getRemoteKeyClosestToCurrentPosition( state: PagingState<Int, Pizza>): Maybe<RemoteKeys> {
return state.anchorPosition?.let { position ->
state.closestItemToPosition(position)?.uid?.let { studentUid ->
dbRemoteKeyRepository.getAllRemoteKeys(studentUid, RemoteKeyType.PIZZA)
}
}?: Maybe.empty()
}
}

View File

@ -0,0 +1,80 @@
package com.example.pizza.Model.Repository.Rest
import android.annotation.SuppressLint
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.lifecycle.MutableLiveData
import androidx.paging.rxjava3.RxPagingSource
import com.example.pizza.Model.Basket.Basket
import com.example.pizza.Model.Basket.PizzaBasket
import com.example.pizza.Model.Dto.BasketDto
import com.example.pizza.Model.Dto.toBasket
import com.example.pizza.Model.Dto.toBasketDto
import com.example.pizza.Model.Dto.toPizza
import com.example.pizza.Model.Dto.toUserDto
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.Repository.BasketRepository
import com.example.pizza.Model.Repository.OfflineBasketRepository
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.RemoteKeys.OfflineRemoteKeyRepository
import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.schedulers.Schedulers
import okhttp3.internal.wait
class RestBasketRepository(private val service: MyServerService,
private val dbBasketRepository: OfflineBasketRepository,
private val dbPizzaRepository: OfflinePizzaRepository,
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
private val database: AppDatabase
) : BasketRepository {
var AllBaskets : MutableLiveData<RxPagingSource<Int, PizzaBasket>?> = MutableLiveData()
@RequiresApi(Build.VERSION_CODES.O)
@SuppressLint("CheckResult")
override fun getUserBasket(uid: Int): RxPagingSource<Int, PizzaBasket> {
insertAll(uid)
return AllBaskets.value!!
}
@RequiresApi(Build.VERSION_CODES.O)
@SuppressLint("CheckResult")
fun insertAll(uid: Int){
Log.d("RestBasketRepository", "Insert All")
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{
dbBasketRepository.deleteAll().blockingAwait()
dbPizzaRepository.deleteAll().blockingAwait()
dbBasketRepository.insertAll(bks).blockingAwait()
dbPizzaRepository.insertAll(ps).blockingAwait()
}
}.map { dbBasketRepository.getUserBasket(uid) }.subscribe { data -> AllBaskets.postValue(data)}
}
@SuppressLint("CheckResult")
override fun insert(group: Basket): Completable = Completable.fromObservable(service.createBasket(group.toBasketDto()))
override fun getUserAllBasket(uid: Int): Flowable<List<PizzaBasket>> {
return dbBasketRepository.getUserAllBasket(uid)
}
override fun update(group: Basket): Completable = throw Exception()
override fun delete(group: Basket): Completable {
throw Exception()
}
override fun deleteByUser(uid: Int): Completable = Completable.fromObservable(service.deleteUserBaskets(uid))
override fun deleteByUserAndPizza(uid: Int, pid: Int): Completable = Completable.fromObservable(service.deleteBasket(
BasketDto(uid,pid,1)
))
}

View File

@ -0,0 +1,54 @@
package com.example.pizza.Model.Repository.Rest
import android.database.Observable
import androidx.paging.rxjava3.RxPagingSource
import androidx.room.Index
import com.example.pizza.Model.Dto.OrderDto
import com.example.pizza.Model.Dto.toOrderDto
import com.example.pizza.Model.Order.Order
import com.example.pizza.Model.Order.PizzaOrder
import com.example.pizza.Model.Repository.OfflineOrderRepository
import com.example.pizza.Model.Repository.OfflinePizzaRepository
import com.example.pizza.Model.Repository.OrderRepository
import com.example.pizza.Model.Repository.Rest.Mediators.OrderRemoteMediator
import com.example.pizza.Model.Repository.Rest.Mediators.PizzaRemoteMediator
import com.example.pizza.Model.Rest.MyServerService
import com.example.pizza.RemoteKeys.OfflineRemoteKeyRepository
import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.core.Completable
class RestOrderRepository(private val service: MyServerService,
private val dbOrderRepository: OfflineOrderRepository,
private val dbPizzaRepository: OfflinePizzaRepository,
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
private val database: AppDatabase
) : OrderRepository {
var mediator: OrderRemoteMediator? = null
override fun getUserHistory(uid: Int): RxPagingSource<Int, PizzaOrder> {
if (mediator==null){
mediator = OrderRemoteMediator(
service,
dbOrderRepository,
dbPizzaRepository,
dbRemoteKeyRepository,
database,
uid
)
}
return dbOrderRepository.getUserHistory(uid)
}
override fun insert(group: Order): Completable = Completable.fromObservable(service.createOrder(group.toOrderDto()))
override fun insertMany(orders: List<Order>): Completable
{
var list : MutableList <OrderDto> = mutableListOf<OrderDto>()
for (order in orders){
list.add(order.toOrderDto())
}
return Completable.fromObservable(service.createOrders(list))
}
}

View File

@ -0,0 +1,62 @@
package com.example.pizza.Model.Repository.Rest
import android.annotation.SuppressLint
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.paging.rxjava3.RxPagingSource
import com.example.pizza.Model.Dto.toPizza
import com.example.pizza.Model.Dto.toPizzaDto
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.Repository.OfflinePizzaRepository
import com.example.pizza.Model.Repository.PizzaRepository
import com.example.pizza.Model.Repository.Rest.Mediators.PizzaRemoteMediator
import com.example.pizza.Model.Rest.MyServerService
import com.example.pizza.RemoteKeys.OfflineRemoteKeyRepository
import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.schedulers.Schedulers
import java.net.ConnectException
import java.net.SocketTimeoutException
class RestPizzaRepository(
private val service: MyServerService,
private val dbPizzaRepository: OfflinePizzaRepository,
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
private val database: AppDatabase
) : PizzaRepository{
var mediator: PizzaRemoteMediator? = null
override fun getAll(): RxPagingSource<Int, Pizza> {
if (mediator==null){
mediator = PizzaRemoteMediator(
service,
dbPizzaRepository,
dbRemoteKeyRepository,
database,
)
}
return dbPizzaRepository.getAll()
}
@RequiresApi(Build.VERSION_CODES.O)
@SuppressLint("CheckResult")
override fun getById(uid: Int): Single<Pizza> {
return service.getPizza(uid).subscribeOn(Schedulers.io()).map { it.toPizza() }
}
@RequiresApi(Build.VERSION_CODES.O)
override fun insert(group: Pizza): Completable = Completable.fromObservable(
service.createPizza(group.toPizzaDto()))
@RequiresApi(Build.VERSION_CODES.O)
override fun update(group: Pizza): Completable = Completable.fromObservable(
service.updatePizza(group.uid!!,group.toPizzaDto()))
override fun delete(group: Pizza): Completable = throw Exception()
override fun deleteAll(): Completable = throw Exception()
override fun insertAll(pizzas: List<Pizza>): Completable = throw Exception()
}

View File

@ -0,0 +1,41 @@
package com.example.pizza.Model.Repository.Rest
import android.annotation.SuppressLint
import android.util.Log
import androidx.paging.ExperimentalPagingApi
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import com.example.pizza.Model.Dto.toUser
import com.example.pizza.Model.Dto.toUserDto
import com.example.pizza.Model.Repository.OfflineUserRepository
import com.example.pizza.Model.Repository.UserRepository
import com.example.pizza.Model.Rest.MyServerService
import com.example.pizza.Model.User.User
import com.example.pizza.RemoteKeys.OfflineRemoteKeyRepository
import com.example.pizza.database.AppDatabase
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Single
class RestUserRepository (
private val service: MyServerService,
private val dbUserRepository: OfflineUserRepository,
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
private val database: AppDatabase
) : UserRepository {
@SuppressLint("CheckResult")
override fun getById(uid: Int): Single<User> = service.getUser(uid).map { it.toUser() }
override fun getByLoginAndPassword(login: String, pass: String): Single<User> {
return service.getUserLP(login, pass).map {
Log.d(RestUserRepository::class.simpleName ,it.toString())
it.toUser() }
}
override fun insert(group: User): Completable = Completable.fromObservable(service.createUser(group.toUserDto()))
override fun update(group: User): Completable = Completable.fromObservable(service.updateUser(group.uid!!,group.toUserDto()))
override fun delete(group: User): Completable = Completable.fromObservable(service.updateUser(group.uid!!,group.toUserDto()))
}

View File

@ -12,8 +12,6 @@ import io.reactivex.rxjava3.core.Single
interface UserRepository {
fun getById(uid : Int): Single<User>
fun getAll(): Flowable<List<User>>
fun getByLoginAndPassword(login : String, pass : String): Single<User>
fun insert(group: User): Completable

View File

@ -0,0 +1,149 @@
package com.example.pizza.Model.Rest
import com.example.pizza.Model.Dto.BasketDto
import com.example.pizza.Model.Dto.OrderDto
import com.example.pizza.Model.Dto.PizzaDto
import com.example.pizza.Model.Dto.UserDto
import com.google.gson.GsonBuilder
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.Single
import kotlinx.serialization.json.Json
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.Field
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.PUT
import retrofit2.http.Path
import retrofit2.http.Query
interface MyServerService {
@GET("pizzas")
fun getPizzas(
@Query("limit") limit: Int,
@Query("offset") offset: Int,
): Flowable<List<PizzaDto>>
@GET("allpizzas")
fun getAllPizzas(
): Observable<List<PizzaDto>>
@GET("baskets/{id}")
fun getUserBaskets(
@Path("id") id: Int,
): Observable<List<BasketDto>>
@GET("pizza/{id}")
fun getPizza(
@Path("id") id: Int,
): Single<PizzaDto>
@GET("baskets")
fun getAllBaskets(
): Observable<List<BasketDto>>
@GET("orders/{id}")
fun getUserOrders(
@Path("id") id: Int,
@Query("page") page: Int,
@Query("size") limit: Int,
): Observable<List<OrderDto>>
@GET("orders")
fun getAllOrders(
): Observable<List<OrderDto>>
@GET("users")
fun getAllUsers(
): Observable<UserDto>
@GET("user/{id}")
fun getUser(
@Path("id") id: Int,
): Single<UserDto>
@GET("user")
fun getUserLP(
@Query("login") login : String ,
@Query("password") password : String
): Single<UserDto>
@POST("user")
fun createUser(
@Body user: UserDto,
): Observable<UserDto>
@POST("pizza")
fun createPizza(
@Body pizza: PizzaDto,
): Observable<PizzaDto>
@POST("basket")
fun createBasket(
@Body basket: BasketDto,
): Observable<BasketDto>
@POST("order")
fun createOrder(
@Body order: OrderDto,
): Observable<OrderDto>
@POST("orders")
fun createOrders(
@Body order: List<OrderDto>,
): Observable<OrderDto>
@PUT("user/{id}")
fun updateUser(
@Path("id") id: Int,
@Body user: UserDto,
): Observable<UserDto>
@PUT("pizza/{id}")
fun updatePizza(
@Path("id") id: Int,
@Body user: PizzaDto,
): Observable<PizzaDto>
@DELETE("baskets/{id}")
fun deleteUserBaskets(
@Path("id") id: Int,
): Observable<BasketDto>
@DELETE("basket")
fun deleteBasket(
@Body user: BasketDto,
): Observable<BasketDto>
companion object {
private const val BASE_URL = "http://192.168.42.168:8080/api/"
@Volatile
private var INSTANCE: MyServerService? = null
fun getInstance(): MyServerService {
return INSTANCE ?: synchronized(this) {
val logger = HttpLoggingInterceptor()
logger.level = HttpLoggingInterceptor.Level.BASIC
val client = OkHttpClient.Builder()
.addInterceptor(logger)
.build()
val gsonBuilder = GsonBuilder()
gsonBuilder.setLenient()
val gson = gsonBuilder.create()
return Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client)
//.addConverterFactory(Json.asConverterFactory("application/json".toMediaType()))
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
//.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build()
.create(MyServerService::class.java)
.also { INSTANCE = it }
}
}
}
}

View File

@ -0,0 +1,15 @@
package com.example.pizza.RemoteKeys
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Maybe
class OfflineRemoteKeyRepository(private val remoteKeysDao: RemoteKeysDao) : RemoteKeyRepository {
override fun getAllRemoteKeys(id: Int, type: RemoteKeyType) =
remoteKeysDao.getRemoteKeys(id, type)
override fun createRemoteKeys(remoteKeys: List<RemoteKeys>) =
remoteKeysDao.insertAll(remoteKeys)
override fun deleteRemoteKey(type: RemoteKeyType) =
remoteKeysDao.clearRemoteKeys(type)
}

View File

@ -0,0 +1,10 @@
package com.example.pizza.RemoteKeys
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Maybe
interface RemoteKeyRepository {
fun getAllRemoteKeys(id: Int, type: RemoteKeyType): Maybe<RemoteKeys>
fun createRemoteKeys(remoteKeys: List<RemoteKeys>) : Completable
fun deleteRemoteKey(type: RemoteKeyType) : Completable
}

View File

@ -0,0 +1,32 @@
package com.example.pizza.RemoteKeys
import androidx.room.Entity
import androidx.room.PrimaryKey
import androidx.room.TypeConverter
import androidx.room.TypeConverters
import com.example.pizza.Model.User.User
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.Basket.Basket
import com.example.pizza.Model.Order.Order
@Entity(tableName = "remote_keys")
data class RemoteKeys(
@PrimaryKey val entityId: Int,
@TypeConverters(RemoteKeyType::class)
val type: RemoteKeyType,
val prevKey: Int?,
val nextKey: Int?
)
enum class RemoteKeyType(private val type: String) {
USER(User::class.simpleName ?: "User"),
PIZZA(Pizza::class.simpleName ?: "Pizza"),
ORDER(Order::class.simpleName ?: "Order"),
BASKET(Basket::class.simpleName ?: "Basket");
@TypeConverter
fun toRemoteKeyType(value: String) = RemoteKeyType.values().first { it.type == value }
@TypeConverter
fun fromRemoteKeyType(value: RemoteKeyType) = value.type
}

View File

@ -0,0 +1,20 @@
package com.example.pizza.RemoteKeys
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Maybe
@Dao
interface RemoteKeysDao {
@Query("SELECT * FROM remote_keys WHERE entityId = :entityId AND type = :type")
fun getRemoteKeys(entityId: Int, type: RemoteKeyType): Maybe<RemoteKeys>
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertAll(remoteKey: List<RemoteKeys>) : Completable
@Query("DELETE FROM remote_keys WHERE type = :type")
fun clearRemoteKeys(type: RemoteKeyType) : Completable
}

View File

@ -14,9 +14,7 @@ object AppViewModelProvider {
initializer {
PizzaEditViewModel(studentApplication().container.pizzaRepository)
}
initializer {
UserViewModel(studentApplication().container.userRepository)
}
initializer {
BasketEditViewModel(studentApplication().container.basketRepository)
}
@ -29,6 +27,9 @@ object AppViewModelProvider {
initializer {
OrderListViewModel(studentApplication().container.orderRepository)
}
initializer {
UserViewModel(studentApplication().container.userRepository)
}
}
}

View File

@ -4,15 +4,18 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.ExperimentalPagingApi
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.PagingSource
import androidx.paging.rxjava3.cachedIn
import androidx.paging.rxjava3.flowable
import com.example.pizza.Model.Basket.PizzaBasket
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.Rest.RestOrderRepository
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.schedulers.Schedulers
@ -24,38 +27,33 @@ class OrderListViewModel(private val orderRepository: OrderRepository): ViewMode
private val pizzas: MutableLiveData<PagingData<PizzaOrder>?> = MutableLiveData()
fun getPizzas(uid: Int): LiveData<PagingData<PizzaOrder>?> {
if (pizzas.value == null) {
loadPizzas(uid)
}
return pizzas
}
private fun createPagingConfig(): PagingConfig {
@OptIn(ExperimentalCoroutinesApi::class, ExperimentalPagingApi::class)
private fun loadPizzas(uid: Int) {
val pageSize = 3
val placeholders = true
return PagingConfig(
pageSize,
pageSize,
placeholders,
pageSize * 2,
pageSize + pageSize * 2, Int.MIN_VALUE
var config = PagingConfig(
pageSize = pageSize,
enablePlaceholders =placeholders
)
}
private fun loadPizzas(uid: Int) {
val disposable = Pager(
config = createPagingConfig(),
pagingSourceFactory = {orderRepository.getUserHistory(uid)}
).flowable
.cachedIn(viewModelScope)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnError({pizzas.value = null})
.subscribe { data ->
pizzas.postValue(data)
}
mDisposable.add(disposable)
// val disposable = Pager(
// config = config,
// remoteMediator = (orderRepository as RestOrderRepository).mediator,
// pagingSourceFactory = { orderRepository.getUserHistory(uid) }
// ).flowable
// .cachedIn(viewModelScope)
// .subscribeOn(Schedulers.io())
// .observeOn(AndroidSchedulers.mainThread())
// .doOnError({pizzas.value = null})
// .subscribe { data ->
// pizzas.postValue(data)
// }
// mDisposable.add(disposable)
}
override fun onCleared() {

View File

@ -36,13 +36,13 @@ class PizzaEditViewModel(
mDisposable.add(disposable)
}
fun savePizza(pizza: Pizza, onSave: () -> Unit) {
fun savePizza(pizza: Pizza, onSave: () -> Unit,onError: () -> Unit) {
val completable: Completable = pizzaRepository.insert(pizza)
val disposable = completable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ onSave() })
.subscribe({ onSave() },{onError()})
mDisposable.add(disposable)
}
fun updatePizza(pizza: Pizza, onSave: () -> Unit, onError: () -> Unit) {

View File

@ -4,6 +4,7 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.ExperimentalPagingApi
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
@ -11,6 +12,7 @@ import androidx.paging.rxjava3.cachedIn
import androidx.paging.rxjava3.flowable
import com.example.pizza.Model.Pizza.Pizza
import com.example.pizza.Model.Repository.PizzaRepository
import com.example.pizza.Model.Repository.Rest.RestPizzaRepository
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.schedulers.Schedulers
@ -22,29 +24,26 @@ class PizzaListViewModel(private val pizzaRepository: PizzaRepository): ViewMode
private val pizzas: MutableLiveData<PagingData<Pizza>> = MutableLiveData()
fun getPizzas(): LiveData<PagingData<Pizza>> {
if (pizzas.value == null) {
loadPizzas()
}
return pizzas
}
private fun createPagingConfig(): PagingConfig {
@OptIn(ExperimentalCoroutinesApi::class, ExperimentalPagingApi::class)
private fun loadPizzas() {
var meditator = (pizzaRepository as RestPizzaRepository).mediator
var pagingSourceFactory = {pizzaRepository.getAll()}
val pageSize = 3
val placeholders = true
return PagingConfig(
pageSize,
pageSize,
placeholders,
pageSize * 2,
pageSize + pageSize * 2, Int.MIN_VALUE
var config = PagingConfig(
pageSize = pageSize,
enablePlaceholders =placeholders
)
}
@OptIn(ExperimentalCoroutinesApi::class)
private fun loadPizzas() {
val disposable = Pager(
config = createPagingConfig(),
pagingSourceFactory = pizzaRepository::getAll
config = config,
pagingSourceFactory = pagingSourceFactory,
remoteMediator = meditator,
).flowable
.cachedIn(viewModelScope)
.subscribeOn(Schedulers.io())

View File

@ -87,6 +87,7 @@ class UserViewModel(
}
override fun onCleared() {
super.onCleared()
mDisposable.clear()

View File

@ -83,12 +83,15 @@ class create_pizza : Fragment() {
return
}
if(!editing) {
pizzaViewModel!!.savePizza(pizza1) {
pizzaViewModel!!.savePizza(pizza1,
onSave = {
Toast.makeText(view.context, "Пицца успешно добавлена", Toast.LENGTH_SHORT).show()
val action = create_pizzaDirections
.actionNavigationCreatePizzaToListNavigation()
Navigation.findNavController(view).navigate(action)
}
},
onError = {Toast.makeText(view.context, "Ошибка!!!", Toast.LENGTH_SHORT).show()}
)
}
else
{

View File

@ -8,7 +8,14 @@ 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.PizzaRepository
import com.example.pizza.Model.Repository.Rest.RestBasketRepository
import com.example.pizza.Model.Repository.Rest.RestOrderRepository
import com.example.pizza.Model.Repository.Rest.RestPizzaRepository
import com.example.pizza.Model.Repository.Rest.RestUserRepository
import com.example.pizza.Model.Repository.UserRepository
import com.example.pizza.Model.Rest.MyServerService
import com.example.pizza.RemoteKeys.OfflineRemoteKeyRepository
import com.example.pizza.RemoteKeys.RemoteKeyRepository
interface AppContainer {
@ -16,20 +23,45 @@ interface AppContainer {
val userRepository: UserRepository
val basketRepository: BasketRepository
val orderRepository : OrderRepository
val remoteKeyRepository: RemoteKeyRepository
}
class AppDataContainer(private val context: Context) : AppContainer {
override val pizzaRepository: PizzaRepository by lazy {
OfflinePizzaRepository(AppDatabase.getInstance(context).pizzaDao())
RestPizzaRepository(
MyServerService.getInstance(),
OfflinePizzaRepository(AppDatabase.getInstance(context).pizzaDao()),
OfflineRemoteKeyRepository(AppDatabase.getInstance(context).remoteKeysDao()),
AppDatabase.getInstance(context))
}
override val userRepository: UserRepository by lazy {
OfflineUserRepository(AppDatabase.getInstance(context).userDao())
RestUserRepository(
MyServerService.getInstance(),
OfflineUserRepository(AppDatabase.getInstance(context).userDao()),
OfflineRemoteKeyRepository(AppDatabase.getInstance(context).remoteKeysDao()),
AppDatabase.getInstance(context)
)
}
override val basketRepository: BasketRepository by lazy {
OfflineBasketRepository(AppDatabase.getInstance(context).basketDao())
RestBasketRepository(
MyServerService.getInstance(),
OfflineBasketRepository(AppDatabase.getInstance(context).basketDao()),
OfflinePizzaRepository(AppDatabase.getInstance(context).pizzaDao()),
OfflineRemoteKeyRepository(AppDatabase.getInstance(context).remoteKeysDao()),
AppDatabase.getInstance(context))
}
override val orderRepository: OrderRepository by lazy {
OfflineOrderRepository(AppDatabase.getInstance(context).orderDao())
RestOrderRepository(
MyServerService.getInstance(),
OfflineOrderRepository(AppDatabase.getInstance(context).orderDao()),
OfflinePizzaRepository(AppDatabase.getInstance(context).pizzaDao()),
OfflineRemoteKeyRepository(AppDatabase.getInstance(context).remoteKeysDao()),
AppDatabase.getInstance(context))
}
override val remoteKeyRepository: RemoteKeyRepository by lazy {
OfflineRemoteKeyRepository(AppDatabase.getInstance(context).remoteKeysDao())
}

View File

@ -26,22 +26,30 @@ import com.example.pizza.Model.Pizza.PizzaDao
import com.example.pizza.Model.Pizza.Singleton
import com.example.pizza.Model.User.User
import com.example.pizza.Model.User.UserDao
import com.example.pizza.RemoteKeys.RemoteKeys
import com.example.pizza.RemoteKeys.RemoteKeysDao
import java.io.ByteArrayOutputStream
import java.text.SimpleDateFormat
import java.util.Date
import java.util.concurrent.Executors
@Database(entities = [User::class, Pizza::class,Basket::class,Order::class], version = 1, exportSchema = false)
@Database(entities = [
User::class,
Pizza::class,
Basket::class,
Order::class,
RemoteKeys::class,
], version = 1, exportSchema = false)
@TypeConverters(ImageConverter::class, DateConverter::class)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
abstract fun pizzaDao(): PizzaDao
abstract fun basketDao(): BasketDao
abstract fun orderDao(): OrderDao
abstract fun remoteKeysDao(): RemoteKeysDao
companion object {
private const val DB_NAME: String = "dp9"
private const val DB_NAME: String = "dp11"
@Volatile
private var INSTANCE: AppDatabase? = null
@ -101,7 +109,7 @@ abstract class AppDatabase : RoomDatabase() {
.addCallback(object : Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
Executors.newSingleThreadExecutor().execute { populateDatabase() }
//Executors.newSingleThreadExecutor().execute { populateDatabase() }
}
})
.build()

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true"/>
</network-security-config>