This commit is contained in:
2026-06-15 23:45:14 +02:00
parent 29fd832bcd
commit 22e3bb4a18
32 changed files with 2531 additions and 362 deletions
+53
View File
@@ -58,6 +58,59 @@ type Repo struct{ db *sql.DB }
func NewRepo(db *sql.DB) *Repo { return &Repo{db: db} }
// CopyProfile duplicates the entire stations→antennas→bands tree from one
// profile to another (used when a profile is duplicated). New ids are assigned;
// the band defaults and ordering are preserved.
func (r *Repo) CopyProfile(ctx context.Context, srcProfileID, dstProfileID int64) error {
tree, err := r.ListTree(ctx, srcProfileID)
if err != nil {
return err
}
tx, err := r.db.BeginTx(ctx, nil)
if err != nil {
return err
}
defer tx.Rollback()
now := db.NowISO()
for _, st := range tree {
var pwr any
if st.TXPower != nil {
pwr = *st.TXPower
}
res, err := tx.ExecContext(ctx,
`INSERT INTO operating_stations(profile_id, name, tx_pwr, sort_order, created_at, updated_at)
VALUES(?,?,?,?,?,?)`, dstProfileID, st.Name, pwr, st.SortOrder, now, now)
if err != nil {
return fmt.Errorf("copy station: %w", err)
}
newStationID, _ := res.LastInsertId()
for _, ant := range st.Antennas {
ares, err := tx.ExecContext(ctx,
`INSERT INTO operating_antennas(station_id, name, sort_order, created_at, updated_at)
VALUES(?,?,?,?,?)`, newStationID, ant.Name, ant.SortOrder, now, now)
if err != nil {
return fmt.Errorf("copy antenna: %w", err)
}
newAntID, _ := ares.LastInsertId()
for _, b := range ant.Bands {
if _, err := tx.ExecContext(ctx,
`INSERT INTO operating_antenna_bands(antenna_id, band, is_default) VALUES(?,?,?)`,
newAntID, b.Band, boolToInt(b.IsDefault)); err != nil {
return fmt.Errorf("copy band: %w", err)
}
}
}
}
return tx.Commit()
}
func boolToInt(b bool) int {
if b {
return 1
}
return 0
}
// ListTree returns every station for the profile with its nested antennas
// and bands. One round-trip per level — three queries total regardless of
// tree size, so the Settings panel stays snappy on big setups.