You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Api/Sources/src/main/kotlin/allin/data/postgres/PostgresFriendDataSource.kt

97 lines
3.3 KiB

package allin.data.postgres
import allin.data.FriendDataSource
import allin.data.postgres.entities.FriendEntity
import allin.data.postgres.entities.friends
import allin.data.postgres.entities.users
import allin.dto.UserDTO
import allin.ext.length
import allin.ext.levenshteinLessEq
import allin.ext.toLowerCase
import allin.model.FriendStatus
import org.ktorm.database.Database
import org.ktorm.dsl.and
import org.ktorm.dsl.div
import org.ktorm.dsl.eq
import org.ktorm.dsl.notEq
import org.ktorm.entity.*
class PostgresFriendDataSource(private val database: Database) : FriendDataSource {
override fun addFriend(sender: String, receiver: String) {
database.friends.add(
FriendEntity {
this.sender = sender
this.receiver = receiver
}
)
}
override fun getFriendFromUserId(id: String): List<UserDTO> {
return database.friends.map { it.toFriend() }
.filter { it.sender == id }
.mapNotNull { friend ->
val receiverUser = database.users.find { usr ->
usr.id eq friend.receiver
}
receiverUser?.toUserDTO(
database,
friendStatus = if (isFriend(friend.receiver, id)) {
FriendStatus.FRIEND
} else FriendStatus.REQUESTED
)
}
}
override fun getFriendRequestsFromUserId(id: String): List<UserDTO> {
return database.friends
.filter { it.receiver eq id }
.mapNotNull {
if (isFriend(firstUser = id, secondUser = it.sender)) {
null
} else {
database.users.find { usr ->
usr.id eq it.sender
}?.toUserDTO(database, friendStatus = FriendStatus.NOT_FRIEND)
}
}
}
override fun deleteFriend(senderId: String, receiverId: String): Boolean {
val result = database.friends.removeIf { (it.sender eq receiverId) and (it.receiver eq senderId) } +
database.friends.removeIf { (it.sender eq senderId) and (it.receiver eq receiverId) }
return result > 0
}
override fun isFriend(firstUser: String, secondUser: String) =
database.friends.any { (it.sender eq firstUser) and (it.receiver eq secondUser) }
override fun filterUsersByUsername(fromUserId: String, search: String): List<UserDTO> {
return database.users
.filter { (it.id notEq fromUserId) }
.mapColumns {
tupleOf(
it.id,
it.username,
it.username.toLowerCase().levenshteinLessEq(
search.lowercase(),
(it.username.length() / 2)
)
)
}
.filter { (_, username, distance) ->
val maxSize = ((username?.length ?: 0) / 2)
distance?.let { it <= maxSize } ?: false
}
.sortedBy { it.second }
.mapNotNull { (id, _, _) ->
id?.let {
val user = database.users.find { it.id eq id }
user?.toUserDTO(database, friendStatus = getFriendStatus(fromUserId, user.id))
}
}
}
}