Skip to content

Commit 6c07d56

Browse files
committed
BoxCodec
1 parent 527a8eb commit 6c07d56

File tree

5 files changed

+207
-1
lines changed

5 files changed

+207
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package io.r2dbc.postgresql.codec;
2+
3+
import io.r2dbc.postgresql.util.Assert;
4+
5+
import java.util.Objects;
6+
7+
/**
8+
* Value object that maps to the {@code box} datatype in Postgres.
9+
*/
10+
public final class Box {
11+
12+
private final Point a;
13+
14+
private final Point b;
15+
16+
private Box(Point a, Point b) {
17+
this.a = Assert.requireNonNull(a, "point A must not be null");
18+
this.b = Assert.requireNonNull(b, "point B must not be null");
19+
}
20+
21+
public static Box of(Point a, Point b) {
22+
return new Box(a, b);
23+
}
24+
25+
public Point getA() {
26+
return this.a;
27+
}
28+
29+
public Point getB() {
30+
return this.b;
31+
}
32+
33+
@Override
34+
public boolean equals(Object o) {
35+
if (this == o) {
36+
return true;
37+
}
38+
if (o == null || getClass() != o.getClass()) {
39+
return false;
40+
}
41+
Box box = (Box) o;
42+
return (this.a.equals(box.a) && this.b.equals(box.b))
43+
|| (this.a.equals(box.b) && this.b.equals(box.a));
44+
}
45+
46+
@Override
47+
public int hashCode() {
48+
return Objects.hash(this.a, this.b);
49+
}
50+
51+
@Override
52+
public String toString() {
53+
return "(" + this.a + "," + this.b + ')';
54+
}
55+
56+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package io.r2dbc.postgresql.codec;
2+
3+
import io.netty.buffer.ByteBuf;
4+
import io.netty.buffer.ByteBufAllocator;
5+
import io.r2dbc.postgresql.type.PostgresqlObjectId;
6+
7+
import java.util.List;
8+
9+
final class BoxCodec extends AbstractGeometryCodec<Box> {
10+
11+
BoxCodec(ByteBufAllocator byteBufAllocator) {
12+
super(Box.class, PostgresqlObjectId.BOX, byteBufAllocator);
13+
}
14+
15+
@Override
16+
Box doDecodeBinary(ByteBuf buffer) {
17+
double x1 = buffer.readDouble();
18+
double y1 = buffer.readDouble();
19+
double x2 = buffer.readDouble();
20+
double y2 = buffer.readDouble();
21+
return Box.of(Point.of(x1, y1), Point.of(x2, y2));
22+
}
23+
24+
@Override
25+
Box doDecodeText(String text) {
26+
List<String> tokens = tokenizeTextData(text);
27+
return Box.of(
28+
Point.of(Double.parseDouble(tokens.get(0)), Double.parseDouble(tokens.get(1))),
29+
Point.of(Double.parseDouble(tokens.get(2)), Double.parseDouble(tokens.get(3)))
30+
);
31+
}
32+
33+
@Override
34+
ByteBuf doEncodeBinary(Box value) {
35+
return this.byteBufAllocator.buffer(32)
36+
.writeDouble(value.getA().getX())
37+
.writeDouble(value.getA().getY())
38+
.writeDouble(value.getB().getX())
39+
.writeDouble(value.getB().getY());
40+
}
41+
42+
}

src/main/java/io/r2dbc/postgresql/codec/DefaultCodecs.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ public DefaultCodecs(ByteBufAllocator byteBufAllocator) {
9797

9898
//Geometry
9999
new CircleCodec(byteBufAllocator),
100-
new PointCodec(byteBufAllocator)
100+
new PointCodec(byteBufAllocator),
101+
new BoxCodec(byteBufAllocator)
101102
));
102103
}
103104

src/test/java/io/r2dbc/postgresql/AbstractCodecIntegrationTests.java

+7
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import io.netty.buffer.Unpooled;
2222
import io.r2dbc.postgresql.api.PostgresqlResult;
2323
import io.r2dbc.postgresql.api.PostgresqlStatement;
24+
import io.r2dbc.postgresql.codec.Box;
2425
import io.r2dbc.postgresql.codec.Circle;
2526
import io.r2dbc.postgresql.codec.EnumCodec;
2627
import io.r2dbc.postgresql.codec.Json;
@@ -461,6 +462,12 @@ void offsetTime() {
461462
testCodec(OffsetTime.class, OffsetTime.of(LocalTime.now(), ZoneOffset.ofHoursMinutes(-3, -30)), "TIMETZ");
462463
}
463464

