Skip to content

Commit

Permalink
Post database repository
Browse files Browse the repository at this point in the history
  • Loading branch information
nathanfallet committed Dec 9, 2023
1 parent 5cfd6c2 commit db5c1f9
Show file tree
Hide file tree
Showing 4 changed files with 347 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package me.nathanfallet.extopy.database.posts

import kotlinx.datetime.Clock
import me.nathanfallet.extopy.database.Database
import me.nathanfallet.extopy.database.users.Users
import me.nathanfallet.extopy.models.posts.Post
import me.nathanfallet.extopy.models.posts.PostPayload
import me.nathanfallet.extopy.models.users.UserContext
import me.nathanfallet.extopy.repositories.posts.IPostsRepository
import me.nathanfallet.usecases.context.IContext
import org.jetbrains.exposed.sql.*

class DatabasePostsRepository(
private val database: Database,
) : IPostsRepository {

override suspend fun get(id: String, context: IContext?): Post? {
if (context !is UserContext) return null
return database.dbQuery {
customJoin(context.userId)
.select { Posts.id eq id }
.groupBy(Posts.id)
.map { Posts.toPost(it, Users.toUser(it)) }
.singleOrNull()
}
}

override suspend fun create(payload: PostPayload, context: IContext?): Post? {
if (context !is UserContext) return null
val id = database.dbQuery {
val id = Posts.generateId()
Posts.insert {
it[Posts.id] = id
it[userId] = context.userId
it[repliedToId] = payload.repliedToId
it[repostOfId] = payload.repostOfId
it[body] = payload.body
it[published] = Clock.System.now().toString()
it[edited] = null
it[expiration] = Clock.System.now().toString()
it[visibility] = ""
}
id
}
return get(id, context)
}

override suspend fun update(id: String, payload: PostPayload, context: IContext?): Boolean {
return database.dbQuery {
Posts.update({ Posts.id eq id }) {
it[body] = payload.body
it[edited] = Clock.System.now().toString()
}
} == 1
}

override suspend fun delete(id: String, context: IContext?): Boolean {
return database.dbQuery {
Posts.deleteWhere {
Op.build { Posts.id eq id }
}
} == 1
}

private fun customJoin(viewedBy: String): FieldSet {
return customJoinColumnSet(viewedBy).customPostsSlice()
}

private fun customJoinColumnSet(viewedBy: String): ColumnSet {
return Posts.join(Users, JoinType.INNER, Posts.userId, Users.id)
.join(LikesInPosts, JoinType.LEFT, Posts.id, LikesInPosts.postId)
.join(Posts.replies, JoinType.LEFT, Posts.id, Posts.replies[Posts.repliedToId])
.join(Posts.reposts, JoinType.LEFT, Posts.id, Posts.reposts[Posts.repostOfId])
.join(
LikesInPosts.likesIn,
JoinType.LEFT,
Posts.id,
LikesInPosts.likesIn[LikesInPosts.postId]
) { LikesInPosts.likesIn[LikesInPosts.userId] eq viewedBy }
}

private fun ColumnSet.customPostsSlice(additionalFields: List<Expression<*>> = listOf()): FieldSet {
return slice(
Posts.columns +
Users.id +
Users.displayName +
Users.username +
Users.avatar +
Users.verified +
Posts.likesCount +
Posts.repliesCount +
Posts.repostsCount +
Posts.likesIn +
additionalFields
)
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package me.nathanfallet.extopy.database.posts

import kotlinx.datetime.toInstant
import me.nathanfallet.extopy.database.users.Users
import me.nathanfallet.extopy.extensions.generateId
import me.nathanfallet.extopy.models.posts.Post
import me.nathanfallet.extopy.models.users.User
Expand All @@ -10,7 +9,7 @@ import org.jetbrains.exposed.sql.*
object Posts : Table() {

val id = varchar("id", 32)
val userId = varchar("user_id", 32)
val userId = varchar("user_id", 32).index()
val repliedToId = varchar("replied_to_id", 32).nullable()
val repostOfId = varchar("repost_of_id", 32).nullable()
val body = text("body")
Expand Down Expand Up @@ -41,7 +40,7 @@ object Posts : Table() {

fun toPost(
row: ResultRow,
user: User?,
user: User? = null,
) = Post(
row[id],
row.getOrNull(userId),
Expand Down Expand Up @@ -73,37 +72,4 @@ object Posts : Table() {
}
}

fun customJoinnable(viewedBy: String): ColumnSet {
return Posts.join(Users, JoinType.INNER, userId, Users.id)
.join(LikesInPosts, JoinType.LEFT, id, LikesInPosts.postId)
.join(replies, JoinType.LEFT, id, replies[repliedToId])
.join(reposts, JoinType.LEFT, id, reposts[repostOfId])
.join(
LikesInPosts.likesIn,
JoinType.LEFT,
id,
LikesInPosts.likesIn[LikesInPosts.postId],
{ LikesInPosts.likesIn[LikesInPosts.userId] eq viewedBy }
)
}

fun customJoin(viewedBy: String): FieldSet {
return customJoinnable(viewedBy).customPostsSlice()
}
}

fun ColumnSet.customPostsSlice(additionalFields: List<Expression<*>> = listOf()): FieldSet {
return slice(
Posts.columns +
Users.id +
Users.displayName +
Users.username +
Users.avatar +
Users.verified +
Posts.likesCount +
Posts.repliesCount +
Posts.repostsCount +
Posts.likesIn +
additionalFields
)
}
Loading

0 comments on commit db5c1f9

Please sign in to comment.