/*
 * Main.java
 *
 * Created on April 13, 2005, 11:28 AM
 */

package derbytest;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import java.util.Properties;

/**
 *
 * @author Øystein Grøvlen
 */
public class Main 
{
    
    /**
     * Runnable that will create and drop table.
     */
    class CreateTable implements Runnable 
    {
        int myId;
        
        CreateTable(int id) {
            this.myId = id;
        }
     
        public void run()        
        {
            Connection conn = null;
            try {
                conn = DriverManager.getConnection(protocol+ "TestDB");
                conn.setAutoCommit(false);
                Statement s = conn.createStatement();
                s.execute("create table testschema.testtab" + myId
                        + "(num int, addr varchar(40))");
                s.execute("drop table testschema.testtab" + myId);
            } catch (SQLException e) {
                printSQLError(e);
            }
  
            try {
                conn.commit();
            } catch (SQLException e) {
                printSQLError(e);
            }
            
            System.out.println("Thread " + myId + " completed");
        }
    }
    
    /* the default framework is embedded*/
    public String framework = "embedded";
    public String driver = "org.apache.derby.jdbc.EmbeddedDriver";
    public String protocol = "jdbc:derby:";

    public static void main(String[] args)
    {
        new Main().go(args);
    }

    void go(String[] args)
    {
        /* parse the arguments to determine which framework is desired*/
        parseArguments(args);

        System.out.println("Starting in " + framework + " mode.");

        try
        {
            /*
               The driver is installed by loading its class.
               In an embedded environment, this will start up Derby, since it is not already running.
             */
            Class.forName(driver).newInstance();
            System.out.println("Loaded the appropriate driver.");           
   
            /*
               The connection specifies create=true to cause
               the database to be created.
             */
            Connection conn = DriverManager.getConnection(protocol +
                    "TestDB;create=true");

            System.out.println("Connected to and created database TestDB");

            conn.setAutoCommit(true);

            /*
               Creating a statement lets us issue commands against
               the connection.
             */
            Statement s = conn.createStatement();
            
            try {
                s.execute("drop schema testschema restrict");
            } catch (SQLException e) {
                // We ignore this, schema does probably not exist               
            }

            final int NTHREADS = 5;
            Thread[] threads = new Thread[NTHREADS];
            for (int i=0; i<NTHREADS; ++i) {
                threads[i] = new Thread(new CreateTable(i));             
            }
            
            for (int i=0; i<NTHREADS; ++i) {
                threads[i].start();           
            }         
            
            // Wait for threads to complete
            for (int i=0; i<NTHREADS; ++i) {
                threads[i].join();           
            }
  
            conn.close();
            System.out.println("Closed connection");

            /*
               In embedded mode, an application should shut down Derby.
               If the application fails to shut down Derby explicitly,
               the Derby does not perform a checkpoint when the JVM shuts down, which means
               that the next connection will be slower.
               Explicitly shutting down Derby with the URL is preferred.
               This style of shutdown will always throw an "exception".
             */
            boolean gotSQLExc = false;

            if (framework.equals("embedded"))
            {
                try
                {
                    DriverManager.getConnection("jdbc:derby:;shutdown=true");
                }
                catch (SQLException se)
                {
                    gotSQLExc = true;
                }

                if (!gotSQLExc)
                {
                    System.out.println("Database did not shut down normally");
                }
                else
                {
                    System.out.println("Database shut down normally");
                }
            }
        }
        catch (Throwable e)
        {
            System.out.println("exception thrown:");

            if (e instanceof SQLException)
            {
                printSQLError((SQLException) e);
            }
            else
            {
                e.printStackTrace();
            }
        }

        System.out.println("finished");
    }

    static void printSQLError(SQLException e)
    {
        while (e != null)
        {
            System.out.println(e.toString());
            e.printStackTrace();
            e = e.getNextException();
        }
    }

    private void parseArguments(String[] args)
    {
        int length = args.length;

        for (int index = 0; index < length; index++)
        {
            if (args[index].equalsIgnoreCase("jccjdbcclient"))
            {
                framework = "jccjdbc";
                driver = "com.ibm.db2.jcc.DB2Driver";
                protocol = "jdbc:derby:net://localhost:1527/";
            }
        }
    }
}