// file: VarmintDB.java
//
import java.util.*;
import java.sql.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;


//*************************************
//
// ISIP_Varmint_VarmintDB
//
//*************************************
public class VarmintDB  {

    //************************************
    //
    // private data
    //
    //************************************

    Connection conn;
    Statement stmt;
    ResultSet result;

    static public String _URL = "jdbc:mysql://Infoserv.ERC.MsState.Edu:3306/cavs-hse-varmint";
    static public String _user = "ies";
    static public String _pWord = "ies4mysql";
    int bNum = 0;
    ThreadDemo thread = null;

    //************************************
    //
    // constructor methods
    //
    //************************************

    // default constructor
    //
    public VarmintDB() {

	try{
	    Class.forName("com.mysql.jdbc.Driver").newInstance();
	}
	catch(Exception e){
	    //	    System.err.println("Unable to load driver.");
	    e.printStackTrace();

	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "VarmintDB: Database error");
	    
	}

	thread = new ThreadDemo(this);
	
	
	
	//  This batch of code will make the connection status frame 
	//  appear.  This will remain for debugging purposes.
	//

	//thread.addWindowListener(new WindowAdapter() {
	//	public void windowClosing(WindowEvent e) {
	//	    System.exit(0);
	//	}
	//    });
	
	//thread.pack();
	//thread.setVisible(true);
	
	
	thread.doAction();
    
