tailly_back_v2/internal/repository/device_repository.go
madipo2611 6f5298d420 v0.0.3
2025-05-03 02:37:08 +03:00

201 lines
3.8 KiB
Go

package repository
import (
"context"
"database/sql"
"errors"
"tailly_back_v2/internal/domain"
)
var (
ErrDeviceNotFound = errors.New("device not found")
ErrInvalidToken = errors.New("invalid confirmation token")
)
type DeviceRepository interface {
Save(ctx context.Context, device *domain.Device) error
GetByID(ctx context.Context, id int) (*domain.Device, error)
GetByToken(ctx context.Context, token string) (*domain.Device, error)
GetByUser(ctx context.Context, userID int) ([]*domain.Device, error)
Update(ctx context.Context, device *domain.Device) error
Delete(ctx context.Context, id int) error
}
type deviceRepository struct {
db *sql.DB
}
func NewDeviceRepository(db *sql.DB) DeviceRepository {
return &deviceRepository{db: db}
}
func (r *deviceRepository) Save(ctx context.Context, device *domain.Device) error {
query := `
INSERT INTO devices (
user_id,
name,
ip_address,
user_agent,
confirmation_token,
expires_at,
created_at
)
VALUES ($1, $2, $3, $4, $5, $6, $7)
RETURNING id
`
err := r.db.QueryRowContext(ctx, query,
device.UserID,
device.Name,
device.IPAddress,
device.UserAgent,
device.ConfirmationToken,
device.ExpiresAt,
device.CreatedAt,
).Scan(&device.ID)
return err
}
func (r *deviceRepository) GetByID(ctx context.Context, id int) (*domain.Device, error) {
query := `
SELECT
id,
user_id,
name,
ip_address,
user_agent,
confirmation_token,
expires_at,
created_at
FROM devices
WHERE id = $1
`
device := &domain.Device{}
err := r.db.QueryRowContext(ctx, query, id).Scan(
&device.ID,
&device.UserID,
&device.Name,
&device.IPAddress,
&device.UserAgent,
&device.ConfirmationToken,
&device.ExpiresAt,
&device.CreatedAt,
)
if err == sql.ErrNoRows {
return nil, ErrDeviceNotFound
}
return device, err
}
func (r *deviceRepository) GetByToken(ctx context.Context, token string) (*domain.Device, error) {
query := `
SELECT
id,
user_id,
name,
ip_address,
user_agent,
confirmation_token,
expires_at,
created_at
FROM devices
WHERE confirmation_token = $1
`
device := &domain.Device{}
err := r.db.QueryRowContext(ctx, query, token).Scan(
&device.ID,
&device.UserID,
&device.Name,
&device.IPAddress,
&device.UserAgent,
&device.ConfirmationToken,
&device.ExpiresAt,
&device.CreatedAt,
)
if err == sql.ErrNoRows {
return nil, ErrInvalidToken
}
return device, err
}
func (r *deviceRepository) GetByUser(ctx context.Context, userID int) ([]*domain.Device, error) {
query := `
SELECT
id,
user_id,
name,
ip_address,
user_agent,
confirmation_token,
expires_at,
created_at
FROM devices
WHERE user_id = $1
ORDER BY created_at DESC
`
rows, err := r.db.QueryContext(ctx, query, userID)
if err != nil {
return nil, err
}
defer rows.Close()
var devices []*domain.Device
for rows.Next() {
var device domain.Device
err := rows.Scan(
&device.ID,
&device.UserID,
&device.Name,
&device.IPAddress,
&device.UserAgent,
&device.ConfirmationToken,
&device.ExpiresAt,
&device.CreatedAt,
)
if err != nil {
return nil, err
}
devices = append(devices, &device)
}
return devices, nil
}
func (r *deviceRepository) Update(ctx context.Context, device *domain.Device) error {
query := `
UPDATE devices
SET
name = $1,
ip_address = $2,
user_agent = $3,
confirmation_token = $4,
expires_at = $5
WHERE id = $6
`
_, err := r.db.ExecContext(ctx, query,
device.Name,
device.IPAddress,
device.UserAgent,
device.ConfirmationToken,
device.ExpiresAt,
device.ID,
)
return err
}
func (r *deviceRepository) Delete(ctx context.Context, id int) error {
query := `DELETE FROM devices WHERE id = $1`
_, err := r.db.ExecContext(ctx, query, id)
return err
}