switched to typing for model IDs

This commit is contained in:
BroodjeAap 2023-03-25 10:44:49 +00:00
parent a9577abbd8
commit 1490fb10bd
10 changed files with 52 additions and 47 deletions

View file

@ -1,8 +1,9 @@
package models
type FilterConnectionID uint
type FilterConnection struct {
ID uint `form:"filter_connection_id" yaml:"filter_connection_id" json:"filter_connection_id"`
WatchID uint `form:"connection_watch_id" gorm:"index" yaml:"connection_watch_id" json:"connection_watch_id" binding:"required"`
OutputID uint `form:"filter_output_id" gorm:"index" yaml:"filter_output_id" json:"filter_output_id" binding:"required"`
InputID uint `form:"filter_input_id" gorm:"index" yaml:"filter_input_id" json:"filter_input_id" binding:"required"`
ID FilterConnectionID `form:"filter_connection_id" yaml:"filter_connection_id" json:"filter_connection_id"`
WatchID WatchID `form:"connection_watch_id" gorm:"index" yaml:"connection_watch_id" json:"connection_watch_id" binding:"required"`
OutputID FilterID `form:"filter_output_id" gorm:"index" yaml:"filter_output_id" json:"filter_output_id" binding:"required"`
InputID FilterID `form:"filter_input_id" gorm:"index" yaml:"filter_input_id" json:"filter_input_id" binding:"required"`
}

View file

@ -2,9 +2,10 @@ package models
import "time"
type ExcpectFailID uint
type ExpectFail struct {
ID uint `yaml:"expect_fail_id" json:"expect_fail_id"`
WatchID uint `yaml:"expect_fail_watch_id" gorm:"index" json:"expect_fail_watch_id"`
Name string `yaml:"expect_fail_name" json:"expect_fail_name"`
Time time.Time `yaml:"expect_fail_time" json:"expect_fail_time"`
ID ExcpectFailID `yaml:"expect_fail_id" json:"expect_fail_id"`
WatchID WatchID `yaml:"expect_fail_watch_id" gorm:"index" json:"expect_fail_watch_id"`
Name string `yaml:"expect_fail_name" json:"expect_fail_name"`
Time time.Time `yaml:"expect_fail_time" json:"expect_fail_time"`
}

View file

