All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.firebirdsql.pool.FBWrappingDataSource Maven / Gradle / Ivy

There is a newer version: 2.2.7
Show newest version
/*
 * Firebird Open Source J2ee connector - jdbc driver
 *
 * Distributable under LGPL license.
 * You may obtain a copy of the License at http://www.gnu.org/copyleft/lgpl.html
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * LGPL License for more details.
 *
 * This file was created by members of the firebird development team.
 * All individual contributions remain the Copyright (C) of those
 * individuals.  Contributors to this file are either listed here or
 * can be obtained from a CVS history command.
 *
 * All rights reserved.
 */
package org.firebirdsql.pool;

import java.io.PrintWriter;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Hashtable;
import java.util.Properties;

import javax.naming.*;
import javax.naming.spi.ObjectFactory;
import javax.resource.Referenceable;
import javax.sql.DataSource;

import org.firebirdsql.ds.RootCommonDataSource;
import org.firebirdsql.gds.DatabaseParameterBuffer;
import org.firebirdsql.gds.TransactionParameterBuffer;
import org.firebirdsql.jdbc.FBConnectionProperties;
import org.firebirdsql.jdbc.FBDriverNotCapableException;

/**
 * Implementation of {@link javax.sql.DataSource} including connection pooling.
 * Following properties are supported:
 * 
    *
  • blobBufferSize * size of the buffer used to transfer BLOB data. * *
  • blockingTimeout * time in milliseconds during which {@link #getConnection()} method will * block if no free connection is in pool. * *
  • charSet * similar to encoding, but takes Java character set name * instead of Firebird's encoding. * *
  • database * path to a database including the server name; for example * localhost/3050:c:/path/to/database.gdb. * *
  • encoding * character encoding for the JDBC connection. * *
  • freeSize * read-only: gives amount of free connections in the pool, when 0, blocking * will occur if workingSize is equal to maxPoolSize. * *
  • isolation * default transaction isolation level for connections as string; possible * values are: *
      *
    • TRANSACTION_READ_COMMITTED *
    • TRANSACTION_REPEATABLE_READ *
    • TRANSACTION_SERIALIZABLE *
    * *
  • loginTimeout * property from {@link javax.sql.DataSource}, in this context is a synonym * for blockingTimeout (however value is specified in seconds). * *
  • maxIdleTime * time in milliseconds after which idle physical connection in the * pool is closed. * *
  • maxStatements * maximum number of pooled prepared statements, if 0, pooling is switched * off. * *
  • maxPoolSize * maximum number of physical connections that can be opened by this data * source. * *
  • minPoolSize * minimum number of connections that will remain open by this data source. * *
  • nonStandardProperty * a non-standard connection parameter in form name[=value]. * *
  • password * password that is used to connect to database. * *
  • pingInterval * time interval during which connection will be proved for aliveness. * *
  • pooling * allows switching pooling off. * *
  • statementPooling * alternative way to switch statement pooling off. * *
  • socketBufferSize * size of the socket buffer in bytes. In some cases values used by JVM by * default are not optimal. This results in performance degradation * (especially when you transfer big BLOBs). Usually 8192 bytes provides * good results. * *
  • roleName * SQL role name. * *
  • tpbMapping * mapping of the TPB parameters to JDBC transaction isolation levels. * *
  • transactionIsolationLevel * default transaction isolation level, number from {@link java.sql.Connection} * interface. * *
  • totalSize * total number of allocated connections. * *
  • type * type of connection that will be created. There are four possible types: * pure Java (or type 4), type 2 that will use Firebird client library to * connect to the database, local-mode type 2 driver, and embedded that * will use embedded engine (access to local databases). Possible values * are (case insensitive): *
      *
    • "PURE_JAVA" or "TYPE4" * for pure Java (type 4) JDBC connections; * *
    • "NATIVE" or "TYPE2" * to use Firebird client library; * *
    • "LOCAL" * to use Firebird client library in local-mode (IPC link to server); * *
    • "EMBEDDED" * to use embedded engine. *
    * *
  • userName * name of the user that will be used to access the database. * *
  • workingSize * number of connections that are in use (e.g. were obtained using * {@link #getConnection()} method, but not yet closed). *
* * @author Roman Rokytskyy */ public class FBWrappingDataSource extends RootCommonDataSource implements DataSource, ObjectFactory, Referenceable, Serializable, FirebirdPool { private static final long serialVersionUID = -2282667414407311473L; private AbstractFBConnectionPoolDataSource pool; private Reference reference; private String description; /** * Create instance of this class. */ public FBWrappingDataSource() { // empty } private synchronized AbstractFBConnectionPoolDataSource getPool() { if (pool == null) pool = FBPooledDataSourceFactory.createFBConnectionPoolDataSource(); return pool; } /** * Finalize this instance. This method will shut the pool down. * * @throws Throwable if something went wrong. */ protected void finalize() throws Throwable { if (pool != null) { pool.shutdown(); } super.finalize(); } /* (non-Javadoc) * @see org.firebirdsql.pool.FirebirdPool#restart() */ public void restart() { if (pool != null) pool.restart(); } /* (non-Javadoc) * @see org.firebirdsql.pool.FirebirdPool#shutdown() */ public void shutdown() { if (pool != null) pool.shutdown(); } /** * Get JDBC connection from this data source. * * @return instance of {@link Connection}. * * @throws SQLException if connection cannot be obtained due to some reason. */ public Connection getConnection() throws SQLException { return getPool().getPooledConnection().getConnection(); } /** * Get JDBC connection for the specified user name and password. * * @return instance of {@link Connection} * * @throws SQLException if something went wrong. */ public Connection getConnection(String user, String password) throws SQLException { return getPool().getPooledConnection(user, password).getConnection(); } /** * Get login timeout. * * @return login timeout. */ public int getLoginTimeout() { return getBlockingTimeout() * 1000; } /** * Get log writer. * * @return instance of {@link PrintWriter}. */ public PrintWriter getLogWriter() { return getPool().getLogWriter(); } /** * Set login timeout. * * @param seconds login timeout. */ public void setLoginTimeout(int seconds) { setBlockingTimeout(seconds * 1000); } /** * Set log writer. * * @param printWriter instance of {@link PrintWriter}. */ public void setLogWriter(PrintWriter printWriter) { getPool().setLogWriter(printWriter); } /* * Properties of this datasource. */ public int getBlockingTimeout() { return getPool().getBlockingTimeout(); } public void setBlockingTimeout(int blockingTimeoutValue) { getPool().setBlockingTimeout(blockingTimeoutValue); } public String getDescription() { return description; } public void setDescription(String descriptionValue) { this.description = descriptionValue; } public int getMaxIdleTime() { return getPool().getMaxIdleTime(); } public void setMaxIdleTime(int maxIdleTime) { getPool().setMaxIdleTime(maxIdleTime); } /** * @deprecated non-standard name, use {@link #getMaxIdleTime()}. */ public int getIdleTimeout() { return getPool().getIdleTimeout(); } /** * @deprecated non-standard name, use {@link #setMaxIdleTime(int)}. */ public void setIdleTimeout(int idleTimeoutValue) { getPool().setIdleTimeout(idleTimeoutValue); } public int getMaxStatements() { return getPool().getMaxStatements(); } public void setMaxStatements(int maxStatements) { getPool().setMaxStatements(maxStatements); } public int getMaxPoolSize() { return getPool().getMaxPoolSize(); } public void setMaxPoolSize(int maxPoolSize) { getPool().setMaxPoolSize(maxPoolSize); } /** * @deprecated non-standard name, use {@link #getMaxPoolSize()}. */ public int getMaxConnections() { return getPool().getMaxConnections(); } /** * @deprecated non-standard name, use {@link #setMaxPoolSize(int)}. */ public void setMaxConnections(int maxConnections) { getPool().setMaxConnections(maxConnections); } public int getMinPoolSize() { return getPool().getMinPoolSize(); } public void setMinPoolSize(int minPoolSize) { getPool().setMinPoolSize(minPoolSize); } /** * @deprecated non-standard name, use {@link #getMinPoolSize()} */ public int getMinConnections() { return getMinPoolSize(); } /** * @deprecated non-standard name, use {@link #setMinPoolSize(int)} */ public void setMinConnections(int minConnections) { setMinPoolSize(minConnections); } public boolean isKeepStatements() { return getPool().isKeepStatements(); } public void setKeepStatements(boolean keepStatements) { getPool().setKeepStatements(keepStatements); } public int getPingInterval() { return getPool().getPingInterval(); } public void setPingInterval(int pingIntervalValue) { getPool().setPingInterval(pingIntervalValue); } public String getPingStatement() { return getPool().getPingStatement(); } public void setPingStatement(String pingStatement) { getPool().setPingStatement(pingStatement); } public int getRetryInterval() { return getPool().getRetryInterval(); } public void setRetryInterval(int retryInterval) { getPool().setRetryInterval(retryInterval); } public boolean isPingable() { return getPool().isPingable(); } /** * @deprecated please use {@link #getRoleName()} instead. */ public String getSqlRole() { return getRoleName(); } /** * @deprecated please use {@link #setRoleName(String)} instead. */ public void setSqlRole(String sqlRole) { setRoleName(sqlRole); } /** * @deprecated use {@link #isPooling()} method. */ public boolean getPooling() { return getPool().isPooling(); } public boolean isPooling() { return getPool().isPooling(); } public void setPooling(boolean pooling) { getPool().setPooling(pooling); } public boolean isStatementPooling() { return getPool().isStatementPooling(); } public void setStatementPooling(boolean statementPooling) { getPool().setStatementPooling(statementPooling); } /** * @deprecated Confusing name. Use {@link #getFreeSize()} instead. */ public int getConnectionCount() throws SQLException { return getPool().getFreeSize(); } public int getFreeSize() throws SQLException { return getPool().getFreeSize(); } public int getWorkingSize() throws SQLException { return getPool().getWorkingSize(); } public int getTotalSize() throws SQLException { return getPool().getTotalSize(); } /** * @deprecated Use {@link #getDefaultTransactionIsolation()} instead. */ public int getTransactionIsolationLevel() { return getDefaultTransactionIsolation(); } /** * @deprecated Use {@link #setDefaultTransactionIsolation(int)} instead. */ public void setTransactionIsolationLevel(int level) { setDefaultTransactionIsolation(level); } /** * @deprecated Use {@link #getDefaultIsolation()} instead. */ public String getIsolation() { return getDefaultIsolation(); } /** * @deprecated Use {@link #setDefaultIsolation(String)} instead. */ public void setIsolation(String isolation) throws SQLException { setDefaultIsolation(isolation); } public void setProperties(Properties props) { getPool().setProperties(props); } public int getBlobBufferSize() { return getPool().getBlobBufferSize(); } public int getBuffersNumber() { return getPool().getBuffersNumber(); } public String getCharSet() { return getPool().getCharSet(); } public String getDatabase() { return getPool().getDatabase(); } public DatabaseParameterBuffer getDatabaseParameterBuffer() throws SQLException { return getPool().getDatabaseParameterBuffer(); } public String getDefaultIsolation() { return getPool().getDefaultIsolation(); } public int getDefaultTransactionIsolation() { return getPool().getDefaultTransactionIsolation(); } public String getEncoding() { return getPool().getEncoding(); } public String getNonStandardProperty(String key) { return getPool().getNonStandardProperty(key); } public String getPassword() { return getPool().getPassword(); } public String getRoleName() { return getPool().getRoleName(); } public int getSocketBufferSize() { return getPool().getSocketBufferSize(); } public String getSqlDialect() { return getPool().getSqlDialect(); } public String getTpbMapping() { return getPool().getTpbMapping(); } public TransactionParameterBuffer getTransactionParameters(int isolation) { return getPool().getTransactionParameters(isolation); } public String getType() { return getPool().getType(); } public String getUserName() { return getPool().getUserName(); } public String getUseTranslation() { return getPool().getUseTranslation(); } public boolean isTimestampUsesLocalTimezone() { return getPool().isTimestampUsesLocalTimezone(); } public boolean isUseStandardUdf() { return getPool().isUseStandardUdf(); } public boolean isUseStreamBlobs() { return getPool().isUseStreamBlobs(); } public void setBlobBufferSize(int bufferSize) { getPool().setBlobBufferSize(bufferSize); } public void setBuffersNumber(int buffersNumber) { getPool().setBuffersNumber(buffersNumber); } public void setCharSet(String charSet) { getPool().setCharSet(charSet); } public void setDatabase(String database) { getPool().setDatabase(database); } public void setDefaultIsolation(String isolation) { getPool().setDefaultIsolation(isolation); } public void setDefaultTransactionIsolation(int defaultIsolationLevel) { getPool().setDefaultTransactionIsolation(defaultIsolationLevel); } public void setEncoding(String encoding) { getPool().setEncoding(encoding); } public void setNonStandardProperty(String key, String value) { getPool().setNonStandardProperty(key, value); } public void setNonStandardProperty(String propertyMapping) { getPool().setNonStandardProperty(propertyMapping); } public void setPassword(String password) { getPool().setPassword(password); } public void setRoleName(String roleName) { getPool().setRoleName(roleName); } public void setSocketBufferSize(int socketBufferSize) { getPool().setSocketBufferSize(socketBufferSize); } public void setSqlDialect(String sqlDialect) { getPool().setSqlDialect(sqlDialect); } public void setTimestampUsesLocalTimezone(boolean timestampUsesLocalTimezone) { getPool().setTimestampUsesLocalTimezone(timestampUsesLocalTimezone); } public void setTpbMapping(String tpbMapping) { getPool().setTpbMapping(tpbMapping); } public void setTransactionParameters(int isolation, TransactionParameterBuffer tpb) { getPool().setTransactionParameters(isolation, tpb); } public void setType(String type) { getPool().setType(type); } public void setUserName(String userName) { getPool().setUserName(userName); } public void setUseStandardUdf(boolean useStandardUdf) { getPool().setUseStandardUdf(useStandardUdf); } public void setUseStreamBlobs(boolean useStreamBlobs) { getPool().setUseStreamBlobs(useStreamBlobs); } public void setUseTranslation(String translationPath) { getPool().setUseTranslation(translationPath); } public boolean isDefaultResultSetHoldable() { return getPool().isDefaultResultSetHoldable(); } public void setDefaultResultSetHoldable(boolean isHoldable) { getPool().setDefaultResultSetHoldable(isHoldable); } public int getSoTimeout() { return getPool().getSoTimeout(); } public void setSoTimeout(int soTimeout) { getPool().setSoTimeout(soTimeout); } public int getConnectTimeout() { return getPool().getConnectTimeout(); } public void setConnectTimeout(int connectTimeout) { getPool().setConnectTimeout(connectTimeout); } /* * JNDI-related code. */ private static final String REF_BLOCKING_TIMEOUT = "blockingTimeout"; // private static final String REF_DATABASE = "database"; private static final String REF_DESCRIPTION = "description"; private static final String REF_MAX_IDLE_TIME = "maxIdleTime"; private static final String REF_IDLE_TIMEOUT = "idleTimeout"; private static final String REF_LOGIN_TIMEOUT = "loginTimeout"; private static final String REF_MAX_POOL_SIZE = "maxPoolSize"; private static final String REF_MIN_POOL_SIZE = "minPoolSize"; private static final String REF_MAX_CONNECTIONS = "maxConnections"; private static final String REF_MIN_CONNECTIONS = "minConnections"; private static final String REF_PING_INTERVAL = "pingInterval"; private static final String REF_RETRY_INTERVAL = "retryInterval"; private static final String REF_POOLING = "pooling"; private static final String REF_STATEMENT_POOLING = "statementPooling"; private static final String REF_PING_STATEMENT = "pingStatement"; // private static final String REF_TYPE = "type"; // private static final String REF_TX_ISOLATION = "transactionIsolationLevel"; // private static final String REF_ISOLATION = "isolation"; private static final String REF_PROPERTIES = "properties"; private static final String REF_NON_STANDARD_PROPERTY = "nonStandard"; /** * Get object instance for the specified name in the specified context. * This method constructs new datasource if obj represents * {@link Reference}, whose factory class is equal to this class. */ public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws Exception { if (!(obj instanceof Reference)) return null; Reference ref = (Reference)obj; ref = (Reference)ref.clone(); if (!getClass().getName().equals(ref.getClassName())) return null; FBWrappingDataSource ds = new FBWrappingDataSource(); for(int i = 0; i < ref.size(); i++) { RefAddr element = ref.get(i); String type = element.getType(); if (REF_BLOCKING_TIMEOUT.equals(type)) ds.setBlockingTimeout(Integer.parseInt(element.getContent().toString())); else if (REF_DESCRIPTION.equals(type)) ds.setDescription(element.getContent().toString()); else if (REF_IDLE_TIMEOUT.equals(type)) ds.setIdleTimeout(Integer.parseInt(element.getContent().toString())); else if (REF_MAX_IDLE_TIME.equals(type)) ds.setMaxIdleTime(Integer.parseInt(element.getContent().toString())); else if (REF_LOGIN_TIMEOUT.equals(type)) ds.setLoginTimeout(Integer.parseInt(element.getContent().toString())); else if (REF_MAX_POOL_SIZE.equals(type)) ds.setMaxPoolSize(Integer.parseInt(element.getContent().toString())); else if (REF_MIN_POOL_SIZE.equals(type)) ds.setMinPoolSize(Integer.parseInt(element.getContent().toString())); else if (REF_MIN_CONNECTIONS.equals(type)) ds.setMinConnections(Integer.parseInt(element.getContent().toString())); else if (REF_MAX_CONNECTIONS.equals(type)) ds.setMaxConnections(Integer.parseInt(element.getContent().toString())); else if (REF_PING_INTERVAL.equals(type)) ds.setPingInterval(Integer.parseInt(element.getContent().toString())); else if (REF_RETRY_INTERVAL.equals(type)) ds.setRetryInterval(Integer.parseInt(element.getContent().toString())); else if (REF_POOLING.equals(type)) ds.setPooling(Boolean.valueOf(element.getContent().toString()).booleanValue()); else if (REF_STATEMENT_POOLING.equals(type)) ds.setStatementPooling(Boolean.valueOf(element.getContent().toString()).booleanValue()); else if (REF_PING_STATEMENT.equals(type)) ds.setPingStatement(element.getContent().toString()); if (REF_NON_STANDARD_PROPERTY.equals(type)) ds.setNonStandardProperty(element.getContent().toString()); else if (REF_PROPERTIES.equals(type)) { byte[] data = (byte[])element.getContent(); FBConnectionProperties props = (FBConnectionProperties)BasicAbstractConnectionPool.deserialize(data); ds.getPool().setConnectionProperties(props); } else if (element.getContent() instanceof String) ds.setNonStandardProperty(type, element.getContent().toString()); } return ds; } /** * Get JDNI reference. * * @return instance of {@link Reference}. */ public Reference getReference() { if (reference == null) return getDefaultReference(); else return reference; } /** * Set JNDI reference for this data source. * * @param reference JNDI reference. */ public void setReference(Reference reference) { this.reference = reference; } /** * Get default JNDI reference for this datasource. This method is called if * datasource is used in non-JCA environment. * * @return instance of {@link Reference} containing all information * that allows to reconstruct the datasource. */ public Reference getDefaultReference() { Reference ref = new Reference(getClass().getName(), getClass().getName(), null); if (getBlockingTimeout() != FBPoolingDefaults.DEFAULT_BLOCKING_TIMEOUT) ref.add(new StringRefAddr(REF_BLOCKING_TIMEOUT, String.valueOf(getBlockingTimeout()))); // if (getDatabase() != null) // ref.add(new StringRefAddr(REF_DATABASE, getDatabase())); if (getDescription() != null) ref.add(new StringRefAddr(REF_DESCRIPTION, getDescription())); if (getMaxIdleTime() != FBPoolingDefaults.DEFAULT_IDLE_TIMEOUT) ref.add(new StringRefAddr(REF_MAX_IDLE_TIME, String.valueOf(getMaxIdleTime()))); if (getLoginTimeout() != FBPoolingDefaults.DEFAULT_LOGIN_TIMEOUT) ref.add(new StringRefAddr(REF_LOGIN_TIMEOUT, String.valueOf(getLoginTimeout()))); if (getMaxPoolSize() != FBPoolingDefaults.DEFAULT_MAX_SIZE) ref.add(new StringRefAddr(REF_MAX_POOL_SIZE, String.valueOf(getMaxPoolSize()))); if (getMinPoolSize() != FBPoolingDefaults.DEFAULT_MIN_SIZE) ref.add(new StringRefAddr(REF_MIN_POOL_SIZE, String.valueOf(getMinPoolSize()))); if (getPingInterval() != FBPoolingDefaults.DEFAULT_PING_INTERVAL) ref.add(new StringRefAddr(REF_PING_INTERVAL, String.valueOf(getPingInterval()))); if (getRetryInterval() != FBPoolingDefaults.DEFAULT_RETRY_INTERVAL) ref.add(new StringRefAddr(REF_RETRY_INTERVAL, String.valueOf(getRetryInterval()))); if (!isPooling()) ref.add(new StringRefAddr(REF_POOLING, String.valueOf(isPooling()))); if (!isStatementPooling()) ref.add(new StringRefAddr(REF_STATEMENT_POOLING, String.valueOf(isStatementPooling()))); ref.add(new StringRefAddr(REF_PING_STATEMENT, getPingStatement())); // if (getType() != null) // ref.add(new StringRefAddr(REF_TYPE, getType())); // // if (getDefaultTransactionIsolation() != FBPoolingDefaults.DEFAULT_ISOLATION) // ref.add(new StringRefAddr(REF_TX_ISOLATION, // String.valueOf(getDefaultTransactionIsolation()))); byte[] data = BasicAbstractConnectionPool.serialize(getPool().getConnectionProperties()); ref.add(new BinaryRefAddr(REF_PROPERTIES, data)); return ref; } // JBBC 4.0 public boolean isWrapperFor(Class iface) throws SQLException { return false; } public Object unwrap(Class iface) throws SQLException { throw new FBDriverNotCapableException(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy