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 <[email protected]> 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 _______________________________________________ pkg-java-commits mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-java-commits

