http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/38e49cf7/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4DataSource.java ---------------------------------------------------------------------- diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4DataSource.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4DataSource.java new file mode 100644 index 0000000..3ec9e93 --- /dev/null +++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4DataSource.java @@ -0,0 +1,366 @@ +// @@@ START COPYRIGHT @@@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// +// @@@ END COPYRIGHT @@@ + +package org.trafodion.jdbc.t4; + +import java.io.PrintWriter; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import java.util.Properties; +import java.util.logging.FileHandler; +import java.util.logging.Formatter; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +import javax.naming.Context; +import javax.naming.NamingException; +import javax.naming.Reference; +import javax.naming.Referenceable; + +/** + * + * <p> + * JDBC Type 4 Driver <code>DataSource</code> class. + * </p> + * <p> + * Description: A <code>DataSource</code> object is a factory for Connection + * objects. An object that implements the <code>DataSource</code> interface is + * typically registered with a JNDI service provider. A JDBC driver that is + * accessed through the <code>DataSource</code> API does not automatically + * register itself with the <code>DriverManager</code> object. + * </p> + * + * <p> + * The <code>TrafT4DataSource</code> class can provide connection pooling and + * statement pooling features. + * </p> + * + * <pre> + * <b>Setting properties for the TrafT4DataSource in the Type 4 driver</b> + * TrafT4DataSource ds = new TrafT4DataSource(); + * ds.setUrl("jdbc:t4jdbc://<NDCS host>:<NDCS port>/:"); + * ds.setCatalog("your catalog"); + * ds.setSchema("your schema"); + * ds.setUser("safeguard user name"); + * ds.setPassword("safeguard password"); + * + * // Following are optional properties + * ds.setConnectionTimeout("timeout in seconds"); + * ds.setT4LogFile("your log file location"); + * ds.setT4LogLevel("SEVERE"); + * ds.setServerDataSource("NDCS datasource name"); + * + * // Properties relevant for Type 4 connection pooling. + * // Set ds.setMaxPoolSize(-1) to turn OFF connection pooling + * ds.setMaxPoolSize("number of connections required"); + * ds.setMinPoolSize("number of connections required"); + * + * // Properties relevant for Type 4 statement pooling. + * // Set ds.setMaxStatement(0) to turn statement pooling OFF + * // Statement pooling is enabled only when connection pooling is enabled. + * ds.setMaxStatements("number of statements to be pooled"); + * </pre> + * + * <pre> + * <b>Programmatically registering TrafT4DataSource with JDNI</b> + * java.util.Hashtable env = new java.util.Hashtable(); + * env.put(Context.INITIAL_CONTEXT_FACTORY, "Factory class name here"); + * javax.naming.Context ctx = new javax.naming.InitialContext(env); + * ctx.rebind("DataSource name here", ds); + * </pre> + * + * <pre> + * <b>Application making Type4 connection using the DataSource from JDNI</b> + * java.util.Hashtable env = new java.util.Hashtable(); + * env.put(Context.INITIAL_CONTEXT_FACTORY, "Factory class name here"); + * javax.naming.Context ctx = new javax.naming.InitialContext(env); + * DataSource ds = (DataSource)ctx.lookup("DataSource name here"); + * java.sql.Connection con = ds.getConnection(); + * </pre> + * + * <p> + * Copyright: (C) Apache Software Foundation (ASF) + * </p> + * + * @see T4Properties + */ +public class TrafT4DataSource extends T4DSProperties implements javax.sql.DataSource, java.io.Serializable, Referenceable + +{ + /** + * Attempts to establish an NDCS connection. + * + * @return a connection to the NDCS server. + * @throws SQLException + * if a database access error or NDCS error occurs. + * @see #getConnection(String, String) + */ + synchronized public Connection getConnection() throws SQLException { + if (logger.isLoggable(Level.FINER)) { + logger.entering("TrafT4DataSource", "getConnection"); + } + + Connection conn; + TrafT4Connection t4Conn; + TrafT4ConnectionPoolDataSource pds; + + if (getSQLException() != null) { + throw TrafT4Messages.createSQLException(null, getLocale(), "invalid_property", getSQLException()); + } + + if (getMaxPoolSize() == -1) { + t4Conn = new TrafT4Connection(this, getT4Properties()); + } else { + if (poolManager != null) { + t4Conn = (TrafT4Connection) poolManager.getConnection(); + } else { + + pds = new TrafT4ConnectionPoolDataSource(getProperties()); + poolManager = new TrafT4PooledConnectionManager(pds, getT4LogLevel()); + t4Conn = (TrafT4Connection) poolManager.getConnection(); + } + } + + t4Conn.setLogInfo(getT4LogLevel(), getLogWriter()); + conn = t4Conn; + + if (logger.isLoggable(Level.FINER)) { + logger.exiting("TrafT4DataSource", "getConnection", conn); + } + + return conn; + } + + /** + * Attempts to establish an NDCS connection. + * + * @return a connection to the NDCS server. + * @param username + * Safeguard user name + * @param password + * Safeguard user password + * @throws SQLException + * if a database access error or NDCS error occurs. + * @see #getConnection() + */ + synchronized public Connection getConnection(String username, String password) throws SQLException { + if (logger.isLoggable(Level.FINER)) { + logger.entering("TrafT4DataSource", "getConnection", new Object[] { this, username }); + } + + Connection conn; + + setUser(username); + setPassword(password); + + conn = getConnection(); + + if (logger.isLoggable(Level.FINER)) { + logger.exiting("TrafT4DataSource", "getConnection", conn); + } + + return conn; + } + + /** + * @return Reference Object containing all the Type 4 property references. + * @throws NamingException + */ + public Reference getReference() throws NamingException { + + Reference ref = new Reference(this.getClass().getName(), "org.trafodion.jdbc.t4.TrafT4DataSourceFactory", null); + return addReferences(ref); + } + + /** + * Sets the print writer for the current Type 4 data source. + * + * @param out + * java.io.PrintWriter for the current T4 connection. + * @throws SQLException + * when error occurs. + * @see #getLogWriter() + * @see javax.sql.ConnectionPoolDataSource + */ + public void setLogWriter(PrintWriter out) throws SQLException { + super.setLogWriter(out); + if (t4Logger_.isLoggable(Level.FINE) == true) { + Object p[] = T4LoggingUtilities.makeParams(null, out); + t4Logger_.logp(Level.FINE, "TrafT4DataSource", "setLogWriter", + "Note, this constructor was called before the previous constructor", p); + } + if (getLogWriter() != null) { + LogRecord lr = new LogRecord(Level.FINE, ""); + Object p[] = T4LoggingUtilities.makeParams(null, out); + lr.setParameters(p); + lr.setSourceClassName("TrafT4DataSource"); + lr.setSourceMethodName("setLogWriter"); + T4LogFormatter lf = new T4LogFormatter(); + String temp = lf.format(lr); + getLogWriter().println(temp); + } + if (poolManager != null) { + poolManager.setLogWriter(getLogWriter()); + } + } + + // Local methods + void setPoolManager(Context nameCtx, String dataSourceName) throws Exception { + if (t4Logger_.isLoggable(Level.FINER) == true) { + Object p[] = T4LoggingUtilities.makeParams(null, nameCtx, dataSourceName); + t4Logger_.logp(Level.FINER, "TrafT4DataSource", "setPoolManager", "", p); + } + Object pds; + + try { + pds = nameCtx.lookup(dataSourceName); + if (pds instanceof TrafT4ConnectionPoolDataSource) { + poolManager = new TrafT4PooledConnectionManager((TrafT4ConnectionPoolDataSource) pds, getT4LogLevel()); + } + } catch (javax.naming.NameNotFoundException nnfe) { + } + } + + // -------------------------------------------------------- + void setupLogFileHandler() { + try { + if (getT4LogFile() == null) { + setT4LogFile(getT4GlobalLogFile()); + setT4LogFileHandler(getT4GlobalLogFileHandler()); + } else { + if (getT4LogFileHandler() == null) { + String temp = getT4LogFile(); + FileHandler fh1 = new FileHandler(temp); + + Formatter ff1 = new T4LogFormatter(); + + fh1.setFormatter(ff1); + setT4LogFileHandler(fh1); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } // end setupLogFileHandler + + // -------------------------------------------------------- + + /** + * Contructor for the <code>TrafT4DataSource</code> object. + * + * @see #TrafT4DataSource(java.util.Properties) + */ + public TrafT4DataSource() { + super(); + if (getT4LogLevel() != Level.OFF) { + setupLogFileHandler(); + } + if (t4Logger_.isLoggable(Level.FINE) == true) { + Object p[] = T4LoggingUtilities.makeParams(null); + t4Logger_.logp(Level.FINE, "TrafT4DataSource", "<init>", + "Note, this constructor was called before the previous constructor", p); + } + try { + if (getLogWriter() != null) { + LogRecord lr = new LogRecord(Level.FINE, ""); + Object p[] = T4LoggingUtilities.makeParams(null); + lr.setParameters(p); + lr.setSourceClassName("TrafT4DataSource"); + lr.setSourceMethodName("<init>"); + T4LogFormatter lf = new T4LogFormatter(); + String temp = lf.format(lr); + getLogWriter().println(temp); + } + } catch (SQLException se) { + // ignore + } + + } + + /** + * Contructor for the <code>TrafT4DataSource</code> object. + * + * @param info + * Contains all the Type 4 properties in a <code>name, + * value</code> + * pair. + * @see #TrafT4DataSource() + * @see java.util.Properties + */ + public TrafT4DataSource(Properties info) { + super(info); + if (getT4LogLevel() != Level.OFF) { + setupLogFileHandler(); + } + if (t4Logger_.isLoggable(Level.FINE) == true) { + Object p[] = T4LoggingUtilities.makeParams(null); + t4Logger_.logp(Level.FINE, "TrafT4DataSource", "<init>", + "Note, this constructor was called before the previous constructor", p); + } + try { + if (getLogWriter() != null) { + LogRecord lr = new LogRecord(Level.FINE, ""); + Object p[] = T4LoggingUtilities.makeParams(null); + lr.setParameters(p); + lr.setSourceClassName("TrafT4DataSource"); + lr.setSourceMethodName("<init>"); + T4LogFormatter lf = new T4LogFormatter(); + String temp = lf.format(lr); + getLogWriter().println(temp); + } + } catch (SQLException se) { + // ignore + } + } + + /** + * @deprecated + */ + public void setNameType(String nameType) { + } + + /** + * @deprecated + */ + public String getNameType() { + return null; + } + + // fields + TrafT4PooledConnectionManager poolManager; + + public Logger getParentLogger() throws SQLFeatureNotSupportedException { + // TODO Auto-generated method stub + return null; + } + + public Object unwrap(Class iface) throws SQLException { + // TODO Auto-generated method stub + return null; + } + + public boolean isWrapperFor(Class iface) throws SQLException { + // TODO Auto-generated method stub + return false; + } +}
http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/38e49cf7/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4DataSourceFactory.java ---------------------------------------------------------------------- diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4DataSourceFactory.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4DataSourceFactory.java new file mode 100644 index 0000000..a1b3408 --- /dev/null +++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4DataSourceFactory.java @@ -0,0 +1,62 @@ +// @@@ START COPYRIGHT @@@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// +// @@@ END COPYRIGHT @@@ + +package org.trafodion.jdbc.t4; + +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Properties; + +import javax.naming.Context; +import javax.naming.Name; +import javax.naming.RefAddr; +import javax.naming.Reference; + +public class TrafT4DataSourceFactory implements javax.naming.spi.ObjectFactory { + public TrafT4DataSourceFactory() { + } + + public Object getObjectInstance(Object refobj, Name name, Context nameCtx, Hashtable env) throws Exception { + Reference ref = (Reference) refobj; + TrafT4DataSource ds; + String dataSourceName = null; + + if (ref.getClassName().equals("org.trafodion.jdbc.t4.TrafT4DataSource")) { + Properties props = new Properties(); + for (Enumeration enum2 = ref.getAll(); enum2.hasMoreElements();) { + RefAddr tRefAddr = (RefAddr) enum2.nextElement(); + String type = tRefAddr.getType(); + String content = (String) tRefAddr.getContent(); + props.setProperty(type, content); + } + + ds = new TrafT4DataSource(props); + dataSourceName = ds.getDataSourceName(); + + if (dataSourceName != null) { + ds.setPoolManager(nameCtx, dataSourceName); + } + return ds; + } else { + return null; + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/38e49cf7/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4Desc.java ---------------------------------------------------------------------- diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4Desc.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4Desc.java new file mode 100644 index 0000000..65ce6ea --- /dev/null +++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4Desc.java @@ -0,0 +1,542 @@ +// @@@ START COPYRIGHT @@@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// +// @@@ END COPYRIGHT @@@ + +package org.trafodion.jdbc.t4; + +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Types; +import java.util.Locale; + +class TrafT4Desc { + + String getColumnClassName() throws SQLException { + switch (dataType_) { + case Types.SMALLINT: + return "java.lang.Integer"; + case Types.INTEGER: + return "java.lang.Integer"; + case Types.BIGINT: + return "java.lang.Long"; + case Types.REAL: + return "java.lang.Float"; + case Types.FLOAT: + case Types.DOUBLE: + return "java.lang.Double"; + case Types.NUMERIC: + case Types.DECIMAL: + return "java.math.BigDecimal"; + case Types.CHAR: + case Types.VARCHAR: + case Types.LONGVARCHAR: + return "java.lang.String"; + case Types.DATE: + return "java.sql.Date"; + case Types.TIME: + return "java.sql.Time"; + case Types.TIMESTAMP: + return "java.sql.Timestamp"; + case Types.OTHER: + return "java.sql.String"; + case Types.CLOB: + return "java.sql.Clob"; + case Types.BLOB: + return "java.sql.Blob"; + case Types.BIT: + case Types.TINYINT: + default: + return null; + } + } // end getColumnClassName + + // --------------------------------------------------------------- + String getColumnTypeName(Locale locale) throws SQLException { + switch (dataType_) { + case Types.SMALLINT: + return "SMALLINT"; + case Types.INTEGER: + return "INTEGER"; + case Types.BIGINT: + return "BIGINT"; + case Types.REAL: + return "REAL"; + case Types.FLOAT: + return "FLOAT"; + case Types.DOUBLE: + return "DOUBLE PRECISION"; + case Types.NUMERIC: + return "NUMERIC"; + case Types.DECIMAL: + return "DECIMAL"; + case Types.CHAR: + return "CHAR"; + case Types.VARCHAR: + return "VARCHAR"; + case Types.LONGVARCHAR: + return "LONG VARCHAR"; + case Types.DATE: + return "DATE"; + case Types.TIME: + return "TIME"; + case Types.TIMESTAMP: + return "TIMESTAMP"; + case Types.BLOB: + return "BLOB"; + case Types.CLOB: + return "CLOB"; + case Types.OTHER: + if (sqlDataType_ == SQLTYPECODE_INTERVAL) { + return "INTERVAL"; + } else { + return "UNKNOWN"; + } + case Types.BIT: + case Types.TINYINT: + default: + return null; + } + } // end getColumnTypeName + + // --------------------------------------------------------------- + void checkValidNumericConversion(Locale locale) throws SQLException { + switch (dataType_) { + case Types.TINYINT: + case Types.SMALLINT: + case Types.INTEGER: + case Types.BIGINT: + case Types.REAL: + case Types.FLOAT: + case Types.DOUBLE: + case Types.NUMERIC: + case Types.DECIMAL: + case Types.BIT: + case Types.CHAR: + case Types.VARCHAR: + case Types.LONGVARCHAR: + case Types.CLOB: + case Types.BLOB: + break; + default: + System.out.println("Data type is " + dataType_); + throw TrafT4Messages.createSQLException(null, locale, "restricted_data_type", null); + } + return; + } // end checkValidNumericConversion + + // --------------------------------------------------------------- + // Constructors + TrafT4Desc(int dataType, short datetimeCode, int maxLen, short precision, short scale, boolean nullInfo, + String colName, boolean signType, int odbcDataType, short odbcPrecision, int sqlCharset, int odbcCharset, + String catalogName, String schemaName, String tableName, int fsDataType, int intLeadPrec, int paramMode) { + catalogName_ = catalogName; + schemaName_ = schemaName; + tableName_ = tableName; + name_ = colName; + if (nullInfo) { + isNullable_ = ResultSetMetaData.columnNullable; + } else { + isNullable_ = ResultSetMetaData.columnNoNulls; + + } + + sqlDataType_ = dataType; + dataType_ = odbcDataType; + sqlDatetimeCode_ = datetimeCode; + sqlCharset_ = sqlCharset; + odbcCharset_ = odbcCharset; + isSigned_ = signType; + sqlOctetLength_ = maxLen; + scale_ = scale; + sqlPrecision_ = precision; + + // + // Convert ODBC type to equivalent JDBC type when necessary. + // + // From SqlUcode.h + // + // #define SQL_WCHAR (-8) + // #define SQL_WVARCHAR (-9) + // #define SQL_WLONGVARCHAR (-10) + // + if (odbcDataType == -8) { + + // ODBC's SQL_WCHAR becomes a Types.CHAR + dataType_ = Types.CHAR; + } else if (odbcDataType == -9) { + + // ODBC's SQL_WVARCHAR becomes a Types.VARCHAR + dataType_ = Types.VARCHAR; + } else if (odbcDataType == -10) { + + // ODBC's SQL_WLONGVARCHAR becomes a Types.LONGVARCHAR + dataType_ = Types.LONGVARCHAR; + + } + if (sqlDataType_ == InterfaceResultSet.SQLTYPECODE_DATETIME) // 9 + { + switch (dataType_) { // ODBC conversion to ODBC2.0 + case 9: // ODBC2 Date + + // check the datetime code and set appropriately + switch (sqlDatetimeCode_) { + case SQLDTCODE_YEAR: + case SQLDTCODE_YEAR_TO_MONTH: + case SQLDTCODE_MONTH: + case SQLDTCODE_MONTH_TO_DAY: + case SQLDTCODE_DAY: + dataType_ = Types.OTHER; + precision_ = odbcPrecision; + displaySize_ = maxLen; + sqlOctetLength_ = maxLen; + break; + default: + dataType_ = Types.DATE; + break; + } + break; + case 10: // ODBC2 TIME + switch (sqlDatetimeCode_) { + case SQLDTCODE_HOUR: + case SQLDTCODE_HOUR_TO_MINUTE: + case SQLDTCODE_MINUTE: + case SQLDTCODE_MINUTE_TO_SECOND: + case SQLDTCODE_SECOND: + dataType_ = Types.OTHER; + precision_ = odbcPrecision; + displaySize_ = maxLen; + sqlOctetLength_ = maxLen; + break; + default: + dataType_ = Types.TIME; + break; + } + break; + case 11: // ODBC2 TIMESTAMP + switch (sqlDatetimeCode_) { + case SQLDTCODE_YEAR_TO_HOUR: + case SQLDTCODE_YEAR_TO_MINUTE: + case SQLDTCODE_MONTH_TO_HOUR: + case SQLDTCODE_MONTH_TO_MINUTE: + case SQLDTCODE_MONTH_TO_SECOND: + // case SQLDTCODE_MONTH_TO_FRACTION: + case SQLDTCODE_DAY_TO_HOUR: + case SQLDTCODE_DAY_TO_MINUTE: + case SQLDTCODE_DAY_TO_SECOND: + // case SQLDTCODE_DAY_TO_FRACTION: + case SQLDTCODE_HOUR_TO_FRACTION: // note: Database + // maps to TIME(6) + // NCS maps to TIMESTAMP + case SQLDTCODE_MINUTE_TO_FRACTION: + case SQLDTCODE_SECOND_TO_FRACTION: + dataType_ = Types.OTHER; + precision_ = odbcPrecision; + displaySize_ = maxLen; + sqlOctetLength_ = maxLen; + break; + default: + dataType_ = Types.TIMESTAMP; + break; + } + break; + default: + dataType_ = Types.TIMESTAMP; + break; + } + } + + switch (dataType_) { + case Types.NUMERIC: + case Types.DECIMAL: + precision_ = odbcPrecision; + displaySize_ = precision_ + 2; // 1 for dot and 1 for sign + // if (scale != 0) // ODBC2.0 + // isCurrency_ = true; + break; + case Types.SMALLINT: + precision_ = odbcPrecision; + if (isSigned_) { + displaySize_ = 6; + } else { + dataType_ = Types.INTEGER; + displaySize_ = 5; + } + break; + case Types.INTEGER: + precision_ = odbcPrecision; + if (isSigned_) { + displaySize_ = 11; + } else { + dataType_ = Types.BIGINT; + displaySize_ = 10; + } + break; + case Types.TINYINT: + precision_ = odbcPrecision; + if (isSigned_) { + displaySize_ = 4; + } else { + displaySize_ = 3; + } + break; + case Types.BIGINT: + precision_ = odbcPrecision; + if (isSigned_) { + displaySize_ = 20; + } else { + displaySize_ = 19; + } + break; + case Types.REAL: + precision_ = odbcPrecision; + displaySize_ = 15; + break; + case Types.DOUBLE: + case Types.FLOAT: + precision_ = odbcPrecision; + displaySize_ = 24; + break; + case Types.DATE: + sqlOctetLength_ = maxLen + 3; + displaySize_ = 10; + precision_ = 10; // ODBC2.0 + break; + case Types.TIME: + sqlOctetLength_ = maxLen + 3; + displaySize_ = (precision == 0)?8: precision + 9; + precision_ = 8; // ODBC2.0 + break; + case Types.TIMESTAMP: + sqlOctetLength_ = maxLen + 3; + precision_ = odbcPrecision; + displaySize_ = precision_; + if (sqlDatetimeCode_ > 3) // if it is more than 3, it is one of + // SQL/MP Datetime columns + { + // like YEAR, YEAR TO MONTH, YEAR TO DAY ...see dfs2rec.h + dataType_ = Types.OTHER; + } + break; + case Types.CHAR: + + // sqlOctetLength_ = maxLen+1; + sqlOctetLength_ = maxLen; + displaySize_ = maxLen; + precision_ = maxLen; // ODBC2.0 + break; + case Types.VARCHAR: + case Types.LONGVARCHAR: + case Types.BLOB: + case Types.CLOB: + boolean shortLength = maxLen < Math.pow(2, 15); + int dataOffset = ((shortLength) ? 2 : 4); + if (sqlDataType_ == SQLTYPECODE_VARCHAR) { + sqlOctetLength_ = maxLen + 1; + } else { + sqlOctetLength_ = maxLen + dataOffset + 1; + } + displaySize_ = maxLen; + precision_ = maxLen; // ODBC2.0 + break; + default: + if (sqlDataType_ == SQLTYPECODE_INTERVAL) { + dataType_ = Types.OTHER; + precision_ = odbcPrecision; + displaySize_ = maxLen; // Make sure maxLen returns the right + // display size for interval + // sqlOctetLength_ = maxLen+3; + // Swastik - commented above line 02/10/2005 for Interval Data + // Type support + // 3 was added earlier because interval datatype was handled in + // the same + // way as varchar and varchar-long were handled. Since we are + // separating it + // we don't need to add the additional 3 + sqlOctetLength_ = maxLen; + } + break; + } + if (sqlDataType_ == SQLTYPECODE_CHAR || sqlDataType_ == SQLTYPECODE_VARCHAR + || sqlDataType_ == SQLTYPECODE_BLOB || sqlDataType_ == SQLTYPECODE_CLOB + || sqlDataType_ == SQLTYPECODE_VARCHAR_LONG || sqlDataType_ == SQLTYPECODE_VARCHAR_WITH_LENGTH) { + isCaseSensitive_ = true; + } + isSearchable_ = true; + fsDataType_ = fsDataType; + intLeadPrec_ = intLeadPrec; + paramMode_ = paramMode; + } // end TrafT4Desc + + // --------------------------------------------------------------- + // Constructors + + TrafT4Desc( + int noNullValue // Descriptor2 only + , + int nullValue // Descriptor2 only + , + int version // Descriptor2 only + , int dataType, short datetimeCode, int maxLen, short precision, short scale, boolean nullInfo, + boolean signType // same as signe + , int odbcDataType, int odbcPrecision, int sqlCharset, int odbcCharset, String colName // same + // as + // colHeadingNm + , String tableName, String catalogName, String schemaName, String headingName // Descriptor2 + // only + , int intLeadPrec, int paramMode, int fsDataType // fsDataType + // seems to be + // the same as + // dataType (see + // old + // descriptor) + , int rowLength) { + + // + // Call the old constructor to set the items that are + // in both the old descriptor and the new descriptor. + // + this(dataType, datetimeCode, maxLen, precision, scale, nullInfo, colName, signType, odbcDataType, + (short) odbcPrecision, sqlCharset, odbcCharset, catalogName, schemaName, tableName, fsDataType, + intLeadPrec, paramMode); + // + // Set the items specific to the new descriptor. + // + noNullValue_ = noNullValue; + nullValue_ = nullValue; + version_ = version; + headingName_ = headingName; + rowLength_ = rowLength; + + maxLen_ = maxLen; + + } // end TrafT4Desc + + // --------------------------------------------------------------- + /*************************************************************************** + * Returns encoding type for character data types from Database + * COLS table. + */ + String getCharacterSetName() throws SQLException { + switch (dataType_) { + case Types.CHAR: + case Types.VARCHAR: + case Types.LONGVARCHAR: + case Types.BLOB: + case Types.CLOB: + return (String) InterfaceUtilities.getCharsetName(sqlCharset_); + default: + return null; + } + } + + // --------------------------------------------------------------- + // Constants + public static final int SQLTYPECODE_CHAR = 1; + public static final int SQLTYPECODE_VARCHAR = 12; + public static final int SQLTYPECODE_VARCHAR_LONG = -1; + public static final int SQLTYPECODE_INTERVAL = 10; + public static final int SQLTYPECODE_VARCHAR_WITH_LENGTH = -601; + public static final int SQLTYPECODE_BLOB = -602; + public static final int SQLTYPECODE_CLOB = -603; + public static final int SQLTYPECODE_SMALLINT = 5; + public static final int SQLTYPECODE_INTEGER = 4; + + // datetime codes taken from NCS - File ....\....\...\Common\DrvrSrvr.h + public static final int SQLDTCODE_YEAR = 4; + public static final int SQLDTCODE_YEAR_TO_MONTH = 5; + // public static final int SQLDTCODE_YEAR_TO_DAY 1 //Database + // DATE + public static final int SQLDTCODE_YEAR_TO_HOUR = 7; // ODBC TIMESTAMP(0) + public static final int SQLDTCODE_YEAR_TO_MINUTE = 8; + // public static final int SQLDTCODE_YEAR_TO_SECOND 3 // + // DatabaseTIMESTAMP(0) + // public static final int SQLDTCODE_YEAR_TO_FRACTION 3 // + // Database TIMESTAMP(1 - 5) + public static final int SQLDTCODE_MONTH = 10; + public static final int SQLDTCODE_MONTH_TO_DAY = 11; + public static final int SQLDTCODE_MONTH_TO_HOUR = 12; + public static final int SQLDTCODE_MONTH_TO_MINUTE = 13; + public static final int SQLDTCODE_MONTH_TO_SECOND = 14; + public static final int SQLDTCODE_MONTH_TO_FRACTION = 14; + public static final int SQLDTCODE_DAY = 15; + public static final int SQLDTCODE_DAY_TO_HOUR = 16; + public static final int SQLDTCODE_DAY_TO_MINUTE = 17; + public static final int SQLDTCODE_DAY_TO_SECOND = 18; + public static final int SQLDTCODE_DAY_TO_FRACTION = 18; + public static final int SQLDTCODE_HOUR = 19; + public static final int SQLDTCODE_HOUR_TO_MINUTE = 20; + // define SQLDTCODE_HOUR_TO_SECOND 2 //Database TIME(0) --> NCS + // Maps this to TIME + public static final int SQLDTCODE_HOUR_TO_FRACTION = 2; // Database TIME(1 - + // 6) // MXCI Maps + // this to TIMESTAMP + public static final int SQLDTCODE_MINUTE = 22; + public static final int SQLDTCODE_MINUTE_TO_SECOND = 23; + public static final int SQLDTCODE_MINUTE_TO_FRACTION = 23; + public static final int SQLDTCODE_SECOND = 24; + public static final int SQLDTCODE_SECOND_TO_FRACTION = 24; + public static final int SQLDTCODE_FRACTION_TO_FRACTION = 29; + + // fields + int sqlCharset_; + int odbcCharset_; + int sqlDataType_; + int dataType_; + short sqlPrecision_; + short sqlDatetimeCode_; + int sqlOctetLength_; + int isNullable_; + String name_; + short scale_; + int precision_; + boolean isSigned_; + boolean isCurrency_; + boolean isCaseSensitive_; + String catalogName_; + String schemaName_; + String tableName_; + int fsDataType_; + int intLeadPrec_; + int paramMode_; + int paramIndex_; + int paramPos_; + + String columnClassName_; + int displaySize_; + // fields which are not pouplated now + String columnLabel_; + boolean isAutoIncrement_; + boolean isSearchable_; + + boolean isValueSet_; // To denote if setXXX method is called for this + // parameter + // String paramValue_; // Contains the value of output parameter value + Object paramValue_; // Contains the value of output parameter value + + int noNullValue_; // Descriptor2 only + int nullValue_; // Descriptor2 only + int version_; // Descriptor2 only + + String headingName_; // Descriptor2 only + + int rowLength_; + int maxLen_; + +} // end class TrafT4Desc http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/38e49cf7/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4Exception.java ---------------------------------------------------------------------- diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4Exception.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4Exception.java new file mode 100644 index 0000000..0406195 --- /dev/null +++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4Exception.java @@ -0,0 +1,38 @@ +// @@@ START COPYRIGHT @@@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// +// @@@ END COPYRIGHT @@@ + +package org.trafodion.jdbc.t4; + +import java.sql.SQLException; + +class TrafT4Exception extends SQLException { + protected String messageId; + + public TrafT4Exception(String reason, String SQLState, int vendorCode, String msgId) { + super(reason, SQLState, vendorCode); + if (msgId == null) { + messageId = ""; + } else { + messageId = msgId; + } + } + +} // end class TrafT4Exception http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/38e49cf7/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4Handle.java ---------------------------------------------------------------------- diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4Handle.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4Handle.java new file mode 100644 index 0000000..9333081 --- /dev/null +++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4Handle.java @@ -0,0 +1,84 @@ +// @@@ START COPYRIGHT @@@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// +// @@@ END COPYRIGHT @@@ + +package org.trafodion.jdbc.t4; + +import java.sql.SQLException; +import java.sql.SQLWarning; + +public abstract class TrafT4Handle { + SQLWarning sqlWarning_; + + public void clearWarnings() throws SQLException { + sqlWarning_ = null; + } + + public SQLWarning getWarnings() throws SQLException { + return sqlWarning_; + } + + void setSQLWarning(T4Properties t4props, String messageId, Object[] messageArguments) { + SQLWarning sqlWarningLeaf = TrafT4Messages.createSQLWarning(t4props, messageId, messageArguments); + if (sqlWarning_ == null) { + sqlWarning_ = sqlWarningLeaf; + } else { + sqlWarning_.setNextWarning(sqlWarningLeaf); + } + } + + // Method used by JNI layer to set the warning + void setSqlWarning(SQLWarning sqlWarning) { + if (sqlWarning_ == null) { + sqlWarning_ = sqlWarning; + } else { + sqlWarning_.setNextWarning(sqlWarning); + } + } + + // Method added to check if the connection had any errors + // This calls the abstract method closeErroredConnection() + //returns true if a connection error occured + boolean performConnectionErrorChecks(SQLException se) { + if (se instanceof TrafT4Exception) { + TrafT4Exception sqlmx_e = (TrafT4Exception) se; + if (sqlmx_e.messageId.equals(ERROR_SOCKET_WRITE_ERROR) || sqlmx_e.messageId.equals(ERROR_SOCKET_READ_ERROR) + || sqlmx_e.messageId.equals(ERROR_SOCKET_IS_CLOSED_ERROR) + || sqlmx_e.messageId.equals(ERROR_INVALID_CONNECTION) || sqlmx_e.messageId.equals(ERROR_IDS_08_S01) + || sqlmx_e.messageId.equals(IDS_S1_T00) + || sqlmx_e.messageId.equals(ERROR_SOCKET_OPEN)) { + closeErroredConnection(sqlmx_e); + return true; + } + } + + return false; + } + + abstract void closeErroredConnection(TrafT4Exception se); + + static final String ERROR_IDS_08_S01 = new String("ids_08_s01"); + static final String ERROR_INVALID_CONNECTION = new String("invalid_connection"); + static final String ERROR_SOCKET_WRITE_ERROR = new String("socket_write_error"); + static final String ERROR_SOCKET_READ_ERROR = new String("socket_read_error"); + static final String ERROR_SOCKET_IS_CLOSED_ERROR = new String("socket_is_closed_error"); + static final String IDS_S1_T00 = new String("ids_s1_t00"); + static final String ERROR_SOCKET_OPEN = new String("socket_open_error"); +} http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/38e49cf7/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4Messages.java ---------------------------------------------------------------------- diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4Messages.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4Messages.java new file mode 100644 index 0000000..312ce27 --- /dev/null +++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4Messages.java @@ -0,0 +1,324 @@ +// @@@ START COPYRIGHT @@@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// +// @@@ END COPYRIGHT @@@ + +package org.trafodion.jdbc.t4; + +import java.sql.SQLWarning; +import java.text.MessageFormat; +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.PropertyResourceBundle; +import java.util.ResourceBundle; +import java.util.logging.Level; +import java.util.logging.Logger; + +class TrafT4Messages { + static Logger getMessageLogger(T4Properties t4props) { + return (t4props != null) ? t4props.t4Logger_ : T4Properties.t4GlobalLogger; + } + + static SQLWarning createSQLWarning(T4Properties t4props, String messageId, Object[] messageArguments) { + Logger log = getMessageLogger(t4props); + + if (log != null && log.isLoggable(Level.WARNING)) { + Object p[] = T4LoggingUtilities.makeParams(t4props, messageId, messageArguments); + log.logp(Level.WARNING, "TrafT4Messages", "createSQLWarning", "", p); + } + + Locale currentLocale = t4props == null ? null : t4props.getLocale(); + currentLocale = currentLocale == null ? Locale.getDefault() : currentLocale; + + int sqlcode = 1; + SQLWarning ret = null; + + try { + PropertyResourceBundle messageBundle = (PropertyResourceBundle) ResourceBundle.getBundle("T4Messages", + currentLocale); + + MessageFormat formatter = new MessageFormat(""); + formatter.setLocale(currentLocale); + formatter.applyPattern(messageBundle.getString(messageId + "_msg")); + + String message = formatter.format(messageArguments); + String sqlState = messageBundle.getString(messageId + "_sqlstate"); + String sqlcodeStr = messageBundle.getString(messageId + "_sqlcode"); + + if (sqlcodeStr != null) { + try { + sqlcode = Integer.parseInt(sqlcodeStr); + } catch (NumberFormatException e1) { + // use 1 as default + } + } + + ret = new SQLWarning(message, sqlState, sqlcode); + } catch (MissingResourceException e) { + // If the resource bundle is not found, concatenate the messageId + // and the parameters + String message; + int i = 0; + + message = "The message id: " + messageId; + if (messageArguments != null) { + message = message.concat(" With parameters: "); + while (true) { + message = message.concat(messageArguments[i++].toString()); + if (i >= messageArguments.length) { + break; + } else { + message = message.concat(","); + } + } + } // end if + + ret = new SQLWarning(message, "01000", 1); + } + + return ret; + } + + static void setSQLWarning(T4Properties t4props, TrafT4Handle handle, SQLWarningOrError[] we1) { + Logger log = getMessageLogger(t4props); + + int curErrorNo; + SQLWarning sqlWarningLeaf; + + if (we1.length == 0) { + handle.setSqlWarning(null); + return; + } + + for (curErrorNo = 0; curErrorNo < we1.length; curErrorNo++) { + if (log != null && log.isLoggable(Level.WARNING)) { + Object p[] = new Object[] { t4props, "Text: " + we1[curErrorNo].text, + "SQLState: " + we1[curErrorNo].sqlState, "SQLCode: " + we1[curErrorNo].sqlCode }; + log.logp(Level.WARNING, "TrafT4Messages", "setSQLWarning", "", p); + } + + sqlWarningLeaf = new SQLWarning(we1[curErrorNo].text, we1[curErrorNo].sqlState, we1[curErrorNo].sqlCode); + handle.setSqlWarning(sqlWarningLeaf); + } // end for + return; + } + + static void setSQLWarning(T4Properties t4props, TrafT4Handle handle, ERROR_DESC_LIST_def sqlWarning) { + Logger log = getMessageLogger(t4props); + + int curErrorNo; + ERROR_DESC_def error_desc_def[]; + SQLWarning sqlWarningLeaf; + + if (sqlWarning.length == 0) { + handle.setSqlWarning(null); + return; + } + + error_desc_def = sqlWarning.buffer; + for (curErrorNo = 0; curErrorNo < sqlWarning.length; curErrorNo++) { + if (log != null && log.isLoggable(Level.WARNING)) { + Object p[] = new Object[] { t4props, "Text: " + error_desc_def[curErrorNo].errorText, + "SQLState: " + error_desc_def[curErrorNo].sqlstate, + "SQLCode: " + error_desc_def[curErrorNo].sqlcode }; + log.logp(Level.WARNING, "TrafT4Messages", "setSQLWarning", "", p); + } + + sqlWarningLeaf = new SQLWarning(error_desc_def[curErrorNo].errorText, error_desc_def[curErrorNo].sqlstate, + error_desc_def[curErrorNo].sqlcode); + handle.setSqlWarning(sqlWarningLeaf); + } + return; + } // end setSQLWarning + + // ------------------------------------------------------------------------------------------------ + static void throwSQLException(T4Properties t4props, ERROR_DESC_LIST_def SQLError) throws TrafT4Exception { + Logger log = getMessageLogger(t4props); + Locale locale = (t4props != null) ? t4props.getLocale() : Locale.getDefault(); + + TrafT4Exception sqlException = null; + TrafT4Exception sqlExceptionHead = null; + int curErrorNo; + + if (SQLError.length == 0) { + throw createSQLException(t4props, locale, "No messages in the Error description", null); + } + + for (curErrorNo = 0; curErrorNo < SQLError.length; curErrorNo++) { + if (log != null && log.isLoggable(Level.SEVERE)) { + Object p[] = new Object[] { t4props, "Text: " + SQLError.buffer[curErrorNo].errorText, + "SQLState: " + SQLError.buffer[curErrorNo].sqlstate, + "SQLCode: " + SQLError.buffer[curErrorNo].sqlcode }; + log.logp(Level.SEVERE, "TrafT4Messages", "throwSQLException", "", p); + } + + if (SQLError.buffer[curErrorNo].errorCodeType == TRANSPORT.ESTIMATEDCOSTRGERRWARN) { + // + // NCS said it was an SQL error, but it really wasn't it was a + // NCS resource governing error + // + sqlException = TrafT4Messages.createSQLException(t4props, locale, "resource_governing", null); + } else { + sqlException = new TrafT4Exception(SQLError.buffer[curErrorNo].errorText, + SQLError.buffer[curErrorNo].sqlstate, SQLError.buffer[curErrorNo].sqlcode, null); + } + if (curErrorNo == 0) { + sqlExceptionHead = sqlException; + } else { + sqlExceptionHead.setNextException(sqlException); + } + } + + throw sqlExceptionHead; + } + + // ------------------------------------------------------------------------------------------------ + static void throwSQLException(T4Properties t4props, SQLWarningOrError[] we1) throws TrafT4Exception { + Logger log = getMessageLogger(t4props); + Locale locale = (t4props != null) ? t4props.getLocale() : Locale.getDefault(); + + TrafT4Exception sqlException = null; + TrafT4Exception sqlExceptionHead = null; + int curErrorNo; + + if (we1.length == 0) { + throw createSQLException(t4props, locale, "No messages in the Error description", null); + } + + for (curErrorNo = 0; curErrorNo < we1.length; curErrorNo++) { + if (log != null && log.isLoggable(Level.SEVERE)) { + Object p[] = new Object[] { t4props, "Text: " + we1[curErrorNo].text, + "SQLState: " + we1[curErrorNo].sqlState, "SQLCode: " + we1[curErrorNo].sqlCode }; + log.logp(Level.SEVERE, "TrafT4Messages", "throwSQLException", "", p); + } + + sqlException = new TrafT4Exception(we1[curErrorNo].text, we1[curErrorNo].sqlState, we1[curErrorNo].sqlCode, + null); + if (curErrorNo == 0) { + sqlExceptionHead = sqlException; + } else { + sqlExceptionHead.setNextException(sqlException); + } + } // end for + + throw sqlExceptionHead; + } // end throwSQLException + + // ------------------------------------------------------------------------------------------------ + static TrafT4Exception createSQLException(T4Properties t4props, Locale msgLocale, String messageId, Object mA1, + Object mA2) { + + Object[] mAs = new Object[2]; + + mAs[0] = mA1; + mAs[1] = mA2; + + return createSQLException(t4props, msgLocale, messageId, mAs); + + } // end createSQLException + + // ------------------------------------------------------------------------------------------------ + static TrafT4Exception createSQLException(T4Properties t4props, Locale msgLocale, String messageId, + Object messageArgument) { + Object[] mAs = new Object[1]; + + mAs[0] = messageArgument; + + return createSQLException(t4props, msgLocale, messageId, mAs); + + } // end createSQLException + + // ------------------------------------------------------------------------------------------------ + static TrafT4Exception createSQLException(T4Properties t4props, Locale msgLocale, String messageId, + Object[] messageArguments) { + Logger log = getMessageLogger(t4props); + + if (log != null && log.isLoggable(Level.SEVERE)) { + Object p[] = T4LoggingUtilities.makeParams(t4props, messageId, messageArguments); + log.logp(Level.SEVERE, "TrafT4Messages", "createSQLException", "", p); + } + + Locale currentLocale = t4props == null ? null : t4props.getLocale(); + currentLocale = currentLocale == null ? Locale.getDefault(): currentLocale; + + int sqlcode; + try { + PropertyResourceBundle messageBundle = (PropertyResourceBundle) ResourceBundle.getBundle("T4Messages", + currentLocale); + + MessageFormat formatter = new MessageFormat(""); + formatter.setLocale(currentLocale); + formatter.applyPattern(messageBundle.getString(messageId + "_msg")); + + String message = formatter.format(messageArguments); + String sqlState = messageBundle.getString(messageId + "_sqlstate"); + String sqlcodeStr = messageBundle.getString(messageId + "_sqlcode"); + + if (sqlcodeStr != null) { + try { + sqlcode = Integer.parseInt(sqlcodeStr); + sqlcode = -sqlcode; + } catch (NumberFormatException e1) { + sqlcode = -1; + } + } else { + sqlcode = -1; + + } + return new TrafT4Exception(message, sqlState, sqlcode, messageId); + } catch (MissingResourceException e) { + // If the resource bundle is not found, concatenate the messageId + // and the parameters + String message; + int i = 0; + + message = "The message id: " + messageId; + if (messageArguments != null) { + message = message.concat(" With parameters: "); + while (true) { + message = message.concat(messageArguments[i++] + ""); + if (i >= messageArguments.length) { + break; + } else { + message = message.concat(","); + } + } + } // end if + + return new TrafT4Exception(message, "HY000", -1, messageId); + } // end catch + } // end createSQLException + + // ------------------------------------------------------------------------------------------------ + static void throwUnsupportedFeatureException(T4Properties t4props, Locale locale, String s) throws TrafT4Exception { + Object[] messageArguments = new Object[1]; + + messageArguments[0] = s; + throw TrafT4Messages.createSQLException(t4props, locale, "unsupported_feature", messageArguments); + } // end throwUnsupportedFeatureException + + // ------------------------------------------------------------------------------------------------ + static void throwDeprecatedMethodException(T4Properties t4props, Locale locale, String s) throws TrafT4Exception { + Object[] messageArguments = new Object[1]; + + messageArguments[0] = s; + throw TrafT4Messages.createSQLException(t4props, locale, "deprecated_method", messageArguments); + } // end throwDeprecatedMethodException + +} // end class TrafT4Messages http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/38e49cf7/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4ParameterMetaData.java ---------------------------------------------------------------------- diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4ParameterMetaData.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4ParameterMetaData.java new file mode 100644 index 0000000..461d144 --- /dev/null +++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4ParameterMetaData.java @@ -0,0 +1,243 @@ +// @@@ START COPYRIGHT @@@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// +// @@@ END COPYRIGHT @@@ + +package org.trafodion.jdbc.t4; + +import java.sql.SQLException; +import java.util.logging.Level; + +public class TrafT4ParameterMetaData implements java.sql.ParameterMetaData { + + public String getParameterClassName(int param) throws SQLException { + if (param > inputDesc.length) { + throw TrafT4Messages.createSQLException(props, props.getLocale(), "invalid_desc_index", null); + } + return inputDesc[param - 1].getColumnClassName(); + } + + public int getParameterCount() throws SQLException { + return inputDesc.length; + } + + public int getParameterMode(int param) throws SQLException { + if (param > inputDesc.length) { + throw TrafT4Messages.createSQLException(props, props.getLocale(), "invalid_desc_index", null); + } + return inputDesc[param - 1].paramMode_; + } + + public int getParameterType(int param) throws SQLException { + if (param > inputDesc.length) { + throw TrafT4Messages.createSQLException(props, props.getLocale(), "invalid_desc_index", null); + } + return inputDesc[param - 1].dataType_; + } + + public String getParameterTypeName(int param) throws SQLException { + if (param > inputDesc.length) { + throw TrafT4Messages.createSQLException(props, props.getLocale(), "invalid_desc_index", null); + } + + return inputDesc[param - 1].getColumnTypeName(props.getLocale()); + } + + public int getPrecision(int param) throws SQLException { + if (param > inputDesc.length) { + throw TrafT4Messages.createSQLException(props, props.getLocale(), "invalid_desc_index", null); + } + + return inputDesc[param - 1].precision_; + } + + public int getScale(int param) throws SQLException { + if (param > inputDesc.length) { + throw TrafT4Messages.createSQLException(props, props.getLocale(), "invalid_desc_index", null); + } + + return inputDesc[param - 1].scale_; + } + + public int isNullable(int param) throws SQLException { + if (param > inputDesc.length) { + throw TrafT4Messages.createSQLException(props, props.getLocale(), "invalid_desc_index", null); + } + + return inputDesc[param - 1].isNullable_; + } + + public boolean isSigned(int param) throws SQLException { + if (param > inputDesc.length) { + throw TrafT4Messages.createSQLException(props, props.getLocale(), "invalid_desc_index", null); + } + return inputDesc[param - 1].isSigned_; + } + + // //////////////////////// + // begin custom accessors// + // //////////////////////// + public int getRowLength() throws SQLException { + // this is the same for all params + // only if we have no input params will we throw an error + if (inputDesc.length == 0) { + throw TrafT4Messages.createSQLException(props, props.getLocale(), "invalid_desc_index", null); + } + + return inputDesc[0].rowLength_; + } + + public int getDisplaySize(int param) throws SQLException { + if (param > inputDesc.length) { + throw TrafT4Messages.createSQLException(props, props.getLocale(), "invalid_desc_index", null); + } + + return inputDesc[param - 1].displaySize_; + } + + public int getFSDataType(int param) throws SQLException { + if (param > inputDesc.length) { + throw TrafT4Messages.createSQLException(props, props.getLocale(), "invalid_desc_index", null); + } + + return inputDesc[param - 1].fsDataType_; + } + + public int getMaxLength(int param) throws SQLException { + if (param > inputDesc.length) { + throw TrafT4Messages.createSQLException(props, props.getLocale(), "invalid_desc_index", null); + } + + return inputDesc[param - 1].maxLen_; + } + + public int getNoNullOffset(int param) throws SQLException { + if (param > inputDesc.length) { + throw TrafT4Messages.createSQLException(props, props.getLocale(), "invalid_desc_index", null); + } + + return inputDesc[param - 1].noNullValue_; + } + + public int getNullOffset(int param) throws SQLException { + if (param > inputDesc.length) { + throw TrafT4Messages.createSQLException(props, props.getLocale(), "invalid_desc_index", null); + } + + return inputDesc[param - 1].nullValue_; + } + + public int getOdbcCharset(int param) throws SQLException { + if (param > inputDesc.length) { + throw TrafT4Messages.createSQLException(props, props.getLocale(), "invalid_desc_index", null); + } + + return inputDesc[param - 1].odbcCharset_; + } + + public int getSqlCharset(int param) throws SQLException { + if (param > inputDesc.length) { + throw TrafT4Messages.createSQLException(props, props.getLocale(), "invalid_desc_index", null); + } + + return inputDesc[param - 1].sqlCharset_; + } + + public int getSqlDataType(int param) throws SQLException { + if (param > inputDesc.length) { + throw TrafT4Messages.createSQLException(props, props.getLocale(), "invalid_desc_index", null); + } + + return inputDesc[param - 1].sqlDataType_; + } + + public int getSqlDatetimeCode(int param) throws SQLException { + if (param > inputDesc.length) { + throw TrafT4Messages.createSQLException(props, props.getLocale(), "invalid_desc_index", null); + } + + return inputDesc[param - 1].sqlDatetimeCode_; + } + + public int getSqlOctetLength(int param) throws SQLException { + if (param > inputDesc.length) { + throw TrafT4Messages.createSQLException(props, props.getLocale(), "invalid_desc_index", null); + } + + return inputDesc[param - 1].sqlOctetLength_; + } + + public int getSqlPrecision(int param) throws SQLException { + if (param > inputDesc.length) { + throw TrafT4Messages.createSQLException(props, props.getLocale(), "invalid_desc_index", null); + } + + return inputDesc[param - 1].sqlPrecision_; + } + + // ///////////////////////////////// + // these are legacy names...do not remove these yet even though they are + // duplicate + // i will depricate these before 2.3 release + // /////////////////////////////// + + /** + * @deprecated + */ + public int getSqlTypeCode(int param) throws SQLException { + if (param > inputDesc.length) { + throw TrafT4Messages.createSQLException(props, props.getLocale(), "invalid_desc_index", null); + } + + return inputDesc[param - 1].dataType_; + } + + /** + * @deprecated + */ + public int getSqlLength(int param) throws SQLException { + if (param > inputDesc.length) { + throw TrafT4Messages.createSQLException(props, props.getLocale(), "invalid_desc_index", null); + } + + return inputDesc[param - 1].maxLen_; + } + + TrafT4ParameterMetaData(TrafT4PreparedStatement stmt, TrafT4Desc[] inputDesc) { + this.props = stmt.connection_.props_; + this.inputDesc = inputDesc; + + if (props.t4Logger_.isLoggable(Level.FINE) == true) { + Object p[] = T4LoggingUtilities.makeParams(stmt.connection_.props_, stmt, inputDesc); + stmt.connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4ParameterMetaData", "", "", p); + } + } + + T4Properties props; + TrafT4Desc[] inputDesc; + public Object unwrap(Class iface) throws SQLException { + // TODO Auto-generated method stub + return null; + } + + public boolean isWrapperFor(Class iface) throws SQLException { + // TODO Auto-generated method stub + return false; + } +} http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/38e49cf7/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4PooledConnection.java ---------------------------------------------------------------------- diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4PooledConnection.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4PooledConnection.java new file mode 100644 index 0000000..edacd1e --- /dev/null +++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4PooledConnection.java @@ -0,0 +1,238 @@ +// @@@ START COPYRIGHT @@@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// +// @@@ END COPYRIGHT @@@ + +package org.trafodion.jdbc.t4; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.LinkedList; +import java.util.Locale; +import java.util.logging.Level; +import java.util.logging.LogRecord; + +import javax.sql.ConnectionEvent; +import javax.sql.ConnectionEventListener; +import javax.sql.StatementEventListener; + +public class TrafT4PooledConnection implements javax.sql.PooledConnection { + + public void addConnectionEventListener(ConnectionEventListener listener) { + try { + if (connection_ != null && connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) { + Object p[] = T4LoggingUtilities.makeParams(connection_.props_, listener); + connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PooledConnecton", "addConnectionEventListener", "", + p); + } + if (connection_ != null && connection_.props_.getLogWriter() != null) { + LogRecord lr = new LogRecord(Level.FINE, ""); + Object p[] = T4LoggingUtilities.makeParams(connection_.props_, listener); + lr.setParameters(p); + lr.setSourceClassName("TrafT4PooledConnection"); + lr.setSourceMethodName("addConnectionEventListener"); + T4LogFormatter lf = new T4LogFormatter(); + String temp = lf.format(lr); + connection_.props_.getLogWriter().println(temp); + } + } catch (SQLException se) { + // ignore + } + if (isClosed_ || connection_ == null) { + return; + } + listenerList_.add(listener); + } + + public void close() throws SQLException { + if (connection_ != null && connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) { + Object p[] = T4LoggingUtilities.makeParams(connection_.props_); + connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PooledConnecton", "close", "", p); + } + if (connection_ != null && connection_.props_.getLogWriter() != null) { + LogRecord lr = new LogRecord(Level.FINE, ""); + Object p[] = T4LoggingUtilities.makeParams(connection_.props_); + lr.setParameters(p); + lr.setSourceClassName("TrafT4PooledConnection"); + lr.setSourceMethodName("close"); + T4LogFormatter lf = new T4LogFormatter(); + String temp = lf.format(lr); + connection_.props_.getLogWriter().println(temp); + } + + //3196 - NDCS transaction for SPJ + if (connection_.ic_.suspendRequest_) { + connection_.suspendUDRTransaction(); + } + + if (isClosed_) { + return; + } + connection_.close(true, true); + } + + public Connection getConnection() throws SQLException { + if (connection_ != null && connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) { + Object p[] = T4LoggingUtilities.makeParams(connection_.props_); + connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PooledConnecton", "getConnection", "", p); + } + if (connection_ != null && connection_.props_.getLogWriter() != null) { + LogRecord lr = new LogRecord(Level.FINE, ""); + Object p[] = T4LoggingUtilities.makeParams(connection_.props_); + lr.setParameters(p); + lr.setSourceClassName("TrafT4PooledConnection"); + lr.setSourceMethodName("getConnection"); + T4LogFormatter lf = new T4LogFormatter(); + String temp = lf.format(lr); + connection_.props_.getLogWriter().println(temp); + } + if (isClosed_ || connection_ == null) { + throw TrafT4Messages.createSQLException(connection_.props_, locale_, "invalid_connection", null); + } + if (LogicalConnectionInUse_) { + connection_.close(false, false); + } + LogicalConnectionInUse_ = true; + connection_.reuse(); + return connection_; + } + + public void removeConnectionEventListener(ConnectionEventListener listener) { + try { + if (connection_ != null && connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) { + Object p[] = T4LoggingUtilities.makeParams(connection_.props_, listener); + connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PooledConnecton", "removeConnectionEventListener", + "", p); + } + if (connection_ != null && connection_.props_.getLogWriter() != null) { + LogRecord lr = new LogRecord(Level.FINE, ""); + Object p[] = T4LoggingUtilities.makeParams(connection_.props_, listener); + lr.setParameters(p); + lr.setSourceClassName("TrafT4PooledConnection"); + lr.setSourceMethodName("removeConnectionEventListener"); + T4LogFormatter lf = new T4LogFormatter(); + String temp = lf.format(lr); + connection_.props_.getLogWriter().println(temp); + } + } catch (SQLException se) { + // ignore + } + if (isClosed_ || connection_ == null) { + return; + } + listenerList_.remove(listener); + } + + // Called by TrafT4Connection when the connection is closed by the application + void logicalClose(boolean sendEvents) { + int i; + int totalListener; + ConnectionEventListener listener; + + LogicalConnectionInUse_ = false; + + try { + //3196 - NDCS transaction for SPJ + if (connection_.ic_.suspendRequest_) { + connection_.suspendUDRTransaction(); + } + } + catch (SQLException ex) {} + + if (sendEvents) { + totalListener = listenerList_.size(); + ConnectionEvent event = new ConnectionEvent(this); + for (i = 0; i < totalListener; i++) { + listener = (ConnectionEventListener) listenerList_.get(i); + listener.connectionClosed(event); + } + } + } + + void sendConnectionErrorEvent(SQLException ex) throws SQLException { + int i; + int totalListener; + ConnectionEventListener listener; + + LogicalConnectionInUse_ = false; + totalListener = listenerList_.size(); + ConnectionEvent event = new ConnectionEvent(this, ex); + for (i = 0; i < totalListener; i++) { + listener = (ConnectionEventListener) listenerList_.get(i); + listener.connectionErrorOccurred(event); + } + close(); + } + + // Constructor + TrafT4PooledConnection(TrafT4ConnectionPoolDataSource pds, T4Properties t4props) throws SQLException { + super(); + + T4Properties t4LocalProps; + + pds_ = pds; + if (t4props != null) { + t4LocalProps = t4props; + locale_ = t4props.getLocale(); + } else { + t4LocalProps = new T4Properties(); + locale_ = Locale.getDefault(); + } + listenerList_ = new LinkedList(); + connection_ = new TrafT4Connection(this, t4LocalProps); + try { + if (connection_ != null && connection_.props_.t4Logger_.isLoggable(Level.FINE) == true) { + Object p[] = T4LoggingUtilities.makeParams(connection_.props_, pds, t4props); + connection_.props_.t4Logger_.logp(Level.FINE, "TrafT4PooledConnecton", "", "", p); + } + if (connection_ != null && connection_.props_.getLogWriter() != null) { + LogRecord lr = new LogRecord(Level.FINE, ""); + Object p[] = T4LoggingUtilities.makeParams(connection_.props_, pds, t4props); + lr.setParameters(p); + lr.setSourceClassName("TrafT4PooledConnection"); + lr.setSourceMethodName(""); + T4LogFormatter lf = new T4LogFormatter(); + String temp = lf.format(lr); + connection_.props_.getLogWriter().println(temp); + } + } catch (SQLException se) { + // ignore + } + } + + TrafT4Connection getTrafT4ConnectionReference() { + return connection_; + } + + private LinkedList listenerList_; + private boolean isClosed_ = false; + private TrafT4ConnectionPoolDataSource pds_; + private TrafT4Connection connection_; + private Locale locale_; + private boolean LogicalConnectionInUse_ = false; + public void addStatementEventListener(StatementEventListener listener) { + // TODO Auto-generated method stub + + } + + public void removeStatementEventListener(StatementEventListener listener) { + // TODO Auto-generated method stub + + } +} http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/38e49cf7/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4PooledConnectionManager.java ---------------------------------------------------------------------- diff --git a/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4PooledConnectionManager.java b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4PooledConnectionManager.java new file mode 100644 index 0000000..e31cd9d --- /dev/null +++ b/core/conn/jdbcT4/src/main/java/org/trafodion/jdbc/t4/TrafT4PooledConnectionManager.java @@ -0,0 +1,385 @@ +// @@@ START COPYRIGHT @@@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +// +// @@@ END COPYRIGHT @@@ + +package org.trafodion.jdbc.t4; + +import java.io.PrintWriter; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Collections; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Timer; +import java.util.TimerTask; +import java.util.Vector; +import java.util.logging.Level; +import java.util.logging.LogRecord; + +import javax.sql.ConnectionEvent; +import javax.sql.ConnectionPoolDataSource; +import javax.sql.PooledConnection; + +public class TrafT4PooledConnectionManager implements javax.sql.ConnectionEventListener { + + public void connectionClosed(ConnectionEvent event) { + if (T4Properties.t4GlobalLogger.isLoggable(Level.FINE) == true) { + Object p[] = T4LoggingUtilities.makeParams(null, event); + T4Properties.t4GlobalLogger.logp(Level.FINE, "TrafT4PooledConnectionManager", "connectionClosed", "", p); + } + if (out_ != null) { + LogRecord lr = new LogRecord(Level.FINE, ""); + Object p[] = T4LoggingUtilities.makeParams(null, event); + lr.setParameters(p); + lr.setSourceClassName("TrafT4PooledConnectionManager"); + lr.setSourceMethodName("connectionClosed"); + T4LogFormatter lf = new T4LogFormatter(); + String temp = lf.format(lr); + out_.println(temp); + } + if (out_ != null) { + if (traceLevel_ != Level.OFF) { + out_.println(traceId_ + "connectionClosed(" + event + ")"); + } + } + PooledConnection pc; + + pc = (PooledConnection) event.getSource(); + + boolean addToFreePool = true; + if (minPoolSize_ > 0 && free_.size() >= minPoolSize_) { + addToFreePool = false; + } + // If an initial pool is being created, then ensure that the connection + // is + // added to the free pool irrespective of minPoolSize being reached + if (initialPoolCreationFlag_) { + addToFreePool = true; + } + boolean wasPresent = removeInUseConnection(pc, addToFreePool); + + if (wasPresent && (!addToFreePool)) { + try { + pc.close(); + } catch (SQLException e) { + // ignore any close error + } + } + } + + public void connectionErrorOccurred(ConnectionEvent event) { + if (out_ != null) { + if (traceLevel_ != Level.OFF) { + out_.println(traceId_ + "connectionErrorOccurred(" + event + ")"); + } + } + + PooledConnection pc; + + pc = (PooledConnection) event.getSource(); + try { + pc.close(); + } catch (SQLException e) { + // ignore any close error + } + removeInUseConnection(pc, false); + } + + public Connection getConnection() throws SQLException { + if (out_ != null) { + if (traceLevel_ != Level.OFF) { + out_.println(traceId_ + "getConnection()"); + } + } + + PooledConnection pc; + boolean validConnection = false; + + do { + if (free_.size() == 0) { + if (maxPoolSize_ == 0 || count_ < maxPoolSize_) { + pc = pds_.getPooledConnection(); + count_++; + pc.addConnectionEventListener(this); + inUse_.add(pc); + + TrafT4Connection c = (TrafT4Connection) pc.getConnection(); + try { + c.ic_.enforceT4ConnectionTimeout(c); + validConnection = true; + } catch (SQLException sqlEx) { + try { + pc.close(); + } catch (Exception e) { + } // cleanup, ignore any errors + } + } else { + throw TrafT4Messages.createSQLException(null, null, "max_pool_size_reached", null); + } + } else { + pc = (PooledConnection) free_.get(0); + if (removeFreeConnection(pc, true)) { + TrafT4Connection c = (TrafT4Connection) pc.getConnection(); + try { + c.ic_.enforceT4ConnectionTimeout(c); + validConnection = true; + } catch (SQLException sqlEx) { + try { + pc.close(); + } catch (Exception e) { + } // cleanup, ignore any errors + } + } + } + } while (!validConnection); + + return pc.getConnection(); + } + + private synchronized boolean removeFreeConnection(PooledConnection pc, boolean addToUsePool) { + boolean wasPresent = free_.remove(pc); + hashTab_.remove(pc); + if (wasPresent) { + if (addToUsePool) { + inUse_.add(pc); + } else { + count_--; + } + } + return wasPresent; + } + + private synchronized boolean removeInUseConnection(PooledConnection pc, boolean addToFreePool) { + boolean wasPresent = inUse_.remove(pc); + hashTab_.remove(pc); + if (wasPresent) { + if (addToFreePool) { + hashTab_.put(pc, new Long(System.currentTimeMillis() + (1000 * maxIdleTime_))); + free_.add(pc); + } else { + count_--; + } + } + return wasPresent; + } + + private void createInitialPool(int initialPoolSize) throws SQLException { + if (initialPoolSize <= 0) { + return; + } + + int limit = initialPoolSize > maxPoolSize_ ? maxPoolSize_ : initialPoolSize; + Connection initPool_[] = new Connection[limit]; + int created = 0; + try { + // Set initialPoolInCreation to indicate that an initial pool is in + // the + // process of being created. + initialPoolCreationFlag_ = true; + + for (int i = 0; i < limit; i++) { + initPool_[i] = getConnection(); + created++; + } + } catch (SQLException se) { + SQLException head = TrafT4Messages.createSQLException(null, null, "initial_pool_creation_error", "" + limit); + head.setNextException(se); + throw head; + } finally { + for (int i = 0; i < created; i++) { + try { + if (initPool_[i] != null) + initPool_[i].close(); + } catch (SQLException se) { + // ignore + } + } + // Ensuring that the initialPoolInCreation has been set to false to + // indicate + // that the initial pool creation process has occured. + initialPoolCreationFlag_ = false; + } + } + + void setLogWriter(PrintWriter out) { + out_ = out; + } + + TrafT4PooledConnectionManager(TrafT4ConnectionPoolDataSource pds, Level traceLevel) throws SQLException { + String className = getClass().getName(); + pds_ = pds; + inUse_ = Collections.synchronizedList(new LinkedList()); + free_ = Collections.synchronizedList(new LinkedList()); + maxPoolSize_ = pds.getMaxPoolSize(); + minPoolSize_ = pds.getMinPoolSize(); + maxIdleTime_ = pds.getMaxIdleTime(); + connectionTimeout_ = pds.getConnectionTimeout(); + traceLevel_ = traceLevel; + timer_ = null; + if (maxIdleTime_ > 0 && maxPoolSize_ > 0) { + IdleConnectionCleanupTask timerTask_ = new IdleConnectionCleanupTask(); + timer_ = new Timer(true); + timer_.schedule(timerTask_, (maxIdleTime_ * 1000), (maxIdleTime_ * 500)); + } + if (connectionTimeout_ > 0 && maxPoolSize_ > 0) { + ConnectionTimeoutCleanupTask timerTask_ = new ConnectionTimeoutCleanupTask(); + if (timer_ == null) { + timer_ = new Timer(true); + } + timer_.schedule(timerTask_, (connectionTimeout_ * 1000), (connectionTimeout_ * 500)); + } + createInitialPool(pds.getInitialPoolSize()); + traceId_ = "jdbcTrace:[" + Thread.currentThread() + "]:[" + hashCode() + "]:" + className + "."; + } + + ConnectionPoolDataSource pds_; + // LinkedList inUse_; + // LinkedList free_; + List inUse_; + List free_; + int count_; + + int maxPoolSize_; + int minPoolSize_; + long maxIdleTime_; + int connectionTimeout_; + Level traceLevel_; + PrintWriter out_; + String traceId_; + Timer timer_; + Hashtable hashTab_ = new java.util.Hashtable(); // synchronized + // We keep a flag to indicate to this class that an initial pool is in the + // process + // of being created + boolean initialPoolCreationFlag_ = false; + + /* + * Private class used to clean up the connections that have surpassed + * maxIdleTime + */ + /* Start TimerTask definition */ + private class IdleConnectionCleanupTask extends TimerTask { + Vector toRemove = null; + + IdleConnectionCleanupTask() { + toRemove = new Vector(); + } + + public void run() { + cleanUp(); + } + + private void cleanUp() { + toRemove.clear(); + synchronized (free_) { + try { + Iterator it_ = free_.iterator(); + while (it_.hasNext()) { + PooledConnection tempPC = (PooledConnection) it_.next(); + Long timeOutVal = (Long) hashTab_.get(tempPC); + if (System.currentTimeMillis() > timeOutVal.longValue()) { + toRemove.add(tempPC); + } + } + } catch (Throwable t) { + if (T4Properties.t4GlobalLogger.isLoggable(Level.WARNING) == true) { + T4Properties.t4GlobalLogger.logp(Level.WARNING, "IdleConnectionCleanupTask", "cleanUp", t + .getMessage()); + } + } + } // synchronized block + for (int i = 0; i < toRemove.size(); i++) { + PooledConnection pc = (PooledConnection) toRemove.get(i); + boolean wasPresent = removeFreeConnection(pc, false); + if (wasPresent) { + // close it to cleanup + try { + /* + * System.out.println("Closing connection : " + ( + * (TrafT4Connection) ( (TrafT4PooledConnection) + * pc).getConnection()).getDialogueId()); + */ + pc.close(); + } catch (SQLException se) { + // Ignore + } + } + } + } + } + + /* End TimerTask definition */ + /* + * Private class used to clean up the connections that have surpassed + * connectionTimeout + */ + /* Start TimerTask definition */ + private class ConnectionTimeoutCleanupTask extends TimerTask { + Vector toRemove = null; + + ConnectionTimeoutCleanupTask() { + toRemove = new Vector(); + } + + public void run() { + cleanUp(); + } + + private void cleanUp() { + toRemove.clear(); + synchronized (inUse_) { + Iterator it_ = inUse_.iterator(); + while (it_.hasNext()) { + try { + PooledConnection tempPC = (PooledConnection) it_.next(); + InterfaceConnection ic = ((TrafT4PooledConnection) tempPC).getTrafT4ConnectionReference().ic_; + if (ic != null) { + T4Connection tconn = ic.getT4Connection(); + if (tconn != null) { + if (tconn.connectionIdleTimeoutOccured()) { + // System.out.println("********* Found a + // timed out connection **********"); + toRemove.add(tempPC); + } + } + } + } catch (Throwable t) { + if (T4Properties.t4GlobalLogger.isLoggable(Level.WARNING) == true) { + T4Properties.t4GlobalLogger.logp(Level.WARNING, "ConnectionTimeoutCleanupTask", "cleanUp", + t.getMessage()); + } + } + } + } // synchronized block + for (int i = 0; i < toRemove.size(); i++) { + PooledConnection pc = (PooledConnection) toRemove.get(i); + removeInUseConnection(pc, false); + // do not close the connections because: + // 1.> Corresponding NCS server is already gone + // 2.> We need to give a timeout error when user uses this + // connection + } + } + } + /* End TimerTask definition */ + +}
