1
0
mirror of https://github.com/postgres/postgres.git synced 2025-09-11 00:12:06 +03:00

Applied patch from Aaron Mulder (ammulder@alumni.princeton.edu) that fixes

jdbc datasource support for jdk1.4/jdbc3

 Modified Files:
 	jdbc/build.xml jdbc/org/postgresql/Driver.java.in
 	jdbc/org/postgresql/jdbc2/optional/BaseDataSource.java
 	jdbc/org/postgresql/jdbc2/optional/PGObjectFactory.java
 	jdbc/org/postgresql/jdbc2/optional/PooledConnectionImpl.java
 	jdbc/org/postgresql/jdbc2/optional/PoolingDataSource.java
 	jdbc/org/postgresql/test/jdbc2/optional/BaseDataSourceTest.java
 	jdbc/org/postgresql/test/jdbc2/optional/OptionalTestSuite.java
 	jdbc/org/postgresql/test/jdbc3/Jdbc3TestSuite.java
 Added Files:
 	jdbc/org/postgresql/jdbc3/Jdbc3ConnectionPool.java
 	jdbc/org/postgresql/jdbc3/Jdbc3ObjectFactory.java
 	jdbc/org/postgresql/jdbc3/Jdbc3PooledConnection.java
 	jdbc/org/postgresql/jdbc3/Jdbc3PoolingDataSource.java
 	jdbc/org/postgresql/jdbc3/Jdbc3SimpleDataSource.java
 	jdbc/org/postgresql/test/jdbc2/optional/PoolingDataSourceTest.java
 	jdbc/org/postgresql/test/jdbc3/Jdbc3ConnectionPoolTest.java
 	jdbc/org/postgresql/test/jdbc3/Jdbc3PoolingDataSourceTest.java
 	jdbc/org/postgresql/test/jdbc3/Jdbc3SimpleDataSourceTest.java
 	jdbc/org/postgresql/test/util/MiniJndiContext.java
 	jdbc/org/postgresql/test/util/MiniJndiContextFactory.java
This commit is contained in:
Barry Lind
2002-09-25 07:01:31 +00:00
parent 65bf5a39e0
commit 7bf1c8b0ad
20 changed files with 1023 additions and 31 deletions

View File

@@ -2,10 +2,11 @@ package org.postgresql.test.jdbc2.optional;
import junit.framework.TestCase;
import org.postgresql.test.TestUtil;
import org.postgresql.jdbc2.optional.SimpleDataSource;
import org.postgresql.jdbc2.optional.BaseDataSource;
import java.sql.*;
import java.util.*;
import javax.naming.*;
/**
* Common tests for all the BaseDataSource implementations. This is
@@ -15,10 +16,11 @@ import java.sql.*;
* tests.
*
* @author Aaron Mulder (ammulder@chariotsolutions.com)
* @version $Revision: 1.3 $
* @version $Revision: 1.4 $
*/
public abstract class BaseDataSourceTest extends TestCase
{
public static String DATA_SOURCE_JNDI = "BaseDataSource";
protected Connection con;
protected BaseDataSource bds;
@@ -60,7 +62,10 @@ public abstract class BaseDataSourceTest extends TestCase
*/
protected Connection getDataSourceConnection() throws SQLException
{
initializeDataSource();
if(bds == null)
{
initializeDataSource();
}
return bds.getConnection();
}
@@ -174,6 +179,21 @@ public abstract class BaseDataSourceTest extends TestCase
}
}
/**
* Uses the mini-JNDI implementation for testing purposes
*/
protected InitialContext getInitialContext()
{
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "org.postgresql.test.util.MiniJndiContextFactory");
try {
return new InitialContext(env);
} catch(NamingException e) {
fail("Unable to create InitialContext: "+e.getMessage());
return null;
}
}
/**
* Eventually, we must test stuffing the DataSource in JNDI and
* then getting it back out and make sure it's still usable. This
@@ -182,6 +202,26 @@ public abstract class BaseDataSourceTest extends TestCase
*/
public void testJndi()
{
// TODO: Put the DS in JNDI, retrieve it, and try some of this stuff again
}
initializeDataSource();
BaseDataSource oldbds = bds;
InitialContext ic = getInitialContext();
try {
ic.rebind(DATA_SOURCE_JNDI, bds);
bds = (BaseDataSource)ic.lookup(DATA_SOURCE_JNDI);
assertTrue("Got null looking up DataSource from JNDI!", bds != null);
compareJndiDataSource(oldbds, bds);
} catch (NamingException e) {
fail(e.getMessage());
}
oldbds = bds;
testUseConnection();
assertTrue("Test should not have changed DataSource ("+bds+" != "+oldbds+")!", bds == oldbds);
}
/**
* Check whether a DS was dereferenced from JNDI or recreated.
*/
protected void compareJndiDataSource(BaseDataSource oldbds, BaseDataSource bds) {
assertTrue("DataSource was dereferenced, should have been serialized or recreated", bds != oldbds);
}
}

