Skip to content

Commit 44d349d

Browse files
committed
Reverse dependencies between bsoncodec and bson
This commit reverses the dependency between the bson and bsoncodec package. This allows the bson package to contain the Marshal and Unmarshal family of functions and the Encoder and Decoder types. This allows future types in the bson package to handle the empty interface. The default encoders and decoders are split across two packages, because the bsoncodec package can only provide encoders and decoders for non-bson package types. The empty interface decoder is defined twice: a partial version in bsoncdec and a complete version in the bson package. Almost all users should use a Registry created from both sets of encoders and decoders. The bsoncodec package was split into the bsonrw and bsoncodec packages. The new bsonrw package contains the ValueReader and ValueWriter definitions and implementations. A new bsonrwtest package was created with the previously used llValueReaderWriter type that is useful for unit testing a ValueReader or ValueWriter implementation. This allows users outside of the bsoncodec and bsonrw packages to use this type with their own ValueReader and ValueWriter implementations. The llbson package is renamed bsoncore and moved out of internal. This will allow other users to directly use this low level bson package. Eventually the entire BSON library will use bsoncore to handle reading and writing BSON from and to bytes. This package replaces the elements package, which will be removed in a future commit. GODRIVER-592 Change-Id: I1e2dabc83cae9705fc062a6b763e0d2b91cde3ef
1 parent 604eb85 commit 44d349d

File tree

107 files changed

+8977
-8245
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

107 files changed

+8977
-8245
lines changed

benchmark/bson.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package benchmark
22

33
import (
44
"errors"
5-
"github.com/mongodb/mongo-go-driver/bson/bsoncodec"
65
"io/ioutil"
76
"path/filepath"
87

@@ -25,7 +24,7 @@ func loadSourceDocument(pathParts ...string) (*bson.Document, error) {
2524
return nil, err
2625
}
2726
doc := bson.NewDocument()
28-
err = bsoncodec.UnmarshalExtJSON(data, true, &doc)
27+
err = bson.UnmarshalExtJSON(data, true, &doc)
2928
if err != nil {
3029
return nil, err
3130
}

benchmark/bson_map.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"errors"
66
"fmt"
77

8-
"github.com/mongodb/mongo-go-driver/bson/bsoncodec"
8+
"github.com/mongodb/mongo-go-driver/bson"
99
)
1010