465+
@Test
466+
void box() {
467+
testCodec(Box.class, Box.of(Point.of(1.9, 2.8), Point.of(3.7, 4.6)), "BOX");
468+
testCodec(Box.class, Box.of(Point.of(1.5, 3.3), Point.of(5., 7.)), "BOX");
469+
}
470+
464471
private static <T> Mono<T> close(Connection connection) {
465472
return Mono.from(connection
466473
.close())
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package io.r2dbc.postgresql.codec;
2+
3+
import io.netty.buffer.ByteBuf;
4+
import io.r2dbc.postgresql.client.Parameter;
5+
import io.r2dbc.postgresql.client.ParameterAssert;
6+
import org.junit.jupiter.api.Test;
7+
8+
import static io.r2dbc.postgresql.client.Parameter.NULL_VALUE;
9+
import static io.r2dbc.postgresql.message.Format.FORMAT_BINARY;
10+
import static io.r2dbc.postgresql.message.Format.FORMAT_TEXT;
11+
import static io.r2dbc.postgresql.type.PostgresqlObjectId.BOX;
12+
import static io.r2dbc.postgresql.type.PostgresqlObjectId.POINT;
13+
import static io.r2dbc.postgresql.type.PostgresqlObjectId.VARCHAR;
14+
import static io.r2dbc.postgresql.util.ByteBufUtils.encode;
15+
import static io.r2dbc.postgresql.util.TestByteBufAllocator.TEST;
16+
import static org.assertj.core.api.Assertions.assertThat;
17+
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
18+
19+
/**
20+
* Unit tests for {@link BoxCodec}.
21+
*/
22+
public class BoxCodecUnitTest {
23+
24+
private static final int dataType = BOX.getObjectId();
25+
26+
@Test
27+
void constructorNoByteBufAllocator() {
28+
assertThatIllegalArgumentException().isThrownBy(() -> new BoxCodec(null))
29+
.withMessage("byteBufAllocator must not be null");
30+
}
31+
32+
@Test
33+
void decode() {
34+
Box box = Box.of(Point.of(1.9, 2.8), Point.of(3.7, 4.6));
35+
36+
ByteBuf boxTextFormat = encode(TEST, "((1.9, 2.8),(3.7, 4.6))");
37+
assertThat(new BoxCodec(TEST).decode(boxTextFormat, dataType, FORMAT_TEXT, Box.class))
38+
.isEqualTo(box);
39+
40+
ByteBuf boxByteFormat = TEST.buffer(32)
41+
.writeDouble(1.9).writeDouble(2.8)
42+
.writeDouble(3.7).writeDouble(4.6);
43+
assertThat(new BoxCodec(TEST).decode(boxByteFormat, dataType, FORMAT_BINARY, Box.class))
44+
.isEqualTo(box);
45+
}
46+
47+
@Test
48+
void decodeNoByteBuf() {
49+
assertThat(new BoxCodec(TEST).decode(null, dataType, FORMAT_TEXT, Box.class)).isNull();
50+
}
51+
52+
@Test
53+
void doCanDecode() {
54+
BoxCodec codec = new BoxCodec(TEST);
55+
56+
assertThat(codec.doCanDecode(BOX, FORMAT_BINARY)).isTrue();
57+
assertThat(codec.doCanDecode(VARCHAR, FORMAT_TEXT)).isFalse();
58+
assertThat(codec.doCanDecode(POINT, FORMAT_TEXT)).isFalse();
59+
}
60+
61+
@Test
62+
void doCanDecodeNoFormat() {
63+
assertThatIllegalArgumentException().isThrownBy(() -> new BoxCodec(TEST).doCanDecode(VARCHAR, null))
64+
.withMessage("format must not be null");
65+
}
66+
67+
@Test
68+
void doCanDecodeNoType() {
69+
assertThatIllegalArgumentException().isThrownBy(() -> new BoxCodec(TEST).doCanDecode(null, FORMAT_TEXT))
70+
.withMessage("type must not be null");
71+
}
72+
73+
@Test
74+
void doEncode() {
75+
Box box = Box.of(Point.of(1.9, 2.8), Point.of(3.7, 4.6));
76+
77+
ParameterAssert.assertThat(new BoxCodec(TEST).doEncode(box))
78+
.hasFormat(FORMAT_BINARY)
79+
.hasType(dataType)
80+
.hasValue(TEST.buffer(32)
81+
.writeDouble(1.9)
82+
.writeDouble(2.8)
83+
.writeDouble(3.7)
84+
.writeDouble(4.6)
85+
);
86+
}
87+
88+
@Test
89+
void doEncodeNoValue() {
90+
assertThatIllegalArgumentException().isThrownBy(() -> new BoxCodec(TEST).doEncode(null))
91+
.withMessage("value must not be null");
92+
}
93+
94+
@Test
95+
void encodeNull() {
96+
ParameterAssert.assertThat(new BoxCodec(TEST).encodeNull())
97+
.isEqualTo(new Parameter(FORMAT_BINARY, dataType, NULL_VALUE));
98+
}
99+
100+
}

0 commit comments

Comments
 (0)