View File

@@ -8,7 +8,7 @@ import junit.framework.TestSuite;
* PooledConnection implementations.
*
* @author Aaron Mulder (ammulder@chariotsolutions.com)
* @version $Revision: 1.2 $
* @version $Revision: 1.3 $
*/
public class OptionalTestSuite extends TestSuite
{
@@ -21,6 +21,7 @@ public class OptionalTestSuite extends TestSuite
TestSuite suite = new TestSuite();
suite.addTestSuite(SimpleDataSourceTest.class);
suite.addTestSuite(ConnectionPoolTest.class);
suite.addTestSuite(ConnectionPoolTest.class);
return suite;
}
}

View File

@@ -0,0 +1,106 @@
package org.postgresql.test.jdbc2.optional;
import java.sql.SQLException;
import org.postgresql.test.TestUtil;
import org.postgresql.jdbc2.optional.PoolingDataSource;
import org.postgresql.jdbc2.optional.BaseDataSource;
/**
* Minimal tests for pooling DataSource. Needs many more.
*
* @author Aaron Mulder (ammulder@chariotsolutions.com)
* @version $Revision: 1.1 $
*/
public class PoolingDataSourceTest extends BaseDataSourceTest
{
private final static String DS_NAME = "JDBC 2 SE Test DataSource";
/**
* Constructor required by JUnit
*/
public PoolingDataSourceTest(String name)
{
super(name);
}
protected void tearDown() throws Exception
{
super.tearDown();
if (bds instanceof PoolingDataSource)
{
((PoolingDataSource) bds).close();
}
}
/**
* Creates and configures a new SimpleDataSource.
*/
protected void initializeDataSource()
{
if (bds == null)
{
bds = new PoolingDataSource();
String db = TestUtil.getURL();
if (db.indexOf('/') > -1)
{
db = db.substring(db.lastIndexOf('/') + 1);
}
else if (db.indexOf(':') > -1)
{
db = db.substring(db.lastIndexOf(':') + 1);
}
bds.setDatabaseName(db);
bds.setUser(TestUtil.getUser());
bds.setPassword(TestUtil.getPassword());
((PoolingDataSource) bds).setDataSourceName(DS_NAME);
((PoolingDataSource) bds).setInitialConnections(2);
((PoolingDataSource) bds).setMaxConnections(10);
}
}
/**
* In this case, we *do* want it to be pooled.
*/
public void testNotPooledConnection()
{
try
{
con = getDataSourceConnection();
String name = con.toString();
con.close();
con = getDataSourceConnection();
String name2 = con.toString();
con.close();
assertTrue("Pooled DS doesn't appear to be pooling connections!", name.equals(name2));
}
catch (SQLException e)
{
fail(e.getMessage());
}
}
/**
* In this case, the desired behavior is dereferencing.
*/
protected void compareJndiDataSource(BaseDataSource oldbds, BaseDataSource bds)
{
assertTrue("DataSource was serialized or recreated, should have been dereferenced", bds == oldbds);
}
/**
* Check that 2 DS instances can't use the same name.
*/
public void testCantReuseName()
{
initializeDataSource();
PoolingDataSource pds = new PoolingDataSource();
try
{
pds.setDataSourceName(DS_NAME);
fail("Should have denied 2nd DataSource with same name");
}
catch (IllegalArgumentException e)
{
}
}
}

View File

