OSDN Git Service

Update of Java driver from Peter Mount.
authorBruce Momjian <bruce@momjian.us>
Fri, 7 Nov 1997 21:07:48 +0000 (21:07 +0000)
committerBruce Momjian <bruce@momjian.us>
Fri, 7 Nov 1997 21:07:48 +0000 (21:07 +0000)
src/interfaces/jdbc/JDBC_Test.java
src/interfaces/jdbc/README
src/interfaces/jdbc/postgresql/Connection.java
src/interfaces/jdbc/postgresql/Driver.java
src/interfaces/jdbc/postgresql/PreparedStatement.java
src/interfaces/jdbc/postgresql/ResultSet.java
src/interfaces/jdbc/postgresql/ResultSetMetaData.java

index 2453e4c..c546469 100644 (file)
@@ -10,16 +10,21 @@ class JDBC_Test
   
   public static void main(String argv[])
   {
+    if(argv.length<3) {
+      System.err.println("java JDBC_Test jdbc-url user password [debug]");
+      System.exit(1);
+    }
+    
     String url = new String(argv[0]);
     String usr = new String(argv[1]);
     String pwd = new String(argv[2]);
     Connection db;
     Statement s;
-    ResultSet rs;
     
     // This line outputs debug information to stderr. To enable this, simply
-    // remove the //
-    DriverManager.setLogStream(System.err);
+    // add an extra parameter to the command line
+    if(argv.length>3)
+      DriverManager.setLogStream(System.err);
     
     // Load the driver
     try {
@@ -31,12 +36,15 @@ class JDBC_Test
     // Lets do a few things -- it doesn't do everything, but
     // it tests out basic functionality
     try {
+      //----------------------------------------
+      // Connect to database
       System.out.println("Connecting to Database URL = " + url);
       db = DriverManager.getConnection(url, usr, pwd);
       System.out.println("Connected...Now creating a statement");
       s = db.createStatement();
       
-      // test Date & Warnings
+      //----------------------------------------
+      // test DateStyle & Warnings
       System.out.println("Ok... now set European date style");
       s.executeUpdate("set datestyle='european'");
       
@@ -49,59 +57,115 @@ class JDBC_Test
       }
       db.clearWarnings();
       
+      //----------------------------------------
+      // Creating a table
       System.out.println("Ok...now we will create a table");
       s.executeUpdate("create table test (a int2, b int2,c timestamp,d date)");
       
+      //----------------------------------------
+      // Simple inserts
       System.out.println("Now we will insert some columns");
       s.executeUpdate("insert into test values (1, 1,'now','now')");
       s.executeUpdate("insert into test values (2, 1,'now','01-11-1997')"); // As we are in european, this should mean 1 November 1997
       s.executeUpdate("insert into test values (3, 1,'now','11-01-1997')"); // As we are in european, this should mean 11 January 1997
       System.out.println("Inserted some data");
       
+      //----------------------------------------
+      // Now a select (see seperate method at end)
       System.out.println("Now lets try a select");
-      rs = s.executeQuery("select a, b,c,d from test");
-      System.out.println("Back from the select...the following are results");
-      System.out.println("row  a       b       c                       d          'd as string'");
-      int i = 0;
-      while (rs.next())
-       {
-         int a = rs.getInt("a");       // Example of retriving by column name
-         int b = rs.getInt("b");
-         Timestamp c = rs.getTimestamp(3); // Example of by column number
-         java.sql.Date d = rs.getDate(4);  // Note, java.sql.Date here
-         System.out.println("row " + i + "     " + a + "       " + b + "       " + c + "       " + d + " '"+rs.getString(4)+"'");
-         i++;
-       }
+      select(s,"");
       
-      // This is a bug at the moment... when you use set datestyle
-      // it must be followed by show datestyle
-      System.out.println("Now switch to US date format");
-      s.executeUpdate("set datestyle='US'");
-      s.executeUpdate("show datestyle");
-      
-      System.out.println("Now lets try a select");
-      rs = s.executeQuery("select a, b,c,d from test");
-      System.out.println("Back from the select...the following are results");
-      //int i = 0;
-      System.out.println("row  a       b       c                       d          'd as string'");
-      while (rs.next())
-       {
-         int a = rs.getInt("a");       // Example of retriving by column name
-         int b = rs.getInt("b");
-         Timestamp c = rs.getTimestamp(3); // Example of by column number
-         java.sql.Date d = rs.getDate(4);  // Note, java.sql.Date here
-         System.out.println("row " + i + "     " + a + "       " + b + "       " + c + "       " + d + " '"+rs.getString(4)+"'");
-         i++;
-       }
+      //----------------------------------------
+      // Now run some tests
+      runTests(db,s);
       
+      //----------------------------------------
+      // Dropping a table
       System.out.println("Ok...dropping the table");
       s.executeUpdate("drop table test");
       
+      //----------------------------------------
+      // Closing the connection
       System.out.println("Now closing the connection");
       s.close();
       db.close();
+      
+      //----------------------------------------
     } catch (SQLException e) {
       System.out.println("Exception: " + e.toString());
     }
   }
+  
+  /**
+   * This performs some tests - not really part of an example, hence
+   * they are in a seperate method.
+   */
+  public static void runTests(Connection db, Statement s) throws SQLException
+  {
+    //----------------------------------------
+    // This is a bug at the moment... when you use set datestyle
+    // it must be followed by show datestyle
+    System.out.println("Now switch to US date format");
+    s.executeUpdate("set datestyle='US'");
+    s.executeUpdate("show datestyle");
+    
+    System.out.println("Now lets try a select");
+    select(s,"");
+    
+    //----------------------------------------
+    // Inserting dates using PreparedStatement
+    System.out.println("Ok, now a test using PreparedStatement");
+    Date dt = new Date(97,11,1);
+    PreparedStatement ps = db.prepareStatement("insert into test values (?,?,'now',?)");
+    
+    // first insert in US style
+    s.executeUpdate("set datestyle='US'");
+    s.executeUpdate("show datestyle");
+    ps.setInt(1,8);
+    ps.setInt(2,8);
+    ps.setDate(3,dt);
+    ps.executeUpdate();
+    
+    // second insert in European style
+    s.executeUpdate("set datestyle='european'");
+    s.executeUpdate("show datestyle");
+    ps.setInt(1,9);
+    ps.setInt(2,9);
+    ps.setDate(3,dt);
+    ps.executeUpdate();
+    
+    System.out.println("Now run the select again - first as European");
+    select(s,"where a>7");
+    
+    s.executeUpdate("set datestyle='US'");
+    s.executeUpdate("show datestyle");
+    System.out.println("Then as US");
+    select(s,"where a>7");
+  }
+  
+  /**
+   * This performs a select. It's seperate because the tests use it in
+   * multiple places.
+   * @param s Statement to run under
+   * @throws SQLException
+   */
+  public static void select(Statement s,String sql) throws SQLException
+  {
+    sql="select a, b,c,d from test "+sql;
+    System.out.println("\nQuery: "+sql);
+    ResultSet rs = s.executeQuery(sql);
+    System.out.println("row    a       b       c                       d          'd as string'");
+    System.out.println("-------------------------------------------------------------------------------");
+    int i = 0;
+    while(rs.next()) {
+      int a = rs.getInt("a");  // Example of retriving by column name
+      int b = rs.getInt("b");
+      Timestamp c = rs.getTimestamp(3); // Example of by column number
+      java.sql.Date d = rs.getDate(4);  // Note, java.sql.Date here
+      System.out.println("row " + i + "        " + a + "       " + b + "       " + c + "       " + d + " '"+rs.getString(4)+"'");
+      i++;
+    }
+    rs.close();
+  }
+  
 }
index bbc105e..cd43a5a 100644 (file)
@@ -121,7 +121,8 @@ or if passing the user & password directly via DriverManager.getConnection():
 
        jdbc:postgresql:database?auth=y
 
-PS: 'y' could be anything, aslong as there is something after the '='
+PS: Password authentication is enabled if the value of auth starts with 'y'.
+    It is case insensitive.
 
 ---------------------------------------------------------------------------
 
index e79d1fe..09344e1 100644 (file)
@@ -36,15 +36,20 @@ public class Connection implements java.sql.Connection
   private String PG_PASSWORD;
   private String PG_DATABASE;
   private boolean PG_STATUS;
-  private boolean PG_AUTH;     // true, then password auth used
   
   public boolean CONNECTION_OK = true;
   public boolean CONNECTION_BAD = false;
   
+  private static final int STARTUP_LEN  = 288; // Length of a startup packet
+  
+  // These are defined in src/include/libpq/pqcomm.h
   private int STARTUP_CODE = STARTUP_USER;
   private static final int STARTUP_USER = 7;   // User auth
+  private static final int STARTUP_KRB4 = 10;  // Kerberos 4 (unused)
+  private static final int STARTUP_KRB5 = 11;  // Kerberos 5 (unused)
+  private static final int STARTUP_HBA  = 12;  // Host Based
+  private static final int STARTUP_NONE = 13;  // Unauthenticated (unused)
   private static final int STARTUP_PASS = 14;  // Password auth
-  private static final int STARTUP_LEN  = 288; // Length of a startup packet
   
   private boolean autoCommit = true;
   private boolean readOnly = false;
@@ -84,10 +89,22 @@ public class Connection implements java.sql.Connection
     PG_HOST = new String(host);
     PG_STATUS = CONNECTION_BAD;
     
