Connection.java
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:22k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. package postgresql;
  2. import java.io.*;
  3. import java.net.*;
  4. import java.sql.*;
  5. import java.util.*;
  6. import postgresql.Field;
  7. import postgresql.fastpath.*;
  8. import postgresql.largeobject.*;
  9. import postgresql.util.*;
  10. /**
  11.  * $Id: Connection.java,v 1.17 1999/05/18 23:17:15 peter Exp $
  12.  *
  13.  * This abstract class is used by postgresql.Driver to open either the JDBC1 or
  14.  * JDBC2 versions of the Connection class.
  15.  *
  16.  */
  17. public abstract class Connection
  18. {
  19.   // This is the network stream associated with this connection
  20.   public PG_Stream pg_stream;
  21.   
  22.   // This is set by postgresql.Statement.setMaxRows()
  23.   public int maxrows = 0; // maximum no. of rows; 0 = unlimited
  24.   
  25.   private String PG_HOST;
  26.   private int PG_PORT;
  27.   private String PG_USER;
  28.   private String PG_PASSWORD;
  29.   private String PG_DATABASE;
  30.   private boolean PG_STATUS;
  31.   
  32.   public boolean CONNECTION_OK = true;
  33.   public boolean CONNECTION_BAD = false;
  34.   
  35.   public boolean autoCommit = true;
  36.   public boolean readOnly = false;
  37.   
  38.   public Driver this_driver;
  39.   private String this_url;
  40.   private String cursor = null; // The positioned update cursor name
  41.   
  42.   // These are new for v6.3, they determine the current protocol versions
  43.   // supported by this version of the driver. They are defined in
  44.   // src/include/libpq/pqcomm.h
  45.   protected static final int PG_PROTOCOL_LATEST_MAJOR = 1;
  46.   protected static final int PG_PROTOCOL_LATEST_MINOR = 0;
  47.   private static final int SM_DATABASE = 64;
  48.   private static final int SM_USER = 32;
  49.   private static final int SM_OPTIONS = 64;
  50.   private static final int SM_UNUSED = 64;
  51.   private static final int SM_TTY = 64;
  52.   
  53.   private static final int AUTH_REQ_OK       = 0;
  54.   private static final int AUTH_REQ_KRB4     = 1;
  55.   private static final int AUTH_REQ_KRB5     = 2;
  56.   private static final int AUTH_REQ_PASSWORD = 3;
  57.   private static final int AUTH_REQ_CRYPT    = 4;
  58.   
  59.   // New for 6.3, salt value for crypt authorisation
  60.   private String salt;
  61.   
  62.   // This is used by Field to cache oid -> names.
  63.   // It's here, because it's shared across this connection only.
  64.   // Hence it cannot be static within the Field class, because it would then
  65.   // be across all connections, which could be to different backends.
  66.   public Hashtable fieldCache = new Hashtable();
  67.   
  68.   // Now handle notices as warnings, so things like "show" now work
  69.   public SQLWarning firstWarning = null;
  70.   
  71.     /**
  72.      * This is called by Class.forName() from within postgresql.Driver
  73.      */
  74.     public Connection()
  75.     {
  76.     }
  77.     
  78.     /**
  79.      * This method actually opens the connection. It is called by Driver.
  80.      *
  81.      * @param host the hostname of the database back end
  82.      * @param port the port number of the postmaster process
  83.      * @param info a Properties[] thing of the user and password
  84.      * @param database the database to connect to
  85.      * @param u the URL of the connection
  86.      * @param d the Driver instantation of the connection
  87.      * @return a valid connection profile
  88.      * @exception SQLException if a database access error occurs
  89.      */
  90.     protected void openConnection(String host, int port, Properties info, String database, String url, Driver d) throws SQLException
  91.     {
  92.     // Throw an exception if the user or password properties are missing
  93.     // This occasionally occurs when the client uses the properties version
  94.     // of getConnection(), and is a common question on the email lists
  95.     if(info.getProperty("user")==null)
  96.       throw new PSQLException("postgresql.con.user");
  97.     if(info.getProperty("password")==null)
  98.       throw new PSQLException("postgresql.con.pass");
  99.     
  100.     this_driver = d;
  101.     this_url = new String(url);
  102.     PG_DATABASE = new String(database);
  103.     PG_PASSWORD = new String(info.getProperty("password"));
  104.     PG_USER = new String(info.getProperty("user"));
  105.     PG_PORT = port;
  106.     PG_HOST = new String(host);
  107.     PG_STATUS = CONNECTION_BAD;
  108.     
  109.     // Now make the initial connection
  110.     try
  111.       {
  112. pg_stream = new PG_Stream(host, port);
  113.       } catch (ConnectException cex) {
  114. // Added by Peter Mount <peter@retep.org.uk>
  115. // ConnectException is thrown when the connection cannot be made.
  116. // we trap this an return a more meaningful message for the end user
  117. throw new PSQLException ("postgresql.con.refused");
  118.       } catch (IOException e) {
  119. throw new PSQLException ("postgresql.con.failed",e);
  120.       }
  121.       
  122.       // Now we need to construct and send a startup packet
  123.       try
  124. {
  125.   // Ver 6.3 code
  126.   pg_stream.SendInteger(4+4+SM_DATABASE+SM_USER+SM_OPTIONS+SM_UNUSED+SM_TTY,4);
  127.   pg_stream.SendInteger(PG_PROTOCOL_LATEST_MAJOR,2);
  128.   pg_stream.SendInteger(PG_PROTOCOL_LATEST_MINOR,2);
  129.   pg_stream.Send(database.getBytes(),SM_DATABASE);
  130.   
  131.   // This last send includes the unused fields
  132.   pg_stream.Send(PG_USER.getBytes(),SM_USER+SM_OPTIONS+SM_UNUSED+SM_TTY);
  133.   
  134.   // now flush the startup packets to the backend
  135.   pg_stream.flush();
  136.   
  137.   // Now get the response from the backend, either an error message
  138.   // or an authentication request
  139.   int areq = -1; // must have a value here
  140.   do {
  141.     int beresp = pg_stream.ReceiveChar();
  142.     switch(beresp)
  143.       {
  144.       case 'E':
  145. // An error occured, so pass the error message to the
  146. // user.
  147. //
  148. // The most common one to be thrown here is:
  149. // "User authentication failed"
  150. //
  151. throw new SQLException(pg_stream.ReceiveString(4096));
  152.       case 'R':
  153. // Get the type of request
  154. areq = pg_stream.ReceiveIntegerR(4);
  155. // Get the password salt if there is one
  156. if(areq == AUTH_REQ_CRYPT) {
  157.   byte[] rst = new byte[2];
  158.   rst[0] = (byte)pg_stream.ReceiveChar();
  159.   rst[1] = (byte)pg_stream.ReceiveChar();
  160.   salt = new String(rst,0,2);
  161.   DriverManager.println("Salt="+salt);
  162. }
  163. // now send the auth packet
  164. switch(areq)
  165.   {
  166.   case AUTH_REQ_OK:
  167.     break;
  168.     
  169.   case AUTH_REQ_KRB4:
  170.     DriverManager.println("postgresql: KRB4");
  171.     throw new PSQLException("postgresql.con.kerb4");
  172.     
  173.   case AUTH_REQ_KRB5:
  174.     DriverManager.println("postgresql: KRB5");
  175.     throw new PSQLException("postgresql.con.kerb5");
  176.     
  177.   case AUTH_REQ_PASSWORD:
  178.     DriverManager.println("postgresql: PASSWORD");
  179.     pg_stream.SendInteger(5+PG_PASSWORD.length(),4);
  180.     pg_stream.Send(PG_PASSWORD.getBytes());
  181.     pg_stream.SendInteger(0,1);
  182.     pg_stream.flush();
  183.     break;
  184.     
  185.   case AUTH_REQ_CRYPT:
  186.     DriverManager.println("postgresql: CRYPT");
  187.     String crypted = UnixCrypt.crypt(salt,PG_PASSWORD);
  188.     pg_stream.SendInteger(5+crypted.length(),4);
  189.     pg_stream.Send(crypted.getBytes());
  190.     pg_stream.SendInteger(0,1);
  191.     pg_stream.flush();
  192.     break;
  193.     
  194.   default:
  195.     throw new PSQLException("postgresql.con.auth",new Integer(areq));
  196.   }
  197. break;
  198.       default:
  199. throw new PSQLException("postgresql.con.authfail");
  200.       }
  201.     } while(areq != AUTH_REQ_OK);
  202.   
  203. } catch (IOException e) {
  204.   throw new PSQLException("postgresql.con.failed",e);
  205. }
  206.       // Originally we issued a SHOW DATESTYLE statement to find the databases default
  207.       // datestyle. However, this caused some problems with timestamps, so in 6.5, we
  208.       // went the way of ODBC, and set the connection to ISO.
  209.       //
  210.       // This may cause some clients to break when they assume anything other than ISO,
  211.       // but then - they should be using the proper methods ;-)
  212.       //
  213.       //
  214.       firstWarning = null;
  215.       
  216.       ExecSQL("set datestyle to 'ISO'");
  217.       
  218.       // Initialise object handling
  219.       initObjectTypes();
  220.       
  221.       // Mark the connection as ok, and cleanup
  222.       firstWarning = null;
  223.       PG_STATUS = CONNECTION_OK;
  224.     }
  225.     
  226.     // These methods used to be in the main Connection implementation. As they
  227.     // are common to all implementations (JDBC1 or 2), they are placed here.
  228.     // This should make it easy to maintain the two specifications.
  229.     
  230.     /**
  231.      * This adds a warning to the warning chain.
  232.      * @param msg message to add
  233.      */
  234.     public void addWarning(String msg)
  235.     {
  236. DriverManager.println(msg);
  237. // Add the warning to the chain
  238. if(firstWarning!=null)
  239.     firstWarning.setNextWarning(new SQLWarning(msg));
  240. else
  241.     firstWarning = new SQLWarning(msg);
  242. // Now check for some specific messages
  243. // This is obsolete in 6.5, but I've left it in here so if we need to use this
  244. // technique again, we'll know where to place it.
  245. //
  246. // This is generated by the SQL "show datestyle"
  247. //if(msg.startsWith("NOTICE:") && msg.indexOf("DateStyle")>0) {
  248. //// 13 is the length off "DateStyle is "
  249. //msg = msg.substring(msg.indexOf("DateStyle is ")+13);
  250. //  
  251. //for(int i=0;i<dateStyles.length;i+=2)
  252. //if(msg.startsWith(dateStyles[i]))
  253. //currentDateStyle=i+1; // this is the index of the format
  254. //}
  255.     }
  256.     
  257.     /**
  258.      * Send a query to the backend.  Returns one of the ResultSet
  259.      * objects.
  260.      *
  261.      * <B>Note:</B> there does not seem to be any method currently
  262.      * in existance to return the update count.
  263.      *
  264.      * @param sql the SQL statement to be executed
  265.      * @return a ResultSet holding the results
  266.      * @exception SQLException if a database error occurs
  267.      */
  268.     public java.sql.ResultSet ExecSQL(String sql) throws SQLException
  269.     {
  270. // added Oct 7 1998 to give us thread safety.
  271. synchronized(pg_stream) {
  272.     
  273.     Field[] fields = null;
  274.     Vector tuples = new Vector();
  275.     byte[] buf = new byte[sql.length()];
  276.     int fqp = 0;
  277.     boolean hfr = false;
  278.     String recv_status = null, msg;
  279. int update_count = 1;
  280.     SQLException final_error = null;
  281.     
  282.     if (sql.length() > 8192)
  283. throw new PSQLException("postgresql.con.toolong",sql);
  284.     try
  285. {
  286.     pg_stream.SendChar('Q');
  287.     buf = sql.getBytes();
  288.     pg_stream.Send(buf);
  289.     pg_stream.SendChar(0);
  290.     pg_stream.flush();
  291. } catch (IOException e) {
  292.     throw new PSQLException("postgresql.con.ioerror",e);
  293. }
  294.     
  295.     while (!hfr || fqp > 0)
  296. {
  297.     Object tup=null; // holds rows as they are recieved
  298.     
  299.     int c = pg_stream.ReceiveChar();
  300.     
  301.     switch (c)
  302. {
  303. case 'A': // Asynchronous Notify
  304.     int pid = pg_stream.ReceiveInteger(4);
  305.     msg = pg_stream.ReceiveString(8192);
  306.     break;
  307. case 'B': // Binary Data Transfer
  308.     if (fields == null)
  309. throw new PSQLException("postgresql.con.tuple");
  310.     tup = pg_stream.ReceiveTuple(fields.length, true);
  311.     // This implements Statement.setMaxRows()
  312.     if(maxrows==0 || tuples.size()<maxrows)
  313. tuples.addElement(tup);
  314.     break;
  315. case 'C': // Command Status
  316.     recv_status = pg_stream.ReceiveString(8192);
  317. // Now handle the update count correctly.
  318. if(recv_status.startsWith("INSERT") || recv_status.startsWith("UPDATE")) {
  319. try {
  320. update_count = Integer.parseInt(recv_status.substring(1+recv_status.lastIndexOf(' ')));
  321. } catch(NumberFormatException nfe) {
  322. throw new PSQLException("postgresql.con.fathom",recv_status);
  323. }
  324. }
  325.     if (fields != null)
  326. hfr = true;
  327.     else
  328. {
  329.     try
  330. {
  331.     pg_stream.SendChar('Q');
  332.     pg_stream.SendChar(' ');
  333.     pg_stream.SendChar(0);
  334.     pg_stream.flush();
  335. } catch (IOException e) {
  336.     throw new PSQLException("postgresql.con.ioerror",e);
  337. }
  338.     fqp++;
  339. }
  340.     break;
  341. case 'D': // Text Data Transfer
  342.     if (fields == null)
  343. throw new PSQLException("postgresql.con.tuple");
  344.     tup = pg_stream.ReceiveTuple(fields.length, false);
  345.     // This implements Statement.setMaxRows()
  346.     if(maxrows==0 || tuples.size()<maxrows)
  347. tuples.addElement(tup);
  348.     break;
  349. case 'E': // Error Message
  350.     msg = pg_stream.ReceiveString(4096);
  351.     final_error = new SQLException(msg);
  352.     hfr = true;
  353.     break;
  354. case 'I': // Empty Query
  355.     int t = pg_stream.ReceiveChar();
  356.     
  357.     if (t != 0)
  358. throw new PSQLException("postgresql.con.garbled");
  359.     if (fqp > 0)
  360. fqp--;
  361.     if (fqp == 0)
  362. hfr = true;
  363.     break;
  364. case 'N': // Error Notification
  365.     addWarning(pg_stream.ReceiveString(4096));
  366.     break;
  367. case 'P': // Portal Name
  368.     String pname = pg_stream.ReceiveString(8192);
  369.     break;
  370. case 'T': // MetaData Field Description
  371.     if (fields != null)
  372. throw new PSQLException("postgresql.con.multres");
  373.     fields = ReceiveFields();
  374.     break;
  375. default:
  376.     throw new PSQLException("postgresql.con.type",new Character((char)c));
  377. }
  378. }
  379.     if (final_error != null)
  380. throw final_error;
  381.     return getResultSet(this, fields, tuples, recv_status, update_count);
  382. }
  383.     }
  384.     /**
  385.      * Receive the field descriptions from the back end
  386.      *
  387.      * @return an array of the Field object describing the fields
  388.      * @exception SQLException if a database error occurs
  389.      */
  390.     private Field[] ReceiveFields() throws SQLException
  391.     {
  392. int nf = pg_stream.ReceiveIntegerR(2), i;
  393. Field[] fields = new Field[nf];
  394. for (i = 0 ; i < nf ; ++i)
  395.     {
  396. String typname = pg_stream.ReceiveString(8192);
  397. int typid = pg_stream.ReceiveIntegerR(4);
  398. int typlen = pg_stream.ReceiveIntegerR(2);
  399. fields[i] = new Field(this, typname, typid, typlen);
  400.     }
  401. return fields;
  402.     }
  403.     
  404.     /**
  405.      * In SQL, a result table can be retrieved through a cursor that
  406.      * is named.  The current row of a result can be updated or deleted
  407.      * using a positioned update/delete statement that references the
  408.      * cursor name.
  409.      *
  410.      * We support one cursor per connection.
  411.      *
  412.      * setCursorName sets the cursor name.
  413.      *
  414.      * @param cursor the cursor name
  415.      * @exception SQLException if a database access error occurs
  416.      */
  417.     public void setCursorName(String cursor) throws SQLException
  418.     {
  419. this.cursor = cursor;
  420.     }
  421.     
  422.     /**
  423.      * getCursorName gets the cursor name.
  424.      *
  425.      * @return the current cursor name
  426.      * @exception SQLException if a database access error occurs
  427.      */
  428.     public String getCursorName() throws SQLException
  429.     {
  430. return cursor;
  431.     }
  432.     
  433.     /**
  434.      * We are required to bring back certain information by
  435.      * the DatabaseMetaData class.  These functions do that.
  436.      *
  437.      * Method getURL() brings back the URL (good job we saved it)
  438.      *
  439.      * @return the url
  440.      * @exception SQLException just in case...
  441.      */
  442.     public String getURL() throws SQLException
  443.     {
  444. return this_url;
  445.     }
  446.     
  447.     /**
  448.      * Method getUserName() brings back the User Name (again, we
  449.      * saved it)
  450.      *
  451.      * @return the user name
  452.      * @exception SQLException just in case...
  453.      */
  454.     public String getUserName() throws SQLException
  455.     {
  456. return PG_USER;
  457.     }
  458.     
  459.     /**
  460.      * This returns the Fastpath API for the current connection.
  461.      *
  462.      * <p><b>NOTE:</b> This is not part of JDBC, but allows access to
  463.      * functions on the postgresql backend itself.
  464.      *
  465.      * <p>It is primarily used by the LargeObject API
  466.      *
  467.      * <p>The best way to use this is as follows:
  468.      *
  469.      * <p><pre>
  470.      * import postgresql.fastpath.*;
  471.      * ...
  472.      * Fastpath fp = ((postgresql.Connection)myconn).getFastpathAPI();
  473.      * </pre>
  474.      *
  475.      * <p>where myconn is an open Connection to postgresql.
  476.      *
  477.      * @return Fastpath object allowing access to functions on the postgresql
  478.      * backend.
  479.      * @exception SQLException by Fastpath when initialising for first time
  480.      */
  481.     public Fastpath getFastpathAPI() throws SQLException
  482.     {
  483. if(fastpath==null)
  484.     fastpath = new Fastpath(this,pg_stream);
  485. return fastpath;
  486.     }
  487.     
  488.     // This holds a reference to the Fastpath API if already open
  489.     private Fastpath fastpath = null;
  490.     
  491.     /**
  492.      * This returns the LargeObject API for the current connection.
  493.      *
  494.      * <p><b>NOTE:</b> This is not part of JDBC, but allows access to
  495.      * functions on the postgresql backend itself.
  496.      *
  497.      * <p>The best way to use this is as follows:
  498.      *
  499.      * <p><pre>
  500.      * import postgresql.largeobject.*;
  501.      * ...
  502.      * LargeObjectManager lo = ((postgresql.Connection)myconn).getLargeObjectAPI();
  503.      * </pre>
  504.      *
  505.      * <p>where myconn is an open Connection to postgresql.
  506.      *
  507.      * @return LargeObject object that implements the API
  508.      * @exception SQLException by LargeObject when initialising for first time
  509.      */
  510.     public LargeObjectManager getLargeObjectAPI() throws SQLException
  511.     {
  512. if(largeobject==null)
  513.     largeobject = new LargeObjectManager(this);
  514. return largeobject;
  515.     }
  516.     
  517.     // This holds a reference to the LargeObject API if already open
  518.     private LargeObjectManager largeobject = null;
  519.     
  520.     /**
  521.      * This method is used internally to return an object based around
  522.      * postgresql's more unique data types.
  523.      *
  524.      * <p>It uses an internal Hashtable to get the handling class. If the
  525.      * type is not supported, then an instance of postgresql.util.PGobject
  526.      * is returned.
  527.      *
  528.      * You can use the getValue() or setValue() methods to handle the returned
  529.      * object. Custom objects can have their own methods.
  530.      *
  531.      * In 6.4, this is extended to use the postgresql.util.Serialize class to
  532.      * allow the Serialization of Java Objects into the database without using
  533.      * Blobs. Refer to that class for details on how this new feature works.
  534.      *
  535.      * @return PGobject for this type, and set to value
  536.      * @exception SQLException if value is not correct for this type
  537.      * @see postgresql.util.Serialize
  538.      */
  539.     public Object getObject(String type,String value) throws SQLException
  540.     {
  541. try {
  542.     Object o = objectTypes.get(type);
  543.     
  544.     // If o is null, then the type is unknown, so check to see if type
  545.     // is an actual table name. If it does, see if a Class is known that
  546.     // can handle it
  547.     if(o == null) {
  548. Serialize ser = new Serialize(this,type);
  549. objectTypes.put(type,ser);
  550. return ser.fetch(Integer.parseInt(value));
  551.     }
  552.     
  553.     // If o is not null, and it is a String, then its a class name that
  554.     // extends PGobject.
  555.     //
  556.     // This is used to implement the postgresql unique types (like lseg,
  557.     // point, etc).
  558.     if(o instanceof String) {
  559. // 6.3 style extending PG_Object
  560. PGobject obj = null;
  561. obj = (PGobject)(Class.forName((String)o).newInstance());
  562. obj.setType(type);
  563. obj.setValue(value);
  564. return (Object)obj;
  565.     } else {
  566. // If it's an object, it should be an instance of our Serialize class
  567. // If so, then call it's fetch method.
  568. if(o instanceof Serialize)
  569.     return ((Serialize)o).fetch(Integer.parseInt(value));
  570.     }
  571. } catch(SQLException sx) {
  572.     // rethrow the exception. Done because we capture any others next
  573.     sx.fillInStackTrace();
  574.     throw sx;
  575. } catch(Exception ex) {
  576.     throw new PSQLException("postgresql.con.creobj",type,ex);
  577. }
  578. // should never be reached
  579. return null;
  580.     }
  581.     
  582.     /**
  583.      * This stores an object into the database.
  584.      * @param o Object to store
  585.      * @return OID of the new rectord
  586.      * @exception SQLException if value is not correct for this type
  587.      * @see postgresql.util.Serialize
  588.      */
  589.     public int putObject(Object o) throws SQLException
  590.     {
  591. try {
  592.     String type = o.getClass().getName();
  593.     Object x = objectTypes.get(type);
  594.     
  595.     // If x is null, then the type is unknown, so check to see if type
  596.     // is an actual table name. If it does, see if a Class is known that
  597.     // can handle it
  598.     if(x == null) {
  599. Serialize ser = new Serialize(this,type);
  600. objectTypes.put(type,ser);
  601. return ser.store(o);
  602.     }
  603.     
  604.     // If it's an object, it should be an instance of our Serialize class
  605.     // If so, then call it's fetch method.
  606.     if(x instanceof Serialize)
  607. return ((Serialize)x).store(o);
  608.     
  609.     // Thow an exception because the type is unknown
  610.     throw new PSQLException("postgresql.con.strobj");
  611.     
  612. } catch(SQLException sx) {
  613.     // rethrow the exception. Done because we capture any others next
  614.     sx.fillInStackTrace();
  615.     throw sx;
  616. } catch(Exception ex) {
  617.     throw new PSQLException("postgresql.con.strobjex",ex);
  618. }
  619.     }
  620.     
  621.     /**
  622.      * This allows client code to add a handler for one of postgresql's
  623.      * more unique data types.
  624.      *
  625.      * <p><b>NOTE:</b> This is not part of JDBC, but an extension.
  626.      *
  627.      * <p>The best way to use this is as follows:
  628.      *
  629.      * <p><pre>
  630.      * ...
  631.      * ((postgresql.Connection)myconn).addDataType("mytype","my.class.name");
  632.      * ...
  633.      * </pre>
  634.      *
  635.      * <p>where myconn is an open Connection to postgresql.
  636.      *
  637.      * <p>The handling class must extend postgresql.util.PGobject
  638.      *
  639.      * @see postgresql.util.PGobject
  640.      */
  641.     public void addDataType(String type,String name)
  642.     {
  643. objectTypes.put(type,name);
  644.     }
  645.     
  646.     // This holds the available types
  647.     private Hashtable objectTypes = new Hashtable();
  648.     
  649.     // This array contains the types that are supported as standard.
  650.     //
  651.     // The first entry is the types name on the database, the second
  652.     // the full class name of the handling class.
  653.     //
  654.     private static final String defaultObjectTypes[][] = {
  655. {"box", "postgresql.geometric.PGbox"},
  656. {"circle", "postgresql.geometric.PGcircle"},
  657. {"line", "postgresql.geometric.PGline"},
  658. {"lseg", "postgresql.geometric.PGlseg"},
  659. {"path", "postgresql.geometric.PGpath"},
  660. {"point", "postgresql.geometric.PGpoint"},
  661. {"polygon", "postgresql.geometric.PGpolygon"},
  662. {"money", "postgresql.util.PGmoney"}
  663.     };
  664.     
  665.     // This initialises the objectTypes hashtable
  666.     private void initObjectTypes()
  667.     {
  668. for(int i=0;i<defaultObjectTypes.length;i++)
  669.     objectTypes.put(defaultObjectTypes[i][0],defaultObjectTypes[i][1]);
  670.     }
  671.     
  672.     // These are required by other common classes
  673.     public abstract java.sql.Statement createStatement() throws SQLException;
  674.     
  675.     /**
  676.      * This returns a resultset. It must be overridden, so that the correct
  677.      * version (from jdbc1 or jdbc2) are returned.
  678.      */
  679.     protected abstract java.sql.ResultSet getResultSet(postgresql.Connection conn, Field[] fields, Vector tuples, String status, int updateCount) throws SQLException;
  680. }