-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feat]: 채팅방 메세지를 조회할 수 있다 #14
base: develop
Are you sure you want to change the base?
Changes from 4 commits
2412286
12f82b3
90670a0
1105137
4796e7b
5dc78b2
d8e2e2f
5fdd6ee
9979e44
6231163
8ed4d1b
76e58a3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package gloddy.groupChat.dto.command | ||
|
||
import gloddy.util.CursorRequest | ||
import java.util.* | ||
|
||
data class GroupChatGetMessageCommand( | ||
val userId: Long, | ||
val chatId: UUID, | ||
val cursorRequest: CursorRequest | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package gloddy.groupChat.service | ||
|
||
import gloddy.groupChat.GroupChatMessage | ||
import gloddy.groupChat.dto.command.GroupChatGetMessageCommand | ||
import gloddy.port.`in`.GetGroupChatMessageUseCase | ||
import gloddy.port.out.GetGroupChatMessagePort | ||
import gloddy.util.CursorRequest | ||
import gloddy.util.PageCursor | ||
|
||
class GroupChatGetMessageCommander(private val getGroupChatMessagePort: GetGroupChatMessagePort) : GetGroupChatMessageUseCase { | ||
|
||
override fun getPosts(command: GroupChatGetMessageCommand): PageCursor<GroupChatMessage> { | ||
var posts = findAllBy(command) | ||
var nextKey = posts.stream() | ||
.mapToLong(GroupChatMessage::sequenceId) | ||
.min() | ||
.orElse(CursorRequest.NONE_KEY) | ||
return PageCursor(command.cursorRequest.next(nextKey), posts.size, posts) | ||
} | ||
|
||
private fun findAllBy(command: GroupChatGetMessageCommand): List<GroupChatMessage> { | ||
return if (command.cursorRequest.hasKey()) { | ||
getGroupChatMessagePort.findWithKey(command) | ||
} else { | ||
getGroupChatMessagePort.findWithoutKey(command) | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package gloddy.port.`in` | ||
|
||
import gloddy.groupChat.GroupChatMessage | ||
import gloddy.groupChat.dto.command.GroupChatGetMessageCommand | ||
import gloddy.util.PageCursor | ||
|
||
interface GetGroupChatMessageUseCase { | ||
|
||
fun getPosts(groupChatGetMessageCommand: GroupChatGetMessageCommand): PageCursor<GroupChatMessage> | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 도메인 서비스에 대한 추상화는 필요 없을 거라는 판단하에 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package gloddy.port.out | ||
|
||
import gloddy.groupChat.GroupChatMessage | ||
import gloddy.groupChat.dto.command.GroupChatGetMessageCommand | ||
|
||
interface GetGroupChatMessagePort { | ||
fun findWithoutKey(groupChatGetMessageCommand: GroupChatGetMessageCommand): List<GroupChatMessage> | ||
|
||
fun findWithKey(groupChatGetMessageCommand: GroupChatGetMessageCommand): List<GroupChatMessage> | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Domain 모듈의 영속성 추상클래스 <-(implement) Storage 모듈의 영속성 클래스의 이름 규칙을 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 확인했습니다 앞으로 반영하겠습니다🫡 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package gloddy.util | ||
|
||
|
||
data class CursorRequest( | ||
val key: Long? | ||
) { | ||
companion object { | ||
const val NONE_KEY: Long = -1L | ||
} | ||
|
||
fun hasKey(): Boolean { | ||
return key != null | ||
} | ||
|
||
fun next(key: Long?): CursorRequest { | ||
return CursorRequest(key) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package gloddy.util | ||
|
||
data class PageCursor<T>( | ||
val nextCursorRequest: CursorRequest, | ||
val size: Int, | ||
val body: List<T> | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package gloddy.adapter | ||
|
||
import gloddy.groupChat.GroupChatMessage | ||
import gloddy.groupChat.dto.command.GroupChatGetMessageCommand | ||
import gloddy.persistence.repository.GroupChatMessageRepository | ||
import gloddy.port.out.GetGroupChatMessagePort | ||
|
||
class GroupChatMessageCommandAdapter( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 조회용 Adapter Repository니깐 그리고 GroupChat 하위 도메인들(GroupChatMessage, GroupChatUser) 또한 그에 맞는 새로운 레포지토리를 파는게 아닌 GroupChatRepository 내부에서 처리하는게 관리가 용이할 것 같애서 위처럼 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
private val repository: GroupChatMessageRepository) | ||
: GetGroupChatMessagePort { | ||
|
||
override fun findWithoutKey(command: GroupChatGetMessageCommand): List<GroupChatMessage> { | ||
return repository.findAllByMemberIdAndOrderByIdDesc( | ||
command.userId, | ||
command.chatId | ||
) | ||
} | ||
|
||
override fun findWithKey(command: GroupChatGetMessageCommand): List<GroupChatMessage> { | ||
return repository.findAllByLessThanIdMemberIdAndOrderByIdDesc( | ||
command.cursorRequest.key, | ||
command.userId, | ||
command.chatId | ||
) | ||
} | ||
|
||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package gloddy.persistence.repository | ||
|
||
import gloddy.groupChat.GroupChatMessage | ||
import gloddy.groupChat.vo.MessageType | ||
import org.springframework.jdbc.core.RowMapper | ||
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource | ||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate | ||
import java.time.LocalDateTime | ||
import java.util.* | ||
|
||
class GroupChatMessageRepository(private val namedParameterJdbcTemplate: NamedParameterJdbcTemplate) { | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 일단 쿼리를 직접짜야겠다는 생각을 하였고 보다 익숙한 |
||
companion object { | ||
private const val TABLE = "GroupChatMessage" | ||
private val ROW_MAPPER: RowMapper<GroupChatMessage> = RowMapper { rs, rowNum -> | ||
GroupChatMessage( | ||
userId = rs.getLong("userId"), | ||
chatId = rs.getObject("chatId", UUID::class.java), | ||
messageType = MessageType.valueOf(rs.getString("messageType")), | ||
content = rs.getString("content"), | ||
createdAt = rs.getObject("createdAt", LocalDateTime::class.java) ?: LocalDateTime.now(), | ||
deleted = rs.getBoolean("deleted"), | ||
deletedAt = rs.getObject("deletedAt", LocalDateTime::class.java), | ||
id = rs.getObject("id", UUID::class.java), | ||
sequenceId = rs.getLong("sequenceId")) | ||
} | ||
} | ||
|
||
fun findAllByMemberIdAndOrderByIdDesc(userId: Long, chatId: UUID): List<GroupChatMessage> { | ||
val sql = """ | ||
SELECT * | ||
FROM $TABLE as message | ||
INNER JOIN GroupChatUser AS user | ||
ON user.chatId = message.chatId | ||
WHERE chatId = :chatId and user.createdAt < message.createdAt | ||
ORDER BY sequenceId desc | ||
""".trimIndent() | ||
val params = MapSqlParameterSource() | ||
.addValue("chatId", chatId) | ||
|
||
return namedParameterJdbcTemplate.query(sql, params, ROW_MAPPER) | ||
} | ||
|
||
fun findAllByLessThanIdMemberIdAndOrderByIdDesc(sequenceId: Long?, userId: Long, chatId: UUID): List<GroupChatMessage> { | ||
val sql = """ | ||
SELECT * | ||
FROM $TABLE | ||
WHERE chatId = :chatId and sequenceId < :sequenceId | ||
ORDER BY sequenceId desc | ||
""".trimIndent() | ||
val params = MapSqlParameterSource() | ||
.addValue("sequenceId", sequenceId) | ||
.addValue("chatId", chatId) | ||
|
||
return namedParameterJdbcTemplate.query(sql, params, ROW_MAPPER) | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
조회에 대한 도메인 서비스 이름을
~Commander
라고 지은 이유가 뭔가요??Commander
는 CUD에 대한 도메인 서비스를 가리키는 의도로 지었는데 여기서는GroupChatReader
라는 클래스 명이 맞지 않을까요?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CUD에 대한 서비스가 아닌 단순히 '요청(명령)을 한다'라는 의미로 이해하여 네이밍을 하게되었습니다. 말씀해주신대로
GroupChatReader
로 변경하고 앞으로 맞춰서 작성하겠습니다!There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
그럼 혹시
dto
패키지 하위의command
들도 CUD를 위한dto
인가요??