FlexDXCluster/database.go

290 lines
8.1 KiB
Go
Raw 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
}
type ContactsRepository struct {
db *sql.DB
Log *log.Logger
}
type FlexDXClusterRepository struct {
db *sql.DB
Log *log.Logger
}
func NewContactsRepository(filePath string, log *log.Logger) *ContactsRepository {
db, err := sql.Open("sqlite3", filePath)
if err != nil {
fmt.Println("Cannot open db", err)
}
return &ContactsRepository{
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,
"flexSpotNumber" INTEGER UNIQUE,
"dx" TEXT NOT NULL,
"freqMhz" TEXT,
"freqHz" TEXT,
"band" TEXT,
"mode" TEXT,
"spotter" INTEGER,
"flexMode" TEXT,
"source" TEXT,
"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,
}
}
func (r *ContactsRepository) ListByCountry(countryID string) ([]*Contact, error) {
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
}
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
}
func (r *ContactsRepository) ListByCountryMode(countryID string, mode string) ([]*Contact, error) {
modeUSB := "USB"
modeLSB := "LSB"
if mode == "USB" || mode == "LSB" {
rows, err := r.db.Query("SELECT callsign, band, mode, dxcc, stationcallsign, country FROM log WHERE dxcc = ? AND (mode = ? OR mode = ?)", countryID, modeLSB, modeUSB)
if err != nil {
log.Error("could not query database", err)
return nil, err
}
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
}
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
}
}
func (r *ContactsRepository) ListByCountryBand(countryID string, band string) ([]*Contact, error) {
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
}
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
}
func (r *ContactsRepository) ListByCallSign(callSign string, band string, mode string) ([]*Contact, error) {
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
}
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
}
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 {
fmt.Println(err)
return nil, err
}
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.TimeStamp, &s.LifeTime, &s.Priority,
&s.Comment, &s.Color, &s.BackgroundColor); err != nil {
fmt.Println(err)
return nil, err
}
}
return &s, nil
}
func (r *FlexDXClusterRepository) CreateSpot(spot FlexSpot) {
query := "INSERT INTO `spots` (`commandNumber`, `flexSpotNumber`, `dx`, `freqMhz`, `freqHz`, `band`, `mode`, `spotter`, `flexMode`, `source`, `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, time.Now().Unix(), spot.LifeTime, spot.Priority, spot.Comment, spot.Color, spot.BackgroundColor)
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)
}
}
func (r *FlexDXClusterRepository) UpdateSpotSameBand(spot FlexSpot) {
return
}
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
}
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.TimeStamp, &s.LifeTime, &s.Priority,
&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
}
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.TimeStamp, &s.LifeTime, &s.Priority,
&s.Comment, &s.Color, &s.BackgroundColor); err != nil {
fmt.Println(err)
return nil, err
}
}
return &s, nil
}
func (r *FlexDXClusterRepository) UpdateFlexSpotNumberByID(flexSpot string, spot FlexSpot) (*FlexSpot, error) {
flexSpotNumberInt, _ := strconv.Atoi(flexSpot)
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)
}
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.TimeStamp, &s.LifeTime, &s.Priority,
&s.Comment, &s.Color, &s.BackgroundColor); err != nil {
fmt.Println(err)
return nil, err
}
}
return &s, nil
}
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")
}
}