Skip to content

Commit

Permalink
Support JSON data type (#118)
Browse files Browse the repository at this point in the history
* Support JSON column type

* Add test case for JSON null
  • Loading branch information
yfuruyama authored Aug 31, 2021
1 parent ed9ae3f commit 043d3b6
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 104 deletions.
25 changes: 25 additions & 0 deletions decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,17 @@ func DecodeColumn(column spanner.GenericColumnValue) (string, error) {
}
decoded = append(decoded, fmt.Sprintf("[%s]", strings.Join(columns, ", ")))
}
case sppb.TypeCode_JSON:
var vs []spanner.NullJSON
if err := column.Decode(&vs); err != nil {
return "", err
}
if vs == nil {
return "NULL", nil
}
for _, v := range vs {
decoded = append(decoded, nullJSONToString(v))
}
}
return fmt.Sprintf("[%s]", strings.Join(decoded, ", ")), nil
case sppb.TypeCode_BOOL:
Expand Down Expand Up @@ -203,6 +214,12 @@ func DecodeColumn(column spanner.GenericColumnValue) (string, error) {
return "", err
}
return nullDateToString(v), nil
case sppb.TypeCode_JSON:
var v spanner.NullJSON
if err := column.Decode(&v); err != nil {
return "", err
}
return nullJSONToString(v), nil
default:
return fmt.Sprintf("%s", column.Value), nil
}
Expand Down Expand Up @@ -273,3 +290,11 @@ func nullDateToString(v spanner.NullDate) string {
return "NULL"
}
}

func nullJSONToString(v spanner.NullJSON) string {
if v.Valid {
return v.String()
} else {
return "NULL"
}
}
32 changes: 32 additions & 0 deletions decoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ func equalStringSlice(a []string, b []string) bool {
return true
}

type jsonMessage struct {
Msg string `json:"msg"`
}

func TestDecodeColumn(t *testing.T) {
tests := []struct {
desc string
Expand Down Expand Up @@ -115,6 +119,16 @@ func TestDecodeColumn(t *testing.T) {
value: civil.DateOf(time.Unix(1516676400, 0)),
want: "2018-01-23",
},
{
desc: "json",
value: spanner.NullJSON{Value: jsonMessage{Msg: "foo"}, Valid: true},
want: `{"msg":"foo"}`,
},
{
desc: "json null is not NULL",
value: spanner.NullJSON{Value: nil, Valid: true},
want: `null`,
},

// nullable
{
Expand Down Expand Up @@ -157,6 +171,11 @@ func TestDecodeColumn(t *testing.T) {
value: spanner.NullDate{Date: civil.DateOf(time.Unix(0, 0)), Valid: false},
want: "NULL",
},
{
desc: "null json",
value: spanner.NullJSON{Value: nil, Valid: false},
want: "NULL",
},

// array non-nullable
{
Expand Down Expand Up @@ -221,6 +240,14 @@ func TestDecodeColumn(t *testing.T) {
},
want: "[[10, Hello], [20, NULL]]",
},
{
desc: "array json",
value: []spanner.NullJSON{
{Value: jsonMessage{Msg: "foo"}, Valid: true},
{Value: jsonMessage{Msg: "bar"}, Valid: true},
},
want: `[{"msg":"foo"}, {"msg":"bar"}]`,
},

// array nullable
{
Expand Down Expand Up @@ -263,6 +290,11 @@ func TestDecodeColumn(t *testing.T) {
value: []civil.Date(nil),
want: "NULL",
},
{
desc: "null array json",
value: []spanner.NullJSON(nil),
want: "NULL",
},
}

for _, test := range tests {
Expand Down
20 changes: 13 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,22 @@ module github.com/cloudspannerecosystem/spanner-cli
go 1.13

require (
cloud.google.com/go v0.79.0
cloud.google.com/go/spanner v1.17.0
cloud.google.com/go v0.93.3
cloud.google.com/go/spanner v1.25.0
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e
github.com/google/go-cmp v0.5.5
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/google/go-cmp v0.5.6
github.com/googleapis/gax-go/v2 v2.1.0 // indirect
github.com/jessevdk/go-flags v1.4.0
github.com/mattn/go-runewidth v0.0.8 // indirect
github.com/olekukonko/tablewriter v0.0.4
github.com/xlab/treeprint v1.0.1-0.20200715141336-10e0bc383e01
google.golang.org/api v0.43.0
google.golang.org/genproto v0.0.0-20210331142528-b7513248f0ba
google.golang.org/grpc v1.36.1
google.golang.org/protobuf v1.26.0
golang.org/x/net v0.0.0-20210825183410-e898025ed96a // indirect
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf // indirect
golang.org/x/text v0.3.7 // indirect
google.golang.org/api v0.54.0
google.golang.org/genproto v0.0.0-20210830153122-0bac4d21c8ea
google.golang.org/grpc v1.40.0
google.golang.org/protobuf v1.27.1
)
Loading

0 comments on commit 043d3b6

Please sign in to comment.