Files
zkill-susser/db/db.go
2026-01-26 12:47:39 +01:00

226 lines
8.4 KiB
Go

package db
import (
"context"
"strings"
"zkillsusser/models"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/schema"
)
type DB interface {
Init() error
Get() *gorm.DB
SearchShips(query string, limit int) ([]models.InvType, error)
SearchSystems(query string, limit int) ([]models.MapSolarSystem, error)
SearchModules(query string, limit int) ([]models.InvType, error)
SearchGroups(query string, limit int) ([]models.InvGroup, error)
GetItemTypes(itemIDs []int64) ([]models.InvType, error)
GetSolarSystems(systemIDs []int64) ([]models.MapSolarSystem, error)
ExpandGroupsIntoItemTypeIds(groups []int64) ([]int64, error)
GetType(ctx context.Context, typeID int32) (*models.InvType, error)
GetGroup(ctx context.Context, groupID int32) (*models.InvGroup, error)
GetCategory(ctx context.Context, categoryID int32) (*models.InvCategory, error)
GetMarketGroup(ctx context.Context, marketGroupID int32) (*models.InvMarketGroup, error)
GetSolarSystem(ctx context.Context, systemID int32) (*models.MapSolarSystem, error)
GetConstellation(ctx context.Context, constellationID int32) (*models.MapConstellation, error)
GetRegion(ctx context.Context, regionID int32) (*models.MapRegion, error)
// Analytics queries
// QueryTimeByHour(ctx context.Context, filters AnalyticsFilters) ([]TimeAggregationByHour, error)
// QueryTimeByDay(ctx context.Context, filters AnalyticsFilters) ([]TimeAggregationByDay, error)
// QueryTimeByDate(ctx context.Context, filters AnalyticsFilters) ([]TimeAggregationByDate, error)
// QueryTimeByMonth(ctx context.Context, filters AnalyticsFilters) ([]TimeAggregationByMonth, error)
// QueryLocationBySystem(ctx context.Context, filters AnalyticsFilters) ([]LocationAggregationBySystem, error)
// QueryLocationByRegion(ctx context.Context, filters AnalyticsFilters) ([]LocationAggregationByRegion, error)
// QueryLocationByConstellation(ctx context.Context, filters AnalyticsFilters) ([]LocationAggregationByConstellation, error)
// QueryLocationBySecurity(ctx context.Context, filters AnalyticsFilters) ([]LocationAggregationBySecurity, error)
// QueryShipByVictim(ctx context.Context, filters AnalyticsFilters) ([]ShipAggregationByVictimShip, error)
// QueryShipByAttacker(ctx context.Context, filters AnalyticsFilters) ([]ShipAggregationByAttackerShip, error)
// QueryPlayerByVictimCharacter(ctx context.Context, filters AnalyticsFilters) ([]PlayerAggregationByVictimCharacter, error)
// QueryPlayerByVictimCorporation(ctx context.Context, filters AnalyticsFilters) ([]PlayerAggregationByVictimCorporation, error)
// QueryPlayerByVictimAlliance(ctx context.Context, filters AnalyticsFilters) ([]PlayerAggregationByVictimAlliance, error)
// QueryPlayerByAttackerCharacter(ctx context.Context, filters AnalyticsFilters) ([]PlayerAggregationByAttackerCharacter, error)
// QueryPlayerByAttackerCorporation(ctx context.Context, filters AnalyticsFilters) ([]PlayerAggregationByAttackerCorporation, error)
// QueryPlayerByAttackerAlliance(ctx context.Context, filters AnalyticsFilters) ([]PlayerAggregationByAttackerAlliance, error)
// QueryModuleBySlotType(ctx context.Context, filters AnalyticsFilters) ([]ModuleAggregationBySlotType, error)
// QueryModuleByModule(ctx context.Context, filters AnalyticsFilters) ([]ModuleAggregationByModule, error)
// QueryModuleCoOccurrence(ctx context.Context, filters AnalyticsFilters, selectedModuleID int32, selectedSlot string) ([]ModuleCoOccurrence, error)
// QueryKillmailIDs(ctx context.Context, filters AnalyticsFilters, limit, offset int) ([]int64, error)
// QueryKillmailWithItems(ctx context.Context, killmailID int64) (*FlatKillmailComplete, error)
}
type DBWrapper struct {
db *gorm.DB // For SQLite (EVE static data)
}
var db *DBWrapper
func GetDB(path string) (DB, error) {
if db != nil {
return db, nil
}
sdb, err := gorm.Open(sqlite.Open(path), &gorm.Config{
NamingStrategy: schema.NamingStrategy{
NoLowerCase: true,
},
})
db = &DBWrapper{
db: sdb,
}
err = db.Init()
return db, err
}
func (db *DBWrapper) Get() *gorm.DB {
return db.db
}
func (db *DBWrapper) Init() error {
return nil
}
func (db *DBWrapper) ExpandGroupsIntoItemTypeIds(groups []int64) ([]int64, error) {
var groupTypeIDs []int64
result := db.db.Model(&models.InvType{}).
Select("typeID").
Where("groupID IN ?", groups).
Pluck("typeID", &groupTypeIDs)
return groupTypeIDs, result.Error
}
func (db *DBWrapper) SearchShips(query string, limit int) ([]models.InvType, error) {
var ships []models.InvType
searchPattern := "%" + strings.ToLower(query) + "%"
err := db.db.Table("invTypes").
Joins("INNER JOIN invGroups ON invTypes.groupID = invGroups.groupID").
Where("LOWER(invTypes.\"typeName\") LIKE ? AND invGroups.categoryID IN (6)", searchPattern).
Limit(limit).
Find(&ships).Error
return ships, err
}
func (db *DBWrapper) SearchSystems(query string, limit int) ([]models.MapSolarSystem, error) {
var systems []models.MapSolarSystem
searchPattern := "%" + strings.ToLower(query) + "%"
err := db.db.Table("mapSolarSystems").
Where("LOWER(\"solarSystemName\") LIKE ?", searchPattern).
Limit(limit).
Find(&systems).Error
return systems, err
}
func (db *DBWrapper) SearchModules(query string, limit int) ([]models.InvType, error) {
var modules []models.InvType
searchPattern := "%" + strings.ToLower(query) + "%"
err := db.db.Table("invTypes").
Joins("INNER JOIN invGroups ON invTypes.groupID = invGroups.groupID").
Where("LOWER(invTypes.\"typeName\") LIKE ? AND invGroups.categoryID IN (7, 66)", searchPattern).
Limit(limit).
Find(&modules).Error
return modules, err
}
func (db *DBWrapper) SearchGroups(query string, limit int) ([]models.InvGroup, error) {
var groups []models.InvGroup
searchPattern := "%" + strings.ToLower(query) + "%"
err := db.db.Table("invGroups").
Where("LOWER(\"groupName\") LIKE ?", searchPattern).
Limit(limit).
Find(&groups).Error
return groups, err
}
func (db *DBWrapper) GetItemTypes(itemIDs []int64) ([]models.InvType, error) {
var itemTypes []models.InvType
res := db.db.Model(&models.InvType{}).
Where("typeID IN ?", itemIDs).
Find(&itemTypes)
return itemTypes, res.Error
}
func (db *DBWrapper) GetSolarSystems(systemIDs []int64) ([]models.MapSolarSystem, error) {
var systems []models.MapSolarSystem
res := db.db.Model(&models.MapSolarSystem{}).
Where("solarSystemID IN ?", systemIDs).
Find(&systems)
return systems, res.Error
}
func deduplicateInt64(slice []int64) []int64 {
seen := make(map[int64]bool)
result := make([]int64, 0, len(slice))
for _, v := range slice {
if !seen[v] {
seen[v] = true
result = append(result, v)
}
}
return result
}
func (db *DBWrapper) GetType(ctx context.Context, typeID int32) (*models.InvType, error) {
var typeModel models.InvType
res := db.db.Model(&models.InvType{}).
Where("typeID = ?", typeID).
First(&typeModel)
return &typeModel, res.Error
}
func (db *DBWrapper) GetGroup(ctx context.Context, groupID int32) (*models.InvGroup, error) {
var group models.InvGroup
res := db.db.Model(&models.InvGroup{}).
Where("groupID = ?", groupID).
First(&group)
return &group, res.Error
}
func (db *DBWrapper) GetCategory(ctx context.Context, categoryID int32) (*models.InvCategory, error) {
var category models.InvCategory
res := db.db.Model(&models.InvCategory{}).
Where("categoryID = ?", categoryID).
First(&category)
return &category, res.Error
}
func (db *DBWrapper) GetMarketGroup(ctx context.Context, marketGroupID int32) (*models.InvMarketGroup, error) {
var marketGroup models.InvMarketGroup
res := db.db.Model(&models.InvMarketGroup{}).
Where("marketGroupID = ?", marketGroupID).
First(&marketGroup)
return &marketGroup, res.Error
}
func (db *DBWrapper) GetSolarSystem(ctx context.Context, systemID int32) (*models.MapSolarSystem, error) {
var system models.MapSolarSystem
res := db.db.Model(&models.MapSolarSystem{}).
Where("solarSystemID = ?", systemID).
First(&system)
return &system, res.Error
}
func (db *DBWrapper) GetConstellation(ctx context.Context, constellationID int32) (*models.MapConstellation, error) {
var constellation models.MapConstellation
res := db.db.Model(&models.MapConstellation{}).
Where("constellationID = ?", constellationID).
First(&constellation)
return &constellation, res.Error
}
func (db *DBWrapper) GetRegion(ctx context.Context, regionID int32) (*models.MapRegion, error) {
var region models.MapRegion
res := db.db.Model(&models.MapRegion{}).
Where("regionID = ?", regionID).
First(&region)
return &region, res.Error
}