Skip to content

Commit 4cb9095

Browse files
authored
Fix JSON decode (#25)
* Call String() directly from array and document type * fix test * Add experimental json parser * Add workaround for bson.M unmarshal
1 parent 84c7de5 commit 4cb9095

File tree

4 files changed

+82
-14
lines changed

4 files changed

+82
-14
lines changed

pkg/models/column.go

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,22 @@ func (c *Column) AppendValue(rv bson.RawValue) error {
130130
return fmt.Errorf("field %s should have type %s, but got %s", c.Name, c.Type().ItemTypeString(), rv.Type.String())
131131
}
132132

133-
c.Field.Append(pointer(rv.Document().String()))
133+
v, err := rawDocToJson(rv)
134+
if err != nil {
135+
return err
136+
}
137+
138+
c.Field.Append(&v)
134139
case bson.TypeArray:
135140
if c.Type() != data.FieldTypeNullableString {
136141
return fmt.Errorf("field %s should have type %s, but got %s", c.Name, c.Type().ItemTypeString(), rv.Type.String())
137142
}
138143

139-
c.Field.Append(pointer(rv.Array().String()))
144+
v, err := rawArrayToJson(rv)
145+
if err != nil {
146+
return err
147+
}
148+
c.Field.Append(&v)
140149

141150
default:
142151
if c.Type() != data.FieldTypeNullableString {
@@ -158,7 +167,7 @@ func (c *Column) Type() data.FieldType {
158167
return c.Field.Type()
159168
}
160169

161-
func NewColumn(rowIndex int, element bson.RawElement) *Column {
170+
func NewColumn(rowIndex int, element bson.RawElement) (*Column, error) {
162171
key := element.Key()
163172
value := element.Value()
164173
var field *data.Field
@@ -194,11 +203,21 @@ func NewColumn(rowIndex int, element bson.RawElement) *Column {
194203

195204
case bson.TypeEmbeddedDocument:
196205
field = data.NewField(key, nil, make([]*string, rowIndex+1))
197-
field.Set(rowIndex, pointer(value.Document().String()))
206+
207+
v, err := rawDocToJson(value)
208+
if err != nil {
209+
return nil, err
210+
}
211+
field.Set(rowIndex, &v)
198212

199213
case bson.TypeArray:
200214
field = data.NewField(key, nil, make([]*string, rowIndex+1))
201-
field.Set(rowIndex, pointer(value.Array().String()))
215+
216+
v, err := rawArrayToJson(value)
217+
if err != nil {
218+
return nil, err
219+
}
220+
field.Set(rowIndex, &v)
202221

203222
default:
204223
field = data.NewField(key, nil, make([]*string, rowIndex+1))
@@ -209,7 +228,7 @@ func NewColumn(rowIndex int, element bson.RawElement) *Column {
209228
Name: key,
210229
Field: field,
211230
BsonTypes: []bsontype.Type{value.Type},
212-
}
231+
}, nil
213232
}
214233

215234
// Convert array and embedded document type values to json.RawMessage if allowed

pkg/models/utils.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package models
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
7+
"go.mongodb.org/mongo-driver/bson"
8+
)
9+
10+
func rawArrayToJson(value bson.RawValue) (string, error) {
11+
var bsonDoc bson.M
12+
err := bson.UnmarshalExtJSON([]byte(fmt.Sprintf(`{"data":%s}`, value.String())), true, &bsonDoc)
13+
if err != nil {
14+
return "", err
15+
}
16+
17+
rawBytes, err := json.Marshal(bsonDoc["data"])
18+
if err != nil {
19+
return "", err
20+
}
21+
return string(rawBytes), nil
22+
}
23+
24+
func rawDocToJson(value bson.RawValue) (string, error) {
25+
var bsonMap bson.M
26+
27+
err := bson.UnmarshalExtJSON([]byte(value.String()), true, &bsonMap)
28+
if err != nil {
29+
return "", err
30+
}
31+
32+
rawBytes, err := json.Marshal(bsonMap)
33+
if err != nil {
34+
return "", err
35+
}
36+
return string(rawBytes), nil
37+
}

pkg/plugin/query.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,11 @@ func CreateTableFramesFromQuery(ctx context.Context, tableName string, cursor *m
8181
if element.Value().Type == bson.TypeNull {
8282
continue
8383
}
84-
columns[name] = models.NewColumn(rowIndex, element)
84+
nc, err := models.NewColumn(rowIndex, element)
85+
if err != nil {
86+
return nil, err
87+
}
88+
columns[name] = nc
8589
}
8690
}
8791

pkg/plugin/query_test.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -740,14 +740,22 @@ func TestCreateTableFramesFromQuery(t *testing.T) {
740740
t.Fatal(err)
741741
}
742742

743-
v, _ := frame.Fields[0].ConcreteAt(0)
744-
var doc bson.M
745-
bson.UnmarshalExtJSON(v.(json.RawMessage), true, &doc)
746-
assertEq(t, doc["0"], int32(1))
747-
assertEq(t, doc["1"], "bar")
743+
v, notNull := frame.Fields[0].ConcreteAt(0)
744+
if !notNull {
745+
t.Fatal("null value")
746+
}
747+
748+
var doc bson.A
749+
err = bson.UnmarshalExtJSON(v.(json.RawMessage), true, &doc)
750+
if err != nil {
751+
t.Fatal(err)
752+
}
753+
754+
assertEq(t, doc[0], int32(1))
755+
assertEq(t, doc[1], "bar")
748756

749-
docIn := doc["2"].(bson.M)
750-
assertEq(t, docIn["baz"], int32(1))
757+
docIn := doc[2].(bson.D)
758+
assertEq(t, docIn.Map()["baz"], int32(1))
751759
})
752760

753761
t.Run("array and embedded docs can exist in the same field", func(t *testing.T) {

0 commit comments

Comments
 (0)