190 lines
5.6 KiB
Go
190 lines
5.6 KiB
Go
package repository
|
|
|
|
import (
|
|
"errors"
|
|
"github.com/jmoiron/sqlx"
|
|
"go.mongodb.org/mongo-driver/v2/bson"
|
|
"go.mongodb.org/mongo-driver/v2/mongo"
|
|
"go.mongodb.org/mongo-driver/v2/mongo/options"
|
|
"time"
|
|
|
|
"git.urec56.ru/urec/chat_back_go/internal/database"
|
|
"git.urec56.ru/urec/chat_back_go/internal/domain"
|
|
"git.urec56.ru/urec/chat_back_go/internal/logger"
|
|
)
|
|
|
|
type messageRepository struct {
|
|
db *sqlx.DB
|
|
mc *mongo.Collection
|
|
l *logger.Logger
|
|
}
|
|
|
|
type SendMessage struct {
|
|
ID domain.UUID `bson:"id"`
|
|
Message string `bson:"message,omitempty"`
|
|
ImageUrl string `bson:"image_url,omitempty"`
|
|
ChatID int `bson:"chat_id"`
|
|
UserID int `bson:"user_id"`
|
|
CreatedAt time.Time `bson:"created_at"`
|
|
AnswerID domain.UUID `bson:"answer_id,omitempty"`
|
|
AnswerMessage string `bson:"answer_message,omitempty"`
|
|
AnswerImageUrl string `bson:"answer_image_url,omitempty"`
|
|
Visibility bool `bson:"visibility"`
|
|
}
|
|
|
|
type EditMessage struct {
|
|
ID domain.UUID
|
|
Message, ImageUrl string
|
|
}
|
|
|
|
type PinMessage struct {
|
|
ChatID, UserID int
|
|
MessageID domain.UUID
|
|
}
|
|
|
|
type UnpinMessage struct {
|
|
ChatID int
|
|
MessageID domain.UUID
|
|
}
|
|
|
|
type GetSome struct {
|
|
ChatID, Offset, Limit int
|
|
}
|
|
|
|
func newMessageRepo(db *sqlx.DB, mdb *mongo.Database, l *logger.Logger) *messageRepository {
|
|
return &messageRepository{db: db, mc: mdb.Collection("message"), l: l}
|
|
}
|
|
|
|
func (r *messageRepository) Get(ID domain.UUID) (domain.RawMessage, error) {
|
|
var msg domain.RawMessage
|
|
res := r.mc.FindOne(nil, bson.M{"id": ID})
|
|
|
|
if err := res.Decode(&msg); err != nil {
|
|
r.l.Errorf("getting message: %s", err)
|
|
return domain.RawMessage{}, domain.InternalServerError
|
|
}
|
|
|
|
return msg, nil
|
|
}
|
|
|
|
func (r *messageRepository) GetByIDs(IDs []domain.UUID) ([]domain.RawMessage, error) {
|
|
var messages []domain.RawMessage
|
|
res, err := r.mc.Find(nil, bson.M{"visibility": true, "id": bson.M{"$in": IDs}})
|
|
if err != nil {
|
|
r.l.Errorf("getting messages by ids: %s", err)
|
|
return nil, domain.InternalServerError
|
|
}
|
|
|
|
if err = res.All(nil, &messages); err != nil {
|
|
r.l.Errorf("decoding messages by ids: %s", err)
|
|
return nil, domain.InternalServerError
|
|
}
|
|
|
|
return messages, nil
|
|
}
|
|
|
|
func (r *messageRepository) GetSome(messagesInfo GetSome) ([]domain.RawMessage, error) {
|
|
var messages []domain.RawMessage
|
|
findOptions := options.Find().SetSort(bson.M{"created_at": -1}).SetLimit(int64(messagesInfo.Limit)).SetSkip(int64(messagesInfo.Offset))
|
|
res, err := r.mc.Find(nil, bson.M{"visibility": true, "chat_id": messagesInfo.ChatID}, findOptions)
|
|
if err != nil {
|
|
r.l.Errorf("getting some messages: %s", err)
|
|
return nil, domain.InternalServerError
|
|
}
|
|
|
|
if err = res.All(nil, &messages); err != nil {
|
|
r.l.Errorf("decoding some messages: %s", err)
|
|
return nil, domain.InternalServerError
|
|
}
|
|
|
|
return messages, nil
|
|
}
|
|
|
|
func (r *messageRepository) Send(message SendMessage) (domain.RawMessage, error) {
|
|
message.ID = domain.GenerateUUID()
|
|
message.CreatedAt = time.Now()
|
|
message.Visibility = true
|
|
|
|
_, err := r.mc.InsertOne(nil, message)
|
|
if err != nil {
|
|
r.l.Errorf("inserting message: %s", err)
|
|
return domain.RawMessage{}, domain.InternalServerError
|
|
}
|
|
|
|
return domain.RawMessage{
|
|
ID: message.ID,
|
|
Message: message.Message,
|
|
ImageUrl: message.ImageUrl,
|
|
ChatID: message.ChatID,
|
|
UserID: message.UserID,
|
|
CreatedAt: message.CreatedAt,
|
|
AnswerID: message.AnswerID,
|
|
AnswerMessage: message.AnswerMessage,
|
|
AnswerImageUrl: message.AnswerImageUrl,
|
|
}, nil
|
|
}
|
|
|
|
func (r *messageRepository) Delete(ID domain.UUID) error {
|
|
if _, err := r.mc.UpdateOne(nil, bson.M{"id": ID}, bson.M{"$set": bson.M{"visibility": false}}); err != nil {
|
|
r.l.Errorf("deleting message: %s", err)
|
|
return domain.InternalServerError
|
|
}
|
|
|
|
_, err := r.mc.UpdateMany(nil, bson.M{"answer_id": ID}, bson.M{"$set": bson.M{"answer_message": nil, "answer_image_url": nil}})
|
|
if err != nil {
|
|
r.l.Errorf("deleting message: %s", err)
|
|
return domain.InternalServerError
|
|
}
|
|
|
|
return nil
|
|
}
|
|
func (r *messageRepository) Edit(newMessage EditMessage) error {
|
|
_, err := r.mc.UpdateOne(nil, bson.M{"id": newMessage.ID}, bson.M{"$set": bson.M{"message": newMessage.Message, "image_url": newMessage.ImageUrl}})
|
|
if err != nil {
|
|
r.l.Errorf("edditing message: %s", err)
|
|
return domain.InternalServerError
|
|
}
|
|
|
|
_, err = r.mc.UpdateMany(nil, bson.M{"answer_id": newMessage.ID}, bson.M{"$set": bson.M{"answer_message": newMessage.Message, "answer_image_url": newMessage.ImageUrl}})
|
|
if err != nil {
|
|
r.l.Errorf("edditing message: %s", err)
|
|
return domain.InternalServerError
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (r *messageRepository) Pin(msg PinMessage) error {
|
|
query := `INSERT INTO pinned_message (chat_id, message_id, user_id) VALUES ($1, $2, $3)`
|
|
if _, err := r.db.Exec(query, msg.ChatID, msg.MessageID, msg.UserID); err != nil {
|
|
if errors.Is(err, database.IntegrityError) {
|
|
return domain.MessageAlreadyPinnedError
|
|
}
|
|
|
|
r.l.Errorf("pining message: %s", err)
|
|
return domain.InternalServerError
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (r *messageRepository) Unpin(msg UnpinMessage) error {
|
|
query := `DELETE FROM pinned_message WHERE chat_id = $1 AND message_id = $2`
|
|
if _, err := r.db.Exec(query, msg.ChatID, msg.MessageID); err != nil {
|
|
r.l.Errorf("unpining message: %s", err)
|
|
return domain.InternalServerError
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (r *messageRepository) GetPinnedIDs(chatID int) ([]domain.UUID, error) {
|
|
var IDs []domain.UUID
|
|
query := `SELECT message_id FROM pinned_message WHERE chat_id = $1`
|
|
if err := r.db.Select(&IDs, query, chatID); err != nil {
|
|
r.l.Errorf("getting pinned ids: %s", err)
|
|
return []domain.UUID{}, domain.InternalServerError
|
|
}
|
|
|
|
return IDs, nil
|
|
}
|