blob: 2fe133feb3c0c1816aa9ecf65f61be1e9e6e9dd2 [file] [log] [blame]
package model
import (
"context"
"fmt"
"net"
"strconv"
)
func (m *sqlModel) GetCheckablePeers(ctx context.Context) ([]*Peer, error) {
data := []struct {
sqlPeer `db:"peers"`
sqlPeerRouter `db:"peer_routers"`
}{}
q := `
SELECT
peers.id "peers.id",
peers.asn "peers.asn",
peers.name "peers.name",
peer_routers.peer_id "peer_routers.peer_id",
peer_routers.v6 "peer_routers.v6",
peer_routers.v4 "peer_routers.v4"
FROM peers
LEFT JOIN peer_routers
ON peer_routers.peer_id = peers.id
`
if err := m.db.SelectContext(ctx, &data, q); err != nil {
return nil, fmt.Errorf("SELECT peers/peerRouters: %v", err)
}
// Collapse peers into map
// ID -> Peer
peers := make(map[string]*Peer)
for _, row := range data {
peer, ok := peers[row.sqlPeer.ID]
if !ok {
asn, err := strconv.ParseInt(row.sqlPeer.ASN, 10, 64)
if err != nil {
return nil, fmt.Errorf("data corruption: invalid ASN %q", row.sqlPeer.ASN)
}
peer = &Peer{
ASN: asn,
Name: row.sqlPeer.Name,
Routers: []*Router{},
}
peers[row.sqlPeer.ID] = peer
}
var v6 net.IP
var v4 net.IP
if row.sqlPeerRouter.V6.Valid {
v6 = net.ParseIP(row.sqlPeerRouter.V6.String)
}
if row.sqlPeerRouter.V4.Valid {
v4 = net.ParseIP(row.sqlPeerRouter.V4.String)
}
peer.Routers = append(peer.Routers, &Router{
V6: v6,
V4: v4,
})
}
res := make([]*Peer, len(peers))
i := 0
for _, peer := range peers {
res[i] = peer
i += 1
}
return res, nil
}