132 lines
4.7 KiB
Go
132 lines
4.7 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/gochat/gochat/internal/model"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// ConversationLabelRepo provides data access for the ConversationLabel join table.
|
|
type ConversationLabelRepo struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
func NewConversationLabelRepo(db *gorm.DB) *ConversationLabelRepo {
|
|
return &ConversationLabelRepo{db: db}
|
|
}
|
|
|
|
// AddLabel attaches a tag to a conversation.
|
|
func (r *ConversationLabelRepo) AddLabel(ctx context.Context, cl *model.ConversationLabel) error {
|
|
return r.db.WithContext(ctx).Create(cl).Error
|
|
}
|
|
|
|
// AddLabels attaches multiple tags to a conversation in a single transaction.
|
|
func (r *ConversationLabelRepo) AddLabels(ctx context.Context, labels []model.ConversationLabel) error {
|
|
return r.db.WithContext(ctx).CreateInBatches(labels, 100).Error
|
|
}
|
|
|
|
// RemoveLabel detaches a specific tag from a conversation.
|
|
func (r *ConversationLabelRepo) RemoveLabel(ctx context.Context, conversationID, tagID uint) error {
|
|
return r.db.WithContext(ctx).
|
|
Where("conversation_id = ? AND tag_id = ?", conversationID, tagID).
|
|
Delete(&model.ConversationLabel{}).Error
|
|
}
|
|
|
|
// RemoveAllLabels detaches all tags from a conversation.
|
|
func (r *ConversationLabelRepo) RemoveAllLabels(ctx context.Context, conversationID uint) error {
|
|
return r.db.WithContext(ctx).
|
|
Where("conversation_id = ?", conversationID).
|
|
Delete(&model.ConversationLabel{}).Error
|
|
}
|
|
|
|
// FindByConversationID returns all labels attached to a conversation, with tag details preloaded.
|
|
func (r *ConversationLabelRepo) FindByConversationID(ctx context.Context, conversationID uint) ([]model.ConversationLabel, error) {
|
|
var labels []model.ConversationLabel
|
|
if err := r.db.WithContext(ctx).
|
|
Preload("Tag").
|
|
Where("conversation_id = ?", conversationID).
|
|
Find(&labels).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return labels, nil
|
|
}
|
|
|
|
// FindByTagID returns all conversations that have a specific tag, with pagination.
|
|
func (r *ConversationLabelRepo) FindByTagID(ctx context.Context, accountID, tagID uint, offset, limit int) ([]model.ConversationLabel, int64, error) {
|
|
var labels []model.ConversationLabel
|
|
var count int64
|
|
db := r.db.WithContext(ctx).Model(&model.ConversationLabel{}).
|
|
Where("account_id = ? AND tag_id = ?", accountID, tagID)
|
|
db.Count(&count)
|
|
if err := db.Preload("Conversation").Preload("Tag").
|
|
Offset(offset).Limit(limit).
|
|
Find(&labels).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
return labels, count, nil
|
|
}
|
|
|
|
// FindByAccountID returns all unique tags used in an account (with usage counts).
|
|
func (r *ConversationLabelRepo) FindByAccountID(ctx context.Context, accountID uint) ([]model.ConversationLabel, error) {
|
|
var labels []model.ConversationLabel
|
|
if err := r.db.WithContext(ctx).
|
|
Preload("Tag").
|
|
Where("account_id = ?", accountID).
|
|
Find(&labels).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return labels, nil
|
|
}
|
|
|
|
// BatchAddLabels adds labels to multiple conversations at once.
|
|
func (r *ConversationLabelRepo) BatchAddLabels(ctx context.Context, conversationIDs []uint, tagID uint, accountID uint) error {
|
|
labels := make([]model.ConversationLabel, len(conversationIDs))
|
|
for i, convID := range conversationIDs {
|
|
labels[i] = model.ConversationLabel{
|
|
ConversationID: convID,
|
|
TagID: tagID,
|
|
AccountID: accountID,
|
|
}
|
|
}
|
|
return r.db.WithContext(ctx).CreateInBatches(labels, 100).Error
|
|
}
|
|
|
|
// BatchRemoveLabels removes a tag from multiple conversations at once.
|
|
func (r *ConversationLabelRepo) BatchRemoveLabels(ctx context.Context, conversationIDs []uint, tagID uint) error {
|
|
return r.db.WithContext(ctx).
|
|
Where("conversation_id IN ? AND tag_id = ?", conversationIDs, tagID).
|
|
Delete(&model.ConversationLabel{}).Error
|
|
}
|
|
|
|
// Exists checks if a specific label is already attached to a conversation.
|
|
func (r *ConversationLabelRepo) Exists(ctx context.Context, conversationID, tagID uint) (bool, error) {
|
|
var count int64
|
|
if err := r.db.WithContext(ctx).Model(&model.ConversationLabel{}).
|
|
Where("conversation_id = ? AND tag_id = ?", conversationID, tagID).
|
|
Count(&count).Error; err != nil {
|
|
return false, err
|
|
}
|
|
return count > 0, nil
|
|
}
|
|
|
|
// ReplaceLabels replaces all labels on a conversation with the given set of tag IDs.
|
|
func (r *ConversationLabelRepo) ReplaceLabels(ctx context.Context, conversationID, accountID uint, tagIDs []uint) error {
|
|
// Remove all existing labels
|
|
if err := r.RemoveAllLabels(ctx, conversationID); err != nil {
|
|
return err
|
|
}
|
|
// Add new labels
|
|
if len(tagIDs) == 0 {
|
|
return nil
|
|
}
|
|
labels := make([]model.ConversationLabel, len(tagIDs))
|
|
for i, tagID := range tagIDs {
|
|
labels[i] = model.ConversationLabel{
|
|
ConversationID: conversationID,
|
|
TagID: tagID,
|
|
AccountID: accountID,
|
|
}
|
|
}
|
|
return r.db.WithContext(ctx).CreateInBatches(labels, 100).Error
|
|
} |