not completed lab5

This commit is contained in:
movavi 2023-12-05 22:58:26 +03:00
parent e2d0f1f73a
commit 6565ea911b
40 changed files with 2496 additions and 33 deletions

View File

@ -98,6 +98,14 @@ dependencies {
implementation("androidx.room:room-ktx:$room_version")
implementation("androidx.room:room-paging:$room_version")
// retrofit
val retrofitVersion = "2.9.0"
implementation("com.squareup.retrofit2:retrofit:$retrofitVersion")
implementation("com.squareup.okhttp3:logging-interceptor:4.11.0")
implementation("androidx.paging:paging-compose:3.2.1")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1")
implementation("com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:1.0.0")
// Tests
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")

View File

@ -0,0 +1,111 @@
package com.example.flowershopapp.API.Mediator
import androidx.paging.ExperimentalPagingApi
import androidx.paging.LoadType
import androidx.paging.PagingState
import androidx.paging.RemoteMediator
import androidx.room.withTransaction
import com.example.flowershopapp.API.Model.toBouquet
import com.example.flowershopapp.API.MyServerService
import com.example.flowershopapp.API.Repository.RestOrderBouquetRepository
import com.example.flowershopapp.Database.AppDatabase
import com.example.flowershopapp.Database.RemoteKeys.Model.RemoteKeyType
import com.example.flowershopapp.Database.RemoteKeys.Model.RemoteKeys
import com.example.flowershopapp.Database.RemoteKeys.Repository.OfflineRemoteKeyRepository
import com.example.flowershopapp.Entities.Model.Bouquet
import com.example.flowershopapp.Entities.Repository.Bouquet.OfflineBouquetRepository
import retrofit2.HttpException
import java.io.IOException
@OptIn(ExperimentalPagingApi::class)
class BouquetRemoteMediator(
private val service: MyServerService,
private val dbBouquetRepository: OfflineBouquetRepository,
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
private val orderBouquetRestRepository: RestOrderBouquetRepository,
private val database: AppDatabase
) : RemoteMediator<Int, Bouquet>() {
override suspend fun initialize(): InitializeAction {
return InitializeAction.LAUNCH_INITIAL_REFRESH
}
override suspend fun load(
loadType: LoadType,
state: PagingState<Int, Bouquet>
): MediatorResult {
val page = when (loadType) {
LoadType.REFRESH -> {
val remoteKeys = getRemoteKeyClosestToCurrentPosition(state)
remoteKeys?.nextKey?.minus(1) ?: 1
}
LoadType.PREPEND -> {
val remoteKeys = getRemoteKeyForFirstItem(state)
remoteKeys?.prevKey
?: return MediatorResult.Success(endOfPaginationReached = remoteKeys != null)
}
LoadType.APPEND -> {
val remoteKeys = getRemoteKeyForLastItem(state)
remoteKeys?.nextKey
?: return MediatorResult.Success(endOfPaginationReached = remoteKeys != null)
}
}
try {
val bouquets = service.getBouquets(page, state.config.pageSize).map { it.toBouquet() }
val endOfPaginationReached = bouquets.isEmpty()
database.withTransaction {
if (loadType == LoadType.REFRESH) {
dbRemoteKeyRepository.deleteRemoteKey(RemoteKeyType.BOUQUET)
dbBouquetRepository.deleteAll()
}
val prevKey = if (page == 1) null else page - 1
val nextKey = if (endOfPaginationReached) null else page + 1
val keys = bouquets.map {
it.bouquetId?.let { it1 ->
RemoteKeys(
entityId = it1,
type = RemoteKeyType.BOUQUET,
prevKey = prevKey,
nextKey = nextKey
)
}
}
orderBouquetRestRepository.getAll()
dbRemoteKeyRepository.createRemoteKeys(keys)
dbBouquetRepository.insertBouquets(bouquets)
}
return MediatorResult.Success(endOfPaginationReached = endOfPaginationReached)
} catch (exception: IOException) {
return MediatorResult.Error(exception)
} catch (exception: HttpException) {
return MediatorResult.Error(exception)
}
}
private suspend fun getRemoteKeyForLastItem(state: PagingState<Int, Bouquet>): RemoteKeys? {
return state.pages.lastOrNull { it.data.isNotEmpty() }?.data?.lastOrNull()
?.let { bouquet ->
bouquet.bouquetId?.let { dbRemoteKeyRepository.getAllRemoteKeys(it, RemoteKeyType.BOUQUET) }
}
}
private suspend fun getRemoteKeyForFirstItem(state: PagingState<Int, Bouquet>): RemoteKeys? {
return state.pages.firstOrNull { it.data.isNotEmpty() }?.data?.firstOrNull()
?.let { bouquet ->
bouquet.bouquetId?.let { dbRemoteKeyRepository.getAllRemoteKeys(it, RemoteKeyType.BOUQUET) }
}
}
private suspend fun getRemoteKeyClosestToCurrentPosition(
state: PagingState<Int, Bouquet>
): RemoteKeys? {
return state.anchorPosition?.let { position ->
state.closestItemToPosition(position)?.bouquetId?.let { bouquetUid ->
dbRemoteKeyRepository.getAllRemoteKeys(bouquetUid, RemoteKeyType.BOUQUET)
}
}
}
}

View File

@ -0,0 +1,108 @@
package com.example.flowershopapp.API.Mediator
import androidx.paging.ExperimentalPagingApi
import androidx.paging.LoadType
import androidx.paging.PagingState
import androidx.paging.RemoteMediator
import androidx.room.withTransaction
import com.example.flowershopapp.API.Model.toOrder
import com.example.flowershopapp.API.MyServerService
import com.example.flowershopapp.Database.AppDatabase
import com.example.flowershopapp.Database.RemoteKeys.Model.RemoteKeyType
import com.example.flowershopapp.Database.RemoteKeys.Model.RemoteKeys
import com.example.flowershopapp.Database.RemoteKeys.Repository.OfflineRemoteKeyRepository
import com.example.flowershopapp.Entities.Model.Order
import com.example.flowershopapp.Entities.Repository.Order.OfflineOrderRepository
import retrofit2.HttpException
import java.io.IOException
@OptIn(ExperimentalPagingApi::class)
class OrderRemoteMediator(
private val service: MyServerService,
private val dbOrderRepository: OfflineOrderRepository,
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
private val database: AppDatabase
) : RemoteMediator<Int, Order>() {
override suspend fun initialize(): InitializeAction {
return InitializeAction.LAUNCH_INITIAL_REFRESH
}
override suspend fun load(
loadType: LoadType,
state: PagingState<Int, Order>
): MediatorResult {
val page = when (loadType) {
LoadType.REFRESH -> {
val remoteKeys = getRemoteKeyClosestToCurrentPosition(state)
remoteKeys?.nextKey?.minus(1) ?: 1
}
LoadType.PREPEND -> {
val remoteKeys = getRemoteKeyForFirstItem(state)
remoteKeys?.prevKey
?: return MediatorResult.Success(endOfPaginationReached = remoteKeys != null)
}
LoadType.APPEND -> {
val remoteKeys = getRemoteKeyForLastItem(state)
remoteKeys?.nextKey
?: return MediatorResult.Success(endOfPaginationReached = remoteKeys != null)
}
}
try {
val Orders = service.getOrders(page, state.config.pageSize).map { it.toOrder() }
val endOfPaginationReached = Orders.isEmpty()
database.withTransaction {
if (loadType == LoadType.REFRESH) {
dbRemoteKeyRepository.deleteRemoteKey(RemoteKeyType.ORDER)
dbOrderRepository.deleteAll()
}
val prevKey = if (page == 1) null else page - 1
val nextKey = if (endOfPaginationReached) null else page + 1
val keys = Orders.map {
it.orderId?.let { it1 ->
RemoteKeys(
entityId = it1,
type = RemoteKeyType.ORDER,
prevKey = prevKey,
nextKey = nextKey
)
}
}
dbRemoteKeyRepository.createRemoteKeys(keys)
dbOrderRepository.insertOrders(Orders)
}
return MediatorResult.Success(endOfPaginationReached = endOfPaginationReached)
} catch (exception: IOException) {
return MediatorResult.Error(exception)
} catch (exception: HttpException) {
return MediatorResult.Error(exception)
}
}
private suspend fun getRemoteKeyForLastItem(state: PagingState<Int, Order>): RemoteKeys? {
return state.pages.lastOrNull { it.data.isNotEmpty() }?.data?.lastOrNull()
?.let { Order ->
Order.orderId?.let { dbRemoteKeyRepository.getAllRemoteKeys(it, RemoteKeyType.ORDER) }
}
}
private suspend fun getRemoteKeyForFirstItem(state: PagingState<Int, Order>): RemoteKeys? {
return state.pages.firstOrNull { it.data.isNotEmpty() }?.data?.firstOrNull()
?.let { Order ->
Order.orderId?.let { dbRemoteKeyRepository.getAllRemoteKeys(it, RemoteKeyType.ORDER) }
}
}
private suspend fun getRemoteKeyClosestToCurrentPosition(
state: PagingState<Int, Order>
): RemoteKeys? {
return state.anchorPosition?.let { position ->
state.closestItemToPosition(position)?.orderId?.let { OrderUid ->
dbRemoteKeyRepository.getAllRemoteKeys(OrderUid, RemoteKeyType.ORDER)
}
}
}
}

View File

@ -0,0 +1,112 @@
package com.example.flowershopapp.API.Mediator
import androidx.paging.ExperimentalPagingApi
import androidx.paging.LoadType
import androidx.paging.PagingState
import androidx.paging.RemoteMediator
import androidx.room.withTransaction
import com.example.flowershopapp.API.Model.toUser
import com.example.flowershopapp.API.MyServerService
import com.example.flowershopapp.API.Repository.RestOrderBouquetRepository
import com.example.flowershopapp.API.Repository.RestUserOrderRepository
import com.example.flowershopapp.Database.AppDatabase
import com.example.flowershopapp.Database.RemoteKeys.Model.RemoteKeyType
import com.example.flowershopapp.Database.RemoteKeys.Model.RemoteKeys
import com.example.flowershopapp.Database.RemoteKeys.Repository.OfflineRemoteKeyRepository
import com.example.flowershopapp.Entities.Model.User
import com.example.flowershopapp.Entities.Repository.User.OfflineUserRepository
import retrofit2.HttpException
import java.io.IOException
@OptIn(ExperimentalPagingApi::class)
class UserRemoteMediator(
private val service: MyServerService,
private val dbUserRepository: OfflineUserRepository,
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
private val userOrderRestRepository: RestUserOrderRepository,
private val database: AppDatabase
) : RemoteMediator<Int, User>() {
override suspend fun initialize(): InitializeAction {
return InitializeAction.LAUNCH_INITIAL_REFRESH
}
override suspend fun load(
loadType: LoadType,
state: PagingState<Int, User>
): MediatorResult {
val page = when (loadType) {
LoadType.REFRESH -> {
val remoteKeys = getRemoteKeyClosestToCurrentPosition(state)
remoteKeys?.nextKey?.minus(1) ?: 1
}
LoadType.PREPEND -> {
val remoteKeys = getRemoteKeyForFirstItem(state)
remoteKeys?.prevKey
?: return MediatorResult.Success(endOfPaginationReached = remoteKeys != null)
}
LoadType.APPEND -> {
val remoteKeys = getRemoteKeyForLastItem(state)
remoteKeys?.nextKey
?: return MediatorResult.Success(endOfPaginationReached = remoteKeys != null)
}
}
try {
val Users = service.getUsers().map { it.toUser() }
val endOfPaginationReached = Users.isEmpty()
database.withTransaction {
if (loadType == LoadType.REFRESH) {
dbRemoteKeyRepository.deleteRemoteKey(RemoteKeyType.ORDER)
dbUserRepository.deleteAll()
}
val prevKey = if (page == 1) null else page - 1
val nextKey = if (endOfPaginationReached) null else page + 1
val keys = Users.map {
it.userId?.let { it1 ->
RemoteKeys(
entityId = it1,
type = RemoteKeyType.ORDER,
prevKey = prevKey,
nextKey = nextKey
)
}
}
userOrderRestRepository.getAll()
dbRemoteKeyRepository.createRemoteKeys(keys)
dbUserRepository.insertUsers(Users)
}
return MediatorResult.Success(endOfPaginationReached = endOfPaginationReached)
} catch (exception: IOException) {
return MediatorResult.Error(exception)
} catch (exception: HttpException) {
return MediatorResult.Error(exception)
}
}
private suspend fun getRemoteKeyForLastItem(state: PagingState<Int, User>): RemoteKeys? {
return state.pages.lastOrNull { it.data.isNotEmpty() }?.data?.lastOrNull()
?.let { User ->
User.userId?.let { dbRemoteKeyRepository.getAllRemoteKeys(it, RemoteKeyType.ORDER) }
}
}
private suspend fun getRemoteKeyForFirstItem(state: PagingState<Int, User>): RemoteKeys? {
return state.pages.firstOrNull { it.data.isNotEmpty() }?.data?.firstOrNull()
?.let { User ->
User.userId?.let { dbRemoteKeyRepository.getAllRemoteKeys(it, RemoteKeyType.ORDER) }
}
}
private suspend fun getRemoteKeyClosestToCurrentPosition(
state: PagingState<Int, User>
): RemoteKeys? {
return state.anchorPosition?.let { position ->
state.closestItemToPosition(position)?.userId?.let { UserUid ->
dbRemoteKeyRepository.getAllRemoteKeys(UserUid, RemoteKeyType.ORDER)
}
}
}
}

View File

@ -0,0 +1,29 @@
package com.example.flowershopapp.API.Model
import com.example.flowershopapp.Entities.Model.Bouquet
import kotlinx.serialization.Serializable
@Serializable
data class BouquetRemote(
val bouquetId: Int? = 0,
val name: String = "",
val quantityOfFlowers: Int = 0,
val price: Int = 0,
val image: ByteArray? = null,
)
fun BouquetRemote.toBouquet(): Bouquet = Bouquet(
bouquetId,
name,
quantityOfFlowers,
price,
image
)
fun Bouquet.toBouquetRemote(): BouquetRemote = BouquetRemote(
bouquetId,
name,
quantityOfFlowers,
price,
image
)

View File

@ -0,0 +1,24 @@
package com.example.flowershopapp.API.Model
import com.example.flowershopapp.Entities.Model.Bouquet
import com.example.flowershopapp.Entities.Model.OrderBouquetCrossRef
import com.example.flowershopapp.Entities.Model.OrdersWithBouquets
import kotlinx.serialization.Serializable
@Serializable
data class OrderBouquetRemote(
val order: OrderRemote = OrderRemote(),
val bouquet: List<BouquetRemote> = listOf()
)
fun OrderBouquetRemote.toOrdersWithBouquets(): OrdersWithBouquets {
val convertedOrder = this.order.toOrder()
val convertedBouquets = this.bouquet.map { it.toBouquet() }
return OrdersWithBouquets(convertedOrder, convertedBouquets)
}
fun OrdersWithBouquets.toOrderBouquetRemote(): OrderBouquetRemote {
val convertedOrder = this.order.toOrderRemote()
val convertedBouquets = this.bouquets.map { it.toBouquetRemote() }
return OrderBouquetRemote(convertedOrder, convertedBouquets)
}

View File

@ -0,0 +1,23 @@
package com.example.flowershopapp.API.Model
import com.example.flowershopapp.Entities.Model.Order
import kotlinx.serialization.Serializable
@Serializable
data class OrderRemote(
val orderId: Int? = 0,
val date: String = "",
val sum: Int = 0,
)
fun OrderRemote.toOrder(): Order = Order(
orderId,
date,
sum
)
fun Order.toOrderRemote(): OrderRemote = OrderRemote(
orderId,
date,
sum
)

View File

@ -0,0 +1,23 @@
package com.example.flowershopapp.API.Model
import com.example.flowershopapp.Entities.Model.UserOrderCrossRef
import com.example.flowershopapp.Entities.Model.UsersWithOrders
import kotlinx.serialization.Serializable
@Serializable
data class UserOrderRemote(
val user: UserRemote = UserRemote(),
val order: List<OrderRemote> = listOf()
)
fun UserOrderRemote.toUserOrder(): UsersWithOrders{
val convertedUser = this.user.toUser()
val convertedOrders = this.order.map { it.toOrder() }
return UsersWithOrders(convertedUser, convertedOrders)
}
fun UsersWithOrders.toUserOrderRemote(): UserOrderRemote{
val convertedUser = this.user.toUserRemote()
val convertedOrdesr = this.orders.map { it.toOrderRemote() }
return UserOrderRemote(convertedUser, convertedOrdesr)
}

View File

@ -0,0 +1,29 @@
package com.example.flowershopapp.API.Model
import com.example.flowershopapp.Entities.Model.User
import kotlinx.serialization.Serializable
@Serializable
data class UserRemote(
val userId: Int? = 0,
val userName: String = "",
val dateOfBirth: String = "",
val phoneNumber: String = "",
val password: String = ""
)
fun UserRemote.toUser(): User = User(
userId,
userName,
dateOfBirth,
phoneNumber,
password
)
fun User.toUserRemote(): UserRemote = UserRemote(
userId,
userName,
dateOfBirth,
phoneNumber,
password
)

View File

@ -0,0 +1,170 @@
package com.example.flowershopapp.API
import com.example.flowershopapp.API.Model.BouquetRemote
import com.example.flowershopapp.API.Model.OrderBouquetRemote
import com.example.flowershopapp.API.Model.OrderRemote
import com.example.flowershopapp.API.Model.UserOrderRemote
import com.example.flowershopapp.API.Model.UserRemote
import com.example.flowershopapp.Entities.Model.UsersWithOrders
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import kotlinx.serialization.json.Json
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.PUT
import retrofit2.http.Path
import retrofit2.http.Query
interface MyServerService {
@GET("Users")
suspend fun getUsers(): List<UserRemote>
@GET("Users/{name}")
suspend fun getUser(
@Path("name") name: String,
): UserRemote
@GET("Users/{name}")
suspend fun getUserWithOrders(
@Path("name") name: String,
): UserOrderRemote
@GET("Users/{id}")
suspend fun getUsersWithOrders(): List<UserOrderRemote>
@POST("Users")
suspend fun createUser(
@Body User: UserRemote,
): UserRemote
@PUT("Users/{id}")
suspend fun updateUser(
@Path("id") id: Int,
@Body User: UserRemote,
): UserRemote
@DELETE("Users/{id}")
suspend fun deleteUser(
@Path("id") id: Int,
): UserRemote
@GET("Orders")
suspend fun getOrders(
@Query("_page") page: Int,
@Query("_limit") limit: Int,
): List<OrderRemote>
@GET("Orders/{id}")
suspend fun getOrder(
@Path("id") id: Int,
): OrderRemote
@GET("Orders/{id}")
suspend fun getOrderWithBouquets(
@Path("id") id: Int,
): OrderBouquetRemote
@GET("Orders/{id}")
suspend fun getOrdersWithBouquets(): List<OrderBouquetRemote>
@POST("Orders")
suspend fun createOrder(
@Body Order: OrderRemote,
): OrderRemote
@PUT("Orders/{id}")
suspend fun updateOrder(
@Path("id") id: Int,
@Body Order: OrderRemote,
): OrderRemote
@DELETE("Orders/{id}")
suspend fun deleteOrder(
@Path("id") id: Int,
): OrderRemote
@GET("Bouquets")
suspend fun getBouquets(
@Query("_page") page: Int,
@Query("_limit") limit: Int,
): List<BouquetRemote>
@GET("Bouquets/{id}")
suspend fun getBouquet(
@Path("id") id: Int,
): BouquetRemote
@POST("Bouquets")
suspend fun createBouquet(
@Body Bouquet: BouquetRemote,
): BouquetRemote
@PUT("Bouquets/{id}")
suspend fun updateBouquet(
@Path("id") id: Int,
@Body Bouquet: BouquetRemote,
): BouquetRemote
@DELETE("Bouquets/{id}")
suspend fun deleteBouquet(
@Path("id") id: Int,
): BouquetRemote
@POST("OrderBouquets")
suspend fun createOrderBouquet(
@Body OrderBouquet: OrderBouquetRemote,
): OrderBouquetRemote
@PUT("OrderBouquets/{id}")
suspend fun updateOrderBouquet(
@Path("id") id: Int,
@Body OrderBouquet: OrderBouquetRemote,
): OrderBouquetRemote
@DELETE("OrderBouquets/{id}")
suspend fun deleteOrderBouquet(
@Path("id") id: Int,
): OrderBouquetRemote
@POST("UserOrders")
suspend fun createUserOrder(
@Body UserOrder: UserOrderRemote,
): UserOrderRemote
@PUT("UserOrders/{id}")
suspend fun updateUserOrder(
@Path("id") id: Int,
@Body UserOrder: UserOrderRemote,
): UserOrderRemote
@DELETE("UserOrders/{id}")
suspend fun deleteUserOrder(
@Path("id") id: Int,
): UserOrderRemote
companion object {
private const val BASE_URL = "http://10.0.2.2:8079/"
@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()
return Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client)
.addConverterFactory(Json.asConverterFactory("application/json".toMediaType()))
.build()
.create(MyServerService::class.java)
.also { INSTANCE = it }
}
}
}
}

