This commit is contained in:
HappyHakunaMatata 2024-10-10 22:18:47 +02:00
parent e9e79ac3f4
commit 2417249eca
15 changed files with 767 additions and 128 deletions

View file

@ -23,6 +23,7 @@ import (
"github.com/yggdrasil-network/yggdrasil-go/src/address" "github.com/yggdrasil-network/yggdrasil-go/src/address"
"github.com/yggdrasil-network/yggdrasil-go/src/admin" "github.com/yggdrasil-network/yggdrasil-go/src/admin"
"github.com/yggdrasil-network/yggdrasil-go/src/config" "github.com/yggdrasil-network/yggdrasil-go/src/config"
database "github.com/yggdrasil-network/yggdrasil-go/src/db"
"github.com/yggdrasil-network/yggdrasil-go/src/ipv6rwc" "github.com/yggdrasil-network/yggdrasil-go/src/ipv6rwc"
monitoring "github.com/yggdrasil-network/yggdrasil-go/src/monitoring" monitoring "github.com/yggdrasil-network/yggdrasil-go/src/monitoring"
@ -128,7 +129,6 @@ func init() {
//init cfg //init cfg
cfg = config.GenerateConfig() cfg = config.GenerateConfig()
///tested
addressCmd.Flags().StringP("useconffile", "f", "", "Read HJSON/JSON config from specified file path") addressCmd.Flags().StringP("useconffile", "f", "", "Read HJSON/JSON config from specified file path")
rootCmd.AddCommand(addressCmd) rootCmd.AddCommand(addressCmd)
genconfCmd.Flags().BoolP("json", "j", false, "print configuration as JSON instead of HJSON") genconfCmd.Flags().BoolP("json", "j", false, "print configuration as JSON instead of HJSON")
@ -143,8 +143,9 @@ func init() {
normaliseconfCmd.Flags().StringP("useconffile", "f", "", "Read HJSON/JSON config from specified file path") normaliseconfCmd.Flags().StringP("useconffile", "f", "", "Read HJSON/JSON config from specified file path")
normaliseconfCmd.Flags().BoolP("json", "j", false, "print configuration as JSON instead of HJSON") normaliseconfCmd.Flags().BoolP("json", "j", false, "print configuration as JSON instead of HJSON")
rootCmd.AddCommand(normaliseconfCmd) rootCmd.AddCommand(normaliseconfCmd)
///
runCmd.Flags().BoolP("db", "d", false, "Enable logging to the database")
runCmd.Flags().Int32P("setdbtimer", "s", 0, "Set the logging interval to the database in minutes")
runCmd.Flags().StringP("logto", "t", "", "File path to log to, \"syslog\" or \"stdout\"") runCmd.Flags().StringP("logto", "t", "", "File path to log to, \"syslog\" or \"stdout\"")
runCmd.Flags().StringP("loglevel", "l", "", "loglevel to enable") runCmd.Flags().StringP("loglevel", "l", "", "loglevel to enable")
runCmd.Flags().BoolP("useconf", "u", false, "Read HJSON/JSON config from stdin") runCmd.Flags().BoolP("useconf", "u", false, "Read HJSON/JSON config from stdin")
@ -210,7 +211,6 @@ func cmdAddress(cmd *cobra.Command, args []string) (err error) {
} }
func cmdSnet(cmd *cobra.Command, args []string) (err error) { func cmdSnet(cmd *cobra.Command, args []string) (err error) {
fmt.Println("Test")
configFile, err := cmd.Flags().GetString("useconffile") configFile, err := cmd.Flags().GetString("useconffile")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
@ -344,17 +344,16 @@ func cmdNormaliseconf(cmd *cobra.Command, args []string) (err error) {
func cmdRun(cmd *cobra.Command, args []string) (err error) { func cmdRun(cmd *cobra.Command, args []string) (err error) {
isUseConf, err := cmd.Flags().GetBool("useconf") isUseConf, err := cmd.Flags().GetBool("useconf")
if err != nil { if err != nil {
logger.Error(err.Error()) fmt.Print(err.Error())
} }
if isUseConf { if isUseConf {
if _, err := cfg.ReadFrom(os.Stdin); err != nil { if _, err := cfg.ReadFrom(os.Stdin); err != nil {
logger.Error(err.Error()) fmt.Print(err.Error())
return err
} }
} else { } else {
configFile, err := cmd.Flags().GetString("useconffile") configFile, err := cmd.Flags().GetString("useconffile")
if err != nil { if err != nil {
logger.Error(err.Error()) fmt.Print(err.Error())
} }
if configFile != "" { if configFile != "" {
rootpath = configFile rootpath = configFile
@ -362,19 +361,28 @@ func cmdRun(cmd *cobra.Command, args []string) (err error) {
if rootpath != "" { if rootpath != "" {
err = ReadConfigFile(&rootpath) err = ReadConfigFile(&rootpath)
if err != nil { if err != nil {
logger.Error(err.Error()) fmt.Print(err.Error())
} }
} }
} }
logto, err := cmd.Flags().GetString("logto") logto, err := cmd.Flags().GetString("logto")
if err != nil { if err != nil {
logger.Error(err.Error()) fmt.Print(err.Error())
return err
} }
if logto != "" { if logto != "" {
cmdLogto(logto) cmdLogto(logto)
} }
UseDB, err := cmd.Flags().GetBool("db")
if err != nil {
fmt.Print(err.Error())
}
min, err := cmd.Flags().GetInt32("setdbtimer")
if err != nil {
fmt.Print(err.Error())
}
if min > 0 {
database.Timer = int(min)
}
ctx, cancel = signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) ctx, cancel = signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
// Capture the service being stopped on Windows. // Capture the service being stopped on Windows.
minwinsvc.SetOnExit(cancel) minwinsvc.SetOnExit(cancel)
@ -387,7 +395,7 @@ func cmdRun(cmd *cobra.Command, args []string) (err error) {
loglvl, err := cmd.Flags().GetString("loglevel") loglvl, err := cmd.Flags().GetString("loglevel")
if err != nil { if err != nil {
logger.Error(err.Error()) logger.Error(err.Error())
return err //return err
} }
if loglvl != "" { if loglvl != "" {
setLogLevel(loglvl, logger) setLogLevel(loglvl, logger)
@ -482,6 +490,19 @@ func cmdRun(cmd *cobra.Command, args []string) (err error) {
} }
} }
//Set up the DB module.
if UseDB {
db, err := database.OpenExistDb(logger, n.core)
if err != nil {
db, err = database.CreateDb(logger, n.core)
if err != nil {
logger.Printf(err.Error())
panic(err)
}
}
db.CreateTimer(ctx)
db.OnListen(ctx)
}
m, _ := monitoring.New(n.core, logger) m, _ := monitoring.New(n.core, logger)
// Block until we are told to shut down. // Block until we are told to shut down.

View file

@ -130,6 +130,22 @@ func (c *Core) GetPaths() []PathEntryInfo {
return paths return paths
} }
func (c *Core) GetMappedPaths() map[string]PathEntryInfo {
paths := make(map[string]PathEntryInfo)
ps := c.PacketConn.PacketConn.Debug.GetPaths()
for _, p := range ps {
info := PathEntryInfo{
Key: p.Key,
Sequence: p.Sequence,
Path: p.Path,
}
addr := address.AddrForKey(info.Key)
addrStr := net.IP(addr[:]).String()
paths[addrStr] = info
}
return paths
}
func (c *Core) GetSessions() []SessionInfo { func (c *Core) GetSessions() []SessionInfo {
var sessions []SessionInfo var sessions []SessionInfo
ss := c.PacketConn.Debug.GetSessions() ss := c.PacketConn.Debug.GetSessions()
@ -144,6 +160,63 @@ func (c *Core) GetSessions() []SessionInfo {
return sessions return sessions
} }
func (c *Core) GetMappedSessions() map[string]SessionInfo {
sessions := make(map[string]SessionInfo)
ss := c.PacketConn.Debug.GetSessions()
for _, s := range ss {
info := SessionInfo{
Key: s.Key,
RXBytes: s.RX,
TXBytes: s.TX,
Uptime: s.Uptime,
}
addr := address.AddrForKey(info.Key)
addrStr := net.IP(addr[:]).String()
sessions[addrStr] = info
}
return sessions
}
func (c *Core) GetMappedPeers() map[string]PeerInfo {
peers := make(map[string]PeerInfo)
conns := map[net.Conn]network.DebugPeerInfo{}
iwpeers := c.PacketConn.PacketConn.Debug.GetPeers()
for _, p := range iwpeers {
conns[p.Conn] = p
}
phony.Block(&c.links, func() {
for info, state := range c.links._links {
var conn net.Conn
peerinfo := PeerInfo{
URI: info.uri,
LastError: state._err,
LastErrorTime: state._errtime,
}
if c := state._conn; c != nil {
conn = c
peerinfo.Up = true
peerinfo.Inbound = state.linkType == linkTypeIncoming
peerinfo.RXBytes = atomic.LoadUint64(&c.rx)
peerinfo.TXBytes = atomic.LoadUint64(&c.tx)
peerinfo.Uptime = time.Since(c.up)
}
if p, ok := conns[conn]; ok {
peerinfo.Key = p.Key
peerinfo.Root = p.Root
peerinfo.Port = p.Port
peerinfo.Priority = p.Priority
peerinfo.Latency = p.Latency
addr := address.AddrForKey(peerinfo.Key)
addrStr := net.IP(addr[:]).String()
peers[addrStr] = peerinfo
}
}
})
return peers
}
// Listen starts a new listener (either TCP or TLS). The input should be a url.URL // Listen starts a new listener (either TCP or TLS). The input should be a url.URL
// parsed from a string of the form e.g. "tcp://a.b.c.d:e". In the case of a // parsed from a string of the form e.g. "tcp://a.b.c.d:e". In the case of a
// link-local address, the interface should be provided as the second argument. // link-local address, the interface should be provided as the second argument.

View file

@ -6,8 +6,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"github.com/yggdrasil-network/yggdrasil-go/src/core" db "github.com/yggdrasil-network/yggdrasil-go/src/db/dbConfig"
"github.com/yggdrasil-network/yggdrasil-go/src/db"
) )
type PathEntryInfoDBConfig struct { type PathEntryInfoDBConfig struct {
@ -15,20 +14,29 @@ type PathEntryInfoDBConfig struct {
name string name string
} }
var Name = "PathEntryInfo" var (
Name = "PathEntryInfo"
Path = ""
)
func New() (*PathEntryInfoDBConfig, error) { func New() (*PathEntryInfoDBConfig, error) {
var path string
if Path == "" {
dir, _ := os.Getwd() dir, _ := os.Getwd()
fileName := fmt.Sprintf("%s.db", Name) fileName := fmt.Sprintf("%s.db", Name)
filePath := filepath.Join(dir, fileName) path = filepath.Join(dir, fileName)
} else {
path = Path
}
schemas := []string{ schemas := []string{
`CREATE TABLE IF NOT EXISTS path_entry_info ( `CREATE TABLE IF NOT EXISTS path_entry_info (
Id INTEGER NOT NULL PRIMARY KEY, Id INTEGER NOT NULL PRIMARY KEY,
Key BLOB, Key BLOB,
Path BLOB, Path BLOB,
Sequence INTEGER Sequence INTEGER,
DateTime TEXT
);`} );`}
dbcfg, err := db.New("sqlite3", &schemas, filePath) dbcfg, err := db.New("sqlite3", &schemas, path)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -39,8 +47,28 @@ func New() (*PathEntryInfoDBConfig, error) {
return cfg, nil return cfg, nil
} }
func (cfg *PathEntryInfoDBConfig) Add(model *core.PathEntryInfoDB) (_ sql.Result, err error) { func Open() (*PathEntryInfoDBConfig, error) {
query := "INSERT INTO path_entry_info (Key, Path, Sequence) VALUES (?, ?, ?)" var path string
if Path == "" {
dir, _ := os.Getwd()
fileName := fmt.Sprintf("%s.db", Name)
path = filepath.Join(dir, fileName)
} else {
path = Path
}
dbcfg, err := db.OpenIfExist("sqlite3", path)
if err != nil {
return nil, err
}
cfg := &PathEntryInfoDBConfig{
name: Name,
DbConfig: dbcfg,
}
return cfg, nil
}
func (cfg *PathEntryInfoDBConfig) Add(model *db.PathEntryInfoDB) (_ sql.Result, err error) {
query := "INSERT INTO path_entry_info (Key, Path, Sequence, DateTime) VALUES (?, ?, ?, datetime('now'))"
result, err := cfg.DbConfig.DB.Exec( result, err := cfg.DbConfig.DB.Exec(
query, query,
model.Key.GetPKIXPublicKeyBytes(), model.Key.GetPKIXPublicKeyBytes(),
@ -57,7 +85,7 @@ func (cfg *PathEntryInfoDBConfig) Add(model *core.PathEntryInfoDB) (_ sql.Result
return result, nil return result, nil
} }
func (cfg *PathEntryInfoDBConfig) Remove(model *core.PathEntryInfoDB) (err error) { func (cfg *PathEntryInfoDBConfig) Remove(model *db.PathEntryInfoDB) (err error) {
_, err = cfg.DbConfig.DB.Exec("DELETE FROM path_entry_info WHERE Id = ?", _, err = cfg.DbConfig.DB.Exec("DELETE FROM path_entry_info WHERE Id = ?",
model.Id) model.Id)
if err != nil { if err != nil {
@ -66,7 +94,7 @@ func (cfg *PathEntryInfoDBConfig) Remove(model *core.PathEntryInfoDB) (err error
return nil return nil
} }
func (cfg *PathEntryInfoDBConfig) Update(model *core.PathEntryInfoDB) (err error) { func (cfg *PathEntryInfoDBConfig) Update(model *db.PathEntryInfoDB) (err error) {
_, err = cfg.DbConfig.DB.Exec(`UPDATE path_entry_info _, err = cfg.DbConfig.DB.Exec(`UPDATE path_entry_info
SET SET
Sequence = ?, Sequence = ?,
@ -81,7 +109,7 @@ func (cfg *PathEntryInfoDBConfig) Update(model *core.PathEntryInfoDB) (err error
return nil return nil
} }
func (cfg *PathEntryInfoDBConfig) Get(model *core.PathEntryInfoDB) (_ *sql.Rows, err error) { func (cfg *PathEntryInfoDBConfig) Get(model *db.PathEntryInfoDB) (_ *sql.Rows, err error) {
rows, err := cfg.DbConfig.DB.Query("SELECT Sequence, Key, Path FROM path_entry_info WHERE Id = ?", rows, err := cfg.DbConfig.DB.Query("SELECT Sequence, Key, Path FROM path_entry_info WHERE Id = ?",
model.Id, model.Id,
) )

View file

@ -6,9 +6,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
_ "github.com/mattn/go-sqlite3" db "github.com/yggdrasil-network/yggdrasil-go/src/db/dbConfig"
"github.com/yggdrasil-network/yggdrasil-go/src/core"
"github.com/yggdrasil-network/yggdrasil-go/src/db"
) )
type PeerInfoDBConfig struct { type PeerInfoDBConfig struct {
@ -16,12 +14,20 @@ type PeerInfoDBConfig struct {
name string name string
} }
var Name = "PeerInfo" var (
Name = "PeerInfo"
Path = ""
)
func New() (*PeerInfoDBConfig, error) { func New() (*PeerInfoDBConfig, error) {
var path string
if Path == "" {
dir, _ := os.Getwd() dir, _ := os.Getwd()
fileName := fmt.Sprintf("%s.db", Name) fileName := fmt.Sprintf("%s.db", Name)
filePath := filepath.Join(dir, fileName) path = filepath.Join(dir, fileName)
} else {
path = Path
}
schemas := []string{ schemas := []string{
`CREATE TABLE IF NOT EXISTS peer_infos ( `CREATE TABLE IF NOT EXISTS peer_infos (
Id INTEGER NOT NULL PRIMARY KEY, Id INTEGER NOT NULL PRIMARY KEY,
@ -38,9 +44,10 @@ func New() (*PeerInfoDBConfig, error) {
Rxbytes BIGINT, Rxbytes BIGINT,
Txbytes BIGINT, Txbytes BIGINT,
uptime INTEGER, uptime INTEGER,
latency SMALLINT latency SMALLINT,
DateTime TEXT
);`} );`}
dbcfg, err := db.New("sqlite3", &schemas, filePath) dbcfg, err := db.New("sqlite3", &schemas, path)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -51,8 +58,34 @@ func New() (*PeerInfoDBConfig, error) {
return cfg, nil return cfg, nil
} }
func (cfg *PeerInfoDBConfig) Add(model *core.PeerInfoDB) (_ sql.Result, err error) { func Open() (*PeerInfoDBConfig, error) {
query := "INSERT OR REPLACE INTO peer_infos (uri, up, inbound, last_error, last_error_time, key, root, coords, port, priority, Rxbytes, Txbytes, uptime, latency) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" var path string
if Path == "" {
dir, _ := os.Getwd()
fileName := fmt.Sprintf("%s.db", Name)
path = filepath.Join(dir, fileName)
} else {
path = Path
}
dbcfg, err := db.OpenIfExist("sqlite3", path)
if err != nil {
return nil, err
}
cfg := &PeerInfoDBConfig{
name: Name,
DbConfig: dbcfg,
}
return cfg, nil
}
func (cfg *PeerInfoDBConfig) Add(model *db.PeerInfoDB) (_ sql.Result, err error) {
query := `
INSERT OR REPLACE INTO
peer_infos
(uri, up, inbound, last_error, last_error_time, key, root,
coords, port, priority, Rxbytes, Txbytes, uptime, latency, DateTime)
VALUES
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, datetime('now'))`
result, err := cfg.DbConfig.DB.Exec(query, result, err := cfg.DbConfig.DB.Exec(query,
model.URI, model.URI,
model.Up, model.Up,
@ -79,7 +112,7 @@ func (cfg *PeerInfoDBConfig) Add(model *core.PeerInfoDB) (_ sql.Result, err erro
return result, nil return result, nil
} }
func (cfg *PeerInfoDBConfig) Remove(model *core.PeerInfoDB) (err error) { func (cfg *PeerInfoDBConfig) Remove(model *db.PeerInfoDB) (err error) {
_, err = cfg.DbConfig.DB.Exec("DELETE FROM peer_infos WHERE Id = ?", _, err = cfg.DbConfig.DB.Exec("DELETE FROM peer_infos WHERE Id = ?",
model.Id) model.Id)
if err != nil { if err != nil {
@ -88,7 +121,7 @@ func (cfg *PeerInfoDBConfig) Remove(model *core.PeerInfoDB) (err error) {
return nil return nil
} }
func (cfg *PeerInfoDBConfig) Get(model *core.PeerInfoDB) (_ *sql.Rows, err error) { func (cfg *PeerInfoDBConfig) Get(model *db.PeerInfoDB) (_ *sql.Rows, err error) {
rows, err := cfg.DbConfig.DB.Query(` rows, err := cfg.DbConfig.DB.Query(`
SELECT SELECT
up, inbound, last_error, last_error_time, coords, port, up, inbound, last_error, last_error_time, coords, port,
@ -120,7 +153,7 @@ func (cfg *PeerInfoDBConfig) Get(model *core.PeerInfoDB) (_ *sql.Rows, err error
return rows, nil return rows, nil
} }
func (cfg *PeerInfoDBConfig) Update(model *core.PeerInfoDB) (err error) { func (cfg *PeerInfoDBConfig) Update(model *db.PeerInfoDB) (err error) {
_, err = cfg.DbConfig.DB.Exec(`UPDATE peer_infos _, err = cfg.DbConfig.DB.Exec(`UPDATE peer_infos
SET SET
up = ?, up = ?,

View file

@ -6,8 +6,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"github.com/yggdrasil-network/yggdrasil-go/src/core" db "github.com/yggdrasil-network/yggdrasil-go/src/db/dbConfig"
"github.com/yggdrasil-network/yggdrasil-go/src/db"
) )
type SelfInfoDBConfig struct { type SelfInfoDBConfig struct {
@ -15,19 +14,28 @@ type SelfInfoDBConfig struct {
name string name string
} }
var Name = "SelfInfo" var (
Name = "SelfInfo"
Path = ""
)
func New() (*SelfInfoDBConfig, error) { func New() (*SelfInfoDBConfig, error) {
var path string
if Path == "" {
dir, _ := os.Getwd() dir, _ := os.Getwd()
fileName := fmt.Sprintf("%s.db", Name) fileName := fmt.Sprintf("%s.db", Name)
filePath := filepath.Join(dir, fileName) path = filepath.Join(dir, fileName)
} else {
path = Path
}
schemas := []string{ schemas := []string{
`CREATE TABLE IF NOT EXISTS self_info ( `CREATE TABLE IF NOT EXISTS self_info (
Id INTEGER NOT NULL PRIMARY KEY, Id INTEGER NOT NULL PRIMARY KEY,
Key BLOB, Key BLOB,
RoutingEntries INTEGER RoutingEntries INTEGER,
DateTime TEXT
);`} );`}
dbcfg, err := db.New("sqlite3", &schemas, filePath) dbcfg, err := db.New("sqlite3", &schemas, path)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -38,8 +46,33 @@ func New() (*SelfInfoDBConfig, error) {
return cfg, nil return cfg, nil
} }
func (cfg *SelfInfoDBConfig) Add(model *core.SelfInfoDB) (_ sql.Result, err error) { func Open() (*SelfInfoDBConfig, error) {
query := "INSERT OR REPLACE INTO self_info (Key, RoutingEntries) VALUES (?, ?)" var path string
if Path == "" {
dir, _ := os.Getwd()
fileName := fmt.Sprintf("%s.db", Name)
path = filepath.Join(dir, fileName)
} else {
path = Path
}
dbcfg, err := db.OpenIfExist("sqlite3", path)
if err != nil {
return nil, err
}
cfg := &SelfInfoDBConfig{
name: Name,
DbConfig: dbcfg,
}
return cfg, nil
}
func (cfg *SelfInfoDBConfig) Add(model *db.SelfInfoDB) (_ sql.Result, err error) {
query := `
INSERT OR REPLACE INTO
self_info
(Key, RoutingEntries, DateTime)
VALUES
(?, ?, datetime('now'))`
result, err := cfg.DbConfig.DB.Exec(query, result, err := cfg.DbConfig.DB.Exec(query,
model.Key.GetPKIXPublicKeyBytes(), model.Key.GetPKIXPublicKeyBytes(),
model.RoutingEntries) model.RoutingEntries)
@ -54,7 +87,7 @@ func (cfg *SelfInfoDBConfig) Add(model *core.SelfInfoDB) (_ sql.Result, err erro
return result, nil return result, nil
} }
func (cfg *SelfInfoDBConfig) Update(model *core.SelfInfoDB) (err error) { func (cfg *SelfInfoDBConfig) Update(model *db.SelfInfoDB) (err error) {
_, err = cfg.DbConfig.DB.Exec(`UPDATE self_info _, err = cfg.DbConfig.DB.Exec(`UPDATE self_info
SET SET
RoutingEntries = ?, RoutingEntries = ?,
@ -68,7 +101,7 @@ func (cfg *SelfInfoDBConfig) Update(model *core.SelfInfoDB) (err error) {
return nil return nil
} }
func (cfg *SelfInfoDBConfig) Remove(model *core.SelfInfoDB) (err error) { func (cfg *SelfInfoDBConfig) Remove(model *db.SelfInfoDB) (err error) {
_, err = cfg.DbConfig.DB.Exec("DELETE FROM self_info WHERE Id = ?", _, err = cfg.DbConfig.DB.Exec("DELETE FROM self_info WHERE Id = ?",
model.Id) model.Id)
if err != nil { if err != nil {
@ -77,7 +110,7 @@ func (cfg *SelfInfoDBConfig) Remove(model *core.SelfInfoDB) (err error) {
return nil return nil
} }
func (cfg *SelfInfoDBConfig) Get(model *core.SelfInfoDB) (_ *sql.Rows, err error) { func (cfg *SelfInfoDBConfig) Get(model *db.SelfInfoDB) (_ *sql.Rows, err error) {
rows, err := cfg.DbConfig.DB.Query("SELECT RoutingEntries, Key FROM self_info WHERE Id = ?", rows, err := cfg.DbConfig.DB.Query("SELECT RoutingEntries, Key FROM self_info WHERE Id = ?",
model.Id) model.Id)
if err != nil { if err != nil {

View file

@ -6,8 +6,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"github.com/yggdrasil-network/yggdrasil-go/src/core" db "github.com/yggdrasil-network/yggdrasil-go/src/db/dbConfig"
"github.com/yggdrasil-network/yggdrasil-go/src/db"
) )
type SessionInfoDBConfig struct { type SessionInfoDBConfig struct {
@ -15,21 +14,30 @@ type SessionInfoDBConfig struct {
name string name string
} }
var Name = "SessionInfo" var (
Name = "SessionInfo"
Path = ""
)
func New() (*SessionInfoDBConfig, error) { func New() (*SessionInfoDBConfig, error) {
var path string
if Path == "" {
dir, _ := os.Getwd() dir, _ := os.Getwd()
fileName := fmt.Sprintf("%s.db", Name) fileName := fmt.Sprintf("%s.db", Name)
filePath := filepath.Join(dir, fileName) path = filepath.Join(dir, fileName)
} else {
path = Path
}
schemas := []string{ schemas := []string{
`CREATE TABLE IF NOT EXISTS session_info ( `CREATE TABLE IF NOT EXISTS session_info (
Id INTEGER NOT NULL PRIMARY KEY, Id INTEGER NOT NULL PRIMARY KEY,
Key BLOB, Key BLOB,
RXBytes INTEGER, RXBytes INTEGER,
TXBytes INTEGER, TXBytes INTEGER,
Duration INTEGER Duration INTEGER,
DateTime TEXT
);`} );`}
dbcfg, err := db.New("sqlite3", &schemas, filePath) dbcfg, err := db.New("sqlite3", &schemas, path)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -40,8 +48,33 @@ func New() (*SessionInfoDBConfig, error) {
return cfg, nil return cfg, nil
} }
func (cfg *SessionInfoDBConfig) Add(model *core.SessionInfoDB) (_ sql.Result, err error) { func Open() (*SessionInfoDBConfig, error) {
query := "INSERT INTO session_info (Key, RXBytes, TXBytes, Duration) VALUES (?, ?, ?, ?)" var path string
if Path == "" {
dir, _ := os.Getwd()
fileName := fmt.Sprintf("%s.db", Name)
path = filepath.Join(dir, fileName)
} else {
path = Path
}
dbcfg, err := db.OpenIfExist("sqlite3", path)
if err != nil {
return nil, err
}
cfg := &SessionInfoDBConfig{
name: Name,
DbConfig: dbcfg,
}
return cfg, nil
}
func (cfg *SessionInfoDBConfig) Add(model *db.SessionInfoDB) (_ sql.Result, err error) {
query := `
INSERT INTO
session_info
(Key, RXBytes, TXBytes, Duration, DateTime)
VALUES
(?, ?, ?, ?, datetime('now'))`
result, err := cfg.DbConfig.DB.Exec(query, result, err := cfg.DbConfig.DB.Exec(query,
model.Key.GetPKIXPublicKeyBytes(), model.Key.GetPKIXPublicKeyBytes(),
model.RXBytes, model.RXBytes,
@ -59,7 +92,7 @@ func (cfg *SessionInfoDBConfig) Add(model *core.SessionInfoDB) (_ sql.Result, er
return result, nil return result, nil
} }
func (cfg *SessionInfoDBConfig) Remove(model *core.SessionInfoDB) (err error) { func (cfg *SessionInfoDBConfig) Remove(model *db.SessionInfoDB) (err error) {
_, err = cfg.DbConfig.DB.Exec("DELETE FROM session_info WHERE Id = ?", _, err = cfg.DbConfig.DB.Exec("DELETE FROM session_info WHERE Id = ?",
model.Id) model.Id)
if err != nil { if err != nil {
@ -68,7 +101,7 @@ func (cfg *SessionInfoDBConfig) Remove(model *core.SessionInfoDB) (err error) {
return nil return nil
} }
func (cfg *SessionInfoDBConfig) Update(model *core.SessionInfoDB) (err error) { func (cfg *SessionInfoDBConfig) Update(model *db.SessionInfoDB) (err error) {
_, err = cfg.DbConfig.DB.Exec(`UPDATE session_info _, err = cfg.DbConfig.DB.Exec(`UPDATE session_info
SET SET
RXBytes = RXBytes + ?, RXBytes = RXBytes + ?,
@ -84,7 +117,7 @@ func (cfg *SessionInfoDBConfig) Update(model *core.SessionInfoDB) (err error) {
return nil return nil
} }
func (cfg *SessionInfoDBConfig) Get(model *core.SessionInfoDB) (_ *sql.Rows, err error) { func (cfg *SessionInfoDBConfig) Get(model *db.SessionInfoDB) (_ *sql.Rows, err error) {
rows, err := cfg.DbConfig.DB.Query("SELECT RXBytes, TXBytes, Duration, Key FROM session_info WHERE Id = ?", rows, err := cfg.DbConfig.DB.Query("SELECT RXBytes, TXBytes, Duration, Key FROM session_info WHERE Id = ?",
model.Id, model.Id,
) )

View file

@ -6,8 +6,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"github.com/yggdrasil-network/yggdrasil-go/src/core" db "github.com/yggdrasil-network/yggdrasil-go/src/db/dbConfig"
"github.com/yggdrasil-network/yggdrasil-go/src/db"
) )
type TreeEntryInfoDBConfig struct { type TreeEntryInfoDBConfig struct {
@ -15,20 +14,30 @@ type TreeEntryInfoDBConfig struct {
name string name string
} }
var Name = "TreeEntryInfo" var (
Name = "TreeEntryInfo"
Path = ""
)
func New() (*TreeEntryInfoDBConfig, error) { func New() (*TreeEntryInfoDBConfig, error) {
var path string
if Path == "" {
dir, _ := os.Getwd() dir, _ := os.Getwd()
fileName := fmt.Sprintf("%s.db", Name) fileName := fmt.Sprintf("%s.db", Name)
filePath := filepath.Join(dir, fileName) path = filepath.Join(dir, fileName)
} else {
path = Path
}
schemas := []string{ schemas := []string{
`CREATE TABLE IF NOT EXISTS tree_entry_info ( `CREATE TABLE IF NOT EXISTS tree_entry_info (
Id INTEGER NOT NULL PRIMARY KEY, Id INTEGER NOT NULL PRIMARY KEY,
Key BLOB, Key BLOB,
Parent BLOB, Parent BLOB,
Sequence INTEGER Sequence INTEGER,
TreeId INTEGER NULL,
DateTime TEXT
);`} );`}
dbcfg, err := db.New("sqlite3", &schemas, filePath) dbcfg, err := db.New("sqlite3", &schemas, path)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -39,12 +48,42 @@ func New() (*TreeEntryInfoDBConfig, error) {
return cfg, nil return cfg, nil
} }
func (cfg *TreeEntryInfoDBConfig) Add(model *core.TreeEntryInfoDB) (_ sql.Result, err error) { func Open() (*TreeEntryInfoDBConfig, error) {
query := "INSERT INTO tree_entry_info (Key, Parent, Sequence) VALUES (?, ?, ?)" var path string
if Path == "" {
dir, _ := os.Getwd()
fileName := fmt.Sprintf("%s.db", Name)
path = filepath.Join(dir, fileName)
} else {
path = Path
}
dbcfg, err := db.OpenIfExist("sqlite3", path)
if err != nil {
return nil, err
}
cfg := &TreeEntryInfoDBConfig{
name: Name,
DbConfig: dbcfg,
}
return cfg, nil
}
func (cfg *TreeEntryInfoDBConfig) Add(model *db.TreeEntryInfoDB) (_ sql.Result, err error) {
query := `
INSERT INTO
tree_entry_info
(Key, Parent, Sequence, TreeId, DateTime)
VALUES
(?, ?, ?, ?, datetime('now'))`
/*var _id sql.NullInt32 = sql.NullInt32{}
if model.TreeId != 0 {
_id = sql.NullInt32{Int32: int32(model.TreeId), Valid: true}
}*/
result, err := cfg.DbConfig.DB.Exec(query, result, err := cfg.DbConfig.DB.Exec(query,
model.Key.GetPKIXPublicKeyBytes(), model.Key.GetPKIXPublicKeyBytes(),
model.Parent.GetPKIXPublicKeyBytes(), model.Parent.GetPKIXPublicKeyBytes(),
model.Sequence, model.Sequence,
model.TreeId,
) )
if err != nil { if err != nil {
return nil, err return nil, err
@ -57,7 +96,7 @@ func (cfg *TreeEntryInfoDBConfig) Add(model *core.TreeEntryInfoDB) (_ sql.Result
return result, nil return result, nil
} }
func (cfg *TreeEntryInfoDBConfig) Remove(model *core.TreeEntryInfoDB) (err error) { func (cfg *TreeEntryInfoDBConfig) Remove(model *db.TreeEntryInfoDB) (err error) {
_, err = cfg.DbConfig.DB.Exec("DELETE FROM tree_entry_info WHERE Id = ?", _, err = cfg.DbConfig.DB.Exec("DELETE FROM tree_entry_info WHERE Id = ?",
model.Id) model.Id)
if err != nil { if err != nil {
@ -66,23 +105,28 @@ func (cfg *TreeEntryInfoDBConfig) Remove(model *core.TreeEntryInfoDB) (err error
return nil return nil
} }
func (cfg *TreeEntryInfoDBConfig) Update(model *core.TreeEntryInfoDB) (err error) { func (cfg *TreeEntryInfoDBConfig) Update(model *db.TreeEntryInfoDB) (err error) {
/*var _id sql.NullInt32 = sql.NullInt32{}
if model.TreeId != 0 {
_id = sql.NullInt32{Int32: int32(model.TreeId), Valid: true}
}*/
_, err = cfg.DbConfig.DB.Exec(`UPDATE tree_entry_info _, err = cfg.DbConfig.DB.Exec(`UPDATE tree_entry_info
SET SET
Sequence = ?, Sequence = ?,
Key = ?, Key = ?,
Parent = ? Parent = ?,
TreeId = ?
WHERE WHERE
Id = ?`, Id = ?`,
model.Sequence, model.Key.GetPKIXPublicKeyBytes(), model.Parent.GetPKIXPublicKeyBytes(), model.Id) model.Sequence, model.Key.GetPKIXPublicKeyBytes(), model.Parent.GetPKIXPublicKeyBytes(), model.TreeId, model.Id)
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
func (cfg *TreeEntryInfoDBConfig) Get(model *core.TreeEntryInfoDB) (_ *sql.Rows, err error) { func (cfg *TreeEntryInfoDBConfig) Get(model *db.TreeEntryInfoDB) (_ *sql.Rows, err error) {
rows, err := cfg.DbConfig.DB.Query("SELECT Sequence, Key, Parent FROM tree_entry_info WHERE Id = ?", rows, err := cfg.DbConfig.DB.Query("SELECT Sequence, Key, Parent, TreeId FROM tree_entry_info WHERE Id = ?",
model.Id, model.Id,
) )
if err != nil { if err != nil {
@ -91,11 +135,17 @@ func (cfg *TreeEntryInfoDBConfig) Get(model *core.TreeEntryInfoDB) (_ *sql.Rows,
defer rows.Close() defer rows.Close()
var _key []byte var _key []byte
var _path []byte var _path []byte
var _id sql.NullInt32
for rows.Next() { for rows.Next() {
err = rows.Scan(&model.Sequence, &_key, &_path) err = rows.Scan(&model.Sequence, &_key, &_path, &_id)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if _id.Valid {
model.TreeId = int(_id.Int32)
} else {
model.TreeId = 0
}
model.Key.ParsePKIXPublicKey(&_key) model.Key.ParsePKIXPublicKey(&_key)
model.Parent.ParsePKIXPublicKey(&_path) model.Parent.ParsePKIXPublicKey(&_path)
} }

334
src/db/database.go Normal file
View file

@ -0,0 +1,334 @@
package database
import (
"context"
"path/filepath"
"time"
"github.com/yggdrasil-network/yggdrasil-go/src/core"
pathentryinfodb "github.com/yggdrasil-network/yggdrasil-go/src/db/PathEntryInfoDB"
peerinfodb "github.com/yggdrasil-network/yggdrasil-go/src/db/PeerInfoDB"
selfinfodb "github.com/yggdrasil-network/yggdrasil-go/src/db/SelfInfoDB"
sessioninfodb "github.com/yggdrasil-network/yggdrasil-go/src/db/SessionInfoDB"
treeentryinfodb "github.com/yggdrasil-network/yggdrasil-go/src/db/TreeEntryInfoDB"
dbConfig "github.com/yggdrasil-network/yggdrasil-go/src/db/dbConfig"
)
type databaseConfig struct {
treeentryinfodb treeentryinfodb.TreeEntryInfoDBConfig
sessioninfodb sessioninfodb.SessionInfoDBConfig
selfInfoDBConfig selfinfodb.SelfInfoDBConfig
pathEntryInfoDBConfig pathentryinfodb.PathEntryInfoDBConfig
peerInfoDBConfig peerinfodb.PeerInfoDBConfig
ticker *time.Ticker
Api *core.Core
Logger core.Logger
}
var (
path = ""
Timer = 5
)
func (db *databaseConfig) CreateTimer(ctx context.Context) {
db.ticker = time.NewTicker(time.Duration(Timer) * time.Minute)
go func() {
defer db.ticker.Stop()
for {
select {
case <-ctx.Done():
db.Logger.Infoln("Timer is stopped")
_ = db.CloseDb()
case <-db.ticker.C:
db._backUpData()
}
}
}()
}
func (db *databaseConfig) OnListen(ctx context.Context) {
db.ticker = time.NewTicker(time.Duration(Timer) * time.Minute)
go func() {
defer db.ticker.Stop()
sessions := make(map[string]core.SessionInfo)
peers := make(map[string]core.PeerInfo)
paths := make(map[string]core.PathEntryInfo)
for {
{
APIsessions := db.Api.GetMappedSessions()
APIpaths := db.Api.GetMappedPaths()
for key, session := range APIsessions {
if _, exist := sessions[key]; !exist {
db._pathCallBack(APIpaths[key])
db._sessionCallBack(session)
}
paths[key] = APIpaths[key]
sessions[key] = session
}
for key := range sessions {
if _, exist := APIsessions[key]; !exist {
db._pathCallBack(APIpaths[key])
db._sessionCallBack(sessions[key])
delete(sessions, key)
delete(paths, key)
}
}
}
{
APIpeers := db.Api.GetMappedPeers()
for key, peer := range APIpeers {
if _, exist := peers[key]; !exist {
db._peerCallBack(peer)
}
peers[key] = peer
}
for key := range peers {
if _, exist := APIpeers[key]; !exist {
db._peerCallBack(peers[key])
delete(peers, key)
}
}
}
select {
case <-ctx.Done():
_ = db.CloseDb()
case <-db.ticker.C:
db._sessionBackUp(sessions)
db._peerBackUp(peers)
db._papthBackUp(paths)
}
}
}()
}
func (db *databaseConfig) _sessionBackUp(sessions map[string]core.SessionInfo) {
for _, session := range sessions {
entity, err := dbConfig.NewSessionInfoDB(session)
if err != nil {
db.Logger.Errorf("Error creating SessionInfoDB: %v\n", err)
return
}
_, err = db.sessioninfodb.Add(entity)
if err != nil {
db.Logger.Errorf("Error saving SessionInfoDB: %v\n", err)
return
}
}
}
func (db *databaseConfig) _peerBackUp(peers map[string]core.PeerInfo) {
for _, peer := range peers {
entity, err := dbConfig.NewPeerInfoDB(peer)
if err != nil {
db.Logger.Errorf("Error creating PeerInfoDB: %v\n", err)
return
}
_, err = db.peerInfoDBConfig.Add(entity)
if err != nil {
db.Logger.Errorf("Error saving PeerInfoDB: %v\n", err)
return
}
}
}
func (db *databaseConfig) _papthBackUp(paths map[string]core.PathEntryInfo) {
for _, path := range paths {
entity, err := dbConfig.NewPathEntryInfoDB(path)
if err != nil {
db.Logger.Errorf("Error creating PathInfoDB: %v\n", err)
return
}
_, err = db.pathEntryInfoDBConfig.Add(entity)
if err != nil {
db.Logger.Errorf("Error saving PathInfoDB: %v\n", err)
return
}
}
}
func (db *databaseConfig) _sessionCallBack(session core.SessionInfo) {
entity, err := dbConfig.NewSessionInfoDB(session)
if err != nil {
db.Logger.Errorf("Error creating SessionInfoDB: %v\n", err)
return
}
_, err = db.sessioninfodb.Add(entity)
if err != nil {
db.Logger.Errorf("Error saving SessionInfoDB: %v\n", err)
return
}
}
func (db *databaseConfig) _peerCallBack(peer core.PeerInfo) {
entity, err := dbConfig.NewPeerInfoDB(peer)
if err != nil {
db.Logger.Errorf("Error creating PeerInfoDB: %v\n", err)
return
}
_, err = db.peerInfoDBConfig.Add(entity)
if err != nil {
db.Logger.Errorf("Error saving PeerInfoDB: %v\n", err)
return
}
}
func (db *databaseConfig) _pathCallBack(path core.PathEntryInfo) {
entity, err := dbConfig.NewPathEntryInfoDB(path)
if err != nil {
db.Logger.Errorf("Error creating PathInfoDB: %v\n", err)
return
}
_, err = db.pathEntryInfoDBConfig.Add(entity)
if err != nil {
db.Logger.Errorf("Error saving PathInfoDB: %v\n", err)
return
}
}
func (db *databaseConfig) _backUpData() {
db.Logger.Infoln("Backup started")
{
selfinfo := db.Api.GetSelf()
entity, _ := dbConfig.NewSelfInfoDB(selfinfo)
db.selfInfoDBConfig.Add(entity)
}
{
trees := db.Api.GetTree()
id := uniqueId()
for _, tree := range trees {
entity, err := dbConfig.NewTreeEntryInfoDB(tree)
entity.TreeId = id
if err != nil {
db.Logger.Errorln("Error creating TreeEntryInfoDB: %v\n", err)
continue
}
db.treeentryinfodb.Add(entity)
}
}
db.Logger.Infoln("Backup completed.")
}
func OpenExistDb(log core.Logger, core *core.Core) (_ *databaseConfig, err error) {
if path != "" {
path = addExtensionIfNotExist(path)
}
treeentryinfodb.Path = path
sessioninfodb.Path = path
pathentryinfodb.Path = path
selfinfodb.Path = path
peerinfodb.Path = path
treeentrydb, err := treeentryinfodb.Open()
if err != nil {
return nil, err
}
sessiondb, err := sessioninfodb.Open()
if err != nil {
return nil, err
}
pathentry, err := pathentryinfodb.Open()
if err != nil {
return nil, err
}
selfinfodb, err := selfinfodb.Open()
if err != nil {
return nil, err
}
peerinfodb, err := peerinfodb.Open()
if err != nil {
return nil, err
}
db := &databaseConfig{
treeentryinfodb: *treeentrydb,
sessioninfodb: *sessiondb,
selfInfoDBConfig: *selfinfodb,
pathEntryInfoDBConfig: *pathentry,
peerInfoDBConfig: *peerinfodb,
}
db.Logger = log
db.Api = core
return db, nil
}
func (db *databaseConfig) CloseDb() (errs []error) {
err := db.treeentryinfodb.DbConfig.CloseDb()
if err != nil {
errs = append(errs, err)
}
err = db.sessioninfodb.DbConfig.CloseDb()
if err != nil {
errs = append(errs, err)
}
err = db.selfInfoDBConfig.DbConfig.CloseDb()
if err != nil {
errs = append(errs, err)
}
err = db.pathEntryInfoDBConfig.DbConfig.CloseDb()
if err != nil {
errs = append(errs, err)
}
err = db.peerInfoDBConfig.DbConfig.CloseDb()
if err != nil {
errs = append(errs, err)
}
return errs
}
func CreateDb(log core.Logger, core *core.Core) (_ *databaseConfig, err error) {
if path != "" {
path = addExtensionIfNotExist(path)
}
treeentryinfodb.Path = path
sessioninfodb.Path = path
pathentryinfodb.Path = path
selfinfodb.Path = path
peerinfodb.Path = path
treeentrydb, err := treeentryinfodb.New()
if err != nil {
return nil, err
}
sessiondb, err := sessioninfodb.New()
if err != nil {
return nil, err
}
pathentry, err := pathentryinfodb.New()
if err != nil {
return nil, err
}
selfinfodb, err := selfinfodb.New()
if err != nil {
return nil, err
}
peerinfodb, err := peerinfodb.New()
if err != nil {
return nil, err
}
db := &databaseConfig{
treeentryinfodb: *treeentrydb,
sessioninfodb: *sessiondb,
selfInfoDBConfig: *selfinfodb,
pathEntryInfoDBConfig: *pathentry,
peerInfoDBConfig: *peerinfodb,
}
db.Logger = log
db.Api = core
return db, nil
}
func addExtensionIfNotExist(fileName string) string {
if !withExtension(fileName) {
return addExtension(fileName)
}
return fileName
}
func withExtension(filePath string) bool {
ext := filepath.Ext(filePath)
return ext != ""
}
func addExtension(fileName string) string {
return fileName + ".db"
}
func uniqueId() int {
return int(time.Now().Unix())
}

View file

@ -1,4 +1,4 @@
package core package db
import ( import (
"bytes" "bytes"
@ -8,10 +8,12 @@ import (
"encoding/binary" "encoding/binary"
"errors" "errors"
"fmt" "fmt"
"github.com/yggdrasil-network/yggdrasil-go/src/core"
) )
type PeerInfoDB struct { type PeerInfoDB struct {
PeerInfo core.PeerInfo
Id int Id int
Coords Blob Coords Blob
Key PublicKeyContainer Key PublicKeyContainer
@ -21,32 +23,33 @@ type PeerInfoDB struct {
} }
type SelfInfoDB struct { type SelfInfoDB struct {
SelfInfo core.SelfInfo
Id int Id int
Key PublicKeyContainer Key PublicKeyContainer
} }
type TreeEntryInfoDB struct { type TreeEntryInfoDB struct {
TreeEntryInfo core.TreeEntryInfo
Id int Id int
Key PublicKeyContainer Key PublicKeyContainer
Parent PublicKeyContainer Parent PublicKeyContainer
TreeId int
} }
type PathEntryInfoDB struct { type PathEntryInfoDB struct {
PathEntryInfo core.PathEntryInfo
Id int Id int
Key PublicKeyContainer Key PublicKeyContainer
Path Blob Path Blob
} }
type SessionInfoDB struct { type SessionInfoDB struct {
SessionInfo core.SessionInfo
Id int Id int
Key PublicKeyContainer Key PublicKeyContainer
} }
func NewPeerInfoDB(peerInfo PeerInfo) (_ *PeerInfoDB, err error) { func NewPeerInfoDB(peerInfo core.PeerInfo) (_ *PeerInfoDB, err error) {
peer := &PeerInfoDB{ peer := &PeerInfoDB{
PeerInfo: peerInfo, PeerInfo: peerInfo,
} }
@ -81,7 +84,7 @@ func NewPeerInfoDB(peerInfo PeerInfo) (_ *PeerInfoDB, err error) {
return peer, nil return peer, nil
} }
func NewSelfInfoDB(selfinfo SelfInfo) (_ *SelfInfoDB, err error) { func NewSelfInfoDB(selfinfo core.SelfInfo) (_ *SelfInfoDB, err error) {
model := &SelfInfoDB{ model := &SelfInfoDB{
SelfInfo: selfinfo, SelfInfo: selfinfo,
} }
@ -96,7 +99,7 @@ func NewSelfInfoDB(selfinfo SelfInfo) (_ *SelfInfoDB, err error) {
return model, nil return model, nil
} }
func NewTreeEntryInfoDB(treeEntyInfo TreeEntryInfo) (_ *TreeEntryInfoDB, err error) { func NewTreeEntryInfoDB(treeEntyInfo core.TreeEntryInfo) (_ *TreeEntryInfoDB, err error) {
model := &TreeEntryInfoDB{ model := &TreeEntryInfoDB{
TreeEntryInfo: treeEntyInfo, TreeEntryInfo: treeEntyInfo,
} }
@ -110,10 +113,11 @@ func NewTreeEntryInfoDB(treeEntyInfo TreeEntryInfo) (_ *TreeEntryInfoDB, err err
} }
publicKey = model.Parent.GetPKIXPublicKey() publicKey = model.Parent.GetPKIXPublicKey()
model.Parent.MarshalPKIXPublicKey(&publicKey) model.Parent.MarshalPKIXPublicKey(&publicKey)
model.TreeId = 0
return model, nil return model, nil
} }
func NewPathEntryInfoDB(PathEntryInfo PathEntryInfo) (_ *PathEntryInfoDB, err error) { func NewPathEntryInfoDB(PathEntryInfo core.PathEntryInfo) (_ *PathEntryInfoDB, err error) {
model := &PathEntryInfoDB{ model := &PathEntryInfoDB{
PathEntryInfo: PathEntryInfo, PathEntryInfo: PathEntryInfo,
} }
@ -130,7 +134,7 @@ func NewPathEntryInfoDB(PathEntryInfo PathEntryInfo) (_ *PathEntryInfoDB, err er
return model, nil return model, nil
} }
func NewSessionInfoDB(SessionInfo SessionInfo) (_ *SessionInfoDB, err error) { func NewSessionInfoDB(SessionInfo core.SessionInfo) (_ *SessionInfoDB, err error) {
model := &SessionInfoDB{ model := &SessionInfoDB{
SessionInfo: SessionInfo, SessionInfo: SessionInfo,
} }

View file

@ -2,6 +2,8 @@ package db
import ( import (
"database/sql" "database/sql"
"errors"
"fmt"
"os" "os"
"path" "path"
) )
@ -21,6 +23,7 @@ func New(driver string, schemas *[]string, uri string) (*DbConfig, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
fmt.Println(uri)
cfg := &DbConfig{ cfg := &DbConfig{
DB: db, DB: db,
Uri: uri, Uri: uri,
@ -30,6 +33,25 @@ func New(driver string, schemas *[]string, uri string) (*DbConfig, error) {
return cfg, nil return cfg, nil
} }
func OpenIfExist(driver string, uri string) (*DbConfig, error) {
name := path.Base(uri)
cfg := &DbConfig{
Uri: uri,
Name: name,
Driver: driver,
}
fmt.Print(uri)
IsExist := cfg.DBIsExist()
if !IsExist {
return nil, errors.New("database does not exist")
}
err := cfg.OpenDb()
if !IsExist {
return nil, err
}
return cfg, nil
}
func initDB(driver string, schemas *[]string, uri string) (*sql.DB, error) { func initDB(driver string, schemas *[]string, uri string) (*sql.DB, error) {
database, err := sql.Open(driver, uri) database, err := sql.Open(driver, uri)
if err != nil { if err != nil {

View file

@ -16,13 +16,14 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/yggdrasil-network/yggdrasil-go/src/core" "github.com/yggdrasil-network/yggdrasil-go/src/core"
peerinfodb "github.com/yggdrasil-network/yggdrasil-go/src/db/PeerInfoDB" peerinfodb "github.com/yggdrasil-network/yggdrasil-go/src/db/PeerInfoDB"
db "github.com/yggdrasil-network/yggdrasil-go/src/db/dbConfig"
) )
func TestPeerGetCoords(t *testing.T) { func TestPeerGetCoords(t *testing.T) {
peerinfo := core.PeerInfo{ peerinfo := core.PeerInfo{
Coords: []uint64{1, 2, 3, 4}, Coords: []uint64{1, 2, 3, 4},
} }
peer, err := core.NewPeerInfoDB(peerinfo) peer, err := db.NewPeerInfoDB(peerinfo)
require.NoError(t, err) require.NoError(t, err)
target := []byte{1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0} target := []byte{1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0}
@ -34,7 +35,7 @@ func TestPeerGetCoords(t *testing.T) {
func TestPeerSetCoords(t *testing.T) { func TestPeerSetCoords(t *testing.T) {
peerinfo := core.PeerInfo{} peerinfo := core.PeerInfo{}
peer, err := core.NewPeerInfoDB(peerinfo) peer, err := db.NewPeerInfoDB(peerinfo)
require.NoError(t, err) require.NoError(t, err)
peer.Coords.ParseByteSliсe([]byte{4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}) peer.Coords.ParseByteSliсe([]byte{4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0})
require.NoError(t, err) require.NoError(t, err)
@ -72,7 +73,7 @@ func TestAddPeer(t *testing.T) {
Uptime: 3600, Uptime: 3600,
Latency: 50.0, Latency: 50.0,
} }
peer, err := core.NewPeerInfoDB(peerinfo) peer, err := db.NewPeerInfoDB(peerinfo)
require.NoError(t, err) require.NoError(t, err)
mock.ExpectExec("INSERT OR REPLACE INTO peer_infos"). mock.ExpectExec("INSERT OR REPLACE INTO peer_infos").
@ -130,7 +131,7 @@ func TestRemovePeer(t *testing.T) {
Uptime: 3600, Uptime: 3600,
Latency: 50.0, Latency: 50.0,
} }
peer, err := core.NewPeerInfoDB(peerinfo) peer, err := db.NewPeerInfoDB(peerinfo)
require.NoError(t, err) require.NoError(t, err)
mock.ExpectExec("DELETE FROM peer_infos WHERE Id = \\?"). mock.ExpectExec("DELETE FROM peer_infos WHERE Id = \\?").
@ -174,7 +175,7 @@ func TestGetPeer(t *testing.T) {
Uptime: 3600, Uptime: 3600,
Latency: 50.0, Latency: 50.0,
} }
peer, err := core.NewPeerInfoDB(peerinfo) peer, err := db.NewPeerInfoDB(peerinfo)
require.NoError(t, err) require.NoError(t, err)
rows := sqlmock.NewRows([]string{"up", "inbound", "last_error", "last_error_time", "coords", rows := sqlmock.NewRows([]string{"up", "inbound", "last_error", "last_error_time", "coords",
@ -223,7 +224,7 @@ func TestUpdatePeer(t *testing.T) {
Uptime: 3600, Uptime: 3600,
Latency: 50.0, Latency: 50.0,
} }
peer, err := core.NewPeerInfoDB(peerinfo) peer, err := db.NewPeerInfoDB(peerinfo)
require.NoError(t, err) require.NoError(t, err)
mock.ExpectExec(`UPDATE peer_infos mock.ExpectExec(`UPDATE peer_infos
SET SET
@ -292,7 +293,7 @@ func TestMain(t *testing.T) {
Uptime: 3600, Uptime: 3600,
Latency: 50.0, Latency: 50.0,
} }
peer, err := core.NewPeerInfoDB(peerinfo) peer, err := db.NewPeerInfoDB(peerinfo)
require.NoError(t, err) require.NoError(t, err)
root2PubKey, _, err := ed25519.GenerateKey(rand.Reader) root2PubKey, _, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err) require.NoError(t, err)
@ -312,7 +313,7 @@ func TestMain(t *testing.T) {
Uptime: 3600, Uptime: 3600,
Latency: 50.0, Latency: 50.0,
} }
peer2, err := core.NewPeerInfoDB(peerinfo2) peer2, err := db.NewPeerInfoDB(peerinfo2)
require.NoError(t, err) require.NoError(t, err)
_, err = peerdb.Add(peer) _, err = peerdb.Add(peer)
require.NoError(t, err) require.NoError(t, err)

View file

@ -13,6 +13,7 @@ import (
"github.com/yggdrasil-network/yggdrasil-go/src/core" "github.com/yggdrasil-network/yggdrasil-go/src/core"
pathentryinfodb "github.com/yggdrasil-network/yggdrasil-go/src/db/PathEntryInfoDB" pathentryinfodb "github.com/yggdrasil-network/yggdrasil-go/src/db/PathEntryInfoDB"
db "github.com/yggdrasil-network/yggdrasil-go/src/db/dbConfig"
) )
func TestSelectPathEntryInfo(t *testing.T) { func TestSelectPathEntryInfo(t *testing.T) {
@ -32,7 +33,7 @@ func TestSelectPathEntryInfo(t *testing.T) {
Path: []uint64{0, 0, 0}, Path: []uint64{0, 0, 0},
Sequence: 100, Sequence: 100,
} }
model, err := core.NewPathEntryInfoDB(entry) model, err := db.NewPathEntryInfoDB(entry)
require.NoError(t, err) require.NoError(t, err)
rows := sqlmock.NewRows([]string{"Sequence", "Key", "Path"}). rows := sqlmock.NewRows([]string{"Sequence", "Key", "Path"}).
@ -68,7 +69,7 @@ func TestInsertPathEntryInfo(t *testing.T) {
Path: []uint64{0, 0, 0}, Path: []uint64{0, 0, 0},
Sequence: 100, Sequence: 100,
} }
model, err := core.NewPathEntryInfoDB(entry) model, err := db.NewPathEntryInfoDB(entry)
require.NoError(t, err) require.NoError(t, err)
mock.ExpectExec("INSERT INTO path_entry_info"). mock.ExpectExec("INSERT INTO path_entry_info").
WithArgs( WithArgs(
@ -102,7 +103,7 @@ func TestDeletePathEntryInfo(t *testing.T) {
Path: []uint64{0, 0, 0}, Path: []uint64{0, 0, 0},
Sequence: 100, Sequence: 100,
} }
model, err := core.NewPathEntryInfoDB(entry) model, err := db.NewPathEntryInfoDB(entry)
require.NoError(t, err) require.NoError(t, err)
mock.ExpectExec("DELETE FROM path_entry_info WHERE Id = \\?"). mock.ExpectExec("DELETE FROM path_entry_info WHERE Id = \\?").
WithArgs( WithArgs(
@ -133,7 +134,7 @@ func TestUpdatePathEntryInfo(t *testing.T) {
Path: []uint64{0, 0, 0}, Path: []uint64{0, 0, 0},
Sequence: 100, Sequence: 100,
} }
model, err := core.NewPathEntryInfoDB(entry) model, err := db.NewPathEntryInfoDB(entry)
require.NoError(t, err) require.NoError(t, err)
mock.ExpectExec(` mock.ExpectExec(`
UPDATE path_entry_info UPDATE path_entry_info
@ -183,7 +184,7 @@ func TestMainPathEntryInfo(t *testing.T) {
Path: []uint64{0, 0, 0}, Path: []uint64{0, 0, 0},
Sequence: 100, Sequence: 100,
} }
model, err := core.NewPathEntryInfoDB(entry) model, err := db.NewPathEntryInfoDB(entry)
require.NoError(t, err) require.NoError(t, err)
secondEntry := core.PathEntryInfo{ secondEntry := core.PathEntryInfo{
@ -191,7 +192,7 @@ func TestMainPathEntryInfo(t *testing.T) {
Path: []uint64{0, 0, 0}, Path: []uint64{0, 0, 0},
Sequence: 100, Sequence: 100,
} }
secondModel, err := core.NewPathEntryInfoDB(secondEntry) secondModel, err := db.NewPathEntryInfoDB(secondEntry)
require.NoError(t, err) require.NoError(t, err)
_, err = pathentryinfodb.Add(model) _, err = pathentryinfodb.Add(model)

View file

@ -13,6 +13,7 @@ import (
"github.com/yggdrasil-network/yggdrasil-go/src/core" "github.com/yggdrasil-network/yggdrasil-go/src/core"
selfinfodb "github.com/yggdrasil-network/yggdrasil-go/src/db/SelfInfoDB" selfinfodb "github.com/yggdrasil-network/yggdrasil-go/src/db/SelfInfoDB"
db "github.com/yggdrasil-network/yggdrasil-go/src/db/dbConfig"
) )
func TestSelectSelfInfo(t *testing.T) { func TestSelectSelfInfo(t *testing.T) {
@ -30,7 +31,7 @@ func TestSelectSelfInfo(t *testing.T) {
selfinfo := core.SelfInfo{ selfinfo := core.SelfInfo{
Key: pubkey, Key: pubkey,
} }
model, err := core.NewSelfInfoDB(selfinfo) model, err := db.NewSelfInfoDB(selfinfo)
require.NoError(t, err) require.NoError(t, err)
rows := sqlmock.NewRows([]string{"RoutingEntries", "Key"}). rows := sqlmock.NewRows([]string{"RoutingEntries", "Key"}).
@ -64,7 +65,7 @@ func TestInsertSelfInfo(t *testing.T) {
selfinfo := core.SelfInfo{ selfinfo := core.SelfInfo{
Key: pubkey, Key: pubkey,
} }
model, err := core.NewSelfInfoDB(selfinfo) model, err := db.NewSelfInfoDB(selfinfo)
require.NoError(t, err) require.NoError(t, err)
mock.ExpectExec("INSERT OR REPLACE INTO self_info"). mock.ExpectExec("INSERT OR REPLACE INTO self_info").
WithArgs( WithArgs(
@ -95,7 +96,7 @@ func TestDeleteSelfInfo(t *testing.T) {
selfinfo := core.SelfInfo{ selfinfo := core.SelfInfo{
Key: pubkey, Key: pubkey,
} }
model, err := core.NewSelfInfoDB(selfinfo) model, err := db.NewSelfInfoDB(selfinfo)
require.NoError(t, err) require.NoError(t, err)
mock.ExpectExec("DELETE FROM self_info WHERE Id = \\?"). mock.ExpectExec("DELETE FROM self_info WHERE Id = \\?").
WithArgs( WithArgs(
@ -125,7 +126,7 @@ func TestUpdateSelfInfo(t *testing.T) {
Key: pubkey, Key: pubkey,
RoutingEntries: 100, RoutingEntries: 100,
} }
model, err := core.NewSelfInfoDB(selfinfo) model, err := db.NewSelfInfoDB(selfinfo)
require.NoError(t, err) require.NoError(t, err)
mock.ExpectExec(` mock.ExpectExec(`
UPDATE self_info UPDATE self_info
@ -172,14 +173,14 @@ func TestMainSelfInfo(t *testing.T) {
Key: firstKey, Key: firstKey,
RoutingEntries: 100, RoutingEntries: 100,
} }
firstModel, err := core.NewSelfInfoDB(firstSelfinfo) firstModel, err := db.NewSelfInfoDB(firstSelfinfo)
require.NoError(t, err) require.NoError(t, err)
secondSelfinfo := core.SelfInfo{ secondSelfinfo := core.SelfInfo{
Key: secondKey, Key: secondKey,
RoutingEntries: 200, RoutingEntries: 200,
} }
secondModel, err := core.NewSelfInfoDB(secondSelfinfo) secondModel, err := db.NewSelfInfoDB(secondSelfinfo)
require.NoError(t, err) require.NoError(t, err)
_, err = selfinfodb.Add(firstModel) _, err = selfinfodb.Add(firstModel)

View file

@ -13,6 +13,7 @@ import (
"github.com/yggdrasil-network/yggdrasil-go/src/core" "github.com/yggdrasil-network/yggdrasil-go/src/core"
sessioninfodb "github.com/yggdrasil-network/yggdrasil-go/src/db/SessionInfoDB" sessioninfodb "github.com/yggdrasil-network/yggdrasil-go/src/db/SessionInfoDB"
db "github.com/yggdrasil-network/yggdrasil-go/src/db/dbConfig"
) )
func TestSelectSessionInfo(t *testing.T) { func TestSelectSessionInfo(t *testing.T) {
@ -33,7 +34,7 @@ func TestSelectSessionInfo(t *testing.T) {
TXBytes: 10, TXBytes: 10,
Uptime: time.Hour, Uptime: time.Hour,
} }
model, err := core.NewSessionInfoDB(entry) model, err := db.NewSessionInfoDB(entry)
require.NoError(t, err) require.NoError(t, err)
rows := sqlmock.NewRows([]string{"RXBytes", "TXBytes", "Duration", "Key"}). rows := sqlmock.NewRows([]string{"RXBytes", "TXBytes", "Duration", "Key"}).
@ -70,7 +71,7 @@ func TestInsertSessionInfo(t *testing.T) {
TXBytes: 10, TXBytes: 10,
Uptime: time.Hour, Uptime: time.Hour,
} }
model, err := core.NewSessionInfoDB(entry) model, err := db.NewSessionInfoDB(entry)
require.NoError(t, err) require.NoError(t, err)
mock.ExpectExec("INSERT INTO session_info"). mock.ExpectExec("INSERT INTO session_info").
@ -107,7 +108,7 @@ func TestDeleteSessionInfo(t *testing.T) {
TXBytes: 10, TXBytes: 10,
Uptime: time.Hour, Uptime: time.Hour,
} }
model, err := core.NewSessionInfoDB(entry) model, err := db.NewSessionInfoDB(entry)
require.NoError(t, err) require.NoError(t, err)
mock.ExpectExec("DELETE FROM session_info WHERE Id = \\?"). mock.ExpectExec("DELETE FROM session_info WHERE Id = \\?").
WithArgs( WithArgs(
@ -139,7 +140,7 @@ func TestUpdateSessionInfo(t *testing.T) {
TXBytes: 10, TXBytes: 10,
Uptime: time.Hour, Uptime: time.Hour,
} }
model, err := core.NewSessionInfoDB(entry) model, err := db.NewSessionInfoDB(entry)
require.NoError(t, err) require.NoError(t, err)
mock.ExpectExec(` mock.ExpectExec(`
UPDATE session_info UPDATE session_info
@ -192,7 +193,7 @@ func TestMainSessionInfo(t *testing.T) {
TXBytes: 10, TXBytes: 10,
Uptime: time.Hour, Uptime: time.Hour,
} }
model, err := core.NewSessionInfoDB(entry) model, err := db.NewSessionInfoDB(entry)
require.NoError(t, err) require.NoError(t, err)
secondEntry := core.SessionInfo{ secondEntry := core.SessionInfo{
@ -201,7 +202,7 @@ func TestMainSessionInfo(t *testing.T) {
TXBytes: 10, TXBytes: 10,
Uptime: time.Hour, Uptime: time.Hour,
} }
secondModel, err := core.NewSessionInfoDB(secondEntry) secondModel, err := db.NewSessionInfoDB(secondEntry)
require.NoError(t, err) require.NoError(t, err)
_, err = sessioninfodb.Add(model) _, err = sessioninfodb.Add(model)

View file

@ -13,6 +13,7 @@ import (
"github.com/yggdrasil-network/yggdrasil-go/src/core" "github.com/yggdrasil-network/yggdrasil-go/src/core"
treeentryinfodb "github.com/yggdrasil-network/yggdrasil-go/src/db/TreeEntryInfoDB" treeentryinfodb "github.com/yggdrasil-network/yggdrasil-go/src/db/TreeEntryInfoDB"
db "github.com/yggdrasil-network/yggdrasil-go/src/db/dbConfig"
) )
func TestSelectTreeEntryInfo(t *testing.T) { func TestSelectTreeEntryInfo(t *testing.T) {
@ -32,11 +33,11 @@ func TestSelectTreeEntryInfo(t *testing.T) {
Parent: pubkey, Parent: pubkey,
Sequence: 10, Sequence: 10,
} }
model, err := core.NewTreeEntryInfoDB(entry) model, err := db.NewTreeEntryInfoDB(entry)
require.NoError(t, err) require.NoError(t, err)
rows := sqlmock.NewRows([]string{"Sequence", "Key", "Parent"}). rows := sqlmock.NewRows([]string{"Sequence", "Key", "Parent", "TreeId"}).
AddRow(100, model.Key.GetPKIXPublicKeyBytes(), model.Parent.GetPKIXPublicKeyBytes()) AddRow(100, model.Key.GetPKIXPublicKeyBytes(), model.Parent.GetPKIXPublicKeyBytes(), 1)
mock.ExpectQuery("SELECT (.+) FROM tree_entry_info WHERE Id = \\?"). mock.ExpectQuery("SELECT (.+) FROM tree_entry_info WHERE Id = \\?").
WithArgs(model.Id). WithArgs(model.Id).
@ -68,7 +69,7 @@ func TestInsertTreeEntryInfo(t *testing.T) {
Parent: pubkey, Parent: pubkey,
Sequence: 10, Sequence: 10,
} }
model, err := core.NewTreeEntryInfoDB(entry) model, err := db.NewTreeEntryInfoDB(entry)
require.NoError(t, err) require.NoError(t, err)
mock.ExpectExec("INSERT INTO tree_entry_info"). mock.ExpectExec("INSERT INTO tree_entry_info").
@ -76,6 +77,7 @@ func TestInsertTreeEntryInfo(t *testing.T) {
model.Key.GetPKIXPublicKeyBytes(), model.Key.GetPKIXPublicKeyBytes(),
model.Parent.GetPKIXPublicKeyBytes(), model.Parent.GetPKIXPublicKeyBytes(),
model.Sequence, model.Sequence,
model.TreeId,
). ).
WillReturnResult(sqlmock.NewResult(1, 1)) WillReturnResult(sqlmock.NewResult(1, 1))
@ -103,7 +105,7 @@ func TestDeleteTreeEntryInfo(t *testing.T) {
Parent: pubkey, Parent: pubkey,
Sequence: 10, Sequence: 10,
} }
model, err := core.NewTreeEntryInfoDB(entry) model, err := db.NewTreeEntryInfoDB(entry)
require.NoError(t, err) require.NoError(t, err)
mock.ExpectExec("DELETE FROM tree_entry_info WHERE Id = \\?"). mock.ExpectExec("DELETE FROM tree_entry_info WHERE Id = \\?").
WithArgs( WithArgs(
@ -134,20 +136,22 @@ func TestUpdateTreeEntryInfo(t *testing.T) {
Parent: pubkey, Parent: pubkey,
Sequence: 10, Sequence: 10,
} }
model, err := core.NewTreeEntryInfoDB(entry) model, err := db.NewTreeEntryInfoDB(entry)
require.NoError(t, err) require.NoError(t, err)
mock.ExpectExec(` mock.ExpectExec(`
UPDATE tree_entry_info UPDATE tree_entry_info
SET SET
Sequence = \?, Sequence = \?,
Key = \?, Key = \?,
Parent = \? Parent = \?,
TreeId = \?
WHERE WHERE
Id = \?`). Id = \?`).
WithArgs( WithArgs(
model.Sequence, model.Sequence,
model.Key.GetPKIXPublicKeyBytes(), model.Key.GetPKIXPublicKeyBytes(),
model.Parent.GetPKIXPublicKeyBytes(), model.Parent.GetPKIXPublicKeyBytes(),
model.TreeId,
model.Id, model.Id,
).WillReturnResult(sqlmock.NewResult(1, 1)) ).WillReturnResult(sqlmock.NewResult(1, 1))
@ -184,7 +188,7 @@ func TestMainTreeEntryInfo(t *testing.T) {
Parent: pubkey, Parent: pubkey,
Sequence: 10, Sequence: 10,
} }
model, err := core.NewTreeEntryInfoDB(entry) model, err := db.NewTreeEntryInfoDB(entry)
require.NoError(t, err) require.NoError(t, err)
secondEntry := core.TreeEntryInfo{ secondEntry := core.TreeEntryInfo{
@ -192,7 +196,7 @@ func TestMainTreeEntryInfo(t *testing.T) {
Parent: secondPubKey, Parent: secondPubKey,
Sequence: 20, Sequence: 20,
} }
secondModel, err := core.NewTreeEntryInfoDB(secondEntry) secondModel, err := db.NewTreeEntryInfoDB(secondEntry)
require.NoError(t, err) require.NoError(t, err)
_, err = treeentryinfodb.Add(model) _, err = treeentryinfodb.Add(model)