sboag       01/03/11 18:04:13

  Modified:    java/src/org/apache/xalan/lib/sql XConnection.java
                        XStatement.java
  Added:       java/src/org/apache/xalan/lib/sql ConnectionPool.java
                        DefaultConnectionPool.java ExtensionError.java
                        PooledConnection.java QueryParameter.java
                        SQLExtensionError.java XConnectionPoolManager.java
  Log:
  These are John Gentilin <[EMAIL PROTECTED]>
  patches for connection pooling and parameterized
  queries.  These should be considered to be unstable
  right now, as we are still working on some things.
  
  Revision  Changes    Path
  1.9       +537 -114  
xml-xalan/java/src/org/apache/xalan/lib/sql/XConnection.java
  
  Index: XConnection.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/lib/sql/XConnection.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- XConnection.java  2001/02/21 14:05:41     1.8
  +++ XConnection.java  2001/03/12 02:04:09     1.9
  @@ -2,7 +2,7 @@
    * The Apache Software License, Version 1.1
    *
    *
  - * Copyright (c) 1999 The Apache Software Foundation.  All rights 
  + * Copyright (c) 1999 The Apache Software Foundation.  All rights
    * reserved.
    *
    * Redistribution and use in source and binary forms, with or without
  @@ -10,7 +10,7 @@
    * are met:
    *
    * 1. Redistributions of source code must retain the above copyright
  - *    notice, this list of conditions and the following disclaimer. 
  + *    notice, this list of conditions and the following disclaimer.
    *
    * 2. Redistributions in binary form must reproduce the above copyright
    *    notice, this list of conditions and the following disclaimer in
  @@ -18,7 +18,7 @@
    *    distribution.
    *
    * 3. The end-user documentation included with the redistribution,
  - *    if any, must include the following acknowledgment:  
  + *    if any, must include the following acknowledgment:
    *       "This product includes software developed by the
    *        Apache Software Foundation (http://www.apache.org/)."
    *    Alternately, this acknowledgment may appear in the software itself,
  @@ -26,7 +26,7 @@
    *
    * 4. The names "Xalan" and "Apache Software Foundation" must
    *    not be used to endorse or promote products derived from this
  - *    software without prior written permission. For written 
  + *    software without prior written permission. For written
    *    permission, please contact [EMAIL PROTECTED]
    *
    * 5. Products derived from this software may not be called "Apache",
  @@ -62,15 +62,19 @@
   import java.sql.SQLException;
   
   import java.util.Properties;
  +import java.util.Vector;
  +import java.util.StringTokenizer;
   
  -import org.xml.sax.AttributeList;
   
   import org.w3c.dom.Element;
   import org.w3c.dom.NamedNodeMap;
   import org.w3c.dom.traversal.NodeIterator;
  +import org.w3c.dom.NodeList;
  +import org.w3c.dom.Node;
   
  +import org.apache.xalan.stree.ElementImpl;
  +
   /**
  - * <meta name="usage" content="experimental"/>
    * An XSLT extension that allows a stylesheet to
    * access JDBC data. From the stylesheet perspective,
    * XConnection provides 3 extension functions: new(),
  @@ -86,54 +90,152 @@
   public class XConnection
   {
   
  -  /** Flag for DEBUG mode          */
  -  private static final boolean DEBUG = false;
  -
     /**
  -   * A JDBC driver of the form "foo.bar.Driver".
  +   * Flag for DEBUG mode
      */
  -  public String m_driver;
  +  private static final boolean DEBUG = true;
   
  -  /**
  -   * A database URL of the form jdbc:subprotocol:subname.
  -   */
  -  public String m_dbURL;
   
     /**
  -   * A user ID.
  +   * The JDBC connection.
      */
  -  public String m_user;
  +  public Connection m_connection = null;
   
     /**
  -   * A password.
  +   * Reference to the ConnectionPool used
      */
  -  public String m_password;
  +  public ConnectionPool m_ConnectionPool;
   
  +
     /**
  -   * A list of arbitrary string tag/value pairs as connection
  -   * arguments; normally at least a "user" and "password"
  -   * property should be included.
  +   * For PreparedStatements, we need a place to
  +   * to store the parameters in a vector.
      */
  -  public Properties m_protocol;
  +   public Vector        m_ParameterList = new Vector();
  +
  +
  +  // The original constructors will be kept around for backwards
  +  // compatibility. Future Stylesheets should use the approaite
  +  // connect method to receive full error information.
  +  //
  +  public XConnection (String ConnPoolName)
  +  {
  +    connect(ConnPoolName);
  +  }
  +
  +  public XConnection(String driver, String dbURL)
  +  {
  +    connect(driver, dbURL);
  +  }
   
  +  public XConnection(NodeList list)
  +  {
  +    connect(list);
  +  }
  +
  +  public XConnection(String driver, String dbURL, String user,
  +                     String password)
  +  {
  +    connect(driver, dbURL, user, password);
  +  }
  +
  +  public XConnection(String driver, String dbURL, Element protocolElem)
  +  {
  +    connect(driver, dbURL, protocolElem);
  +  }
  +
     /**
  -   * The JDBC connection.
  +   *
  +   * Create an XConnection using the name of an existing Connection Pool
  +   * @param <code>String poolName</code>, name of the existing pool
  +   * to pull connections from.
  +   *
      */
  -  public Connection m_connection = null;
  +  public NodeIterator connect(String ConnPoolName)
  +  {
  +    try
  +    {
  +      XConnectionPoolManager mgr = new XConnectionPoolManager();
  +      m_ConnectionPool = mgr.getPool(ConnPoolName);
  +      m_connection = m_ConnectionPool.getConnection();
  +    }
  +    catch(SQLException e)
  +    {
  +      SQLExtensionError err = new SQLExtensionError(e);
  +      return err;
  +    }
   
  +    return null;
  +  }
  +
     /**
      * Create an XConnection object with just a driver and database URL.
      * @param driver JDBC driver of the form foo.bar.Driver.
      * @param dbURL database URL of the form jdbc:subprotocol:subname.
      */
  -  public XConnection(String driver, String dbURL)
  +
  +  public NodeIterator connect(String driver, String dbURL)
  +  {
  +    try
  +    {
  +      init(driver, dbURL, new Properties() );
  +    }
  +    catch(SQLException e)
  +    {
  +      SQLExtensionError err = new SQLExtensionError(e);
  +      return err;
  +    }
  +    catch (Exception e)
  +    {
  +      ExtensionError err = new ExtensionError(e);
  +      return err;
  +    }
  +
  +    return null;
  +
  +  }
  +
  +  public NodeIterator connect(Element protocolElem)
     {
  +    try
  +    {
  +      initFromElement(protocolElem);
  +    }
  +    catch(SQLException e)
  +    {
  +      SQLExtensionError err = new SQLExtensionError(e);
  +      return err;
  +    }
  +    catch (Exception e)
  +    {
  +      ExtensionError err = new ExtensionError(e);
  +      return err;
  +    }
   
  -    super();
  +    return null;
   
  -    init(driver, dbURL, null, null, null, 1);
     }
   
  +  public NodeIterator connect(NodeList list)
  +  {
  +    try
  +    {
  +      initFromElement( (Element) list.item(0) );
  +    }
  +    catch(SQLException e)
  +    {
  +      SQLExtensionError err = new SQLExtensionError(e);
  +      return err;
  +    }
  +    catch (Exception e)
  +    {
  +      ExtensionError err = new ExtensionError(e);
  +      return err;
  +    }
  +
  +    return null;
  +  }
  +
     /**
      * Create an XConnection object with user ID and password.
      * @param driver JDBC driver of the form foo.bar.Driver.
  @@ -141,15 +243,32 @@
      * @param user user ID.
      * @param password connection password.
      */
  -  public XConnection(String driver, String dbURL, String user,
  +  public NodeIterator connect(String driver, String dbURL, String user,
                        String password)
     {
  +    try
  +    {
  +      Properties prop = new Properties();
  +      prop.put("user", user);
  +      prop.put("password", password);
   
  -    super();
  +      init(driver, dbURL, prop);
  +    }
  +    catch(SQLException e)
  +    {
  +      SQLExtensionError err = new SQLExtensionError(e);
  +      return err;
  +    }
  +    catch (Exception e)
  +    {
  +      ExtensionError err = new ExtensionError(e);
  +      return err;
  +    }
   
  -    init(driver, dbURL, user, password, null, 3);
  +    return null;
     }
   
  +
     /**
      * Create an XConnection object with a connection protocol
      * @param driver JDBC driver of the form foo.bar.Driver.
  @@ -157,134 +276,422 @@
      * @param protocolElem list of string tag/value connection arguments,
      * normally including at least "user" and "password".
      */
  -  public XConnection(String driver, String dbURL, Element protocolElem)
  +  public NodeIterator connect(String driver, String dbURL, Element 
protocolElem)
     {
  +    try
  +    {
  +      Properties prop = new Properties();
   
  -    super();
  +      NamedNodeMap atts = protocolElem.getAttributes();
   
  -    init(driver, dbURL, null, null, protocolElem, 2);
  +      for (int i = 0; i < atts.getLength(); i++)
  +      {
  +        prop.put(atts.item(i).getNodeName(), atts.item(i).getNodeValue());
  +      }
  +
  +      init(driver, dbURL, prop);
  +    }
  +    catch(SQLException e)
  +    {
  +      SQLExtensionError err = new SQLExtensionError(e);
  +      return err;
  +    }
  +    catch (Exception e)
  +    {
  +      ExtensionError err = new ExtensionError(e);
  +      return err;
  +    }
  +
  +    return null;
     }
   
  +
     /**
  -   * Initialize.
      *
  -   * @param driver JDBC driver of the form foo.bar.Driver.
  -   * @param dbURL database URL of the form jdbc:subprotocol:subname.
  -   * @param user user ID
  -   * @param password connection password.
  -   * @param protocolElem list of string tag/value connection arguments,
  -   * normally including at least "user" and "password".
  -   * @param getConnectionArgs Connection arguments
  +   * Allow the database connection information to be sepcified in
  +   * the XML tree. The connection information could also be
  +   * externally originated and passed in as an XSL Parameter.
  +   *
  +   * The required XML Format is as follows.
  +   *
  +   * // A document fragment is needed to specify the connection information
  +   * // the top tag name is not specific for this code, we are only 
interested
  +   * // in the tags inside.
  +   * <DBINFO-TAG>
  +   *
  +   * // Specify the driver name for this connection pool
  +   *  <dbdriver>drivername</dbdriver>
  +   *
  +   * // Specify the URL for the driver in this connection pool
  +   *  <dburl>url</dburl>
  +   *
  +   * // Specify the password for this connection pool
  +   *  <password>password</password>
  +   *
  +   * // Specify the username for this connection pool
  +   *  <user>username</user>
  +   *
  +   *  // You can add extra protocol items including the User Name & Password
  +   *  // with the protocol tag. For each extra protocol item, add a new 
element
  +   *  // where the name of the item is specified as the name attribute and
  +   *  // and its value as the elements value.
  +   *  <protocol name="name of value">value</protocol>
  +   *
  +   * </DBINFO-TAG>
  +   *
      */
  -  private void init(String driver, String dbURL, String user,
  -                    String password, Element protocolElem,
  -                    int getConnectionArgs)
  +  private void initFromElement(Element e)
  +    throws SQLException
     {
  +
  +    Properties prop = new Properties();
  +    String driver = "";
  +    String dbURL = "";
  +    Node n = e.getFirstChild();
   
  -    m_driver = driver;
  -    m_dbURL = dbURL;
  -    m_user = user;
  -    m_password = password;
  +    if (null == n) return; // really need to throw an error
   
  -    if (protocolElem == null)
  -      m_protocol = null;
  -    else
  +    do
       {
  -      m_protocol = new Properties();
  +      String nName = n.getNodeName();
   
  -      NamedNodeMap atts = protocolElem.getAttributes();
  +      if (nName.equalsIgnoreCase("dbdriver"))
  +      {
  +        driver = "";
  +        Node n1 = n.getFirstChild();
  +        if (null != n1)
  +        {
  +          driver = n1.getNodeValue();
  +        }
  +      }
   
  -      for (int i = 0; i < atts.getLength(); i++)
  +      if (nName.equalsIgnoreCase("dburl"))
         {
  -        m_protocol.put(atts.item(i).getNodeName(),
  -                       atts.item(i).getNodeValue());
  +        dbURL = "";
  +        Node n1 = n.getFirstChild();
  +        if (null != n1)
  +        {
  +          dbURL = n1.getNodeValue();
  +        }
         }
  -    }
  +
  +      if (nName.equalsIgnoreCase("password"))
  +      {
  +        String s = "";
  +        Node n1 = n.getFirstChild();
  +        if (null != n1)
  +        {
  +          s = n1.getNodeValue();
  +        }
  +        prop.put("password", s);
  +      }
   
  -    connect(driver, dbURL, user, password, m_protocol, getConnectionArgs);
  +      if (nName.equalsIgnoreCase("user"))
  +      {
  +        String s = "";
  +        Node n1 = n.getFirstChild();
  +        if (null != n1)
  +        {
  +          s = n1.getNodeValue();
  +        }
  +        prop.put("user", s);
  +      }
  +
  +      if (nName.equalsIgnoreCase("protocol"))
  +      {
  +        String Name = "";
  +
  +        NamedNodeMap attrs = n.getAttributes();
  +        Node n1 = attrs.getNamedItem("name");
  +        if (null != n1)
  +        {
  +          String s = "";
  +          Name = n1.getNodeValue();
  +
  +          Node n2 = n.getFirstChild();
  +          if (null != n2) s = n2.getNodeValue();
  +
  +          prop.put(Name, s);
  +        }
  +      }
  +
  +    } while ( (n = n.getNextSibling()) != null);
  +
  +    init(driver, dbURL, prop);
     }
   
  +
  +
     /**
  -   * Connect to the JDBC database.
  -   * @param driver Database url of the form jdbc:subprotocol:subname .
  +   * Initilize is being called because we did not have an
  +   * existing Connection Pool, so let's see if we created one
  +   * already or lets create one ourselves.
  +   *
  +   * @param driver JDBC driver of the form foo.bar.Driver.
      * @param dbURL database URL of the form jdbc:subprotocol:subname.
  -   * @param user user ID
  -   * @param password connection password.
  -   * @param protocol List of arbitrary string tag/value pairs as
  -   * connection arguments; normally at least a "user" and "password"
  -   * property should be included.
  +   * @param Properties list of string tag/value connection arguments,
  +   * normally including at least "user" and "password".
      * @param getConnectionArgs Connection arguments
      */
  -  public void connect(String driver, String dbURL, String user,
  -                      String password, Properties protocol,
  -                      int getConnectionArgs)
  +  private void init(String driver, String dbURL, Properties prop)
  +    throws SQLException
     {
  +    String user = prop.getProperty("user");
  +    if (user == null) user = "";
   
  -    try
  +    String passwd = prop.getProperty("password");
  +    if (passwd == null) passwd = "";
  +
  +    String poolName = driver + dbURL + user + passwd;
  +
  +    XConnectionPoolManager mgr = new XConnectionPoolManager();
  +    m_ConnectionPool = mgr.getPool(poolName);
  +    if (m_ConnectionPool == null)
       {
  +      DefaultConnectionPool defpool = new DefaultConnectionPool();
  +      defpool.setDriver(driver);
  +      defpool.setURL(dbURL);
  +      defpool.setProtocol(prop);
  +      defpool.setActive(true);
   
  -      // The driver is installed by loading its class.
  -      Class.forName(driver).newInstance();
  +      mgr.registerPool(poolName, defpool);
   
  -      // Use the appropriate getConnection() method.
  -      switch (getConnectionArgs)
  -      {
  -      case 1 :
  -        m_connection = DriverManager.getConnection(dbURL);
  -        break;
  -      case 2 :
  -        m_connection = DriverManager.getConnection(dbURL, protocol);
  -        break;
  -      case 3 :
  -        m_connection = DriverManager.getConnection(dbURL, user, password);
  -      }
  +      m_ConnectionPool = defpool;
  +    }
   
  -      /*
  -      We could also turn autocommit off by putting
  -      ;autocommit=false on the URL.
  -      */
  -      try
  -      {
  -        m_connection.setAutoCommit(false);
  -      }
  -      catch(java.sql.SQLException se)
  -      {
  -        // Some drivers do not support transactions
  -      }
   
  -      DatabaseMetaData dma = m_connection.getMetaData();
  +    m_connection = m_ConnectionPool.getConnection();
  +  }
   
  -      if (DEBUG)
  -      {
  -        System.out.println("\nConnected to " + dma.getURL());
  -        System.out.println("Driver   " + dma.getDriverName());
  -        System.out.println("Version  " + dma.getDriverVersion());
  -        System.out.println("");
  -      }
  +
  +  /**
  +   * Execute a query statement by instantiating an
  +   * [EMAIL PROTECTED] org.apache.xalan.lib.sql.XStatement XStatement}
  +   * object. The XStatement executes the query, and uses the result set
  +   * to create a [EMAIL PROTECTED] org.apache.xalan.lib.sql.RowSet RowSet},
  +   * a row-set element.
  +   *
  +   * @param queryString the SQL query.
  +   * @return XStatement implements NodeIterator.
  +   *
  +   * @throws SQLException
  +   */
  +  public NodeIterator query(String queryString)
  +  {
  +    try
  +    {
  +      return new XStatement(this, queryString);
  +    }
  +    catch(SQLException e)
  +    {
  +      SQLExtensionError err = new SQLExtensionError(e);
  +      return err;
       }
  -    catch (Throwable e)
  +    catch (Exception e)
       {
  -      e.printStackTrace();
  +      ExtensionError err = new ExtensionError(e);
  +      return err;
       }
  +
     }
   
     /**
  -   * Execute a query statement by instantiating an [EMAIL PROTECTED] 
org.apache.xalan.lib.sql.XStatement XStatement}
  -   * object. The XStatement executes the query, and uses the result set to 
create a
  -   * [EMAIL PROTECTED] org.apache.xalan.lib.sql.RowSet RowSet}, a row-set 
element.
  +   * Execute a parameterized query statement by instantiating an
  +   * [EMAIL PROTECTED] org.apache.xalan.lib.sql.XStatement XStatement}
  +   * object. The XStatement executes the query, and uses the result set
  +   * to create a [EMAIL PROTECTED] org.apache.xalan.lib.sql.RowSet RowSet},
  +   * a row-set element.
  +   *
      * @param queryString the SQL query.
      * @return XStatement implements NodeIterator.
      *
      * @throws SQLException
      */
  -  public NodeIterator query(String queryString) throws SQLException
  +  public NodeIterator pquery(String queryString)
     {
  +    try
  +    {
  +      return new XStatement(this, queryString, m_ParameterList);
  +    }
  +    catch(SQLException e)
  +    {
  +      SQLExtensionError err = new SQLExtensionError(e);
  +      return err;
  +    }
  +    catch (Exception e)
  +    {
  +      ExtensionError err = new ExtensionError(e);
  +      return err;
  +    }
   
  -    // TODO: These need to be pooled.
  -    return new XStatement(this, queryString);
  +
     }
   
  +
     /**
  +   * Execute a parameterized query statement by instantiating an
  +   * [EMAIL PROTECTED] org.apache.xalan.lib.sql.XStatement XStatement}
  +   * object. The XStatement executes the query, and uses the result set
  +   * to create a [EMAIL PROTECTED] org.apache.xalan.lib.sql.RowSet RowSet},
  +   * a row-set element.
  +   * This method allows for the user to pass in a comma seperated
  +   * String that represents a list of parameter types. If supplied
  +   * the parameter types will be used to overload the current types
  +   * in the current parameter list.
  +   *
  +   * @param queryString the SQL query.
  +   * @return XStatement implements NodeIterator.
  +   *
  +   * @throws SQLException
  +   */
  +  public NodeIterator pquery(String queryString, String typeInfo)
  +  {
  +    try
  +    {
  +      int indx = 0;
  +      QueryParameter param = null;
  +
  +      // Parse up the parameter types that were defined
  +      // with the query
  +      StringTokenizer plist = new StringTokenizer(typeInfo);
  +
  +      // Override the existing type that is stored in the
  +      // parameter list. If there are more types than parameters
  +      // ignore for now, a more meaningfull error should occur
  +      // when the actual query is executed.
  +      while (plist.hasMoreTokens())
  +      {
  +        String value = plist.nextToken();
  +        param = (QueryParameter) m_ParameterList.elementAt(indx);
  +        if ( null != param )
  +        {
  +          param.setType(value);
  +        }
  +      }
  +
  +      return new XStatement(this, queryString, m_ParameterList);
  +    }
  +    catch(SQLException e)
  +    {
  +      SQLExtensionError err = new SQLExtensionError(e);
  +      return err;
  +    }
  +    catch (Exception e)
  +    {
  +      ExtensionError err = new ExtensionError(e);
  +      return err;
  +    }
  +
  +
  +  }
  +
  +  /**
  +   * Add an untyped value to the parameter list.
  +   */
  +  public void addParameter(String value)
  +  {
  +    addParameterWithType(value, null);
  +  }
  +
  +  /**
  +   * Add a typed parameter to the parameter list.
  +   */
  +  public void addParameterWithType(String value, String Type)
  +  {
  +    m_ParameterList.addElement( new QueryParameter(value, Type) );
  +  }
  +
  +
  +  /**
  +   * Add a single parameter to the parameter list
  +   * formatted as an Element
  +   */
  +  public void addParameterFromElement(Element e)
  +  {
  +    NamedNodeMap attrs = e.getAttributes();
  +    Node Type = attrs.getNamedItem("type");
  +    Node n1  = e.getFirstChild();
  +    if (null != n1)
  +    {
  +      String value = n1.getNodeValue();
  +      if (value == null) value = "";
  +      m_ParameterList.addElement( new QueryParameter(value, 
Type.getNodeValue()) );
  +    }
  +  }
  +
  +
  +  /**
  +   * Add a section of parameters to the Parameter List
  +   * Do each element from the list
  +   */
  +  public void addParameterFromElement(NodeList nl)
  +  {
  +    //
  +    // Each child of the NodeList represents a node
  +    // match from the select= statment. Process each
  +    // of them as a seperate list.
  +    // The XML Format is as follows
  +    //
  +    // <START-TAG>
  +    //   <TAG1 type="int">value</TAG1>
  +    //   <TAGA type="int">value</TAGA>
  +    //   <TAG2 type="string">value</TAG2>
  +    // </START-TAG>
  +    //
  +    // The XSL to process this is formatted as follows
  +    // <xsl:param name="plist" select="//START-TAG" />
  +    // <sql:addParameter( $plist );
  +    //
  +    int count = nl.getLength();
  +    for (int x=0; x<count; x++)
  +    {
  +      addParameters( (Element) nl.item(x));
  +    }
  +  }
  +
  +  private void addParameters(Element elem)
  +  {
  +    //
  +    // Process all of the Child Elements
  +    // The format is as follows
  +    //
  +    //<TAG type ="typeid">value</TAG>
  +    //<TAG1 type ="typeid">value</TAG1>
  +    //<TAGA type ="typeid">value</TAGA>
  +    //
  +    // The name of the Node is not important just is value
  +    // and if it contains a type attribute
  +
  +    Node n = elem.getFirstChild();
  +
  +    if (null == n) return;
  +
  +    do
  +    {
  +      if (n.getNodeType() == Node.ELEMENT_NODE)
  +      {
  +        NamedNodeMap attrs = n.getAttributes();
  +        Node Type = attrs.getNamedItem("type");
  +        String TypeStr;
  +
  +        if (Type == null) TypeStr = "string";
  +        else TypeStr = Type.getNodeValue();
  +
  +        Node n1  = n.getFirstChild();
  +        if (null != n1)
  +        {
  +          String value = n1.getNodeValue();
  +          if (value == null) value = "";
  +
  +
  +          m_ParameterList.addElement(
  +            new QueryParameter(value, TypeStr) );
  +        }
  +      }
  +    } while ( (n = n.getNextSibling()) != null);
  +  }
  +
  +  /**
      * Close the connection to the data source.
      *
      *
  @@ -298,12 +705,28 @@
   
       if (null != m_connection)
       {
  -      m_connection.close();
  +      if (null != m_ConnectionPool)
  +      {
  +        m_ConnectionPool.releaseConnection(m_connection);
   
  -      m_connection = null;
  +      }
  +      else
  +      {
  +        // something is wrong here, we have a connection
  +        // but no controlling pool, close it anyway the
  +        // error will show up as an exeption elsewhere.
  +        m_connection.close();
  +      }
       }
   
  +    m_connection = null;
  +
       if (DEBUG)
         System.out.println("Exiting XConnection.close");
  +  }
  +
  +  protected void finalize()
  +  {
  +    if (DEBUG) System.out.println("In XConnection, finalize");
     }
   }
  
  
  
  1.11      +162 -29   
xml-xalan/java/src/org/apache/xalan/lib/sql/XStatement.java
  
  Index: XStatement.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/lib/sql/XStatement.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- XStatement.java   2001/02/21 14:05:41     1.10
  +++ XStatement.java   2001/03/12 02:04:10     1.11
  @@ -2,7 +2,7 @@
    * The Apache Software License, Version 1.1
    *
    *
  - * Copyright (c) 1999 The Apache Software Foundation.  All rights 
  + * Copyright (c) 1999 The Apache Software Foundation.  All rights
    * reserved.
    *
    * Redistribution and use in source and binary forms, with or without
  @@ -10,7 +10,7 @@
    * are met:
    *
    * 1. Redistributions of source code must retain the above copyright
  - *    notice, this list of conditions and the following disclaimer. 
  + *    notice, this list of conditions and the following disclaimer.
    *
    * 2. Redistributions in binary form must reproduce the above copyright
    *    notice, this list of conditions and the following disclaimer in
  @@ -18,7 +18,7 @@
    *    distribution.
    *
    * 3. The end-user documentation included with the redistribution,
  - *    if any, must include the following acknowledgment:  
  + *    if any, must include the following acknowledgment:
    *       "This product includes software developed by the
    *        Apache Software Foundation (http://www.apache.org/)."
    *    Alternately, this acknowledgment may appear in the software itself,
  @@ -26,7 +26,7 @@
    *
    * 4. The names "Xalan" and "Apache Software Foundation" must
    *    not be used to endorse or promote products derived from this
  - *    software without prior written permission. For written 
  + *    software without prior written permission. For written
    *    permission, please contact [EMAIL PROTECTED]
    *
    * 5. Products derived from this software may not be called "Apache",
  @@ -63,14 +63,27 @@
   import org.w3c.dom.DOMException;
   
   import java.sql.Statement;
  +import java.sql.PreparedStatement;
   import java.sql.SQLException;
   import java.sql.ResultSet;
   
  +import java.util.Vector;
  +import java.util.Enumeration;
  +
  +import java.math.BigDecimal;
  +import java.math.BigInteger;
  +
  +import java.sql.Timestamp;
  +import java.sql.Time;
  +import java.sql.Date;
  +
  +import java.lang.Integer;
  +import java.lang.Double;
  +
   import org.apache.xpath.axes.ContextNodeList;
   import org.apache.xalan.res.XSLTErrorResources;
   
   /**
  - * <meta name="usage" content="experimental"/>
    * Represents a JDBC query statement. Also acts as both a
    * NodeIterator and the Document node for the row-set representation
    * of the query result set.
  @@ -80,16 +93,22 @@
   {
   
     /** Flag for DEBUG mode          */
  -  private static final boolean DEBUG = false;
  +  private static final boolean DEBUG = true;
   
  -  /** JDBC Query statement          */
  -  private Statement m_statement;
  +  /**
  +   * Ths JDBC Statement that is used for the query.
  +   * It is allocated as a prepared statement but may
  +   * only be use as a regular statemwnt.
  +   *
  +   */
  +  private Statement         m_statement;
  +  private PreparedStatement m_pstatement;
   
     /** Node counter          */
     private int m_nodeCounter = 0;
   
     /**
  -   * Get And Increment Node Counter 
  +   * Get And Increment Node Counter
      *
      *
      * @return Node counter
  @@ -119,7 +138,7 @@
     ResultSet m_resultSet;
   
     /**
  -   * Get the ResultSet from executing the query string 
  +   * Get the ResultSet from executing the query string
      *
      *
      * @return ResultSet instance
  @@ -176,8 +195,11 @@
   
       // The SQL statement which lets us execute commands against the 
connection.
       m_xconnection = connection;
  +
       m_statement = m_xconnection.m_connection.createStatement();
  +
       m_queryString = queryString;
  +
       m_resultSet = m_statement.executeQuery(m_queryString);
       m_rowset = new RowSet(this);
   
  @@ -185,11 +207,123 @@
         System.out.println("Exiting XStatement constructor");
     }
   
  +  public XStatement(XConnection connection, String queryString, Vector pList)
  +          throws SQLException
  +  {
  +
  +    super(null);
  +
  +    if (DEBUG)
  +      System.out.println("In XStatement constructor for pquery");
  +
  +    // The SQL statement which lets us execute commands against the 
connection.
  +    m_xconnection = connection;
  +    m_queryString = queryString;
  +
  +    if (DEBUG)
  +    {
  +      System.out.println("Executing PQuery: " + m_queryString);
  +    }
  +    m_pstatement = 
m_xconnection.m_connection.prepareStatement(m_queryString);
  +    Enumeration enum = pList.elements();
  +    int indx = 1;
  +    while (enum.hasMoreElements())
  +    {
  +      QueryParameter param = (QueryParameter) enum.nextElement();
  +      setParameter(indx, m_pstatement, param);
  +      indx++;
  +    }
  +
  +    m_resultSet = m_pstatement.executeQuery();
  +    m_rowset = new RowSet(this);
  +
  +    //
  +    // Make a copy of the statement for external access
  +    m_statement = m_pstatement;
  +
  +    if (DEBUG)
  +      System.out.println("Exiting XStatement constructor");
  +  }
  +
  +
  +  /**
  +   * Set the parameter for a Prepared Statement
  +   *
  +   */
  +  public void setParameter(int pos, PreparedStatement stmt, QueryParameter p)
  +    throws SQLException
  +  {
  +    String type = p.getType();
  +    if (type.equalsIgnoreCase("string"))
  +    {
  +      stmt.setString(pos, p.getValue());
  +    }
  +
  +    else if (type.equalsIgnoreCase("bigdecimal"))
  +    {
  +      stmt.setBigDecimal(pos, new BigDecimal(p.getValue()));
  +    }
  +
  +    else if (type.equalsIgnoreCase("boolean"))
  +    {
  +      Integer i = new Integer( p.getValue() );
  +      boolean b = ((i.intValue() != 0) ? false : true);
  +      stmt.setBoolean(pos, b);
  +    }
  +
  +    else if (type.equalsIgnoreCase("bytes"))
  +    {
  +      stmt.setBytes(pos, p.getValue().getBytes());
  +    }
  +
  +    else if (type.equalsIgnoreCase("date"))
  +    {
  +      stmt.setDate(pos, Date.valueOf(p.getValue()));
  +    }
  +
  +    else if (type.equalsIgnoreCase("double"))
  +    {
  +      Double d = new Double(p.getValue());
  +      stmt.setDouble(pos, d.doubleValue() );
  +    }
  +
  +    else if (type.equalsIgnoreCase("float"))
  +    {
  +      Float f = new Float(p.getValue());
  +      stmt.setFloat(pos, f.floatValue());
  +    }
  +
  +    else if (type.equalsIgnoreCase("long"))
  +    {
  +      Long l = new Long(p.getValue());
  +      stmt.setLong(pos, l.longValue());
  +    }
  +
  +    else if (type.equalsIgnoreCase("short"))
  +    {
  +      Short s = new Short(p.getValue());
  +      stmt.setShort(pos, s.shortValue());
  +    }
  +
  +    else if (type.equalsIgnoreCase("time"))
  +    {
  +      stmt.setTime(pos, Time.valueOf(p.getValue()) );
  +    }
  +
  +    else if (type.equalsIgnoreCase("timestamp"))
  +    {
  +
  +      stmt.setTimestamp(pos, Timestamp.valueOf(p.getValue()) );
  +    }
  +
  +  }
  +
  +
     /**
  -   * Get the representation of the JDBC Query statement 
  +   * Get the representation of the JDBC Query statement
      *
      *
  -   * @return the representation of the JDBC Query statement, this 
  +   * @return the representation of the JDBC Query statement, this
      */
     public XStatement getXStatement()
     {
  @@ -216,7 +350,7 @@
      * iterator. The available set of constants is defined in the
      * <code>NodeFilter</code> interface.
      *
  -   * @return which node types are to be presented 
  +   * @return which node types are to be presented
      */
     public int getWhatToShow()
     {
  @@ -386,9 +520,8 @@
   
       try
       {
  -      org.apache.xpath.patterns.NodeTest nt = this.getNodeTest();
  -      if ((nt == null) || ((nt.getNamespace() == null)
  -              && (nt.getLocalName().equals(S_DOCELEMENTNAME))))
  +      if ((this.getNodeTest().getNamespace() == null)
  +              && 
(this.getNodeTest().getLocalName().equals(S_DOCELEMENTNAME)))
           return m_rowset;
         else
           return null;
  @@ -447,7 +580,7 @@
     // ===== ContextNodeList implementation =====
   
     /**
  -   * The current node is the RowSet  
  +   * The current node is the RowSet
      *
      *
      * @return The row-set
  @@ -481,7 +614,7 @@
      * Set whether nodes should be cached - not implemented
      *
      *
  -   * @param b Flag indicating whether nodes should be cached 
  +   * @param b Flag indicating whether nodes should be cached
      */
     public void setShouldCacheNodes(boolean b)
     {
  @@ -502,7 +635,7 @@
     }
   
     /**
  -   * Not implemented 
  +   * Not implemented
      *
      *
      * @param i
  @@ -514,7 +647,7 @@
     }
   
     /**
  -   * Return size 
  +   * Return size
      *
      *
      * @return 1
  @@ -536,7 +669,7 @@
     }
   
     /**
  -   * Overide cloneWithReset method 
  +   * Overide cloneWithReset method
      *
      *
      * @return A clone of this which has been reset
  @@ -557,7 +690,7 @@
      * Clone this object
      *
      *
  -   * @return A clone of this object 
  +   * @return A clone of this object
      *
      * @throws CloneNotSupportedException
      */
  @@ -568,26 +701,26 @@
   
       return clone;
     }
  -  
  +
     /** Index of Last node found by this iterator   */
     private int m_last = 0;
  -  
  +
     /**
  -   * Get index of the last found node 
  +   * Get index of the last found node
      *
      *
  -   * @return index of last found node 
  +   * @return index of last found node
      */
     public int getLast()
     {
       return m_last;
     }
  -  
  +
     /**
  -   * Set the index of the last found node 
  +   * Set the index of the last found node
      *
      *
  -   * @aram index of last found node 
  +   * @aram index of last found node
      */
     public void setLast(int last)
     {
  
  
  
  1.3       +0 -0      
xml-xalan/java/src/org/apache/xalan/lib/sql/ConnectionPool.java
  
  
  
  
  1.3       +10 -11    
xml-xalan/java/src/org/apache/xalan/lib/sql/DefaultConnectionPool.java
  
  
  
  
  1.3       +0 -0      
xml-xalan/java/src/org/apache/xalan/lib/sql/ExtensionError.java
  
  
  
  
  1.3       +0 -0      
xml-xalan/java/src/org/apache/xalan/lib/sql/PooledConnection.java
  
  
  
  
  1.3       +0 -0      
xml-xalan/java/src/org/apache/xalan/lib/sql/QueryParameter.java
  
  
  
  
  1.3       +0 -0      
xml-xalan/java/src/org/apache/xalan/lib/sql/SQLExtensionError.java
  
  
  
  
  1.3       +0 -0      
xml-xalan/java/src/org/apache/xalan/lib/sql/XConnectionPoolManager.java
  
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to