[libpostgresql-jdbc-java] 01/05: fix:PGLine backpatch issue #343 from Phillip Ross
Emmanuel Bourg
ebourg-guest at moszumanska.debian.org
Mon Jan 9 21:17:42 UTC 2017
This is an automated email from the git hooks/post-receive script.
ebourg-guest pushed a commit to tag REL9_3_1104
in repository libpostgresql-jdbc-java.
commit 7c34d01135c1010ff72b55eae9892132da9a75ac
Author: Dave Cramer <davecramer at gmail.com>
Date: Thu Jul 9 14:10:42 2015 -0400
fix:PGLine backpatch issue #343 from Phillip Ross
---
org/postgresql/geometric/PGline.java | 138 +++++++++++++++++----------
org/postgresql/test/jdbc2/GeometricTest.java | 61 +++++++++++-
org/postgresql/util/PGtokenizer.java | 24 ++++-
3 files changed, 171 insertions(+), 52 deletions(-)
diff --git a/org/postgresql/geometric/PGline.java b/org/postgresql/geometric/PGline.java
index f082573..ba8c7a6 100644
--- a/org/postgresql/geometric/PGline.java
+++ b/org/postgresql/geometric/PGline.java
@@ -17,38 +17,72 @@ import java.io.Serializable;
import java.sql.SQLException;
/**
- * This implements a line consisting of two points.
+ * This implements a line represented by the linear equation Ax + By + C = 0
*
- * Currently line is not yet implemented in the backend, but this class
- * ensures that when it's done were ready for it.
- */
+ **/
public class PGline extends PGobject implements Serializable, Cloneable
{
+
+ /**
+ * Coefficient of x
+ */
+ public double a;
+
/**
- * These are the two points.
+ * Coefficient of y
*/
- public PGpoint point[] = new PGpoint[2];
+ public double b;
/**
- * @param x1 coordinate for first point
- * @param y1 coordinate for first point
- * @param x2 coordinate for second point
- * @param y2 coordinate for second point
+ * Constant
+ */
+ public double c;
+
+ /**
+ * @param a coefficient of x
+ * @param b coefficient of y
+ * @param c constant
+ */
+ public PGline(double a, double b, double c) {
+ this();
+ this.a = a;
+ this.b = b;
+ this.c = c;
+ }
+
+ /**
+ * @param x1 coordinate for first point on the line
+ * @param y1 coordinate for first point on the line
+ * @param x2 coordinate for second point on the line
+ * @param y2 coordinate for second point on the line
*/
public PGline(double x1, double y1, double x2, double y2)
{
- this(new PGpoint(x1, y1), new PGpoint(x2, y2));
+ this();
+ if (x1 == x2) {
+ a = -1;
+ b = 0;
+ } else {
+ a = (y2 - y1) / (x2 - x1);
+ b = -1;
+ }
+ c = y1 - a * x1;
}
/**
- * @param p1 first point
- * @param p2 second point
+ * @param p1 first point on the line
+ * @param p2 second point on the line
*/
public PGline(PGpoint p1, PGpoint p2)
{
- this();
- this.point[0] = p1;
- this.point[1] = p2;
+ this(p1.x, p1.y, p2.x, p2.y);
+ }
+
+ /**
+ * @param lseg Line segment which calls on this line.
+ */
+ public PGline(PGlseg lseg) {
+ this(lseg.point[0], lseg.point[1]);
}
/**
@@ -62,7 +96,7 @@ public class PGline extends PGobject implements Serializable, Cloneable
}
/**
- * reuired by the driver
+ * required by the driver
*/
public PGline()
{
@@ -75,44 +109,51 @@ public class PGline extends PGobject implements Serializable, Cloneable
*/
public void setValue(String s) throws SQLException
{
- PGtokenizer t = new PGtokenizer(PGtokenizer.removeBox(s), ',');
- if (t.getSize() != 2)
- throw new PSQLException(GT.tr("Conversion to type {0} failed: {1}.", new Object[]{type,s}), PSQLState.DATA_TYPE_MISMATCH);
-
- point[0] = new PGpoint(t.getToken(0));
- point[1] = new PGpoint(t.getToken(1));
+ if (s.trim().startsWith("{")) {
+ PGtokenizer t = new PGtokenizer(PGtokenizer.removeCurlyBrace(s), ',');
+ if (t.getSize() != 3)
+ throw new PSQLException(GT.tr("Conversion to type {0} failed: {1}.", new Object[]{type,s}), PSQLState.DATA_TYPE_MISMATCH);
+ a = Double.parseDouble(t.getToken(0));
+ b = Double.parseDouble(t.getToken(1));
+ c = Double.parseDouble(t.getToken(2));
+ } else if (s.trim().startsWith("[")) {
+ PGtokenizer t = new PGtokenizer(PGtokenizer.removeBox(s), ',');
+ if (t.getSize() != 2)
+ throw new PSQLException(GT.tr("Conversion to type {0} failed: {1}.", new Object[]{type,s}), PSQLState.DATA_TYPE_MISMATCH);
+ PGpoint point1 = new PGpoint(t.getToken(0));
+ PGpoint point2 = new PGpoint(t.getToken(1));
+ a = point2.x - point1.x;
+ b = point2.y - point1.y;
+ c = point1.y;
+ }
}
/**
* @param obj Object to compare with
* @return true if the two lines are identical
*/
- public boolean equals(Object obj)
- {
- if (obj instanceof PGline)
- {
- PGline p = (PGline)obj;
- return (p.point[0].equals(point[0]) && p.point[1].equals(point[1])) ||
- (p.point[0].equals(point[1]) && p.point[1].equals(point[0]));
- }
- return false;
- }
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (obj == null || getClass() != obj.getClass()) return false;
+ if (!super.equals(obj)) return false;
- public int hashCode() {
- return point[0].hashCode() ^ point[1].hashCode();
+ PGline pGline = (PGline)obj;
+
+ return Double.compare(pGline.a, a) == 0 &&
+ Double.compare(pGline.b, b) == 0 &&
+ Double.compare(pGline.c, c) == 0;
}
- public Object clone() throws CloneNotSupportedException
- {
- PGline newPGline = (PGline) super.clone();
- if( newPGline.point != null )
- {
- newPGline.point = (PGpoint[]) newPGline.point.clone();
- for( int i = 0; i < newPGline.point.length; ++i )
- if( newPGline.point[i] != null )
- newPGline.point[i] = (PGpoint) newPGline.point[i].clone();
- }
- return newPGline;
+ public int hashCode() {
+ int result = super.hashCode();
+ long temp;
+ temp = Double.doubleToLongBits(a);
+ result = 31 * result + (int)(temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(b);
+ result = 31 * result + (int)(temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(c);
+ result = 31 * result + (int)(temp ^ (temp >>> 32));
+ return result;
}
/**
@@ -120,6 +161,7 @@ public class PGline extends PGobject implements Serializable, Cloneable
*/
public String getValue()
{
- return "[" + point[0] + "," + point[1] + "]";
+ return "{" + a + "," + b + "," + c + "}";
}
-}
+
+}
\ No newline at end of file
diff --git a/org/postgresql/test/jdbc2/GeometricTest.java b/org/postgresql/test/jdbc2/GeometricTest.java
index 199c916..f5effaa 100644
--- a/org/postgresql/test/jdbc2/GeometricTest.java
+++ b/org/postgresql/test/jdbc2/GeometricTest.java
@@ -11,7 +11,12 @@ import org.postgresql.test.TestUtil;
import org.postgresql.util.PGobject;
import org.postgresql.geometric.*;
import junit.framework.TestCase;
+import org.postgresql.util.PSQLException;
+
import java.sql.*;
+import java.util.ArrayList;
+import java.util.List;
+
/*
* Test case for geometric type I/O
@@ -31,8 +36,8 @@ public class GeometricTest extends TestCase
{
con = TestUtil.openDB();
TestUtil.createTable(con,
- "testgeometric",
- "boxval box, circleval circle, lsegval lseg, pathval path, polygonval polygon, pointval point");
+ "testgeometric",
+ "boxval box, circleval circle, lsegval lseg, pathval path, polygonval polygon, pointval point, lineval line");
}
// Tear down the fixture for this test case.
@@ -107,7 +112,57 @@ public class GeometricTest extends TestCase
checkReadWrite(new PGpolygon(points), "polygonval");
}
+ public void testPGline() throws Exception {
+ final String columnName = "lineval";
+
+ // PostgreSQL versions older than 9.4 support creating columns with the LINE datatype, but
+ // not actually writing to those columns. Only try to write if the version if at least 9.4
+ final boolean roundTripToDatabase = TestUtil.haveMinimumServerVersion(con, "9.4");
+
+ if (TestUtil.haveMinimumServerVersion(con, "9.4")) {
+
+ // Apparently the driver requires public no-args constructor, and postgresql doesn't accept lines with A and B
+ // coefficients both being zero... so assert a no-arg instantiated instance throws an exception.
+ if (roundTripToDatabase) {
+ try {
+ checkReadWrite(new PGline(), columnName);
+ fail("Expected a PGSQLException to be thrown");
+ } catch (PSQLException e) {
+ assertTrue(e.getMessage().contains("A and B cannot both be zero"));
+ }
+ }
+
+ // Generate a dataset for testing.
+ List<PGline> linesToTest = new ArrayList<PGline>();
+ for (double i = 1; i <= 3; i += 0.25) {
+ // Test the 3-arg constructor (coefficients+constant)
+ linesToTest.add(new PGline(i, (0 - i), (1 / i)));
+ linesToTest.add(new PGline("{" + i + "," + (0 - i) + "," + (1 / i) + "}"));
+ // Test the 4-arg constructor (x/y coords of two points on the line)
+ linesToTest.add(new PGline(i, (0 - i), (1 / i), (1 / i / i)));
+ linesToTest.add(new PGline(i, (0 - i), i, (1 / i / i))); // tests vertical line
+ // Test 2-arg constructor (2 PGpoints on the line);
+ linesToTest.add(new PGline(new PGpoint(i, (0 - i)), new PGpoint((1 / i), (1 / i / i))));
+ linesToTest.add(new PGline(new PGpoint(i, (0 - i)), new PGpoint(i, (1 / i / i)))); // tests vertical line
+ // Test 1-arg constructor (PGlseg on the line);
+ linesToTest.add(new PGline(new PGlseg(i, (0 - i), (1 / i), (1 / i / i))));
+ linesToTest.add(new PGline(new PGlseg(i, (0 - i), i, (1 / i / i))));
+ linesToTest.add(new PGline(new PGlseg(new PGpoint(i, (0 - i)), new PGpoint((1 / i), (1 / i / i)))));
+ linesToTest.add(new PGline(new PGlseg(new PGpoint(i, (0 - i)), new PGpoint(i, (1 / i / i)))));
+ }
+
+ // Include persistence an querying if the postgresql version supports it.
+ if (roundTripToDatabase) {
+ for (PGline testLine : linesToTest) {
+ checkReadWrite(testLine, columnName);
+ }
+ }
+
+ }
+ }
+
public void testPGpoint() throws Exception {
checkReadWrite(new PGpoint(1.0, 2.0), "pointval");
}
-}
+
+}
\ No newline at end of file
diff --git a/org/postgresql/util/PGtokenizer.java b/org/postgresql/util/PGtokenizer.java
index 284c37a..06c7783 100644
--- a/org/postgresql/util/PGtokenizer.java
+++ b/org/postgresql/util/PGtokenizer.java
@@ -218,4 +218,26 @@ public class PGtokenizer
remove
("<", ">");
}
-}
+
+ /*
+ * Removes curly braces { and } from the beginning and end of a string
+ * @param s String to remove from
+ * @return String without the { or }
+ */
+ public static String removeCurlyBrace(String s)
+ {
+ return remove
+ (s, "{", "}");
+ }
+
+ /*
+ * Removes < and > from the beginning and end of all tokens
+ * @return String without the < or >
+ */
+ public void removeCurlyBrace()
+ {
+ remove
+ ("{", "}");
+ }
+
+}
\ No newline at end of file
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/libpostgresql-jdbc-java.git
More information about the pkg-java-commits
mailing list