]> granicus.if.org Git - postgresql/commitdiff
Fix for java to allow password, european dates,from Peter T Mount
authorBruce Momjian <bruce@momjian.us>
Thu, 30 Oct 1997 18:24:44 +0000 (18:24 +0000)
committerBruce Momjian <bruce@momjian.us>
Thu, 30 Oct 1997 18:24:44 +0000 (18:24 +0000)
src/interfaces/jdbc/JDBC_Test.java
src/interfaces/jdbc/README
src/interfaces/jdbc/postgresql/Connection.java
src/interfaces/jdbc/postgresql/ResultSet.java

index 30cda33304a1570406b6ae798e82b2cdfdc6b551..2453e4ca949f577566423d502b68e58b09f0b955 100644 (file)
@@ -4,58 +4,104 @@ import java.sql.*;
 
 class JDBC_Test
 {
-        public JDBC_Test() 
+  public JDBC_Test() 
+  {
+  }
+  
+  public static void main(String argv[])
+  {
+    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);
+    
+    // Load the driver
+    try {
+      Class.forName("postgresql.Driver");
+    } catch (ClassNotFoundException e) {
+      System.err.println("Exception: " + e.toString());
+    }
+    
+    // Lets do a few things -- it doesn't do everything, but
+    // it tests out basic functionality
+    try {
+      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
+      System.out.println("Ok... now set European date style");
+      s.executeUpdate("set datestyle='european'");
+      
+      System.out.println("and see what style we are now using (handled by warnings)");
+      s.executeUpdate("show datestyle");
+      SQLWarning sw = db.getWarnings();
+      while(sw!=null) {
+       System.out.println("--> "+sw.getMessage());
+       sw=sw.getNextWarning();
+      }
+      db.clearWarnings();
+      
+      System.out.println("Ok...now we will create a table");
+      s.executeUpdate("create table test (a int2, b int2,c timestamp,d date)");
+      
+      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");
+      
+      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++;
        }
-
-       public static void main(String argv[])
+      
+      // 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())
        {
-               String url = new String(argv[0]);
-               Connection db;
-               Statement s;
-               ResultSet rs;
-
-               // Load the driver
-               try
-               {
-                       Class.forName("postgresql.Driver");
-               } catch (ClassNotFoundException e) {
-                       System.err.println("Exception: " + e.toString());
-               }
-
-               // Lets do a few things -- it doesn't do everything, but
-               // it tests out basic functionality
-               try
-               {
-               System.out.println("Connecting to Database URL = " + url);
-               db = DriverManager.getConnection(url, "adrian", "");
-               System.out.println("Connected...Now creating a statement");
-               s = db.createStatement();
-               System.out.println("Ok...now we will create a table");
-               s.executeUpdate("create table test (a int2, b int2)");
-               System.out.println("Now we will insert some columns");
-               s.executeUpdate("insert into test values (1, 1)");
-               s.executeUpdate("insert into test values (2, 1)");
-               s.executeUpdate("insert into test values (3, 1)");
-               System.out.println("Inserted some data");
-               System.out.println("Now lets try a select");
-               rs = s.executeQuery("select a, b from test");
-               System.out.println("Back from the select...the following are results");
-               int i = 0;
-               while (rs.next())
-               {
-                       int a = rs.getInt("a");
-                       int b = rs.getInt("b");
-                       System.out.println("row " + i + "       " + a + "       " + b);
-                       i++;
-               }
-               System.out.println("Ok...dropping the table");
-               s.executeUpdate("drop table test");
-               System.out.println("Now closing the connection");
-               s.close();
-               db.close();
-               } catch (SQLException e) {
-               System.out.println("Exception: " + e.toString());
-               }
+         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++;
        }
+      
+      System.out.println("Ok...dropping the table");
+      s.executeUpdate("drop table test");
+      
+      System.out.println("Now closing the connection");
+      s.close();
+      db.close();
+    } catch (SQLException e) {
+      System.out.println("Exception: " + e.toString());
+    }
+  }
 }
index 465331ab231cdfec524d48a9cf23c4e383e677d7..bbc105ea8cc63e51df8cc05bff1fa72b391038ee 100644 (file)
@@ -112,6 +112,17 @@ them to the URL. eg:
        jdbc:postgresql:database?user=me
        jdbc:postgresql:database?user=me&password=mypass
 
