482 lines
9.4 KiB
Go
482 lines
9.4 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
|
|
HubAddress string
|
|
VPNNetwork []byte
|
|
Password []byte
|
|
}
|
|
|
|
const Config_SelectQuery = "SELECT ConfigID,HubAddress,VPNNetwork,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,HubAddress,VPNNetwork,Password) VALUES(?,?,?,?)", row.ConfigID, row.HubAddress, row.VPNNetwork, 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 HubAddress=?,VPNNetwork=? WHERE ConfigID=?", row.HubAddress, row.VPNNetwork, 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 HubAddress=?,VPNNetwork=?,Password=? WHERE ConfigID=?", row.HubAddress, row.VPNNetwork, 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,HubAddress,VPNNetwork,Password FROM config WHERE ConfigID=?", ConfigID)
|
|
err = r.Scan(&row.ConfigID, &row.HubAddress, &row.VPNNetwork, &row.Password)
|
|
return
|
|
}
|
|
|
|
func Config_GetWhere(
|
|
tx TX,
|
|
query string,
|
|
args ...any,
|
|
) (
|
|
row *Config,
|
|
err error,
|
|
) {
|
|
row = &Config{}
|
|
r := tx.QueryRow(query, args...)
|
|
err = r.Scan(&row.ConfigID, &row.HubAddress, &row.VPNNetwork, &row.Password)
|
|
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.HubAddress, &row.VPNNetwork, &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: sessions
|
|
// ----------------------------------------------------------------------------
|
|
|
|
type Session struct {
|
|
SessionID string
|
|
CSRF string
|
|
SignedIn bool
|
|
CreatedAt int64
|
|
LastSeenAt int64
|
|
}
|
|
|
|
const Session_SelectQuery = "SELECT SessionID,CSRF,SignedIn,CreatedAt,LastSeenAt FROM sessions"
|
|
|
|
func Session_Insert(
|
|
tx TX,
|
|
row *Session,
|
|
) (err error) {
|
|
Session_Sanitize(row)
|
|
if err = Session_Validate(row); err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = tx.Exec("INSERT INTO sessions(SessionID,CSRF,SignedIn,CreatedAt,LastSeenAt) VALUES(?,?,?,?,?)", row.SessionID, row.CSRF, row.SignedIn, row.CreatedAt, row.LastSeenAt)
|
|
return err
|
|
}
|
|
|
|
func Session_Delete(
|
|
tx TX,
|
|
SessionID string,
|
|
) (err error) {
|
|
result, err := tx.Exec("DELETE FROM sessions WHERE SessionID=?", SessionID)
|
|
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 Session_Get(
|
|
tx TX,
|
|
SessionID string,
|
|
) (
|
|
row *Session,
|
|
err error,
|
|
) {
|
|
row = &Session{}
|
|
r := tx.QueryRow("SELECT SessionID,CSRF,SignedIn,CreatedAt,LastSeenAt FROM sessions WHERE SessionID=?", SessionID)
|
|
err = r.Scan(&row.SessionID, &row.CSRF, &row.SignedIn, &row.CreatedAt, &row.LastSeenAt)
|
|
return
|
|
}
|
|
|
|
func Session_GetWhere(
|
|
tx TX,
|
|
query string,
|
|
args ...any,
|
|
) (
|
|
row *Session,
|
|
err error,
|
|
) {
|
|
row = &Session{}
|
|
r := tx.QueryRow(query, args...)
|
|
err = r.Scan(&row.SessionID, &row.CSRF, &row.SignedIn, &row.CreatedAt, &row.LastSeenAt)
|
|
return
|
|
}
|
|
|
|
func Session_Iterate(
|
|
tx TX,
|
|
query string,
|
|
args ...any,
|
|
) iter.Seq2[*Session, error] {
|
|
rows, err := tx.Query(query, args...)
|
|
if err != nil {
|
|
return func(yield func(*Session, error) bool) {
|
|
yield(nil, err)
|
|
}
|
|
}
|
|
|
|
return func(yield func(*Session, error) bool) {
|
|
defer rows.Close()
|
|
for rows.Next() {
|
|
row := &Session{}
|
|
err := rows.Scan(&row.SessionID, &row.CSRF, &row.SignedIn, &row.CreatedAt, &row.LastSeenAt)
|
|
if !yield(row, err) {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func Session_List(
|
|
tx TX,
|
|
query string,
|
|
args ...any,
|
|
) (
|
|
l []*Session,
|
|
err error,
|
|
) {
|
|
for row, err := range Session_Iterate(tx, query, args...) {
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
l = append(l, row)
|
|
}
|
|
return l, nil
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Table: peers
|
|
// ----------------------------------------------------------------------------
|
|
|
|
type Peer struct {
|
|
PeerIP byte
|
|
Version int64
|
|
APIKey string
|
|
Name string
|
|
PublicIP []byte
|
|
Port uint16
|
|
Mediator bool
|
|
EncPubKey []byte
|
|
SignPubKey []byte
|
|
}
|
|
|
|
const Peer_SelectQuery = "SELECT PeerIP,Version,APIKey,Name,PublicIP,Port,Mediator,EncPubKey,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(PeerIP,Version,APIKey,Name,PublicIP,Port,Mediator,EncPubKey,SignPubKey) VALUES(?,?,?,?,?,?,?,?,?)", row.PeerIP, row.Version, row.APIKey, row.Name, row.PublicIP, row.Port, row.Mediator, row.EncPubKey, row.SignPubKey)
|
|
return err
|
|
}
|
|
|
|
func Peer_Update(
|
|
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 Version=?,Name=?,PublicIP=?,Port=?,Mediator=? WHERE PeerIP=?", row.Version, row.Name, row.PublicIP, row.Port, row.Mediator, 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_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 Version=?,APIKey=?,Name=?,PublicIP=?,Port=?,Mediator=?,EncPubKey=?,SignPubKey=? WHERE PeerIP=?", row.Version, row.APIKey, row.Name, row.PublicIP, row.Port, row.Mediator, row.EncPubKey, row.SignPubKey, 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,
|
|
PeerIP byte,
|
|
) (err error) {
|
|
result, err := tx.Exec("DELETE FROM peers WHERE PeerIP=?", 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,
|
|
PeerIP byte,
|
|
) (
|
|
row *Peer,
|
|
err error,
|
|
) {
|
|
row = &Peer{}
|
|
r := tx.QueryRow("SELECT PeerIP,Version,APIKey,Name,PublicIP,Port,Mediator,EncPubKey,SignPubKey FROM peers WHERE PeerIP=?", PeerIP)
|
|
err = r.Scan(&row.PeerIP, &row.Version, &row.APIKey, &row.Name, &row.PublicIP, &row.Port, &row.Mediator, &row.EncPubKey, &row.SignPubKey)
|
|
return
|
|
}
|
|
|
|
func Peer_GetWhere(
|
|
tx TX,
|
|
query string,
|
|
args ...any,
|
|
) (
|
|
row *Peer,
|
|
err error,
|
|
) {
|
|
row = &Peer{}
|
|
r := tx.QueryRow(query, args...)
|
|
err = r.Scan(&row.PeerIP, &row.Version, &row.APIKey, &row.Name, &row.PublicIP, &row.Port, &row.Mediator, &row.EncPubKey, &row.SignPubKey)
|
|
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.PeerIP, &row.Version, &row.APIKey, &row.Name, &row.PublicIP, &row.Port, &row.Mediator, &row.EncPubKey, &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
|
|
}
|