View File

@ -0,0 +1,63 @@
package com.example.flowershopapp.API.Repository
import android.util.Log
import androidx.paging.ExperimentalPagingApi
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import com.example.flowershopapp.API.Mediator.BouquetRemoteMediator
import com.example.flowershopapp.API.Model.toBouquet
import com.example.flowershopapp.API.Model.toBouquetRemote
import com.example.flowershopapp.API.MyServerService
import com.example.flowershopapp.Database.AppContainer
import com.example.flowershopapp.Database.AppDatabase
import com.example.flowershopapp.Database.RemoteKeys.Repository.OfflineRemoteKeyRepository
import com.example.flowershopapp.Entities.Model.Bouquet
import com.example.flowershopapp.Entities.Repository.Bouquet.BouquetRepository
import com.example.flowershopapp.Entities.Repository.Bouquet.OfflineBouquetRepository
import kotlinx.coroutines.flow.Flow
class RestBouquetRepository(
private val service: MyServerService,
private val dbBouquetRepository: OfflineBouquetRepository,
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
private val orderBouquetRestRepository: RestOrderBouquetRepository,
private val database: AppDatabase
) : BouquetRepository {
override fun getAll(): Flow<PagingData<Bouquet>> {
Log.d(RestBouquetRepository::class.simpleName, "Get Bouquets")
val pagingSourceFactory = { dbBouquetRepository.getAllBouquetsPagingSource() }
@OptIn(ExperimentalPagingApi::class)
return Pager(
config = PagingConfig(
pageSize = AppContainer.LIMIT,
enablePlaceholders = false
),
remoteMediator = BouquetRemoteMediator(
service,
dbBouquetRepository,
dbRemoteKeyRepository,
orderBouquetRestRepository,
database
),
pagingSourceFactory = pagingSourceFactory
).flow
}
override suspend fun getBouquet(uid: Int): Bouquet =
service.getBouquet(uid).toBouquet()
override suspend fun insert(Bouquet: Bouquet) {
service.createBouquet(Bouquet.toBouquetRemote()).toBouquet()
}
override suspend fun update(Bouquet: Bouquet) {
Bouquet.bouquetId?.let { service.updateBouquet(it, Bouquet.toBouquetRemote()).toBouquet() }
}
override suspend fun delete(Bouquet: Bouquet) {
Bouquet.bouquetId?.let { service.deleteBouquet(it).toBouquet() }
}
}

