mirror of
https://github.com/netbirdio/netbird.git
synced 2026-09-01 04:21:29 +02:00
113 lines
2.6 KiB
Go
113 lines
2.6 KiB
Go
package networkmapdb
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"encoding/json"
|
|
"errors"
|
|
"reflect"
|
|
"strings"
|
|
|
|
"github.com/netbirdio/netbird/shared/management/networkmap/nmdata"
|
|
)
|
|
|
|
const (
|
|
NMAP_STRUCT_TAG = "nmap"
|
|
NMAP_SKIP = "skip"
|
|
NMAP_MAP_TO = "map_to"
|
|
)
|
|
|
|
type NetworkMapDBStore interface {
|
|
GetGroups(ctx context.Context, accountId string) ([]nmdata.Group, error) // TODO: join/populate peers
|
|
GetPeers(ctx context.Context, accountId string) ([]nmdata.Peer, error)
|
|
GetPolicies(ctx context.Context, accountId string) ([]nmdata.Policy, error)
|
|
GetRoutes(ctx context.Context, accountId string) ([]nmdata.Route, error)
|
|
}
|
|
|
|
type NetworkMapDBStoreImpl struct {
|
|
store NetworkMapDBStore
|
|
}
|
|
|
|
func FromSqlTypesToSharedTypes(src reflect.Value, dst reflect.Value) error {
|
|
typ := src.Type()
|
|
|
|
for i := 0; i < typ.NumField(); i++ {
|
|
f := typ.Field(i)
|
|
|
|
fieldTags := make(map[string]string)
|
|
if v := f.Tag.Get(NMAP_STRUCT_TAG); v != "" {
|
|
for _, t := range strings.Split(v, ",") {
|
|
kv := tagFromString(t)
|
|
fieldTags[kv.Key] = kv.Value
|
|
}
|
|
}
|
|
if _, ok := fieldTags[NMAP_SKIP]; ok {
|
|
continue
|
|
}
|
|
if f.PkgPath != "" { // skip unexported fields
|
|
continue
|
|
}
|
|
dstFieldName := f.Name
|
|
if override, ok := fieldTags[NMAP_MAP_TO]; ok {
|
|
dstFieldName = override
|
|
}
|
|
|
|
dstField := dst.FieldByName(dstFieldName)
|
|
if !dstField.IsValid() {
|
|
return errors.New("invalid field in destination type: " + dstFieldName)
|
|
}
|
|
|
|
srcField := src.Field(i)
|
|
|
|
srcFieldType := srcField.Type().String()
|
|
switch srcFieldType {
|
|
case "string":
|
|
s := srcField.Interface().(string)
|
|
dstField.SetString(s)
|
|
case "sql.NullString":
|
|
s := srcField.Interface().(sql.NullString)
|
|
if s.Valid {
|
|
dstField.SetString(s.String)
|
|
}
|
|
case "sql.NullTime":
|
|
s := srcField.Interface().(sql.NullTime)
|
|
if s.Valid {
|
|
if dstField.Kind() == reflect.Ptr {
|
|
t := reflect.ValueOf(&s.Time).Elem()
|
|
dstField.Set(t.Addr())
|
|
} else {
|
|
dstField.Set(reflect.ValueOf(s.Time))
|
|
}
|
|
}
|
|
case "sql.NullBool":
|
|
s := srcField.Interface().(sql.NullBool)
|
|
if s.Valid {
|
|
dstField.SetBool(s.Bool)
|
|
}
|
|
case "sql.NullInt64":
|
|
s := srcField.Interface().(sql.NullInt64)
|
|
if s.Valid {
|
|
dstField.SetInt(s.Int64)
|
|
}
|
|
case "json.RawMessage":
|
|
s := srcField.Interface().(json.RawMessage)
|
|
json.Unmarshal(s, dstField.Addr().Interface())
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
type fieldTag struct {
|
|
Key string
|
|
Value string
|
|
}
|
|
|
|
func tagFromString(t string) fieldTag {
|
|
kv := strings.Split(t, ":")
|
|
if len(kv) == 1 {
|
|
return fieldTag{Key: strings.TrimSpace(kv[0])}
|
|
}
|
|
return fieldTag{Key: strings.TrimSpace(kv[0]), Value: strings.TrimSpace(kv[1])}
|
|
}
|