Skip to content

feature: adding support for lseg type #305

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/main/java/io/r2dbc/postgresql/codec/DefaultCodecs.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ public DefaultCodecs(ByteBufAllocator byteBufAllocator) {

//Geometry
new CircleCodec(byteBufAllocator),
new LineSegmentCodec(byteBufAllocator),
new PointCodec(byteBufAllocator)
));
}
Expand Down
65 changes: 65 additions & 0 deletions src/main/java/io/r2dbc/postgresql/codec/LineSegment.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.r2dbc.postgresql.codec;

import io.r2dbc.postgresql.util.Assert;

public final class LineSegment {

private final Point point1;

private final Point point2;

public LineSegment(Point point1, Point point2) {
this.point1 = Assert.requireNonNull(point1, "First Point must not be null");
this.point2 = Assert.requireNonNull(point2, "Second Point must not be null");
}

public LineSegment(double x1, double y1, double x2, double y2) {
this.point1 = Point.of(x1, y1);
this.point2 = Point.of(x2, y2);
}

public Point getPoint1() {
return point1;
}

public Point getPoint2() {
return point2;
}

@Override
public boolean equals(Object obj) {
if (obj instanceof LineSegment) {
LineSegment lineSegment = (LineSegment) obj;
return (lineSegment.point1.equals(this.point1) && lineSegment.point2.equals(this.point2))
|| (lineSegment.point1.equals(this.point2) && lineSegment.point2.equals(this.point1));
}
return false;
}

@Override
public int hashCode() {
return point1.hashCode() ^ point2.hashCode();
}

@Override
public String toString() {
return "[" + this.point1.toString() + "," + this.point2.toString() + "]";
}

}
96 changes: 96 additions & 0 deletions src/main/java/io/r2dbc/postgresql/codec/LineSegmentCodec.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.r2dbc.postgresql.codec;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.r2dbc.postgresql.client.Parameter;
import io.r2dbc.postgresql.message.Format;
import io.r2dbc.postgresql.type.PostgresqlObjectId;
import io.r2dbc.postgresql.util.Assert;
import io.r2dbc.postgresql.util.ByteBufUtils;
import reactor.util.annotation.Nullable;

import static io.r2dbc.postgresql.message.Format.FORMAT_BINARY;
import static io.r2dbc.postgresql.type.PostgresqlObjectId.LSEG;

