Files
zkill-susser/db.go

126 lines
2.9 KiB
Go

package main
import (
"fmt"
"zkillsusser/models"
logger "git.site.quack-lab.dev/dave/cylogger"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"gorm.io/gorm/schema"
)
type QueryParams struct {
Ship string
Systems []string
Modules []string
}
type Fit struct {
Data any
}
type DB interface {
DB() *gorm.DB
Raw(sql string, args ...any) *gorm.DB
SaveKillmails(killmails []Killmail) error
QueryFits(params QueryParams) ([]Fit, error)
ShipTypeFind(name string) (*models.InvType, error)
}
type DBWrapper struct {
db *gorm.DB
}
var db *DBWrapper
func GetDB() (DB, error) {
if db != nil {
return db, nil
}
dsn := "host=localhost user=postgres password=postgres dbname=zkill port=5432 sslmode=disable"
gdb, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
PrepareStmt: true,
NamingStrategy: schema.NamingStrategy{
NoLowerCase: true,
},
})
if err != nil {
return nil, err
}
db = &DBWrapper{db: gdb}
return db, nil
}
func (db *DBWrapper) Raw(sql string, args ...any) *gorm.DB {
return db.db.Raw(sql, args...)
}
func (db *DBWrapper) DB() *gorm.DB {
return db.db
}
func (db *DBWrapper) SaveKillmails(killmails []Killmail) error {
return db.db.Session(&gorm.Session{FullSaveAssociations: true}).
Clauses(clause.OnConflict{DoNothing: true}).
CreateInBatches(killmails, 10).Error
}
func (db *DBWrapper) QueryFits(params QueryParams) ([]Fit, error) {
flog := logger.Default.WithPrefix("QueryFits").WithPrefix(fmt.Sprintf("%+v", params))
shipType, err := db.ShipTypeFind(params.Ship)
if err != nil {
return nil, err
}
flog.Trace("Found ship type for %s at %d", shipType.TypeName, shipType.TypeID)
flog.Dump("Ship type", shipType)
victims := []Victim{}
result := db.db.Table("public.zkill_victims").
Where("ship_type_id = ?", shipType.TypeID).
Find(&victims)
if result.Error != nil {
flog.Error("Failed to find killmails: %v", result.Error)
return nil, result.Error
}
flog.Debug("Found %d killmails", result.RowsAffected)
// TODO: DEBUG!
victims = victims[:10]
items := []Item{}
for _, victim := range victims {
vlog := flog.WithPrefix(fmt.Sprintf("victim %d", victim.ID))
vlog.Debug("Finding items")
result = db.db.Table("public.zkill_items").
Where("victim_id = ?", victim.ID).
Find(&items)
if result.Error != nil {
vlog.Error("Failed to find items: %v", result.Error)
return nil, result.Error
}
vlog.Debug("Found %d items", result.RowsAffected)
}
return nil, nil
}
func (db *DBWrapper) ShipTypeFind(name string) (*models.InvType, error) {
flog := logger.Default.WithPrefix("ShipTypeFind").WithPrefix(name)
shipType := &models.InvType{}
flog.Debug("Finding ship type")
result := db.db.Table("evesde.invTypes").
Where("LOWER(\"typeName\") LIKE LOWER(?)", "%"+name+"%").
First(&shipType)
if result.Error != nil {
flog.Error("Failed to find ship type: %v", result.Error)
return nil, result.Error
}
flog.Debug("Found %d records", result.RowsAffected)
return shipType, nil
}