	try{	    
	    // initialize the statment object
	    //
	    stmt = conn.createStatement();
	}
	catch(SQLException e){
	    
	    //	    System.out.println("No statement");
	    e.printStackTrace();

	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "VarmintDB: Database error");

	}
	
	// done
	//
    }


    //************************************
    //
    // inspector methods
    //
    //************************************

    public Vector getBugList(String query){


	// if the query is not a select statement, error and 
	// return an empty vector
	//
	if (!query.toLowerCase().trim().startsWith("select")) {

	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, "Only select queries may be run from the SQL box.  Please try again.");
	    

	    return new Vector(1,1);

	}

	try{
	    // run the query and put the results into the ResultSet
	    //
	    thread.doAction();
	    result = stmt.executeQuery(query);
	}
	catch(SQLException e){

	    // todo
	    //

	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, "That was not a valid query."+
					  "Please try again.");
	    //e.printStackTrace();
	}

	// format the results into vectors of vectors of string pairs; return
	//
	return formatBugList(result);

	// done
	//

    }
    
    public void setConfigVal(String cname, String cval, String cdef) {
	
	String query = "update config set cvals='"+cval+"', cdef='"+cdef+"' where cname='"+cname+"'";
	
	try {
	    thread.doAction();
	    stmt.executeUpdate(query);
	}
	catch(SQLException e){

	    // todo
	    //
	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "getConfigVal: Database error");
	 
	    e.printStackTrace();
	}
    }
	    

    public String[] getConfigVal(String cname) {
	
	String query = "select cvals, cdisplay, cdef from config where cname='"+
	    cname+"'";
	
	String[] ret = new String[3];

	try{
	
	    // run query and put results in a ResultSet
	    //
	    thread.doAction();
	    result = stmt.executeQuery(query);
	    
	    result.next();
	    
	    ret[0] = result.getString("cdisplay");
	    ret[1] = result.getString("cvals");
	    ret[2] = result.getString("cdef");
	}
	catch(SQLException e){

	    // todo
	    //
	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "getConfigVal: Database error");
	 
	    e.printStackTrace();
	}
	
	return ret;
    }

    public Vector getConfig(){

	// format the query that retrieves the config table
	//
	String query = "select cname,cvals,cdef from config";

	try{
	
	    // run query and put results in a ResultSet
	    //
	    thread.doAction();
	    result = stmt.executeQuery(query);
	}
	catch(SQLException e){

	    // todo
	    //
	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "getConfig: Database error");
	 
	    //   e.printStackTrace();

	}

	// format results in vecotrs of vectors of string pairs; return
	//
	return formatBugVector(result);

	// done
	//

    }
    public Vector getConfig(String db){

	// format the query that retrieves the config table
	//
	// String query = "select cname,cdisplay,cvals,cdef from config";
	String query = "select cname,cvals,cdef from config";

	try{
	
	    thread.doAction();
	    // run query and put results in a ResultSet
	    //
	    result = stmt.executeQuery(query);
	}
	catch(SQLException e){

	    // todo
	    //
	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "getConfig(db): Database error");
	    e.printStackTrace();

	}

	// format results in vecotrs of vectors of string pairs; return
	//
	Vector temp = formatBugVector(result);

	// set up some counters
	//
	int n = temp.size();
	int i = 0;

	// look for the fieldName in temp
	//
	while (i < n) {
	    // records are stored as vectors
	    // we search by the inner vector's elt zero
	    //  
	    // we have to cast roadkill.elementAt(i) to a Vector
	    // to check its inner element
	    //
	    String column = ((String)((Vector)
				      temp.elementAt(i)).elementAt(0));
	
	    if (column.equals("Component")) {
		// we found the component field, set its list
		// the list is stored in a vector at position 1
		//

		((Vector)temp.elementAt(i)).setElementAt(getComponent(db), 1);
		return temp;

	    }
	    else {
		// we didn't find it, roll on
		//
		i++;
	    }
	}	

	// if we make it back out here, something went wrong
	// return an empty-component configuration
	// this is an error condition
	//
	return formatBugList(result);
    
	// done
	//

    }

    public String getComponent(String db){

	// format the query that retrieves the componet list
	//
	String query = "select DB,component from component where DB = \'" +
	    db + "\'";
	
	try{

	    thread.doAction();
	    // run the query  and put results in a ResultSet
	    //
	    result = stmt.executeQuery(query);
	}
	catch(SQLException e){

	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "getComponent: Database error.");
	    e.printStackTrace();

	}

	//format the results in vectors of vectors of string pairs
	//
	Vector temp = formatBugVector(result);

	// set up some counters
	//
	int n = temp.size();
	int i = 0;

	// look for the fieldName in temp
	//
	while (i < n) {
	    // records are stored as vectors
	    // we search by the inner vector's elt zero
	    //
	    String column = ((String)((Vector)
				      temp.elementAt(i)).elementAt(0));
	    // we have to cast roadkill.elementAt(i) to a Vector
	    // to check its inner element
	    //
	    //System.out.println(((Vector)roadkill.elementAt(i)).elementAt(0));
	    if (column.equals(db)) {
		// we found the field, return its value
		// the value is stored in a vector at position 1
		//

		// we have to cast roadkill.elementAt(i) to a Vector to
		// check its inner element
		// then we have to cast all that back to a String to return
		//
		return "software,documentation," + (String)((Vector)temp.
				    elementAt(i)).elementAt(1);
		
	    }
	    else {
		// we didn't find it, roll on
		//
		i++;
	    }
	}	

	// we didn't find the component list requested 
	// return db, it's better than nothing
	// 
	return "software,documentation";

    }

    public Vector getAllComponents() {

	Vector returnVector = new Vector(10,10);

	returnVector.add("Software");
	returnVector.add("Documentation");
	

	// format the query that retrieves the componet list
	//
	String query = "select DB,component from component order by DB";
	
	try{
	    
	    thread.doAction();
	    // run the query  and put results in a ResultSet
	    //
	    result = stmt.executeQuery(query);
	}
	catch(SQLException e){
	    
	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "getComponent: Database error.");
	    e.printStackTrace();

	}
	
	//format the results in vectors of vectors of string pairs
	//
	Vector temp = formatBugVector(result);
	
	// set up some counters
	//
	int n = temp.size();
	int i = 0;

	// look for the fieldName in temp
	//
	while (i < n) {
	    StringTokenizer tokenizer =
		new StringTokenizer(( (String)((Vector)temp.
					       elementAt(i)).elementAt(1)),
				    "," );

	    while (tokenizer.hasMoreTokens()) {
		
		returnVector.add(tokenizer.nextToken());
	    }
		
	    i++;
	}
  
	// we didn't find the component list requested 
	// return db, it's better than nothing
	// 
	return returnVector;
       
    }

    public String getDefault(String config_name) {

	// format the query that retrieves the componet list
	//
	String query = "select cdef from config where cname= \'" + config_name + "\'";
	String def = "";

	try{
	    thread.doAction();
	    // run the query  and put results in a ResultSet
	    //
	    result = stmt.executeQuery(query);
	    result.next();
	    def = result.getString(1);
	}
	catch(SQLException e){

	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "getDefault: Database error");
	    e.printStackTrace();
	}
	
	return def;
    }

    public Bug getBug(String database, int bugNumber) {

	// format query that retrieves selected bug
	//
	String query = "select * from bug_list where DBase = \'" + database +
	    "\' and BugNumber = " + bugNumber + " ";

	try{

	    thread.doAction();

	    // run the query and put the results in a ResultSet
	    //
	    result = stmt.executeQuery(query);
	}
	catch(SQLException e){

	    // todo
	    //
	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "getBug: Database error");
	    e.printStackTrace();
	}
 
	// format the results in a Bug; return
	//
	return formatBug(result);

	// done
	//

    }
    
    public boolean isLockedBy(String database, String bugNumber, 
			      String user) {
	/*
	// format query that retrieves lock for selected bug
	//
	String query = "select LockedBy from bug_list where DBase = \'" 
	    + database + "\' and BugNumber = " + bugNumber + " ";
	
	String locked_by = "";
	try {

	    // run the query and put the results in a ResultSet
	    //
	    thread.doAction();
	    result = stmt.executeQuery(query);
	    result.next();
	    locked_by = result.getString(1);
	}
	catch(SQLException e){

	    // todo
	    //
	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "isLocked: Database error");
	    e.printStackTrace();
	}
	
	if (!locked_by.equals(user)) {
	    if (!locked_by.equals("")) {
		JFrame frame = new JFrame("Warning");
		JOptionPane.showMessageDialog(frame, 
					      "Bug "+database+":"+bugNumber+
					      " is locked by "+locked_by);
	    }
	    return false;
	}
	*/
	return true;
    }

    public boolean lockBug(String database, String bugNumber, String user) {

	
	// make sure it is locked by no one
	//
	if (!isLockedBy(database, bugNumber,"")) {
	    return false;
	}
	
	String query = "update bug_list set LockedBy='"+user+
	    "' where DBase = \'" 
	    + database + "\' and BugNumber = " + bugNumber + " ";
	try {
	    
	    // run the query and put the results in a ResultSet
	    //
	    thread.doAction();
	    int changed = stmt.executeUpdate(query);
	}
	catch(SQLException e){
	    
	    // todo
	    //
	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "lockBug: Database error");
	    e.printStackTrace();
	}

	// done
	//
	return true;
    }

    public boolean unLockBug(String database, String bugNumber, String user) {

	// make sure it is locked by user
	//
	if (!isLockedBy(database, bugNumber,user)) {
	    return false;
	}
	
	String query = "update bug_list set LockedBy='' where DBase = \'" 
	    + database + "\' and BugNumber = " + bugNumber + " ";
	try {
	    
	    // run the query and put the results in a ResultSet
	    //
	    thread.doAction();
	    int changed = stmt.executeUpdate(query);
	}
	catch(SQLException e){
	    
	    // todo
	    //
	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "unLockBug: Database error");
	    e.printStackTrace();
	}

	// done
	//
	return true;
    }

    public boolean unLockAll() {

	String query = "update bug_list set LockedBy=''";
	try {
	    
	    // run the query and put the results in a ResultSet
	    //
	    thread.doAction();
	    int changed = stmt.executeUpdate(query);

	    // todo
	    //
	    JFrame frame = new JFrame("UnlockAll");
	    JOptionPane.showMessageDialog(frame, 
					  "Unlocked "+changed+" bugs");
	}
	catch(SQLException e){
	    
	    // todo
	    //
	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "unLockAll: Database error");
	    e.printStackTrace();
	}

	// done
	//
	return true;
    }

    //| Field       | Type     | Null | Key | Default | Extra          |
    //+-------------+----------+------+-----+---------+----------------+
    //| qindex      | int(11)  |      | PRI | 0       | auto_increment |
    //| Description | text     | YES  |     | NULL    |                |
    //| Owner       | text     | YES  |     | NULL    |                |
    //| Query       | blob     | YES  |     | NULL    |                |
    //| Shared      | tinytext | YES  |     | NULL    |                |

    public boolean saveQuery(String uquery, String desc, String owner, 
			     String share) {

	// remove the query in case it already exists
	//
	deleteQuery(desc, owner);
	
	String qquery = Bug.convertToSQL(uquery);
	String qdesc = Bug.convertToSQL(desc);
	String qowner = Bug.convertToSQL(owner);
	String qshare = Bug.convertToSQL(share);


	String query = "insert into queries set Query=\'"+qquery+
	    "\',Description='"+qdesc+"\',Owner=\'"+qowner+
	    "\',Shared=\'"+qshare+"\' ";

	try {
	    thread.doAction();
	    int changed = stmt.executeUpdate(query);
	}
	catch(SQLException e) {
	    
	    // todo
	    //
	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "saveQuery: Database error");
	    e.printStackTrace();
	}

	return true;
    }

    public boolean deleteQuery(String desc, String owner) {

	String qdesc = Bug.convertToSQL(desc);
	String qowner = Bug.convertToSQL(owner);

	String query = "delete from queries where Description='"+
	    qdesc+"' and Owner='"+qowner+"' ";

	try {
	    thread.doAction();
	    int changed = stmt.executeUpdate(query);
	    if (changed == 1) {
		return true;
	    }
	}
	catch(SQLException e) {
	    
	    // todo
	    //
	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "deleteQuery: Database error");
	    e.printStackTrace();
	}
	return false;
    }

    public Vector loadQueries(String user) {
	
	String qowner = Bug.convertToSQL(user);
	
	String query = "select Owner, Description, Query, Shared, qindex "+
	    "from queries "+
	    "where ((queries.Owner=\'VARMINT\') or "+
	    "(queries.Owner=\'"+qowner+"\') or (queries.Shared != \'none\'))"+
	    " order by qindex desc";
	
	//	System.out.println(query);

	try {

	    // run query and put results in a ResultSet
	    //
	    thread.doAction();
	    result = stmt.executeQuery(query);
	}
	catch(SQLException e){

	    // todo
	    //
	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "loadQueries: Database error");
	    e.printStackTrace();
	}

	// format results in vecotrs of vectors of string pairs; return
	//
	return formatBugVector(result);

	// done
	//
    }
    
    public boolean isAdmin(String user) {

	String query = "select users from groups where gname='admin'";
	
	String val = "";
	try {
	    thread.doAction();
	    result = stmt.executeQuery(query);

	    result.next();

	    val = result.getString("users");

	}
	catch(SQLException e){

	    // todo
	    //
	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "isAdmin: Database error");
	    e.printStackTrace();
	}
	
	
	
	StringTokenizer tokenizer = new StringTokenizer(val, ",");
	
	while (tokenizer.hasMoreTokens()) {
	    
	    String line = (String)tokenizer.nextToken();
	    line = line.trim();
	    
	    if (line.equals(user)) {
		return true;
	    }
	}
	
	return false;
    }

    public Vector getGroups() {
	
	String query = "select gname,users from groups";
	
	try {

	    // run query and put results in a ResultSet
	    //
	    thread.doAction();
	    result = stmt.executeQuery(query);
	}
	catch(SQLException e){

	    // todo
	    //
	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "getGroups: Database error");
	    e.printStackTrace();
	}

	// format results in vecotrs of vectors of string pairs; return
	//
	return formatBugVector(result);

	// done
	//
    }

    //************************************
    //
    // mutator methods
    //
    //************************************

    public boolean connect() {

	// connect to default server
	//
	return connect(_URL, _user, _pWord);

	// done
	//

    }

    public boolean connect(String server, String user, String pWord){

	if (stmt != null) {
	    try{
		// close the current statement and connection in that order
		//
		stmt.close();
		
	    }
	    catch(SQLException e){

		// todo
		//
		e.printStackTrace();

		JFrame frame = new JFrame("Warning");
		JOptionPane.showMessageDialog(frame, 
					      "connect: Database error (stmt.close)");

	    }
	}

	if (conn != null) {
	    try{
		// close the current statement and connection in that order
		//
		conn.close();
	    }
	    catch(SQLException e){
		
		// todo
		//
		e.printStackTrace();
		JFrame frame = new JFrame("Warning");
		JOptionPane.showMessageDialog(frame, 
					      "connect: Database error (conn.close)");
		
	    }
	}


	try{
	    // connect to specified server with specified user and pWord
	    //
	    conn = DriverManager.getConnection(server, user, pWord);
	}
	catch(SQLException e){

	    // todo
	    //
	    e.printStackTrace();
		JFrame frame = new JFrame("Warning");
		JOptionPane.showMessageDialog(frame, 
					      "connect: Database error (getConnection)");

	}

	try{
	    // set up new statement
	    //
	    stmt = conn.createStatement();
	}
	catch(SQLException e){

	    // todo
	    //
	    e.printStackTrace();

	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "connect: Database error (createStatement)");
	}

	// done
	//

	return true;

    }

    public boolean disconnect() {

	try{
	    // close the current ResultSet, statement and connection 
	    //in that order
	    //
	    result.close();
	    stmt.close();
	    conn.close();
	}
	catch(SQLException e) {

	    // todo
	    //
	    e.printStackTrace();

	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "disconnect: Database error");

	}

	return true;

	// done
	//

    }

    // creates a new bug record
    // returns the new BugNumber if successfull
    // returns -1 if unsuccessfull
    //
    public int newBug(Bug varmint, String dbase) {

	// get database from bug
	//
	
	String db = dbase;
	
	//	System.out.println(db);
	// get title from bug
	//
	String title = varmint.getField("Title", 0);

	// get env from bug
	//
	String env = varmint.getField("Environment", 0);

	// get class from bug
	//
	String v_class = varmint.getField("Class", 0);
	
	// get priority from bug
	//
	String pri = varmint.getField("Priority", 0);

	// get severity from bug
	//
	String sev = varmint.getField("Severity", 0);

	// get component from bug
	//
	String comp = varmint.getField("Component", 0);

	// get due from bug
	//
	String due = varmint.getField("Due", 0);
	
	// get owner from bug
	//
	String owner = varmint.getField("Owner", 0);

	// get status from bug
	//
	String stat = varmint.getField("Status", 0);


	String oBy = varmint.getField("OpenedBy", 0);

	// get description from bug
	//

	String desc = varmint.getField("Description", 0);
	int tryCount = 0;
	
	try{
	    // get last BugNumber from Sql server
	    //
	    String query = "select BugNumber from bug_list order by BugNumber desc limit 2";
	    thread.doAction();
	    result = stmt.executeQuery(query);
	}
	catch(SQLException e){
	    
	    // todo
	    //
	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "newBug: Database error");
	    e.printStackTrace();
	    
	}
	
	// save last BugNumber and add one to it
	//
	int bNum = -1;
	
	try{
	    if(result.next()){
		// we got results, put the first one in bNum
		//
		//		System.out.println(result.getInt(1));
		bNum = result.getInt(1);
		//		System.out.println(bNum);
	    }
	    else {
		// we didn't get any results, bug creation failed
		//
		return -2;
	    }
	}
	catch(SQLException e){
	    
	    // todo
	    //
	    e.printStackTrace();

	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "newBug: Database error");
		
	}
	
	
	// bug creation didn't fail, add one to bNum
	//
	bNum++;
	
	// format query to make new bug record
	//
	String query = "insert into bug_list (BugNumber, Title, Owner," + 
	    " Priority, Severity, DBase, Component, Class, Due, Status," +
	    " Description, Environment, OpenDate, ModifyDate,OpenedBy) values (\'" +
	    bNum + "\', \'" + title + "\', \'" + owner + "\', \'" + pri + 
	    "\', \'" + sev + "\', \'" + db + "\', \'" + comp + "\', \'" + 
	    v_class + "\', \'" + due + "\', \'" + stat +"\', \'" + 
	    desc +"\', \'" + env +"\', NOW(), NOW(), \'" + oBy +"\')";

	int changed = 0;
	
	try{
	    // send query to server
	    // returns records changed, so save results in changed
	    //
	    thread.doAction();
	    changed = stmt.executeUpdate(query);
       
	}
	catch(SQLException e){

	    System.out.println(query);

	    // todo
	    //

	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "The New Bug could not be  " +
					  "added to the database requested  "
					  +  "Please try another.");
	    //	    e.printStackTrace();
	    
	}

	// check that one and only one record was updated
	// return -1 (error) if more than one record is changed
	//
	if( (changed == 0) || (changed > 1)){
	    return -1;
	}

	// one and only one record was updated, return new BugNumber
	//
	return bNum;

	// done
	//

    }

    public boolean updateBug(String mode, Bug varmint) {

	if(mode == "modify"){
	    return modifyBug(varmint);
	}
	else if(mode == "open"){
	    return openBug(varmint);
	}
	else if(mode == "assign"){
	    return assignBug(varmint);
	}
	else if(mode == "resolve"){
	    return resolveBug(varmint);
	}
	else if(mode == "close"){
	    return closeBug(varmint);
	}
	else{
	    return false;
	}

    }

    public boolean deleteBug(Bug varmint) {
	
	//getBugList() should be re-run after this operation
	//

	//get the database and bugnumber to delete
	//
	String db = varmint.getField("DBase");
	String bNum = varmint.getField("BugNumber");
	
	//format the query string
	//

	String query = "delete from bug_list where DBase = \'" + db +
	    "\' and BugNumber = \'" + bNum + "\'";

	//set up a variable to check the the query works
	//
	int changed = 0;

	//run the query
	//
	try {
	    thread.doAction();
	    changed = stmt.executeUpdate(query);
	}
	catch(SQLException e) {

	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "The Bug could not be  " +
					  "deleted from the database requested"
					  +  " Please try another.");
	    //	    e.printStackTrace();
	}

	//check the success of the query
	//
	if(changed == 0){
	    return false;
	}
	else {
	    return true;
	}

    }
	

	

    //*************************************
    //
    // protected mutator methods
    //
    //*************************************

    protected boolean modifyBug(Bug varmint){

	
	// get appropriate strings from Bug
	//
	String bNum = varmint.getField("BugNumber", 0);
	String title = varmint.getField("Title", 0);
	String status = varmint.getField("Status", 0);
	String pri = varmint.getField("Priority", 0);
	String sev = varmint.getField("Severity", 0);
	String db = varmint.getField("DBase", 0);
	String oBy = varmint.getField("OpenedBy", 0);
	String oDt = varmint.getField("OpenDate", 0);
	String env = varmint.getField("Environment", 0);
	String comp = varmint.getField("Component", 0);
	String tCase = varmint.getField("TestCase", 0);
	String v_class = varmint.getField("Class", 0);
	String rBy = varmint.getField("ResolvedBy", 0);
	String res = varmint.getField("Resolution", 0);
	String resDate = varmint.getField("ResolvedDate", 0);
	String viewD = varmint.getField("ReviewDate", 0);
	String insp = varmint.getField("Inspected", 0);
	String due = varmint.getField("Due", 0);
	String desc = varmint.getField("Description", 0);

	// format query to update bug record
	//
	String query = "update bug_list set " + 
	    "Title = \'" + title + "\', " +
	    "Status = \'" + status + "\', " +
	    "Priority = \'" + pri + "\', " +
	    "Severity = \'" + sev + "\', " +
	    //"OpenedBy = \'" + oBy + "\', " +
	    //"OpenDate = \'" + oDt + "\', " +
	    "Environment = \'" + env + "\', " +
	    "Component = \'" + comp + "\', " +
	    "TestCase = \'" + tCase + "\', " +
	    "Class = \'" + v_class + "\', " +
	    //"ResolvedBy = \'" + rBy + "\', " +
	    "Resolution = \'" + res + "\', " +
	    //"ResolvedDate = \'" + resDate + "\', " +
	    "ReviewDate = \'" + viewD + "\', " +
	    "Inspected = \'" + insp + "\', " +
	    "Due = \'" + due + "\', " +
	    "Description = \'" + desc + "\' ," +
	    "DBase = \'" + db + "\' ," +
	    "ModifyDate = NOW() " +
	    "where BugNumber = \'" + bNum + "\'";

	int changed = 0;
	try{
	    // send query to server
	    // returns records changed, so save results in changed
	    //
	    thread.doAction();
	    changed = stmt.executeUpdate(query);
	}
	catch(SQLException e){
	    
	    // todo
	    //

	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "modifyBug: database error");
	    e.printStackTrace();

	}
	
	// check that one and only one record was updated
	// return false if more than one record is changed
	//
	if( (changed == 0) || (changed > 1)){
	    return false;
	}
	
	// one and only one record was updated, return true
	//
	return true;
	
	// done
	// 
	    
    }

    protected boolean openBug(Bug varmint){
	// get appropriate strings from Bug
	//
	String bNum = varmint.getField("BugNumber", 0);
	String title = varmint.getField("Title", 0);
	String status = varmint.getField("Status", 0);
	String pri = varmint.getField("Priority", 0);
	String sev = varmint.getField("Severity", 0);
	String db = varmint.getField("DBase", 0);
	String oBy = varmint.getField("OpenedBy", 0);
	String oDt = varmint.getField("OpenDate", 0);
	String env = varmint.getField("Environment", 0);
	String comp = varmint.getField("Component", 0);
	String tCase = varmint.getField("TestCase", 0);
	String v_class = varmint.getField("Class", 0);
	String rBy = varmint.getField("ResolvedBy", 0);
	String res = varmint.getField("Resolution", 0);
	String resDate = varmint.getField("ResolvedDate", 0);
	String viewD = varmint.getField("ReviewDate", 0);
	String insp = varmint.getField("Inspected", 0);
	String due = varmint.getField("Due", 0);
	String desc = varmint.getField("Description", 0);

	// format query to update bug record
	//
	String query = "update bug_list set " + 
	    "Title = \'" + title + "\', " +
	    "Status = \'" + status + "\', " +
	    "Priority = \'" + pri + "\', " +
	    "Severity = \'" + sev + "\', " +
	    "Environment = \'" + env + "\', " +
	    "Component = \'" + comp + "\', " +
	    "TestCase = \'" + tCase + "\', " +
	    "Class = \'" + v_class + "\', " +
	    "ResolvedBy = \'" + rBy + "\', " +
	    "Resolution = \'" + res + "\', " +
	    "ResolvedDate = \'\', " +
	    "ReviewDate = \'" + viewD + "\', " +
	    "Inspected = \'" + insp + "\', " +
	    "Due = \'" + due + "\', " +
	    "Description = \'" + desc + "\' ," +
	    "DBase = \'" + db + "\' ," +
	    "ModifyDate = NOW() " +
	    "where BugNumber = \'" + bNum + "\'";

	int changed = 0;

	System.out.println(query);

	try{
	    // send query to server
	    // returns records changed, so save results in changed
	    //
	    thread.doAction();
	    changed = stmt.executeUpdate(query);
	}
	catch(SQLException e){

	    // todo
	    //

	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "The Bug could not be  " +
					  "opened in the database requested"
					  +  "Please try another.");
	    //e.printStackTrace();

	}

	// check that one and only one record was updated
	// return false if more than one record is changed
	//
	if( (changed == 0) || (changed > 1)){
	    return false;
	}

	// one and only one record was updated, return true
	//
	return true;

	// done
	// 
    }

    protected boolean assignBug(Bug varmint){
	
	// get appropriate strings from Bug
	//
	String bNum = varmint.getField("BugNumber", 0);
	String title = varmint.getField("Title", 0);
	String owner = varmint.getField("Owner", 0);
	String pri = varmint.getField("Priority", 0);
	String sev = varmint.getField("Severity", 0);
	String db = varmint.getField("DBase", 0);
	String env = varmint.getField("Environment", 0);
	String comp = varmint.getField("Component", 0);
	String tCase = varmint.getField("TestCase", 0);
	String v_class = varmint.getField("Class", 0);
	String viewD = varmint.getField("ReviewDate", 0);
	String due = varmint.getField("Due", 0);
	String desc = varmint.getField("Description", 0);

	// format query to update bug record
	//
	String query = "update bug_list set " + 
	    "Title = \'" + title + "\', " +
	    "Owner = \'" + owner + "\', " +
	    "Priority = \'" + pri + "\', " +
	    "Severity = \'" + sev + "\', " +
	    "Environment = \'" + env + "\', " +
	    "Component = \'" + comp + "\', " +
	    "TestCase = \'" + tCase + "\', " +
	    "Class = \'" + v_class + "\', " +
	    "ReviewDate = \'" + viewD + "\', " +
	    "Due = \'" + due + "\', " +
	    "ModifyDate = NOW(), " +
	    "Description = \'" + desc + "\' " +
	    "where DBase = \'" + db + "\' " +
	    "and BugNumber = \'" + bNum + "\'";

	int changed = 0;

	try{
	    // send query to server
	    // returns records changed, so save results in changed
	    //
	    thread.doAction();
	    changed = stmt.executeUpdate(query);
	}
	catch(SQLException e){

	    // todo
	    //
	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "The Bug could not be  " +
					  "assigned in the database requested"
					  +  "Please try another.");
	    //	    e.printStackTrace();

	}

	// check that one and only one record was updated
	// return false if more than one record is changed
	//
	if( (changed == 0) || (changed > 1)){
	    return false;
	}

	// one and only one record was updated, return true
	//
	return true;

	// done
	// 
    }

    protected boolean resolveBug(Bug varmint){

	// get appropriate strings from Bug
	//
	String bNum = varmint.getField("BugNumber", 0);
	String title = varmint.getField("Title", 0);
	String owner = varmint.getField("Owner", 0);
	String status = varmint.getField("Status", 0);
	String db = varmint.getField("DBase", 0);
	String tCase = varmint.getField("TestCase", 0);
	String rBy = varmint.getField("ResolvedBy", 0);
	String res = varmint.getField("Resolution", 0);
	String resDate = varmint.getField("ResolvedDate", 0);
	String insp = varmint.getField("Inspected", 0);
	String desc = varmint.getField("Description", 0);

	// format query to update bug record
	//
	String query = "update bug_list set " + 
	    "Title = \'" + title + "\', " +
	    "Owner = \'" + owner + "\', " +
	    "Status = \'" + status + "\', " +
	    "TestCase = \'" + tCase + "\', " +
	    "ResolvedBy = \'" + rBy + "\', " +
	    "Resolution = \'" + res + "\', " +
	    "ResolvedDate = NOW(), " +
	    "Inspected = \'" + insp + "\', " +
	    "ModifyDate = NOW(), " +
	    "Description = \'" + desc + "\' " +
	    "where DBase = \'" + db + "\' " +
	    "and BugNumber = \'" + bNum + "\'";

	int changed = 0;

	try{
	    // send query to server
	    // returns records changed, so save results in changed
	    //
	    thread.doAction();
	    changed = stmt.executeUpdate(query);
	}
	catch(SQLException e){

	    // todo
	    //
	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "The Bug could not be  " +
					  "resolved in the database requested"
					  +  "Please try another.");
	    //	    e.printStackTrace();

	}

	// check that one and only one record was updated
	// return false if more than one record is changed
	//
	if( (changed == 0) || (changed > 1)){
	    return false;
	}

	// one and only one record was updated, return true
	//
	return true;

	// done
	// 
    }

    protected boolean closeBug(Bug varmint){
	
	// get appropriate strings from Bug
	//
	String title = varmint.getField("Title", 0);
	String bNum = varmint.getField("BugNumber", 0);
	String tCase = varmint.getField("TestCase", 0);
	String status = varmint.getField("Status", 0);
	String db = varmint.getField("DBase", 0);
	String desc = varmint.getField("Description", 0);

	// format query to update bug record
	//
	String query = "update bug_list set " +
	    "Title = \'" + title + "\', " + 
	    "Status = \'" + status + "\', " +
	    "TestCase = \'" + tCase + "\', " +
	    "ModifyDate = NOW(), " +
	    "Description = \'" + desc + "\' " +
	    "where DBase = \'" + db + "\' " +
	    "and BugNumber = \'" + bNum + "\'";

	int changed = 0;

	try{
	    // send query to server
	    // returns records changed, so save results in changed
	    //
	    thread.doAction();
	    changed = stmt.executeUpdate(query);
	}
	catch(SQLException e){

	    // todo
	    //
	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "The Bug could not be  " +
					  "closed in the database requested"
					  +  "Please try another.");
	    //	    e.printStackTrace();

	}

	// check that one and only one record was updated
	// return false if more than one record is changed
	//
	if( (changed == 0) || (changed > 1)){
	    return false;
	}

	// one and only one record was updated, return true
	//
	return true;

	// done
	// 
    }

    //*************************************
    //
    // protected facilitator methods
    //
    //*************************************

    protected Vector formatBugVector(ResultSet result){

	// create vector to hold other vectors
	//
	Vector resultVector = new Vector(20,20);

	// create vector to hold string pairs
	//
	Vector recordVector = new Vector(2,2);

	// create ResultSetMetaData object
	//
	ResultSetMetaData mData= null;
	
	try{
	    // get the meta data
	    //
	    mData = result.getMetaData();
	}
	catch(SQLException e){
	    e.printStackTrace();

	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "closeBug: Database error");

	}

	try{
	    while(result.next()) {

		// put one field at a time into recordVector
		// then dump all the fields into resultVector
		//

 		//find the number of columns
		//
		int n = mData.getColumnCount();
		
		int i = 1;
		while(i <= n) {
		    
		    // put fieldName in first segment of recordVector
		    //
		    recordVector.add(result.getString(i));
		    
		    i++;
		}		    
		
		resultVector.addElement(recordVector);
		
		recordVector = new Vector(2,2);
		
	    }
	}
	catch(SQLException e) {

	    // todo
	    //
	    e.printStackTrace();

	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "formatBugVector: Database error");



	}
	catch(Exception e){
	    e.printStackTrace();

	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "formatBugVector: Database error");

	}
	    
	// and now we're done
	// return resultVector
	//
	return resultVector;

	// done
	//
	
    }

    public ResultSet getStats(String query) {
	
	try {
	    thread.doAction();
	    result = stmt.executeQuery(query);
	} catch (SQLException e) {
	    e.printStackTrace();
	    
	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "getStats: Database error");
	}

	return result;
    }

	
    protected Bug formatBug(ResultSet result){

	// create Bug container to hold retrieved bug
	//
	Bug critter = new Bug();

	// create ResultSetMetaData object
	//
	ResultSetMetaData mData= null;
	
	try{
	    mData = result.getMetaData();
	}
	catch(SQLException e){
	    e.printStackTrace();
	    
	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "formatBug: Database error");

	}

	try{
	    // load retrieved Bug into critter
	    //
	    if(result.next()) {
		
		// the fields are already named in Bug
		// dump fields into Bug by fieldName
		//

		int n = mData.getColumnCount();
		int i = 1;
		while(i <= n) {
		    
		    // get fieldName from ResultSet
		    // get content from ResultSet
		    // dump both into the corresponding field in Bug
		    //
		    critter.setField(mData.getColumnName(i), 
				     result.getString(i));
		    
		    //System.out.println(mData.getColumnName(i) + "\t" +
		    //	       result.getString(i));
		    // move to the next field in the ResultSet
		    // (not the next record)
		    //
		    i++;
		    
		    // close while
		    //
		    
		}
		
		// close if
		//
		
	    }
	}
	catch(SQLException e){

	    // todo
	    //
	    e.printStackTrace();

	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "formatBug: Database error");


	}

	// and now we're done
	// return Bug
	//
	//	System.out.println("critter: " + critter.getField("Title"));
	return critter;
	
	// done
	//

    }

    protected Vector formatBugList(ResultSet result){

	// create vector to hold other vectors
	//
	Vector resultVector = new Vector(20,20);

	// create bug to hold string pairs
	//
	Bug critter = null;

	// create ResultSetMetaData object
	//
	ResultSetMetaData mData= null;
	
	try{
	    // get the meta data
	    //
	    mData = result.getMetaData();
	}
	catch(SQLException e){
	    e.printStackTrace();

	    JFrame frame = new JFrame("Warning");
	    JOptionPane.showMessageDialog(frame, 
					  "formatBugList: Database error");

	}

	try{

	    while(result.next()) {
		
		critter = new Bug();

		// the fields are already named in Bug
		// dump fields into Bug by fieldName
		//

		int n = mData.getColumnCount();
		int i = 1;
		while(i <= n) {
		    
		    // get fieldName from ResultSet
		    // get content from ResultSet
		    // dump both into the corresponding field in Bug
		    //
		    critter.setField(mData.getColumnName(i), 
				     result.getString(i));
		    
		    //System.out.println(mData.getColumnName(i) + "\t" +
		    //	       result.getString(i));
		    // move to the next field in the ResultSet
		    // (not the next record)
		    //
		    i++;
		   
		    // close inner while
		    //
		    
		}
		resultVector.add(critter);
		
		// close outer while
		//
		
	    }

	}
	catch(SQLException e) {

	    // todo
	    //
	    e.printStackTrace();

	}
	catch(Exception e){
	    e.printStackTrace();
	}
	    
	// and now we're done
	// return resultVector
	//
	//	System.out.println("" + resultVector.size());
	return resultVector;

	// done
	//
	
    }

    /**
     * the main function is for running diagnostics on the database
     *
     */
    public static void main(String[] args) {
	
	VarmintDB db = new VarmintDB();

	// test that the getDefault works properly for priority
	//
	String def_priority = db.getDefault("Priority");
	if (!def_priority.equals("medium")) {
	    System.out.println("bad default for Priority, >"+
			       def_priority + "<");
	}

	/*	
	// test that locking works
	//
	if (!db.isLockedBy("ifc","0","")) {
	    System.out.println("0: lock error for ifc:0");
	}
	if (db.isLockedBy("ifc","0","duncan")) {
	    System.out.println("1: lock error for ifc:0");
	}
	if (!db.lockBug("ifc","0","duncan")) {
	    System.out.println("2: lock error for ifc:0");
	}
	if (!db.isLockedBy("ifc","0","duncan")) {
	    System.out.println("3: lock error for ifc:0");
	}
	System.out.println("it should report this bug is locked by duncan");
	if (db.lockBug("ifc","0","king")) {
	    System.out.println("4: lock error for ifc:0");
	}
	System.out.println("done");

	if (!db.isLockedBy("ifc","0","duncan")) {
	    System.out.println("5: lock error for ifc:0");
	}

	if (!db.isLockedBy("utils","0","")) {
	    System.out.println("0: lock error for utils:0");
	}
	if (!db.lockBug("utils","0","king")) {
	    System.out.println("1: lock error for utils:0");
	}

	System.out.println("it should report this bug is locked by king");
	if (db.isLockedBy("utils","0","duncan")) {
	    System.out.println("2: lock error for utils:0");
	}
	System.out.println("done");

	if (!db.isLockedBy("ifc","0","duncan")) {
	    System.out.println("6: lock error for ifc:0");
	}
	if (!db.isLockedBy("utils","0","king")) {
	    System.out.println("3: lock error for utils:0");
	}
	
	System.out.println("it should report this bug is locked by duncan");
	if (db.unLockBug("ifc","0","king")) {
	    System.out.println("7: lock error for ifc:0");
	}
	System.out.println("done");

	if (!db.unLockBug("ifc","0","duncan")) {
	    System.out.println("8: lock error for ifc:0");
	}

	if (!db.isLockedBy("utils","0","king")) {
	    System.out.println("4: lock error for utils:0");
	}

	if (!db.unLockBug("utils","0","king")) {
	    System.out.println("5: lock error for utils:0");
	}

	if (db.isLockedBy("utils","0","king")) {
	    System.out.println("4: lock error for utils:0");
	}

	if (!db.isLockedBy("utils","0","")) {
	    System.out.println("5: lock error for utils:0");
	}
	if (!db.isLockedBy("ifc","0","")) {
	    System.out.println("9: lock error for ifc:0");
	}
	*/
	if (!db.isAdmin("picone")) {
	    System.out.println("10: error since duncan is admin");
	}

	if (!db.isAdmin("hamaker")) {
	    System.out.println("10: error since duncan is admin");
	}

	if (!db.isAdmin("parihar")) {
	    System.out.println("10: error since duncan is admin");
	}

	if (db.isAdmin("joeblow")) {
	    System.out.println("10: error since joeblow is not admin");
	}
	
	db.disconnect();
	System.out.println("completed tests");
	
	System.exit(0);
    }

    // end of class
    //

};