@@ -0,0 +1,67 @@
package org.postgresql.test.jdbc3;
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.PooledConnection;
import org.postgresql.test.jdbc2.optional.ConnectionPoolTest;
import org.postgresql.test.TestUtil;
import org.postgresql.jdbc3.*;
/**
* Tests JDBC3 implementation of ConnectionPoolDataSource.
*
* @author Aaron Mulder (ammulder@chariotsolutions.com)
* @version $Revision: 1.1 $
*/
public class Jdbc3ConnectionPoolTest extends ConnectionPoolTest
{
public Jdbc3ConnectionPoolTest(String name)
{
super(name);
}
/**
* Creates and configures a Jdbc3ConnectionPool
*/
protected void initializeDataSource()
{
if (bds == null)
{
bds = new Jdbc3ConnectionPool();
String db = TestUtil.getURL();
if (db.indexOf('/') > -1)
{
db = db.substring(db.lastIndexOf('/') + 1);
}
else if (db.indexOf(':') > -1)
{
db = db.substring(db.lastIndexOf(':') + 1);
}
bds.setDatabaseName(db);
bds.setUser(TestUtil.getUser());
bds.setPassword(TestUtil.getPassword());
}
}
/**
* Makes sure this is a JDBC 3 implementation producing JDBC3
* connections. Depends on toString implementation of
* connection wrappers.
*/
public void testConfirmJdbc3Impl()
{
try
{
initializeDataSource();
assertTrue("Wrong ConnectionPool impl used by test: " + bds.getClass().getName(), bds instanceof Jdbc3ConnectionPool);
PooledConnection pc = ((Jdbc3ConnectionPool) bds).getPooledConnection();
assertTrue("Wrong PooledConnection impl generated by JDBC3 ConnectionPoolDataSource: " + pc.getClass().getName(), pc instanceof Jdbc3PooledConnection);
assertTrue("Wrong Connnection class used in JDBC3 ConnectionPoolDataSource's PooledConnection impl: " + pc.getConnection().toString(), pc.getConnection().toString().indexOf("Jdbc3") > -1);
pc.close();
}
catch (SQLException e)
{
fail(e.getMessage());
}
}
}

View File

@@ -0,0 +1,155 @@
package org.postgresql.test.jdbc3;
import java.sql.Connection;
import java.sql.SQLException;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.postgresql.test.jdbc2.optional.PoolingDataSourceTest;
import org.postgresql.test.TestUtil;
import org.postgresql.jdbc3.Jdbc3PoolingDataSource;
import org.postgresql.jdbc2.optional.PoolingDataSource;
/**
* Minimal tests for JDBC3 pooling DataSource. Needs many more.
*
* @author Aaron Mulder (ammulder@chariotsolutions.com)
* @version $Revision: 1.1 $
*/
public class Jdbc3PoolingDataSourceTest extends PoolingDataSourceTest
{
private final static String DS_NAME = "JDBC 3 Test DataSource";
/**
* Constructor required by JUnit
*/
public Jdbc3PoolingDataSourceTest(String name)
{
super(name);
}
/**
* Creates and configures a new SimpleDataSource.
*/
protected void initializeDataSource()
{
if (bds == null)
{
bds = new Jdbc3PoolingDataSource();
configureDataSource((Jdbc3PoolingDataSource) bds);
}
}
private void configureDataSource(PoolingDataSource source)
{
String db = TestUtil.getURL();
if (db.indexOf('/') > -1)
{
db = db.substring(db.lastIndexOf('/') + 1);
}
else if (db.indexOf(':') > -1)
{
db = db.substring(db.lastIndexOf(':') + 1);
}
source.setDatabaseName(db);
source.setUser(TestUtil.getUser());
source.setPassword(TestUtil.getPassword());
source.setDataSourceName(DS_NAME);
source.setInitialConnections(2);
source.setMaxConnections(10);
}
/**
* Check that 2 DS instances can't use the same name.
*/
public void testCantReuseName()
{
initializeDataSource();
Jdbc3PoolingDataSource pds = new Jdbc3PoolingDataSource();
try
{
pds.setDataSourceName(DS_NAME);
fail("Should have denied 2nd DataSource with same name");
}
catch (IllegalArgumentException e)
{
}
}
/**
* Test that JDBC 2 and JDBC 3 DSs come from different buckets
* as far as creating with the same name
*/
public void testDifferentImplPools()
{
initializeDataSource();
PoolingDataSource pds = new PoolingDataSource();
try
{
configureDataSource(pds);
PoolingDataSource p2 = new PoolingDataSource();
try
{
configureDataSource(p2);
fail("Shouldn't be able to create 2 JDBC 2 DSs with same name");
}
catch (IllegalArgumentException e)
{
}
Jdbc3PoolingDataSource p3 = new Jdbc3PoolingDataSource();
try
{
configureDataSource(p3);
fail("Shouldn't be able to create 2 JDBC 3 DSs with same name");
}
catch (IllegalArgumentException e)
{
}
}
finally
{
pds.close();
}
}
/**
* Test that JDBC 2 and JDBC 3 DSs come from different buckets
* as far as fetching from JNDI
*/
public void testDifferentImplJndi()
{
initializeDataSource();
PoolingDataSource pds = new PoolingDataSource();
try
{
configureDataSource(pds);
try
{
Connection j3c = getDataSourceConnection();
Connection j2c = pds.getConnection();
j2c.close();
j3c.close();
InitialContext ctx = getInitialContext();
ctx.bind("JDBC2", pds);
ctx.bind("JDBC3", bds);
pds = (PoolingDataSource) ctx.lookup("JDBC2");
bds = (Jdbc3PoolingDataSource) ctx.lookup("JDBC3");
j2c = pds.getConnection();
j3c = bds.getConnection();
j2c.close();
j3c.close();
}
catch (SQLException e)
{
fail(e.getMessage());
}
catch (NamingException e)
{
fail(e.getMessage());
}
}
finally
{
pds.close();
}
}
}

