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