Passed
Push — main ( 570b65...2ff189 )
by Acho
02:48
created

rUser   A

Complexity

Conditions 2

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
dl 0
loc 10
rs 10
c 0
b 0
f 0
nop 2
1
package repositories
2
3
import (
4
	"context"
5
	"errors"
6
	"fmt"
7
8
	"github.com/NdoleStudio/httpsms/pkg/entities"
9
	"github.com/NdoleStudio/httpsms/pkg/telemetry"
10
	"github.com/google/uuid"
11
	"github.com/palantir/stacktrace"
12
	"gorm.io/gorm"
13
)
14
15
// gormWebhookRepository is responsible for persisting entities.Webhook
16
type gormWebhookRepository struct {
17
	logger telemetry.Logger
18
	tracer telemetry.Tracer
19
	db     *gorm.DB
20
}
21
22
// NewGormWebhookRepository creates the GORM version of the WebhookRepository
23
func NewGormWebhookRepository(
24
	logger telemetry.Logger,
25
	tracer telemetry.Tracer,
26
	db *gorm.DB,
27
) WebhookRepository {
28
	return &gormWebhookRepository{
29
		logger: logger.WithService(fmt.Sprintf("%T", &gormWebhookRepository{})),
30
		tracer: tracer,
31
		db:     db,
32
	}
33
}
34
35
func (repository *gormWebhookRepository) DeleteAllForUser(ctx context.Context, userID entities.UserID) error {
36
	ctx, span := repository.tracer.Start(ctx)
37
	defer span.End()
38
39
	if err := repository.db.WithContext(ctx).Where("user_id = ?", userID).Delete(&entities.Webhook{}).Error; err != nil {
40
		msg := fmt.Sprintf("cannot delete all [%T] for user with ID [%s]", &entities.Webhook{}, userID)
41
		return repository.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg))
42
	}
43
44
	return nil
45
}
46
47
func (repository *gormWebhookRepository) Save(ctx context.Context, webhook *entities.Webhook) error {
48
	ctx, span := repository.tracer.Start(ctx)
49
	defer span.End()
50
51
	if err := repository.db.WithContext(ctx).Save(webhook).Error; err != nil {
52
		msg := fmt.Sprintf("cannot update webhook with ID [%s]", webhook.ID)
53
		return repository.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg))
54
	}
55
56
	return nil
57
}
58
59
// Index entities.Message between 2 parties
60
func (repository *gormWebhookRepository) Index(ctx context.Context, userID entities.UserID, params IndexParams) ([]*entities.Webhook, error) {
61
	ctx, span := repository.tracer.Start(ctx)
62
	defer span.End()
63
64
	query := repository.db.WithContext(ctx).Where("user_id = ?", userID)
65
	if len(params.Query) > 0 {
66
		queryPattern := "%" + params.Query + "%"
67
		query.Where(repository.db.Where("url ILIKE ?", queryPattern))
68
	}
69
70
	webhooks := make([]*entities.Webhook, 0)
71
	if err := query.Order("created_at DESC").Limit(params.Limit).Offset(params.Skip).Find(&webhooks).Error; err != nil {
72
		msg := fmt.Sprintf("cannot fetch webhooks for user [%s] and params [%+#v]", userID, params)
73
		return nil, repository.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg))
74
	}
75
76
	return webhooks, nil
77
}
78
79
func (repository *gormWebhookRepository) LoadByEvent(ctx context.Context, userID entities.UserID, event string, phoneNumber string) ([]*entities.Webhook, error) {
80
	ctx, span := repository.tracer.Start(ctx)
81
	defer span.End()
82
83
	webhooks := make([]*entities.Webhook, 0)
84
	err := repository.db.
85
		Raw("SELECT * FROM webhooks WHERE user_id = ? AND CAST(? as TEXT) = ANY(events) AND CAST(? as TEXT) = ANY(phone_numbers)", userID, event, phoneNumber).
86
		Scan(&webhooks).
87
		Error
88
	if err != nil {
89
		msg := fmt.Sprintf("cannot load webhooks for user with ID [%s] and event [%s]", userID, event)
90
		return nil, repository.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg))
91
	}
92
93
	return webhooks, nil
94
}
95
96
func (repository *gormWebhookRepository) Load(ctx context.Context, userID entities.UserID, webhookID uuid.UUID) (*entities.Webhook, error) {
97
	ctx, span := repository.tracer.Start(ctx)
98
	defer span.End()
99
100
	webhook := new(entities.Webhook)
101
	err := repository.db.WithContext(ctx).Where("user_id = ?", userID).Where("id = ?", webhookID).First(&webhook).Error
102
	if errors.Is(err, gorm.ErrRecordNotFound) {
103
		msg := fmt.Sprintf("webhook with ID [%s] for user [%s] does not exist", webhookID, userID)
104
		return nil, repository.tracer.WrapErrorSpan(span, stacktrace.PropagateWithCode(err, ErrCodeNotFound, msg))
105
	}
106
107
	if err != nil {
108
		msg := fmt.Sprintf("cannot load webhook with ID [%s] for user [%s]", webhookID, userID)
109
		return nil, repository.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg))
110
	}
111
112
	return webhook, nil
113
}
114
115
func (repository *gormWebhookRepository) Delete(ctx context.Context, userID entities.UserID, webhookID uuid.UUID) error {
116
	ctx, span := repository.tracer.Start(ctx)
117
	defer span.End()
118
119
	err := repository.db.WithContext(ctx).
120
		Where("user_id = ?", userID).
121
		Where("id = ?", webhookID).
122
		Delete(&entities.Webhook{}).Error
123
	if err != nil {
124
		msg := fmt.Sprintf("cannot delete webhook with ID [%s] and userID [%s]", webhookID, userID)
125
		return repository.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg))
126
	}
127
128
	return nil
129
}
130