View File

@@ -0,0 +1,60 @@
package org.postgresql.test.jdbc3;
import java.sql.Connection;
import java.sql.SQLException;
import org.postgresql.test.jdbc2.optional.SimpleDataSourceTest;
import org.postgresql.test.TestUtil;
import org.postgresql.jdbc3.*;
/**
* Tests JDBC3 non-pooling DataSource.
*
* @author Aaron Mulder (ammulder@chariotsolutions.com)
* @version $Revision: 1.1 $
*/
public class Jdbc3SimpleDataSourceTest extends SimpleDataSourceTest {
/**
* Constructor required by JUnit
*/
public Jdbc3SimpleDataSourceTest(String name)
{
super(name);
}
/**
* Creates and configures a new SimpleDataSource.
*/
protected void initializeDataSource()
{
if (bds == null)
{
bds = new Jdbc3SimpleDataSource();
String db = TestUtil.getURL();
if (db.indexOf('/') > -1)
{
db = db.substring(db.lastIndexOf('/') + 1);
}
else if (db.indexOf(':') > -1)
{
db = db.substring(db.lastIndexOf(':') + 1);
}
bds.setDatabaseName(db);
bds.setUser(TestUtil.getUser());
bds.setPassword(TestUtil.getPassword());
}
}
/**
* Makes sure this is a JDBC 3 implementation producing JDBC3
* connections.
*/
public void testConfirmJdbc3Impl()
{
try {
Connection con = getDataSourceConnection();
assertTrue("Wrong SimpleDataSource impl used by test: "+bds.getClass().getName(), bds instanceof Jdbc3SimpleDataSource);
assertTrue("Wrong Connnection class generated by JDBC3 DataSource: "+con.getClass().getName(), con instanceof Jdbc3Connection);
} catch (SQLException e) {
fail(e.getMessage());
}
}
}

View File

@@ -1,10 +1,6 @@
package org.postgresql.test.jdbc3;
import junit.framework.TestSuite;
import junit.framework.TestCase;
import junit.framework.Test;
import java.sql.*;
/*
* Executes all known tests for JDBC3
@@ -17,7 +13,11 @@ public class Jdbc3TestSuite extends TestSuite
*/
public static TestSuite suite()
{
//Currently there are no specific jdbc3 tests so just run the jdbc2 tests
return org.postgresql.test.jdbc2.Jdbc2TestSuite.suite();
TestSuite suite = new TestSuite();
suite.addTest(org.postgresql.test.jdbc2.Jdbc2TestSuite.suite());
suite.addTestSuite(Jdbc3SimpleDataSourceTest.class);
suite.addTestSuite(Jdbc3ConnectionPoolTest.class);
suite.addTestSuite(Jdbc3PoolingDataSourceTest.class);
return suite;
}
}

View File

