From 579327852343e8e4cac3d6139f4f8e258938f831 Mon Sep 17 00:00:00 2001 From: William Perron Date: Fri, 23 Sep 2022 13:53:19 +0000 Subject: [PATCH] add query context with timeline Also change the row column types to sql.NullString to handle cases where null values were causing errors in row scanning. --- cmd/themis-server/main.go | 11 +++++++++-- fmt.go | 10 +++++----- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/cmd/themis-server/main.go b/cmd/themis-server/main.go index 61d1421..f5a47ca 100644 --- a/cmd/themis-server/main.go +++ b/cmd/themis-server/main.go @@ -12,6 +12,7 @@ import ( "strconv" "strings" "syscall" + "time" "github.com/bwmarrin/discordgo" _ "github.com/mattn/go-sqlite3" @@ -378,7 +379,9 @@ func main() { } q := i.ApplicationCommandData().Options[0].StringValue() - rows, err := roDB.Query(q) + deadlined, cancelDeadline := context.WithTimeout(ctx, 15*time.Second) + defer cancelDeadline() + rows, err := roDB.QueryContext(deadlined, q) if err != nil { log.Error().Err(err).Msg("failed to exec user-provided query") return @@ -389,7 +392,10 @@ func main() { log.Error().Err(err).Msg("failed to format rows") } - table := fmt.Sprintf("```\n%s\n```", fmtd[:min(len(fmtd), 1990)]) // TODO(wperron) find a better way to cutover + // 2000 is a magic number here, it's the character limit for a discord + // message, we're cutting slightly under that to allow the backticks + // for the monospaced block. + table := fmt.Sprintf("```\n%s\n```", fmtd[:min(len(fmtd), 1990)]) if err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ Type: discordgo.InteractionResponseChannelMessageWithSource, @@ -429,6 +435,7 @@ func main() { }() <-ctx.Done() + log.Info().Msg("context cancelled, exiting") for _, c := range registeredCommands { err = discord.ApplicationCommandDelete(appId, guildId, c.ID) diff --git a/fmt.go b/fmt.go index 4f94156..750b523 100644 --- a/fmt.go +++ b/fmt.go @@ -29,7 +29,7 @@ func FormatRows(rows *sql.Rows) (string, error) { for rows.Next() { row := make([]interface{}, len(cols)) for i := range row { - row[i] = new(string) + row[i] = new(sql.NullString) } if err := rows.Scan(row...); err != nil { return "", fmt.Errorf("failed to scan next row: %w", err) @@ -37,9 +37,9 @@ func FormatRows(rows *sql.Rows) (string, error) { scanned = append(scanned, row) // keep track of row for later for i, a := range row { - s := a.(*string) - if len(*s) > lengths[i] { - lengths[i] = len(*s) + s := a.(*sql.NullString) + if len(s.String) > lengths[i] { + lengths[i] = len(s.String) } } } @@ -62,7 +62,7 @@ func FormatRows(rows *sql.Rows) (string, error) { for _, r := range scanned { curr = curr[:0] // empty slice but preserve capacity for i := range lengths { - s := r[i].(*string) + s := r[i].(*sql.NullString) curr = append(curr, lengths[i], *s) } sb.WriteString(fmt.Sprintf(pattern, curr...))