1
1
package com .avsystem .commons
2
2
package mongo
3
3
4
- import java .nio .ByteBuffer
5
- import com .avsystem .commons .serialization .GenCodec .{ReadFailure , WriteFailure }
6
- import com .avsystem .commons .serialization .{GenCodec , GenKeyCodec , TransparentWrapping }
7
- import org .bson .codecs .{BsonValueCodec , DecoderContext , EncoderContext }
4
+ import com .avsystem .commons .serialization .GenCodec .ReadFailure
5
+ import com .avsystem .commons .serialization ._
6
+ import org .bson ._
8
7
import org .bson .io .BasicOutputBuffer
9
8
import org .bson .types .{Decimal128 , ObjectId }
10
- import org .bson .{BsonArray , BsonBinary , BsonBinaryReader , BsonBinaryWriter , BsonBoolean , BsonDateTime , BsonDecimal128 , BsonDocument , BsonDouble , BsonElement , BsonInt32 , BsonInt64 , BsonNull , BsonObjectId , BsonString , BsonType , BsonValue }
9
+
10
+ import java .nio .ByteBuffer
11
11
12
12
trait BsonGenCodecs {
13
13
implicit def objectIdCodec : GenCodec [ObjectId ] = BsonGenCodecs .objectIdCodec
14
14
implicit def objectIdKeyCodec : GenKeyCodec [ObjectId ] = BsonGenCodecs .objectIdKeyCodec
15
-
16
15
implicit def decimal128Codec : GenCodec [Decimal128 ] = BsonGenCodecs .decimal128Codec
17
16
18
17
implicit def bsonArrayCodec : GenCodec [BsonArray ] = BsonGenCodecs .bsonArrayCodec
@@ -33,13 +32,13 @@ trait BsonGenCodecs {
33
32
object BsonGenCodecs {
34
33
// needed so that ObjectId can be used as ID type in AutoIdMongoEntity
35
34
// (TransparentWrapping is used in EntityIdMode)
36
- implicit val objectIdIdentityWrapping : TransparentWrapping [ObjectId , ObjectId ] =
37
- TransparentWrapping .identity
35
+ implicit val objectIdIdentityWrapping : TransparentWrapping [ObjectId , ObjectId ] = TransparentWrapping .identity
38
36
39
37
implicit val objectIdCodec : GenCodec [ObjectId ] = GenCodec .nullable(
40
38
i => i.readCustom(ObjectIdMarker ).getOrElse(new ObjectId (i.readSimple().readString())),
41
39
(o, v) => if (! o.writeCustom(ObjectIdMarker , v)) o.writeSimple().writeString(v.toHexString)
42
40
)
41
+
43
42
implicit val objectIdKeyCodec : GenKeyCodec [ObjectId ] =
44
43
GenKeyCodec .create(new ObjectId (_), _.toHexString)
45
44
@@ -48,104 +47,43 @@ object BsonGenCodecs {
48
47
(o, v) => if (! o.writeCustom(Decimal128Marker , v)) o.writeSimple().writeBigDecimal(v.bigDecimalValue())
49
48
)
50
49
51
- implicit val bsonArrayCodec : GenCodec [BsonArray ] = GenCodec .nullableList(
52
- li => new BsonArray (li.iterator(bsonValueCodec.read).to(JList )),
53
- (lo, ba) => ba.asScala.foreach(bsonValueCodec.write(lo.writeElement(), _))
54
- )
55
-
56
- implicit val bsonBinaryCodec : GenCodec [BsonBinary ] =
57
- GenCodec .ByteArrayCodec .transform[BsonBinary ](_.getData, new BsonBinary (_))
58
-
59
- implicit val bsonBooleanCodec : GenCodec [BsonBoolean ] =
60
- GenCodec .BooleanCodec .transform[BsonBoolean ](_.getValue, new BsonBoolean (_))
61
-
62
- implicit val bsonDateTimeCodec : GenCodec [BsonDateTime ] = GenCodec .nullableSimple(
63
- i => new BsonDateTime (i.readTimestamp()),
64
- (o, v) => o.writeTimestamp(v.getValue)
65
- )
66
-
67
- implicit val bsonDocumentCodec : GenCodec [BsonDocument ] = GenCodec .nullableObject(
68
- oi => new BsonDocument (oi.iterator(bsonValueCodec.read).map {
69
- case (k, v) => new BsonElement (k, v)
70
- }.to(JList )),
71
- (oo, bd) => bd.asScala.foreach { case (key, value) =>
72
- bsonValueCodec.write(oo.writeField(key), value)
50
+ implicit val bsonValueCodec : GenCodec [BsonValue ] = GenCodec .create(
51
+ i => i.readCustom(BsonValueMarker ).getOrElse {
52
+ val reader = new BsonBinaryReader (ByteBuffer .wrap(i.readSimple().readBinary()))
53
+ BsonValueUtils .decode(reader)
54
+ },
55
+ (o, bv) => if (! o.writeCustom(BsonValueMarker , bv)) {
56
+ val buffer = new BasicOutputBuffer ()
57
+ val writer = new BsonBinaryWriter (buffer)
58
+ BsonValueUtils .encode(writer, bv)
59
+ writer.flush()
60
+ writer.close()
61
+ o.writeSimple().writeBinary(buffer.toByteArray)
73
62
}
74
63
)
75
64
76
- implicit val bsonDecimal128Codec : GenCodec [BsonDecimal128 ] =
77
- decimal128Codec.transform[BsonDecimal128 ](_.getValue, new BsonDecimal128 (_))
78
-
79
- implicit val bsonDoubleCodec : GenCodec [BsonDouble ] =
80
- GenCodec .DoubleCodec .transform(_.getValue, new BsonDouble (_))
81
-
82
- implicit val bsonInt32Codec : GenCodec [BsonInt32 ] =
83
- GenCodec .IntCodec .transform(_.getValue, new BsonInt32 (_))
65
+ private def bsonValueSubCodec [T <: BsonValue ](fromBsonValue : BsonValue => T ): GenCodec [T ] =
66
+ bsonValueCodec.transform(identity, fromBsonValue)
84
67
85
- implicit val bsonInt64Codec : GenCodec [BsonInt64 ] =
86
- GenCodec .LongCodec .transform(_.getValue, new BsonInt64 (_))
68
+ implicit val bsonArrayCodec : GenCodec [BsonArray ] = bsonValueSubCodec(_.asArray())
69
+ implicit val bsonBinaryCodec : GenCodec [BsonBinary ] = bsonValueSubCodec(_.asBinary())
70
+ implicit val bsonBooleanCodec : GenCodec [BsonBoolean ] = bsonValueSubCodec(_.asBoolean())
71
+ implicit val bsonDateTimeCodec : GenCodec [BsonDateTime ] = bsonValueSubCodec(_.asDateTime())
72
+ implicit val bsonDocumentCodec : GenCodec [BsonDocument ] = bsonValueSubCodec(_.asDocument())
73
+ implicit val bsonDecimal128Codec : GenCodec [BsonDecimal128 ] = bsonValueSubCodec(_.asDecimal128())
74
+ implicit val bsonDoubleCodec : GenCodec [BsonDouble ] = bsonValueSubCodec(_.asDouble())
75
+ implicit val bsonInt32Codec : GenCodec [BsonInt32 ] = bsonValueSubCodec(_.asInt32())
76
+ implicit val bsonInt64Codec : GenCodec [BsonInt64 ] = bsonValueSubCodec(_.asInt64())
87
77
88
78
implicit val bsonNullCodec : GenCodec [BsonNull ] =
89
- GenCodec .create(i => {
90
- if (! i.readNull()) throw new ReadFailure ( " Input did not contain expected null value " )
91
- BsonNull . VALUE
92
- }, (o, _) => o.writeNull())
79
+ bsonValueSubCodec { bv =>
80
+ if (bv.isNull) BsonNull . VALUE
81
+ else throw new ReadFailure ( " Input did not contain expected null value " )
82
+ }
93
83
94
84
implicit val bsonObjectIdCodec : GenCodec [BsonObjectId ] =
95
85
objectIdCodec.transform(_.getValue, new BsonObjectId (_))
96
86
97
87
implicit val bsonStringCodec : GenCodec [BsonString ] =
98
88
GenCodec .StringCodec .transform(_.getValue, new BsonString (_))
99
-
100
- private val mongoBsonValueCodec : BsonValueCodec = new BsonValueCodec ()
101
- private val mongoDecoderContext : DecoderContext = DecoderContext .builder().build()
102
- private val mongoEncoderContext : EncoderContext = EncoderContext .builder().build()
103
-
104
- implicit val bsonValueCodec : GenCodec [BsonValue ] = GenCodec .create(
105
- i => {
106
- val bvOpt = i.readMetadata(BsonTypeMetadata ) map {
107
- case BsonType .ARRAY => bsonArrayCodec.read(i)
108
- case BsonType .BINARY => bsonBinaryCodec.read(i)
109
- case BsonType .BOOLEAN => bsonBooleanCodec.read(i)
110
- case BsonType .DATE_TIME => bsonDateTimeCodec.read(i)
111
- case BsonType .DECIMAL128 => bsonDecimal128Codec.read(i)
112
- case BsonType .DOCUMENT => bsonDocumentCodec.read(i)
113
- case BsonType .DOUBLE => bsonDoubleCodec.read(i)
114
- case BsonType .INT32 => bsonInt32Codec.read(i)
115
- case BsonType .INT64 => bsonInt64Codec.read(i)
116
- case BsonType .NULL => bsonNullCodec.read(i)
117
- case BsonType .OBJECT_ID => bsonObjectIdCodec.read(i)
118
- case BsonType .STRING => bsonStringCodec.read(i)
119
- case other => throw new ReadFailure (s " Unsupported Bson type: $other" )
120
- }
121
- bvOpt.getOrElse {
122
- val reader = new BsonBinaryReader (ByteBuffer .wrap(i.readSimple().readBinary()))
123
- mongoBsonValueCodec.decode(reader, mongoDecoderContext)
124
- }
125
- },
126
- (o, bv) => if (o.keepsMetadata(BsonTypeMetadata )) {
127
- bv match {
128
- case array : BsonArray => bsonArrayCodec.write(o, array)
129
- case binary : BsonBinary => bsonBinaryCodec.write(o, binary)
130
- case boolean : BsonBoolean => bsonBooleanCodec.write(o, boolean)
131
- case dateTime : BsonDateTime => bsonDateTimeCodec.write(o, dateTime)
132
- case decimal128 : BsonDecimal128 => bsonDecimal128Codec.write(o, decimal128)
133
- case document : BsonDocument => bsonDocumentCodec.write(o, document)
134
- case double : BsonDouble => bsonDoubleCodec.write(o, double)
135
- case int32 : BsonInt32 => bsonInt32Codec.write(o, int32)
136
- case int64 : BsonInt64 => bsonInt64Codec.write(o, int64)
137
- case bNull : BsonNull => bsonNullCodec.write(o, bNull)
138
- case objectId : BsonObjectId => bsonObjectIdCodec.write(o, objectId)
139
- case string : BsonString => bsonStringCodec.write(o, string)
140
- case other => throw new WriteFailure (s " Unsupported value: $other" )
141
- }
142
- } else {
143
- val buffer = new BasicOutputBuffer ()
144
- val writer = new BsonBinaryWriter (buffer)
145
- mongoBsonValueCodec.encode(writer, bv, mongoEncoderContext)
146
- writer.flush()
147
- writer.close()
148
- o.writeSimple().writeBinary(buffer.toByteArray)
149
- }
150
- )
151
89
}
0 commit comments