1111
func bsonMapDecoding(ctx context.Context, tm TimerManager, iters int, dataSet string) error {
@@ -18,7 +18,7 @@ func bsonMapDecoding(ctx context.Context, tm TimerManager, iters int, dataSet st
1818

1919
for i := 0; i < iters; i++ {
2020
out := make(map[string]interface{})
21-
err := bsoncodec.Unmarshal(r, &out)
21+
err := bson.Unmarshal(r, &out)
2222
if err != nil {
2323
return nil
2424
}
@@ -36,15 +36,15 @@ func bsonMapEncoding(ctx context.Context, tm TimerManager, iters int, dataSet st
3636
}
3737

3838
doc := make(map[string]interface{})
39-
err = bsoncodec.Unmarshal(r, &doc)
39+
err = bson.Unmarshal(r, &doc)
4040
if err != nil {
4141
return err
4242
}
4343

4444
var buf []byte
4545
tm.ResetTimer()
4646
for i := 0; i < iters; i++ {
47-
buf, err = bsoncodec.MarshalAppend(buf[:0], doc)
47+
buf, err = bson.MarshalAppend(buf[:0], doc)
4848
if err != nil {
4949
return nil
5050
}

benchmark/bson_struct.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"context"
55
"errors"
66

7-
"github.com/mongodb/mongo-go-driver/bson/bsoncodec"
7+
"github.com/mongodb/mongo-go-driver/bson"
88
)
99

1010
func BSONFlatStructDecoding(ctx context.Context, tm TimerManager, iters int) error {
@@ -17,7 +17,7 @@ func BSONFlatStructDecoding(ctx context.Context, tm TimerManager, iters int) err
1717

1818
for i := 0; i < iters; i++ {
1919
out := flatBSON{}
20-
err := bsoncodec.Unmarshal(r, &out)
20+
err := bson.Unmarshal(r, &out)
2121
if err != nil {
2222
return err
2323
}
@@ -32,7 +32,7 @@ func BSONFlatStructEncoding(ctx context.Context, tm TimerManager, iters int) err
3232
}
3333

3434
doc := flatBSON{}
35-
err = bsoncodec.Unmarshal(r, &doc)
35+
err = bson.Unmarshal(r, &doc)
3636
if err != nil {
3737
return err
3838
}
@@ -41,7 +41,7 @@ func BSONFlatStructEncoding(ctx context.Context, tm TimerManager, iters int) err
4141

4242
tm.ResetTimer()
4343
for i := 0; i < iters; i++ {
44-
buf, err = bsoncodec.Marshal(doc)
44+
buf, err = bson.Marshal(doc)
4545
if err != nil {
4646
return err
4747
}
@@ -59,7 +59,7 @@ func BSONFlatStructTagsEncoding(ctx context.Context, tm TimerManager, iters int)
5959
}
6060

6161
doc := flatBSONTags{}
62-
err = bsoncodec.Unmarshal(r, &doc)
62+
err = bson.Unmarshal(r, &doc)
6363
if err != nil {
6464
return err
6565
}
@@ -68,7 +68,7 @@ func BSONFlatStructTagsEncoding(ctx context.Context, tm TimerManager, iters int)
6868

6969
tm.ResetTimer()
7070
for i := 0; i < iters; i++ {
71-
buf, err = bsoncodec.MarshalAppend(buf[:0], doc)
71+
buf, err = bson.MarshalAppend(buf[:0], doc)
7272
if err != nil {
7373
return err
7474
}
@@ -88,7 +88,7 @@ func BSONFlatStructTagsDecoding(ctx context.Context, tm TimerManager, iters int)
8888
tm.ResetTimer()
8989
for i := 0; i < iters; i++ {
9090
out := flatBSONTags{}
91-
err := bsoncodec.Unmarshal(r, &out)
91+
err := bson.Unmarshal(r, &out)
9292
if err != nil {
9393
return err
9494
}

bson/array.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,5 +343,33 @@ func (a *Array) Iterator() (*ArrayIterator, error) {
343343

344344
// Equal compares this document to another, returning true if they are equal.
345345
func (a *Array) Equal(a2 *Array) bool {
346-
return a.doc.Equal(a2.doc)
346+
if a == nil && a2 == nil {
347+
return true
348+
}
349+
350+
if a == nil || a2 == nil {
351+
return false
352+
}
353+
354+
if a.doc == nil && a2.doc == nil {
355+
return true
356+
}
357+
358+
if a.doc == nil || a2.doc == nil {
359+
return false
360+
}
361+
362+
if (len(a.doc.elems) != len(a2.doc.elems)) || (len(a.doc.index) != len(a2.doc.index)) {
363+
return false
364+
}
365+
366+
for index := range a.doc.elems {
367+
v1 := a.doc.elems[index].value
368+
v2 := a2.doc.elems[index].value
369+
370+
if !v1.Equal(v2) {
371+
return false
372+
}
373+
}
374+
return true
347375
}

bson/bsoncodec/benchmark_test.go renamed to bson/benchmark_test.go

Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
package bsoncodec
1+
package bson
22

33
import (
44
"testing"
5-
6-
"github.com/mongodb/mongo-go-driver/bson"
75
)
86

97
type encodetest struct {
@@ -117,42 +115,14 @@ var nestedInstance = nestedtest1{
117115
},
118116
}
119117

120-
func BenchmarkEncodingv2(b *testing.B) {
118+
func BenchmarkEncoding(b *testing.B) {
121119
for i := 0; i < b.N; i++ {
122120
_, _ = Marshal(encodetestInstance)
123121
}
124122
}
125123

126-
func BenchmarkEncodingv2ToDocument(b *testing.B) {
127-
var buf []byte
128-
for i := 0; i < b.N; i++ {
129-
buf, _ = Marshal(encodetestInstance)
130-
_, _ = bson.ReadDocument(buf)
131-
}
132-
}
133-
134-
// func BenchmarkEncodingDocument(b *testing.B) {
135-
// for i := 0; i < b.N; i++ {
136-
// _, _ = MarshalDocument(encodetestInstance)
137-
// }
138-
// }
139-
140-
func BenchmarkEncodingv2Nested(b *testing.B) {
124+
func BenchmarkEncodingNested(b *testing.B) {
141125
for i := 0; i < b.N; i++ {
142126
_, _ = Marshal(nestedInstance)
143127
}
144128
}
145-
146-
func BenchmarkEncodingv2ToDocumentNested(b *testing.B) {
147-
var buf []byte
148-
for i := 0; i < b.N; i++ {
149-
buf, _ = Marshal(nestedInstance)
150-
_, _ = bson.ReadDocument(buf)
151-
}
152-
}
153-
154-
// func BenchmarkEncodingDocumentNested(b *testing.B) {
155-
// for i := 0; i < b.N; i++ {
156-
// _, _ = MarshalDocument(nestedInstance)
157-
// }
158-
// }

bson/bsoncodec/bson_corpus_spec_test.go renamed to bson/bson_corpus_spec_test.go

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
// not use this file except in compliance with the License. You may obtain
55
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
66

7-
package bsoncodec
7+
package bson
88

99
import (
1010
"bytes"
@@ -20,7 +20,8 @@ import (
2020
"unicode/utf8"
2121

2222
"github.com/google/go-cmp/cmp"
23-
"github.com/mongodb/mongo-go-driver/bson"
23+
"github.com/mongodb/mongo-go-driver/bson/bsoncodec"
24+
"github.com/mongodb/mongo-go-driver/bson/bsonrw"
2425
"github.com/stretchr/testify/require"
2526
"github.com/tidwall/pretty"
2627
)
@@ -57,13 +58,14 @@ type parseErrorTestCase struct {
5758
String string `json:"string"`
5859
}
5960

60-
const dataDir = "../../data"
61+
const dataDir = "../data"
6162

62-
var dvd DefaultValueDecoders
63-
var dve DefaultValueEncoders
63+
var pc PrimitiveCodecs
64+
var dvd bsoncodec.DefaultValueDecoders
65+
var dve bsoncodec.DefaultValueEncoders
6466

65-
var dc = DecodeContext{Registry: NewRegistryBuilder().Build()}
66-
var ec = EncodeContext{Registry: NewRegistryBuilder().Build()}
67+
var dc = bsoncodec.DecodeContext{Registry: NewRegistryBuilder().Build()}
68+
var ec = bsoncodec.EncodeContext{Registry: NewRegistryBuilder().Build()}
6769

6870
func findJSONFilesInDir(t *testing.T, dir string) []string {
6971
files := make([]string, 0)
@@ -158,21 +160,21 @@ func normalizeRelaxedDouble(t *testing.T, key string, rEJ string) string {
158160
return fmt.Sprintf(`{"%s":%s}`, key, formatDouble(expectedFloat))
159161
}
160162

161-
// bsonToNative decodes the BSON bytes (b) into a native bson.Document
162-
func bsonToNative(t *testing.T, b []byte, bType, testDesc string) *bson.Document {
163-
doc := bson.NewDocument()
164-
err := dvd.DocumentDecodeValue(dc, NewValueReader(b), &doc)
163+
// bsonToNative decodes the BSON bytes (b) into a native Document
164+
func bsonToNative(t *testing.T, b []byte, bType, testDesc string) *Document {
165+
doc := NewDocument()
166+
err := pc.DocumentDecodeValue(dc, bsonrw.NewBSONValueReader(b), &doc)
165167
expectNoError(t, err, fmt.Sprintf("%s: decoding %s BSON", testDesc, bType))
166168
return doc
167169
}
168170

169-
// nativeToBSON encodes the native bson.Document (doc) into canonical BSON and compares it to the expected
171+
// nativeToBSON encodes the native Document (doc) into canonical BSON and compares it to the expected
170172
// canonical BSON (cB)
171-
func nativeToBSON(t *testing.T, cB []byte, doc *bson.Document, testDesc, bType, docSrcDesc string) {
173+
func nativeToBSON(t *testing.T, cB []byte, doc *Document, testDesc, bType, docSrcDesc string) {
172174
actualB := new(bytes.Buffer)
173-
vw, err := NewBSONValueWriter(actualB)
175+
vw, err := bsonrw.NewBSONValueWriter(actualB)
174176
expectNoError(t, err, fmt.Sprintf("%s: creating ValueWriter", testDesc))
175-
err = dve.DocumentEncodeValue(ec, vw, doc)
177+
err = pc.DocumentEncodeValue(ec, vw, doc)
176178
expectNoError(t, err, fmt.Sprintf("%s: encoding %s BSON", testDesc, bType))
177179

178180
if diff := cmp.Diff(cB, actualB.Bytes()); diff != "" {
@@ -182,16 +184,16 @@ func nativeToBSON(t *testing.T, cB []byte, doc *bson.Document, testDesc, bType,
182184
}
183185
}
184186

185-
// jsonToNative decodes the extended JSON string (ej) into a native bson.Document
186-
func jsonToNative(t *testing.T, ej, ejType, testDesc string) *bson.Document {
187-
doc := bson.NewDocument()
187+
// jsonToNative decodes the extended JSON string (ej) into a native Document
188+
func jsonToNative(t *testing.T, ej, ejType, testDesc string) *Document {
189+
doc := NewDocument()
188190
err := UnmarshalExtJSON([]byte(ej), ejType != "relaxed", &doc)
189191
expectNoError(t, err, fmt.Sprintf("%s: decoding %s extended JSON", testDesc, ejType))
190192
return doc
191193
}
192194

193-
// nativeToJSON encodes the native bson.Document (doc) into an extended JSON string
194-
func nativeToJSON(t *testing.T, ej string, doc *bson.Document, testDesc, ejType, ejShortName, docSrcDesc string) {
195+
// nativeToJSON encodes the native Document (doc) into an extended JSON string
196+
func nativeToJSON(t *testing.T, ej string, doc *Document, testDesc, ejType, ejShortName, docSrcDesc string) {
195197
actualEJ, err := MarshalExtJSON(doc, ejType != "relaxed", true)
196198
expectNoError(t, err, fmt.Sprintf("%s: encoding %s extended JSON", testDesc, ejType))
197199

@@ -296,8 +298,8 @@ func runTest(t *testing.T, file string) {
296298
b, err := hex.DecodeString(d.Bson)
297299
expectNoError(t, err, d.Description)
298300

299-
doc := bson.NewDocument()
300-
err = dvd.DocumentDecodeValue(dc, NewValueReader(b), &doc)
301+
doc := NewDocument()
302+
err = pc.DocumentDecodeValue(dc, bsonrw.NewBSONValueReader(b), &doc)
301303
expectError(t, err, fmt.Sprintf("%s: expected decode error", d.Description))
302304
}
303305

@@ -314,11 +316,11 @@ func runTest(t *testing.T, file string) {
314316

315317
switch test.BsonType {
316318
case "0x00":
317-
doc := bson.NewDocument()
319+
doc := NewDocument()
318320
err := UnmarshalExtJSON([]byte(s), true, &doc)
319321
expectError(t, err, fmt.Sprintf("%s: expected parse error", p.Description))
320322
case "0x13":
321-
ejvr := newExtJSONValueReader(strings.NewReader(s), true)
323+
ejvr := bsonrw.NewExtJSONValueReader(strings.NewReader(s), true)
322324
_, err := ejvr.ReadDecimal128()
323325
expectError(t, err, fmt.Sprintf("%s: expected parse error", p.Description))
324326
default:
@@ -334,3 +336,19 @@ func Test_BsonCorpus(t *testing.T) {
334336
runTest(t, file)
335337
}
336338
}
339+
340+
func expectNoError(t *testing.T, err error, desc string) {
341+
if err != nil {
342+
t.Helper()
343+
t.Errorf("%s: Unepexted error: %v", desc, err)
344+
t.FailNow()
345+
}
346+
}
347+
348+
func expectError(t *testing.T, err error, desc string) {
349+
if err == nil {
350+
t.Helper()
351+
t.Errorf("%s: Expected error", desc)
352+
t.FailNow()
353+
}
354+
}

0 commit comments

Comments
 (0)