refactor: update message handling to support pagination with limit and timestamp
This commit is contained in:
parent
06a2c55da5
commit
f93a0ebcd4
@ -10,14 +10,14 @@
|
||||
- [ ] status
|
||||
- [ ] bio
|
||||
- [ ] profile picture
|
||||
- [ ] provide user info
|
||||
- [x] provide user info
|
||||
- manage rights and roles
|
||||
- [ ] edit roles
|
||||
- [ ] bind roles to users
|
||||
- manage messages
|
||||
- [ ] send
|
||||
- [ ] alert
|
||||
- [ ] query
|
||||
- [x] send
|
||||
- [x] alert
|
||||
- [x] query
|
||||
- files
|
||||
- [ ] upload
|
||||
- [ ] serve
|
||||
|
37
api/chat.go
37
api/chat.go
@ -4,13 +4,17 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"git.tek.govt.hu/dowerx/chat/server/model"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
const CHANNEL_ID string = "id"
|
||||
const (
|
||||
CHANNEL_ID string = "id"
|
||||
DEFAULT_MESSAGE_LIMIT int = 100
|
||||
)
|
||||
|
||||
var upgrader = websocket.Upgrader{
|
||||
ReadBufferSize: 1024,
|
||||
@ -42,7 +46,36 @@ func getMessages(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
messages, msgErr := chatController.GetMessages(id)
|
||||
limitStr := c.Query("limit")
|
||||
fromStr := c.Query("from")
|
||||
|
||||
var limit int = DEFAULT_MESSAGE_LIMIT
|
||||
var from time.Time = time.Now().UTC()
|
||||
var parseErr error
|
||||
|
||||
if limitStr != "" {
|
||||
limit, parseErr = strconv.Atoi(limitStr)
|
||||
if parseErr != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": "invalid limit parameter",
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if fromStr != "" {
|
||||
from, parseErr = time.Parse(time.RFC3339, fromStr)
|
||||
if parseErr != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": "invalid from parameter",
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println(from, limit)
|
||||
|
||||
messages, msgErr := chatController.GetMessages(id, from, limit)
|
||||
if msgErr != nil {
|
||||
sendError(c, msgErr)
|
||||
return
|
||||
|
@ -26,8 +26,8 @@ func (c ChatController) ListAvailableChannels(token string) ([]model.Channel, *u
|
||||
return c.channelDAO.ListAvailableChannels(userID)
|
||||
}
|
||||
|
||||
func (c ChatController) GetMessages(channel int) ([]model.Message, *util.ChatError) {
|
||||
return c.messageDAO.List(model.Channel{ID: channel})
|
||||
func (c ChatController) GetMessages(channel int, from time.Time, limit int) ([]model.Message, *util.ChatError) {
|
||||
return c.messageDAO.List(model.Channel{ID: channel}, from, limit)
|
||||
}
|
||||
|
||||
func (c ChatController) SendMessage(token string, channel int, content string) *util.ChatError {
|
||||
|
@ -1,6 +1,8 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"git.tek.govt.hu/dowerx/chat/server/model"
|
||||
"git.tek.govt.hu/dowerx/chat/server/util"
|
||||
)
|
||||
@ -8,7 +10,7 @@ import (
|
||||
type IMessageDAO interface {
|
||||
Create(message model.Message) (int, *util.ChatError)
|
||||
Read(id int) (model.Message, *util.ChatError)
|
||||
List(channel model.Channel) ([]model.Message, *util.ChatError)
|
||||
List(channel model.Channel, from time.Time, limit int) ([]model.Message, *util.ChatError)
|
||||
Update(message model.Message) *util.ChatError
|
||||
Delete(id int) *util.ChatError
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
"git.tek.govt.hu/dowerx/chat/server/model"
|
||||
"git.tek.govt.hu/dowerx/chat/server/util"
|
||||
"github.com/jmoiron/sqlx"
|
||||
@ -50,9 +53,18 @@ func (d MessageDAO) Read(id int) (model.Message, *util.ChatError) {
|
||||
}
|
||||
|
||||
// List all messages in channel by ID or name
|
||||
func (d MessageDAO) List(channel model.Channel) ([]model.Message, *util.ChatError) {
|
||||
func (d MessageDAO) List(channel model.Channel, from time.Time, limit int) ([]model.Message, *util.ChatError) {
|
||||
|
||||
type queryInfo struct {
|
||||
ID int `db:"id"`
|
||||
Name string `db:"name"`
|
||||
From time.Time `db:"from"`
|
||||
Limit int `db:"limit"`
|
||||
}
|
||||
|
||||
var rows *sqlx.Rows
|
||||
var err error
|
||||
|
||||
if channel.ID != 0 {
|
||||
rows, err = d.db.NamedQuery(
|
||||
`select
|
||||
@ -63,8 +75,10 @@ func (d MessageDAO) List(channel model.Channel) ([]model.Message, *util.ChatErro
|
||||
"m"."content" as "content"
|
||||
from "message" as "m"
|
||||
inner join "user" "u" on "u"."id" = "m"."sender_id"
|
||||
where "m"."channel_id" = :id order by "time"`,
|
||||
&channel)
|
||||
where "m"."channel_id" = :id and "m"."time" < :from
|
||||
order by "time" desc
|
||||
limit :limit`,
|
||||
&queryInfo{ID: channel.ID, From: from, Limit: limit})
|
||||
} else {
|
||||
rows, err = d.db.NamedQuery(
|
||||
`select
|
||||
@ -76,8 +90,10 @@ func (d MessageDAO) List(channel model.Channel) ([]model.Message, *util.ChatErro
|
||||
from "message" as "m"
|
||||
inner join "user" "u" on "u"."id" = "m"."sender_id"
|
||||
inner join "channel" "c" on "c"."id" = "m"."channel_id"
|
||||
where "c"."name" = :name order by "time"`,
|
||||
&channel)
|
||||
where "c"."name" = :name and "m"."time" < :from
|
||||
order by "time" desc
|
||||
limit :limit`,
|
||||
&queryInfo{Name: channel.Name, From: from, Limit: limit})
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@ -98,6 +114,7 @@ func (d MessageDAO) List(channel model.Channel) ([]model.Message, *util.ChatErro
|
||||
messages = append(messages, message)
|
||||
}
|
||||
|
||||
slices.Reverse(messages)
|
||||
return messages, util.MakeError(err, util.DATABASE_QUERY_FAULT)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user