-
Notifications
You must be signed in to change notification settings - Fork 184
Support for geospatial types - point, line, box, polygon etc #306
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
Closed
Changes from 7 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
527a8eb
AbstractGeometryCodec
anshlykov 6c07d56
BoxCodec
anshlykov 0e9402e
LineCodec
anshlykov 6af1108
LsegCodec
anshlykov 602f8d7
PathCodec
anshlykov 6d5c22d
PolygonCodec
anshlykov 6e2c374
refactor
anshlykov 0c147ee
fix review
anshlykov File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
85 changes: 85 additions & 0 deletions
85
src/main/java/io/r2dbc/postgresql/codec/AbstractGeometryCodec.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
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 java.util.ArrayList; | ||
import java.util.List; | ||
|
||
abstract class AbstractGeometryCodec<T> extends AbstractCodec<T> { | ||
|
||
protected final PostgresqlObjectId postgresqlObjectId; | ||
|
||
protected final ByteBufAllocator byteBufAllocator; | ||
|
||
AbstractGeometryCodec(Class<T> type, PostgresqlObjectId postgresqlObjectId, ByteBufAllocator byteBufAllocator) { | ||
super(type); | ||
this.postgresqlObjectId = Assert.requireNonNull(postgresqlObjectId, "postgresqlObjectId must not be null"); | ||
this.byteBufAllocator = Assert.requireNonNull(byteBufAllocator, "byteBufAllocator must not be null"); | ||
} | ||
|
||
abstract T doDecodeBinary(ByteBuf byteBuffer); | ||
|
||
abstract T doDecodeText(String text); | ||
|
||
abstract ByteBuf doEncodeBinary(T value); | ||
|
||
@Override | ||
boolean doCanDecode(PostgresqlObjectId type, Format format) { | ||
Assert.requireNonNull(type, "type must not be null"); | ||
Assert.requireNonNull(format, "format must not be null"); | ||
return postgresqlObjectId == type; | ||
} | ||
|
||
@Override | ||
T doDecode(ByteBuf buffer, PostgresqlObjectId dataType, Format format, Class<? extends T> 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.FORMAT_BINARY) { | ||
return doDecodeBinary(buffer); | ||
} | ||
return doDecodeText(ByteBufUtils.decode(buffer)); | ||
} | ||
|
||
@Override | ||
Parameter doEncode(T value) { | ||
Assert.requireNonNull(value, "value must not be null"); | ||
return create(this.postgresqlObjectId, Format.FORMAT_BINARY, () -> doEncodeBinary(value)); | ||
} | ||
|
||
@Override | ||
public Parameter encodeNull() { | ||
return createNull(postgresqlObjectId, Format.FORMAT_BINARY); | ||
} | ||
|
||
protected List<String> tokenizeTextData(String string) { | ||
List<String> tokens = new ArrayList<>(); | ||
|
||
for (int p = 0, s = 0; p < string.length(); p++) { | ||
char c = string.charAt(p); | ||
|
||
if (c == '(' || c == '[' || c == '<' || c == '{') { | ||
s++; | ||
continue; | ||
} | ||
|
||
if (c == ',' || c == ')' || c == ']' || c == '>' || c == '}') { | ||
if (s != p) { | ||
tokens.add(string.substring(s, p)); | ||
s = p + 1; | ||
} else { | ||
s++; | ||
} | ||
} | ||
} | ||
|
||
return tokens; | ||
} | ||
|
||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package io.r2dbc.postgresql.codec; | ||
|
||
import io.r2dbc.postgresql.util.Assert; | ||
|
||
import java.util.Objects; | ||
|
||
/** | ||
* Value object that maps to the {@code box} datatype in Postgres. | ||
* <p> | ||
* Uses {@code double} to represent the coordinates. | ||
*/ | ||
public final class Box { | ||
|
||
private final Point a; | ||
|
||
private final Point b; | ||
|
||
private Box(Point a, Point b) { | ||
this.a = Assert.requireNonNull(a, "point A must not be null"); | ||
this.b = Assert.requireNonNull(b, "point B must not be null"); | ||
} | ||
|
||
public static Box of(Point a, Point b) { | ||
return new Box(a, b); | ||
} | ||
|
||
public Point getA() { | ||
return this.a; | ||
} | ||
|
||
public Point getB() { | ||
return this.b; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
Box box = (Box) o; | ||
return (this.a.equals(box.a) && this.b.equals(box.b)) | ||
|| (this.a.equals(box.b) && this.b.equals(box.a)); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(this.a, this.b); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "(" + this.a + "," + this.b + ')'; | ||
} | ||
|
||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package io.r2dbc.postgresql.codec; | ||
|
||
import io.netty.buffer.ByteBuf; | ||
import io.netty.buffer.ByteBufAllocator; | ||
import io.r2dbc.postgresql.type.PostgresqlObjectId; | ||
|
||
import java.util.List; | ||
|
||
final class BoxCodec extends AbstractGeometryCodec<Box> { | ||
|
||
BoxCodec(ByteBufAllocator byteBufAllocator) { | ||
super(Box.class, PostgresqlObjectId.BOX, byteBufAllocator); | ||
} | ||
|
||
@Override | ||
Box doDecodeBinary(ByteBuf buffer) { | ||
double x1 = buffer.readDouble(); | ||
double y1 = buffer.readDouble(); | ||
double x2 = buffer.readDouble(); | ||
double y2 = buffer.readDouble(); | ||
return Box.of(Point.of(x1, y1), Point.of(x2, y2)); | ||
} | ||
|
||
@Override | ||
Box doDecodeText(String text) { | ||
List<String> tokens = tokenizeTextData(text); | ||
return Box.of( | ||
Point.of(Double.parseDouble(tokens.get(0)), Double.parseDouble(tokens.get(1))), | ||
Point.of(Double.parseDouble(tokens.get(2)), Double.parseDouble(tokens.get(3))) | ||
); | ||
} | ||
|
||
@Override | ||
ByteBuf doEncodeBinary(Box value) { | ||
return this.byteBufAllocator.buffer(32) | ||
.writeDouble(value.getA().getX()) | ||
.writeDouble(value.getA().getY()) | ||
.writeDouble(value.getB().getX()) | ||
.writeDouble(value.getB().getY()); | ||
} | ||
|
||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package io.r2dbc.postgresql.codec; | ||
|
||
import java.util.Objects; | ||
|
||
/** | ||
* Value object that maps to the {@code line} datatype in Postgres. | ||
* <p> | ||
* Uses {@code double} to represent the coordinates. | ||
*/ | ||
public final class Line { | ||
|
||
private final double a; | ||
|
||
private final double b; | ||
|
||
private final double c; | ||
|
||
private Line(double a, double b, double c) { | ||
this.a = a; | ||
this.b = b; | ||
this.c = c; | ||
} | ||
|
||
public static Line of(double a, double b, double c) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it make sense to add factory methods accepting two points or even x1/y1, x2/y2? |
||
return new Line(a, b, c); | ||
} | ||
|
||
public double getA() { | ||
return this.a; | ||
} | ||
|
||
public double getB() { | ||
return this.b; | ||
} | ||
|
||
public double getC() { | ||
return this.c; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
Line line = (Line) o; | ||
return Double.compare(line.a, this.a) == 0 && | ||
Double.compare(line.b, this.b) == 0 && | ||
Double.compare(line.c, this.c) == 0; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(this.a, this.b, this.c); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "{" + this.a + "," + this.b + "," + this.c + '}'; | ||
} | ||
|
||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should add a bit of Javadoc to the fields.