+By default, the driver doesn't use password authentication. You can enable
+this by adding the argument auth. ie:
+
+       jdbc:postgresql:database?user=me&password=mypass&auth=y
+
+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 '='
+
 ---------------------------------------------------------------------------
 
 That's the basics related to this driver. You'll need to read the JDBC Docs
@@ -120,6 +131,34 @@ on how to use it.
 POSTGRESQL SPECIFICS
 --------------------
 
+Date datatype:
+
+The driver now supports US and European date styles (although it is currently
+limited to postgres format).
+
+Basically the US like to format their dates as mm-dd-yyyy, while in Europe,
+we like to use dd-mm-yyyy. Postgres supports this by the DateStyle variable.
+From psql, you can issue "set datestyle='european';" to set european style,
+and "set datestyle='us';" to set the US format. You can see what the current
+value for this with "show datestyle;".
+
+The driver now issues the "show datestyle;" query when it first connects, so
+any call to ResultSet.getDate() how returns the correct date.
+
+One caveat though: if you change the datestyle from within JDBC, you must also
+issue the "show datestyle" query. Without this, the driver will not know of
+the change.
+
+ie:
+       Statement s = db.createStatement();
+       ...
+       s.executeUpdate("set datestyle='european'");
+       s.executeUpdate("show datestyle");
+       ..
+       s.close();
+       
+                       ------------------
+
 JDBC supports database specific data types using the getObject() call. The
 following types have their own Java equivalents supplied by the driver:
 
@@ -140,9 +179,10 @@ syntax for writing these to the database.
 
 ---------------------------------------------------------------------------
 
-Peter T Mount, August 30 1997
+Peter T Mount, October 28 1997
 home email: pmount@maidast.demon.co.uk http://www.demon.co.uk/finder
 work email: peter@maidstone.gov.uk     http://www.maidstone.gov.uk
 
 Adrian Hall
      email: adrian@hottub.org
+
index bb41dff01bb0b2b7ef102855b553fb063f0c1173..e79d1fe953bf644a9e8c320631c61e147c5c534f 100644 (file)
@@ -36,11 +36,15 @@ 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 int STARTUP_CODE = 7;
+  private int STARTUP_CODE = STARTUP_USER;
+  private static final int STARTUP_USER = 7;   // User auth
+  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;
@@ -49,6 +53,12 @@ public class Connection implements java.sql.Connection
   private String this_url;
   private String cursor = null;        // The positioned update cursor name
   
+  // This is false for US, true for European date formats
+  protected boolean europeanDates = false;
+  
+  // Now handle notices as warnings, so things like "show" now work
+  protected SQLWarning firstWarning = null;
+  
   /**
    * Connect to a PostgreSQL database back end.
    *
@@ -63,7 +73,7 @@ public class Connection implements java.sql.Connection
    */
   public Connection(String host, int port, Properties info, String database, String url, Driver d) throws SQLException
   {
-    int len = 288;                     // Length of a startup packet
+    int len = STARTUP_LEN;     // Length of a startup packet
     
     this_driver = d;
     this_url = new String(url);
@@ -74,6 +84,13 @@ public class Connection implements java.sql.Connection
     PG_HOST = new String(host);
     PG_STATUS = CONNECTION_BAD;
     
+    if(info.getProperty("auth") != null) {
+      PG_AUTH=true;
+      STARTUP_CODE=STARTUP_PASS;
+    } else {
+      STARTUP_CODE=STARTUP_USER;
+    }
+    
     try
       {
        pg_stream = new PG_Stream(host, port);
@@ -88,10 +105,34 @@ public class Connection implements java.sql.Connection
          pg_stream.SendInteger(STARTUP_CODE, 4);               len -= 4;
          pg_stream.Send(database.getBytes(), 64);      len -= 64;
          pg_stream.Send(PG_USER.getBytes(), len);
+         
+         // Send the password packet if required
+         if(PG_AUTH) {
+           len=STARTUP_LEN;
+           pg_stream.SendInteger(len, 4);                      len -= 4;
+           pg_stream.SendInteger(STARTUP_PASS, 4);             len -= 4;
+           pg_stream.Send(PG_USER.getBytes(), PG_USER.length());
+           len-=PG_USER.length();
+           pg_stream.SendInteger(0,1);                 len -= 1;
+           pg_stream.Send(PG_PASSWORD.getBytes(), len);
+         }
+         
        } catch (IOException e) {
          throw new SQLException("Connection failed: " + e.toString());
        }
-       ExecSQL(" ");                           // Test connection
+       
+       // Find out the date style by issuing the SQL: show datestyle
+       // This actually issues a warning, and our own warning handling
+       // code handles this itself.
+       //
+       // Also, this query replaced the NULL query issued to test the
+       // connection.
+       //
+       clearWarnings();
+       ExecSQL("show datestyle");
+       
+       // Mark the connection as ok, and cleanup
+       clearWarnings();
        PG_STATUS = CONNECTION_OK;
   }
   
