diff --git a/command/encoding/json.go b/command/encoding/json.go index c47dbac5..6155a96a 100644 --- a/command/encoding/json.go +++ b/command/encoding/json.go @@ -88,15 +88,28 @@ func NewValuesFromQueryValues(dest [][]interface{}, v []*command.Values) error { return nil } -// XXX MUST Support pretty! +// JSONMarshal serializes Execute and Query results to JSON API format. func JSONMarshal(i interface{}) ([]byte, error) { + return jsonMarshal(i, json.Marshal) +} + +// JSONMarshalIndent serializes Execute and Query results to JSON API format, +// but also applies indent to the output. +func JSONMarshalIndent(i interface{}, prefix, indent string) ([]byte, error) { + f := func(i interface{}) ([]byte, error) { + return json.MarshalIndent(i, prefix, indent) + } + return jsonMarshal(i, f) +} + +func jsonMarshal(i interface{}, f func(i interface{}) ([]byte, error)) ([]byte, error) { switch v := i.(type) { case *command.ExecuteResult: r, err := NewResultFromExecuteResult(v) if err != nil { return nil, err } - return json.Marshal(r) + return f(r) case []*command.ExecuteResult: var err error results := make([]*Result, len(v)) @@ -106,13 +119,13 @@ func JSONMarshal(i interface{}) ([]byte, error) { return nil, err } } - return json.Marshal(results) + return f(results) case *command.QueryRows: r, err := NewRowsFromQueryRows(v) if err != nil { return nil, err } - return json.Marshal(r) + return f(r) case []*command.QueryRows: var err error rows := make([]*Rows, len(v)) @@ -122,14 +135,14 @@ func JSONMarshal(i interface{}) ([]byte, error) { return nil, err } } - return json.Marshal(rows) + return f(rows) case []*command.Values: values := make([][]interface{}, len(v)) if err := NewValuesFromQueryValues(values, v); err != nil { return nil, err } - return json.Marshal(v) + return f(values) default: - return json.Marshal(v) + return f(v) } } diff --git a/command/encoding/json_test.go b/command/encoding/json_test.go index 6ba5ccad..0233bd66 100644 --- a/command/encoding/json_test.go +++ b/command/encoding/json_test.go @@ -31,6 +31,7 @@ func Test_MarshalExecuteResult(t *testing.T) { Error: "something went wrong", Time: 6789, } + b, err = JSONMarshal(r) if err != nil { t.Fatalf("failed to marshal ExecuteResult: %s", err.Error()) @@ -38,6 +39,21 @@ func Test_MarshalExecuteResult(t *testing.T) { if exp, got := `{"last_insert_id":4,"rows_affected":5,"error":"something went wrong","time":6789}`, string(b); exp != got { t.Fatalf("failed to marshal ExecuteResult: exp %s, got %s", exp, got) } + + b, err = JSONMarshalIndent(r, "", " ") + if err != nil { + t.Fatalf("failed to marshal ExecuteResult: %s", err.Error()) + } + exp := `{ + "last_insert_id": 4, + "rows_affected": 5, + "error": "something went wrong", + "time": 6789 +}` + got := string(b) + if exp != got { + t.Fatalf("failed to pretty marshal ExecuteResult: exp: %s, got: %s", exp, got) + } } // Test_MarshalExecuteResults tests JSON marshaling of a slice of ExecuteResults @@ -103,6 +119,35 @@ func Test_MarshalQueryRows(t *testing.T) { if exp, got := `{"columns":["c1","c2","c3"],"types":["int","float","string"],"values":[[123,678,"fiona"]],"time":6789}`, string(b); exp != got { t.Fatalf("failed to marshal QueryRows: exp %s, got %s", exp, got) } + + b, err = JSONMarshalIndent(r, "", " ") + if err != nil { + t.Fatalf("failed to marshal QueryRows: %s", err.Error()) + } + exp := `{ + "columns": [ + "c1", + "c2", + "c3" + ], + "types": [ + "int", + "float", + "string" + ], + "values": [ + [ + 123, + 678, + "fiona" + ] + ], + "time": 6789 +}` + got := string(b) + if exp != got { + t.Fatalf("failed to pretty marshal QueryRows: exp: %s, got: %s", exp, got) + } } // Test_MarshalQueryRowses tests JSON marshaling of a slice of QueryRows