View File

@ -0,0 +1,40 @@
package com.example.flowershopapp.API.Repository
import android.util.Log
import com.example.flowershopapp.API.Model.toOrderBouquet
import com.example.flowershopapp.API.Model.toOrderBouquetRemote
import com.example.flowershopapp.API.MyServerService
import com.example.flowershopapp.Entities.Model.OrderBouquetCrossRef
import com.example.flowershopapp.Entities.Model.OrdersWithBouquets
import com.example.flowershopapp.Entities.Repository.OrderBouquets.OfflineOrdersWithBouquetsRepositoryRepository
import com.example.flowershopapp.Entities.Repository.OrderBouquets.OrdersWithBouquetsRepository
class RestOrderBouquetRepository(
private val service: MyServerService,
private val dbOrderBouquetRepository: OfflineOrdersWithBouquetsRepositoryRepository,
): OrdersWithBouquetsRepository {
override suspend fun getAll(): List<OrderBouquetCrossRef> {
Log.d(RestOrderBouquetRepository::class.simpleName, "Get OrderBouquets")
val existOrderBouquets = dbOrderBouquetRepository.getAll().associateBy { it.orderId }.toMutableMap()
service.getOrdersWithBouquets()
.map { it.toOrderBouquet() }
.forEach { orderBouquet ->
val existOrderBouquet = existOrderBouquets[orderBouquet.orderId]
if (existOrderBouquet == null) {
dbOrderBouquetRepository.insert(orderBouquet)
}
existOrderBouquets[orderBouquet.orderId] = orderBouquet
}
return existOrderBouquets.map { it.value }.sortedBy { it.orderId }
}
override suspend fun insert(orderBouquet: OrderBouquetCrossRef) {
service.createOrderBouquet(orderBouquet.toOrderBouquetRemote()).toOrderBouquet()
}
override suspend fun delete(orderBouquet: OrderBouquetCrossRef) {
service.deleteOrderBouquet(orderBouquet.orderId).toOrderBouquet()
}
}

