Files
FlexDXCluster2/internal/db/db.go
2026-03-17 20:20:23 +01:00

104 lines
2.9 KiB
Go

package db
import (
"context"
"database/sql"
"fmt"
_ "github.com/mattn/go-sqlite3"
)
// DB est le wrapper principal autour de la connexion SQLite
type DB struct {
conn *sql.DB
}
// Open ouvre (ou crée) la base SQLite et applique les migrations
func Open(path string) (*DB, error) {
conn, err := sql.Open("sqlite3", path+"?_journal_mode=WAL&_busy_timeout=5000")
if err != nil {
return nil, fmt.Errorf("open db: %w", err)
}
conn.SetMaxOpenConns(1)
conn.SetMaxIdleConns(1)
db := &DB{conn: conn}
if err := db.migrate(); err != nil {
conn.Close()
return nil, fmt.Errorf("migrate: %w", err)
}
return db, nil
}
func (db *DB) Close() error {
return db.conn.Close()
}
func (db *DB) Conn() *sql.DB {
return db.conn
}
// migrate crée les tables si elles n'existent pas
func (db *DB) migrate() error {
ctx := context.Background()
_, err := db.conn.ExecContext(ctx, `
CREATE TABLE IF NOT EXISTS spots (
id INTEGER PRIMARY KEY AUTOINCREMENT,
dx TEXT NOT NULL,
spotter TEXT NOT NULL,
frequency_khz REAL NOT NULL,
frequency_mhz TEXT NOT NULL,
band TEXT NOT NULL,
mode TEXT NOT NULL,
comment TEXT DEFAULT '',
original_comment TEXT DEFAULT '',
time TEXT DEFAULT '',
timestamp INTEGER NOT NULL,
dxcc TEXT DEFAULT '',
country_name TEXT DEFAULT '',
new_dxcc INTEGER DEFAULT 0,
new_band INTEGER DEFAULT 0,
new_mode INTEGER DEFAULT 0,
new_slot INTEGER DEFAULT 0,
callsign_worked INTEGER DEFAULT 0,
in_watchlist INTEGER DEFAULT 0,
pota_ref TEXT DEFAULT '',
sota_ref TEXT DEFAULT '',
park_name TEXT DEFAULT '',
summit_name TEXT DEFAULT '',
flex_spot_number INTEGER DEFAULT 0,
command_number INTEGER DEFAULT 0,
color TEXT DEFAULT '#ffeaeaea',
background_color TEXT DEFAULT '#ff000000',
priority TEXT DEFAULT '5',
life_time TEXT DEFAULT '900',
cluster_name TEXT DEFAULT '',
source INTEGER DEFAULT 0
)`)
if err != nil {
return fmt.Errorf("create spots table: %w", err)
}
// Index pour les recherches fréquentes
_, err = db.conn.ExecContext(ctx, `
CREATE INDEX IF NOT EXISTS idx_spots_dx_band ON spots(dx, band);
CREATE INDEX IF NOT EXISTS idx_spots_timestamp ON spots(timestamp);
CREATE INDEX IF NOT EXISTS idx_spots_flex_number ON spots(flex_spot_number);
CREATE INDEX IF NOT EXISTS idx_spots_command_number ON spots(command_number);
`)
if err != nil {
return fmt.Errorf("create indexes: %w", err)
}
return nil
}
// DeleteAll supprime tous les spots (appelé au démarrage comme l'ancien code)
func (db *DB) DeleteAll(ctx context.Context) error {
_, err := db.conn.ExecContext(ctx, `DELETE FROM spots`)
return err
}