From 0f9668704d99f70afec477afc05fee1b8cee319f Mon Sep 17 00:00:00 2001 From: William Perron Date: Fri, 9 Sep 2022 12:33:28 -0400 Subject: [PATCH] add `delete-claim` command (#12) Closes #9 --- cmd/themis-server/main.go | 46 +++++++++++++++++++++++++++++++++++++++ store.go | 24 ++++++++++++++++++++ store_test.go | 22 +++++++++++++++++-- 3 files changed, 90 insertions(+), 2 deletions(-) diff --git a/cmd/themis-server/main.go b/cmd/themis-server/main.go index 06bd6d5..69f094b 100644 --- a/cmd/themis-server/main.go +++ b/cmd/themis-server/main.go @@ -104,6 +104,18 @@ func main() { }, }, }, + { + Name: "delete-claim", + Description: "Release one of your claims", + Type: discordgo.ChatApplicationCommand, + Options: []*discordgo.ApplicationCommandOption{ + { + Name: "id", + Description: "numerical ID for the claim", + Type: discordgo.ApplicationCommandOptionInteger, + }, + }, + }, } handlers := map[string]Handler{ "ping": func(s *discordgo.Session, i *discordgo.InteractionCreate) { @@ -219,6 +231,40 @@ func main() { log.Println("[error] failed to respond to command:", err) } }, + "delete-claim": func(s *discordgo.Session, i *discordgo.InteractionCreate) { + id := i.ApplicationCommandData().Options[0] + nick := i.Member.Nick + if nick == "" { + nick = i.Member.User.Username + } + err := store.DeleteClaim(ctx, int(id.IntValue()), nick) + if err != nil { + msg := "Oops, something went wrong :( blame @wperron" + if errors.Is(err, themis.ErrNoSuchClaim) { + msg = err.Error() + } + log.Printf("[error]: %s\n", err) + err = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ + Type: discordgo.InteractionResponseChannelMessageWithSource, + Data: &discordgo.InteractionResponseData{ + Content: msg, + }, + }) + if err != nil { + log.Println("[error] failed to respond to command:", err) + } + } + + err = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ + Type: discordgo.InteractionResponseChannelMessageWithSource, + Data: &discordgo.InteractionResponseData{ + Content: "Got it chief.", + }, + }) + if err != nil { + log.Println("[error] failed to respond to command:", err) + } + }, } registerHandlers(discord, handlers) diff --git a/store.go b/store.go index a930a89..b2aeffa 100644 --- a/store.go +++ b/store.go @@ -4,6 +4,7 @@ import ( "context" "database/sql" _ "embed" + "errors" "fmt" "strings" @@ -268,3 +269,26 @@ func (s *Store) DescribeClaim(ctx context.Context, ID int) (ClaimDetail, error) Provinces: provinces, }, nil } + +var ErrNoSuchClaim = errors.New("No such claim found for player") + +func (s *Store) DeleteClaim(ctx context.Context, ID int, player string) error { + stmt, err := s.db.PrepareContext(ctx, "DELETE FROM claims WHERE id = ? AND player = ?") + if err != nil { + return fmt.Errorf("failed to prepare query: %w", err) + } + + res, err := stmt.ExecContext(ctx, ID, player) + if err != nil { + return fmt.Errorf("failed to delete claim ID %d: %w", ID, err) + } + + rows, err := res.RowsAffected() + if err != nil { + return fmt.Errorf("failed to get affected rows: %w", err) + } + if rows == 0 { + return ErrNoSuchClaim + } + return nil +} diff --git a/store_test.go b/store_test.go index 7e89ba6..5457b79 100644 --- a/store_test.go +++ b/store_test.go @@ -9,8 +9,10 @@ import ( "github.com/stretchr/testify/assert" ) +const TEST_CONN_STRING = "file::memory:?cache=shared" + func TestStore_Claim(t *testing.T) { - store, err := NewStore("file::memory:?cache=shared") + store, err := NewStore(TEST_CONN_STRING) assert.NoError(t, err) type args struct { @@ -70,7 +72,7 @@ func TestStore_Claim(t *testing.T) { } func TestAvailability(t *testing.T) { - store, err := NewStore("file::memory:?cache=shared") + store, err := NewStore(TEST_CONN_STRING) assert.NoError(t, err) store.Claim(context.TODO(), "foo", "Genoa", CLAIM_TYPE_TRADE) @@ -115,3 +117,19 @@ func TestAvailability(t *testing.T) { assert.NoError(t, err) assert.Equal(t, 3, len(availability)) // availability for areas should be the same as before } + +func TestDeleteClaim(t *testing.T) { + store, err := NewStore(TEST_CONN_STRING) + assert.NoError(t, err) + + store.Claim(context.TODO(), "foo", "Genoa", CLAIM_TYPE_TRADE) + store.Claim(context.TODO(), "bar", "Balkans", CLAIM_TYPE_REGION) + store.Claim(context.TODO(), "baz", "English Channel", CLAIM_TYPE_TRADE) + + err = store.DeleteClaim(context.TODO(), 1, "foo") + assert.NoError(t, err) + + err = store.DeleteClaim(context.TODO(), 2, "foo") + assert.Error(t, err) + assert.ErrorIs(t, err, ErrNoSuchClaim) +}