View File

@ -0,0 +1,4 @@
package com.example.flowershopapp.API.Repository
class RestOrderRepository {
}

View File

@ -0,0 +1,42 @@
package com.example.flowershopapp.API.Repository
import android.util.Log
import com.example.flowershopapp.API.Model.toOrderBouquet
import com.example.flowershopapp.API.Model.toUserOrder
import com.example.flowershopapp.API.Model.toUserOrderRemote
import com.example.flowershopapp.API.MyServerService
import com.example.flowershopapp.Entities.Model.UserOrderCrossRef
import com.example.flowershopapp.Entities.Repository.OrderBouquets.OfflineOrdersWithBouquetsRepositoryRepository
import com.example.flowershopapp.Entities.Repository.OrderBouquets.OrdersWithBouquetsRepository
import com.example.flowershopapp.Entities.Repository.UserOrders.OfflineUsersWithOrdersRepository
import com.example.flowershopapp.Entities.Repository.UserOrders.UsersWithOrdersRepository
class RestUserOrderRepository(
private val service: MyServerService,
private val dbUserOrderRepository: OfflineUsersWithOrdersRepository,
): UsersWithOrdersRepository {
override suspend fun getAll(): List<UserOrderCrossRef> {
Log.d(RestUserOrderRepository::class.simpleName, "Get UserOrders")
val existUserOrders = dbUserOrderRepository.getAll().associateBy { it.userId }.toMutableMap()
service.getUsersWithOrders()
.map { it.toUserOrder() }
.forEach { UserOrder ->
val existUserOrder = existUserOrders[UserOrder.orderId]
if (existUserOrder == null) {
dbUserOrderRepository.insert(UserOrder)
}
existUserOrders[UserOrder.orderId] = UserOrder
}
return existUserOrders.map { it.value }.sortedBy { it.orderId }
}
override suspend fun insert(UserOrder: UserOrderCrossRef) {
service.createUserOrder(UserOrder.toUserOrderRemote()).toUserOrder()
}
override suspend fun delete(UserOrder: UserOrderCrossRef) {
service.deleteUserOrder(UserOrder.orderId).toUserOrder()
}
}

