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
|
* Content which is planned to be registered in database
|
||||||
*/
|
*/
|
||||||
@Serializable
|
interface Content
|
||||||
sealed class Content
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It is content, which was added by some external source to use inside of some plugins. For example, you can use
|
* 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
|
@Serializable
|
||||||
data class SpecialContent(
|
data class SpecialContent(
|
||||||
val internalId: ContentId
|
val internalId: ContentId
|
||||||
) : Content()
|
) : Content
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class TextContent(
|
data class TextContent(
|
||||||
val text: String
|
val text: String
|
||||||
) : Content()
|
) : Content
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class BinaryContent(
|
data class BinaryContent(
|
||||||
@ -34,7 +33,7 @@ data class BinaryContent(
|
|||||||
val originalFileName: String,
|
val originalFileName: String,
|
||||||
@Serializable(ByteArrayAllocatorSerializer::class)
|
@Serializable(ByteArrayAllocatorSerializer::class)
|
||||||
val dataAllocator: ByteArrayAllocator
|
val dataAllocator: ByteArrayAllocator
|
||||||
) : Content()
|
) : Content
|
||||||
|
|
||||||
val BinaryContent.isImage: Boolean
|
val BinaryContent.isImage: Boolean
|
||||||
get() = mimeType is KnownMimeTypes.Image
|
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.postssystem.core.content.RegisteredContent
|
||||||
import dev.inmo.micro_utils.pagination.Pagination
|
import dev.inmo.micro_utils.pagination.Pagination
|
||||||
import dev.inmo.micro_utils.pagination.PaginationResult
|
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].
|
* Simple read API by different properties of [dev.inmo.postssystem.core.content.Content].
|
||||||
*/
|
*/
|
||||||
interface ReadContentRepo {
|
interface ReadContentRepo : ReadStandardCRUDRepo<RegisteredContent, ContentId>
|
||||||
/**
|
|
||||||
* @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>
|
|
||||||
}
|
|
||||||
|
@ -1,12 +1,7 @@
|
|||||||
package dev.inmo.postssystem.core.content.api
|
package dev.inmo.postssystem.core.content.api
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.repos.WriteStandardCRUDRepo
|
||||||
import dev.inmo.postssystem.core.content.*
|
import dev.inmo.postssystem.core.content.*
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
interface WriteContentRepo {
|
interface WriteContentRepo : WriteStandardCRUDRepo<RegisteredContent, ContentId, Content>
|
||||||
val contentCreatedFlow: Flow<RegisteredContent>
|
|
||||||
val contentDeletedFlow: Flow<RegisteredContent>
|
|
||||||
|
|
||||||
suspend fun registerContent(content: Content): RegisteredContent?
|
|
||||||
suspend fun deleteContent(id: ContentId): Boolean
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user