@@ -391,7 +432,7 @@ public class Connection implements java.sql.Connection
    */
   public SQLWarning getWarnings() throws SQLException
   {
-    return null;       // We handle warnings as errors
+    return firstWarning;
   }
   
   /**
@@ -402,13 +443,36 @@ public class Connection implements java.sql.Connection
    */
   public void clearWarnings() throws SQLException
   {
-    // Not handles since we handle wanrings as errors
+    firstWarning = null;
   }
   
   // **********************************************************
   //           END OF PUBLIC INTERFACE
   // **********************************************************
   
+  /**
+   * This adds a warning to the warning chain
+   */
+  public void addWarning(String msg)
+  {
+    // Add the warning to the chain
+    if(firstWarning!=null)
+      firstWarning.setNextWarning(new SQLWarning(msg));
+    else
+      firstWarning = new SQLWarning(msg);
+    
+    // Now check for some specific messages
+    
+    // This is generated by the SQL "show datestyle"
+    if(msg.startsWith("NOTICE:DateStyle")) {
+      if(msg.indexOf("with US")==-1)
+       europeanDates=true;
+      else
+       europeanDates=false;
+      System.err.println("europeanDates="+europeanDates);
+    }
+  }
+  
   /**
    * Send a query to the backend.  Returns one of the ResultSet
    * objects.
@@ -497,7 +561,8 @@ public class Connection implements java.sql.Connection
            case 'N':   // Error Notification
              msg = pg_stream.ReceiveString(4096);
              PrintStream log = DriverManager.getLogStream();
-             log.println(msg);
+             if(log!=null) log.println(msg);
+             addWarning(msg);
              break;
            case 'P':   // Portal Name
              String pname = pg_stream.ReceiveString(8192);
index d9222ee8ea27a9ef7a623e3d8e84e4e70831a6dc..b6edf18974a19e89a065b550eaeadf551555fb9c 100644 (file)
@@ -377,17 +377,22 @@ public class ResultSet implements java.sql.ResultSet
     
     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));
-           return new java.sql.Date(yr - 1900, mon -1, day);
-         } catch (NumberFormatException e) {
-           throw new SQLException("Bad Date Form: " + s);
+       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
   }
@@ -432,19 +437,24 @@ public class ResultSet implements java.sql.ResultSet
   public Timestamp getTimestamp(int columnIndex) throws SQLException
   {
     String s = getString(columnIndex);
-    DateFormat df = DateFormat.getDateInstance();
+    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:sszzz");
     
     if (s != null)
       {
-       try
-         {
-           java.sql.Date d = (java.sql.Date)df.parse(s);
-           return new Timestamp(d.getTime());
-         } catch (ParseException e) {
-           throw new SQLException("Bad Timestamp Format: " + s);
-         }
+       int TZ = new Float(s.substring(19)).intValue();
+       TZ = TZ * 60 * 60 * 1000;
+       TimeZone zone = TimeZone.getDefault();
+       zone.setRawOffset(TZ);
+       String nm = zone.getID();
+       s = s.substring(0,18) + nm;
+       try {
+         java.util.Date d = df.parse(s);
+         return new Timestamp(d.getTime());
+       } catch (ParseException e) {
+         throw new SQLException("Bad Timestamp Format: at " + e.getErrorOffset() + " in " + s);
+       }
       }
-    return null;               // SQL NULL
+    return null;                // SQL NULL
   }
   
   /**