mirror of
https://github.com/postgres/postgres.git
synced 2025-07-11 10:01:57 +03:00
Bring in Peter's changes...finally :(
This commit is contained in:
@ -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 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();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user