View File

@ -0,0 +1,74 @@
package com.example.flowershopapp.API.Repository
import android.util.Log
import androidx.paging.ExperimentalPagingApi
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import com.example.flowershopapp.API.Mediator.UserRemoteMediator
import com.example.flowershopapp.API.Model.toUser
import com.example.flowershopapp.API.Model.toUserOrder
import com.example.flowershopapp.API.Model.toUserRemote
import com.example.flowershopapp.API.MyServerService
import com.example.flowershopapp.Database.AppContainer
import com.example.flowershopapp.Database.AppDatabase
import com.example.flowershopapp.Database.RemoteKeys.Repository.OfflineRemoteKeyRepository
import com.example.flowershopapp.Entities.Model.User
import com.example.flowershopapp.Entities.Model.UsersWithOrders
import com.example.flowershopapp.Entities.Repository.User.UserRepository
import com.example.flowershopapp.Entities.Repository.User.OfflineUserRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
class RestUserRepository(
private val service: MyServerService,
private val dbUserRepository: OfflineUserRepository,
private val dbRemoteKeyRepository: OfflineRemoteKeyRepository,
private val userOrderRestRepository: RestUserOrderRepository,
private val database: AppDatabase
) : UserRepository {
override fun getAll(): Flow<PagingData<User>> {
Log.d(RestUserRepository::class.simpleName, "Get Users")
val pagingSourceFactory = { dbUserRepository.getAll() }
@OptIn(ExperimentalPagingApi::class)
return Pager(
config = PagingConfig(
pageSize = AppContainer.LIMIT,
enablePlaceholders = false
),
remoteMediator = UserRemoteMediator(
service,
dbUserRepository,
dbRemoteKeyRepository,
userOrderRestRepository,
database
),
pagingSourceFactory = pagingSourceFactory
).flow
}
override suspend fun getUser(userName: String): User =
service.getUser(userName).toUser()
override suspend fun getUserWithOrders(userName: String): Flow<UsersWithOrders> {
return flowOf(service.getUserWithOrders(userName).toUserOrder())
}
override fun getUsersWithOrders(): Flow<List<UsersWithOrders>> {
TODO("Not yet implemented")
}
override suspend fun insert(User: User) {
service.createUser(User.toUserRemote()).toUser()
}
override suspend fun update(User: User) {
User.userId?.let { service.updateUser(it, User.toUserRemote()).toUser() }
}
override suspend fun delete(User: User) {
User.userId?.let { service.deleteUser(it).toUser() }
}
}

View File

