From 76d13f398c44a954e20496d3c7bf2a50cf419120 Mon Sep 17 00:00:00 2001 From: "Tim (robske_110)" Date: Tue, 27 Feb 2024 20:17:51 +0100 Subject: [PATCH] Add removeRule support for db --- cmd/ical-relay/api.go | 2 +- cmd/ical-relay/config.go | 23 ++++++++++++++------ cmd/ical-relay/data.go | 3 ++- cmd/ical-relay/database.go | 41 +++++++++++++++++++---------------- cmd/ical-relay/dbDataStore.go | 4 ++-- 5 files changed, 43 insertions(+), 30 deletions(-) diff --git a/cmd/ical-relay/api.go b/cmd/ical-relay/api.go index 70b192d..451b9ca 100644 --- a/cmd/ical-relay/api.go +++ b/cmd/ical-relay/api.go @@ -553,7 +553,7 @@ func rulesApiHandler(w http.ResponseWriter, r *http.Request) { return } - dataStore.removeRuleFromProfile(profileName, idint) + dataStore.removeRule(profileName, Rule{id: idint}) } } diff --git a/cmd/ical-relay/config.go b/cmd/ical-relay/config.go index 31e6e4e..7605229 100644 --- a/cmd/ical-relay/config.go +++ b/cmd/ical-relay/config.go @@ -200,6 +200,7 @@ func (c Config) profileExists(name string) bool { } func (c Config) getProfileByName(name string) profile { + c.populateRuleIds(name) return c.Profiles[name] } @@ -216,7 +217,6 @@ func (c Config) addProfile(name string, sources []string, public bool, immutable func (c Config) editProfile(name string, sources []string, public bool, immutablepast bool) { c.Profiles[name] = profile{ - Name: name, Sources: sources, Public: public, ImmutablePast: immutablepast, @@ -245,11 +245,11 @@ func (c Config) addRule(profileName string, rule Rule) error { return nil } -func (c Config) removeRuleFromProfile(profile string, index int) { - log.Info("Removing rule at position " + fmt.Sprint(index+1) + " from profile " + profile) - p := c.Profiles[profile] - p.Rules = append(p.Rules[:index], p.Rules[index+1:]...) - c.Profiles[profile] = p +func (c Config) removeRule(profileName string, rule Rule) { + log.Info("Removing rule at position " + fmt.Sprint(rule.id+1) + " from profile " + profileName) + p := c.Profiles[profileName] + p.Rules = append(p.Rules[:rule.id], p.Rules[rule.id+1:]...) + c.Profiles[profileName] = p } func (c Config) createToken(profileName string, note *string) error { @@ -337,6 +337,15 @@ func (c Config) removeNotifyRecipient(notifierName string, recipient string) err return fmt.Errorf("recipient not found") } +// internal helper functions + +func (c Config) populateRuleIds(profileName string) { + p := c.Profiles[profileName] + for id, rule := range p.Rules { + rule.id = id + } +} + // LEGACY functions (to be moved elsewhere, or not supported yet by DataStore) // TODO: move this function into the application code @@ -361,7 +370,7 @@ func (c Config) RunCleanup() { log.Errorf("RunCleanup could not parse the expiry time: %s", err.Error()) } if time.Now().After(exp) { - c.removeRuleFromProfile(p, i) + c.removeRule(p, Rule{id: i}) } } } diff --git a/cmd/ical-relay/data.go b/cmd/ical-relay/data.go index 7d6dce4..d14fe2a 100644 --- a/cmd/ical-relay/data.go +++ b/cmd/ical-relay/data.go @@ -12,7 +12,7 @@ type DataStore interface { editProfile(name string, sources []string, public bool, immutablePast bool) //TODO: either make this take a profile type or split it into explicit editing functions addSource(profileName string, src string) error addRule(profileName string, rule Rule) error - removeRuleFromProfile(profile string, index int) + removeRule(profileName string, rule Rule) //editRule(string profileName, rule Rule) createToken(profileName string, note *string) error modifyTokenNote(profileName string, token string, note *string) error @@ -44,6 +44,7 @@ type profile struct { } type Rule struct { + id int Filters []map[string]string `yaml:"filters" json:"filters"` Operator string `yaml:"operator" json:"operator"` Action map[string]string `yaml:"action" json:"action"` diff --git a/cmd/ical-relay/database.go b/cmd/ical-relay/database.go index 842c7e8..fa61803 100644 --- a/cmd/ical-relay/database.go +++ b/cmd/ical-relay/database.go @@ -110,7 +110,7 @@ func setDbVersion(dbVersion int) { // these structs are only used for reading type dbRule struct { - Id int64 `db:"id"` + Id int `db:"id"` Operator string `db:"operator"` ActionType string `db:"action_type"` ActionParameters string `db:"action_parameters"` @@ -186,6 +186,7 @@ JOIN profile_sources ps ON id = ps.source WHERE ps.profile = $1`, log.Tracef("%#v\n", dbRules) for _, dbRule := range dbRules { rule := new(Rule) + rule.id = dbRule.Id rule.Operator = dbRule.Operator if dbRule.Expiry != nil { rule.Expiry = dbRule.Expiry.Format(time.RFC3339) @@ -244,7 +245,7 @@ JOIN profile_sources ps ON id = ps.source WHERE profile = $1 AND url = $2)`, pro } func dbAddProfileSource(profile profile, source string) { - var sourceId int64 + var sourceId int err := db.Get(&sourceId, `INSERT INTO source (url) VALUES ($1) RETURNING id`, source) if err != nil { log.Fatal(err) @@ -275,14 +276,18 @@ func dbRemoveAllProfileSources(profile profile) { } } -// TODO: fix this, leaves orphans currently -func dbRemoveProfileSource(profile profile, sourceId int64) { +func dbRemoveProfileSource(profile profile, sourceId int) { _, err := db.Exec(`DELETE FROM profile_sources WHERE profile = $1 AND source = $2`, profile.Name, sourceId) if err != nil { log.Fatal(err) return } + dbCleanupOrphanSources() +} + +func dbCleanupOrphanSources() { + //TODO } // used for importing @@ -298,7 +303,7 @@ func dbProfileRuleExists(profile profile, rule Rule) bool { panic(err) } - var ruleIds []int64 + var ruleIds []int if rule.Expiry != "" { // stored as true NULL in db err = db.Select( &ruleIds, `SELECT id FROM rule WHERE profile = $1 AND operator = $2 @@ -362,7 +367,7 @@ func dbAddProfileRule(profile profile, rule Rule) { var expiry sql.NullString expiry.String = rule.Expiry - var ruleId int64 + var ruleId int err = db.QueryRow( `INSERT INTO rule (profile, operator, action_type, action_parameters, expiry) VALUES ($1, $2, $3, $4, $5) RETURNING id`, profile.Name, rule.Operator, actionType, parametersJson, expiry).Scan(&ruleId) @@ -375,7 +380,7 @@ func dbAddProfileRule(profile profile, rule Rule) { } } -func dbAddRuleFilter(ruleId int64, filter map[string]string) { +func dbAddRuleFilter(ruleId int, filter map[string]string) { filterType := filter["type"] delete(filter, "type") //TODO: possibly deep-copy parametersJson, err := json.Marshal(filter) @@ -390,18 +395,11 @@ func dbAddRuleFilter(ruleId int64, filter map[string]string) { } } -// TODO: replace with dbRemoveRule (by id only) -// this is currently somewhat expensive, since we need to find the module by the full parameters -func dbRemoveProfileModule(profile profile, module map[string]string) { - name := module["name"] - delete(module, "name") - parametersJson, err := json.Marshal(module) - if err != nil { - panic(err) - } - _, err = db.Exec( - `DELETE FROM module WHERE profile=$1 AND name=$2 AND parameters=$3`, - profile.Name, name, parametersJson) +func dbRemoveRule(profile profile, ruleId int) { + //TODO: ignore profile passed here, ruleIds are unique + _, err := db.Exec( + `DELETE FROM rule WHERE profile=$1 AND id=$2`, + profile.Name, ruleId) if err != nil { panic(err) } @@ -516,6 +514,11 @@ func dbDeleteNotifier(notifier notifier) { if err != nil { panic(err) } + dbCleanupOrphanRecipients() +} + +func dbCleanupOrphanRecipients() { + //TODO } func dbAddNotifierRecipient(notifier notifier, recipient string) { diff --git a/cmd/ical-relay/dbDataStore.go b/cmd/ical-relay/dbDataStore.go index e946c66..1331013 100644 --- a/cmd/ical-relay/dbDataStore.go +++ b/cmd/ical-relay/dbDataStore.go @@ -69,8 +69,8 @@ func (c DatabaseDataStore) addRule(profileName string, rule Rule) error { return nil } -func (c DatabaseDataStore) removeRuleFromProfile(profile string, index int) { - log.Error("removeRuleFromProfile currently not supported on db") // TODO: implement +func (c DatabaseDataStore) removeRule(profileName string, rule Rule) { + dbRemoveRule(profile{Name: profileName}, rule.id) } func (c DatabaseDataStore) createToken(profileName string, note *string) error {