From 921ecbb8c631ce5109a7aeaa05486433d2514bf7 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Thu, 23 Dec 2021 15:23:29 +0000 Subject: Refactor code to reduce function size --- internal/mapr/groupsetresult.go | 222 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100644 internal/mapr/groupsetresult.go (limited to 'internal/mapr/groupsetresult.go') diff --git a/internal/mapr/groupsetresult.go b/internal/mapr/groupsetresult.go new file mode 100644 index 0000000..0e8e6e3 --- /dev/null +++ b/internal/mapr/groupsetresult.go @@ -0,0 +1,222 @@ +package mapr + +import ( + "errors" + "fmt" + "os" + "strings" + + "github.com/mimecast/dtail/internal/color" + "github.com/mimecast/dtail/internal/config" + "github.com/mimecast/dtail/internal/io/dlog" + "github.com/mimecast/dtail/internal/io/pool" + "github.com/mimecast/dtail/internal/protocol" +) + +// Result returns a nicely formated result of the query from the group set. +func (g *GroupSet) Result(query *Query, rowsLimit int) (string, int, error) { + rows, columnWidths, err := g.result(query, true) + if err != nil { + return "", 0, err + } + if query.Limit != -1 { + rowsLimit = query.Limit + } + lastColumn := len(query.Select) - 1 + + sb := pool.BuilderBuffer.Get().(*strings.Builder) + defer pool.RecycleBuilderBuffer(sb) + + g.resultWriteFormattedHeader(query, sb, lastColumn, rowsLimit, columnWidths) + g.resultWriteFormattedHeaderSeparator(query, sb, lastColumn, columnWidths) + g.resultWriteFormattedData(query, sb, lastColumn, rowsLimit, columnWidths, rows) + + return sb.String(), len(rows), nil +} + +// Write a nicely formatted header for the result data. +func (g *GroupSet) resultWriteFormattedHeader(query *Query, sb *strings.Builder, + lastColumn, rowsLimit int, columnWidths []int) { + + for i, sc := range query.Select { + format := fmt.Sprintf(" %%%ds ", columnWidths[i]) + str := fmt.Sprintf(format, sc.FieldStorage) + if config.Client.TermColorsEnable { + attrs := []color.Attribute{config.Client.TermColors.MaprTable.HeaderAttr} + if sc.FieldStorage == query.OrderBy { + attrs = append(attrs, config.Client.TermColors.MaprTable.HeaderSortKeyAttr) + } + + for _, groupBy := range query.GroupBy { + if sc.FieldStorage == groupBy { + attrs = append(attrs, config.Client.TermColors.MaprTable.HeaderGroupKeyAttr) + break + } + } + + color.PaintWithAttrs(sb, str, + config.Client.TermColors.MaprTable.HeaderFg, + config.Client.TermColors.MaprTable.HeaderBg, + attrs) + } else { + sb.WriteString(str) + } + + if i == lastColumn { + continue + } + if config.Client.TermColorsEnable { + color.PaintWithAttr(sb, protocol.FieldDelimiter, + config.Client.TermColors.MaprTable.HeaderDelimiterFg, + config.Client.TermColors.MaprTable.HeaderDelimiterBg, + config.Client.TermColors.MaprTable.HeaderDelimiterAttr) + } else { + sb.WriteString(protocol.FieldDelimiter) + } + } + sb.WriteString("\n") +} + +// This writes a nicely formatted line separating the header and the data. +func (g *GroupSet) resultWriteFormattedHeaderSeparator(query *Query, sb *strings.Builder, + lastColumn int, columnWidths []int) { + + for i := 0; i < len(query.Select); i++ { + str := fmt.Sprintf("-%s-", strings.Repeat("-", columnWidths[i])) + if config.Client.TermColorsEnable { + color.PaintWithAttr(sb, str, + config.Client.TermColors.MaprTable.HeaderDelimiterFg, + config.Client.TermColors.MaprTable.HeaderDelimiterBg, + config.Client.TermColors.MaprTable.HeaderDelimiterAttr) + } else { + sb.WriteString(str) + } + if i == lastColumn { + continue + } + if config.Client.TermColorsEnable { + color.PaintWithAttr(sb, protocol.FieldDelimiter, + config.Client.TermColors.MaprTable.HeaderDelimiterFg, + config.Client.TermColors.MaprTable.HeaderDelimiterBg, + config.Client.TermColors.MaprTable.HeaderDelimiterAttr) + } else { + sb.WriteString(protocol.FieldDelimiter) + } + } + sb.WriteString("\n") +} + +// Write the result data nicely formatted. +func (g *GroupSet) resultWriteFormattedData(query *Query, sb *strings.Builder, + lastColumn, rowsLimit int, columnWidths []int, rows []result) { + + for i, r := range rows { + if i == rowsLimit { + break + } + for j, value := range r.values { + format := fmt.Sprintf(" %%%ds ", columnWidths[j]) + str := fmt.Sprintf(format, value) + if config.Client.TermColorsEnable { + color.PaintWithAttr(sb, str, + config.Client.TermColors.MaprTable.DataFg, + config.Client.TermColors.MaprTable.DataBg, + config.Client.TermColors.MaprTable.DataAttr) + } else { + sb.WriteString(str) + } + + if j == lastColumn { + continue + } + if config.Client.TermColorsEnable { + color.PaintWithAttr(sb, protocol.FieldDelimiter, + config.Client.TermColors.MaprTable.DelimiterFg, + config.Client.TermColors.MaprTable.DelimiterBg, + config.Client.TermColors.MaprTable.DelimiterAttr) + } else { + sb.WriteString(protocol.FieldDelimiter) + } + } + sb.WriteString("\n") + } +} + +func (*GroupSet) writeQueryFile(query *Query) error { + queryFile := fmt.Sprintf("%s.query", query.Outfile) + tmpQueryFile := fmt.Sprintf("%s.tmp", queryFile) + dlog.Common.Debug("Writing query file", queryFile) + + fd, err := os.Create(tmpQueryFile) + if err != nil { + return err + } + defer fd.Close() + + fd.WriteString(query.RawQuery) + os.Rename(tmpQueryFile, queryFile) + return nil +} + +// WriteResult writes the result to an CSV outfile. +func (g *GroupSet) WriteResult(query *Query) error { + if !query.HasOutfile() { + return errors.New("No outfile specified") + } + if err := g.writeQueryFile(query); err != nil { + return err + } + + rows, _, err := g.result(query, false) + if err != nil { + return err + } + + dlog.Common.Info("Writing outfile", query.Outfile) + tmpOutfile := fmt.Sprintf("%s.tmp", query.Outfile) + + fd, err := os.Create(tmpOutfile) + if err != nil { + return err + } + defer fd.Close() + + return g.resultWriteUnformatted(query, rows, tmpOutfile, fd) +} + +func (g *GroupSet) resultWriteUnformatted(query *Query, rows []result, tmpOutfile string, + fd *os.File) error { + + // Generate header now + lastColumn := len(query.Select) - 1 + for i, sc := range query.Select { + fd.WriteString(sc.FieldStorage) + if i == lastColumn { + continue + } + fd.WriteString(protocol.CSVDelimiter) + } + fd.WriteString("\n") + + // And now write the data + for i, r := range rows { + if i == query.Limit { + break + } + for j, value := range r.values { + fd.WriteString(value) + if j == lastColumn { + continue + } + fd.WriteString(protocol.CSVDelimiter) + } + fd.WriteString("\n") + } + + if err := os.Rename(tmpOutfile, query.Outfile); err != nil { + os.Remove(tmpOutfile) + return err + } + + return nil +} -- cgit v1.2.3 From 1e205898c1270915b192db51acfdfc6e1a92e3e3 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Thu, 23 Dec 2021 15:46:22 +0000 Subject: refactor --- internal/mapr/groupsetresult.go | 99 ++++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 42 deletions(-) (limited to 'internal/mapr/groupsetresult.go') diff --git a/internal/mapr/groupsetresult.go b/internal/mapr/groupsetresult.go index 0e8e6e3..6d0ac1f 100644 --- a/internal/mapr/groupsetresult.go +++ b/internal/mapr/groupsetresult.go @@ -28,7 +28,7 @@ func (g *GroupSet) Result(query *Query, rowsLimit int) (string, int, error) { defer pool.RecycleBuilderBuffer(sb) g.resultWriteFormattedHeader(query, sb, lastColumn, rowsLimit, columnWidths) - g.resultWriteFormattedHeaderSeparator(query, sb, lastColumn, columnWidths) + g.resultWriteFormattedHeaderRowSeparator(query, sb, lastColumn, columnWidths) g.resultWriteFormattedData(query, sb, lastColumn, rowsLimit, columnWidths, rows) return sb.String(), len(rows), nil @@ -41,44 +41,54 @@ func (g *GroupSet) resultWriteFormattedHeader(query *Query, sb *strings.Builder, for i, sc := range query.Select { format := fmt.Sprintf(" %%%ds ", columnWidths[i]) str := fmt.Sprintf(format, sc.FieldStorage) - if config.Client.TermColorsEnable { - attrs := []color.Attribute{config.Client.TermColors.MaprTable.HeaderAttr} - if sc.FieldStorage == query.OrderBy { - attrs = append(attrs, config.Client.TermColors.MaprTable.HeaderSortKeyAttr) - } - - for _, groupBy := range query.GroupBy { - if sc.FieldStorage == groupBy { - attrs = append(attrs, config.Client.TermColors.MaprTable.HeaderGroupKeyAttr) - break - } - } - - color.PaintWithAttrs(sb, str, - config.Client.TermColors.MaprTable.HeaderFg, - config.Client.TermColors.MaprTable.HeaderBg, - attrs) - } else { - sb.WriteString(str) - } + g.resultWriteFormattedHeaderEntry(query, sb, sc, str) if i == lastColumn { continue } - if config.Client.TermColorsEnable { - color.PaintWithAttr(sb, protocol.FieldDelimiter, - config.Client.TermColors.MaprTable.HeaderDelimiterFg, - config.Client.TermColors.MaprTable.HeaderDelimiterBg, - config.Client.TermColors.MaprTable.HeaderDelimiterAttr) - } else { - sb.WriteString(protocol.FieldDelimiter) - } + g.resultWriteFormattedHeaderEntrySeparator(query, sb) + } sb.WriteString("\n") } +func (g *GroupSet) resultWriteFormattedHeaderEntry(query *Query, sb *strings.Builder, + sc selectCondition, str string) { + + if config.Client.TermColorsEnable { + attrs := []color.Attribute{config.Client.TermColors.MaprTable.HeaderAttr} + if sc.FieldStorage == query.OrderBy { + attrs = append(attrs, config.Client.TermColors.MaprTable.HeaderSortKeyAttr) + } + for _, groupBy := range query.GroupBy { + if sc.FieldStorage == groupBy { + attrs = append(attrs, config.Client.TermColors.MaprTable.HeaderGroupKeyAttr) + break + } + } + color.PaintWithAttrs(sb, str, + config.Client.TermColors.MaprTable.HeaderFg, + config.Client.TermColors.MaprTable.HeaderBg, + attrs) + + } else { + sb.WriteString(str) + } +} + +func (g *GroupSet) resultWriteFormattedHeaderEntrySeparator(query *Query, sb *strings.Builder) { + if config.Client.TermColorsEnable { + color.PaintWithAttr(sb, protocol.FieldDelimiter, + config.Client.TermColors.MaprTable.HeaderDelimiterFg, + config.Client.TermColors.MaprTable.HeaderDelimiterBg, + config.Client.TermColors.MaprTable.HeaderDelimiterAttr) + } else { + sb.WriteString(protocol.FieldDelimiter) + } +} + // This writes a nicely formatted line separating the header and the data. -func (g *GroupSet) resultWriteFormattedHeaderSeparator(query *Query, sb *strings.Builder, +func (g *GroupSet) resultWriteFormattedHeaderRowSeparator(query *Query, sb *strings.Builder, lastColumn int, columnWidths []int) { for i := 0; i < len(query.Select); i++ { @@ -115,20 +125,11 @@ func (g *GroupSet) resultWriteFormattedData(query *Query, sb *strings.Builder, break } for j, value := range r.values { - format := fmt.Sprintf(" %%%ds ", columnWidths[j]) - str := fmt.Sprintf(format, value) - if config.Client.TermColorsEnable { - color.PaintWithAttr(sb, str, - config.Client.TermColors.MaprTable.DataFg, - config.Client.TermColors.MaprTable.DataBg, - config.Client.TermColors.MaprTable.DataAttr) - } else { - sb.WriteString(str) - } - + g.resultWriteFormattedDataEntry(query, sb, columnWidths, j, value) if j == lastColumn { continue } + // Now, write the data entry separator. if config.Client.TermColorsEnable { color.PaintWithAttr(sb, protocol.FieldDelimiter, config.Client.TermColors.MaprTable.DelimiterFg, @@ -142,6 +143,21 @@ func (g *GroupSet) resultWriteFormattedData(query *Query, sb *strings.Builder, } } +func (g *GroupSet) resultWriteFormattedDataEntry(query *Query, sb *strings.Builder, + columnWidths []int, j int, value string) { + + format := fmt.Sprintf(" %%%ds ", columnWidths[j]) + str := fmt.Sprintf(format, value) + if config.Client.TermColorsEnable { + color.PaintWithAttr(sb, str, + config.Client.TermColors.MaprTable.DataFg, + config.Client.TermColors.MaprTable.DataBg, + config.Client.TermColors.MaprTable.DataAttr) + } else { + sb.WriteString(str) + } +} + func (*GroupSet) writeQueryFile(query *Query) error { queryFile := fmt.Sprintf("%s.query", query.Outfile) tmpQueryFile := fmt.Sprintf("%s.tmp", queryFile) @@ -166,7 +182,6 @@ func (g *GroupSet) WriteResult(query *Query) error { if err := g.writeQueryFile(query); err != nil { return err } - rows, _, err := g.result(query, false) if err != nil { return err -- cgit v1.2.3