final class LineSegmentCodec extends AbstractCodec<LineSegment> {

private final ByteBufAllocator byteBufAllocator;

LineSegmentCodec(ByteBufAllocator byteBufAllocator) {
super(LineSegment.class);
this.byteBufAllocator = Assert.requireNonNull(byteBufAllocator, "byteBufAllocator must not be null");
}

@Override
boolean doCanDecode(PostgresqlObjectId type, @Nullable Format format) {
Assert.requireNonNull(type, "type must not be null");

return LSEG == type;
}

@Override
LineSegment doDecode(ByteBuf buffer, PostgresqlObjectId dataType, Format format, Class<? extends LineSegment> type) {
Assert.requireNonNull(buffer, "byteBuf must not be null");
Assert.requireNonNull(type, "type must not be null");
Assert.requireNonNull(format, "format must not be null");

if (format == FORMAT_BINARY) {
double x1 = buffer.readDouble();
double y1 = buffer.readDouble();
double x2 = buffer.readDouble();
double y2 = buffer.readDouble();
return new LineSegment(Point.of(x1, y1), Point.of(x2, y2));
}

String decodedAsString = ByteBufUtils.decode(buffer);
String parenRemovedVal = decodedAsString.replaceAll("[()]", "")
.replace("[", "")
.replace("]", "")
.trim();
String[] coordinatesAsString = parenRemovedVal.split(",");
double x1 = Double.parseDouble(coordinatesAsString[0]);
double y1 = Double.parseDouble(coordinatesAsString[1]);
double x2 = Double.parseDouble(coordinatesAsString[2]);
double y2 = Double.parseDouble(coordinatesAsString[3]);
return new LineSegment(Point.of(x1, y1), Point.of(x2, y2));
}

@Override
Parameter doEncode(LineSegment value) {
Assert.requireNonNull(value, "value must not be null");
Point p1 = value.getPoint1();
Point p2 = value.getPoint2();
return create(LSEG, FORMAT_BINARY, () -> this.byteBufAllocator
.buffer(lengthInBytes())
.writeDouble(p1.getX())
.writeDouble(p1.getY())
.writeDouble(p2.getX())
.writeDouble(p2.getY()));
}

@Override
public Parameter encodeNull() {
return createNull(LSEG, FORMAT_BINARY);
}

int lengthInBytes() {
return 32;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,9 @@ public enum PostgresqlObjectId {
LINE(628),

/**
* The line segment object id
* The line segment(lseg) object id
*/
LINE_SEGMENT(601),
LSEG(601),

/**
* The money object id.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import io.r2dbc.postgresql.codec.Circle;
import io.r2dbc.postgresql.codec.EnumCodec;
import io.r2dbc.postgresql.codec.Json;
import io.r2dbc.postgresql.codec.LineSegment;
import io.r2dbc.postgresql.codec.Point;
import io.r2dbc.spi.Blob;
import io.r2dbc.spi.Clob;
Expand Down Expand Up @@ -334,6 +335,12 @@ void jsonb() {
}, "JSONB");
}

@Test
void lineSegment() {
testCodec(LineSegment.class, new LineSegment(Point.of(1.12, 2.12), Point.of(3.12, 4.12)), "LSEG");
testCodec(LineSegment.class, new LineSegment(Point.of(Double.MIN_VALUE, Double.MIN_VALUE), Point.of(Double.MAX_VALUE, Double.MAX_VALUE)), "LSEG");
}

@Test
void localDate() {
testCodec(LocalDate.class, LocalDate.now(), "DATE");
Expand Down
118 changes: 118 additions & 0 deletions src/test/java/io/r2dbc/postgresql/codec/LineSegmentCodecUnitTests.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
* Copyright 2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.r2dbc.postgresql.codec;

import io.netty.buffer.ByteBuf;
import io.r2dbc.postgresql.client.Parameter;
import io.r2dbc.postgresql.client.ParameterAssert;
import org.junit.jupiter.api.Test;

import static io.r2dbc.postgresql.client.Parameter.NULL_VALUE;
import static io.r2dbc.postgresql.message.Format.FORMAT_BINARY;
import static io.r2dbc.postgresql.message.Format.FORMAT_TEXT;
import static io.r2dbc.postgresql.type.PostgresqlObjectId.LSEG;
import static io.r2dbc.postgresql.type.PostgresqlObjectId.VARCHAR;
import static io.r2dbc.postgresql.util.TestByteBufAllocator.TEST;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;

/**
* Unit tests for {@link LineSegmentCodec}.
*/
final class LineSegmentCodecUnitTests {

@Test
void constructorNoByteBufAllocator() {
assertThatIllegalArgumentException().isThrownBy(() -> new LineSegmentCodec(null))
.withMessage("byteBufAllocator must not be null");
}

@Test
void doCanDecodeNoType() {
assertThatIllegalArgumentException().isThrownBy(() -> new LineSegmentCodec(TEST).doCanDecode(null, FORMAT_BINARY))
.withMessage("type must not be null");
}

@Test
void doCanDecode() {
LineSegmentCodec codec = new LineSegmentCodec(TEST);

assertThat(codec.doCanDecode(VARCHAR, FORMAT_BINARY)).isFalse();
assertThat(codec.doCanDecode(LSEG, FORMAT_TEXT)).isTrue();
assertThat(codec.doCanDecode(LSEG, FORMAT_BINARY)).isTrue();
}

@Test
void doDecodeNoByteBuf() {
assertThatIllegalArgumentException().isThrownBy(() -> new LineSegmentCodec(TEST).doDecode(null, LSEG, FORMAT_BINARY, LineSegment.class))
.withMessage("byteBuf must not be null");
}

@Test
void doDecodeNoType() {
assertThatIllegalArgumentException().isThrownBy(() -> new LineSegmentCodec(TEST).doDecode(TEST.buffer(), LSEG, FORMAT_BINARY, null))
.withMessage("type must not be null");
}

@Test
void doDecodeNoFormat() {
assertThatIllegalArgumentException().isThrownBy(() -> new LineSegmentCodec(TEST).doDecode(TEST.buffer(), LSEG, null, LineSegment.class))
.withMessage("format must not be null");
}

@Test
void doDecode() {
LineSegmentCodec codec = new LineSegmentCodec(TEST);
Point point1 = Point.of(1.12, 2.12);
Point point2 = Point.of(3.12, 4.12);
LineSegment lineSegment = new LineSegment(point1, point2);
ByteBuf lineSegmentAsBinary = TEST.buffer(codec.lengthInBytes())
.writeDouble(1.12)
.writeDouble(2.12)
.writeDouble(3.12)
.writeDouble(4.12);
assertThat(codec.doDecode(lineSegmentAsBinary, LSEG, FORMAT_BINARY, LineSegment.class)).isEqualTo(lineSegment);
}

@Test
void doEncodeNoValue() {
assertThatIllegalArgumentException().isThrownBy(() -> new LineSegmentCodec(TEST).doEncode(null))
.withMessage("value must not be null");
}

@Test
void doEncode() {
LineSegmentCodec codec = new LineSegmentCodec(TEST);
ByteBuf lineSegmentAsBinary = TEST.buffer(codec.lengthInBytes())
.writeDouble(1.12)
.writeDouble(2.12)
.writeDouble(3.12)
.writeDouble(4.12);

ParameterAssert.assertThat(codec.doEncode(new LineSegment(Point.of(1.12, 2.12), Point.of(3.12, 4.12))))
.hasFormat(FORMAT_BINARY)
.hasType(LSEG.getObjectId())
.hasValue(lineSegmentAsBinary);
}

@Test
void encodeNull() {
ParameterAssert.assertThat(new LineSegmentCodec(TEST).encodeNull())
.isEqualTo(new Parameter(FORMAT_BINARY, LSEG.getObjectId(), NULL_VALUE));
}

}