package db import ( "context" "database/sql" "errors" "fmt" "log" "tangled.org/core/knotmirror/models" ) func UpsertHost(ctx context.Context, e *sql.DB, host *models.Host) error { if _, err := e.ExecContext(ctx, `insert into hosts (hostname, no_ssl, status, last_seq) values ($1, $2, $3, $4) on conflict(hostname) do update set no_ssl = excluded.no_ssl, status = excluded.status, last_seq = excluded.last_seq `, host.Hostname, host.NoSSL, host.Status, host.LastSeq, ); err != nil { return fmt.Errorf("upserting host: %w", err) } return nil } func GetHost(ctx context.Context, e *sql.DB, hostname string) (*models.Host, error) { var host models.Host if err := e.QueryRowContext(ctx, `select hostname, no_ssl, status, last_seq from hosts where hostname = $1`, hostname, ).Scan( &host.Hostname, &host.NoSSL, &host.Status, &host.LastSeq, ); err != nil { if errors.Is(err, sql.ErrNoRows) { return nil, nil } return nil, err } return &host, nil } func StoreCursors(ctx context.Context, e *sql.DB, cursors []models.HostCursor) error { tx, err := e.BeginTx(ctx, nil) if err != nil { return fmt.Errorf("starting transaction: %w", err) } defer tx.Rollback() for _, cur := range cursors { if cur.LastSeq <= 0 { continue } if _, err := tx.ExecContext(ctx, `update hosts set last_seq = $1 where hostname = $2`, cur.LastSeq, cur.Hostname, ); err != nil { log.Println("failed to persist host cursor", "host", cur.Hostname, "lastSeq", cur.LastSeq, "err", err) } } return tx.Commit() } func ListHosts(ctx context.Context, e *sql.DB, status models.HostStatus) ([]models.Host, error) { rows, err := e.QueryContext(ctx, `select hostname, no_ssl, status, last_seq from hosts where status = $1`, status, ) if err != nil { return nil, fmt.Errorf("querying hosts: %w", err) } defer rows.Close() var hosts []models.Host for rows.Next() { var host models.Host if err := rows.Scan( &host.Hostname, &host.NoSSL, &host.Status, &host.LastSeq, ); err != nil { return nil, fmt.Errorf("scanning row: %w", err) } hosts = append(hosts, host) } if err := rows.Err(); err != nil { return nil, fmt.Errorf("scanning rows: %w ", err) } return hosts, nil }