201 lines
3.8 KiB
Go
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
|
|
}
|