Skip to content

Commit 9ecda72

Browse files
authored
Merge pull request #409 from AVSystem/bson-long-parsing
Allow interpreting Int32 as Long when reading BSON values
2 parents 82d2eea + c34a25c commit 9ecda72

File tree

4 files changed

+30
-9
lines changed

4 files changed

+30
-9
lines changed

commons-mongo/jvm/src/main/scala/com/avsystem/commons/mongo/BsonReaderInput.scala

+4-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@ class BsonReaderInput(br: BsonReader, override val legacyOptionEncoding: Boolean
1616
override def readString(): String = br.readString()
1717
override def readBoolean(): Boolean = br.readBoolean()
1818
override def readInt(): Int = br.readInt32()
19-
override def readLong(): Long = br.readInt64()
19+
override def readLong(): Long = bsonType match {
20+
case BsonType.INT32 => br.readInt32().toLong // allow converting INT32 to Long
21+
case _ => br.readInt64()
22+
}
2023
override def readTimestamp(): Long = br.readDateTime()
2124
override def readDouble(): Double = br.readDouble()
2225
override def readBigInt(): BigInt = BigInt(br.readBinaryData().getData)

commons-mongo/jvm/src/main/scala/com/avsystem/commons/mongo/BsonValueInput.scala

+6-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,12 @@ class BsonValueInput(bsonValue: BsonValue, override val legacyOptionEncoding: Bo
2222
def readString(): String = handleFailures(bsonValue.asString().getValue)
2323
def readBoolean(): Boolean = handleFailures(bsonValue.asBoolean().getValue)
2424
def readInt(): Int = handleFailures(bsonValue.asInt32().getValue)
25-
def readLong(): Long = handleFailures(bsonValue.asInt64().getValue)
25+
def readLong(): Long = handleFailures {
26+
bsonType match {
27+
case BsonType.INT32 => bsonValue.asInt32().getValue.toLong // allow converting INT32 to Long
28+
case _ => bsonValue.asInt64().getValue
29+
}
30+
}
2631
override def readTimestamp(): Long = handleFailures(bsonValue.asDateTime().getValue)
2732
def readDouble(): Double = handleFailures(bsonValue.asDouble().getValue)
2833
def readBigInt(): BigInt = handleFailures(BigInt(bsonValue.asBinary().getData))

commons-mongo/jvm/src/test/scala/com/avsystem/commons/mongo/BsonInputOutputTest.scala

+14
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ class BsonValueGenCodecRoundtripTest extends GenCodecRoundtripTest {
6868

6969
def createInput(raw: BsonValue): Input =
7070
new BsonValueInput(raw, legacyOptionEncoding)
71+
72+
test("Int32 to Long decoding") {
73+
val input = createInput(new BsonInt32(42))
74+
val result = input.readSimple().readLong()
75+
assert(result == 42L)
76+
}
7177
}
7278

7379
class BsonInputOutputTest extends AnyFunSuite with ScalaCheckPropertyChecks {
@@ -131,6 +137,14 @@ class BsonInputOutputTest extends AnyFunSuite with ScalaCheckPropertyChecks {
131137
forAll(SomethingComplex.gen)(valueEncoding(_, legacyOptionEncoding = true))
132138
}
133139

140+
test("Int32 to Long decoding") {
141+
val doc = new BsonDocument("value", new BsonInt32(42))
142+
val reader = new BsonDocumentReader(doc)
143+
val input = new BsonReaderInput(reader, false)
144+
val sth = SomethingLong.codec.read(input)
145+
assert(sth == SomethingLong(42))
146+
}
147+
134148
test("All encoding schemes with problematic map keys") {
135149
forAll(SomethingComplex.gen) { sth =>
136150
val sthBefore = sth.copy(

commons-mongo/jvm/src/test/scala/com/avsystem/commons/mongo/SomethingPlain.scala

+6-7
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package com.avsystem.commons
22
package mongo
33

44
import com.avsystem.commons.misc.Bytes
5-
import com.avsystem.commons.serialization.GenCodec
5+
import com.avsystem.commons.serialization.HasGenCodec
66
import org.scalacheck.Arbitrary.arbitrary
77
import org.scalacheck.Gen
88

@@ -17,7 +17,7 @@ case class SomethingPlain(
1717
list: List[String],
1818
map: Map[String, String]
1919
)
20-
object SomethingPlain {
20+
object SomethingPlain extends HasGenCodec[SomethingPlain] {
2121
def sizedListOf[T](maxSize: Int, gen: => Gen[T]): Gen[List[T]] = {
2222
Gen.resize(maxSize, Gen.listOf(gen))
2323
}
@@ -50,8 +50,6 @@ object SomethingPlain {
5050
list,
5151
map
5252
)
53-
54-
implicit val codec: GenCodec[SomethingPlain] = GenCodec.materialize
5553
}
5654

5755
case class SomethingComplex(
@@ -61,7 +59,7 @@ case class SomethingComplex(
6159
nestedComplexList: List[List[SomethingPlain]],
6260
option: Option[Int]
6361
)
64-
object SomethingComplex {
62+
object SomethingComplex extends HasGenCodec[SomethingComplex] {
6563
val sthListGen: Gen[List[SomethingPlain]] = SomethingPlain.sizedListOf(8, SomethingPlain.gen)
6664

6765
val gen: Gen[SomethingComplex] = for {
@@ -77,6 +75,7 @@ object SomethingComplex {
7775
nestedComplexList,
7876
option
7977
)
80-
81-
implicit val codec: GenCodec[SomethingComplex] = GenCodec.materialize
8278
}
79+
80+
case class SomethingLong(value: Long)
81+
object SomethingLong extends HasGenCodec[SomethingLong]

0 commit comments

Comments
 (0)