marshall mongodb bson into relaxed json

Signed-off-by: Mukundan Sundararajan <msundar.ms@outlook.com>
This commit is contained in:
Mukundan Sundararajan 2022-03-16 01:52:09 +05:30
parent d05523be8a
commit 83914e8eed
3 changed files with 31 additions and 2 deletions

View File

@ -225,7 +225,14 @@ func (m *MongoDB) Get(req *state.GetRequest) (*state.GetResponse, error) {
case string:
data = []byte(obj)
case primitive.D:
if data, err = bson.MarshalExtJSON(obj, true, true); err != nil {
// Setting canonical to `false`.
// See https://docs.mongodb.com/manual/reference/mongodb-extended-json/#bson-data-types-and-associated-representations
// Having bson marshalled into Relaxed JSON instead of canonical JSON, this way type preservation is lost but
// interoperability is preserved
// See https://mongodb.github.io/swift-bson/docs/current/SwiftBSON/json-interop.html
// A decimal value stored as BSON will be returned as {"d": 5.5} if canonical is set to false instead of
// {"d": {"$numberDouble": 5.5}} when canonical JSON is returned.
if data, err = bson.MarshalExtJSON(obj, false, true); err != nil {
return &state.GetResponse{}, err
}
default:

View File

@ -157,7 +157,14 @@ func (q *Query) execute(ctx context.Context, collection *mongo.Collection) ([]st
case string:
result.Data = []byte(obj)
case primitive.D:
if result.Data, err = bson.MarshalExtJSON(obj, true, true); err != nil {
// Setting canonical to `false`.
// See https://docs.mongodb.com/manual/reference/mongodb-extended-json/#bson-data-types-and-associated-representations
// Having bson marshalled into Relaxed JSON instead of canonical JSON, this way type preservation is lost but
// interoperability is preserved
// See https://mongodb.github.io/swift-bson/docs/current/SwiftBSON/json-interop.html
// A decimal value stored as BSON will be returned as {"d": 5.5} if canonical is set to false instead of
// {"d": {"$numberDouble": 5.5}} when canonical JSON is returned.
if result.Data, err = bson.MarshalExtJSON(obj, false, true); err != nil {
result.Error = err.Error()
}
default:

View File

@ -33,6 +33,10 @@ type ValueType struct {
Message string `json:"message"`
}
type IntValueType struct {
Message int32 `json:"message"`
}
type scenario struct {
key string
value interface{}
@ -97,6 +101,11 @@ func ConformanceTests(t *testing.T, props map[string]string, statestore state.St
value: ValueType{Message: fmt.Sprintf("test%s", key)},
contentType: contenttype.JSONContentType,
},
{
key: fmt.Sprintf("%s-struct-with-int", key),
value: IntValueType{Message: 42},
contentType: contenttype.JSONContentType,
},
{
key: fmt.Sprintf("%s-to-be-deleted", key),
value: "to be deleted",
@ -664,6 +673,12 @@ func ConformanceTests(t *testing.T, props map[string]string, statestore state.St
func assertEquals(t *testing.T, value interface{}, res *state.GetResponse) {
switch v := value.(type) {
case IntValueType:
// Custom type requires case mapping
if err := json.Unmarshal(res.Data, &v); err != nil {
assert.Failf(t, "unmarshal error", "error: %w, json: %s", err, string(res.Data))
}
assert.Equal(t, value, v)
case ValueType:
// Custom type requires case mapping
if err := json.Unmarshal(res.Data, &v); err != nil {