A vibe coded tangled fork which supports pijul.
1package db
2
3import (
4 "context"
5 "database/sql"
6 "errors"
7 "fmt"
8 "log"
9
10 "tangled.org/core/knotmirror/models"
11)
12
13func UpsertHost(ctx context.Context, e *sql.DB, host *models.Host) error {
14 if _, err := e.ExecContext(ctx,
15 `insert into hosts (hostname, no_ssl, status, last_seq)
16 values ($1, $2, $3, $4)
17 on conflict(hostname) do update set
18 no_ssl = excluded.no_ssl,
19 status = excluded.status,
20 last_seq = excluded.last_seq
21 `,
22 host.Hostname,
23 host.NoSSL,
24 host.Status,
25 host.LastSeq,
26 ); err != nil {
27 return fmt.Errorf("upserting host: %w", err)
28 }
29 return nil
30}
31
32func GetHost(ctx context.Context, e *sql.DB, hostname string) (*models.Host, error) {
33 var host models.Host
34 if err := e.QueryRowContext(ctx,
35 `select hostname, no_ssl, status, last_seq
36 from hosts where hostname = $1`,
37 hostname,
38 ).Scan(
39 &host.Hostname,
40 &host.NoSSL,
41 &host.Status,
42 &host.LastSeq,
43 ); err != nil {
44 if errors.Is(err, sql.ErrNoRows) {
45 return nil, nil
46 }
47 return nil, err
48 }
49 return &host, nil
50}
51
52func StoreCursors(ctx context.Context, e *sql.DB, cursors []models.HostCursor) error {
53 tx, err := e.BeginTx(ctx, nil)
54 if err != nil {
55 return fmt.Errorf("starting transaction: %w", err)
56 }
57 defer tx.Rollback()
58 for _, cur := range cursors {
59 if cur.LastSeq <= 0 {
60 continue
61 }
62 if _, err := tx.ExecContext(ctx,
63 `update hosts set last_seq = $1 where hostname = $2`,
64 cur.LastSeq,
65 cur.Hostname,
66 ); err != nil {
67 log.Println("failed to persist host cursor", "host", cur.Hostname, "lastSeq", cur.LastSeq, "err", err)
68 }
69 }
70 return tx.Commit()
71}
72
73func ListHosts(ctx context.Context, e *sql.DB, status models.HostStatus) ([]models.Host, error) {
74 rows, err := e.QueryContext(ctx,
75 `select hostname, no_ssl, status, last_seq
76 from hosts
77 where status = $1`,
78 status,
79 )
80 if err != nil {
81 return nil, fmt.Errorf("querying hosts: %w", err)
82 }
83 defer rows.Close()
84
85 var hosts []models.Host
86 for rows.Next() {
87 var host models.Host
88 if err := rows.Scan(
89 &host.Hostname,
90 &host.NoSSL,
91 &host.Status,
92 &host.LastSeq,
93 ); err != nil {
94 return nil, fmt.Errorf("scanning row: %w", err)
95 }
96 hosts = append(hosts, host)
97 }
98 if err := rows.Err(); err != nil {
99 return nil, fmt.Errorf("scanning rows: %w ", err)
100 }
101 return hosts, nil
102}