@ -5,19 +5,21 @@ import (
"html"
)
type FilterID uint
type FilterType string
type Filter struct {
ID uint `form:"filter_id" yaml:"filter_id" json:"filter_id"`
WatchID uint `form:"filter_watch_id" gorm:"index" yaml:"filter_watch_id" json:"filter_watch_id" binding:"required"`
Name string `form:"filter_name" gorm:"index" yaml:"filter_name" json:"filter_name" binding:"required" validate:"min=1"`
X int `form:"x" yaml:"x" json:"x" validate:"default=0"`
Y int `form:"y" yaml:"y" json:"y" validate:"default=0"`
Type string `form:"filter_type" yaml:"filter_type" json:"filter_type" binding:"required" validate:"oneof=url xpath json css replace match substring math store condition cron"`
Var1 string `form:"var1" yaml:"var1" json:"var1" binding:"required"`
Var2 *string `form:"var2" yaml:"var2" json:"var2"`
Parents []*Filter `gorm:"-:all"`
Children []*Filter `gorm:"-:all"`
Results []string `gorm:"-:all"`
Logs []string `gorm:"-:all"`
ID FilterID `form:"filter_id" yaml:"filter_id" json:"filter_id"`
WatchID WatchID `form:"filter_watch_id" gorm:"index" yaml:"filter_watch_id" json:"filter_watch_id" binding:"required"`
Name string `form:"filter_name" gorm:"index" yaml:"filter_name" json:"filter_name" binding:"required" validate:"min=1"`
X int `form:"x" yaml:"x" json:"x" validate:"default=0"`
Y int `form:"y" yaml:"y" json:"y" validate:"default=0"`
Type FilterType `form:"filter_type" yaml:"filter_type" json:"filter_type" binding:"required" validate:"oneof=url xpath json css replace match substring math store condition cron"`
Var1 string `form:"var1" yaml:"var1" json:"var1" binding:"required"`
Var2 *string `form:"var2" yaml:"var2" json:"var2"`
Parents []*Filter `gorm:"-:all"`
Children []*Filter `gorm:"-:all"`
Results []string `gorm:"-:all"`
Logs []string `gorm:"-:all"`
}
func (filter *Filter) Log(v ...any) {

View file

@ -2,10 +2,11 @@ package models
import "time"
type FilterOutputID uint
type FilterOutput struct {
ID uint `yaml:"filter_output_id" json:"filter_output_id"`
WatchID uint `yaml:"filter_output_watch_id" gorm:"index" json:"filter_output_watch_id"`
Name string `yaml:"filter_output_name" json:"filter_output_name"`
Value string `yaml:"filter_output_value" json:"filter_output_value"`
Time time.Time `yaml:"filter_output_time" json:"filter_output_time"`
ID FilterOutputID `yaml:"filter_output_id" json:"filter_output_id"`
WatchID WatchID `yaml:"filter_output_watch_id" gorm:"index" json:"filter_output_watch_id"`
Name string `yaml:"filter_output_name" json:"filter_output_name"`
Value string `yaml:"filter_output_value" json:"filter_output_value"`
Time time.Time `yaml:"filter_output_time" json:"filter_output_time"`
}

View file

@ -4,8 +4,9 @@ import (
"github.com/robfig/cron/v3"
)
type WatchID uint
type Watch struct {
ID uint `form:"watch_id" yaml:"watch_id"`
ID WatchID `form:"watch_id" yaml:"watch_id"`
Name string `form:"watch_name" gorm:"index" yaml:"watch_name" binding:"required" validate:"min=1"`
CronEntry *cron.Entry `gorm:"-:all"`
LastValue string `gorm:"-:all"`

View file

@ -1,4 +1,3 @@
# Todo
- add time 'jitter' to schedule filter
- var2 with another duration string, var1 + (var2 * random) duration
- switch to proper typing of IDs (type WatchID uint)
- var2 with another duration string, var1 + (var2 * random) duration

View file

@ -30,10 +30,10 @@ import (
)
// ProcessFilters takes the filters of a watch, already 'connected' with buildFilterTree(), and processes the filters in the right order.
func ProcessFilters(filters []Filter, web *Web, watch *Watch, debug bool, scheduleID *uint) {
func ProcessFilters(filters []Filter, web *Web, watch *Watch, debug bool, scheduleID *FilterID) {
// set of watch.IDs that have been processed
// filters will only be processed if all their parents are processed
processedMap := make(map[uint]bool, len(filters))
processedMap := make(map[FilterID]bool, len(filters))
// if this function is called from a schedule, add the schedule filter to the processed set
if scheduleID != nil {
@ -1204,7 +1204,7 @@ func notifyFilter(filters []Filter, filter *Filter, watch *Watch, web *Web, debu
}
// TriggerSchedule gets called by the cronjob scheduler to start a watch execution
func TriggerSchedule(watchID uint, web *Web, scheduleID *uint) {
func TriggerSchedule(watchID WatchID, web *Web, scheduleID *FilterID) {
var watch *Watch
web.db.Model(&Watch{}).First(&watch, watchID)

View file

@ -717,7 +717,7 @@ func TestConditionDiff(t *testing.T) {
testName := "Test"
var tests = []struct {
dbInput []FilterOutput
WatchID uint
WatchID WatchID
Input []string
Want []string
}{
@ -825,7 +825,7 @@ func TestConditionLowerLast(t *testing.T) {
testName := "Test"
var tests = []struct {
dbInput []FilterOutput
WatchID uint
WatchID WatchID
Input []string
Want []string
}{
@ -936,7 +936,7 @@ func TestConditionLowest(t *testing.T) {
testName := "Test"
var tests = []struct {
dbInput []FilterOutput
WatchID uint
WatchID WatchID
Input []string
Want []string
}{
@ -1086,7 +1086,7 @@ func TestConditionHigherLast(t *testing.T) {
testName := "Test"
var tests = []struct {
dbInput []FilterOutput
WatchID uint
WatchID WatchID
Input []string
Want []string
}{
@ -1198,7 +1198,7 @@ func TestConditionHighest(t *testing.T) {
testName := "Test"
var tests = []struct {
dbInput []FilterOutput
WatchID uint
WatchID WatchID
Input []string
Want []string
}{

View file

@ -37,7 +37,7 @@ func validate(err error) map[string]string {
}
func buildFilterTree(filters []Filter, connections []FilterConnection) {
filterMap := make(map[uint]*Filter, len(filters))
filterMap := make(map[FilterID]*Filter, len(filters))
for i := range filters {
filter := &filters[i]
filterMap[filter.ID] = filter

View file

@ -44,7 +44,7 @@ type Web struct {
templates multitemplate.Renderer // multitemplate instance
cron *cron.Cron // cron instance
urlCache map[string]string // holds url -> http response
cronWatch map[uint]cron.EntryID // holds cronFilter.ID -> EntryID
cronWatch map[FilterID]cron.EntryID // holds cronFilter.ID -> EntryID
db *gorm.DB // gorm db instance
notifiers map[string]notifiers.Notifier // holds notifierName -> notifier
startupWarnings []string // simple list of warnings/errors found during startup, displayed on / page
@ -254,7 +254,7 @@ func (web *Web) initCronJobs() {
// type cron and enabled = yes
web.db.Model(&Filter{}).Find(&cronFilters, "type = 'cron' AND var2 = 'yes'")
web.cronWatch = make(map[uint]cron.EntryID, len(cronFilters))
web.cronWatch = make(map[FilterID]cron.EntryID, len(cronFilters))
web.cron = cron.New()
web.cron.Start()
@ -378,7 +378,7 @@ func (web *Web) pruneDB() {
}
// a value can be deleted if it's the same as the previous and next value
IDs := make([]uint, 0, len(values))
IDs := make([]FilterOutputID, 0, len(values))
for i := range values {
if i > len(values)-3 {
break
@ -426,7 +426,7 @@ func (web *Web) index(c *gin.Context) {
web.db.Find(&watches)
// make a map[watch.ID] -> watch so after this we can add data to watches in O(1)
watchMap := make(map[uint]*Watch, len(watches))
watchMap := make(map[WatchID]*Watch, len(watches))
for i := 0; i < len(watches); i++ {
watchMap[watches[i].ID] = &watches[i]
}
@ -456,7 +456,7 @@ func (web *Web) index(c *gin.Context) {
log.Println(err)
} else {
for rows.Next() {
var watchID uint
var watchID WatchID
var _time sql.NullString
var value sql.NullString
err := rows.Scan(&watchID, &_time, &value)
@ -609,7 +609,7 @@ func (web *Web) watchCreatePost(c *gin.Context) {
// the IDs of filters and connections have to be 0 when they are added to the database
// otherwise they will overwrite whatever filters/connections happened to have the same ID
// so we set them all to 0, but keep a map of 'old filter ID' -> filter
filterMap := make(map[uint]*Filter)
filterMap := make(map[FilterID]*Filter)
for i := range export.Filters {
filter := &export.Filters[i]
filterMap[filter.ID] = filter
@ -811,7 +811,7 @@ func (web *Web) watchUpdate(c *gin.Context) {
web.db.Delete(&Filter{}, "watch_id = ?", watch.ID)
web.db.Delete(&ExpectFail{}, "watch_id = ?", watch.ID)
filterMap := make(map[uint]*Filter)
filterMap := make(map[FilterID]*Filter)
if len(newFilters) > 0 {
for i := range newFilters {
filter := &newFilters[i]
@ -1478,14 +1478,14 @@ func (web *Web) importWatch(c *gin.Context) {
}
}
filterMap := make(map[uint]*Filter)
filterMap := make(map[FilterID]*Filter)
for i := range export.Filters {
filter := &export.Filters[i]
filterMap[filter.ID] = filter
filter.ID = 0
filter.X += offsetX
filter.Y += offsetY
filter.WatchID = uint(watchID)
filter.WatchID = WatchID(watchID)
}
if clearFilters {
@ -1510,7 +1510,7 @@ func (web *Web) importWatch(c *gin.Context) {
for i := range export.Connections {
connection := &export.Connections[i]
connection.ID = 0
connection.WatchID = uint(watchID)
connection.WatchID = WatchID(watchID)
connection.OutputID = filterMap[connection.OutputID].ID
connection.InputID = filterMap[connection.InputID].ID
}