update published posts repo

This commit is contained in:
InsanusMokrassar 2020-12-02 17:51:43 +06:00
parent 703f3c057c
commit a3c4b67304
5 changed files with 123 additions and 43 deletions

File diff suppressed because one or more lines are too long

View File

@ -12,14 +12,14 @@ kotlin_coroutines_version=1.4.2
kotlin_serialisation_core_version=1.0.1 kotlin_serialisation_core_version=1.0.1
kotlin_exposed_version=0.28.1 kotlin_exposed_version=0.28.1
ktor_version=1.4.2 ktor_version=1.4.3
klockVersion=2.0.0 klockVersion=2.0.0
uuidVersion=0.2.3 uuidVersion=0.2.3
exposed_version=0.28.1 exposed_version=0.28.1
test_sqlite_version=3.32.3.2 test_sqlite_version=3.32.3.2
microutils_version=0.4.7 microutils_version=0.4.9
javax_activation_version=1.1.1 javax_activation_version=1.1.1

View File

@ -1,14 +1,15 @@
package dev.inmo.postssystem.core.publishing package dev.inmo.postssystem.core.publishing
import dev.inmo.micro_utils.repos.create
import dev.inmo.postssystem.core.post.PostId import dev.inmo.postssystem.core.post.PostId
import dev.inmo.postssystem.core.post.RegisteredPost import dev.inmo.postssystem.core.post.RegisteredPost
import dev.inmo.postssystem.core.post.repo.PostsRepo import dev.inmo.postssystem.core.post.repo.PostsRepo
import dev.inmo.postssystem.core.publishing.repos.PublishedPostsWriteRepo import dev.inmo.postssystem.core.publishing.repos.*
import dev.inmo.postssystem.core.publishing.repos.PublishingKeysRepo
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.*
import kotlinx.serialization.Serializable
interface PublishingTrigger { interface PublishingTrigger {
val postingTriggeredFlow: SharedFlow<RegisteredPost> val postingTriggeredFlow: SharedFlow<PublishedPost>
suspend fun triggerPosting( suspend fun triggerPosting(
triggerControlKey: TriggerControlKey triggerControlKey: TriggerControlKey
@ -20,23 +21,17 @@ class BusinessPublishingTrigger(
private val publishedPostsRepo: PublishedPostsWriteRepo, private val publishedPostsRepo: PublishedPostsWriteRepo,
private val publishingKeysRepo: PublishingKeysRepo private val publishingKeysRepo: PublishingKeysRepo
) : PublishingTrigger { ) : PublishingTrigger {
private val _postingTriggeredFlow: MutableSharedFlow<RegisteredPost> = MutableSharedFlow() private val _postingTriggeredFlow: MutableSharedFlow<PublishedPost> = MutableSharedFlow()
override val postingTriggeredFlow: SharedFlow<RegisteredPost> = _postingTriggeredFlow.asSharedFlow() override val postingTriggeredFlow: SharedFlow<PublishedPost> = _postingTriggeredFlow.asSharedFlow()
override suspend fun triggerPosting(triggerControlKey: TriggerControlKey): PostId? { override suspend fun triggerPosting(triggerControlKey: TriggerControlKey): PostId? {
val postId = publishingKeysRepo.getPostIdByTriggerControlKey(triggerControlKey) ?: return null val postId = publishingKeysRepo.getPostIdByTriggerControlKey(triggerControlKey) ?: return null
publishingKeysRepo.unsetPostTriggerControlKey(postId) publishingKeysRepo.unsetPostTriggerControlKey(postId)
return postsRepo.getPostById(postId) ?.let { post -> return postsRepo.getPostById(postId) ?.let { post ->
publishedPostsRepo.registerPublishedPost(post) ?.let { publishedPost -> publishedPostsRepo.create(post).firstOrNull() ?.also {
if (postsRepo.deletePost(postId)) { _postingTriggeredFlow.emit(it)
_postingTriggeredFlow.emit(post) }
postId } ?.id
} else {
publishedPostsRepo.unpublishPost(publishedPost.id)
null
}
}
}
} }
} }

View File

@ -1,36 +1,40 @@
package dev.inmo.postssystem.core.publishing.repos package dev.inmo.postssystem.core.publishing.repos
import com.soywiz.klock.DateTime
import dev.inmo.micro_utils.pagination.*
import dev.inmo.micro_utils.repos.*
import dev.inmo.postssystem.core.UnixMillis
import dev.inmo.postssystem.core.post.PostId import dev.inmo.postssystem.core.post.PostId
import dev.inmo.postssystem.core.post.RegisteredPost import dev.inmo.postssystem.core.post.RegisteredPost
import dev.inmo.postssystem.core.post.repo.PostsRepo import dev.inmo.postssystem.core.post.repo.PostsRepo
import dev.inmo.postssystem.core.post.repo.ReadPostsRepo
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
interface PublishedPostsReadRepo : ReadPostsRepo typealias PublishedPostId = String
interface PublishedPostsWriteRepo { @Serializable
val postPublishedFlow: Flow<RegisteredPost> data class PublishedPost(
val postUnpublishedFlow: Flow<RegisteredPost> val id: PublishedPostId,
val post: RegisteredPost,
suspend fun registerPublishedPost(registeredPost: RegisteredPost): RegisteredPost? private val publicationTime: UnixMillis
suspend fun unpublishPost(postId: PostId): Boolean? ) {
@Transient
val publicationDateTime = DateTime(publicationTime)
} }
interface PublishedPostsRepo : PublishedPostsReadRepo, PublishedPostsWriteRepo interface PublishedPostsReadRepo : ReadCRUDRepo<PublishedPost, PublishedPostId> {
suspend fun getPostPublishing(
class BusinessPublishedPostsRepo( postId: PostId,
private val realPostsRepoWithPublishedPosts: PostsRepo pagination: Pagination,
) : PublishedPostsRepo, ReadPostsRepo by realPostsRepoWithPublishedPosts { reversed: Boolean = false
override val postPublishedFlow: Flow<RegisteredPost> ): PaginationResult<PublishedPostId>
get() = realPostsRepoWithPublishedPosts.postCreatedFlow
override val postUnpublishedFlow: Flow<RegisteredPost>
get() = realPostsRepoWithPublishedPosts.postDeletedFlow
override suspend fun registerPublishedPost(
registeredPost: RegisteredPost
): RegisteredPost? = realPostsRepoWithPublishedPosts.createPost(registeredPost)
override suspend fun unpublishPost(
postId: PostId
): Boolean? = realPostsRepoWithPublishedPosts.deletePost(postId)
} }
suspend inline fun PostId.isPublished(lookIn: PublishedPostsReadRepo): Boolean {
return lookIn.getPostPublishing(this, FirstPagePagination(1)).results.isNotEmpty()
}
suspend inline fun RegisteredPost.isPublished(lookIn: PublishedPostsReadRepo): Boolean {
return lookIn.getPostPublishing(id, FirstPagePagination(1)).results.isNotEmpty()
}
interface PublishedPostsWriteRepo : WriteCRUDRepo<PublishedPost, PublishedPostId, RegisteredPost>
interface PublishedPostsRepo : PublishedPostsReadRepo, PublishedPostsWriteRepo, CRUDRepo<PublishedPost, PublishedPostId, RegisteredPost>

View File

@ -0,0 +1,81 @@
package dev.inmo.postssystem.core.publishing.exposed
import com.soywiz.klock.DateTime
import dev.inmo.micro_utils.coroutines.launchSynchronously
import dev.inmo.micro_utils.pagination.*
import dev.inmo.micro_utils.pagination.utils.reverse
import dev.inmo.micro_utils.repos.exposed.AbstractExposedCRUDRepo
import dev.inmo.micro_utils.repos.exposed.initTable
import dev.inmo.postssystem.core.generateId
import dev.inmo.postssystem.core.post.PostId
import dev.inmo.postssystem.core.post.RegisteredPost
import dev.inmo.postssystem.core.post.repo.ReadPostsRepo
import dev.inmo.postssystem.core.publishing.repos.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.statements.InsertStatement
import org.jetbrains.exposed.sql.statements.UpdateStatement
import org.jetbrains.exposed.sql.transactions.transaction
class ExposedPublishedPostsRepo(
override val database: Database,
private val postsRepo: ReadPostsRepo,
tableName: String = "PublishedPostsRepo",
private val scope: CoroutineScope = CoroutineScope(Dispatchers.Default)
) : PublishedPostsRepo,
AbstractExposedCRUDRepo<PublishedPost, PublishedPostId, RegisteredPost>(
tableName = tableName
) {
private val idColumn = text("id")
private val postIdColumn = text("postId")
private val dateTimeColumn = double("dateTime").clientDefault {
DateTime.now().unixMillis
}
override val selectByIds: SqlExpressionBuilder.(List<PublishedPostId>) -> Op<Boolean> = { idColumn.inList(it) }
override val InsertStatement<Number>.asObject: PublishedPost get() = TODO()
override fun InsertStatement<Number>.asObject(value: RegisteredPost): PublishedPost = PublishedPost(
get(idColumn),
value,
get(dateTimeColumn)
)
override val selectById: SqlExpressionBuilder.(PublishedPostId) -> Op<Boolean> = { idColumn.eq(it) }
override val ResultRow.asObject: PublishedPost
get() = PublishedPost(
get(idColumn),
requireNotNull(launchSynchronously(scope) { postsRepo.getPostById(get(postIdColumn)) }) { "Post with id \"${get(postIdColumn)}\" not found" },
get(dateTimeColumn)
)
init {
initTable()
}
override fun insert(value: RegisteredPost, it: InsertStatement<Number>) {
it[idColumn] = generateId()
it[postIdColumn] = value.id
}
override fun update(id: PublishedPostId, value: RegisteredPost, it: UpdateStatement) {
it[postIdColumn] = value.id
}
override suspend fun getPostPublishing(
postId: PostId,
pagination: Pagination,
reversed: Boolean
): PaginationResult<PublishedPostId> = transaction(database) {
val query = select { postIdColumn.eq(postId) }
query.paginate(pagination, postIdColumn, reversed).map {
it[idColumn]
} to query.count()
}.let { (results, count) ->
results.createPaginationResult(
if (reversed) pagination.reverse(count) else pagination,
count
)
}
}