From 92e1ea5d42647e9f4bdf62bdd0d2f6bb455700af Mon Sep 17 00:00:00 2001 From: Chris Sexton Date: Fri, 15 Jan 2016 11:54:09 -0500 Subject: [PATCH] Update first plugin for SQL --- main.go | 2 +- plugins/first.go | 112 +++++++++++++++++++++++++++++++++++------------ 2 files changed, 86 insertions(+), 28 deletions(-) diff --git a/main.go b/main.go index a5ec0ed..b738fb6 100644 --- a/main.go +++ b/main.go @@ -57,7 +57,7 @@ func main() { Bot = bot.NewBot(Config, Client) // Bot.AddHandler(plugins.NewTestPlugin(Bot)) Bot.AddHandler("admin", plugins.NewAdminPlugin(Bot)) - // Bot.AddHandler("first", plugins.NewFirstPlugin(Bot)) + Bot.AddHandler("first", plugins.NewFirstPlugin(Bot)) // Bot.AddHandler("downtime", plugins.NewDowntimePlugin(Bot)) Bot.AddHandler("talker", plugins.NewTalkerPlugin(Bot)) Bot.AddHandler("dice", plugins.NewDicePlugin(Bot)) diff --git a/plugins/first.go b/plugins/first.go index 3cf1656..58b2868 100644 --- a/plugins/first.go +++ b/plugins/first.go @@ -3,6 +3,7 @@ package plugins import ( + "database/sql" "fmt" "log" "regexp" @@ -10,8 +11,6 @@ import ( "time" "github.com/chrissexton/alepale/bot" - "labix.org/v2/mgo" - "labix.org/v2/mgo/bson" ) // This is a first plugin to serve as an example and quick copy/paste for new plugins. @@ -19,41 +18,96 @@ import ( type FirstPlugin struct { First *FirstEntry Bot *bot.Bot - Coll *mgo.Collection + db *sql.DB } type FirstEntry struct { - Day time.Time - Time time.Time - Body string - Nick string + id int64 + day time.Time + time time.Time + body string + nick string + saved bool +} + +// Insert or update the first entry +func (fe *FirstEntry) save(db *sql.DB) error { + if _, err := db.Exec(`insert into first (day, time, body, nick) + values (?, ?, ?, ?)`, + fe.day, + fe.time, + fe.body, + fe.nick, + ); err != nil { + return err + } + return nil } // NewFirstPlugin creates a new FirstPlugin with the Plugin interface func NewFirstPlugin(b *bot.Bot) *FirstPlugin { - // Mongo is removed, this plugin will crash if started - log.Fatal("The First plugin has not been upgraded to SQL yet.") - var coll *mgo.Collection - // coll := b.Db.C("first") - var firsts []FirstEntry - query := bson.M{"day": midnight(time.Now())} - log.Println("Day:", midnight(time.Now())) - coll.Find(query).All(&firsts) + if b.DBVersion == 1 { + _, err := b.DB.Exec(`create table if not exists first ( + id integer primary key, + day datetime, + time datetime, + body string, + nick string + );`) + if err != nil { + log.Fatal("Could not create first table: ", err) + } + } - log.Println("FIRSTS:", firsts) + log.Println("First plugin initialized with day:", midnight(time.Now())) - var first *FirstEntry - if len(firsts) > 0 { - first = &firsts[0] + first, err := getLastFirst(b.DB) + if err != nil { + log.Fatal("Could not initialize first plugin: ", err) } return &FirstPlugin{ Bot: b, - Coll: coll, + db: b.DB, First: first, } } +func getLastFirst(db *sql.DB) (*FirstEntry, error) { + // Get last first entry + var id sql.NullInt64 + var day sql.NullInt64 + var timeEntered sql.NullInt64 + var body sql.NullString + var nick sql.NullString + + err := db.QueryRow(`select + id, max(day), time, body, nick from first + limit 1; + `).Scan( + &id, + &day, + &timeEntered, + &body, + &nick, + ) + switch { + case err == sql.ErrNoRows || !id.Valid: + log.Println("No previous first entries") + return nil, nil + case err != nil: + return nil, err + } + return &FirstEntry{ + id: id.Int64, + day: time.Unix(day.Int64, 0), + time: time.Unix(timeEntered.Int64, 0), + body: body.String, + nick: nick.String, + saved: true, + }, nil +} + func midnight(t time.Time) time.Time { y, m, d := t.Date() return time.Date(y, m, d, 0, 0, 0, 0, time.UTC) @@ -74,7 +128,7 @@ func (p *FirstPlugin) Message(message bot.Message) bool { p.recordFirst(message) return false } else if p.First != nil { - if isToday(p.First.Time) && p.allowed(message) { + if isToday(p.First.time) && p.allowed(message) { p.recordFirst(message) return false } @@ -122,12 +176,16 @@ func (p *FirstPlugin) allowed(message bot.Message) bool { func (p *FirstPlugin) recordFirst(message bot.Message) { log.Println("Recording first: ", message.User.Name, ":", message.Body) p.First = &FirstEntry{ - Day: midnight(time.Now()), - Time: message.Time, - Body: message.Body, - Nick: message.User.Name, + day: midnight(time.Now()), + time: message.Time, + body: message.Body, + nick: message.User.Name, + } + err := p.First.save(p.db) + if err != nil { + log.Println("Error saving first entry: ", err) + return } - p.Coll.Insert(p.First) p.announceFirst(message) } @@ -135,7 +193,7 @@ func (p *FirstPlugin) announceFirst(message bot.Message) { c := message.Channel if p.First != nil { p.Bot.SendMessage(c, fmt.Sprintf("%s had first at %s with the message: \"%s\"", - p.First.Nick, p.First.Time.Format(time.Kitchen), p.First.Body)) + p.First.nick, p.First.time.Format(time.Kitchen), p.First.body)) } }