first commit
This commit is contained in:
103
internal/db/db.go
Normal file
103
internal/db/db.go
Normal file
@@ -0,0 +1,103 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user