mirror of
https://github.com/alice-lg/alice-lg.git
synced 2024-05-11 05:55:03 +00:00
use per RS table
This commit is contained in:
@ -7,20 +7,27 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/alice-lg/alice-lg/pkg/api"
|
||||
"github.com/alice-lg/alice-lg/pkg/config"
|
||||
|
||||
"github.com/jackc/pgx/v4"
|
||||
"github.com/jackc/pgx/v4/pgxpool"
|
||||
)
|
||||
|
||||
// RoutesBackend implements a postgres store for routes.
|
||||
type RoutesBackend struct {
|
||||
pool *pgxpool.Pool
|
||||
pool *pgxpool.Pool
|
||||
sources []*config.SourceConfig
|
||||
}
|
||||
|
||||
// NewRoutesBackend creates a new instance with a postgres
|
||||
// connection pool.
|
||||
func NewRoutesBackend(pool *pgxpool.Pool) *RoutesBackend {
|
||||
func NewRoutesBackend(
|
||||
pool *pgxpool.Pool,
|
||||
sources []*config.SourceConfig,
|
||||
) *RoutesBackend {
|
||||
return &RoutesBackend{
|
||||
pool: pool,
|
||||
pool: pool,
|
||||
sources: sources,
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,9 +49,11 @@ func (b *RoutesBackend) SetRoutes(
|
||||
}
|
||||
defer tx.Rollback(ctx)
|
||||
|
||||
if err := b.clear(ctx, tx, sourceID); err != nil {
|
||||
// Create table from template
|
||||
if err := b.initTable(ctx, tx, sourceID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// persist all routes
|
||||
for _, r := range routes {
|
||||
if err := b.persist(ctx, tx, sourceID, r, now); err != nil {
|
||||
@ -58,6 +67,28 @@ func (b *RoutesBackend) SetRoutes(
|
||||
return nil
|
||||
}
|
||||
|
||||
// Private routesTable returns the name of the routes table
|
||||
// for a sourceID
|
||||
func (b *RoutesBackend) routesTable(sourceID string) string {
|
||||
return "routes_" + sourceID
|
||||
}
|
||||
|
||||
// Private initTable recreates the routes table
|
||||
// for a single sourceID
|
||||
func (b *RoutesBackend) initTable(
|
||||
ctx context.Context,
|
||||
tx pgx.Tx,
|
||||
sourceID string,
|
||||
) error {
|
||||
tbl := b.routesTable(sourceID)
|
||||
qry := `
|
||||
DROP TABLE IF EXISTS ` + tbl + `;
|
||||
CREATE TABLE ` + tbl + ` ( LIKE routes INCLUDING ALL )
|
||||
`
|
||||
_, err := tx.Exec(ctx, qry)
|
||||
return err
|
||||
}
|
||||
|
||||
// Private persist route in database
|
||||
func (b *RoutesBackend) persist(
|
||||
ctx context.Context,
|
||||
@ -66,8 +97,9 @@ func (b *RoutesBackend) persist(
|
||||
route *api.LookupRoute,
|
||||
now time.Time,
|
||||
) error {
|
||||
tbl := b.routesTable(sourceID)
|
||||
qry := `
|
||||
INSERT INTO routes (
|
||||
INSERT INTO ` + tbl + ` (
|
||||
id,
|
||||
rs_id,
|
||||
neighbor_id,
|
||||
@ -91,17 +123,19 @@ func (b *RoutesBackend) persist(
|
||||
}
|
||||
|
||||
// Private clear removes all routes.
|
||||
/*
|
||||
func (b *RoutesBackend) clear(
|
||||
ctx context.Context,
|
||||
tx pgx.Tx,
|
||||
sourceID string,
|
||||
) error {
|
||||
qry := `
|
||||
DELETE FROM routes WHERE rs_id = $1
|
||||
DELETE FROM routes WHERE rs_id = $1
|
||||
`
|
||||
_, err := tx.Exec(ctx, qry, sourceID)
|
||||
return err
|
||||
}
|
||||
*/
|
||||
|
||||
// Private queryCountByState will query routes and filter
|
||||
// by state
|
||||
@ -111,10 +145,11 @@ func (b *RoutesBackend) queryCountByState(
|
||||
sourceID string,
|
||||
state string,
|
||||
) pgx.Row {
|
||||
qry := `SELECT COUNT(1) FROM routes
|
||||
WHERE rs_id = $1 AND route -> 'state' = $2`
|
||||
tbl := b.routesTable(sourceID)
|
||||
qry := `SELECT COUNT(1) FROM ` + tbl + `
|
||||
WHERE route -> 'state' = $1`
|
||||
|
||||
return tx.QueryRow(ctx, qry, sourceID, "\""+state+"\"")
|
||||
return tx.QueryRow(ctx, qry, "\""+state+"\"")
|
||||
}
|
||||
|
||||
// CountRoutesAt returns the number of filtered and imported
|
||||
@ -171,9 +206,17 @@ func (b *RoutesBackend) FindByNeighbors(
|
||||
vars[i] = fmt.Sprintf("$%d", i+1)
|
||||
}
|
||||
listQry := strings.Join(vars, ",")
|
||||
qry := `
|
||||
SELECT route FROM routes
|
||||
WHERE neighbor_id IN (` + listQry + `)`
|
||||
|
||||
qrys := []string{}
|
||||
for _, src := range b.sources {
|
||||
tbl := b.routesTable(src.ID)
|
||||
qry := `
|
||||
SELECT route FROM ` + tbl + `
|
||||
WHERE neighbor_id IN (` + listQry + `)`
|
||||
qrys = append(qrys, qry)
|
||||
}
|
||||
|
||||
qry := strings.Join(qrys, " UNION ")
|
||||
|
||||
rows, err := tx.Query(ctx, qry, vals...)
|
||||
if err != nil {
|
||||
@ -196,10 +239,16 @@ func (b *RoutesBackend) FindByPrefix(
|
||||
}
|
||||
defer tx.Rollback(ctx)
|
||||
// We are searching route.Network
|
||||
qry := `
|
||||
SELECT route FROM routes
|
||||
WHERE network ILIKE $1
|
||||
`
|
||||
qrys := []string{}
|
||||
for _, src := range b.sources {
|
||||
tbl := b.routesTable(src.ID)
|
||||
qry := `
|
||||
SELECT route FROM ` + tbl + `
|
||||
WHERE network ILIKE $1
|
||||
`
|
||||
qrys = append(qrys, qry)
|
||||
}
|
||||
qry := strings.Join(qrys, " UNION ")
|
||||
rows, err := tx.Query(ctx, qry, prefix+"%")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/alice-lg/alice-lg/pkg/api"
|
||||
"github.com/alice-lg/alice-lg/pkg/config"
|
||||
)
|
||||
|
||||
func TestCountRoutesAt(t *testing.T) {
|
||||
@ -29,6 +30,7 @@ func TestCountRoutesAt(t *testing.T) {
|
||||
Network: "1.2.3.0/24",
|
||||
},
|
||||
}
|
||||
b.initTable(ctx, tx, "rs1")
|
||||
b.persist(ctx, tx, "rs1", r, now)
|
||||
|
||||
r.Route.ID = "r4242"
|
||||
@ -63,7 +65,13 @@ func TestFindByNeighbors(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer tx.Rollback(ctx)
|
||||
b := &RoutesBackend{pool: pool}
|
||||
b := &RoutesBackend{
|
||||
pool: pool,
|
||||
sources: []*config.SourceConfig{
|
||||
{ID: "rs1"},
|
||||
{ID: "rs2"},
|
||||
},
|
||||
}
|
||||
r := &api.LookupRoute{
|
||||
State: "filtered",
|
||||
Neighbor: &api.Neighbor{
|
||||
@ -74,6 +82,8 @@ func TestFindByNeighbors(t *testing.T) {
|
||||
Network: "1.2.3.0/24",
|
||||
},
|
||||
}
|
||||
b.initTable(ctx, tx, "rs1")
|
||||
b.initTable(ctx, tx, "rs2")
|
||||
b.persist(ctx, tx, "rs1", r, now)
|
||||
|
||||
r.Route.ID = "r4242"
|
||||
@ -85,7 +95,7 @@ func TestFindByNeighbors(t *testing.T) {
|
||||
|
||||
r.Route.ID = "r4244"
|
||||
r.Neighbor.ID = "n25"
|
||||
b.persist(ctx, tx, "rs1", r, now)
|
||||
b.persist(ctx, tx, "rs2", r, now)
|
||||
|
||||
if err := tx.Commit(ctx); err != nil {
|
||||
t.Fatal(err)
|
||||
@ -113,7 +123,13 @@ func TestFindByPrefix(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer tx.Rollback(ctx)
|
||||
b := &RoutesBackend{pool: pool}
|
||||
b := &RoutesBackend{
|
||||
pool: pool,
|
||||
sources: []*config.SourceConfig{
|
||||
{ID: "rs1"},
|
||||
{ID: "rs2"},
|
||||
},
|
||||
}
|
||||
r := &api.LookupRoute{
|
||||
State: "filtered",
|
||||
Neighbor: &api.Neighbor{
|
||||
@ -124,6 +140,9 @@ func TestFindByPrefix(t *testing.T) {
|
||||
Network: "1.2.3.0/24",
|
||||
},
|
||||
}
|
||||
|
||||
b.initTable(ctx, tx, "rs1")
|
||||
b.initTable(ctx, tx, "rs2")
|
||||
b.persist(ctx, tx, "rs1", r, now)
|
||||
|
||||
r.Route.ID = "r4242"
|
||||
@ -133,7 +152,7 @@ func TestFindByPrefix(t *testing.T) {
|
||||
r.Route.ID = "r4243"
|
||||
r.Route.Network = "1.2.5.0/24"
|
||||
r.Neighbor.ID = "n24"
|
||||
b.persist(ctx, tx, "rs1", r, now)
|
||||
b.persist(ctx, tx, "rs2", r, now)
|
||||
|
||||
r.Route.ID = "r4244"
|
||||
r.Route.Network = "5.5.5.0/24"
|
||||
|
Reference in New Issue
Block a user