add businessContentRepo
This commit is contained in:
parent
f7d60fa672
commit
20e3fd6934
@ -11,8 +11,7 @@ typealias ContentId = String
|
||||
/**
|
||||
* Content which is planned to be registered in database
|
||||
*/
|
||||
@Serializable
|
||||
sealed class Content
|
||||
interface Content
|
||||
|
||||
/**
|
||||
* It is content, which was added by some external source to use inside of some plugins. For example, you can use
|
||||
@ -21,12 +20,12 @@ sealed class Content
|
||||
@Serializable
|
||||
data class SpecialContent(
|
||||
val internalId: ContentId
|
||||
) : Content()
|
||||
) : Content
|
||||
|
||||
@Serializable
|
||||
data class TextContent(
|
||||
val text: String
|
||||
) : Content()
|
||||
) : Content
|
||||
|
||||
@Serializable
|
||||
data class BinaryContent(
|
||||
@ -34,7 +33,7 @@ data class BinaryContent(
|
||||
val originalFileName: String,
|
||||
@Serializable(ByteArrayAllocatorSerializer::class)
|
||||
val dataAllocator: ByteArrayAllocator
|
||||
) : Content()
|
||||
) : Content
|
||||
|
||||
val BinaryContent.isImage: Boolean
|
||||
get() = mimeType is KnownMimeTypes.Image
|
||||
|
@ -0,0 +1,120 @@
|
||||
package dev.inmo.postssystem.core.content.api
|
||||
|
||||
import dev.inmo.micro_utils.pagination.*
|
||||
import dev.inmo.micro_utils.repos.Repo
|
||||
import dev.inmo.micro_utils.repos.UpdatedValuePair
|
||||
import dev.inmo.postssystem.core.content.*
|
||||
import dev.inmo.postssystem.core.generateContentId
|
||||
import kotlinx.coroutines.flow.*
|
||||
|
||||
interface BusinessContentRepoReadHelpInterface : Repo {
|
||||
suspend fun getKeysByPagination(pagination: Pagination): PaginationResult<ContentId>
|
||||
suspend fun contains(contentId: ContentId): Boolean
|
||||
suspend fun getType(contentId: ContentId): AdapterType?
|
||||
suspend fun count(): Long
|
||||
}
|
||||
interface BusinessContentRepoWriteHelpInterface : Repo {
|
||||
suspend fun deleteContentId(contentId: ContentId)
|
||||
suspend fun saveType(contentId: ContentId, type: AdapterType): Boolean
|
||||
}
|
||||
interface BusinessContentRepoHelpInterface : BusinessContentRepoReadHelpInterface, BusinessContentRepoWriteHelpInterface
|
||||
|
||||
typealias AdapterType = String
|
||||
|
||||
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: BusinessContentRepoReadHelpInterface,
|
||||
) : 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: BusinessContentRepoHelpInterface
|
||||
) : 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 ->
|
||||
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: BusinessContentRepoHelpInterface
|
||||
) : ContentRepo, ReadContentRepo by BusinessReadContentRepo(
|
||||
adapters,
|
||||
helperRepo
|
||||
), WriteContentRepo by BusinessWriteContentRepo(
|
||||
adapters,
|
||||
helperRepo
|
||||
)
|
@ -4,22 +4,10 @@ import dev.inmo.postssystem.core.content.ContentId
|
||||
import dev.inmo.postssystem.core.content.RegisteredContent
|
||||
import dev.inmo.micro_utils.pagination.Pagination
|
||||
import dev.inmo.micro_utils.pagination.PaginationResult
|
||||
import dev.inmo.micro_utils.repos.ReadStandardCRUDRepo
|
||||
import dev.inmo.micro_utils.repos.pagination.getAll
|
||||
|
||||
/**
|
||||
* Simple read API by different properties of [dev.inmo.postssystem.core.content.Content].
|
||||
*/
|
||||
interface ReadContentRepo {
|
||||
/**
|
||||
* @return [Set] of [ContentId] wich currently known in this instance of API
|
||||
*/
|
||||
suspend fun getContentsIds(): Set<ContentId>
|
||||
/**
|
||||
* @return [RegisteredContent] if it is available by [id]
|
||||
*/
|
||||
suspend fun getContentById(id: ContentId): RegisteredContent?
|
||||
|
||||
/**
|
||||
* @return all [RegisteredContent] by pages basing on their creation date
|
||||
*/
|
||||
suspend fun getContentByPagination(pagination: Pagination): PaginationResult<RegisteredContent>
|
||||
}
|
||||
interface ReadContentRepo : ReadStandardCRUDRepo<RegisteredContent, ContentId>
|
||||
|
@ -1,12 +1,7 @@
|
||||
package dev.inmo.postssystem.core.content.api
|
||||
|
||||
import dev.inmo.micro_utils.repos.WriteStandardCRUDRepo
|
||||
import dev.inmo.postssystem.core.content.*
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface WriteContentRepo {
|
||||
val contentCreatedFlow: Flow<RegisteredContent>
|
||||
val contentDeletedFlow: Flow<RegisteredContent>
|
||||
|
||||
suspend fun registerContent(content: Content): RegisteredContent?
|
||||
suspend fun deleteContent(id: ContentId): Boolean
|
||||
}
|
||||
interface WriteContentRepo : WriteStandardCRUDRepo<RegisteredContent, ContentId, Content>
|
||||
|
Loading…
Reference in New Issue
Block a user