Commit 6a061da2 authored by Marc G. Fournier's avatar Marc G. Fournier

Update patch from Peter <patches@maidast.demon.co.uk>

parent 0b6dc93b
package postgresql;
import java.math.*;
import java.sql.*;
import java.math.*;
/**
* @version 1.0 15-APR-1997
* @author <A HREF="mailto:adrian@hottub.org">Adrian Hall</A>
*
* CallableStatement is used to execute SQL stored procedures.
*
* JDBC provides a stored procedure SQL escape that allows stored procedures
* to be called in a standard way for all RDBMS's. This escape syntax has
* one form that includes a result parameter and one that does not. If used,
* the result parameter must be generated as an OUT parameter. The other
* parameters may be used for input, output or both. Parameters are refered
* to sequentially, by number. The first parameter is 1.
*
* <PRE>
* {?= call <procedure-name>[<arg1>,<arg2>, ...]}
* {call <procedure-name>[<arg1>,<arg2>, ...]}
* </PRE>
*
* IN parameters are set using the set methods inherited from
* PreparedStatement. The type of all OUT parameters must be registered
* prior to executing the stored procedure; their values are retrieved
* after execution via the get methods provided here.
*
* A CallableStatement may return a ResultSet or multiple ResultSets. Multiple
* ResultSets are handled using operations inherited from Statement.
*
* For maximum portability, a call's ResultSets and update counts should be
* processed prior to getting the values of output parameters.
*
* @see java.sql.Connection#prepareCall
* @see java.sql.ResultSet
* @see java.sql.CallableStatement
* JDBC Interface to Postgres95 functions
*/
public class CallableStatement implements java.sql.CallableStatement
// Copy methods from the Result set object here.
public class CallableStatement extends PreparedStatement implements java.sql.CallableStatement
{
public void registerOutParameter (int paramterIndex, int sqlType) throws SQLException
CallableStatement(Connection c,String q) throws SQLException
{
// XXX-Not Implemented
super(c,q);
}
public void registerOutParameter (int parameterIndex, int sqlType, int scale) throws SQLException
{
// XXX-Not Implemented
// Before executing a stored procedure call you must explicitly
// call registerOutParameter to register the java.sql.Type of each
// out parameter.
public void registerOutParameter(int parameterIndex, int sqlType) throws SQLException {
}
public boolean wasNull () throws SQLException
// You must also specify the scale for numeric/decimal types:
public void registerOutParameter(int parameterIndex, int sqlType,
int scale) throws SQLException
{
// XXX-Not Implemented
}
public String getString (int parameterIndex) throws SQLException
{
// XXX-Not Implemented
public boolean isNull(int parameterIndex) throws SQLException {
return true;
}
public boolean getBoolean (int parameterIndex) throws SQLException
{
// XXX-Not Implemented
// New API (JPM)
public boolean wasNull() throws SQLException {
// check to see if the last access threw an exception
return false; // fake it for now
}
public byte getByte (int parameterIndex) throws SQLException
{
// XXX-Not Implemented
// Methods for retrieving OUT parameters from this statement.
public String getChar(int parameterIndex) throws SQLException {
return null;
}
public short getShort (int parameterIndex) throws SQLException
{
// XXX-Not Implemented
// New API (JPM)
public String getString(int parameterIndex) throws SQLException {
return null;
}
//public String getVarChar(int parameterIndex) throws SQLException {
// return null;
//}
public int getInt (int parameterIndex) throws SQLException
{
// XXX-Not Implemented
public String getLongVarChar(int parameterIndex) throws SQLException {
return null;
}
public long getLong (int parameterIndex) throws SQLException
{
// XXX-Not Implemented
// New API (JPM) (getBit)
public boolean getBoolean(int parameterIndex) throws SQLException {
return false;
}
public float getFloat (int parameterIndex) throws SQLException
{
// XXX-Not Implemented
// New API (JPM) (getTinyInt)
public byte getByte(int parameterIndex) throws SQLException {
return 0;
}
public double getDouble (int parameterIndex) throws SQLException
{
// XXX-Not Implemented
// New API (JPM) (getSmallInt)
public short getShort(int parameterIndex) throws SQLException {
return 0;
}
public BigDecimal getBigDecimal (int parameterIndex, int scale) throws SQLException
{
// XXX-Not Implemented
// New API (JPM) (getInteger)
public int getInt(int parameterIndex) throws SQLException {
return 0;
}
public byte[] getBytes (int parameterIndex) throws SQLException
{
// XXX-Not Implemented
// New API (JPM) (getBigInt)
public long getLong(int parameterIndex) throws SQLException {
return 0;
}
public Date getDate (int parameterIndex) throws SQLException
{
// XXX-Not Implemented
public float getFloat(int parameterIndex) throws SQLException {
return (float) 0.0;
}
public Time getTime (int parameterIndex) throws SQLException
{
// XXX-Not Implemented
public double getDouble(int parameterIndex) throws SQLException {
return 0.0;
}
public Timestamp getTimestamp (int parameterIndex) throws SQLException
{
// XXX-Not Implemented
public BigDecimal getBigDecimal(int parameterIndex, int scale)
throws SQLException {
return null;
}
public Object getObject (int parameterIndex) throws SQLException
{
// XXX-Not Implemented
// New API (JPM) (getBinary)
public byte[] getBytes(int parameterIndex) throws SQLException {
return null;
}
// New API (JPM) (getLongVarBinary)
public byte[] getBinaryStream(int parameterIndex) throws SQLException {
return null;
}
public java.sql.Date getDate(int parameterIndex) throws SQLException {
return null;
}
public java.sql.Time getTime(int parameterIndex) throws SQLException {
return null;
}
public java.sql.Timestamp getTimestamp(int parameterIndex)
throws SQLException {
return null;
}
//----------------------------------------------------------------------
// Advanced features:
// You can obtain a ParameterMetaData object to get information
// about the parameters to this CallableStatement.
public DatabaseMetaData getMetaData() {
return null;
}
// getObject returns a Java object for the parameter.
// See the JDBC spec's "Dynamic Programming" chapter for details.
public Object getObject(int parameterIndex)
throws SQLException {
return null;
}
}
......@@ -45,7 +45,7 @@ public class Connection implements java.sql.Connection
private boolean autoCommit = true;
private boolean readOnly = false;
private Driver this_driver;
protected Driver this_driver;
private String this_url;
private String cursor = null; // The positioned update cursor name
......@@ -153,7 +153,7 @@ public class Connection implements java.sql.Connection
public java.sql.CallableStatement prepareCall(String sql) throws SQLException
{
throw new SQLException("Callable Statements are not supported at this time");
// return new CallableStatement(this, sql);
// return new CallableStatement(this, sql);
}
/**
......@@ -295,8 +295,7 @@ public class Connection implements java.sql.Connection
*/
public java.sql.DatabaseMetaData getMetaData() throws SQLException
{
// return new DatabaseMetaData(this);
throw new SQLException("DatabaseMetaData not supported");
return new DatabaseMetaData(this);
}
/**
......
......@@ -2,12 +2,8 @@ package postgresql;
import java.sql.*;
import java.util.*;
import postgresql.*;
/**
* @version 1.0 15-APR-1997
* @author <A HREF="mailto:adrian@hottub.org">Adrian Hall</A>
*
* The Java SQL framework allows for multiple database drivers. Each
* driver should supply a class that implements the Driver interface
*
......@@ -28,12 +24,19 @@ import postgresql.*;
*/
public class Driver implements java.sql.Driver
{
// These should be in sync with the backend that the driver was
// distributed with
static final int MAJORVERSION = 6;
static final int MINORVERSION = 2;
static
{
try
{
new Driver();
try {
// moved the registerDriver from the constructor to here
// because some clients call the driver themselves (I know, as
// my early jdbc work did - and that was based on other examples).
// Placing it here, means that the driver is registered once only.
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException e) {
e.printStackTrace();
}
......@@ -46,7 +49,6 @@ public class Driver implements java.sql.Driver
*/
public Driver() throws SQLException
{
java.sql.DriverManager.registerDriver(this);
}
/**
......@@ -79,19 +81,10 @@ public class Driver implements java.sql.Driver
*/
public java.sql.Connection connect(String url, Properties info) throws SQLException
{
DriverURL dr = new DriverURL(url);
int port;
if (!(dr.protocol().equals("jdbc")))
if((props = parseURL(url,info))==null)
return null;
if (!(dr.subprotocol().equals("postgresql")))
return null;
if (dr.host().equals("unknown"))
return null;
port = dr.port();
if (port == -1)
port = 5432; // Default PostgreSQL port
return new Connection (dr.host(), port, info, dr.database(), url, this);
return new Connection (host(), port(), props, database(), url, this);
}
/**
......@@ -108,12 +101,9 @@ public class Driver implements java.sql.Driver
*/
public boolean acceptsURL(String url) throws SQLException
{
DriverURL dr = new DriverURL(url);
if (dr.protocol().equals("jdbc"))
if (dr.subprotocol().equals("postgresql"))
return true;
if(parseURL(url,null)==null)
return false;
return true;
}
/**
......@@ -146,7 +136,7 @@ public class Driver implements java.sql.Driver
*/
public int getMajorVersion()
{
return 1;
return MAJORVERSION;
}
/**
......@@ -156,7 +146,7 @@ public class Driver implements java.sql.Driver
*/
public int getMinorVersion()
{
return 0;
return MINORVERSION;
}
/**
......@@ -170,76 +160,105 @@ public class Driver implements java.sql.Driver
{
return false;
}
}
/**
* The DriverURL class splits a JDBC URL into its subcomponents
*
* protocol:subprotocol:/[/host[:port]/][database]
*/
class DriverURL
{
private String protocol, subprotocol, host, database;
private int port = -1;
private Properties props;
static private String[] protocols = { "jdbc","postgresql" };
/**
* Constructs a new DriverURL, splitting the specified URL into its
* component parts
*/
public DriverURL(String url) throws SQLException
Properties parseURL(String url,Properties defaults) throws SQLException
{
int a, b, c;
String tmp, hostport, dbportion;
int state = -1;
Properties urlProps = new Properties(defaults);
String key = new String();
String value = new String();
a = url.indexOf(':');
if (a == -1)
throw new SQLException("Bad URL Protocol specifier");
b = url.indexOf(':', a+1);
if (b == -1)
throw new SQLException("Bad URL Subprotocol specifier");
protocol = new String(url.substring(0, a));
subprotocol = new String(url.substring(a+1, b));
tmp = new String(url.substring(b+1, url.length()));
if (tmp.length() < 2)
throw new SQLException("Bad URL Database specifier");
if (!tmp.substring(0, 2).equals("//"))
{
host = new String("unknown");
port = -1;
database = new String(tmp.substring(1, tmp.length()));
return;
StringTokenizer st = new StringTokenizer(url, ":/;=&?", true);
for (int count = 0; (st.hasMoreTokens()); count++) {
String token = st.nextToken();
// PM June 29 1997
// Added this, to help me understand how this works.
// Unless you want each token to be processed, leave this commented out
// but don't delete it.
//DriverManager.println("wellFormedURL: state="+state+" count="+count+" token='"+token+"'");
// PM Aug 2 1997 - Modified to allow multiple backends
if (count <= 3) {
if ((count % 2) == 1 && token.equals(":"))
;
else if((count % 2) == 0) {
boolean found=(count==0)?true:false;
for(int tmp=0;tmp<protocols.length;tmp++) {
if(token.equals(protocols[tmp])) {
// PM June 29 1997 Added this property to enable the driver
// to handle multiple backend protocols.
if(count == 2 && tmp > 0) {
urlProps.put("Protocol",token);
found=true;
}
dbportion = new String(tmp.substring(2, tmp.length()));
c = dbportion.indexOf('/');
if (c == -1)
throw new SQLException("Bad URL Database specifier");
a = dbportion.indexOf(':');
if (a == -1)
{
host = new String(dbportion.substring(0, c));
port = -1;
database = new String(dbportion.substring(c+1, dbportion.length()));
} else {
host = new String(dbportion.substring(0, a));
port = Integer.valueOf(dbportion.substring(a+1, c)).intValue();
database = new String(dbportion.substring(c+1, dbportion.length()));
}
}
/**
* Returns the protocol name of the DriverURL
*/
public String protocol()
{
return protocol;
if(found == false)
return null;
} else return null;
}
else if (count > 3) {
if (count == 4 && token.equals("/")) state = 0;
else if (count == 4) {
urlProps.put("PGDBNAME", token);
state = -2;
}
else if (count == 5 && state == 0 && token.equals("/"))
state = 1;
else if (count == 5 && state == 0)
return null;
else if (count == 6 && state == 1)
urlProps.put("PGHOST", token);
else if (count == 7 && token.equals(":")) state = 2;
else if (count == 8 && state == 2) {
try {
Integer portNumber = Integer.decode(token);
urlProps.put("PGPORT", portNumber.toString());
} catch (Exception e) {
return null;
}
}
else if ((count == 7 || count == 9) &&
(state == 1 || state == 2) && token.equals("/"))
state = -1;
else if (state == -1) {
urlProps.put("PGDBNAME", token);
state = -2;
}
else if (state <= -2 && (count % 2) == 1) {
// PM Aug 2 1997 - added tests for ? and &
if (token.equals(";") || token.equals("?") || token.equals("&") ) state = -3;
else if (token.equals("=")) state = -5;
}
else if (state <= -2 && (count % 2) == 0) {
if (state == -3) key = token;
else if (state == -5) {
value = token;
//DriverManager.println("put("+key+","+value+")");
urlProps.put(key, value);
state = -2;
}
}
}
}
/**
* Returns the subprotocol name of the DriverURL
*/
public String subprotocol()
{
return subprotocol;
// PM June 29 1997
// This now outputs the properties only if we are logging
if(DriverManager.getLogStream() != null)
urlProps.list(DriverManager.getLogStream());
return urlProps;
}
/**
......@@ -247,7 +266,7 @@ class DriverURL
*/
public String host()
{
return host;
return props.getProperty("PGHOST","localhost");
}
/**
......@@ -256,7 +275,7 @@ class DriverURL
*/
public int port()
{
return port;
return Integer.parseInt(props.getProperty("PGPORT","5432"));
}
/**
......@@ -264,6 +283,15 @@ class DriverURL
*/
public String database()
{
return database;
return props.getProperty("PGDBNAME");
}
/**
* Returns any property
*/
public String property(String name)
{
return props.getProperty(name);
}
}
......@@ -54,20 +54,34 @@ public class Field
throw new SQLException("Unexpected return from query for type");
result.next();
type_name = result.getString(1);
if (type_name.equals("int2")) sql_type = Types.SMALLINT;
else if (type_name.equals("int4")) sql_type = Types.INTEGER;
else if (type_name.equals("int8")) sql_type = Types.BIGINT;
else if (type_name.equals("cash")) sql_type = Types.DECIMAL;
else if (type_name.equals("money")) sql_type = Types.DECIMAL;
else if (type_name.equals("float4")) sql_type = Types.REAL;
else if (type_name.equals("float8")) sql_type = Types.DOUBLE;
else if (type_name.equals("bpchar")) sql_type = Types.CHAR;
else if (type_name.equals("varchar")) sql_type = Types.VARCHAR;
else if (type_name.equals("bool")) sql_type = Types.BIT;
else if (type_name.equals("date")) sql_type = Types.DATE;
else if (type_name.equals("time")) sql_type = Types.TIME;
else if (type_name.equals("abstime")) sql_type = Types.TIMESTAMP;
else sql_type = Types.OTHER;
if (type_name.equals("int2"))
sql_type = Types.SMALLINT;
else if (type_name.equals("int4"))
sql_type = Types.INTEGER;
else if (type_name.equals("int8"))
sql_type = Types.BIGINT;
else if (type_name.equals("cash"))
sql_type = Types.DECIMAL;
else if (type_name.equals("money"))
sql_type = Types.DECIMAL;
else if (type_name.equals("float4"))
sql_type = Types.REAL;
else if (type_name.equals("float8"))
sql_type = Types.DOUBLE;
else if (type_name.equals("bpchar"))
sql_type = Types.CHAR;
else if (type_name.equals("varchar"))
sql_type = Types.VARCHAR;
else if (type_name.equals("bool"))
sql_type = Types.BIT;
else if (type_name.equals("date"))
sql_type = Types.DATE;
else if (type_name.equals("time"))
sql_type = Types.TIME;
else if (type_name.equals("abstime"))
sql_type = Types.TIMESTAMP;
else
sql_type = Types.OTHER;
}
return sql_type;
}
......
......@@ -23,9 +23,123 @@ public class PG_Object
* @param type a string describing the type of the object
* @param value a string representation of the value of the object
*/
public PG_Object(String type, String value)
public PG_Object(String type, String value) throws SQLException
{
this.type = type;
this.value = value;
}
/**
* This returns true if the object is a 'box'
*/
public boolean isBox()
{
return type.equals("box");
}
/**
* This returns a PGbox object, or null if it's not
* @return PGbox
*/
public PGbox getBox() throws SQLException
{
if(isBox())
return new PGbox(value);
return null;
}
/**
* This returns true if the object is a 'point'
*/
public boolean isCircle()
{
return type.equals("circle");
}
/**
* This returns a PGcircle object, or null if it's not
* @return PGcircle
*/
public PGcircle getCircle() throws SQLException
{
if(isCircle())
return new PGcircle(value);
return null;
}
/**
* This returns true if the object is a 'lseg' (line segment)
*/
public boolean isLseg()
{
return type.equals("lseg");
}
/**
* This returns a PGlsegobject, or null if it's not
* @return PGlseg
*/
public PGlseg getLseg() throws SQLException
{
if(isLseg())
return new PGlseg(value);
return null;
}
/**
* This returns true if the object is a 'path'
*/
public boolean isPath()
{
return type.equals("path");
}
/**
* This returns a PGpath object, or null if it's not
* @return PGpath
*/
public PGpath getPath() throws SQLException
{
if(isPath())
return new PGpath(value);
return null;
}
/**
* This returns true if the object is a 'point'
*/
public boolean isPoint()
{
return type.equals("point");
}
/**
* This returns a PGpoint object, or null if it's not
* @return PGpoint object
*/
public PGpoint getPoint() throws SQLException
{
if(isPoint())
return new PGpoint(value);
return null;
}
/**
* This returns true if the object is a 'polygon'
*/
public boolean isPolygon()
{
return type.equals("polygon");
}
/**
* This returns a PGpolygon object, or null if it's not
* @return PGpolygon
*/
public PGpolygon getPolygon() throws SQLException
{
if(isPolygon())
return new PGpolygon(value);
return null;
}
}
......@@ -9,9 +9,6 @@ import java.sql.*;
import postgresql.*;
/**
* @version 1.0 15-APR-1997
* @author <A HREF="mailto:adrian@hottub.org">Adrian Hall</A>
*
* A ResultSet provides access to a table of data generated by executing a
* Statement. The table rows are retrieved in sequence. Within a row its
* column values can be accessed in any order.
......@@ -843,3 +840,4 @@ public class ResultSet implements java.sql.ResultSet
return fields.length;
}
}
......@@ -427,3 +427,4 @@ public class ResultSetMetaData implements java.sql.ResultSetMetaData
return fields[columnIndex - 1];
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment