FlexDXCluster/database.go

387 lines
11 KiB
Go
Raw Permalink Normal View History

2024-09-23 16:24:50 +07:00
package main
import (
"context"
"database/sql"
"fmt"
"os"
"strconv"
"time"
log "github.com/sirupsen/logrus"
)
type Contact struct {
Callsign string
Band string
Mode string
DXCC string
StationCallsign string
Country string
}
2024-09-26 12:24:56 +07:00
type Spotter struct {
Spotter string
NumberofSpots string
}
type Log4OMContactsRepository struct {
2024-09-23 16:24:50 +07:00
db *sql.DB
Log *log.Logger
}
type FlexDXClusterRepository struct {
db *sql.DB
Log *log.Logger
}
2024-09-26 12:24:56 +07:00
func NewLog4OMContactsRepository(filePath string, log *log.Logger) *Log4OMContactsRepository {
2024-09-23 16:24:50 +07:00
db, err := sql.Open("sqlite3", filePath)
if err != nil {
fmt.Println("Cannot open db", err)
}
2024-09-26 12:24:56 +07:00
return &Log4OMContactsRepository{
2024-09-23 16:24:50 +07:00
db: db,
Log: log}
}
func NewFlexDXDatabase(filePath string, log *log.Logger) *FlexDXClusterRepository {
db, err := sql.Open("sqlite3", filePath)
if err != nil {
fmt.Println("Cannot open db", err)
}
log.Info("Opening SQLite database")
_, err = db.ExecContext(
context.Background(),
`CREATE TABLE IF NOT EXISTS "spots" (
"id" INTEGER NOT NULL UNIQUE,
"commandNumber" INTEGER NOT NULL UNIQUE,
2024-09-24 11:57:48 +07:00
"flexSpotNumber" INTEGER,
2024-09-23 16:24:50 +07:00
"dx" TEXT NOT NULL,
"freqMhz" TEXT,
"freqHz" TEXT,
"band" TEXT,
"mode" TEXT,
"spotter" INTEGER,
"flexMode" TEXT,
"source" TEXT,
2024-09-24 11:57:48 +07:00
"time" TEXT,
2024-09-23 16:24:50 +07:00
"timestamp" INTEGER,
"lifeTime" TEXT,
"priority" TEXT,
"comment" TEXT,
"color" TEXT,
"backgroundColor" INTEGER,
PRIMARY KEY("id" AUTOINCREMENT)
)`,
)
if err != nil {
log.Warn("Cannot create table", err)
}
return &FlexDXClusterRepository{
db: db,
Log: log,
}
}
2024-09-26 12:24:56 +07:00
func (r *Log4OMContactsRepository) ListByCountry(countryID string) ([]*Contact, error) {
2024-09-23 16:24:50 +07:00
rows, err := r.db.Query("SELECT callsign, band, mode, dxcc, stationcallsign, country FROM log WHERE dxcc = ?", countryID)
if err != nil {
log.Error("could not query database", err)
return nil, err
}
2024-09-26 12:24:56 +07:00
defer rows.Close()
2024-09-23 16:24:50 +07:00
contacts := []*Contact{}
for rows.Next() {
c := Contact{}
if err := rows.Scan(&c.Callsign, &c.Band, &c.Mode, &c.DXCC, &c.StationCallsign, &c.Country); err != nil {
log.Error("could not query database", err)
return nil, err
}
contacts = append(contacts, &c)
}
return contacts, nil
}
2024-09-26 12:24:56 +07:00
func (r *Log4OMContactsRepository) ListByCountryMode(countryID string, mode string) ([]*Contact, error) {
2024-09-23 16:24:50 +07:00
if mode == "USB" || mode == "LSB" {
2024-09-26 15:23:05 +07:00
rows, err := r.db.Query("SELECT callsign, band, mode, dxcc, stationcallsign, country FROM log WHERE dxcc = ? AND (mode = ? OR mode = ?)", countryID, "USB", "LSB")
2024-09-23 16:24:50 +07:00
if err != nil {
log.Error("could not query database", err)
return nil, err
}
2024-09-26 12:24:56 +07:00
defer rows.Close()
2024-09-23 16:24:50 +07:00
contacts := []*Contact{}
for rows.Next() {
c := Contact{}
if err := rows.Scan(&c.Callsign, &c.Band, &c.Mode, &c.DXCC, &c.StationCallsign, &c.Country); err != nil {
log.Error("could not query database", err)
return nil, err
}
contacts = append(contacts, &c)
}
return contacts, nil
} else {
rows, err := r.db.Query("SELECT callsign, band, mode, dxcc, stationcallsign, country FROM log WHERE dxcc = ? AND mode = ?", countryID, mode)
if err != nil {
log.Error("could not query the database", err)
return nil, err
}
2024-09-26 12:24:56 +07:00
defer rows.Close()
2024-09-23 16:24:50 +07:00
contacts := []*Contact{}
for rows.Next() {
c := Contact{}
if err := rows.Scan(&c.Callsign, &c.Band, &c.Mode, &c.DXCC, &c.StationCallsign, &c.Country); err != nil {
fmt.Println(err)
return nil, err
}
contacts = append(contacts, &c)
}
return contacts, nil
}
}
2024-09-26 12:24:56 +07:00
func (r *Log4OMContactsRepository) ListByCountryBand(countryID string, band string) ([]*Contact, error) {
2024-09-23 16:24:50 +07:00
rows, err := r.db.Query("SELECT callsign, band, mode, dxcc, stationcallsign, country FROM log WHERE dxcc = ? AND band = ?", countryID, band)
if err != nil {
fmt.Println(err)
return nil, err
}
2024-09-26 12:24:56 +07:00
defer rows.Close()
2024-09-23 16:24:50 +07:00
contacts := []*Contact{}
for rows.Next() {
c := Contact{}
if err := rows.Scan(&c.Callsign, &c.Band, &c.Mode, &c.DXCC, &c.StationCallsign, &c.Country); err != nil {
fmt.Println(err)
return nil, err
}
contacts = append(contacts, &c)
}
return contacts, nil
}
2024-09-26 12:24:56 +07:00
func (r *Log4OMContactsRepository) ListByCallSign(callSign string, band string, mode string) ([]*Contact, error) {
2024-09-23 16:24:50 +07:00
rows, err := r.db.Query("SELECT callsign, band, mode, dxcc, stationcallsign, country FROM log WHERE callsign = ? AND band = ? AND mode = ?", callSign, band, mode)
if err != nil {
fmt.Println(err)
return nil, err
}
2024-09-26 12:24:56 +07:00
defer rows.Close()
2024-09-23 16:24:50 +07:00
contacts := []*Contact{}
for rows.Next() {
c := Contact{}
if err := rows.Scan(&c.Callsign, &c.Band, &c.Mode, &c.DXCC, &c.StationCallsign, &c.Country); err != nil {
fmt.Println(err)
return nil, err
}
contacts = append(contacts, &c)
}
return contacts, nil
}
2024-09-26 12:24:56 +07:00
func (r *FlexDXClusterRepository) GetAllSpots(limit string) []FlexSpot {
Spots := []FlexSpot{}
var query string
if limit == "0" {
query = "SELECT * from spots ORDER BY id DESC"
} else {
query = fmt.Sprintf("SELECT * from spots ORDER BY id DESC LIMIT %s", limit)
}
rows, err := r.db.Query(query)
if err != nil {
r.Log.Error(err)
return nil
}
defer rows.Close()
s := FlexSpot{}
for rows.Next() {
if err := rows.Scan(&s.ID, &s.CommandNumber, &s.FlexSpotNumber, &s.DX, &s.FrequencyMhz, &s.FrequencyHz, &s.Band, &s.Mode, &s.SpotterCallsign, &s.FlexMode, &s.Source, &s.UTCTime, &s.TimeStamp, &s.LifeTime, &s.Priority,
&s.Comment, &s.Color, &s.BackgroundColor); err != nil {
fmt.Println(err)
return nil
}
Spots = append(Spots, s)
}
return Spots
}
func (r *FlexDXClusterRepository) GetSpotters() []Spotter {
sList := []Spotter{}
2024-09-26 15:23:05 +07:00
rows, err := r.db.Query("select spotter, count(*) as occurences from spots group by spotter order by occurences desc, spotter limit 5")
2024-09-26 12:24:56 +07:00
if err != nil {
r.Log.Error(err)
return nil
}
defer rows.Close()
s := Spotter{}
for rows.Next() {
if err := rows.Scan(&s.Spotter, &s.NumberofSpots); err != nil {
fmt.Println(err)
return nil
}
sList = append(sList, s)
}
return sList
}
2024-09-23 16:24:50 +07:00
func (r *FlexDXClusterRepository) FindDXSameBand(spot FlexSpot) (*FlexSpot, error) {
rows, err := r.db.Query("SELECT * from spots WHERE dx = ? AND band = ?", spot.DX, spot.Band)
if err != nil {
2024-09-26 12:24:56 +07:00
r.Log.Error(err)
2024-09-23 16:24:50 +07:00
return nil, err
}
2024-09-26 12:24:56 +07:00
defer rows.Close()
2024-09-23 16:24:50 +07:00
s := FlexSpot{}
for rows.Next() {
2024-09-24 11:57:48 +07:00
if err := rows.Scan(&s.ID, &s.CommandNumber, &s.FlexSpotNumber, &s.DX, &s.FrequencyMhz, &s.FrequencyHz, &s.Band, &s.Mode, &s.SpotterCallsign, &s.FlexMode, &s.Source, &s.UTCTime, &s.TimeStamp, &s.LifeTime, &s.Priority,
2024-09-23 16:24:50 +07:00
&s.Comment, &s.Color, &s.BackgroundColor); err != nil {
fmt.Println(err)
return nil, err
}
}
return &s, nil
}
func (r *FlexDXClusterRepository) CreateSpot(spot FlexSpot) {
2024-09-24 11:57:48 +07:00
query := "INSERT INTO `spots` (`commandNumber`, `flexSpotNumber`, `dx`, `freqMhz`, `freqHz`, `band`, `mode`, `spotter`, `flexMode`, `source`, `time`, `timestamp`, `lifeTime`, `priority`, `comment`, `color`, `backgroundColor`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
insertResult, err := r.db.ExecContext(context.Background(), query, spot.CommandNumber, spot.CommandNumber, spot.DX, spot.FrequencyMhz, spot.FrequencyHz, spot.Band, spot.Mode, spot.SpotterCallsign, spot.FlexMode, spot.Source, spot.UTCTime, time.Now().Unix(), spot.LifeTime, spot.Priority, spot.Comment, spot.Color, spot.BackgroundColor)
2024-09-23 16:24:50 +07:00
if err != nil {
log.Errorf("cannot insert spot in database: %s", err)
}
_, err = insertResult.LastInsertId()
if err != nil {
log.Errorf("impossible to retrieve last inserted id: %s", err)
}
}
2024-09-26 12:24:56 +07:00
func (r *FlexDXClusterRepository) UpdateSpotSameBand(spot FlexSpot) error {
_, err := r.db.Exec(`UPDATE spots SET commandNumber = ?, DX = ?, freqMhz = ?, freqHz = ?, band = ?, mode = ?, spotter = ?, flexMode = ?, source = ?, time = ?, timestamp = ?, lifeTime = ?, priority = ?, comment = ?, color = ?, backgroundColor = ? WHERE DX = ? AND band = ?`,
spot.CommandNumber, spot.DX, spot.FrequencyMhz, spot.FrequencyHz, spot.Band, spot.Mode, spot.SpotterCallsign, spot.FlexMode, spot.Source, spot.UTCTime, spot.TimeStamp, spot.LifeTime, spot.Priority, spot.Comment, spot.Color, spot.BackgroundColor, spot.DX, spot.Band)
if err != nil {
r.Log.Errorf("could not update database: %s", err)
return err
}
return nil
2024-09-23 16:24:50 +07:00
}
func (r *FlexDXClusterRepository) FindSpotByCommandNumber(commandNumber string) (*FlexSpot, error) {
rows, err := r.db.Query("SELECT * from spots WHERE commandNumber = ?", commandNumber)
if err != nil {
fmt.Println(err)
return nil, err
}
2024-09-26 12:24:56 +07:00
defer rows.Close()
2024-09-23 16:24:50 +07:00
s := FlexSpot{}
for rows.Next() {
2024-09-24 11:57:48 +07:00
if err := rows.Scan(&s.ID, &s.CommandNumber, &s.FlexSpotNumber, &s.DX, &s.FrequencyMhz, &s.FrequencyHz, &s.Band, &s.Mode, &s.SpotterCallsign, &s.FlexMode, &s.Source, &s.UTCTime, &s.TimeStamp, &s.LifeTime, &s.Priority,
2024-09-23 16:24:50 +07:00
&s.Comment, &s.Color, &s.BackgroundColor); err != nil {
fmt.Println(err)
return nil, err
}
}
return &s, nil
}
func (r *FlexDXClusterRepository) FindSpotByFlexSpotNumber(spotNumber string) (*FlexSpot, error) {
rows, err := r.db.Query("SELECT * from spots WHERE flexSpotNumber = ?", spotNumber)
if err != nil {
fmt.Println(err)
return nil, err
}
2024-09-26 12:24:56 +07:00
defer rows.Close()
2024-09-23 16:24:50 +07:00
s := FlexSpot{}
for rows.Next() {
2024-09-24 11:57:48 +07:00
if err := rows.Scan(&s.ID, &s.CommandNumber, &s.FlexSpotNumber, &s.DX, &s.FrequencyMhz, &s.FrequencyHz, &s.Band, &s.Mode, &s.SpotterCallsign, &s.FlexMode, &s.Source, &s.UTCTime, &s.TimeStamp, &s.LifeTime, &s.Priority,
2024-09-23 16:24:50 +07:00
&s.Comment, &s.Color, &s.BackgroundColor); err != nil {
fmt.Println(err)
return nil, err
}
}
return &s, nil
}
2024-09-24 11:57:48 +07:00
func (r *FlexDXClusterRepository) UpdateFlexSpotNumberByID(flexSpotNumber string, spot FlexSpot) (*FlexSpot, error) {
flexSpotNumberInt, _ := strconv.Atoi(flexSpotNumber)
2024-09-23 16:24:50 +07:00
rows, err := r.db.Query(`UPDATE spots SET flexSpotNumber = ? WHERE id = ? RETURNING *`, flexSpotNumberInt, spot.ID)
if err != nil {
r.Log.Errorf("could not update database: %s", err)
}
2024-09-26 12:24:56 +07:00
defer rows.Close()
2024-09-23 16:24:50 +07:00
s := FlexSpot{}
for rows.Next() {
2024-09-24 11:57:48 +07:00
if err := rows.Scan(&s.ID, &s.CommandNumber, &s.FlexSpotNumber, &s.DX, &s.FrequencyMhz, &s.FrequencyHz, &s.Band, &s.Mode, &s.SpotterCallsign, &s.FlexMode, &s.Source, &s.UTCTime, &s.TimeStamp, &s.LifeTime, &s.Priority,
2024-09-23 16:24:50 +07:00
&s.Comment, &s.Color, &s.BackgroundColor); err != nil {
fmt.Println(err)
return nil, err
}
}
return &s, nil
}
2024-09-24 11:57:48 +07:00
func (r *FlexDXClusterRepository) DeleteSpotByFlexSpotNumber(flexSpotNumber string) {
flexSpotNumberInt, _ := strconv.Atoi(flexSpotNumber)
query := "DELETE from spots WHERE flexSpotNumber = ?"
_, err := r.db.Exec(query, flexSpotNumberInt)
if err != nil {
r.Log.Errorf("could not delete spot %v from database", flexSpotNumberInt)
}
}
2024-09-23 16:24:50 +07:00
func DeleteDatabase(filePath string, log *log.Logger) {
_, err := os.Stat(filePath)
if !os.IsNotExist(err) {
err := os.Remove(filePath)
if err != nil {
log.Error("could not delete existing database")
}
log.Info("deleting existing database")
}
}