-    if(info.getProperty("auth") != null) {
-      PG_AUTH=true;
+    // This handles the auth property. Any value begining with p enables
+    // password authentication, while anything begining with i enables
+    // ident (RFC 1413) authentication. Any other values default to trust.
+    //
+    // Also, the postgresql.auth system property can be used to change the
+    // local default, if the auth property is not present.
+    //
+    String auth = info.getProperty("auth",System.getProperty("postgresql.auth","trust")).toLowerCase();
+    if(auth.startsWith("p")) {
+      // Password authentication
       STARTUP_CODE=STARTUP_PASS;
+    } else if(auth.startsWith("i")) {
+      // Ident (RFC 1413) authentication
+      STARTUP_CODE=STARTUP_HBA;
     } else {
+      // Anything else defaults to trust authentication
       STARTUP_CODE=STARTUP_USER;
     }
     
@@ -107,7 +124,7 @@ public class Connection implements java.sql.Connection
          pg_stream.Send(PG_USER.getBytes(), len);
          
          // Send the password packet if required
-         if(PG_AUTH) {
+         if(STARTUP_CODE == STARTUP_PASS) {
            len=STARTUP_LEN;
            pg_stream.SendInteger(len, 4);                      len -= 4;
            pg_stream.SendInteger(STARTUP_PASS, 4);             len -= 4;
index 674c96f..7b71145 100644 (file)
@@ -27,7 +27,7 @@ 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 final int MINORVERSION = 3;
   
   static 
   {
@@ -125,8 +125,22 @@ public class Driver implements java.sql.Driver
    */
   public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException
   {
-    return null;               // We don't need anything except
-    // the username, which is a default
+    Properties p = parseURL(url,info);
+    
+    // naughty, but its best for speed. If anyone adds a property here, then
+    // this _MUST_ be increased to accomodate them.
+    DriverPropertyInfo d,dpi[] = new DriverPropertyInfo[1];
+    int i=0;
+    
+    dpi[i++] = d = new DriverPropertyInfo("auth",p.getProperty("auth","default"));
+    d.description = "determines if password authentication is used";
+    d.choices = new String[4];
+    d.choices[0]="default";    // Get value from postgresql.auth property, defaults to trust
+    d.choices[1]="trust";      // No password authentication
+    d.choices[2]="password";   // Password authentication
+    d.choices[3]="ident";      // Ident (RFC 1413) protocol
+    
+    return dpi;
   }
   
   /**
@@ -168,6 +182,10 @@ public class Driver implements java.sql.Driver
   /**
    * Constructs a new DriverURL, splitting the specified URL into its
    * component parts
+   * @param url JDBC URL to parse
+   * @param defaults Default properties
+   * @return Properties with elements added from the url
+   * @throws SQLException
    */
   Properties parseURL(String url,Properties defaults) throws SQLException
   {
index 98fdb6f..479f86e 100644 (file)
@@ -7,8 +7,8 @@ import java.text.*;
 import java.util.*;
 
 /**
- * @version 1.0 15-APR-1997
- * @author <A HREF="mailto:adrian@hottub.org">Adrian Hall</A>
+ * @version 6.3 15-APR-1997
+ * @author <A HREF="mailto:adrian@hottub.org">Adrian Hall</A><A HREF="mailto:petermount@earthling.net">Peter Mount</A>
  *
  * A SQL Statement is pre-compiled and stored in a PreparedStatement object.
  * This object can then be used to efficiently execute this statement multiple
@@ -294,9 +294,9 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta
         */
        public void setDate(int parameterIndex, java.sql.Date x) throws SQLException
        {
-               DateFormat df = DateFormat.getDateInstance();
-
-               set(parameterIndex, "'" + df.format(x) + "'");
+         SimpleDateFormat df = new SimpleDateFormat(connection.europeanDates?"''dd-MM-yyyy''":"''MM-dd-yyyy''");
+         
+         set(parameterIndex, df.format(x));
        }
 
        /**
index b6edf18..017b0ad 100644 (file)
@@ -374,27 +374,12 @@ public class ResultSet implements java.sql.ResultSet
   public java.sql.Date getDate(int columnIndex) throws SQLException
   {
     String s = getString(columnIndex);
-    
-    if (s != null)
-      {
-       try {
-         if (s.length() != 10)
-           throw new NumberFormatException("Wrong Length!");
-         int mon = Integer.parseInt(s.substring(0,2));
-         int day = Integer.parseInt(s.substring(3,5));
-         int yr = Integer.parseInt(s.substring(6));
-         if(connection.europeanDates) {
-           // We europeans prefer dd mm yyyy
-           int t = mon;
-           mon = day;
-           day = t;
-         }
-         return new java.sql.Date(yr - 1900, mon -1, day);
-       } catch (NumberFormatException e) {
-         throw new SQLException("Bad Date Form: " + s);
-       }
-      }
-    return null;               // SQL NULL
+    SimpleDateFormat df = new SimpleDateFormat(connection.europeanDates?"dd-MM-yyyy":"MM-dd-yyyy");
+    try {
+      return new java.sql.Date(df.parse(s).getTime());
+    } catch (ParseException e) {
+      throw new SQLException("Bad Date Format: at " + e.getErrorOffset() + " in " + s);
+    }
   }
   
   /**
index f058e2e..7d2c1ce 100644 (file)
@@ -190,9 +190,11 @@ public class ResultSetMetaData implements java.sql.ResultSetMetaData
     for (i = 0 ; i < rows.size(); ++i)
       {
        byte[][] x = (byte[][])(rows.elementAt(i));
-       int xl = x[column - 1].length;
-       if (xl > max)
-         max = xl;
+       if(x[column-1]!=null) {
+         int xl = x[column - 1].length;
+         if (xl > max)
+           max = xl;
+       }
       }
     return max;
   }