From fa67a247cf66ea86f6fcc773c27cfd4698d2405a Mon Sep 17 00:00:00 2001 From: "Marc G. Fournier" Date: Sat, 20 Sep 1997 02:21:25 +0000 Subject: [PATCH] Bring in Peter's changes...finally :( --- .../jdbc/postgresql/Connection.java | 256 +--------- src/interfaces/jdbc/postgresql/PG_Stream.java | 309 ++++++++++++ src/interfaces/jdbc/postgresql/PGbox.java | 59 +++ src/interfaces/jdbc/postgresql/PGcircle.java | 72 +++ src/interfaces/jdbc/postgresql/PGlobj.java | 462 ++++++++++++++++++ src/interfaces/jdbc/postgresql/PGlseg.java | 58 +++ src/interfaces/jdbc/postgresql/PGpath.java | 99 ++++ src/interfaces/jdbc/postgresql/PGpoint.java | 96 ++++ src/interfaces/jdbc/postgresql/PGpolygon.java | 60 +++ .../jdbc/postgresql/PGtokenizer.java | 100 ++++ 10 files changed, 1324 insertions(+), 247 deletions(-) create mode 100644 src/interfaces/jdbc/postgresql/PG_Stream.java create mode 100644 src/interfaces/jdbc/postgresql/PGbox.java create mode 100644 src/interfaces/jdbc/postgresql/PGcircle.java create mode 100644 src/interfaces/jdbc/postgresql/PGlobj.java create mode 100644 src/interfaces/jdbc/postgresql/PGlseg.java create mode 100644 src/interfaces/jdbc/postgresql/PGpath.java create mode 100644 src/interfaces/jdbc/postgresql/PGpoint.java create mode 100644 src/interfaces/jdbc/postgresql/PGpolygon.java create mode 100644 src/interfaces/jdbc/postgresql/PGtokenizer.java diff --git a/src/interfaces/jdbc/postgresql/Connection.java b/src/interfaces/jdbc/postgresql/Connection.java index a208970ae2..bb41dff01b 100644 --- a/src/interfaces/jdbc/postgresql/Connection.java +++ b/src/interfaces/jdbc/postgresql/Connection.java @@ -28,7 +28,7 @@ import postgresql.*; */ public class Connection implements java.sql.Connection { - private PG_Stream pg_stream; + protected PG_Stream pg_stream; private String PG_HOST; private int PG_PORT; @@ -591,256 +591,18 @@ public class Connection implements java.sql.Connection { return PG_USER; } -} - -// *********************************************************************** - -// This class handles all the Streamed I/O for a postgresql connection -class PG_Stream -{ - private Socket connection; - private InputStream pg_input; - private OutputStream pg_output; - - /** - * Constructor: Connect to the PostgreSQL back end and return - * a stream connection. - * - * @param host the hostname to connect to - * @param port the port number that the postmaster is sitting on - * @exception IOException if an IOException occurs below it. - */ - public PG_Stream(String host, int port) throws IOException - { - connection = new Socket(host, port); - pg_input = connection.getInputStream(); - pg_output = connection.getOutputStream(); - } - - /** - * Sends a single character to the back end - * - * @param val the character to be sent - * @exception IOException if an I/O error occurs - */ - public void SendChar(int val) throws IOException - { - pg_output.write(val); - } - - /** - * Sends an integer to the back end - * - * @param val the integer to be sent - * @param siz the length of the integer in bytes (size of structure) - * @exception IOException if an I/O error occurs - */ - public void SendInteger(int val, int siz) throws IOException - { - byte[] buf = new byte[siz]; - - while (siz-- > 0) - { - buf[siz] = (byte)(val & 0xff); - val >>= 8; - } - Send(buf); - } - - /** - * Send an array of bytes to the backend - * - * @param buf The array of bytes to be sent - * @exception IOException if an I/O error occurs - */ - public void Send(byte buf[]) throws IOException - { - pg_output.write(buf); - } - - /** - * Send an exact array of bytes to the backend - if the length - * has not been reached, send nulls until it has. - * - * @param buf the array of bytes to be sent - * @param siz the number of bytes to be sent - * @exception IOException if an I/O error occurs - */ - public void Send(byte buf[], int siz) throws IOException - { - int i; - - pg_output.write(buf, 0, (buf.length < siz ? buf.length : siz)); - if (buf.length < siz) - { - for (i = buf.length ; i < siz ; ++i) - { - pg_output.write(0); - } - } - } - - /** - * Receives a single character from the backend - * - * @return the character received - * @exception SQLException if an I/O Error returns - */ - public int ReceiveChar() throws SQLException - { - int c = 0; - - try - { - c = pg_input.read(); - if (c < 0) throw new IOException("EOF"); - } catch (IOException e) { - throw new SQLException("Error reading from backend: " + e.toString()); - } - return c; - } - - /** - * Receives an integer from the backend - * - * @param siz length of the integer in bytes - * @return the integer received from the backend - * @exception SQLException if an I/O error occurs - */ - public int ReceiveInteger(int siz) throws SQLException - { - int n = 0; - - try - { - for (int i = 0 ; i < siz ; i++) - { - int b = pg_input.read(); - - if (b < 0) - throw new IOException("EOF"); - n = n | (b >> (8 * i)) ; - } - } catch (IOException e) { - throw new SQLException("Error reading from backend: " + e.toString()); - } - return n; - } - - /** - * Receives a null-terminated string from the backend. Maximum of - * maxsiz bytes - if we don't see a null, then we assume something - * has gone wrong. - * - * @param maxsiz maximum length of string - * @return string from back end - * @exception SQLException if an I/O error occurs - */ - public String ReceiveString(int maxsiz) throws SQLException - { - byte[] rst = new byte[maxsiz]; - int s = 0; - - try - { - while (s < maxsiz) - { - int c = pg_input.read(); - if (c < 0) - throw new IOException("EOF"); - else if (c == 0) - break; - else - rst[s++] = (byte)c; - } - if (s >= maxsiz) - throw new IOException("Too Much Data"); - } catch (IOException e) { - throw new SQLException("Error reading from backend: " + e.toString()); - } - String v = new String(rst, 0, s); - return v; - } /** - * Read a tuple from the back end. A tuple is a two dimensional - * array of bytes - * - * @param nf the number of fields expected - * @param bin true if the tuple is a binary tuple - * @return null if the current response has no more tuples, otherwise - * an array of strings - * @exception SQLException if a data I/O error occurs - */ - public byte[][] ReceiveTuple(int nf, boolean bin) throws SQLException - { - int i, bim = (nf + 7)/8; - byte[] bitmask = Receive(bim); - byte[][] answer = new byte[nf][0]; - - int whichbit = 0x80; - int whichbyte = 0; - - for (i = 0 ; i < nf ; ++i) - { - boolean isNull = ((bitmask[whichbyte] & whichbit) == 0); - whichbit >>= 1; - if (whichbit == 0) - { - ++whichbyte; - whichbit = 0x80; - } - if (isNull) - answer[i] = null; - else - { - int len = ReceiveInteger(4); - if (!bin) - len -= 4; - if (len < 0) - len = 0; - answer[i] = Receive(len); - } - } - return answer; - } - - /** - * Reads in a given number of bytes from the backend - * - * @param siz number of bytes to read - * @return array of bytes received - * @exception SQLException if a data I/O error occurs - */ - private byte[] Receive(int siz) throws SQLException - { - byte[] answer = new byte[siz]; - int s = 0; - - try - { - while (s < siz) - { - int w = pg_input.read(answer, s, siz - s); - if (w < 0) - throw new IOException("EOF"); - s += w; - } - } catch (IOException e) { - throw new SQLException("Error reading from backend: " + e.toString()); - } - return answer; - } - - /** - * Closes the connection + * This method is not part of the Connection interface. Its is an extension + * that allows access to the PostgreSQL Large Object API * - * @exception IOException if a IO Error occurs + * @return PGlobj class that implements the API */ - public void close() throws IOException + public PGlobj getLargeObjectAPI() throws SQLException { - pg_output.close(); - pg_input.close(); - connection.close(); + return new PGlobj(this); } } + +// *********************************************************************** + diff --git a/src/interfaces/jdbc/postgresql/PG_Stream.java b/src/interfaces/jdbc/postgresql/PG_Stream.java new file mode 100644 index 0000000000..3e3350dd10 --- /dev/null +++ b/src/interfaces/jdbc/postgresql/PG_Stream.java @@ -0,0 +1,309 @@ +package postgresql; + +import java.io.*; +import java.lang.*; +import java.net.*; +import java.util.*; +import java.sql.*; +import postgresql.*; + +/** + * @version 1.0 15-APR-1997 + * + * This class is used by Connection & PGlobj for communicating with the + * backend. + * + * @see java.sql.Connection + */ +// This class handles all the Streamed I/O for a postgresql connection +public class PG_Stream +{ + private Socket connection; + private InputStream pg_input; + private OutputStream pg_output; + + /** + * Constructor: Connect to the PostgreSQL back end and return + * a stream connection. + * + * @param host the hostname to connect to + * @param port the port number that the postmaster is sitting on + * @exception IOException if an IOException occurs below it. + */ + public PG_Stream(String host, int port) throws IOException + { + connection = new Socket(host, port); + pg_input = connection.getInputStream(); + pg_output = connection.getOutputStream(); + } + + /** + * Sends a single character to the back end + * + * @param val the character to be sent + * @exception IOException if an I/O error occurs + */ + public void SendChar(int val) throws IOException + { + //pg_output.write(val); + byte b[] = new byte[1]; + b[0] = (byte)val; + pg_output.write(b); + } + + /** + * Sends an integer to the back end + * + * @param val the integer to be sent + * @param siz the length of the integer in bytes (size of structure) + * @exception IOException if an I/O error occurs + */ + public void SendInteger(int val, int siz) throws IOException + { + byte[] buf = new byte[siz]; + + while (siz-- > 0) + { + buf[siz] = (byte)(val & 0xff); + val >>= 8; + } + Send(buf); + } + + /** + * Send an array of bytes to the backend + * + * @param buf The array of bytes to be sent + * @exception IOException if an I/O error occurs + */ + public void Send(byte buf[]) throws IOException + { + pg_output.write(buf); + } + + /** + * Send an exact array of bytes to the backend - if the length + * has not been reached, send nulls until it has. + * + * @param buf the array of bytes to be sent + * @param siz the number of bytes to be sent + * @exception IOException if an I/O error occurs + */ + public void Send(byte buf[], int siz) throws IOException + { + Send(buf,0,siz); + } + + /** + * Send an exact array of bytes to the backend - if the length + * has not been reached, send nulls until it has. + * + * @param buf the array of bytes to be sent + * @param off offset in the array to start sending from + * @param siz the number of bytes to be sent + * @exception IOException if an I/O error occurs + */ + public void Send(byte buf[], int off, int siz) throws IOException + { + int i; + + pg_output.write(buf, off, ((buf.length-off) < siz ? (buf.length-off) : siz)); + if((buf.length-off) < siz) + { + for (i = buf.length-off ; i < siz ; ++i) + { + pg_output.write(0); + } + } + } + + /** + * Receives a single character from the backend + * + * @return the character received + * @exception SQLException if an I/O Error returns + */ + public int ReceiveChar() throws SQLException + { + int c = 0; + + try + { + c = pg_input.read(); + if (c < 0) throw new IOException("EOF"); + } catch (IOException e) { + throw new SQLException("Error reading from backend: " + e.toString()); + } + return c; + } + + /** + * Receives an integer from the backend + * + * @param siz length of the integer in bytes + * @return the integer received from the backend + * @exception SQLException if an I/O error occurs + */ + public int ReceiveInteger(int siz) throws SQLException + { + int n = 0; + + try + { + for (int i = 0 ; i < siz ; i++) + { + int b = pg_input.read(); + + if (b < 0) + throw new IOException("EOF"); + n = n | (b >> (8 * i)) ; + } + } catch (IOException e) { + throw new SQLException("Error reading from backend: " + e.toString()); + } + return n; + } + + /** + * Receives a null-terminated string from the backend. Maximum of + * maxsiz bytes - if we don't see a null, then we assume something + * has gone wrong. + * + * @param maxsiz maximum length of string + * @return string from back end + * @exception SQLException if an I/O error occurs + */ + public String ReceiveString(int maxsiz) throws SQLException + { + byte[] rst = new byte[maxsiz]; + int s = 0; + + try + { + while (s < maxsiz) + { + int c = pg_input.read(); + if (c < 0) + throw new IOException("EOF"); + else if (c == 0) + break; + else + rst[s++] = (byte)c; + } + if (s >= maxsiz) + throw new IOException("Too Much Data"); + } catch (IOException e) { + throw new SQLException("Error reading from backend: " + e.toString()); + } + String v = new String(rst, 0, s); + return v; + } + + /** + * Read a tuple from the back end. A tuple is a two dimensional + * array of bytes + * + * @param nf the number of fields expected + * @param bin true if the tuple is a binary tuple + * @return null if the current response has no more tuples, otherwise + * an array of strings + * @exception SQLException if a data I/O error occurs + */ + public byte[][] ReceiveTuple(int nf, boolean bin) throws SQLException + { + int i, bim = (nf + 7)/8; + byte[] bitmask = Receive(bim); + byte[][] answer = new byte[nf][0]; + + int whichbit = 0x80; + int whichbyte = 0; + + for (i = 0 ; i < nf ; ++i) + { + boolean isNull = ((bitmask[whichbyte] & whichbit) == 0); + whichbit >>= 1; + if (whichbit == 0) + { + ++whichbyte; + whichbit = 0x80; + } + if (isNull) + answer[i] = null; + else + { + int len = ReceiveInteger(4); + if (!bin) + len -= 4; + if (len < 0) + len = 0; + answer[i] = Receive(len); + } + } + return answer; + } + + /** + * Reads in a given number of bytes from the backend + * + * @param siz number of bytes to read + * @return array of bytes received + * @exception SQLException if a data I/O error occurs + */ + private byte[] Receive(int siz) throws SQLException + { + byte[] answer = new byte[siz]; + int s = 0; + + try + { + while (s < siz) + { + int w = pg_input.read(answer, s, siz - s); + if (w < 0) + throw new IOException("EOF"); + s += w; + } + } catch (IOException e) { + throw new SQLException("Error reading from backend: " + e.toString()); + } + return answer; + } + + /** + * Reads in a given number of bytes from the backend + * + * @param buf buffer to store result + * @param off offset in buffer + * @param siz number of bytes to read + * @exception SQLException if a data I/O error occurs + */ + public void Receive(byte[] b,int off,int siz) throws SQLException + { + int s = 0; + + try + { + while (s < siz) + { + int w = pg_input.read(b, off+s, siz - s); + if (w < 0) + throw new IOException("EOF"); + s += w; + } + } catch (IOException e) { + throw new SQLException("Error reading from backend: " + e.toString()); + } + } + + /** + * Closes the connection + * + * @exception IOException if a IO Error occurs + */ + public void close() throws IOException + { + pg_output.close(); + pg_input.close(); + connection.close(); + } +} diff --git a/src/interfaces/jdbc/postgresql/PGbox.java b/src/interfaces/jdbc/postgresql/PGbox.java new file mode 100644 index 0000000000..b8edc00846 --- /dev/null +++ b/src/interfaces/jdbc/postgresql/PGbox.java @@ -0,0 +1,59 @@ +/** + * @version 6.2 + * + * This implements a box consisting of two points + * + */ + +package postgresql; + +import java.io.*; +import java.sql.*; + +public class PGbox implements Serializable +{ + /** + * These are the two points. + */ + public PGpoint point[] = new PGpoint[2]; + + public PGbox(double x1,double y1,double x2,double y2) + { + this.point[0] = new PGpoint(x1,y1); + this.point[1] = new PGpoint(x2,y2); + } + + public PGbox(PGpoint p1,PGpoint p2) + { + this.point[0] = p1; + this.point[1] = p2; + } + + /** + * This constructor is used by the driver. + */ + public PGbox(String s) throws SQLException + { + PGtokenizer t = new PGtokenizer(s,','); + if(t.getSize() != 2) + throw new SQLException("conversion of box failed - "+s); + + point[0] = new PGpoint(t.getToken(0)); + point[1] = new PGpoint(t.getToken(1)); + } + + public boolean equals(Object obj) + { + PGbox p = (PGbox)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])); + } + + /** + * This returns the lseg in the syntax expected by postgresql + */ + public String toString() + { + return point[0].toString()+","+point[1].toString(); + } +} diff --git a/src/interfaces/jdbc/postgresql/PGcircle.java b/src/interfaces/jdbc/postgresql/PGcircle.java new file mode 100644 index 0000000000..543a0a71c9 --- /dev/null +++ b/src/interfaces/jdbc/postgresql/PGcircle.java @@ -0,0 +1,72 @@ +/** + * + * This implements a circle consisting of a point and a radius + * + */ + +package postgresql; + +import java.io.*; +import java.sql.*; + +public class PGcircle implements Serializable +{ + /** + * This is the centre point + */ + public PGpoint center; + + /** + * This is the radius + */ + double radius; + + public PGcircle(double x,double y,double r) + { + this.center = new PGpoint(x,y); + this.radius = r; + } + + public PGcircle(PGpoint c,double r) + { + this.center = c; + this.radius = r; + } + + public PGcircle(PGcircle c) + { + this.center = new PGpoint(c.center); + this.radius = c.radius; + } + + /** + * This constructor is used by the driver. + */ + public PGcircle(String s) throws SQLException + { + PGtokenizer t = new PGtokenizer(PGtokenizer.removeAngle(s),','); + if(t.getSize() != 2) + throw new SQLException("conversion of circle failed - "+s); + + try { + center = new PGpoint(t.getToken(0)); + radius = Double.valueOf(t.getToken(1)).doubleValue(); + } catch(NumberFormatException e) { + throw new SQLException("conversion of circle failed - "+s+" - +"+e.toString()); + } + } + + public boolean equals(Object obj) + { + PGcircle p = (PGcircle)obj; + return p.center.equals(center) && p.radius==radius; + } + + /** + * This returns the circle in the syntax expected by postgresql + */ + public String toString() + { + return "<"+center+","+radius+">"; + } +} diff --git a/src/interfaces/jdbc/postgresql/PGlobj.java b/src/interfaces/jdbc/postgresql/PGlobj.java new file mode 100644 index 0000000000..939ad9a501 --- /dev/null +++ b/src/interfaces/jdbc/postgresql/PGlobj.java @@ -0,0 +1,462 @@ +// Java Interface to Postgres +// $Id: PGlobj.java,v 1.1 1997/09/20 02:21:22 scrappy Exp $ + +// Copyright (c) 1997 Peter T Mount + +package postgresql; + +import java.sql.*; +import java.math.*; +import java.net.*; +import java.io.*; +import java.util.*; + +/** + * This class implements the large object interface to postgresql. + * + * It provides the basic methods required to run the interface, plus + * a pair of methods that provide InputStream and OutputStream classes + * for this object. + */ +public class PGlobj +{ + // This table contains the function oid's used by the backend + private Hashtable func = new Hashtable(); + + protected postgresql.Connection conn; + + /** + * These are the values for mode, taken from libpq-fs.h + */ + public static final int INV_ARCHIVE = 0x00010000; + public static final int INV_WRITE = 0x00020000; + public static final int INV_READ = 0x00040000; + + /** + * These are the functions that implement the interface + */ + private static final String OPEN = "lo_open"; + private static final String CLOSE = "lo_close"; + private static final String CREATE = "lo_creat"; + private static final String UNLINK = "lo_unlink"; + private static final String SEEK = "lo_lseek"; + private static final String TELL = "lo_tell"; + private static final String READ = "loread"; + private static final String WRITE = "lowrite"; + + /** + * This creates the interface + */ + public PGlobj(Connection conn) throws SQLException + { + if(!(conn instanceof postgresql.Connection)) + throw new SQLException("PGlobj: Wrong connection class"); + + this.conn = (postgresql.Connection)conn; + ResultSet res = (postgresql.ResultSet)conn.createStatement().executeQuery("select proname, oid from pg_proc" + + " where proname = 'lo_open'" + + " or proname = 'lo_close'" + + " or proname = 'lo_creat'" + + " or proname = 'lo_unlink'" + + " or proname = 'lo_lseek'" + + " or proname = 'lo_tell'" + + " or proname = 'loread'" + + " or proname = 'lowrite'"); + + if(res==null) + throw new SQLException("failed to initialise large object interface"); + + while(res.next()) { + func.put(res.getString(1),new Integer(res.getInt(2))); + DriverManager.println("PGlobj:func "+res.getString(1)+" oid="+res.getInt(2)); + } + res.close(); + } + + // this returns the oid of the function + private int getFunc(String name) throws SQLException + { + Integer i = (Integer)func.get(name); + if(i==null) + throw new SQLException("unknown function: "+name); + return i.intValue(); + } + + /** + * This calls a function on the backend + * @param fnid oid of the function to run + * @param args array containing args, 3 ints per arg + */ + public int PQfn(int fnid,int args[]) throws SQLException + { + return PQfn(fnid,args,null,0,0); + } + + // fix bug in 6.1.1 + public void writeInt(DataOutputStream data,int i) throws IOException + { + data.writeByte((i>>24)&0xff); + data.writeByte( i &0xff); + data.writeByte((i>>8) &0xff); + data.writeByte((i>>16)&0xff); + } + + /** + * This calls a function on the backend + * @param fnid oid of the function to run + * @param args array containing args, 3 ints per arg + * @param buf byte array to write into, null returns result as an integer + * @param off offset in array + * @param len number of bytes to read + */ + public int PQfn(int fnid,int args[],byte buf[],int off,int len) throws SQLException + { + //ByteArrayOutputStream b = new ByteArrayOutputStream(); + //DataOutputStream data = new DataOutputStream(b); + int in = -1; + + try { + int al=args.length/3; + + // For some reason, the backend takes these in the reverse order + byte b[] = new byte[2+4+4]; + int bp=0; + b[bp++]='F'; + b[bp++]=0; + b[bp++]=(byte)((fnid)&0xff); + b[bp++]=(byte)((fnid>>24)&0xff); + b[bp++]=(byte)((fnid>>16)&0xff); + b[bp++]=(byte)((fnid>>8)&0xff); + b[bp++]=(byte)((al)&0xff); + b[bp++]=(byte)((al>>24)&0xff); + b[bp++]=(byte)((al>>16)&0xff); + b[bp++]=(byte)((al>>8)&0xff); + conn.pg_stream.Send(b); + + //conn.pg_stream.SendChar('F'); + //conn.pg_stream.SendInteger(fnid,4); + //conn.pg_stream.SendInteger(args.length / 3,4); + + int l = args.length-1; + if(args[l]==0) l--; + + for(int i=0;irl) + throw new IOException("mark invalidated"); + obj.seek(fd,mp); + } catch(SQLException e) { + throw new IOException(e.toString()); + } + } + + public boolean markSupported() + { + return true; + } + + + public void close() throws IOException + { + try { + obj.close(fd); + } catch(SQLException e) { + throw new IOException(e.toString()); + } + } +} + +// This class implements an OutputStream to a large object +class PGlobjOutput extends OutputStream +{ + private PGlobj obj; + private int fd; + + // This creates an Input stream based for a large object + public PGlobjOutput(PGlobj obj,int fd) + { + this.obj = obj; + this.fd = fd; + } + + public void write(int i) throws IOException + { + byte b[] = new byte[1]; + b[0] = (byte)i; + write(b,0,1); + } + + public void write(byte b[],int off,int len) throws IOException + { + try { + obj.write(fd,b,off,len); + } catch(SQLException e) { + throw new IOException(e.toString()); + } + } + + public void close() throws IOException + { + try { + obj.close(fd); + } catch(SQLException e) { + throw new IOException(e.toString()); + } + } +} diff --git a/src/interfaces/jdbc/postgresql/PGlseg.java b/src/interfaces/jdbc/postgresql/PGlseg.java new file mode 100644 index 0000000000..d073b46b20 --- /dev/null +++ b/src/interfaces/jdbc/postgresql/PGlseg.java @@ -0,0 +1,58 @@ +/** + * + * This implements a lseg (line segment) consisting of two points + * + */ + +package postgresql; + +import java.io.*; +import java.sql.*; + +public class PGlseg implements Serializable +{ + /** + * These are the two points. + */ + public PGpoint point[] = new PGpoint[2]; + + public PGlseg(double x1,double y1,double x2,double y2) + { + this.point[0] = new PGpoint(x1,y1); + this.point[1] = new PGpoint(x2,y2); + } + + public PGlseg(PGpoint p1,PGpoint p2) + { + this.point[0] = p1; + this.point[1] = p2; + } + + /** + * This constructor is used by the driver. + */ + public PGlseg(String s) throws SQLException + { + PGtokenizer t = new PGtokenizer(PGtokenizer.removeBox(s),','); + if(t.getSize() != 2) + throw new SQLException("conversion of lseg failed - "+s); + + point[0] = new PGpoint(t.getToken(0)); + point[1] = new PGpoint(t.getToken(1)); + } + + public boolean equals(Object obj) + { + PGlseg p = (PGlseg)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])); + } + + /** + * This returns the lseg in the syntax expected by postgresql + */ + public String toString() + { + return "["+point[0]+","+point[1]+"]"; + } +} diff --git a/src/interfaces/jdbc/postgresql/PGpath.java b/src/interfaces/jdbc/postgresql/PGpath.java new file mode 100644 index 0000000000..d87bbedbaa --- /dev/null +++ b/src/interfaces/jdbc/postgresql/PGpath.java @@ -0,0 +1,99 @@ +/** + * + * This implements a path (a multiple segmented line, which may be closed) + * + */ + +package postgresql; + +import java.io.*; +import java.sql.*; + +public class PGpath implements Serializable +{ + public int npoints; + public boolean open; + public PGpoint point[]; + + public PGpath(int num,PGpoint[] points,boolean open) + { + npoints = num; + this.point = points; + this.open = open; + } + + /** + * This constructor is used by the driver. + */ + public PGpath(String s) throws SQLException + { + // First test to see if were open + if(s.startsWith("[") && s.endsWith("]")) { + open = true; + s = PGtokenizer.removeBox(s); + } else if(s.startsWith("(") && s.endsWith(")")) { + open = false; + s = PGtokenizer.removePara(s); + } else + throw new SQLException("cannot tell if path is open or closed"); + + PGtokenizer t = new PGtokenizer(s,','); + npoints = t.getSize(); + point = new PGpoint[npoints]; + for(int p=0;p");} + public void removeAngle() {remove("<",">");} +} -- GitLab