Files

96 lines
3.0 KiB
Go

package repository
import (
"context"
"errors"
"fmt"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgxpool"
"github.com/panelhosting/panel/internal/models"
)
var ErrServerNotFound = errors.New("server not found")
type ServerRepository struct {
pool *pgxpool.Pool
}
func NewServerRepository(pool *pgxpool.Pool) *ServerRepository {
return &ServerRepository{pool: pool}
}
func (r *ServerRepository) Count(ctx context.Context) (int64, error) {
var count int64
err := r.pool.QueryRow(ctx, `SELECT COUNT(*) FROM servers`).Scan(&count)
return count, err
}
func (r *ServerRepository) CreateDefault(ctx context.Context, name, hostname, ip string) (*models.Server, error) {
const q = `
INSERT INTO servers (name, hostname, ip_address, status)
VALUES ($1, $2, $3::inet, 'online')
RETURNING id, uuid, name, hostname, ip_address::text, ssh_port, status,
agent_version, os_info, resources, settings, last_seen_at, created_at, updated_at
`
var s models.Server
err := r.pool.QueryRow(ctx, q, name, hostname, ip).Scan(
&s.ID, &s.UUID, &s.Name, &s.Hostname, &s.IPAddress, &s.SSHPort, &s.Status,
&s.AgentVersion, &s.OSInfo, &s.Resources, &s.Settings, &s.LastSeenAt, &s.CreatedAt, &s.UpdatedAt,
)
if err != nil {
return nil, fmt.Errorf("create server: %w", err)
}
return &s, nil
}
func (r *ServerRepository) GetFirst(ctx context.Context) (*models.Server, error) {
const q = `
SELECT id, uuid, name, hostname, ip_address::text, ssh_port, status,
agent_version, os_info, resources, settings, last_seen_at, created_at, updated_at
FROM servers ORDER BY id LIMIT 1
`
var s models.Server
err := r.pool.QueryRow(ctx, q).Scan(
&s.ID, &s.UUID, &s.Name, &s.Hostname, &s.IPAddress, &s.SSHPort, &s.Status,
&s.AgentVersion, &s.OSInfo, &s.Resources, &s.Settings, &s.LastSeenAt, &s.CreatedAt, &s.UpdatedAt,
)
if errors.Is(err, pgx.ErrNoRows) {
return nil, ErrServerNotFound
}
if err != nil {
return nil, fmt.Errorf("get first server: %w", err)
}
return &s, nil
}
func (r *ServerRepository) GetByID(ctx context.Context, id int64) (*models.Server, error) {
const q = `
SELECT id, uuid, name, hostname, ip_address::text, ssh_port, status,
agent_version, os_info, resources, settings, last_seen_at, created_at, updated_at
FROM servers WHERE id = $1
`
var s models.Server
err := r.pool.QueryRow(ctx, q, id).Scan(
&s.ID, &s.UUID, &s.Name, &s.Hostname, &s.IPAddress, &s.SSHPort, &s.Status,
&s.AgentVersion, &s.OSInfo, &s.Resources, &s.Settings, &s.LastSeenAt, &s.CreatedAt, &s.UpdatedAt,
)
if errors.Is(err, pgx.ErrNoRows) {
return nil, ErrServerNotFound
}
if err != nil {
return nil, fmt.Errorf("get server: %w", err)
}
return &s, nil
}
func (r *ServerRepository) GrantAccess(ctx context.Context, userID, serverID int64, canManage bool) error {
const q = `
INSERT INTO server_access (user_id, server_id, can_manage)
VALUES ($1, $2, $3)
ON CONFLICT (user_id, server_id) DO NOTHING
`
_, err := r.pool.Exec(ctx, q, userID, serverID, canManage)
return err
}