/**
 * Client application that loads fortunes from a cookie file into
 * a Derby database.
 *
 * Hard codes location of fortune files to ../../data/
 *
 * Authored by Jean Anderson (jta@bristowhill.com) with welcome improvements 
 * by Ed Korthof at ApacheCon US 2004.
 */

import java.io.*;
import java.sql.*;

public class LoadFortune {      
  public static void main (String[] args) {


    if(args.length != 2) {
        System.out.println("ERROR: database name and cookie filename required.");
        return;
    }

    String      databaseName = args[0];
    String      cookieFile = args[1];
    String      fullPath="../../data/" + cookieFile;
    String      dbUrl="jdbc:derby:" + databaseName;
    Connection  conn = null;
    Statement   stmt = null;
    ResultSet   rs = null;
    PreparedStatement ps = null;

    try {
        // Connect to Derby database and prepare the insert statement.
        Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
        conn = DriverManager.getConnection(dbUrl);

        // Get the max id
        int maxId=0;
        stmt = conn.createStatement();
        rs = stmt.executeQuery("select max(id) from fortunes");
        if(rs.next())
            maxId = rs.getInt(1);
        rs.close();
        stmt.close();

        // Prepare the statement that will perform inserts.
        ps = conn.prepareStatement
            ("insert into fortunes (id, src, fortune) values (?, ?, ?)");

        // Open the cookie file
        BufferedReader fortuneFile = new BufferedReader(new FileReader(fullPath));
        // Read records until we get to the end of the file.
        int minId=maxId+1;
        String inString = fortuneFile.readLine();
        StringBuffer thisFortune = new StringBuffer();
        while (inString != null) {

            if (inString.equals("%")) {
                // skip empty record
                continue;
            }
            thisFortune.setLength(0);
            thisFortune.append(inString);
            inString = fortuneFile.readLine();

            // Read lines until we reach a % terminator.
            // Retain the original line feeds.
            while (inString.equals("%") == false) {
                thisFortune.append("\n");
                thisFortune.append(inString);
                inString = fortuneFile.readLine();
            }

            // Insert this fortune into the database.
            maxId++;
            // System.out.println("Inserting " + cookieFile + " record=" + maxId);
            // System.out.println("fortune1=***" + thisFortune + "***");
            // System.out.println("fortune2=***" + insertString + "***");

            ps.setInt(1, maxId);
            ps.setString(2, cookieFile);
            ps.setString(3, thisFortune.toString());
            ps.executeUpdate();

            // Get next record.
            inString = fortuneFile.readLine();
        }

        System.out.println("Loaded " + fullPath + "(minId=" +
            minId + " maxId=" + maxId + ")");

        // Cleanup
        fortuneFile.close();
        ps.close();
        conn.close();

        // Close database connection
        try {
            DriverManager.getConnection("jdbc:derby:;shutdown=true");
        }
        catch (SQLException se) {
            // Successful shutdown produces exception XJ015, 
            // which we can safely ignore.
            if( ! "XJ015".equals((se).getSQLState()) ) {
                SQLExceptionPrint((SQLException)se);
                throw se;
            }
        }
    }
    catch (Throwable e) {
        System.out.println("exception thrown:");
        errorPrint(e);
    }
    finally {
        try {
            if(rs != null)
                rs.close();
            if(stmt != null)
                stmt.close();
            if(ps != null)
                ps.close();
            if(conn != null)
                conn.close();
        }
        catch (Throwable e) {
            System.out.println("exception thrown:");
            errorPrint(e);
        }
    }

  } // END main

  static void errorPrint(Throwable e) {
      if (e instanceof SQLException) 
	SQLExceptionPrint((SQLException)e);
      else
	System.out.println("A non SQL error occurred.");
        e.printStackTrace();
  }

  static void SQLExceptionPrint(SQLException sqle) {
      while (sqle != null) {
	System.out.println("\n---SQLException Caught---\n");
	System.out.println("SQLState:   " + (sqle).getSQLState());
	System.out.println("Severity: " + (sqle).getErrorCode());
	System.out.println("Message:  " + (sqle).getMessage()); 
	sqle.printStackTrace();  
	sqle = sqle.getNextException();
      }
  }
}
