493 lines
9.2 KiB
Go
493 lines
9.2 KiB
Go
package db
|
|
|
|
import (
|
|
"database/sql"
|
|
"iter"
|
|
)
|
|
|
|
type TX interface {
|
|
Exec(query string, args ...any) (sql.Result, error)
|
|
Query(query string, args ...any) (*sql.Rows, error)
|
|
QueryRow(query string, args ...any) *sql.Row
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Table: config
|
|
// ----------------------------------------------------------------------------
|
|
|
|
type Config struct {
|
|
ConfigID int64
|
|
Password []byte
|
|
}
|
|
|
|
const Config_SelectQuery = "SELECT ConfigID,Password FROM config"
|
|
|
|
func Config_Insert(
|
|
tx TX,
|
|
row *Config,
|
|
) (err error) {
|
|
Config_Sanitize(row)
|
|
if err = Config_Validate(row); err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = tx.Exec("INSERT INTO config(ConfigID,Password) VALUES(?,?)", row.ConfigID, row.Password)
|
|
return err
|
|
}
|
|
|
|
func Config_Update(
|
|
tx TX,
|
|
row *Config,
|
|
) (err error) {
|
|
Config_Sanitize(row)
|
|
if err = Config_Validate(row); err != nil {
|
|
return err
|
|
}
|
|
|
|
result, err := tx.Exec("UPDATE config SET Password=? WHERE ConfigID=?", row.Password, row.ConfigID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
n, err := result.RowsAffected()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
switch n {
|
|
case 0:
|
|
return sql.ErrNoRows
|
|
case 1:
|
|
return nil
|
|
default:
|
|
panic("multiple rows updated")
|
|
}
|
|
}
|
|
|
|
func Config_UpdateFull(
|
|
tx TX,
|
|
row *Config,
|
|
) (err error) {
|
|
Config_Sanitize(row)
|
|
if err = Config_Validate(row); err != nil {
|
|
return err
|
|
}
|
|
|
|
result, err := tx.Exec("UPDATE config SET Password=? WHERE ConfigID=?", row.Password, row.ConfigID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
n, err := result.RowsAffected()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
switch n {
|
|
case 0:
|
|
return sql.ErrNoRows
|
|
case 1:
|
|
return nil
|
|
default:
|
|
panic("multiple rows updated")
|
|
}
|
|
}
|
|
|
|
func Config_Delete(
|
|
tx TX,
|
|
ConfigID int64,
|
|
) (err error) {
|
|
result, err := tx.Exec("DELETE FROM config WHERE ConfigID=?", ConfigID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
n, err := result.RowsAffected()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
switch n {
|
|
case 0:
|
|
return sql.ErrNoRows
|
|
case 1:
|
|
return nil
|
|
default:
|
|
panic("multiple rows deleted")
|
|
}
|
|
}
|
|
|
|
func Config_Get(
|
|
tx TX,
|
|
ConfigID int64,
|
|
) (
|
|
row *Config,
|
|
err error,
|
|
) {
|
|
row = &Config{}
|
|
r := tx.QueryRow("SELECT ConfigID,Password FROM config WHERE ConfigID=?", ConfigID)
|
|
if err = r.Scan(&row.ConfigID, &row.Password); err != nil {
|
|
row = nil
|
|
}
|
|
return
|
|
}
|
|
|
|
func Config_GetWhere(
|
|
tx TX,
|
|
query string,
|
|
args ...any,
|
|
) (
|
|
row *Config,
|
|
err error,
|
|
) {
|
|
row = &Config{}
|
|
r := tx.QueryRow(query, args...)
|
|
if err = r.Scan(&row.ConfigID, &row.Password); err != nil {
|
|
row = nil
|
|
}
|
|
return
|
|
}
|
|
|
|
func Config_Iterate(
|
|
tx TX,
|
|
query string,
|
|
args ...any,
|
|
) iter.Seq2[*Config, error] {
|
|
rows, err := tx.Query(query, args...)
|
|
if err != nil {
|
|
return func(yield func(*Config, error) bool) {
|
|
yield(nil, err)
|
|
}
|
|
}
|
|
|
|
return func(yield func(*Config, error) bool) {
|
|
defer rows.Close()
|
|
for rows.Next() {
|
|
row := &Config{}
|
|
err := rows.Scan(&row.ConfigID, &row.Password)
|
|
if !yield(row, err) {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func Config_List(
|
|
tx TX,
|
|
query string,
|
|
args ...any,
|
|
) (
|
|
l []*Config,
|
|
err error,
|
|
) {
|
|
for row, err := range Config_Iterate(tx, query, args...) {
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
l = append(l, row)
|
|
}
|
|
return l, nil
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Table: networks
|
|
// ----------------------------------------------------------------------------
|
|
|
|
type Network struct {
|
|
NetworkID int64
|
|
LocalDomain string
|
|
Network []byte
|
|
}
|
|
|
|
const Network_SelectQuery = "SELECT NetworkID,LocalDomain,Network FROM networks"
|
|
|
|
func Network_Insert(
|
|
tx TX,
|
|
row *Network,
|
|
) (err error) {
|
|
Network_Sanitize(row)
|
|
if err = Network_Validate(row); err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = tx.Exec("INSERT INTO networks(NetworkID,LocalDomain,Network) VALUES(?,?,?)", row.NetworkID, row.LocalDomain, row.Network)
|
|
return err
|
|
}
|
|
|
|
func Network_UpdateFull(
|
|
tx TX,
|
|
row *Network,
|
|
) (err error) {
|
|
Network_Sanitize(row)
|
|
if err = Network_Validate(row); err != nil {
|
|
return err
|
|
}
|
|
|
|
result, err := tx.Exec("UPDATE networks SET LocalDomain=?,Network=? WHERE NetworkID=?", row.LocalDomain, row.Network, row.NetworkID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
n, err := result.RowsAffected()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
switch n {
|
|
case 0:
|
|
return sql.ErrNoRows
|
|
case 1:
|
|
return nil
|
|
default:
|
|
panic("multiple rows updated")
|
|
}
|
|
}
|
|
|
|
func Network_Delete(
|
|
tx TX,
|
|
NetworkID int64,
|
|
) (err error) {
|
|
result, err := tx.Exec("DELETE FROM networks WHERE NetworkID=?", NetworkID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
n, err := result.RowsAffected()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
switch n {
|
|
case 0:
|
|
return sql.ErrNoRows
|
|
case 1:
|
|
return nil
|
|
default:
|
|
panic("multiple rows deleted")
|
|
}
|
|
}
|
|
|
|
func Network_Get(
|
|
tx TX,
|
|
NetworkID int64,
|
|
) (
|
|
row *Network,
|
|
err error,
|
|
) {
|
|
row = &Network{}
|
|
r := tx.QueryRow("SELECT NetworkID,LocalDomain,Network FROM networks WHERE NetworkID=?", NetworkID)
|
|
if err = r.Scan(&row.NetworkID, &row.LocalDomain, &row.Network); err != nil {
|
|
row = nil
|
|
}
|
|
return
|
|
}
|
|
|
|
func Network_GetWhere(
|
|
tx TX,
|
|
query string,
|
|
args ...any,
|
|
) (
|
|
row *Network,
|
|
err error,
|
|
) {
|
|
row = &Network{}
|
|
r := tx.QueryRow(query, args...)
|
|
if err = r.Scan(&row.NetworkID, &row.LocalDomain, &row.Network); err != nil {
|
|
row = nil
|
|
}
|
|
return
|
|
}
|
|
|
|
func Network_Iterate(
|
|
tx TX,
|
|
query string,
|
|
args ...any,
|
|
) iter.Seq2[*Network, error] {
|
|
rows, err := tx.Query(query, args...)
|
|
if err != nil {
|
|
return func(yield func(*Network, error) bool) {
|
|
yield(nil, err)
|
|
}
|
|
}
|
|
|
|
return func(yield func(*Network, error) bool) {
|
|
defer rows.Close()
|
|
for rows.Next() {
|
|
row := &Network{}
|
|
err := rows.Scan(&row.NetworkID, &row.LocalDomain, &row.Network)
|
|
if !yield(row, err) {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func Network_List(
|
|
tx TX,
|
|
query string,
|
|
args ...any,
|
|
) (
|
|
l []*Network,
|
|
err error,
|
|
) {
|
|
for row, err := range Network_Iterate(tx, query, args...) {
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
l = append(l, row)
|
|
}
|
|
return l, nil
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Table: peers
|
|
// ----------------------------------------------------------------------------
|
|
|
|
type Peer struct {
|
|
NetworkID int64
|
|
PeerIP byte
|
|
APIKey string
|
|
Name string
|
|
Addr4 []byte
|
|
Addr6 []byte
|
|
Port uint16
|
|
Relay bool
|
|
WGPubKey []byte
|
|
SignPubKey []byte
|
|
}
|
|
|
|
const Peer_SelectQuery = "SELECT NetworkID,PeerIP,APIKey,Name,Addr4,Addr6,Port,Relay,WGPubKey,SignPubKey FROM peers"
|
|
|
|
func Peer_Insert(
|
|
tx TX,
|
|
row *Peer,
|
|
) (err error) {
|
|
Peer_Sanitize(row)
|
|
if err = Peer_Validate(row); err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = tx.Exec("INSERT INTO peers(NetworkID,PeerIP,APIKey,Name,Addr4,Addr6,Port,Relay,WGPubKey,SignPubKey) VALUES(?,?,?,?,?,?,?,?,?,?)", row.NetworkID, row.PeerIP, row.APIKey, row.Name, row.Addr4, row.Addr6, row.Port, row.Relay, row.WGPubKey, row.SignPubKey)
|
|
return err
|
|
}
|
|
|
|
func Peer_UpdateFull(
|
|
tx TX,
|
|
row *Peer,
|
|
) (err error) {
|
|
Peer_Sanitize(row)
|
|
if err = Peer_Validate(row); err != nil {
|
|
return err
|
|
}
|
|
|
|
result, err := tx.Exec("UPDATE peers SET APIKey=?,Name=?,Addr4=?,Addr6=?,Port=?,Relay=?,WGPubKey=?,SignPubKey=? WHERE NetworkID=? AND PeerIP=?", row.APIKey, row.Name, row.Addr4, row.Addr6, row.Port, row.Relay, row.WGPubKey, row.SignPubKey, row.NetworkID, row.PeerIP)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
n, err := result.RowsAffected()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
switch n {
|
|
case 0:
|
|
return sql.ErrNoRows
|
|
case 1:
|
|
return nil
|
|
default:
|
|
panic("multiple rows updated")
|
|
}
|
|
}
|
|
|
|
func Peer_Delete(
|
|
tx TX,
|
|
NetworkID int64,
|
|
PeerIP byte,
|
|
) (err error) {
|
|
result, err := tx.Exec("DELETE FROM peers WHERE NetworkID=? AND PeerIP=?", NetworkID, PeerIP)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
n, err := result.RowsAffected()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
switch n {
|
|
case 0:
|
|
return sql.ErrNoRows
|
|
case 1:
|
|
return nil
|
|
default:
|
|
panic("multiple rows deleted")
|
|
}
|
|
}
|
|
|
|
func Peer_Get(
|
|
tx TX,
|
|
NetworkID int64,
|
|
PeerIP byte,
|
|
) (
|
|
row *Peer,
|
|
err error,
|
|
) {
|
|
row = &Peer{}
|
|
r := tx.QueryRow("SELECT NetworkID,PeerIP,APIKey,Name,Addr4,Addr6,Port,Relay,WGPubKey,SignPubKey FROM peers WHERE NetworkID=? AND PeerIP=?", NetworkID, PeerIP)
|
|
if err = r.Scan(&row.NetworkID, &row.PeerIP, &row.APIKey, &row.Name, &row.Addr4, &row.Addr6, &row.Port, &row.Relay, &row.WGPubKey, &row.SignPubKey); err != nil {
|
|
row = nil
|
|
}
|
|
return
|
|
}
|
|
|
|
func Peer_GetWhere(
|
|
tx TX,
|
|
query string,
|
|
args ...any,
|
|
) (
|
|
row *Peer,
|
|
err error,
|
|
) {
|
|
row = &Peer{}
|
|
r := tx.QueryRow(query, args...)
|
|
if err = r.Scan(&row.NetworkID, &row.PeerIP, &row.APIKey, &row.Name, &row.Addr4, &row.Addr6, &row.Port, &row.Relay, &row.WGPubKey, &row.SignPubKey); err != nil {
|
|
row = nil
|
|
}
|
|
return
|
|
}
|
|
|
|
func Peer_Iterate(
|
|
tx TX,
|
|
query string,
|
|
args ...any,
|
|
) iter.Seq2[*Peer, error] {
|
|
rows, err := tx.Query(query, args...)
|
|
if err != nil {
|
|
return func(yield func(*Peer, error) bool) {
|
|
yield(nil, err)
|
|
}
|
|
}
|
|
|
|
return func(yield func(*Peer, error) bool) {
|
|
defer rows.Close()
|
|
for rows.Next() {
|
|
row := &Peer{}
|
|
err := rows.Scan(&row.NetworkID, &row.PeerIP, &row.APIKey, &row.Name, &row.Addr4, &row.Addr6, &row.Port, &row.Relay, &row.WGPubKey, &row.SignPubKey)
|
|
if !yield(row, err) {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func Peer_List(
|
|
tx TX,
|
|
query string,
|
|
args ...any,
|
|
) (
|
|
l []*Peer,
|
|
err error,
|
|
) {
|
|
for row, err := range Peer_Iterate(tx, query, args...) {
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
l = append(l, row)
|
|
}
|
|
return l, nil
|
|
}
|