add uuid identifiers for timers

This commit is contained in:
lyx0 2023-10-04 00:05:38 +02:00
parent ec9045d2b6
commit 80d9ed9fdc
4 changed files with 98 additions and 56 deletions

View file

@ -6,6 +6,7 @@ import (
"strings"
"github.com/gempir/go-twitch-irc/v4"
"github.com/google/uuid"
"github.com/lyx0/nourybot/internal/data"
)
@ -42,12 +43,13 @@ func (app *application) AddTimer(name, repeat string, message twitch.PrivateMess
)
return
}
id := uuid.NewString()
timer := &data.Timer{
Name: name,
Text: text,
Channel: message.Channel,
Repeat: repeat,
Name: name,
Text: text,
Identifier: id,
Channel: message.Channel,
Repeat: repeat,
}
// Check if the time string we got is valid, this is important
@ -55,10 +57,11 @@ func (app *application) AddTimer(name, repeat string, message twitch.PrivateMess
// time format string is supplied.
if validateTimeFormat {
timer := &data.Timer{
Name: name,
Text: text,
Channel: message.Channel,
Repeat: repeat,
Name: name,
Text: text,
Identifier: id,
Channel: message.Channel,
Repeat: repeat,
}
err = app.Models.Timers.Insert(timer)
@ -74,9 +77,8 @@ func (app *application) AddTimer(name, repeat string, message twitch.PrivateMess
} else {
// cronName is the internal, unique tag/name for the timer.
// A timer named "sponsor" in channel "forsen" will be named "forsensponsor"
cronName := fmt.Sprintf("%s%s", message.Channel, name)
app.Scheduler.AddFunc(fmt.Sprintf("@every %s", repeat), func() { app.newPrivateMessageTimer(message.Channel, text) }, cronName)
app.Scheduler.AddFunc(fmt.Sprintf("@every %s", repeat), func() { app.newPrivateMessageTimer(message.Channel, text) }, id)
app.Log.Infow("Added new timer",
"timer", timer,
)
@ -116,14 +118,14 @@ func (app *application) EditTimer(name, repeat string, message twitch.PrivateMes
// -----------------------
// Delete the old timer
// -----------------------
cronName := fmt.Sprintf("%s%s", message.Channel, name)
app.Scheduler.RemoveJob(cronName)
identifier := old.Identifier
app.Scheduler.RemoveJob(identifier)
err = app.Models.Timers.Delete(name)
if err != nil {
app.Log.Errorw("Error deleting timer from database",
"name", name,
"cronName", cronName,
"identifier", identifier,
"error", err,
)
@ -165,11 +167,13 @@ func (app *application) EditTimer(name, repeat string, message twitch.PrivateMes
return
}
id := uuid.NewString()
timer := &data.Timer{
Name: name,
Text: text,
Channel: message.Channel,
Repeat: repeat,
Name: name,
Text: text,
Identifier: id,
Channel: message.Channel,
Repeat: repeat,
}
// Check if the time string we got is valid, this is important
@ -177,10 +181,11 @@ func (app *application) EditTimer(name, repeat string, message twitch.PrivateMes
// time format string is supplied.
if validateTimeFormat {
timer := &data.Timer{
Name: name,
Text: text,
Channel: message.Channel,
Repeat: repeat,
Name: name,
Text: text,
Identifier: id,
Channel: message.Channel,
Repeat: repeat,
}
err = app.Models.Timers.Insert(timer)
@ -196,9 +201,7 @@ func (app *application) EditTimer(name, repeat string, message twitch.PrivateMes
} else { // this is a bit scuffed. The else here is the end of a successful call.
// cronName is the internal, unique tag/name for the timer.
// A timer named "sponsor" in channel "forsen" will be named "forsensponsor"
cronName := fmt.Sprintf("%s%s", message.Channel, name)
app.Scheduler.AddFunc(fmt.Sprintf("@every %s", repeat), func() { app.newPrivateMessageTimer(message.Channel, text) }, cronName)
app.Scheduler.AddFunc(fmt.Sprintf("@every %s", repeat), func() { app.newPrivateMessageTimer(message.Channel, text) }, id)
app.Log.Infow("Updated a timer",
"Name", name,
@ -247,12 +250,12 @@ func (app *application) ListTimers() string {
t := fmt.Sprintf(
"ID: \t\t%v\n"+
"Name: \t\t%v\n"+
"CronName: \t\t%v\n"+
"Identifier: \t%v\n"+
"Text: \t\t%v\n"+
"Channel: \t%v\n"+
"Repeat: \t%v\n"+
"\n\n",
v.ID, v.Name, v.CronName, v.Text, v.Channel, v.Repeat,
v.ID, v.Name, v.Identifier, v.Text, v.Channel, v.Repeat,
)
// Add new value to the slice
@ -292,7 +295,6 @@ func (app *application) InitialTimers() {
// cronName is the internal, unique tag/name for the timer.
// A timer named "sponsor" in channel "forsen" will be named "forsensponsor"
cronName := fmt.Sprintf("%s%s", v.Channel, v.Name)
// Repeating is at what times the timer should repeat.
// 2 minute timer is @every 2m
@ -301,7 +303,7 @@ func (app *application) InitialTimers() {
// Add new value to the slice
ts = append(ts, v)
app.Scheduler.AddFunc(repeating, func() { app.newPrivateMessageTimer(v.Channel, v.Text) }, cronName)
app.Scheduler.AddFunc(repeating, func() { app.newPrivateMessageTimer(v.Channel, v.Text) }, v.Identifier)
}
app.Log.Infow("Initial timers",
@ -317,20 +319,29 @@ func (app *application) newPrivateMessageTimer(channel, text string) {
// DeleteTimer takes in the name of a timer and tries to delete the timer from the database.
func (app *application) DeleteTimer(name string, message twitch.PrivateMessage) {
cronName := fmt.Sprintf("%s%s", message.Channel, name)
app.Scheduler.RemoveJob(cronName)
identifier, err := app.Models.Timers.GetIdentifier(name)
if err != nil {
app.Log.Errorw("Error retrieving identifier rom database",
"name", name,
"identifier", identifier,
"error", err,
)
}
app.Scheduler.RemoveJob(identifier)
app.Log.Infow("Deleting timer",
"name", name,
"identifier", identifier,
"message.Channel", message.Channel,
"cronName", cronName,
)
err := app.Models.Timers.Delete(name)
err = app.Models.Timers.Delete(identifier)
if err != nil {
app.Log.Errorw("Error deleting timer from database",
"name", name,
"cronName", cronName,
"identifier", identifier,
"error", err,
)

View file

@ -47,6 +47,7 @@ type Models struct {
}
Timers interface {
Get(name string) (*Timer, error)
GetIdentifier(name string) (string, error)
Insert(timer *Timer) error
Update(timer *Timer) error
GetAll() ([]*Timer, error)

View file

@ -8,12 +8,12 @@ import (
)
type Timer struct {
ID int `json:"id" redis:"timer-id"`
Name string `json:"name" redis:"timer-name"`
CronName string `redis:"timer-cronname"`
Text string `json:"text" redis:"timer-text"`
Channel string `json:"channel" redis:"timer-channel"`
Repeat string `json:"repeat" redis:"timer-repeat"`
ID int `json:"id" redis:"timer-id"`
Name string `json:"name" redis:"timer-name"`
Identifier string `json:"identifier"`
Text string `json:"text" redis:"timer-text"`
Channel string `json:"channel" redis:"timer-channel"`
Repeat string `json:"repeat" redis:"timer-repeat"`
}
type TimerModel struct {
@ -22,7 +22,7 @@ type TimerModel struct {
func (t TimerModel) Get(name string) (*Timer, error) {
query := `
SELECT id, name, text, channel, repeat
SELECT id, name, identifier, text, channel, repeat
FROM timers
WHERE name = $1
`
@ -32,6 +32,7 @@ func (t TimerModel) Get(name string) (*Timer, error) {
err := t.DB.QueryRow(query, name).Scan(
&timer.ID,
&timer.Name,
&timer.Identifier,
&timer.Text,
&timer.Channel,
&timer.Repeat,
@ -48,15 +49,44 @@ func (t TimerModel) Get(name string) (*Timer, error) {
return &timer, nil
}
func (t TimerModel) GetIdentifier(name string) (string, error) {
query := `
SELECT id, name, identifier, text, channel, repeat
FROM timers
WHERE name = $1
`
var timer Timer
err := t.DB.QueryRow(query, name).Scan(
&timer.ID,
&timer.Name,
&timer.Identifier,
&timer.Text,
&timer.Channel,
&timer.Repeat,
)
if err != nil {
switch {
case errors.Is(err, sql.ErrNoRows):
return "", ErrRecordNotFound
default:
return "", err
}
}
return timer.Identifier, nil
}
// Insert adds a command into the database.
func (t TimerModel) Insert(timer *Timer) error {
query := `
INSERT into timers(name, text, channel, repeat)
VALUES ($1, $2, $3, $4)
INSERT into timers(name, identifier, text, channel, repeat)
VALUES ($1, $2, $3, $4, $5)
RETURNING id;
`
args := []interface{}{timer.Name, timer.Text, timer.Channel, timer.Repeat}
args := []interface{}{timer.Name, timer.Identifier, timer.Text, timer.Channel, timer.Repeat}
result, err := t.DB.Exec(query, args...)
if err != nil {
@ -78,7 +108,7 @@ func (t TimerModel) Insert(timer *Timer) error {
// GetAll() returns a pointer to a slice of all channels (`[]*Channel`) in the database.
func (t TimerModel) GetAll() ([]*Timer, error) {
query := `
SELECT id, name, text, channel, repeat
SELECT id, name, identifier, text, channel, repeat
FROM timers
ORDER BY id`
@ -110,6 +140,7 @@ func (t TimerModel) GetAll() ([]*Timer, error) {
err := rows.Scan(
&timer.ID,
&timer.Name,
&timer.Identifier,
&timer.Text,
&timer.Channel,
&timer.Repeat,
@ -158,14 +189,14 @@ func (t TimerModel) Update(timer *Timer) error {
// Delete takes in a command name and queries the database for an entry with
// the same name and tries to delete that entry.
func (t TimerModel) Delete(name string) error {
func (t TimerModel) Delete(identifier string) error {
// Prepare the statement.
query := `
DELETE FROM timers
WHERE name = $1`
WHERE identifier = $1`
// Execute the query returning the number of affected rows.
result, err := t.DB.Exec(query, name)
result, err := t.DB.Exec(query, identifier)
if err != nil {
return err
}

View file

@ -1,17 +1,16 @@
CREATE TABLE IF NOT EXISTS timers (
id bigserial PRIMARY KEY,
name text NOT NULL,
identifier text NOT NULL,
text text NOT NULL,
channel text NOT NULL,
repeat text NOT NULL
);
INSERT INTO timers (name,"text",channel,repeat) VALUES
('nourylul-60m','timer every 60 minutes :)','nourylul','60m'),
('nourylul-2m','timer every 2 minutes :)','nourylul','2m'),
('nourybot-60m','timer every 60 minutes :)','nourybot','60m'),
('nourybot-1h','timer every 1 hour :)','nourybot','1h'),
('xnoury-60m','timer every 420 minutes :)','xnoury','420m'),
('xnoury-1h','timer every 1 hour :)','xnoury','1h'),
('xnoury-15m','180 minutes timer :)','xnoury','180m');
INSERT INTO timers (name,identifier,"text",channel,repeat) VALUES
('nourylul-60m','678efbe2-fa2f-4849-8dbc-9ec32e6ffd3b','timer every 60 minutes :)','nourylul','60m'),
('nourylul-2m','63142f10-1672-4353-8b03-e72f5a4dd566','timer every 2 minutes :)','nourylul','2m'),
('nourybot-60m','2ad01f96-05d3-444e-9dd6-524d397caa96','timer every 60 minutes :)','nourybot','60m'),
('nourybot-1h','2353fd22-fef9-4cbd-b01e-bc8804992f4c', 'timer every 1 hour :)','nourybot','1h'),
('xnoury-15m','6e178e14-36c2-45e1-af59-b5dea4903fee','180 minutes timer :)','xnoury','180m');