[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