Driver.java
上传用户:psq1974
上传日期:2007-01-06
资源大小:1195k
文件大小:10k
源码类别:

mpeg/mp3

开发平台:

C/C++

  1. package postgresql;
  2. import java.sql.*;
  3. import java.util.*;
  4. /**
  5.  * The Java SQL framework allows for multiple database drivers.  Each
  6.  * driver should supply a class that implements the Driver interface
  7.  *
  8.  * <p>The DriverManager will try to load as many drivers as it can find and
  9.  * then for any given connection request, it will ask each driver in turn
  10.  * to try to connect to the target URL.
  11.  *
  12.  * <p>It is strongly recommended that each Driver class should be small and
  13.  * standalone so that the Driver class can be loaded and queried without
  14.  * bringing in vast quantities of supporting code.
  15.  *
  16.  * <p>When a Driver class is loaded, it should create an instance of itself
  17.  * and register it with the DriverManager.  This means that a user can load
  18.  * and register a driver by doing Class.forName("foo.bah.Driver")
  19.  *
  20.  * @see postgresql.Connection
  21.  * @see java.sql.Driver
  22.  */
  23. public class Driver implements java.sql.Driver 
  24. {
  25.   // These should be in sync with the backend that the driver was
  26.   // distributed with
  27.   static final int MAJORVERSION = 6;
  28.   static final int MINORVERSION = 4;
  29.   
  30.   static 
  31.   {
  32.     try {
  33.       // moved the registerDriver from the constructor to here
  34.       // because some clients call the driver themselves (I know, as
  35.       // my early jdbc work did - and that was based on other examples).
  36.       // Placing it here, means that the driver is registered once only.
  37.       java.sql.DriverManager.registerDriver(new Driver());
  38.     } catch (SQLException e) {
  39.       e.printStackTrace();
  40.     }
  41.   }
  42.   
  43.   /**
  44.    * Construct a new driver and register it with DriverManager
  45.    *
  46.    * @exception SQLException for who knows what!
  47.    */
  48.   public Driver() throws SQLException
  49.   {
  50.   }
  51.   
  52.   /**
  53.    * Try to make a database connection to the given URL.  The driver
  54.    * should return "null" if it realizes it is the wrong kind of
  55.    * driver to connect to the given URL.  This will be common, as
  56.    * when the JDBC driverManager is asked to connect to a given URL,
  57.    * it passes the URL to each loaded driver in turn.
  58.    *
  59.    * <p>The driver should raise an SQLException if it is the right driver
  60.    * to connect to the given URL, but has trouble connecting to the
  61.    * database.
  62.    *
  63.    * <p>The java.util.Properties argument can be used to pass arbitrary
  64.    * string tag/value pairs as connection arguments.  Normally, at least
  65.    * "user" and "password" properties should be included in the 
  66.    * properties.
  67.    *
  68.    * Our protocol takes the forms:
  69.    * <PRE>
  70.    * jdbc:postgresql://host:port/database?param1=val1&...
  71.    * </PRE>
  72.    *
  73.    * @param url the URL of the database to connect to
  74.    * @param info a list of arbitrary tag/value pairs as connection
  75.    * arguments
  76.    * @return a connection to the URL or null if it isnt us
  77.    * @exception SQLException if a database access error occurs
  78.    * @see java.sql.Driver#connect
  79.    */
  80.   public java.sql.Connection connect(String url, Properties info) throws SQLException
  81.   {
  82.     if((props = parseURL(url,info))==null)
  83.       return null;
  84.     
  85.     return new Connection (host(), port(), props, database(), url, this);
  86.   }
  87.   
  88.   /**
  89.    * Returns true if the driver thinks it can open a connection to the
  90.    * given URL.  Typically, drivers will return true if they understand
  91.    * the subprotocol specified in the URL and false if they don't.  Our
  92.    * protocols start with jdbc:postgresql:
  93.    *
  94.    * @see java.sql.Driver#acceptsURL
  95.    * @param url the URL of the driver
  96.    * @return true if this driver accepts the given URL
  97.    * @exception SQLException if a database-access error occurs
  98.    *  (Dont know why it would *shrug*)
  99.    */
  100.   public boolean acceptsURL(String url) throws SQLException
  101.   {
  102.     if(parseURL(url,null)==null)
  103.       return false;
  104.     return true;
  105.   }
  106.   
  107.   /**
  108.    * The getPropertyInfo method is intended to allow a generic GUI
  109.    * tool to discover what properties it should prompt a human for
  110.    * in order to get enough information to connect to a database.
  111.    *
  112.    * <p>Note that depending on the values the human has supplied so
  113.    * far, additional values may become necessary, so it may be necessary
  114.    * to iterate through several calls to getPropertyInfo
  115.    *
  116.    * @param url the Url of the database to connect to
  117.    * @param info a proposed list of tag/value pairs that will be sent on
  118.    *  connect open.
  119.    * @return An array of DriverPropertyInfo objects describing
  120.    *  possible properties.  This array may be an empty array if
  121.    * no properties are required
  122.    * @exception SQLException if a database-access error occurs
  123.    * @see java.sql.Driver#getPropertyInfo
  124.    */
  125.   public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException
  126.   {
  127.     Properties p = parseURL(url,info);
  128.     
  129.     // naughty, but its best for speed. If anyone adds a property here, then
  130.     // this _MUST_ be increased to accomodate them.
  131.     DriverPropertyInfo d,dpi[] = new DriverPropertyInfo[0];
  132.     //int i=0;
  133.     
  134.     //dpi[i++] = d = new DriverPropertyInfo("auth",p.getProperty("auth","default"));
  135.     //d.description = "determines if password authentication is used";
  136.     //d.choices = new String[4];
  137.     //d.choices[0]="default"; // Get value from postgresql.auth property, defaults to trust
  138.     //d.choices[1]="trust"; // No password authentication
  139.     //d.choices[2]="password"; // Password authentication
  140.     //d.choices[3]="ident"; // Ident (RFC 1413) protocol
  141.     
  142.     return dpi;
  143.   }
  144.   
  145.   /**
  146.    * Gets the drivers major version number
  147.    *
  148.    * @return the drivers major version number
  149.    */
  150.   public int getMajorVersion()
  151.   {
  152.     return MAJORVERSION;
  153.   }
  154.   
  155.   /**
  156.    * Get the drivers minor version number
  157.    *
  158.    * @return the drivers minor version number
  159.    */
  160.   public int getMinorVersion()
  161.   {
  162.     return MINORVERSION;
  163.   }
  164.   
  165.   /**
  166.    * Report whether the driver is a genuine JDBC compliant driver.  A
  167.    * driver may only report "true" here if it passes the JDBC compliance
  168.    * tests, otherwise it is required to return false.  JDBC compliance
  169.    * requires full support for the JDBC API and full support for SQL 92
  170.    * Entry Level.  
  171.    *
  172.    * <p>For PostgreSQL, this is not yet possible, as we are not SQL92
  173.    * compliant (yet).
  174.    */
  175.   public boolean jdbcCompliant()
  176.   {
  177.     return false;
  178.   }
  179.   
  180.   private Properties props;
  181.   
  182.   static private String[] protocols = { "jdbc","postgresql" };
  183.   
  184.   /**
  185.    * Constructs a new DriverURL, splitting the specified URL into its
  186.    * component parts
  187.    * @param url JDBC URL to parse
  188.    * @param defaults Default properties
  189.    * @return Properties with elements added from the url
  190.    * @exception SQLException
  191.    */
  192.   Properties parseURL(String url,Properties defaults) throws SQLException
  193.   {
  194.     int state = -1;
  195.     Properties urlProps = new Properties(defaults);
  196.     String key = new String();
  197.     String value = new String();
  198.     
  199.     StringTokenizer st = new StringTokenizer(url, ":/;=&?", true);
  200.     for (int count = 0; (st.hasMoreTokens()); count++) {
  201.       String token = st.nextToken();
  202.       
  203.       // PM June 29 1997
  204.       // Added this, to help me understand how this works.
  205.       // Unless you want each token to be processed, leave this commented out
  206.       // but don't delete it.
  207.       //DriverManager.println("wellFormedURL: state="+state+" count="+count+" token='"+token+"'");
  208.       
  209.       // PM Aug 2 1997 - Modified to allow multiple backends
  210.       if (count <= 3) {
  211. if ((count % 2) == 1 && token.equals(":"))
  212.   ;
  213. else if((count % 2) == 0) {
  214.   boolean found=(count==0)?true:false;
  215.   for(int tmp=0;tmp<protocols.length;tmp++) {
  216.     if(token.equals(protocols[tmp])) {
  217.       // PM June 29 1997 Added this property to enable the driver
  218.       // to handle multiple backend protocols.
  219.       if(count == 2 && tmp > 0) {
  220. urlProps.put("Protocol",token);
  221. found=true;
  222.       }
  223.     }
  224.   }
  225.   
  226.   if(found == false)
  227.     return null;
  228. } else return null;
  229.       }
  230.       else if (count > 3) {
  231. if (count == 4 && token.equals("/")) state = 0;
  232. else if (count == 4) {
  233.   urlProps.put("PGDBNAME", token);
  234.   state = -2;
  235. }
  236. else if (count == 5 && state == 0 && token.equals("/"))
  237.   state = 1;
  238. else if (count == 5 && state == 0)
  239.   return null;
  240. else if (count == 6 && state == 1)
  241.   urlProps.put("PGHOST", token);
  242. else if (count == 7 && token.equals(":")) state = 2;
  243. else if (count == 8 && state == 2) {
  244.   try {
  245.     Integer portNumber = Integer.decode(token);
  246.     urlProps.put("PGPORT", portNumber.toString());
  247.   } catch (Exception e) {
  248.     return null;
  249.   }
  250. }
  251. else if ((count == 7 || count == 9) &&
  252.  (state == 1 || state == 2) && token.equals("/"))
  253.   state = -1;
  254. else if (state == -1) {
  255.   urlProps.put("PGDBNAME", token);
  256.   state = -2;
  257. }
  258. else if (state <= -2 && (count % 2) == 1) {
  259.   // PM Aug 2 1997 - added tests for ? and &
  260.   if (token.equals(";") || token.equals("?") || token.equals("&") ) state = -3;
  261.   else if (token.equals("=")) state = -5;
  262. }
  263. else if (state <= -2 && (count % 2) == 0) {
  264.   if (state == -3) key = token;
  265.   else if (state == -5) {
  266.     value = token;
  267.     //DriverManager.println("put("+key+","+value+")");
  268.     urlProps.put(key, value);
  269.     state = -2;
  270.   }
  271. }
  272.       }
  273.     }
  274.     
  275.     // PM June 29 1997
  276.     // This now outputs the properties only if we are logging
  277.     if(DriverManager.getLogStream() != null)
  278.       urlProps.list(DriverManager.getLogStream());
  279.     
  280.     return urlProps;
  281.     
  282.   }
  283.   
  284.   /**
  285.    * @return the hostname portion of the URL
  286.    */
  287.   public String host()
  288.   {
  289.     return props.getProperty("PGHOST","localhost");
  290.   }
  291.   
  292.   /**
  293.    * @return the port number portion of the URL or -1 if no port was specified
  294.    */
  295.   public int port()
  296.   {
  297.     return Integer.parseInt(props.getProperty("PGPORT","5432"));
  298.   }
  299.   
  300.   /**
  301.    * @return the database name of the URL
  302.    */
  303.   public String database()
  304.   {
  305.     return props.getProperty("PGDBNAME");
  306.   }
  307.   
  308.   /**
  309.    * @return the value of any property specified in the URL or properties
  310.    * passed to connect(), or null if not found.
  311.    */
  312.   public String property(String name)
  313.   {
  314.     return props.getProperty(name);
  315.   }
  316. }