Bring in Peter's changes...finally :(
This commit is contained in:
parent
e9cd0f2e6b
commit
fa67a247cf
@ -28,7 +28,7 @@ import postgresql.*;
|
|||||||
*/
|
*/
|
||||||
public class Connection implements java.sql.Connection
|
public class Connection implements java.sql.Connection
|
||||||
{
|
{
|
||||||
private PG_Stream pg_stream;
|
protected PG_Stream pg_stream;
|
||||||
|
|
||||||
private String PG_HOST;
|
private String PG_HOST;
|
||||||
private int PG_PORT;
|
private int PG_PORT;
|
||||||
@ -591,256 +591,18 @@ public class Connection implements java.sql.Connection
|
|||||||
{
|
{
|
||||||
return PG_USER;
|
return PG_USER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is not part of the Connection interface. Its is an extension
|
||||||
|
* that allows access to the PostgreSQL Large Object API
|
||||||
|
*
|
||||||
|
* @return PGlobj class that implements the API
|
||||||
|
*/
|
||||||
|
public PGlobj getLargeObjectAPI() throws SQLException
|
||||||
|
{
|
||||||
|
return new PGlobj(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ***********************************************************************
|
// ***********************************************************************
|
||||||
|
|
||||||
// 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
|
|
||||||
*
|
|
||||||
* @exception IOException if a IO Error occurs
|
|
||||||
*/
|
|
||||||
public void close() throws IOException
|
|
||||||
{
|
|
||||||
pg_output.close();
|
|
||||||
pg_input.close();
|
|
||||||
connection.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
309
src/interfaces/jdbc/postgresql/PG_Stream.java
Normal file
309
src/interfaces/jdbc/postgresql/PG_Stream.java
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
}
|
59
src/interfaces/jdbc/postgresql/PGbox.java
Normal file
59
src/interfaces/jdbc/postgresql/PGbox.java
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
}
|
72
src/interfaces/jdbc/postgresql/PGcircle.java
Normal file
72
src/interfaces/jdbc/postgresql/PGcircle.java
Normal file
@ -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+">";
|
||||||
|
}
|
||||||
|
}
|
462
src/interfaces/jdbc/postgresql/PGlobj.java
Normal file
462
src/interfaces/jdbc/postgresql/PGlobj.java
Normal file
@ -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;i<l;i++)
|
||||||
|
conn.pg_stream.SendInteger(args[i],4);
|
||||||
|
|
||||||
|
if(args[args.length-1]==0)
|
||||||
|
conn.pg_stream.Send(buf,off,len);
|
||||||
|
|
||||||
|
} catch(Exception e) {
|
||||||
|
throw new SQLException("lo_open failed");
|
||||||
|
}
|
||||||
|
//try {
|
||||||
|
if((in = conn.pg_stream.ReceiveChar())!='V') {
|
||||||
|
if(in=='E')
|
||||||
|
throw new SQLException(conn.pg_stream.ReceiveString(4096));
|
||||||
|
throw new SQLException("lobj: expected 'V' from backend, got "+((char)in));
|
||||||
|
}
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
in = conn.pg_stream.ReceiveChar();
|
||||||
|
switch(in)
|
||||||
|
{
|
||||||
|
case 'G':
|
||||||
|
if(buf==null)
|
||||||
|
in = conn.pg_stream.ReceiveInteger(4);
|
||||||
|
else
|
||||||
|
conn.pg_stream.Receive(buf,off,len);
|
||||||
|
conn.pg_stream.ReceiveChar();
|
||||||
|
return in;
|
||||||
|
|
||||||
|
case 'E':
|
||||||
|
throw new SQLException("lobj: error - "+conn.pg_stream.ReceiveString(4096));
|
||||||
|
|
||||||
|
case 'N':
|
||||||
|
conn.pg_stream.ReceiveString(4096);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '0':
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new SQLException("lobj: protocol error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// } catch(IOException ioe) {
|
||||||
|
// throw new SQLException("lobj: Network error - "+ioe);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This opens a large object. It returns a handle that is used to
|
||||||
|
* access the object.
|
||||||
|
*/
|
||||||
|
public int open(int lobjId,int mode) throws SQLException
|
||||||
|
{
|
||||||
|
int args[] = new int[2*3];
|
||||||
|
args[0] = args[3] = 4;
|
||||||
|
args[1] = args[4] = 1;
|
||||||
|
args[2] = lobjId;
|
||||||
|
args[5] = mode;
|
||||||
|
|
||||||
|
int fd = PQfn(getFunc(OPEN),args);
|
||||||
|
if(fd<0)
|
||||||
|
throw new SQLException("lo_open: no object");
|
||||||
|
seek(fd,0);
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This closes a large object.
|
||||||
|
*/
|
||||||
|
public void close(int fd) throws SQLException
|
||||||
|
{
|
||||||
|
int args[] = new int[1*3];
|
||||||
|
args[0] = 4;
|
||||||
|
args[1] = 1;
|
||||||
|
args[2] = fd;
|
||||||
|
|
||||||
|
// flush/close streams here?
|
||||||
|
PQfn(getFunc(CLOSE),args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This reads a block of bytes from the large object
|
||||||
|
* @param fd descriptor for an open large object
|
||||||
|
* @param buf byte array to write into
|
||||||
|
* @param off offset in array
|
||||||
|
* @param len number of bytes to read
|
||||||
|
*/
|
||||||
|
public void read(int fd,byte buf[],int off,int len) throws SQLException
|
||||||
|
{
|
||||||
|
int args[] = new int[2*3];
|
||||||
|
args[0] = args[3] = 4;
|
||||||
|
args[1] = args[4] = 1;
|
||||||
|
args[2] = fd;
|
||||||
|
args[5] = len;
|
||||||
|
|
||||||
|
PQfn(getFunc(READ),args,buf,off,len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This writes a block of bytes to an open large object
|
||||||
|
* @param fd descriptor for an open large object
|
||||||
|
* @param buf byte array to write into
|
||||||
|
* @param off offset in array
|
||||||
|
* @param len number of bytes to read
|
||||||
|
*/
|
||||||
|
public void write(int fd,byte buf[],int off,int len) throws SQLException
|
||||||
|
{
|
||||||
|
int args[] = new int[2*3];
|
||||||
|
args[0] = args[3] = 4;
|
||||||
|
args[1] = args[4] = 1;
|
||||||
|
args[2] = fd;
|
||||||
|
args[5] = 0;
|
||||||
|
|
||||||
|
PQfn(getFunc(WRITE),args,buf,off,len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This sets the current read or write location on a large object.
|
||||||
|
* @param fd descriptor of an open large object
|
||||||
|
* @param off offset in object
|
||||||
|
*/
|
||||||
|
public void seek(int fd,int off) throws SQLException
|
||||||
|
{
|
||||||
|
int args[] = new int[3*3];
|
||||||
|
args[0] = args[3] = args[6] = 4;
|
||||||
|
args[1] = args[4] = args[7] = 1;
|
||||||
|
args[2] = fd;
|
||||||
|
args[5] = off;
|
||||||
|
args[8] = 0; // SEEK
|
||||||
|
|
||||||
|
PQfn(getFunc(SEEK),args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This creates a new large object.
|
||||||
|
*
|
||||||
|
* the mode is a bitmask describing different attributes of the new object
|
||||||
|
*
|
||||||
|
* returns the oid of the large object created.
|
||||||
|
*/
|
||||||
|
public int create(int mode) throws SQLException
|
||||||
|
{
|
||||||
|
int args[] = new int[1*3];
|
||||||
|
args[0] = 4;
|
||||||
|
args[1] = 1;
|
||||||
|
args[2] = mode;
|
||||||
|
|
||||||
|
return PQfn(getFunc(CREATE),args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This returns the current location within the large object
|
||||||
|
*/
|
||||||
|
public int tell(int fd) throws SQLException
|
||||||
|
{
|
||||||
|
int args[] = new int[1*3];
|
||||||
|
args[0] = 4;
|
||||||
|
args[1] = 1;
|
||||||
|
args[2] = fd;
|
||||||
|
|
||||||
|
return PQfn(getFunc(TELL),args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This removes a large object from the database
|
||||||
|
*/
|
||||||
|
public void unlink(int fd) throws SQLException
|
||||||
|
{
|
||||||
|
int args[] = new int[1*3];
|
||||||
|
args[0] = 4;
|
||||||
|
args[1] = 1;
|
||||||
|
args[2] = fd;
|
||||||
|
|
||||||
|
PQfn(getFunc(UNLINK),args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This returns an InputStream based on an object
|
||||||
|
*/
|
||||||
|
public InputStream getInputStream(int fd) throws SQLException
|
||||||
|
{
|
||||||
|
return (InputStream) new PGlobjInput(this,fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This returns an OutputStream based on an object
|
||||||
|
*/
|
||||||
|
public OutputStream getOutputStream(int fd) throws SQLException
|
||||||
|
{
|
||||||
|
return (OutputStream) new PGlobjOutput(this,fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* As yet, the lo_import and lo_export functions are not implemented.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
// This class implements an InputStream based on a large object
|
||||||
|
//
|
||||||
|
// Note: Unlike most InputStreams, this one supports mark()/reset()
|
||||||
|
//
|
||||||
|
class PGlobjInput extends InputStream
|
||||||
|
{
|
||||||
|
private PGlobj obj;
|
||||||
|
private int fd;
|
||||||
|
|
||||||
|
private int mp; // mark position
|
||||||
|
private int rl; // read limit
|
||||||
|
|
||||||
|
// This creates an Input stream based for a large object
|
||||||
|
public PGlobjInput(PGlobj obj,int fd)
|
||||||
|
{
|
||||||
|
this.obj = obj;
|
||||||
|
this.fd = fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int read() throws IOException
|
||||||
|
{
|
||||||
|
byte b[] = new byte[1];
|
||||||
|
read(b,0,1);
|
||||||
|
return (int)b[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public int read(byte b[],int off,int len) throws IOException
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
obj.read(fd,b,off,len);
|
||||||
|
} catch(SQLException e) {
|
||||||
|
throw new IOException(e.toString());
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long skip(long n) throws IOException
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
int cp = obj.tell(fd);
|
||||||
|
obj.seek(fd,cp+(int)n);
|
||||||
|
return obj.tell(fd) - cp;
|
||||||
|
} catch(SQLException e) {
|
||||||
|
throw new IOException(e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void mark(int readLimit)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
mp = obj.tell(fd);
|
||||||
|
rl = readLimit;
|
||||||
|
} catch(SQLException e) {
|
||||||
|
// We should throw an exception here, but mark() doesn't ;-(
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() throws IOException
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
int cp = obj.tell(fd);
|
||||||
|
if((cp-mp)>rl)
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
58
src/interfaces/jdbc/postgresql/PGlseg.java
Normal file
58
src/interfaces/jdbc/postgresql/PGlseg.java
Normal file
@ -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]+"]";
|
||||||
|
}
|
||||||
|
}
|
99
src/interfaces/jdbc/postgresql/PGpath.java
Normal file
99
src/interfaces/jdbc/postgresql/PGpath.java
Normal file
@ -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<npoints;p++)
|
||||||
|
point[p] = new PGpoint(t.getToken(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object obj)
|
||||||
|
{
|
||||||
|
PGpath p = (PGpath)obj;
|
||||||
|
|
||||||
|
if(p.npoints != npoints)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(p.open != open)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for(int i=0;i<npoints;i++)
|
||||||
|
if(!point[i].equals(p.point[i]))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This returns the polygon in the syntax expected by postgresql
|
||||||
|
*/
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
StringBuffer b = new StringBuffer(open?"[":"(");
|
||||||
|
|
||||||
|
for(int p=0;p<npoints;p++)
|
||||||
|
b.append(point[p].toString());
|
||||||
|
|
||||||
|
b.append(open?"]":")");
|
||||||
|
|
||||||
|
return b.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOpen()
|
||||||
|
{
|
||||||
|
return open;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isClosed()
|
||||||
|
{
|
||||||
|
return !open;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void closePath()
|
||||||
|
{
|
||||||
|
open = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void openPath()
|
||||||
|
{
|
||||||
|
open = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
96
src/interfaces/jdbc/postgresql/PGpoint.java
Normal file
96
src/interfaces/jdbc/postgresql/PGpoint.java
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* This implements a version of java.awt.Point, except it uses double
|
||||||
|
* to represent the coordinates.
|
||||||
|
*
|
||||||
|
* It maps to the point datatype in postgresql.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package postgresql;
|
||||||
|
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.io.*;
|
||||||
|
import java.sql.*;
|
||||||
|
|
||||||
|
public class PGpoint implements Serializable
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* These are the coordinates.
|
||||||
|
* These are public, because their equivalents in java.awt.Point are
|
||||||
|
*/
|
||||||
|
public double x,y;
|
||||||
|
|
||||||
|
public PGpoint(double x,double y)
|
||||||
|
{
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PGpoint(PGpoint p)
|
||||||
|
{
|
||||||
|
this(p.x,p.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This constructor is used by the driver.
|
||||||
|
*/
|
||||||
|
public PGpoint(String s) throws SQLException
|
||||||
|
{
|
||||||
|
PGtokenizer t = new PGtokenizer(PGtokenizer.removePara(s),',');
|
||||||
|
try {
|
||||||
|
x = Double.valueOf(t.getToken(0)).doubleValue();
|
||||||
|
y = Double.valueOf(t.getToken(1)).doubleValue();
|
||||||
|
} catch(NumberFormatException e) {
|
||||||
|
throw new SQLException("conversion of point failed - "+e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object obj)
|
||||||
|
{
|
||||||
|
PGpoint p = (PGpoint)obj;
|
||||||
|
return x == p.x && y == p.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This returns the point in the syntax expected by postgresql
|
||||||
|
*/
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return "("+x+","+y+")";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void translate(int x,int y)
|
||||||
|
{
|
||||||
|
translate((double)x,(double)y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void translate(double x,double y)
|
||||||
|
{
|
||||||
|
this.x += x;
|
||||||
|
this.y += y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void move(int x,int y)
|
||||||
|
{
|
||||||
|
setLocation(x,y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void move(double x,double y)
|
||||||
|
{
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// refer to java.awt.Point for description of this
|
||||||
|
public void setLocation(int x,int y)
|
||||||
|
{
|
||||||
|
move((double)x,(double)y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// refer to java.awt.Point for description of this
|
||||||
|
public void setLocation(Point p)
|
||||||
|
{
|
||||||
|
setLocation(p.x,p.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
60
src/interfaces/jdbc/postgresql/PGpolygon.java
Normal file
60
src/interfaces/jdbc/postgresql/PGpolygon.java
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* This implements a polygon (based on java.awt.Polygon)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package postgresql;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.sql.*;
|
||||||
|
|
||||||
|
public class PGpolygon implements Serializable
|
||||||
|
{
|
||||||
|
public int npoints;
|
||||||
|
|
||||||
|
public PGpoint point[];
|
||||||
|
|
||||||
|
public PGpolygon(int num,PGpoint[] points)
|
||||||
|
{
|
||||||
|
npoints = num;
|
||||||
|
this.point = points;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This constructor is used by the driver.
|
||||||
|
*/
|
||||||
|
public PGpolygon(String s) throws SQLException
|
||||||
|
{
|
||||||
|
PGtokenizer t = new PGtokenizer(PGtokenizer.removePara(s),',');
|
||||||
|
npoints = t.getSize();
|
||||||
|
point = new PGpoint[npoints];
|
||||||
|
for(int p=0;p<npoints;p++)
|
||||||
|
point[p] = new PGpoint(t.getToken(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object obj)
|
||||||
|
{
|
||||||
|
PGpolygon p = (PGpolygon)obj;
|
||||||
|
|
||||||
|
if(p.npoints != npoints)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for(int i=0;i<npoints;i++)
|
||||||
|
if(!point[i].equals(p.point[i]))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This returns the polygon in the syntax expected by postgresql
|
||||||
|
*/
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
StringBuffer b = new StringBuffer();
|
||||||
|
for(int p=0;p<npoints;p++)
|
||||||
|
b.append(point[p].toString());
|
||||||
|
return b.toString();
|
||||||
|
}
|
||||||
|
}
|
100
src/interfaces/jdbc/postgresql/PGtokenizer.java
Normal file
100
src/interfaces/jdbc/postgresql/PGtokenizer.java
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* This class is used to tokenize the text output of postgres.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package postgresql;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class PGtokenizer
|
||||||
|
{
|
||||||
|
protected Vector tokens;
|
||||||
|
|
||||||
|
public PGtokenizer(String string,char delim)
|
||||||
|
{
|
||||||
|
tokenize(string,delim);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tokenizes a new string
|
||||||
|
*/
|
||||||
|
public int tokenize(String string,char delim)
|
||||||
|
{
|
||||||
|
tokens = new Vector();
|
||||||
|
|
||||||
|
int nest=0,p,s;
|
||||||
|
for(p=0,s=0;p<string.length();p++) {
|
||||||
|
char c = string.charAt(p);
|
||||||
|
|
||||||
|
// increase nesting if an open character is found
|
||||||
|
if(c == '(' || c == '[')
|
||||||
|
nest++;
|
||||||
|
|
||||||
|
// decrease nesting if a close character is found
|
||||||
|
if(c == ')' || c == ']')
|
||||||
|
nest--;
|
||||||
|
|
||||||
|
if(nest==0 && c==delim) {
|
||||||
|
tokens.addElement(string.substring(s,p));
|
||||||
|
s=p+1; // +1 to skip the delimiter
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't forget the last token ;-)
|
||||||
|
if(s<string.length())
|
||||||
|
tokens.addElement(string.substring(s));
|
||||||
|
|
||||||
|
return tokens.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSize()
|
||||||
|
{
|
||||||
|
return tokens.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getToken(int n)
|
||||||
|
{
|
||||||
|
return (String)tokens.elementAt(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This returns a new tokenizer based on one of our tokens
|
||||||
|
*/
|
||||||
|
public PGtokenizer tokenizeToken(int n,char delim)
|
||||||
|
{
|
||||||
|
return new PGtokenizer(getToken(n),delim);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This removes the lead/trailing strings from a string
|
||||||
|
*/
|
||||||
|
public static String remove(String s,String l,String t)
|
||||||
|
{
|
||||||
|
if(s.startsWith(l)) s = s.substring(l.length());
|
||||||
|
if(s.endsWith(t)) s = s.substring(0,s.length()-t.length());
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This removes the lead/trailing strings from all tokens
|
||||||
|
*/
|
||||||
|
public void remove(String l,String t)
|
||||||
|
{
|
||||||
|
for(int i=0;i<tokens.size();i++) {
|
||||||
|
tokens.setElementAt(remove((String)tokens.elementAt(i),l,t),i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String removePara(String s) {return remove(s,"(",")");}
|
||||||
|
public void removePara() {remove("(",")");}
|
||||||
|
|
||||||
|
public static String removeBox(String s) {return remove(s,"[","]");}
|
||||||
|
public void removeBox() {remove("[","]");}
|
||||||
|
|
||||||
|
public static String removeAngle(String s) {return remove(s,"<",">");}
|
||||||
|
public void removeAngle() {remove("<",">");}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user