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
 | |
| }
 |