update published posts repo

This commit is contained in:
2020-12-02 17:51:43 +06:00
parent 703f3c057c
commit a3c4b67304
5 changed files with 123 additions and 43 deletions
PostsSystem.drawiogradle.properties
publishing
api
src
commonMain
kotlin
dev
inmo
postssystem
exposed
src
jvmMain
kotlin
dev
inmo
postssystem
core

File diff suppressed because one or more lines are too long

@ -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

@ -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
} else {
publishedPostsRepo.unpublishPost(publishedPost.id)
null
}
} }
} } ?.id
} }
} }

@ -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>

@ -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
)
}
}