Fix variable support

This commit is contained in:
Chris Sexton 2016-05-20 16:28:48 -04:00
parent b048890b05
commit 079c6ab2ec
3 changed files with 42 additions and 52 deletions

View File

@ -149,22 +149,12 @@ func (b *bot) migrateDB() {
} }
} }
if b.dbVersion == 1 {
if _, err := b.db.Exec(`create table if not exists variables ( if _, err := b.db.Exec(`create table if not exists variables (
id integer primary key, id integer primary key,
name string, name string,
perms string,
type string
);`); err != nil {
log.Fatal("Initial DB migration create variables table: ", err)
}
if _, err := b.db.Exec(`create table if not exists 'values' (
id integer primary key,
varId integer,
value string value string
);`); err != nil { );`); err != nil {
log.Fatal("Initial DB migration create values table: ", err) log.Fatal("Initial DB migration create variables table: ", err)
}
} }
} }

View File

@ -159,7 +159,7 @@ func (b *bot) Filter(message msg.Message, input string) string {
func (b *bot) getVar(varName string) (string, error) { func (b *bot) getVar(varName string) (string, error) {
var text string var text string
err := b.db.QueryRow(`select v.value from variables as va inner join "values" as v on va.id = va.id = v.varId order by random() limit 1`).Scan(&text) err := b.db.Get(&text, `select value from variables where name=? order by random() limit 1`, varName)
switch { switch {
case err == sql.ErrNoRows: case err == sql.ErrNoRows:
return "", fmt.Errorf("No factoid found") return "", fmt.Errorf("No factoid found")
@ -170,19 +170,14 @@ func (b *bot) getVar(varName string) (string, error) {
} }
func (b *bot) listVars(channel string, parts []string) { func (b *bot) listVars(channel string, parts []string) {
rows, err := b.db.Query(`select name from variables`) var variables []string
err := b.db.Select(&variables, `select name from variables group by name`)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
msg := "I know: $who, $someone, $digit, $nonzero" msg := "I know: $who, $someone, $digit, $nonzero"
for rows.Next() { if len(variables) > 0 {
var variable string msg += ", " + strings.Join(variables, ", ")
err := rows.Scan(&variable)
if err != nil {
log.Println("Error scanning variable.")
continue
}
msg = fmt.Sprintf("%s, %s", msg, variable)
} }
b.SendMessage(channel, msg) b.SendMessage(channel, msg)
} }

View File

@ -3,8 +3,6 @@
package admin package admin
import ( import (
"database/sql"
"fmt"
"log" "log"
"math/rand" "math/rand"
"strings" "strings"
@ -19,14 +17,14 @@ import (
type AdminPlugin struct { type AdminPlugin struct {
Bot bot.Bot Bot bot.Bot
DB *sqlx.DB db *sqlx.DB
} }
// NewAdminPlugin creates a new AdminPlugin with the Plugin interface // NewAdminPlugin creates a new AdminPlugin with the Plugin interface
func New(bot bot.Bot) *AdminPlugin { func New(bot bot.Bot) *AdminPlugin {
p := &AdminPlugin{ p := &AdminPlugin{
Bot: bot, Bot: bot,
DB: bot.DB(), db: bot.DB(),
} }
p.LoadData() p.LoadData()
return p return p
@ -36,18 +34,8 @@ func New(bot bot.Bot) *AdminPlugin {
// This function returns true if the plugin responds in a meaningful way to the users message. // This function returns true if the plugin responds in a meaningful way to the users message.
// Otherwise, the function returns false and the bot continues execution of other plugins. // Otherwise, the function returns false and the bot continues execution of other plugins.
func (p *AdminPlugin) Message(message msg.Message) bool { func (p *AdminPlugin) Message(message msg.Message) bool {
// This bot does not reply to anything
if !message.User.Admin {
return false
}
body := message.Body body := message.Body
if len(body) == 0 {
return false
}
if body[0] == '$' { if body[0] == '$' {
return p.handleVariables(message) return p.handleVariables(message)
} }
@ -56,32 +44,49 @@ func (p *AdminPlugin) Message(message msg.Message) bool {
} }
func (p *AdminPlugin) handleVariables(message msg.Message) bool { func (p *AdminPlugin) handleVariables(message msg.Message) bool {
if parts := strings.SplitN(message.Body, "!=", 2); len(parts) == 2 {
variable := strings.ToLower(strings.TrimSpace(parts[0]))
value := strings.TrimSpace(parts[1])
_, err := p.db.Exec(`delete from variables where name=? and value=?`, variable, value)
if err != nil {
p.Bot.SendMessage(message.Channel, "I'm broke and need attention in my variable creation code.")
log.Println("[admin]: ", err)
} else {
p.Bot.SendMessage(message.Channel, "Removed.")
}
return true
}
parts := strings.SplitN(message.Body, "=", 2) parts := strings.SplitN(message.Body, "=", 2)
if len(parts) != 2 { if len(parts) != 2 {
return false return false
} }
variable := strings.TrimSpace(parts[0]) variable := strings.ToLower(strings.TrimSpace(parts[0]))
value := parts[1] value := strings.TrimSpace(parts[1])
var count int64 var count int64
var varId int64 row := p.db.QueryRow(`select count(*) from variables where value = ?`, variable, value)
err := p.DB.QueryRow(`select count(*), varId from variables vs inner join "values" v on vs.id = v.varId where vs.name = ? and v.value = ?`, variable, value).Scan(&count) err := row.Scan(&count)
switch {
case err == sql.ErrNoRows:
_, err := p.DB.Exec(`insert into "values" (varId, value) values (?, ?)`, varId, value)
if err != nil { if err != nil {
log.Println(err)
}
msg := fmt.Sprintf("Added '%s' to %s.\n", value, variable)
p.Bot.SendMessage(message.Channel, msg)
return true
case err != nil:
p.Bot.SendMessage(message.Channel, "I'm broke and need attention in my variable creation code.") p.Bot.SendMessage(message.Channel, "I'm broke and need attention in my variable creation code.")
log.Println("Admin error: ", err) log.Println("[admin]: ", err)
return true return true
} }
if count > 0 {
p.Bot.SendMessage(message.Channel, "I've already got that one.") p.Bot.SendMessage(message.Channel, "I've already got that one.")
} else {
_, err := p.db.Exec(`INSERT INTO variables (name, value) VALUES (?, ?)`, variable, value)
if err != nil {
p.Bot.SendMessage(message.Channel, "I'm broke and need attention in my variable creation code.")
log.Println("[admin]: ", err)
return true
}
p.Bot.SendMessage(message.Channel, "Added.")
}
return true return true
} }