/*
 * Main.java
 *
 */

package derby1295;

import java.sql.*;

/**
 * Test <test purpose>
 * 
 * @author dag.wanvik@sun.com
 */
public class Main {
    
    Connection con = null;

    /** Creates a new instance of Main */
    public Main() {
    }

    private org.apache.derby.drda.NetworkServerControl netServer;
      
    private void startServer() {
        try {
            netServer = new org.apache.derby.drda.NetworkServerControl
                (java.net.InetAddress.getByName("localhost"), 1527);
            java.io.PrintWriter consoleWriter = new java.io.PrintWriter
                (System.out, true);
            netServer.start(consoleWriter);
            boolean knowIfServerUp = false; // do we know if server is
            // ready to accept connections  
            int numTimes = 5;

            // Test to see if server is ready for connections, for 15 seconds.
            while(!knowIfServerUp && (numTimes >0)) {
                try {
                    // testing for connection to see if the network server
                    // is up and running if server is not ready yet, this
                    // method will throw an exception 
                    numTimes--;
                    netServer.ping();
                    knowIfServerUp = true;
                }
                catch(Exception e) {
                    System.out.println("[NsSample] Unable to obtain a " + 
                                       "connection to network server, " + 
                                       "trying again after 3000 ms.");
                    Thread.currentThread().sleep(3000);
                }
            }
        } catch (Exception e) {
            System.out.println("Error starting server: " + e.toString());
        }
    }
    
    private void shutdownServer() {
        try {
            netServer.shutdown();
        } catch (Exception e) {
            System.out.println("Error shuting down: " + e.toString());
        }
    }

    private void dropTable() {
        try {
            Statement st = con.createStatement();
            st.execute("DROP TABLE mytab");
            st.close();
        } catch (SQLException sqlE) {
            // expected
        } catch (Exception e) {
            System.out.println("Error dropping table: " + e.toString());
        }
    }

    private void createTable() {
        try {
            Statement st = con.createStatement();
            st.execute("CREATE TABLE mytab (id int primary key, " + 
                       "name varchar(50))");
        } catch (SQLException sqlE) {
            System.out.println("Error creating table: " + sqlE.toString());
        } catch (Exception e) {
            System.out.println("Error creating table: " + e.toString());
        }
    }

    private void insertData() {
        try {
            int i;
            PreparedStatement ps = con.prepareStatement
                ("INSERT INTO mytab VALUES (?, ?)");
            for (i=0; i<10; i++) {
                ps.setInt(1, i);
                ps.setString(2, "Testing " + i);
                ps.executeUpdate();
            }

            ps.close();
        } catch (SQLException sqlE) {
            System.out.println("Error inserting data: " + sqlE.toString());
        }
    }

    private void dumpRows() {
        try {
            int i=0;
            Statement s = con.createStatement();

            ResultSet rs = s.executeQuery("SELECT * from mytab");
            
            while (rs.next()) {
                System.out.println("row " + i + ": " + rs.getInt(1) + " " + 
                                   rs.getString(2));
                i++;
            }

            s.close();
        } catch (SQLException sqlE) {
            System.out.println("Error dumping rows: " + sqlE.toString());
        }
    }

    private void myAssert(boolean b, String s) {
        if (!b) {
            System.out.println("Failed assert: "+ s);
        }

    }

    private void doStuff() {
        Statement s = null; 
        ResultSet rs = null;

        try {
            s = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
                                    ResultSet.CONCUR_READ_ONLY);
            rs = s.executeQuery("SELECT * from mytab");

            
            rs.last();
            boolean b = rs.next();
            myAssert(!b, "1");
            System.out.println("You should see this, first next from last " + 
                               "will work but return false");

            b = rs.next(); // fails

            System.out.println("If you see this repro did not work: " + 
                               "a second next from last row worked");

        } catch (SQLException e) {
            System.out.println("Error expected in repro: " + e.getSQLState() +
                               ": " + e);
        } finally {
            if (rs != null) {
                try { rs.close(); } catch (Exception e) {};
            }
            if (s != null) {
                try { s.close(); } catch (Exception e) {};
            }
        }


    }

    private void doBothDrivers(){
        Statement selectStatement = null;
        ResultSet rs = null;
        Statement st = null;

        String urls[] = {"jdbc:derby://localhost:1527/test1;create=true;"+
                         "territory=en_US",
                         "jdbc:derby:test1;create=true;territory=en_US"};
        String drivers[] = {"org.apache.derby.jdbc.ClientDriver",
                            "org.apache.derby.jdbc.EmbeddedDriver"};

        // Start from 1: Only run with embedded; bug is not seen with Derby
        // client driver.
        for (int dNo = 1; dNo < 2; dNo++) { 
            try {
                Class.forName(drivers[dNo]);
                con = DriverManager.getConnection(urls[dNo]);
                con.setAutoCommit(true);
                con.setHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT);

                System.out.println("* Testing with " + drivers[dNo] );

                dropTable();
                createTable();
                insertData();

                doStuff();

                dumpRows();
                con.close();

            } catch (SQLException e) {
                while (e != null) {
                    System.out.println(e);
                    e = e.getNextException();
                }
            } catch (Exception e) {
                System.out.println(e);
            }
        }

    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Main m = new Main();
        // m.startServer();
        m.doBothDrivers();
        // m.shutdownServer();
    }
    
}

// Local Variables: ***
// indent-tabs-mode: nil ***
// fill-column: 79 ***
// End: ***
