Files
Messenger/server/internal/store/messages.go
T

85 lines
2.5 KiB
Go
Raw Normal View History

package store
import (
"context"
"errors"
"github.com/jackc/pgx/v5"
)
// InsertMessage creates a new message in a conversation and returns it.
// mediaID, when non-nil, attaches a previously uploaded media object.
func (s *Store) InsertMessage(ctx context.Context, conversationID, senderID int64, body string, mediaID *int64) (*Message, error) {
var m Message
err := s.pool.QueryRow(ctx, `
INSERT INTO messages(conversation_id, sender_id, body, media_id)
VALUES($1, $2, $3, $4)
RETURNING id, conversation_id, sender_id, body, media_id, created_at, edited_at, deleted_at
`, conversationID, senderID, body, mediaID).Scan(
&m.ID, &m.ConversationID, &m.SenderID, &m.Body, &m.MediaID,
&m.CreatedAt, &m.EditedAt, &m.DeletedAt,
)
if err != nil {
return nil, err
}
return &m, nil
}
// GetMessageByID retrieves a message by ID or returns ErrNotFound.
func (s *Store) GetMessageByID(ctx context.Context, id int64) (*Message, error) {
var m Message
err := s.pool.QueryRow(ctx, `
SELECT id, conversation_id, sender_id, body, media_id, created_at, edited_at, deleted_at
FROM messages WHERE id=$1
`, id).Scan(
&m.ID, &m.ConversationID, &m.SenderID, &m.Body, &m.MediaID,
&m.CreatedAt, &m.EditedAt, &m.DeletedAt,
)
if err != nil {
if errors.Is(err, pgx.ErrNoRows) {
return nil, ErrNotFound
}
return nil, err
}
return &m, nil
}
// ListMessages returns messages for a conversation in reverse chronological order.
// If before > 0, only messages with ID less than before are returned.
func (s *Store) ListMessages(ctx context.Context, conversationID int64, before int64, limit int) ([]Message, error) {
var rows pgx.Rows
var err error
if before > 0 {
rows, err = s.pool.Query(ctx, `
SELECT id, conversation_id, sender_id, body, media_id, created_at, edited_at, deleted_at
FROM messages
WHERE conversation_id=$1 AND id<$2
ORDER BY id DESC LIMIT $3
`, conversationID, before, limit)
} else {
rows, err = s.pool.Query(ctx, `
SELECT id, conversation_id, sender_id, body, media_id, created_at, edited_at, deleted_at
FROM messages
WHERE conversation_id=$1
ORDER BY id DESC LIMIT $2
`, conversationID, limit)
}
if err != nil {
return nil, err
}
defer rows.Close()
var msgs []Message
for rows.Next() {
var m Message
if err := rows.Scan(
&m.ID, &m.ConversationID, &m.SenderID, &m.Body, &m.MediaID,
&m.CreatedAt, &m.EditedAt, &m.DeletedAt,
); err != nil {
return nil, err
}
msgs = append(msgs, m)
}
return msgs, nil
}