@ -18,6 +18,11 @@ interface AppContainer {
val orderRepository: OrderRepository
val userOrdersRepository: UsersWithOrdersRepository
val orderBouquetsRepository: OrdersWithBouquetsRepository
companion object {
const val TIMEOUT = 5000L
const val LIMIT = 10
}
}
class AppDataContainer(private val context: Context) : AppContainer {
override val userRepository: UserRepository by lazy {
@ -36,7 +41,4 @@ class AppDataContainer(private val context: Context) : AppContainer {
OfflineOrdersWithBouquetsRepositoryRepository(AppDatabase.getInstance(context).orderWithBouquetsDao())
}
companion object {
const val TIMEOUT = 5000L
}
}

View File

@ -0,0 +1,20 @@
package com.example.flowershopapp.Database.RemoteKeys.DAO
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.example.flowershopapp.Database.RemoteKeys.Model.RemoteKeyType
import com.example.flowershopapp.Database.RemoteKeys.Model.RemoteKeys
@Dao
interface RemoteKeysDao {
@Query("SELECT * FROM remote_keys WHERE entityId = :entityId AND type = :type")
suspend fun getRemoteKeys(entityId: Int, type: RemoteKeyType): RemoteKeys?
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAll(remoteKey: List<RemoteKeys?>)
@Query("DELETE FROM remote_keys WHERE type = :type")
suspend fun clearRemoteKeys(type: RemoteKeyType)
}

View File

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

View File

@ -0,0 +1,16 @@
package com.example.flowershopapp.Database.RemoteKeys.Repository
import com.example.flowershopapp.Database.RemoteKeys.DAO.RemoteKeysDao
import com.example.flowershopapp.Database.RemoteKeys.Model.RemoteKeyType
import com.example.flowershopapp.Database.RemoteKeys.Model.RemoteKeys
class OfflineRemoteKeyRepository(private val remoteKeysDao: RemoteKeysDao) : RemoteKeyRepository {
override suspend fun getAllRemoteKeys(id: Int, type: RemoteKeyType) =
remoteKeysDao.getRemoteKeys(id, type)
override suspend fun createRemoteKeys(remoteKeys: List<RemoteKeys?>) =
remoteKeysDao.insertAll(remoteKeys)
override suspend fun deleteRemoteKey(type: RemoteKeyType) =
remoteKeysDao.clearRemoteKeys(type)
}

View File

@ -0,0 +1,10 @@
package com.example.flowershopapp.Database.RemoteKeys.Repository
import com.example.flowershopapp.Database.RemoteKeys.Model.RemoteKeyType
import com.example.flowershopapp.Database.RemoteKeys.Model.RemoteKeys
interface RemoteKeyRepository {
suspend fun getAllRemoteKeys(id: Int, type: RemoteKeyType): RemoteKeys?
suspend fun createRemoteKeys(remoteKeys: List<RemoteKeys?>)
suspend fun deleteRemoteKey(type: RemoteKeyType)
}

View File

@ -1,5 +1,6 @@
package com.example.flowershopapp.Entities.DAO
import androidx.paging.PagingSource
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
@ -13,18 +14,20 @@ import kotlinx.coroutines.flow.Flow
@Dao
interface BouquetDAO {
@Query("select * from bouquets")
fun getAll(): Flow<List<Bouquet>>
fun getAll(): PagingSource<Int, Bouquet>
@Query("select * from bouquets where bouquetId = :id")
fun getBouquet(id: Int): Bouquet
@Insert
suspend fun insert(bouquet: Bouquet)
suspend fun insert(vararg bouquet: Bouquet)
@Update
suspend fun update(bouquet: Bouquet)
@Delete
suspend fun delete(bouquet: Bouquet)
@Query("DELETE FROM bouquets")
suspend fun deleteAll()
}

View File

@ -1,5 +1,6 @@
package com.example.flowershopapp.Entities.DAO
import androidx.paging.PagingSource
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
@ -12,7 +13,7 @@ import kotlinx.coroutines.flow.Flow
@Dao
interface OrderDAO {
@Query("select * from orders")
fun getAll(): List<Order>
fun getAll(): PagingSource<Int, Order>
@Query("select * from orders")
fun getOrdersWithBouquet(): Flow<List<OrdersWithBouquets>>
@ -21,11 +22,14 @@ interface OrderDAO {
fun getOrderWithBouquet(id: Int): OrdersWithBouquets
@Insert
suspend fun insert(order: Order)
suspend fun insert(vararg order: Order)
@Update
suspend fun update(order: Order)
@Delete
suspend fun delete(order: Order)
@Query("DELETE FROM orders")
suspend fun deleteAll()
}

View File

@ -3,19 +3,20 @@ package com.example.flowershopapp.Entities.DAO
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.example.flowershopapp.Entities.Model.OrderBouquetCrossRef
import com.example.flowershopapp.Entities.Model.OrdersWithBouquets
import com.example.flowershopapp.Entities.Model.UsersWithOrders
import kotlinx.coroutines.flow.Flow
@Dao
interface OrdersWithBouquet {
@Query("select * from orderbouquetcrossref")
suspend fun getAll() : List<OrderBouquetCrossRef>
@Insert
suspend fun insert(order: OrderBouquetCrossRef)
@Update
suspend fun update(order: OrderBouquetCrossRef)
@Delete
suspend fun delete(order: OrderBouquetCrossRef)
}

View File

@ -1,10 +1,12 @@
package com.example.flowershopapp.Entities.DAO
import androidx.paging.PagingSource
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.example.flowershopapp.Entities.Model.Order
import com.example.flowershopapp.Entities.Model.OrdersWithBouquets
import com.example.flowershopapp.Entities.Model.User
import com.example.flowershopapp.Entities.Model.UsersWithOrders
@ -13,7 +15,7 @@ import kotlinx.coroutines.flow.Flow
@Dao
interface UserDAO {
@Query("select * from users")
fun getAll(): List<User>
fun getAll(): PagingSource<Int, User>
@Query("select * from users where name = :userName")
fun getUser(userName: String): User
@ -25,11 +27,13 @@ interface UserDAO {
fun getUsersWithOrders(): Flow<List<UsersWithOrders>>
@Insert
suspend fun insert(user: User)
suspend fun insert(vararg user: User)
@Update
suspend fun update(user: User)
@Delete
suspend fun delete(user: User)
@Query("DELETE FROM users")
suspend fun deleteAll()
}

View File

@ -3,18 +3,18 @@ package com.example.flowershopapp.Entities.DAO
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.example.flowershopapp.Entities.Model.OrderBouquetCrossRef
import com.example.flowershopapp.Entities.Model.UserOrderCrossRef
import com.example.flowershopapp.Entities.Model.UsersWithOrders
@Dao
interface UsersWithOrders {
@Query("select * from userordercrossref")
suspend fun getAll() : List<UserOrderCrossRef>
@Insert
suspend fun insert(user: UserOrderCrossRef)
@Update
suspend fun update(user: UserOrderCrossRef)
@Delete
suspend fun delete(user: UserOrderCrossRef)
}

View File

@ -1,5 +1,6 @@
package com.example.flowershopapp.Entities.Repository.Bouquet
import androidx.paging.PagingData
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
@ -8,8 +9,8 @@ import com.example.flowershopapp.Entities.Model.Bouquet
import kotlinx.coroutines.flow.Flow
interface BouquetRepository {
fun getAll(): Flow<List<Bouquet>>
fun getBouquet(id: Int): Bouquet
fun getAll(): Flow<PagingData<Bouquet>>
suspend fun getBouquet(id: Int): Bouquet
suspend fun insert(bouquet: Bouquet)
suspend fun update(bouquet: Bouquet)
suspend fun delete(bouquet: Bouquet)

View File

@ -1,13 +1,28 @@
package com.example.flowershopapp.Entities.Repository.Bouquet
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.PagingSource
import com.example.flowershopapp.Database.AppContainer
import com.example.flowershopapp.Entities.DAO.BouquetDAO
import com.example.flowershopapp.Entities.Model.Bouquet
import kotlinx.coroutines.flow.Flow
class OfflineBouquetRepository(private val bouquetDAO: BouquetDAO) : BouquetRepository {
override fun getAll(): Flow<List<Bouquet>> = bouquetDAO.getAll()
override fun getBouquet(id: Int): Bouquet = bouquetDAO.getBouquet(id)
override fun getAll(): Flow<PagingData<Bouquet>> = Pager(
config = PagingConfig(
pageSize = AppContainer.LIMIT,
enablePlaceholders = false
),
pagingSourceFactory = bouquetDAO::getAll
).flow
override suspend fun getBouquet(id: Int): Bouquet = bouquetDAO.getBouquet(id)
override suspend fun insert(bouquet: Bouquet) = bouquetDAO.insert(bouquet)
override suspend fun update(bouquet: Bouquet) = bouquetDAO.update(bouquet)
override suspend fun delete(bouquet: Bouquet) = bouquetDAO.delete(bouquet)
suspend fun deleteAll() = bouquetDAO.deleteAll()
fun getAllBouquetsPagingSource(): PagingSource<Int, Bouquet> = bouquetDAO.getAll()
suspend fun insertBouquets(bouquets: List<Bouquet>) =
bouquetDAO.insert(*bouquets.toTypedArray())
}

View File

@ -1,15 +1,31 @@
package com.example.flowershopapp.Entities.Repository.Order
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.PagingSource
import com.example.flowershopapp.Database.AppContainer
import com.example.flowershopapp.Entities.DAO.OrderDAO
import com.example.flowershopapp.Entities.Model.Bouquet
import com.example.flowershopapp.Entities.Model.Order
import com.example.flowershopapp.Entities.Model.OrdersWithBouquets
import kotlinx.coroutines.flow.Flow
class OfflineOrderRepository(private val orderDAO: OrderDAO) : OrderRepository {
override fun getAll(): List<Order> = orderDAO.getAll()
override fun getAll(): Flow<PagingData<Order>> = Pager(
config = PagingConfig(
pageSize = AppContainer.LIMIT,
enablePlaceholders = false
),
pagingSourceFactory = orderDAO::getAll
).flow
override fun getOrdersWithBouquet(): Flow<List<OrdersWithBouquets>> = orderDAO.getOrdersWithBouquet()
override fun getOrderWithBouquet(id: Int): OrdersWithBouquets = orderDAO.getOrderWithBouquet(id)
override suspend fun insert(order: Order) = orderDAO.insert(order)
override suspend fun update(order: Order) = orderDAO.update(order)
override suspend fun delete(order: Order) = orderDAO.delete(order)
fun getAllOrdersPagingSource(): PagingSource<Int, Order> = orderDAO.getAll()
suspend fun deleteAll() = orderDAO.deleteAll()
suspend fun insertOrders(orders: List<Order>) =
orderDAO.insert(*orders.toTypedArray())
}

View File

@ -1,5 +1,6 @@
package com.example.flowershopapp.Entities.Repository.Order
import androidx.paging.PagingData
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
@ -9,7 +10,7 @@ import com.example.flowershopapp.Entities.Model.OrdersWithBouquets
import kotlinx.coroutines.flow.Flow
interface OrderRepository {
fun getAll(): List<Order>
fun getAll(): Flow<PagingData<Order>>
fun getOrdersWithBouquet(): Flow<List<OrdersWithBouquets>>
fun getOrderWithBouquet(id: Int): OrdersWithBouquets
suspend fun insert(order: Order)

View File

@ -2,9 +2,11 @@ package com.example.flowershopapp.Entities.Repository.OrderBouquets
import com.example.flowershopapp.Entities.DAO.OrdersWithBouquet
import com.example.flowershopapp.Entities.Model.OrderBouquetCrossRef
import com.example.flowershopapp.Entities.Model.OrdersWithBouquets
import kotlinx.coroutines.flow.Flow
class OfflineOrdersWithBouquetsRepositoryRepository(private val orderBouquetsDAO: OrdersWithBouquet) : OrdersWithBouquetsRepository {
override suspend fun getAll() = orderBouquetsDAO.getAll()
override suspend fun insert(order: OrderBouquetCrossRef) = orderBouquetsDAO.insert(order)
override suspend fun update(order: OrderBouquetCrossRef) = orderBouquetsDAO.update(order)
override suspend fun delete(order: OrderBouquetCrossRef) = orderBouquetsDAO.delete(order)
}

View File

@ -1,9 +1,11 @@
package com.example.flowershopapp.Entities.Repository.OrderBouquets
import com.example.flowershopapp.Entities.Model.OrderBouquetCrossRef
import com.example.flowershopapp.Entities.Model.OrdersWithBouquets
import kotlinx.coroutines.flow.Flow
interface OrdersWithBouquetsRepository {
suspend fun getAll(): List<OrderBouquetCrossRef>
suspend fun insert(order: OrderBouquetCrossRef)
suspend fun update(order: OrderBouquetCrossRef)
suspend fun delete(order: OrderBouquetCrossRef)
}

View File

@ -1,15 +1,30 @@
package com.example.flowershopapp.Entities.Repository.User
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import com.example.flowershopapp.Database.AppContainer
import com.example.flowershopapp.Entities.DAO.UserDAO
import com.example.flowershopapp.Entities.Model.Order
import com.example.flowershopapp.Entities.Model.User
import com.example.flowershopapp.Entities.Model.UsersWithOrders
import kotlinx.coroutines.flow.Flow
class OfflineUserRepository(private val userDAO: UserDAO) : UserRepository{
override fun getAll(): List<User> = userDAO.getAll()
override fun getUser(userName: String): User = userDAO.getUser(userName)
override fun getUserWithOrders(userName: String): Flow<UsersWithOrders> = userDAO.getUserWithOrders(userName)
override fun getAll(): Flow<PagingData<User>> = Pager(
config = PagingConfig(
pageSize = AppContainer.LIMIT,
enablePlaceholders = false
),
pagingSourceFactory = userDAO::getAll
).flow
override suspend fun getUser(userName: String): User = userDAO.getUser(userName)
override suspend fun getUserWithOrders(userName: String): Flow<UsersWithOrders> = userDAO.getUserWithOrders(userName)
override fun getUsersWithOrders(): Flow<List<UsersWithOrders>> = userDAO.getUsersWithOrders()
override suspend fun insert(user: User) = userDAO.insert(user)
override suspend fun update(user: User) = userDAO.update(user)
override suspend fun delete(user: User) = userDAO.delete(user)
suspend fun deleteAll() = userDAO.deleteAll()
suspend fun insertUsers(users: List<User>) =
userDAO.insert(*users.toTypedArray())
}

View File

@ -1,17 +1,20 @@
package com.example.flowershopapp.Entities.Repository.User
import androidx.paging.PagingData
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.example.flowershopapp.Entities.Model.Order
import com.example.flowershopapp.Entities.Model.User
import com.example.flowershopapp.Entities.Model.UsersWithOrders
import kotlinx.coroutines.flow.Flow
interface UserRepository {
fun getAll(): List<User>
fun getUser(userName: String): User
fun getUserWithOrders(userName: String): Flow<UsersWithOrders>
fun getAll(): Flow<PagingData<User>>
suspend fun getUser(userName: String): User
suspend fun getUserWithOrders(userName: String): Flow<UsersWithOrders>
fun getUsersWithOrders(): Flow<List<UsersWithOrders>>
suspend fun insert(user: User)
suspend fun update(user: User)
suspend fun delete(user: User)
}

View File

@ -4,7 +4,7 @@ import com.example.flowershopapp.Entities.DAO.UsersWithOrders
import com.example.flowershopapp.Entities.Model.UserOrderCrossRef
class OfflineUsersWithOrdersRepository(private val userOrders: UsersWithOrders) : com.example.flowershopapp.Entities.Repository.UserOrders.UsersWithOrdersRepository {
override suspend fun getAll() = userOrders.getAll()
override suspend fun insert(user: UserOrderCrossRef) = userOrders.insert(user)
override suspend fun update(user: UserOrderCrossRef) = userOrders.update(user)
override suspend fun delete(user: UserOrderCrossRef) = userOrders.delete(user)
}

View File

@ -1,9 +1,10 @@
package com.example.flowershopapp.Entities.Repository.UserOrders
import com.example.flowershopapp.Entities.Model.OrderBouquetCrossRef
import com.example.flowershopapp.Entities.Model.UserOrderCrossRef
interface UsersWithOrdersRepository {
suspend fun getAll(): List<UserOrderCrossRef>
suspend fun insert(user: UserOrderCrossRef)
suspend fun update(user: UserOrderCrossRef)
suspend fun delete(user: UserOrderCrossRef)
}

42
server/.gitignore vendored Normal file
View File

@ -0,0 +1,42 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
# Compiled output
/dist
/tmp
/out-tsc
/bazel-out
# Node
/node_modules
npm-debug.log
yarn-error.log
# IDEs and editors
.idea/
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# Visual Studio Code
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history/*
# Miscellaneous
/.angular/cache
.sass-cache/
/connect.lock
/coverage
/libpeerconnection.log
testem.log
/typings
# System files
.DS_Store
Thumbs.db

42
server/data.json Normal file
View File

@ -0,0 +1,42 @@
{
"groups": [
{
"id": 1,
"name": "ПИбд-21"
},
{
"id": 2,
"name": "ПИбд-22"
},
{
"name": "ПИбд-23",
"id": 3
}
],
"students": [
{
"id": 2,
"firstName": "Test22244",
"lastName": "Test2",
"groupId": 2,
"phone": "Phone2",
"email": "Email2"
},
{
"firstName": "Test3",
"lastName": "Test3",
"groupId": 1,
"phone": "Phone3",
"email": "Email3",
"id": 3
},
{
"firstName": "werwerwe",
"lastName": "werwer",
"groupId": 1,
"phone": "sefswer",
"email": "werwer",
"id": 4
}
]
}

1335
server/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

12
server/package.json Normal file
View File

@ -0,0 +1,12 @@
{
"name": "fake-db",
"version": "1.0.0",
"scripts": {
"start": "json-server --watch data.json --host 0.0.0.0 -p 8079"
},
"dependencies": {
},
"devDependencies": {
"json-server": "0.17.4"
}
}

26
server/readme.md Normal file
View File

@ -0,0 +1,26 @@
Установка nodejs:
1. Заходим на сайт https://nodejs.org/en/
2. Скачиваем LTS версию
3. Устанавливаем
Переход в каталог с сервером:
```commandline
cd ./server
```
Установка зависимостей:
```commandline
npm install
```
Запуск:
```commandline
npm start
```
Примеры:
- http://localhost:8079
- http://localhost:8079/students
- http://localhost:8079/students?_expand=group
Документация -- https://www.npmjs.com/package/json-server