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.*
|
2022-10-25 06:43:12 +00:00
|
|
|
import org.jetbrains.exposed.sql.statements.*
|
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"
|
|
|
|
) {
|
2022-10-25 06:43:12 +00:00
|
|
|
val idColumn = text("id")
|
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))
|
|
|
|
|
|
|
|
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-10-25 06:43:12 +00:00
|
|
|
override fun createAndInsertId(value: NewPost, it: InsertStatement<Number>): PostId {
|
|
|
|
val id = PostId(uuid4().toString())
|
|
|
|
it[idColumn] = id.string
|
|
|
|
return id
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun update(id: PostId?, value: NewPost, it: UpdateBuilder<Int>) {
|
|
|
|
id ?: error("Unable to find post id in update")
|
2022-08-18 12:59:05 +00:00
|
|
|
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>) {
|
2022-10-25 06:43:12 +00:00
|
|
|
super.insert(value, it)
|
2022-09-09 12:17:02 +00:00
|
|
|
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
|
|
|
}
|