Self-contained HTTP/HTTPS/TCP/UDP reverse proxy manager written in Go, with SQLite storage, a Bootstrap 5 admin UI (Go templates, no JS framework), and a REST API under /api/v1. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QTXFrNP1imCW7jtfL5SZrw
86 lines
2.8 KiB
Go
86 lines
2.8 KiB
Go
package database
|
|
|
|
import (
|
|
"database/sql"
|
|
"errors"
|
|
|
|
"github.com/owen/vibeproxy/internal/models"
|
|
)
|
|
|
|
func scanStream(rs rowScanner) (models.Stream, error) {
|
|
var s models.Stream
|
|
var proxyProto, enabled int
|
|
var created, updated string
|
|
err := rs.Scan(&s.ID, &s.Protocol, &s.ListenIP, &s.ListenPort, &s.DestinationHost, &s.DestinationPort,
|
|
&s.ConnectTimeoutMS, &s.IdleTimeoutMS, &proxyProto, &enabled, &s.Comments, &created, &updated)
|
|
if err != nil {
|
|
return s, err
|
|
}
|
|
s.ProxyProtocol = proxyProto == 1
|
|
s.Enabled = enabled == 1
|
|
s.CreatedAt = parseTime(created)
|
|
s.UpdatedAt = parseTime(updated)
|
|
return s, nil
|
|
}
|
|
|
|
const streamCols = `id, protocol, listen_ip, listen_port, destination_host, destination_port, connect_timeout_ms, idle_timeout_ms, proxy_protocol, enabled, comments, created_at, updated_at`
|
|
|
|
func ListStreams(db *sql.DB) ([]models.Stream, error) {
|
|
rows, err := db.Query(`SELECT ` + streamCols + ` FROM streams ORDER BY id`)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var out []models.Stream
|
|
for rows.Next() {
|
|
s, err := scanStream(rows)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
out = append(out, s)
|
|
}
|
|
return out, rows.Err()
|
|
}
|
|
|
|
func GetStream(db *sql.DB, id int64) (*models.Stream, error) {
|
|
row := db.QueryRow(`SELECT `+streamCols+` FROM streams WHERE id = ?`, id)
|
|
s, err := scanStream(row)
|
|
if err != nil {
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
return nil, ErrNotFound
|
|
}
|
|
return nil, err
|
|
}
|
|
return &s, nil
|
|
}
|
|
|
|
func SaveStream(db *sql.DB, s *models.Stream) (int64, error) {
|
|
if s.ID == 0 {
|
|
res, err := db.Exec(`INSERT INTO streams (protocol, listen_ip, listen_port, destination_host, destination_port,
|
|
connect_timeout_ms, idle_timeout_ms, proxy_protocol, enabled, comments) VALUES (?,?,?,?,?,?,?,?,?,?)`,
|
|
s.Protocol, s.ListenIP, s.ListenPort, s.DestinationHost, s.DestinationPort, s.ConnectTimeoutMS,
|
|
s.IdleTimeoutMS, boolToInt(s.ProxyProtocol), boolToInt(s.Enabled), s.Comments)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
id, err := res.LastInsertId()
|
|
s.ID = id
|
|
return id, err
|
|
}
|
|
_, err := db.Exec(`UPDATE streams SET protocol=?, listen_ip=?, listen_port=?, destination_host=?, destination_port=?,
|
|
connect_timeout_ms=?, idle_timeout_ms=?, proxy_protocol=?, enabled=?, comments=?, updated_at=strftime('%Y-%m-%dT%H:%M:%fZ','now')
|
|
WHERE id=?`, s.Protocol, s.ListenIP, s.ListenPort, s.DestinationHost, s.DestinationPort, s.ConnectTimeoutMS,
|
|
s.IdleTimeoutMS, boolToInt(s.ProxyProtocol), boolToInt(s.Enabled), s.Comments, s.ID)
|
|
return s.ID, err
|
|
}
|
|
|
|
func DeleteStream(db *sql.DB, id int64) error {
|
|
_, err := db.Exec(`DELETE FROM streams WHERE id = ?`, id)
|
|
return err
|
|
}
|
|
|
|
func SetStreamEnabled(db *sql.DB, id int64, enabled bool) error {
|
|
_, err := db.Exec(`UPDATE streams SET enabled = ?, updated_at = strftime('%Y-%m-%dT%H:%M:%fZ','now') WHERE id = ?`, boolToInt(enabled), id)
|
|
return err
|
|
}
|