118 lines
4.4 KiB
Kotlin
118 lines
4.4 KiB
Kotlin
package dev.inmo.postssystem.core.content.api.business
|
|
|
|
import dev.inmo.micro_utils.pagination.*
|
|
import dev.inmo.micro_utils.repos.UpdatedValuePair
|
|
import dev.inmo.postssystem.core.content.*
|
|
import dev.inmo.postssystem.core.content.api.*
|
|
import dev.inmo.postssystem.core.generateContentId
|
|
import kotlinx.coroutines.flow.*
|
|
|
|
interface BusinessContentRepoContentAdapter {
|
|
val type: AdapterType
|
|
suspend fun storeContent(contentId: ContentId, content: Content): Boolean
|
|
suspend fun getContent(contentId: ContentId): Content?
|
|
suspend fun removeContent(contentId: ContentId)
|
|
}
|
|
|
|
class BusinessReadContentRepo(
|
|
adapters: List<BusinessContentRepoContentAdapter>,
|
|
private val helperRepo: BusinessContentRepoReadHelper,
|
|
) : ReadContentRepo {
|
|
private val adaptersMap: Map<String, BusinessContentRepoContentAdapter> = adapters.map {
|
|
it.type to it
|
|
}.toMap()
|
|
override suspend fun contains(id: ContentId): Boolean = helperRepo.contains(id)
|
|
|
|
override suspend fun count(): Long = helperRepo.count()
|
|
|
|
override suspend fun getById(id: ContentId): RegisteredContent? = helperRepo.getType(id) ?.let {
|
|
adaptersMap[it] ?.getContent(id) ?.let { content ->
|
|
RegisteredContent(id, content)
|
|
}
|
|
}
|
|
|
|
override suspend fun getByPagination(
|
|
pagination: Pagination
|
|
): PaginationResult<RegisteredContent> = helperRepo.getKeysByPagination(
|
|
pagination
|
|
).let {
|
|
it.results.mapNotNull {
|
|
getById(it)
|
|
}.createPaginationResult(
|
|
it,
|
|
count()
|
|
)
|
|
}
|
|
}
|
|
|
|
class BusinessWriteContentRepo(
|
|
private val adapters: List<BusinessContentRepoContentAdapter>,
|
|
private val helperRepo: BusinessContentRepoHelper
|
|
) : WriteContentRepo {
|
|
private val adaptersMap = adapters.map { it.type to it }.toMap()
|
|
private val _deletedObjectsIdsFlow = MutableSharedFlow<ContentId>()
|
|
override val deletedObjectsIdsFlow: Flow<ContentId> = _deletedObjectsIdsFlow.asSharedFlow()
|
|
private val _newObjectsFlow = MutableSharedFlow<RegisteredContent>()
|
|
override val newObjectsFlow: Flow<RegisteredContent> = _newObjectsFlow.asSharedFlow()
|
|
private val _updatedObjectsFlow = MutableSharedFlow<RegisteredContent>()
|
|
override val updatedObjectsFlow: Flow<RegisteredContent> = _updatedObjectsFlow.asSharedFlow()
|
|
|
|
override suspend fun create(values: List<Content>): List<RegisteredContent> {
|
|
return values.mapNotNull { content ->
|
|
if (content is OtherContentLinkContent) {
|
|
adapters.forEach {
|
|
val existsContent = it.getContent(content.otherId)
|
|
if (existsContent != null) {
|
|
return@mapNotNull RegisteredContent(
|
|
content.otherId,
|
|
existsContent
|
|
)
|
|
}
|
|
}
|
|
}
|
|
val contentId = generateContentId()
|
|
val adapter = adapters.firstOrNull { it.storeContent(contentId, content) } ?: return@mapNotNull null
|
|
if (!helperRepo.saveType(contentId, adapter.type)) {
|
|
adapter.removeContent(contentId)
|
|
}
|
|
RegisteredContent(contentId, content).also { _newObjectsFlow.emit(it) }
|
|
}
|
|
}
|
|
|
|
override suspend fun deleteById(ids: List<ContentId>) {
|
|
ids.forEach { contentId ->
|
|
adaptersMap[helperRepo.getType(contentId)] ?.removeContent(contentId) ?: adapters.forEach {
|
|
it.removeContent(contentId)
|
|
}
|
|
helperRepo.deleteContentId(contentId)
|
|
_deletedObjectsIdsFlow.emit(contentId)
|
|
}
|
|
}
|
|
|
|
override suspend fun update(id: ContentId, value: Content): RegisteredContent? {
|
|
adaptersMap[helperRepo.getType(id)] ?.removeContent(id) ?: adapters.forEach {
|
|
it.removeContent(id)
|
|
}
|
|
adapters.firstOrNull { it.storeContent(id, value) } ?: return null
|
|
return RegisteredContent(id, value).also { _updatedObjectsFlow.emit(it) }
|
|
}
|
|
|
|
override suspend fun update(values: List<UpdatedValuePair<ContentId, Content>>): List<RegisteredContent> {
|
|
return values.mapNotNull {
|
|
update(it.first, it.second)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
class BusinessContentRepo(
|
|
adapters: List<BusinessContentRepoContentAdapter>,
|
|
helperRepo: BusinessContentRepoHelper
|
|
) : ContentRepo, ReadContentRepo by BusinessReadContentRepo(
|
|
adapters,
|
|
helperRepo
|
|
), WriteContentRepo by BusinessWriteContentRepo(
|
|
adapters,
|
|
helperRepo
|
|
)
|