Skip to content

Commit

Permalink
Add 'line' output format. Closes #114
Browse files Browse the repository at this point in the history
  • Loading branch information
binaek authored Feb 9, 2021
1 parent a1832d5 commit 277fec6
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 6 deletions.
2 changes: 1 addition & 1 deletion cmd/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Examples:
OnCmd(cmd).
AddBoolFlag(constants.ArgHeader, "", true, "Include column headers csv and table output").
AddStringFlag(constants.ArgSeparator, "", ",", "Separator string for csv output").
AddStringFlag(constants.ArgOutput, "", "table", "Output format: csv, json or table").
AddStringFlag(constants.ArgOutput, "", "table", "Output format: line, csv, json or table").
AddBoolFlag(constants.ArgTimer, "", false, "Turn on the timer which reports query time.")

return cmd
Expand Down
1 change: 1 addition & 0 deletions constants/args.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const (
ArgJSON = "json"
ArgCSV = "csv"
ArgTable = "table"
ArgLine = "line"
ArgListAllTableNames = "L"
ArgSelectAll = "A"
ArgForce = "force"
Expand Down
12 changes: 10 additions & 2 deletions db/client_execute.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
// ExecuteSync :: execute a query against this client and wait for the result
func (c *Client) ExecuteSync(query string) (*SyncQueryResult, error) {
// https://github.com/golang/go/wiki/CodeReviewComments#indent-error-flow
result, err := c.executeQuery(query, false)
result, err := c.executeQuery(query, false, false)
if err != nil {
return nil, err
}
Expand All @@ -27,7 +27,7 @@ func (c *Client) ExecuteSync(query string) (*SyncQueryResult, error) {
return syncResult, nil
}

func (c *Client) executeQuery(query string, showSpinner bool) (*QueryResult, error) {
func (c *Client) executeQuery(query string, showSpinner bool, countStream bool) (*QueryResult, error) {
if query == "" {
return &QueryResult{}, nil
}
Expand All @@ -44,6 +44,9 @@ func (c *Client) executeQuery(query string, showSpinner bool) (*QueryResult, err
// if showspinner is false, the spinner gets created, but is never shown
// so the s.Active() will always come back false . . .
spinner = utils.StartSpinnerAfterDelay("Loading results...", constants.SpinnerShowTimeout, queryDone)
} else {
// no point in showing count if we don't have the spinner
countStream = false
}

rows, err := c.dbClient.Query(query)
Expand Down Expand Up @@ -93,6 +96,11 @@ func (c *Client) executeQuery(query string, showSpinner bool) (*QueryResult, err
// populate row data - handle special case types
result := populateRow(columnValues, colTypes)

if !countStream {
// stop the spinner if we don't want to show load count
utils.StopSpinner(spinner)
}

// we have started populating results
rowChan <- result

Expand Down
4 changes: 2 additions & 2 deletions db/interactive_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ func (c *InteractiveClient) executor(line string, resultsStreamer *ResultStreame
resultsStreamer.Done()
} else {
// otherwise execute query
if result, err := c.client.executeQuery(query, true); err != nil {
if result, err := c.client.executeQuery(query, true, cmdconfig.Viper().Get(constants.ArgOutput) == constants.ArgTable); err != nil {
utils.ShowError(err)
resultsStreamer.Done()
} else {
Expand Down Expand Up @@ -268,7 +268,7 @@ func (c *InteractiveClient) queryCompleter(d prompt.Document, schemaMetadata *sc
if isFirstWord(text) {
// add all we know that can be the first words
s = []prompt.Suggest{
prompt.Suggest{
{
Text: "select",
},
}
Expand Down
2 changes: 1 addition & 1 deletion db/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func ExecuteQuery(queryString string) (*ResultStreamer, error) {
// start the interactive prompt in a go routine
go interactiveClient.InteractiveQuery(resultsStreamer, onComplete)
} else {
result, err := client.executeQuery(queryString, false)
result, err := client.executeQuery(queryString, false, false)
if err != nil {
onComplete()
return nil, err
Expand Down
64 changes: 64 additions & 0 deletions display/display.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"encoding/json"
"fmt"
"os"
"strings"
"unicode/utf8"

"github.com/jedib0t/go-pretty/v6/table"
"github.com/jedib0t/go-pretty/v6/text"
Expand All @@ -22,11 +24,73 @@ func ShowOutput(result *db.QueryResult) {
displayJSON(result)
} else if cmdconfig.Viper().Get(constants.ArgOutput) == constants.ArgCSV {
displayCSV(result)
} else if cmdconfig.Viper().Get(constants.ArgOutput) == constants.ArgLine {
displayLine(result)
} else {
// default
displayTable(result)
}
}

func displayLine(result *db.QueryResult) {
colNames := ColumnNames(result.ColTypes)
maxColNameLength := 0
for _, colName := range colNames {
thisLength := utf8.RuneCountInString(colName)
if thisLength > maxColNameLength {
maxColNameLength = thisLength
}
}
itemIdx := 0
for item := range *result.RowChan {

recordAsString, _ := ColumnValuesAsString(item, result.ColTypes)

requiredTerminalColumnsForValuesOfRecord := 0
for _, colValue := range recordAsString {
colRequired := getTerminalColumnsRequiredForString(colValue)
if requiredTerminalColumnsForValuesOfRecord < colRequired {
requiredTerminalColumnsForValuesOfRecord = colRequired
}
}

lineFormat := fmt.Sprintf("%%-%ds | %%-%ds", maxColNameLength, requiredTerminalColumnsForValuesOfRecord)

fmt.Printf("-[ RECORD %-2d ]%s\n", (itemIdx + 1), strings.Repeat("-", 75))
for idx, column := range recordAsString {
lines := strings.Split(column, "\n")
for lineIdx, line := range lines {
if lineIdx == 0 {
// the first line
fmt.Printf(lineFormat, colNames[idx], line)
} else {
// next lines
fmt.Printf(lineFormat, "", line)
}

// is this not the last line of value?
if lineIdx < len(lines)-1 {
fmt.Printf(" +\n")
} else {
fmt.Printf("\n")
}

}
}
itemIdx++
}
}

func getTerminalColumnsRequiredForString(str string) int {
colsRequired := 0
for _, line := range strings.Split(str, "\n") {
if colsRequired < utf8.RuneCountInString(line) {
colsRequired = utf8.RuneCountInString(line)
}
}
return colsRequired
}

func displayJSON(result *db.QueryResult) {
var jsonOutput []map[string]interface{}
for item := range *result.RowChan {
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ require (
github.com/kr/text v0.2.0 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/lib/pq v1.8.0
github.com/mattn/go-runewidth v0.0.9
github.com/mitchellh/go-wordwrap v1.0.0 // indirect
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/olekukonko/tablewriter v0.0.4
Expand Down
1 change: 1 addition & 0 deletions metaquery/definitions.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ func init() {
{value: constants.ArgJSON, description: "Set output to JSON"},
{value: constants.ArgCSV, description: "Set output to CSV"},
{value: constants.ArgTable, description: "Set output to Table"},
{value: constants.ArgLine, description: "Set output to Line"},
},
completer: completerFromArgsOf(constants.CmdOutput),
},
Expand Down

0 comments on commit 277fec6

Please sign in to comment.