Skip to content

Commit

Permalink
Merge pull request #51 from nlnwa/date-parsing
Browse files Browse the repository at this point in the history
Normalization of dates in responses from query command
  • Loading branch information
johnerikhalse authored Aug 21, 2023
2 parents 494869d + acce5f4 commit 3af42e6
Show file tree
Hide file tree
Showing 7 changed files with 296 additions and 54 deletions.
26 changes: 13 additions & 13 deletions cmd/report/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func (o *queryCmdOptions) run() error {
}

request := reportV1.ExecuteDbQueryRequest{
Query: q.query,
Query: q.Query,
Limit: o.pageSize,
}

Expand All @@ -77,10 +77,10 @@ func (o *queryCmdOptions) run() error {
}

var formatter format.Formatter
if q.template == "" {
if q.Template == "" {
formatter, err = format.NewFormatter("", w, o.format, o.goTemplate)
} else {
formatter, err = format.NewFormatter("", w, "template", q.template)
formatter, err = format.NewFormatter("", w, "template", q.Template)
}
if err != nil {
return fmt.Errorf("failed to create formatter: %w", err)
Expand Down Expand Up @@ -131,8 +131,8 @@ func newQueryCmd() *cobra.Command {
q := listStoredQueries(d)
var names []string
for _, s := range q {
if strings.HasPrefix(s.name, toComplete) {
names = append(names, s.name+"\t"+s.description)
if strings.HasPrefix(s.Name, toComplete) {
names = append(names, s.Name+"\t"+s.Description)
}
}
return names, cobra.ShellCompDirectiveDefault
Expand All @@ -157,18 +157,18 @@ func newQueryCmd() *cobra.Command {

// query is a struct for holding query definitions
type query struct {
name string
description string
query string
template string
Name string `json:"name"`
Description string `json:"description"`
Query string `json:"query"`
Template string `json:"template"`
}

func (o *queryCmdOptions) parseQuery() (*query, error) {
var q *query

if strings.HasPrefix(o.queryOrFile, "r.") {
q = &query{
query: o.queryOrFile,
Query: o.queryOrFile,
}
} else {
filename, err := findQueryFile(o.queryOrFile)
Expand All @@ -182,7 +182,7 @@ func (o *queryCmdOptions) parseQuery() (*query, error) {
}
}

q.query = fmt.Sprintf(q.query, o.queryArgs...)
q.Query = fmt.Sprintf(q.Query, o.queryArgs...)

return q, nil
}
Expand Down Expand Up @@ -228,9 +228,9 @@ func readQuery(name string) (*query, error) {
return nil, err
}
} else {
qd.query = string(data)
qd.Query = string(data)
}
qd.name = strings.TrimSuffix(filepath.Base(name), filepath.Ext(name))
qd.Name = strings.TrimSuffix(filepath.Base(name), filepath.Ext(name))

return qd, nil
}
Expand Down
92 changes: 92 additions & 0 deletions cmd/report/query_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package report

import (
"github.com/stretchr/testify/assert"
"testing"
)

func Test_queryCmdOptions_parseQuery(t *testing.T) {
tests := []struct {
name string
fieldsFromFlags *queryCmdOptions
fieldsAfterParse *queryCmdOptions
want *query
wantErr assert.ErrorAssertionFunc
}{
{"template file",
&queryCmdOptions{queryOrFile: "testdata/template1.yaml"},
&queryCmdOptions{
queryOrFile: "testdata/template1.yaml",
},
&query{
Name: "template1",
Description: "Example template\n",
Query: "r.db('veidemann').table('config_crawl_entities')\n",
Template: "{{.id}} {{.meta.name}}\n",
},
assert.NoError},
{"template file with template flag",
&queryCmdOptions{
queryOrFile: "testdata/template1.yaml",
goTemplate: "{{.id}}",
},
&queryCmdOptions{
queryOrFile: "testdata/template1.yaml",
goTemplate: "{{.id}}",
},
&query{
Name: "template1",
Description: "Example template\n",
Query: "r.db('veidemann').table('config_crawl_entities')\n",
Template: "{{.id}} {{.meta.name}}\n",
},
assert.NoError},
{"template file with format flag",
&queryCmdOptions{
queryOrFile: "testdata/template1.yaml",
format: "yaml",
},
&queryCmdOptions{
queryOrFile: "testdata/template1.yaml",
format: "yaml",
},
&query{
Name: "template1",
Description: "Example template\n",
Query: "r.db('veidemann').table('config_crawl_entities')\n",
Template: "{{.id}} {{.meta.name}}\n",
},
assert.NoError},
{"nonexisting template file",
&queryCmdOptions{
queryOrFile: "missing.yaml",
},
&queryCmdOptions{queryOrFile: "missing.yaml"},
nil,
assert.Error},
{"query",
&queryCmdOptions{
queryOrFile: "r.db('veidemann').table('config_crawl_entities')",
},
&queryCmdOptions{
queryOrFile: "r.db('veidemann').table('config_crawl_entities')",
},
&query{
Name: "",
Description: "",
Query: "r.db('veidemann').table('config_crawl_entities')",
Template: "",
},
assert.NoError},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := tt.fieldsFromFlags.parseQuery()
if !tt.wantErr(t, err, "parseQuery()") {
return
}
assert.Equalf(t, tt.fieldsAfterParse, tt.fieldsFromFlags, "Fields after parseQuery()")
assert.Equalf(t, tt.want, got, "parseQuery()")
})
}
}
8 changes: 8 additions & 0 deletions cmd/report/testdata/template1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
description: |
Example template
query: |
r.db('veidemann').table('config_crawl_entities')
template: |
{{.id}} {{.meta.name}}
17 changes: 11 additions & 6 deletions format/JsonFormatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
package format

import (
"encoding/json"
"fmt"
"io"
"reflect"
Expand All @@ -28,17 +29,16 @@ type jsonFormatter struct {

// newJsonFormatter creates a new json formatter
func newJsonFormatter(s *MarshalSpec) Formatter {
return &jsonFormatter{
MarshalSpec: s,
return &preFormatter{
&jsonFormatter{
MarshalSpec: s,
},
}
}

// WriteRecord writes a record to the formatters writer
func (jf *jsonFormatter) WriteRecord(record interface{}) error {
switch v := record.(type) {
case string:
_, err := fmt.Fprint(jf.rWriter, v)
return err
case proto.Message:
var values reflect.Value
values = reflect.ValueOf(v).Elem().FieldByName("Value")
Expand All @@ -65,7 +65,12 @@ func (jf *jsonFormatter) WriteRecord(record interface{}) error {
}
}
default:
return fmt.Errorf("illegal record type '%T'", record)
j, err := json.Marshal(v)
if err != nil {
return err
}
_, err = fmt.Fprint(jf.rWriter, string(j))
return err
}
return nil
}
Expand Down
12 changes: 1 addition & 11 deletions format/TemplateFormatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func newTemplateFormatter(s *MarshalSpec) (Formatter, error) {
return nil, err
}
t.parsedTemplate = pt
return t, nil
return &preFormatter{t}, nil
}

// WriteRecord writes a record to the formatters writer
Expand Down Expand Up @@ -108,16 +108,6 @@ func parseTemplate(templateString string) (*template.Template, error) {
return fmt.Sprintf("%-24.24s", ts.AsTime().Format(time.RFC3339))
}
},
"rethinktime": func(ts map[string]interface{}) string {
if ts == nil {
return " "
} else {
dateTime, _ := ts["dateTime"].(map[string]interface{})
date, _ := dateTime["date"].(map[string]interface{})
time, _ := dateTime["time"].(map[string]interface{})
return fmt.Sprintf("%04.f-%02.f-%02.fT%02.f:%02.f:%02.f", date["year"], date["month"], date["day"], time["hour"], time["minute"], time["second"])
}
},
"json": func(v interface{}) (string, error) {
if v == nil {
return "", nil
Expand Down
36 changes: 18 additions & 18 deletions format/YamlFormatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,29 +29,16 @@ type yamlFormatter struct {

// newYamlFormatter creates a new yaml formatter
func newYamlFormatter(s *MarshalSpec) Formatter {
return &yamlFormatter{
MarshalSpec: s,
return &preFormatter{
&yamlFormatter{
MarshalSpec: s,
},
}
}

// WriteRecord writes a record to the formatters writer
func (yf *yamlFormatter) WriteRecord(record interface{}) error {
switch v := record.(type) {
case string:
final, err := yaml.JSONToYAML([]byte(v))
if err != nil {
fmt.Printf("err: %v\n", err)
return err
}

_, err = fmt.Fprint(yf.rWriter, string(final))
if err != nil {
return err
}
_, err = fmt.Fprintln(yf.rWriter, "---")
if err != nil {
return err
}
case proto.Message:
var values reflect.Value
values = reflect.ValueOf(v).Elem().FieldByName("Value")
Expand Down Expand Up @@ -88,7 +75,20 @@ func (yf *yamlFormatter) WriteRecord(record interface{}) error {
return err
}
default:
return fmt.Errorf("illegal record type '%T'", record)
final, err := yaml.Marshal(record)
if err != nil {
fmt.Printf("err: %v\n", err)
return err
}

_, err = fmt.Fprint(yf.rWriter, string(final))
if err != nil {
return err
}
_, err = fmt.Fprintln(yf.rWriter, "---")
if err != nil {
return err
}
}
return nil
}
Expand Down
Loading

0 comments on commit 3af42e6

Please sign in to comment.