@@ -0,0 +1,228 @@
package org.postgresql.test.util;
import java.util.*;
import java.rmi.MarshalledObject;
import java.io.Serializable;
import javax.naming.*;
import javax.naming.spi.ObjectFactory;
/**
* The Context for a trivial JNDI implementation. This is not meant to
* be very useful, beyond testing JNDI features of the connection
* pools. It is not a complete JNDI implementations.
*
* @author Aaron Mulder (ammulder@chariotsolutions.com)
* @version $Revision: 1.1 $
*/
public class MiniJndiContext implements Context
{
private Map map = new HashMap();
public MiniJndiContext()
{
}
public Object lookup(Name name) throws NamingException
{
return lookup(name.get(0));
}
public Object lookup(String name) throws NamingException
{
Object o = map.get(name);
if (o == null)
{
return null;
}
if (o instanceof Reference)
{
Reference ref = (Reference) o;
try
{
Class factoryClass = Class.forName(ref.getFactoryClassName());
ObjectFactory fac = (ObjectFactory) factoryClass.newInstance();
Object result = fac.getObjectInstance(ref, null, this, null);
return result;
}
catch (Exception e)
{
throw new NamingException("Unable to dereference to object: " + e);
}
}
else if (o instanceof MarshalledObject)
{
try
{
Object result = ((MarshalledObject) o).get();
return result;
}
catch (java.io.IOException e)
{
throw new NamingException("Unable to deserialize object: " + e);
}
catch (ClassNotFoundException e)
{
throw new NamingException("Unable to deserialize object: " + e);
}
}
else
{
throw new NamingException("JNDI Object is neither Referenceable nor Serializable");
}
}
public void bind(Name name, Object obj) throws NamingException
{
rebind(name.get(0), obj);
}
public void bind(String name, Object obj) throws NamingException
{
rebind(name, obj);
}
public void rebind(Name name, Object obj) throws NamingException
{
rebind(name.get(0), obj);
}
public void rebind(String name, Object obj) throws NamingException
{
if (obj instanceof Referenceable)
{
Reference ref = ((Referenceable) obj).getReference();
map.put(name, ref);
}
else if (obj instanceof Serializable)
{
try
{
MarshalledObject mo = new MarshalledObject(obj);
map.put(name, mo);
}
catch (java.io.IOException e)
{
throw new NamingException("Unable to serialize object to JNDI: " + e);
}
}
else
{
throw new NamingException("Object to store in JNDI is neither Referenceable nor Serializable");
}
}
public void unbind(Name name) throws NamingException
{
unbind(name.get(0));
}
public void unbind(String name) throws NamingException
{
map.remove(name);
}
public void rename(Name oldName, Name newName) throws NamingException
{
rename(oldName.get(0), newName.get(0));
}
public void rename(String oldName, String newName) throws NamingException
{
map.put(newName, map.remove(oldName));
}
public NamingEnumeration list(Name name) throws NamingException
{
return null;
}
public NamingEnumeration list(String name) throws NamingException
{
return null;
}
public NamingEnumeration listBindings(Name name) throws NamingException
{
return null;
}
public NamingEnumeration listBindings(String name) throws NamingException
{
return null;
}
public void destroySubcontext(Name name) throws NamingException
{
}
public void destroySubcontext(String name) throws NamingException
{
}
public Context createSubcontext(Name name) throws NamingException
{
return null;
}
public Context createSubcontext(String name) throws NamingException
{
return null;
}
public Object lookupLink(Name name) throws NamingException
{
return null;
}
public Object lookupLink(String name) throws NamingException
{
return null;
}
public NameParser getNameParser(Name name) throws NamingException
{
return null;
}
public NameParser getNameParser(String name) throws NamingException
{
return null;
}
public Name composeName(Name name, Name prefix) throws NamingException
{
return null;
}
public String composeName(String name, String prefix)
throws NamingException
{
return null;
}
public Object addToEnvironment(String propName, Object propVal)
throws NamingException
{
return null;
}
public Object removeFromEnvironment(String propName)
throws NamingException
{
return null;
}
public Hashtable getEnvironment() throws NamingException
{
return null;
}
public void close() throws NamingException
{
}
public String getNameInNamespace() throws NamingException
{
return null;
}
}

View File

@@ -0,0 +1,22 @@
package org.postgresql.test.util;
import java.util.*;
import javax.naming.*;
import javax.naming.spi.InitialContextFactory;
/**
* The ICF for a trivial JNDI implementation. This is not meant to
* be very useful, beyond testing JNDI features of the connection
* pools.
*
* @author Aaron Mulder (ammulder@chariotsolutions.com)
* @version $Revision: 1.1 $
*/
public class MiniJndiContextFactory implements InitialContextFactory
{
public Context getInitialContext(Hashtable environment)
throws NamingException
{
return new MiniJndiContext();
}
}