package org.sf.mustru.test;
import java.io.UnsupportedEncodingException;
import junit.framework.TestCase;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.sf.mustru.docs.*;
import org.sf.mustru.utils.Constants;
import org.sf.mustru.utils.DbTools;
import org.sf.mustru.utils.StringTools;
import com.sleepycat.bind.tuple.TupleBinding;
import com.sleepycat.bind.tuple.TupleInput;
import com.sleepycat.bind.tuple.TupleOutput;
import com.sleepycat.je.DatabaseEntry;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.SecondaryDatabase;
import com.sleepycat.je.SecondaryKeyCreator;
public class TestDbTools extends TestCase
{
private DbTools dbt = null;
private static String DBDIR = Constants.DBTESTDIR; //*-- testing directory for the database environment
private static String DBNAME1 = "db1"; //*-- name of database 1
private static String DBNAME2 = "db2"; //*-- name of database 2
private static String SECDB = "secdb"; //*-- name of secondary database
private static Logger logger = Logger.getLogger(TestDbTools.class.getName());
protected void setUp()
{ PropertyConfigurator.configure (Constants.LOG4J_FILE); }
//*-- Create / Drop a database
public void testCreateDropDB()
{
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue("t1 create", dbt.createDB(DBNAME1, true) );
assertTrue("t1 drop", dbt.dropDB(DBNAME1) );
dbt.closeEnv();
System.out.println("Completed create and drop tests...");
}
//*-- Open and close a database
public void testOpenClose()
{
//*-- first create the database
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue("t2 create", dbt.createDB(DBNAME1, true) );
dbt.closeEnv();
//*-- open / close the database in read only mode
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue("t2 open read only", dbt.openDB(DBNAME1, true) );
assertNotNull("t1 current DB null", dbt.getCurrentDB() );
assertTrue("t2 close", dbt.closeDB());
dbt.closeEnv();
//*-- Open / close an existing database in r/w mode
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue("t2 open read write", dbt.openDB(DBNAME1, false) );
assertTrue("t2 close", dbt.closeDB());
dbt.closeEnv();
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue("t2 drop", dbt.dropDB(DBNAME1) );
dbt.closeEnv();
System.out.println("Completed open and close tests......");
}
//*-- try to open a non-existing database
public void testOpenDB()
{
//*-- create a database
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue("t3 create", dbt.createDB(DBNAME1, true) );
dbt.closeEnv();
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertFalse("t3 create", dbt.openDB("Bad DB", true) );
dbt.closeEnv();
//*-- drop the database
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue("t3 drop", dbt.dropDB(DBNAME1) );
dbt.closeEnv();
}
//*-- Drop an existing database
public void testDropDB()
{
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue("t4 create", dbt.createDB(DBNAME1, true) );
assertTrue("t4 drop", dbt.dropDB(DBNAME1) );
//*-- try to drop a non-existent databse
assertFalse("t4 bad drop", dbt.dropDB("NotDB") );
dbt.closeEnv();
System.out.println("Completed drop test.....");
}
public void testGetNextKey()
{
//*-- create an empty database
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue("t5 create", dbt.createDB(DBNAME2, true) );
dbt.closeEnv();
//*-- load the database with ten records
int numRecords = 10; loadDB("t4", numRecords, false, DBNAME2);
String keyString = ++numRecords + "";
//*-- get the next key
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue("t5 open read only", dbt.openDB(DBNAME2, true) );
String dbKey = null; String nextKey = null;
try { dbKey = dbt.getNextKey(); nextKey = StringTools.fillin( keyString, 10, false, '0', 10 - keyString.length()); }
catch (DatabaseException dbe) { logger.error("Could not get next key " + dbe.getMessage() ); }
assertEquals("t5 get n+1 key", nextKey, dbKey );
assertTrue("t5 close", dbt.closeDB());
dbt.closeEnv();
//*-- drop the database
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue("t5 drop", dbt.dropDB(DBNAME2) );
dbt.closeEnv();
System.out.println("Completed get next key test...");
}
public void testFetch()
{
//*-- create an empty database
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue("t6 create", dbt.createDB(DBNAME2, true) );
dbt.closeEnv();
// *-- load a few rows
loadDB("t6", 5, false, DBNAME2);
//*-- open the database with primary key
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue("t6 open ", dbt.openDB(DBNAME2, false) );
assertNotNull("t6 current null", dbt.getCurrentDB() );
//*-- fetch the document and verify
String dbKey = "0000000002";
DatabaseEntry data = new DatabaseEntry(); TestDoc doc = new TestDoc();
if (dbt.fetch(dbKey, data) )
{ doc = (TestDoc) doc.getBdbBinding().entryToObject(data); }
String contents = "contents " + 2;
assertEquals("t6", contents, doc.getContents() );
dbt.closeDB(); dbt.closeEnv();
//*-- drop the database
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue("t6 drop", dbt.dropDB(DBNAME2) );
dbt.closeEnv();
System.out.println("Completed fetch document...");
}
public void testCount()
{
//*-- create an empty database
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue("t6a create", dbt.createDB(DBNAME2, true) );
dbt.closeEnv();
//*-- load a few rows
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
loadDB("t6a", 5, false, DBNAME2);
assertEquals("t6a size 1", 5, dbt.sizeDB(DBNAME2));
dbt.closeDB(); dbt.closeEnv();
//*-- drop the database
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue("t6a drop", dbt.dropDB(DBNAME2) );
dbt.closeEnv();
}
public void testDelete()
{
//*-- create an empty database
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue("t7 create", dbt.createDB(DBNAME2, true) );
dbt.closeEnv();
// *-- load a few rows
loadDB("t7", 10, false, DBNAME2);
//*-- fetch a document, delete the document and attempt to fetch it again
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue( "t7 open ", dbt.openDB(DBNAME2, false) );
String dbKey = "0000000002"; DatabaseEntry data = new DatabaseEntry();
assertTrue( "t7 fetch not successful", dbt.fetch(dbKey, data) );
data = new DatabaseEntry();
assertTrue("t7 delete failed", dbt.delete(dbKey) );
assertFalse( "t7 fetch should have failed", dbt.fetch(dbKey, data) );
dbt.closeDB(); dbt.closeEnv();
//*-- try to delete a non-existent row
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue( "t7 open ", dbt.openDB(DBNAME2, false) );
dbKey = "Bad key";
assertFalse("t7 this delete should fail", dbt.delete(dbKey) );
dbt.closeDB(); dbt.closeEnv();
//*-- drop the database
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue("t7 drop", dbt.dropDB(DBNAME2) );
dbt.closeEnv();
System.out.println("Completed delete document...");
}
public void testUpdate()
{
//*-- create an empty database
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue("t8 create", dbt.createDB(DBNAME2, true) );
dbt.closeEnv();
// *-- load a few rows
loadDB("t8", 10, false, DBNAME2);
//*-- fetch a record, update its contents and verify the update
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue( "t8 open ", dbt.openDB(DBNAME2, false) );
String dbKey = "0000000002"; DatabaseEntry data = new DatabaseEntry();
assertTrue("t8 fetch", dbt.fetch(dbKey, data) );
TestDoc doc = new TestDoc();
doc = (TestDoc) doc.getBdbBinding().entryToObject(data);
String newContents = "new contents"; doc.setContents(newContents);
assertTrue("t8 update", dbt.update(dbKey, (StoreAbleInterface) doc) );
dbt.fetch(dbKey, data);
doc = new TestDoc();
doc = (TestDoc) doc.getBdbBinding().entryToObject(data);
assertEquals("t8 content was not updated", newContents, doc.getContents() );
dbt.closeDB(); dbt.closeEnv();
//*-- drop the database
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue("t8 drop", dbt.dropDB(DBNAME2) );
dbt.closeEnv();
System.out.println("Completed update of document....");
}
public void testExists()
{
//*-- create an empty database
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue("t9 create", dbt.createDB(DBNAME2, true) );
dbt.closeEnv();
// *-- load a few rows
loadDB("t9", 10, false, DBNAME2);
//*-- check if a row exists with the given key
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue( "t9 open ", dbt.openDB(DBNAME2, true) );
try
{
assertTrue(" t9 exists should be OK", dbt.exists("0000000004") );
assertFalse(" t9 exists should not be OK", dbt.exists("0000000099") );
}
catch (DatabaseException de)
{ System.out.println("Py.. key problem " + de.getMessage()); }
finally { dbt.closeDB(); dbt.closeEnv(); }
//*-- drop the database
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue("t9 drop", dbt.dropDB(DBNAME2) );
dbt.closeEnv();
System.out.println("Completed exists with py key");
}
public void testcreateSecDB()
{
//*-- create an empty database
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
boolean dupFlag = false;
assertTrue("t10 create", dbt.createDB(DBNAME2, true, dupFlag) );
dbt.closeEnv();
// *-- load a few rows
loadDB("t10", 10, dupFlag, DBNAME2);
//*-- create the secondary database
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
dbt.openDB(DBNAME2, false, dupFlag);
DBKeyCreator skc = new DBKeyCreator(new TestDocBinding() );
assertTrue("t10 create SEC ", dbt.createSecDB(SECDB, false, skc) );
//*-- drop the secondary database
assertTrue("t10 drop SEC", dbt.dropSecDB(SECDB ) );
dbt.closeDB(); dbt.closeEnv();
//*-- drop the database
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue("t10 drop", dbt.dropDB(DBNAME2) );
dbt.closeEnv();
System.out.println("Completed create/drop sec DB");
}
public void testOpenSecDB()
{
//*-- create an empty database
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
boolean dupFlag = false;
assertTrue("t11 create", dbt.createDB(DBNAME2, true, dupFlag) );
dbt.closeEnv();
// *-- load a few rows
loadDB("t11", 10, dupFlag, DBNAME2);
//*-- create the secondary database
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
dbt.openDB(DBNAME2, false, dupFlag);
DBKeyCreator skc1 = new DBKeyCreator(new TestDocBinding() );
assertTrue("t11 create SEC ", dbt.createSecDB(SECDB, false, skc1) );
dbt.closeDB(); dbt.closeEnv();
//*-- open the secondary database
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
dbt.openDB(DBNAME2, false, dupFlag);
DBKeyCreator skc2 = new DBKeyCreator(new TestDocBinding() );
assertTrue("t11 open SEC", dbt.openSecDB(SECDB, false, skc2) );
assertTrue("t11 close SEC", dbt.closeSecDB() );
dbt.closeDB(); dbt.closeEnv();
//*-- drop the database
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
dbt.openDB(DBNAME2, false, dupFlag);
assertTrue("t11 open SEC", dbt.openSecDB(SECDB, false, skc2) );
assertTrue("t11 close SEC", dbt.closeSecDB() );
assertTrue("t11 drop", dbt.dropDB(DBNAME2) );
dbt.closeEnv();
System.out.println("Completed open/close sec DB");
}
public void testFetchSecDB()
{
//*-- create an empty database
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
boolean dupFlag = false;
assertTrue("t12 create", dbt.createDB(DBNAME2, true, dupFlag) );
dbt.closeEnv();
// *-- load a few rows
loadDB("t12", 10, dupFlag, DBNAME2);
//*-- create the secondary database
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
dbt.openDB(DBNAME2, false, dupFlag);
DBKeyCreator skc1 = new DBKeyCreator(new TestDocBinding() );
assertTrue("t12 create SEC ", dbt.createSecDB(SECDB, false, skc1) );
dbt.closeDB(); dbt.closeEnv();
//*-- open the secondary database
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
dbt.openDB(DBNAME2, false, dupFlag);
DBKeyCreator skc2 = new DBKeyCreator(new TestDocBinding() );
assertTrue("t12 create SEC ", dbt.createSecDB(SECDB, false, skc2) );
assertTrue("t12 open SEC", dbt.openSecDB(SECDB, false, skc2) );
//*-- fetch a single entry
DatabaseEntry dbe = dbt.fetchSec("1");
assertNotNull("t12 fetch SEC", dbe );
TestDoc doc = new TestDoc(); doc = (TestDoc) doc.getBdbBinding().entryToObject(dbe);
assertEquals("t12 contents SEC", "contents 2", doc.getContents() );
//*-- fetch an array of entries
DatabaseEntry[] dbeArray = dbt.fetchSecArray("3");
assertNotNull("t12 fetch SEC Array", dbeArray );
for (int i = 0; i < dbeArray.length; i++)
{ TestDoc doc1 = new TestDoc(); doc1 = (TestDoc) doc1.getBdbBinding().entryToObject(dbeArray[i]);
System.out.println("Sec. Key: " + doc1.getSeckey() + " Contents: " + doc1.getContents() );
}
assertTrue("t12 close SEC", dbt.closeSecDB() );
dbt.closeDB(); dbt.closeEnv();
//*-- drop the database
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
dbt.openDB(DBNAME2, false, dupFlag);
assertTrue("t12 drop", dbt.dropDB(DBNAME2) );
dbt.closeEnv();
System.out.println("Completed fetch sec DB");
}
public void testMultipleDB()
{
//*-- create two dbs
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
boolean dupFlag = false;
assertTrue("t13 create db1", dbt.createDB(DBNAME1, true, dupFlag) );
assertTrue("t13 create db2", dbt.createDB(DBNAME2, true, dupFlag) );
dbt.closeEnv();
loadDB("t13", 10, dupFlag, DBNAME1);
loadDB("t13a", 20, dupFlag, DBNAME2);
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
dupFlag = false;
assertTrue("t13 open db1", dbt.openDB(DBNAME1, true, dupFlag) );
assertTrue("t13 open db2", dbt.openDB(DBNAME2, true, dupFlag) );
//*-- fetch a single entry from DBNAME1
dbt.setCurrentDB(DBNAME1);
String dbKey = "0000000002"; DatabaseEntry data = new DatabaseEntry();
assertTrue("t13 fetch", dbt.fetch(dbKey, data) );
TestDoc doc = new TestDoc();
doc = (TestDoc) doc.getBdbBinding().entryToObject(data);
assertEquals("t13 contents from 1", "contents 2", doc.getContents());
//*-- fetch a single entry from DBNAME2
dbt.setCurrentDB(DBNAME2);
dbKey = "0000000012"; data = new DatabaseEntry();
assertTrue("t13 fetch", dbt.fetch(dbKey, data) );
doc = new TestDoc();
doc = (TestDoc) doc.getBdbBinding().entryToObject(data);
assertEquals("t13 contents from 2", "contents 12", doc.getContents());
assertTrue("t13 close db1", dbt.closeDB(DBNAME1) );
assertTrue("t13 close db2", dbt.closeDB(DBNAME2) );
dbt.closeEnv();
//*-- drop the two dbs
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue("t13 drop db2", dbt.dropDB(DBNAME1) );
assertTrue("t13 drop db1", dbt.dropDB(DBNAME2) );
dbt.closeEnv();
System.out.println("Completed multiple databases test");
}
public boolean loadDB(String testNo, int nrows, boolean dupFlag, String dbname)
{
//*-- open the database
dbt = new DbTools(); dbt.openEnv(DBDIR, false);
assertTrue( testNo + " open ", dbt.openDB(dbname, false, dupFlag) );
assertNotNull(testNo + " py. null", dbt.getCurrentDB() );
//*-- insert n rows in the database
for (int i = 1; i <= nrows; i++)
{
//*-- build a dummy document
Integer secKey = new Integer( i / 2);
TestDoc idoc = new TestDoc("contents " + i, secKey.toString() );
//*-- get the next key
try
{
String indexString = "" + i;
String nextKey = StringTools.fillin( "" + i, 10, false, '0', 10 - indexString.length());
String dbKey = dbt.getNextKey();
assertEquals(testNo + " unmatched key", nextKey, dbKey );
//*-- insert an entry
assertTrue(testNo + " insert", dbt.insert(dbKey, idoc) );
}
catch (DatabaseException dbe)
{ logger.error("Failed to get next key " + dbe.getMessage() ); }
} //*-- end of for
dbt.closeDB(); dbt.closeEnv();
return true;
}
public void ttestDumpDB()
{
dbt = new DbTools(); dbt.openEnv(Constants.getDBDIR(), false);
String dbName = "QUERY_DB"; TupleBinding tpb = new IndexableDoc().getBdbBinding();
String filename = "/home/manuk/out.txt";
assertTrue("t5 create", dbt.dumpDB(dbName, tpb, filename) );
dbt.closeEnv();
System.out.println("Completed database dump test");
}
protected void tearDown()
{
DbTools dbt = new DbTools(); dbt.openEnv(DBDIR, false);
/* List dbnames = dbt.fetchDBnames();
for (int i = 0; i < dbnames.size(); i++)
{ dbt.dropDB((String) dbnames.get(i) );
System.out.println("tearDown: dropped " + (String) dbnames.get(i));
}*/
dbt.closeEnv();
}
}
/**
* Test object to store in the database
*/
class TestDoc implements StoreAbleInterface
{
public TupleBinding bdbBinding = null;
public String contents = "";
public String seckey = "";
public TestDoc()
{ setBdbBinding(new TestDocBinding() ); }
public TestDoc(String contents, String seckey)
{ this(); setContents(contents); setSeckey(seckey); }
public TupleBinding getBdbBinding()
{ return bdbBinding; }
public void setBdbBinding( TupleBinding bdbBinding)
{ this.bdbBinding = bdbBinding; }
public String getContents()
{ return (this.contents); }
public void setContents ( String contents )
{ this.contents = contents; }
public String getSeckey()
{ return seckey; }
public void setSeckey(String seckey)
{ this.seckey = seckey; }
}
/**
* Binding for test object
*
*/
class TestDocBinding extends TupleBinding
{
//*-- create an IndexableDoc object from the input database entry
public Object entryToObject(TupleInput ti)
{
TestDoc o = new TestDoc();
o.setContents( ti.readString() );
o.setSeckey(ti.readString() );
return o;
}
//*-- create a database entry from the indexable doc
public void objectToEntry(Object o, TupleOutput to)
{
TestDoc id = (TestDoc) o;
to.writeString(id.getContents());
to.writeString(id.getSeckey() );
}
}
class DBKeyCreator implements SecondaryKeyCreator
{
private TupleBinding ti;
public DBKeyCreator( TupleBinding ti) { this.ti = ti; }
/**
* Create a secondary key from the file signature
* @param SecondaryDatabase sbd
* @param DatabaseEntry key
* @param DatabaseEntry data
* @param DatabaseEntry result returned to caller
*/
public boolean createSecondaryKey( SecondaryDatabase sbd, DatabaseEntry key, DatabaseEntry data, DatabaseEntry result)
{
try
{ TestDoc idoc = (TestDoc) ti.entryToObject(data);
String seckey = idoc.getSeckey();
result.setData(seckey.getBytes("UTF-8"));
}
catch (UnsupportedEncodingException ue)
{ System.out.println("Encoding error in create secondary key" + ue.getMessage()); }
return true;
}
}