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_exposed_version=0.28.1
ktor_version=1.4.2
ktor_version=1.4.3
klockVersion=2.0.0
uuidVersion=0.2.3
exposed_version=0.28.1
test_sqlite_version=3.32.3.2
microutils_version=0.4.7
microutils_version=0.4.9
javax_activation_version=1.1.1

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

@ -1,36 +1,40 @@
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.RegisteredPost
import dev.inmo.postssystem.core.post.repo.PostsRepo
import dev.inmo.postssystem.core.post.repo.ReadPostsRepo
import kotlinx.coroutines.flow.Flow
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
interface PublishedPostsReadRepo : ReadPostsRepo
interface PublishedPostsWriteRepo {
val postPublishedFlow: Flow<RegisteredPost>
val postUnpublishedFlow: Flow<RegisteredPost>
suspend fun registerPublishedPost(registeredPost: RegisteredPost): RegisteredPost?
suspend fun unpublishPost(postId: PostId): Boolean?
typealias PublishedPostId = String
@Serializable
data class PublishedPost(
val id: PublishedPostId,
val post: RegisteredPost,
private val publicationTime: UnixMillis
) {
@Transient
val publicationDateTime = DateTime(publicationTime)
}
interface PublishedPostsRepo : PublishedPostsReadRepo, PublishedPostsWriteRepo
class BusinessPublishedPostsRepo(
private val realPostsRepoWithPublishedPosts: PostsRepo
) : PublishedPostsRepo, ReadPostsRepo by realPostsRepoWithPublishedPosts {
override val postPublishedFlow: Flow<RegisteredPost>
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)
interface PublishedPostsReadRepo : ReadCRUDRepo<PublishedPost, PublishedPostId> {
suspend fun getPostPublishing(
postId: PostId,
pagination: Pagination,
reversed: Boolean = false
): PaginationResult<PublishedPostId>
}
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
)
}
}