/*
* Danet GmbH
* Beratung und Software-Entwicklung
* Gesch�ftstelle AN
*
* $Id: PersMap.java 2326 2007-03-27 21:59:44Z mlipp $
*
* $Log$
* Revision 1.2 2005/04/22 15:11:07 drmlipp
* Merged changes from 1.3 branch up to 1.3p15.
*
* Revision 1.1.1.3.6.2 2005/04/14 11:45:08 drmlipp
* More (minor) optimizations.
*
* Revision 1.1.1.3.6.1 2005/04/13 16:14:08 drmlipp
* Optimized db access.
*
* Revision 1.1.1.3 2004/08/18 15:18:47 drmlipp
* Update to 1.2
*
* Revision 1.24 2004/06/14 19:37:20 lipp
* Fixed assignment functions and cleaned up assignment related
* interfaces.
*
* Revision 1.23 2004/02/13 10:16:20 lipp
* Using "standard" table for tests.
*
* Revision 1.22 2003/11/03 12:40:58 lipp
* Added test.
*
* Revision 1.21 2003/08/27 12:14:41 lipp
* Fixed test case.
*
* Revision 1.20 2003/05/23 14:40:10 lipp
* HSQL does not supports column length queries after all.
*
* Revision 1.19 2003/05/17 20:03:09 lipp
* HSQL supports column length queries now.
*
* Revision 1.18 2003/03/06 18:20:11 schlue
* Test cases for batch support separated.
*
* Revision 1.17 2003/03/06 13:47:46 schlue
* Handling of null values fixed.
*
* Revision 1.16 2003/02/21 16:02:29 lipp
* Must use reeeeaaaaally long string to make this a real test case.
*
* Revision 1.15 2003/02/20 09:37:24 schlue
* Using driver name instead of product as criterion for special treatment.
*
* Revision 1.14 2003/02/18 15:20:38 schlue
* svalue handling fixed.
*
* Revision 1.13 2002/10/09 08:57:30 schlue
* Missing import statements added.
*
* Revision 1.12 2002/10/09 08:48:07 schlue
* Style checking errors corrected.
*
* Revision 1.11 2002/10/08 12:00:55 schlue
* Test case for serialization added.
* New aspects of test case for setting of connection added.
*
* Revision 1.10 2002/08/30 07:24:25 schlue
* isModified added.
*
* Revision 1.9 2002/08/23 13:17:09 schlue
* Modifications and fixes acc. to code review.
*
* Revision 1.8 2002/08/22 17:17:26 schlue
* Testing of threshold for svalue against DB schema implemented.
* New utility operation for determining column length added.
* Optional oracle test environment.
*
* Revision 1.7 2002/08/22 10:58:53 schlue
* Utility method to determine column length added.
*
* Revision 1.6 2002/08/22 08:36:07 schlue
* Max key length added.
* Garbage collection optimzed.
*
* Revision 1.5 2002/08/20 08:58:42 lipp
* Updated retrieval of jdbc infos.
*
* Revision 1.4 2002/08/20 08:48:22 schlue
* Testcases adapted to new JDBCPersistenceMap code.
*
* Revision 1.3 2002/02/04 15:31:31 lipp
* New special db server properties.
*
* Revision 1.2 2001/12/11 10:27:01 feldgen
* loading jdbc-properties from file
*
* Revision 1.1 2001/12/07 12:33:17 schlue
* Implementation of persistent map finished
*
*
*/
package util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Properties;
import java.sql.Connection;
import java.sql.DriverManager;
import de.danet.an.util.JDBCUtil;
import de.danet.an.util.persistentmaps.JDBCPersistentMap;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Tests the SegmentedResourceBundle
* @version 1.0
*/
public class PersMap extends TestCase {
/**
* Properties to use in test cases
*/
private static Properties props = new Properties();
/**
* Default connection used in test cases.
*/
private static Connection con = null;
/**
* Optional second connection used in test cases.
*/
private static Connection secondCon = null;
/**
* Flag if bacth support should be tested separately
*/
private static boolean testBatchSupport = false;
/**
* Name of DB product.
*/
private static String dbDriver = null;
/**
* Konstruktor zum Erzeugen eines TestCase.
* @param name a <code>String</code> value
*/
public PersMap(String name) {
super (name);
}
/**
* Assembling the test suite
* @return a <code>Test</code> value
* @exception Exception if an error occurs
*/
public static Test suite() throws Exception {
TestSuite suite = new TestSuite();
// load properties from jdbc.properties
props.load(Thread.currentThread().getContextClassLoader()
.getResourceAsStream("jdbc.properties"));
// register database driver
Class.forName(props.getProperty("driver"));
con = DriverManager.getConnection(props.getProperty("database"),
props.getProperty("user"),
props.getProperty("password"));
dbDriver = con.getMetaData().getDriverName();
System.out.println("First Driver: " + dbDriver);
if (JDBCUtil.dbProperties(null, con).supportsBatchUpdates()) {
System.out.println("First driver supports batch");
testBatchSupport = true;
}
boolean withSecondCon = false;
try {
props.load(Thread.currentThread().getContextClassLoader()
.getResourceAsStream("jdbc-other.properties"));
withSecondCon = true;
System.out.println("Testing with two connections");
} catch (NullPointerException exc) {
// To be ignored
}
if (withSecondCon) {
// register second database driver
Class.forName(props.getProperty("driver"));
secondCon = DriverManager.getConnection
(props.getProperty("database"), props.getProperty("user"),
props.getProperty("password"));
System.out.println("Second Driver: "
+ secondCon.getMetaData().getDriverName());
if (JDBCUtil.dbProperties(null, secondCon)
.supportsBatchUpdates()) {
System.out.println("Second driver supports batch");
testBatchSupport = !testBatchSupport;
}
} else {
testBatchSupport = false;
}
System.out.println("Test batch support: " + testBatchSupport);
suite.addTest(new PersMap("setConnection"));
suite.addTest(new PersMap("setSValueMax"));
suite.addTest(new PersMap("setID"));
suite.addTest(new PersMap("storeAndLoad"));
suite.addTest(new PersMap("modifyAndRemove"));
suite.addTest(new PersMap("loadStatement"));
suite.addTest(new PersMap("insertStatement"));
suite.addTest(new PersMap("updateStatement"));
suite.addTest(new PersMap("deleteStatement"));
suite.addTest(new PersMap("copyMap"));
suite.addTest(new PersMap("cleanTable"));
suite.addTest(new PersMap("serialize"));
suite.addTest(new PersMap("nullString"));
return suite;
}
/**
* Test setting of connections.
* This includes support of (two) parallel connections.
* @exception Exception if an error occurs
*/
public void setConnection() throws Exception {
JDBCPersistentMap testMap = new JDBCPersistentMap(null, "Danet");
testMap.setConnection(con);
testMap.put("HSc", "Holger Schl�ter");
testMap.put("MSc", "Matthias Schirm");
testMap.setConnection(con);
testMap.store();
testMap.setConnection(con);
testMap.store();
if (secondCon != null) {
testMap.clear();
testMap.setConnection(secondCon);
assertTrue(testMap.maxKeyLength() == 50);
testMap.put("ALM", "Alex M�ller");
testMap.store();
testMap.clear();
assertTrue(testMap.size() == 0);
testMap.load();
assertTrue(testMap.size() == 1);
}
testMap.setConnection(null);
testMap.setConnection(con);
assertTrue(testMap.maxKeyLength() == 50);
testMap.load();
assertTrue(testMap.size() == 2);
if (secondCon != null) {
testMap.setConnection(secondCon);
testMap.store();
testMap.load();
assertTrue(testMap.size() == 2);
}
testMap.setConnection(con);
if (secondCon != null) {
// Change connection with unsaved modifications
testMap.load();
assertTrue(testMap.size() == 2);
testMap.put("HSc", "Holger Schlueter"); //Update
testMap.remove("MSc"); // Delete
testMap.put("GB", "Gunnar von der Beck"); // Insert
testMap.put("ALM", "Alex M�ller");
assertTrue(testMap.size() == 3);
testMap.setConnection(secondCon);
testMap.store();
testMap.load();
assertTrue(testMap.size() == 3);
}
testMap.setConnection(con);
testMap.clear();
testMap.store();
if (secondCon != null) {
testMap.setConnection(secondCon);
testMap.clear();
testMap.store();
}
}
/**
* Test setting of maximum svalue
* @exception Exception if an error occurs
*/
public void setSValueMax() throws Exception {
JDBCPersistentMap testMap = new JDBCPersistentMap(null, "Danet");
int maxSValue = 0;
testMap.setSValueMax(130764);
assertTrue(testMap.getSValueMax() == 130764);
testMap.setConnection(con);
maxSValue = testMap.getSValueMax();
testMap.setSValueMax(maxSValue+1);
assertTrue("Expected " + maxSValue + ", got " + testMap.getSValueMax(),
testMap.getSValueMax() == maxSValue);
testMap.setSValueMax(maxSValue-1);
assertTrue(testMap.getSValueMax() == maxSValue-1);
testMap.setSValueMax(maxSValue);
assertTrue(testMap.getSValueMax() == maxSValue);
testMap.setConnection(null);
assertTrue(testMap.getSValueMax() == maxSValue);
testMap.setSValueMax(maxSValue+1);
assertTrue(testMap.getSValueMax() == maxSValue+1);
JDBCPersistentMap testMap2 = new JDBCPersistentMap(null, "Danet2");
Connection con2 = null;
int maxSValue2 = 0;
if (secondCon != null) {
con2 = secondCon;
testMap2.setConnection(con2);
maxSValue2 = testMap2.getSValueMax();
testMap2.setSValueMax(maxSValue2+1);
assertTrue(testMap2.getSValueMax() == maxSValue2);
testMap2.setSValueMax(maxSValue2-1);
assertTrue(testMap2.getSValueMax() == maxSValue2-1);
testMap2.setSValueMax(maxSValue2);
assertTrue(testMap2.getSValueMax() == maxSValue2);
} else {
con2 = con;
maxSValue2 = maxSValue;
testMap2.setConnection(con2);
testMap2.setSValueMax(maxSValue2);
assertTrue(testMap2.getSValueMax() == maxSValue2);
}
if (maxSValue < maxSValue2) {
testMap2.setConnection(con);
assertTrue(testMap2.getSValueMax() == maxSValue);
} else if (maxSValue2 < maxSValue) {
testMap.setConnection(con2);
assertTrue(testMap.getSValueMax() == maxSValue2);
}
testMap.setConnection(null);
testMap.setSValueMax(maxSValue+maxSValue2);
assertTrue(testMap.getSValueMax() == maxSValue+maxSValue2);
assertTrue(testMap2.getSValueMax() != maxSValue+maxSValue2);
testMap2.setConnection(null);
testMap2.setSValueMax(maxSValue+maxSValue2);
assertTrue(testMap2.getSValueMax() == maxSValue+maxSValue2);
testMap.setConnection(con);
assertTrue(testMap.getSValueMax() == maxSValue+maxSValue2);
testMap.setConnection(null);
}
/**
* Test setting of IDs
* @exception Exception if an error occurs
*/
public void setID() throws Exception {
JDBCPersistentMap testMap = new JDBCPersistentMap(null, "Danet");
assertTrue(!testMap.isModified());
testMap.setConnection(con);
assertTrue(!testMap.isModified());
testMap.put("HSc", "Holger Schl�ter");
assertTrue(testMap.isModified());
testMap.put("MSc", "Matthias Schirm");
testMap.setConnection(con);
assertTrue(testMap.isModified());
testMap.store();
assertTrue(!testMap.isModified());
testMap.setMapId("Dnaet");
assertTrue(!testMap.isModified());
testMap.load();
assertTrue(!testMap.isModified());
assertTrue(testMap.size() == 0);
testMap.setMapId("Danet");
testMap.load();
assertTrue(testMap.size() == 2);
testMap.clear();
testMap.store();
}
/**
* Test storing an reloading of a map. If (exactly) one
* connection supports batch commands, test for both connections.
* @exception Exception if an error occurs
*/
public void storeAndLoad() throws Exception {
storeAndLoadCon(con);
if (testBatchSupport) {
storeAndLoadCon(secondCon);
}
}
/**
* Test storing an reloading of a map for a given connection
* @exception Exception if an error occurs
* @param usecon connection to be used
*/
private void storeAndLoadCon(Connection useCon) throws Exception {
JDBCPersistentMap storeMap = new JDBCPersistentMap(null, "Danet");
storeMap.setConnection(useCon);
assertTrue(storeMap.maxKeyLength() == 50);
assertTrue(!storeMap.isModified());
storeMap.put("HSc", "Holger Schl�ter");
assertTrue(storeMap.isModified());
storeMap.put("MSc", "Matthias Schirm");
storeMap.put("ML", "Dr. Michael Lipp");
storeMap.put("GB", "Gunnar von de Beck");
StringBuffer sb = new StringBuffer ();
for (int i = 0; i < 1600; i++) {
sb.append ("0123456789");
}
String longString = sb.toString ();
storeMap.put("LONG", longString);
storeMap.put("INT", new Integer(1307));
storeMap.put("NULL", null);
boolean exceptionCaught = false;
try {
storeMap.put(null, null);
} catch (IllegalArgumentException exc) {
exceptionCaught = true;
}
assertTrue(exceptionCaught);
storeMap.store();
storeMap.store();
JDBCPersistentMap loadMap = new JDBCPersistentMap(null, "Danet");
loadMap.setConnection(useCon);
loadMap.load();
// Verfiy that maps do match
assertTrue(loadMap.size() == 7);
// for (Iterator i = loadMap.entrySet().iterator(); i.hasNext ();) {
// Map.Entry e = (Map.Entry)i.next ();
// assertTrue ("Got: " + e.getValue() + " != Put: "
// + storeMap.get (e.getKey()),
// e.getValue ().equals (storeMap.get (e.getKey())));
// }
assertTrue(storeMap.equals(loadMap));
}
/**
* Test modifying and removing map values. If (exactly) one
* connection supports batch commands, test for both connections.
* @exception Exception if an error occurs
*/
public void modifyAndRemove() throws Exception {
modifyAndRemoveCon(con);
if (testBatchSupport) {
modifyAndRemoveCon(secondCon);
}
}
/**
* Test modifying and removing map values.
* @param usecon connection to be used
* @exception Exception if an error occurs
*/
private void modifyAndRemoveCon(Connection useCon) throws Exception {
JDBCPersistentMap storeMap = new JDBCPersistentMap(null, "Danet");
storeMap.setConnection(useCon);
storeMap.load();
assertTrue(!storeMap.isModified());
storeMap.remove("HSc");
assertTrue(storeMap.isModified());
storeMap.remove("MSc");
storeMap.remove("RSc");
storeMap.put("ML", "Dr. Michael Lipp");
storeMap.put("ROt", "Ralf Ott");
storeMap.put("HDO", null);
storeMap.put("ALM", "Alex M�ller");
storeMap.put("MSc", "Matthias Schirm");
storeMap.put("ALM", "Alexander M�ller");
StringBuffer sb = new StringBuffer ();
for (int i = 0; i < 1600; i++) {
sb.append ("0123456789");
}
String longString = sb.toString ();
storeMap.put("GB", longString);
storeMap.put("HSc", "Holger Schlueter");
storeMap.put("NULL", "NULL");
storeMap.remove("HDO");
storeMap.remove("HDO");
storeMap.put("LONG", "Gunnar von der Beck");
storeMap.remove("INT");
storeMap.remove("INT");
storeMap.remove("ROt");
storeMap.store();
storeMap.store();
JDBCPersistentMap loadMap = new JDBCPersistentMap(null, "Danet");
loadMap.setConnection(useCon);
loadMap.load();
// Verfiy that maps do match
assertTrue(loadMap.size() == 7);
assertTrue(storeMap.equals(loadMap));
}
/**
* Test setting the loadStatement
* @exception Exception if an error occurs
*/
public void loadStatement() throws Exception {
JDBCPersistentMap map = new JDBCPersistentMap(null, "Danet");
map.setConnection(con);
String oldStatement = map.getLoadStatement();
map.setLoadStatement("ILLEGAL STATEMENT");
String newStatement = map.getLoadStatement();
// Verfiy that new statement ist used
assertTrue(newStatement.equals("ILLEGAL STATEMENT"));
boolean exceptionCaught = false;
try {
map.load();
} catch( IOException exc ) {
exceptionCaught = true;
}
assertTrue(exceptionCaught);
}
/**
* Test setting the insertStatement
* @exception Exception if an error occurs
*/
public void insertStatement() throws Exception {
JDBCPersistentMap map = new JDBCPersistentMap(null, "Danet");
map.setConnection(con);
map.load();
String oldStatement = map.getInsertStatement();
map.setInsertStatement("ILLEGAL STATEMENT");
String newStatement = map.getInsertStatement();
assertTrue(newStatement.equals("ILLEGAL STATEMENT"));
// Verify that nothing is done (optimizing)
map.put("HSc", "Holger Schlueter"); // Already existing -> modify
map.store();
// Verfiy that new statement ist used
map.put("HDO", "Dr. O.");
boolean exceptionCaught = false;
try {
map.store();
} catch( IOException exc ) {
exceptionCaught = true;
}
assertTrue(exceptionCaught);
map.setInsertStatement(oldStatement);
map.store();
}
/**
* Test setting the updateStatement
* @exception Exception if an error occurs
*/
public void updateStatement() throws Exception {
JDBCPersistentMap map = new JDBCPersistentMap(null, "Danet");
map.setConnection(con);
map.load();
String oldStatement = map.getUpdateStatement();
map.setUpdateStatement
("ILLEGAL STATEMENT WHERE MAPID = ? AND ITEM = ?");
String newStatement = map.getUpdateStatement();
assertTrue(newStatement.equals
("ILLEGAL STATEMENT WHERE MAPID = ? AND ITEM = ?"));
// Verify that nothing is done (optimizing)
map.put("HsC", "Holger Schlueter"); // New key -> insert
map.store();
// Verfiy that new statement ist used
map.put("HSc", "Holger Schl�ter");
boolean exceptionCaught = false;
try {
map.store();
} catch( IOException exc ) {
exceptionCaught = true;
}
assertTrue(exceptionCaught);
map.setUpdateStatement(oldStatement);
map.store();
}
/**
* Test setting the deleteStatement
* @exception Exception if an error occurs
*/
public void deleteStatement() throws Exception {
JDBCPersistentMap map = new JDBCPersistentMap(null, "Danet");
map.setConnection(con);
map.load();
String oldStatement = map.getDeleteStatement();
map.setDeleteStatement("ILLEGAL STATEMENT");
String newStatement = map.getDeleteStatement();
assertTrue(newStatement.equals("ILLEGAL STATEMENT"));
// Verify that nothing is done (optimizing)
map.remove("HSC"); // Not existing
map.store();
// Verfiy that new statement ist used
map.remove("ALM");
boolean exceptionCaught = false;
try {
map.store();
} catch( IOException exc ) {
exceptionCaught = true;
}
assertTrue(exceptionCaught);
map.setDeleteStatement(oldStatement);
map.store();
}
/**
* Copying a map
* @exception Exception if an error occurs
*/
public void copyMap() throws Exception {
JDBCPersistentMap map1 = new JDBCPersistentMap(null, "Danet");
map1.setConnection(con);
assertTrue(map1.size() == 0);
map1.load();
assertTrue(map1.size() == 8);
JDBCPersistentMap map2 = new JDBCPersistentMap(null, "Danet2");
map2.setConnection(con);
assertTrue(map2.size() == 0);
map2.putAll(map1);
assertTrue(map2.size() == 8);
map2.store();
JDBCPersistentMap map3= new JDBCPersistentMap(null, "Danet2");
map3.setConnection(con);
assertTrue(map3.size() == 0);
map3.load();
assertTrue(map3.size() == 8);
map2.clear();
map2.store();
map3.load();
assertTrue(map3.size() == 0);
}
/**
* Cleaning the table
* @exception Exception if an error occurs
*/
public void cleanTable() throws Exception {
JDBCPersistentMap map
= new JDBCPersistentMap(null, "Danet","DefaultPersistenceMap");
map.setConnection(con);
map.store(); // Clear DB table
map.put("HSc", "Holger Schl�ter");
map.put("MSc", "Matthias Schirm");
map.put("ML", "Dr. Michael Lipp");
map.put("GB", "Gunnar von de Beck");
map.put("INT", new Integer(1307));
map.put("NULL", null);
assertTrue(map.size() == 6);
map.load(); // Load empty map
assertTrue(map.size() == 0);
map.put("HSc", "Holger Schl�ter");
map.put("MSc", "Matthias Schirm");
map.put("ML", "Dr. Michael Lipp");
map.put("GB", "Gunnar von de Beck");
map.put("INT", new Integer(1307));
map.put("NULL", null);
map.store();
map.load();
assertTrue(map.size() == 6);
map.clear(); // Clear the map
assertTrue(map.size() == 0);
map.store();
map.load();
assertTrue(map.size() == 0);
}
/**
* Testing serialization
* @exception Exception if an error occurs
*/
public void serialize() throws Exception {
JDBCPersistentMap map
= new JDBCPersistentMap(null, "Danet","DefaultPersistenceMap");
map.setConnection(con);
map.put("HSc", "Holger Schl�ter");
map.put("ML", "Dr. Michael Lipp");
map.put("GB", "Gunnar von de Beck");
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream o = new ObjectOutputStream(bo);
o.writeObject(map);
o.close();
map.remove("HSc");
map.store();
map.load();
assertTrue(map.size() == 2); // Two entries stored in DB
ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream i = new ObjectInputStream(bi);
map = (JDBCPersistentMap)i.readObject(); // Three object read
assertTrue(map.size() == 3);
i.close();
map.setConnection(con);
map.store(); // Three objects stored
map.clear();
assertTrue(map.size() == 0);
map.load(); // All three objects read
assertTrue(map.size() == 3);
}
/**
* Testing null and "" distinction.
* @exception Exception if an error occurs
*/
public void nullString() throws Exception {
JDBCPersistentMap map
= new JDBCPersistentMap(null, "Danet","DefaultPersistenceMap");
map.setConnection(con);
map.put("nullString", null);
map.put("emptyString", "");
map.store();
map.load();
assertTrue (map.get ("nullString") == null);
assertTrue (map.get("emptyString").equals (""));
}
}