PlaguPoster/posts/src/jvmMain/kotlin/exposed/ExposedPostsRepo.kt

144 lines
4.9 KiB
Kotlin
Raw Normal View History

2022-08-18 12:59:05 +00:00
package dev.inmo.plaguposter.posts.exposed
import com.benasher44.uuid.uuid4
2022-09-09 11:27:11 +00:00
import com.soywiz.klock.DateTime
2022-08-18 12:59:05 +00:00
import dev.inmo.micro_utils.repos.KeyValuesRepo
import dev.inmo.micro_utils.repos.exposed.AbstractExposedCRUDRepo
2022-08-19 18:52:31 +00:00
import dev.inmo.micro_utils.repos.exposed.initTable
2022-08-18 12:59:05 +00:00
import dev.inmo.plaguposter.posts.models.*
import dev.inmo.plaguposter.posts.repo.PostsRepo
2022-08-20 16:26:38 +00:00
import dev.inmo.tgbotapi.types.ChatId
import dev.inmo.tgbotapi.types.MessageIdentifier
2022-09-04 09:46:45 +00:00
import kotlinx.coroutines.flow.*
2022-08-18 12:59:05 +00:00
import kotlinx.serialization.json.Json
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.statements.InsertStatement
import org.jetbrains.exposed.sql.statements.UpdateStatement
2022-08-20 16:26:38 +00:00
import org.jetbrains.exposed.sql.transactions.transaction
2022-08-18 12:59:05 +00:00
class ExposedPostsRepo(
2022-08-20 16:26:38 +00:00
override val database: Database
2022-08-18 12:59:05 +00:00
) : PostsRepo, AbstractExposedCRUDRepo<RegisteredPost, PostId, NewPost>(
tableName = "posts"
) {
val idColumn = text("id").clientDefault { uuid4().toString() }
2022-09-09 12:01:50 +00:00
val createdColumn = double("datetime").default(0.0)
2022-08-18 12:59:05 +00:00
private val contentRepo by lazy {
ExposedContentInfoRepo(
database,
idColumn
)
}
2022-08-19 18:52:31 +00:00
override val primaryKey: PrimaryKey = PrimaryKey(idColumn)
2022-08-18 12:59:05 +00:00
override val selectById: SqlExpressionBuilder.(PostId) -> Op<Boolean> = { idColumn.eq(it.string) }
override val selectByIds: SqlExpressionBuilder.(List<PostId>) -> Op<Boolean> = { idColumn.inList(it.map { it.string }) }
override val ResultRow.asObject: RegisteredPost
get() {
val id = PostId(get(idColumn))
return RegisteredPost(
id,
2022-09-09 11:27:11 +00:00
DateTime(get(createdColumn)),
2022-08-18 12:59:05 +00:00
with(contentRepo) {
select { postIdColumn.eq(id.string) }.map {
it.asObject
}
}
)
}
2022-09-04 09:46:45 +00:00
private val _removedPostsFlow = MutableSharedFlow<RegisteredPost>()
override val removedPostsFlow: Flow<RegisteredPost> = _removedPostsFlow.asSharedFlow()
2022-08-19 18:52:31 +00:00
init {
initTable()
}
2022-08-18 12:59:05 +00:00
override fun InsertStatement<Number>.asObject(value: NewPost): RegisteredPost {
val id = PostId(get(idColumn))
with(contentRepo) {
value.content.forEach { contentInfo ->
insert {
it[postIdColumn] = id.string
it[chatIdColumn] = contentInfo.chatId.chatId
it[messageIdColumn] = contentInfo.messageId
it[groupColumn] = contentInfo.group
it[orderColumn] = contentInfo.order
}
}
}
return RegisteredPost(
id,
2022-09-09 11:27:11 +00:00
DateTime(get(createdColumn)),
2022-08-18 12:59:05 +00:00
with(contentRepo) {
select { postIdColumn.eq(id.string) }.map {
it.asObject
}
}
)
}
override fun update(id: PostId, value: NewPost, it: UpdateStatement) {
with(contentRepo) {
deleteWhere { postIdColumn.eq(id.string) }
value.content.forEach { contentInfo ->
insert {
it[postIdColumn] = id.string
it[chatIdColumn] = contentInfo.chatId.chatId
it[messageIdColumn] = contentInfo.messageId
it[groupColumn] = contentInfo.group
it[orderColumn] = contentInfo.order
}
}
}
}
2022-09-09 12:17:02 +00:00
override fun insert(value: NewPost, it: InsertStatement<Number>) {
it[createdColumn] = DateTime.now().unixMillis
}
2022-08-20 16:26:38 +00:00
override suspend fun deleteById(ids: List<PostId>) {
onBeforeDelete(ids)
2022-09-04 09:46:45 +00:00
val posts = ids.mapNotNull {
getById(it)
}.associateBy { it.id }
val existsIds = posts.keys.toList()
2022-08-20 16:26:38 +00:00
transaction(db = database) {
val deleted = deleteWhere(null, null) {
2022-09-04 09:46:45 +00:00
selectByIds(existsIds)
2022-08-20 16:26:38 +00:00
}
with(contentRepo) {
deleteWhere {
2022-09-04 09:46:45 +00:00
postIdColumn.inList(existsIds.map { it.string })
2022-08-20 16:26:38 +00:00
}
}
2022-09-04 09:46:45 +00:00
if (deleted == existsIds.size) {
existsIds
2022-08-20 16:26:38 +00:00
} else {
2022-09-04 09:46:45 +00:00
existsIds.filter {
2022-08-20 16:26:38 +00:00
select { selectById(it) }.limit(1).none()
}
}
}.forEach {
_deletedObjectsIdsFlow.emit(it)
2022-09-04 09:46:45 +00:00
_removedPostsFlow.emit(posts[it] ?: return@forEach)
2022-08-20 16:26:38 +00:00
}
}
override suspend fun getIdByChatAndMessage(chatId: ChatId, messageId: MessageIdentifier): PostId? {
return transaction(database) {
with(contentRepo) {
select { chatIdColumn.eq(chatId.chatId).and(messageIdColumn.eq(messageId)) }.limit(1).firstOrNull() ?.get(postIdColumn)
} ?.let(::PostId)
}
}
2022-09-09 11:27:11 +00:00
override suspend fun getPostCreationTime(postId: PostId): DateTime? = transaction(database) {
select { selectById(postId) }.limit(1).firstOrNull() ?.get(createdColumn) ?.let(::DateTime)
}
2022-08-18 12:59:05 +00:00
}