/**
 *      sample4 JDBC sample application
 *
 *      Sep 24 1997 JP
 *
 *      This simple JDBC application does the following using
 *      Solid native JDBC driver. 
 *  
 *  1. Registers the driver using JDBC driver manager services
 *  2. Prompts the user for a valid JDBC connect string
 *  3. Connects to Solid Server using the driver
 *  4. Drops and creates a table sample4. If the table
 *     does not exist dumps the related exception.
 *  5. Inserts file given as an argument to database (method Store)
 *  6. Reads this 'blob' back to file out.tmp (method Restore)
 *  7. Closes connection
 *
 *  To build and run the application 
 *
 *  1. Make sure you have a working Java Development environment
 *  2. Install and start Solid Server to connect. Ensure that the Server 
 *     is up and running.
 *  3. Append SolidDriver.zip into the CLASSPATH definition used 
 *     by your development/running environment. 
 *  4. Create a java project based on the file sample4.java. 
 *  5. Build and run the application.
 * 
 *  For more information read the readme.htm file contained by 
 *  SOLID JDBC Driver package.
 *
 */

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

public class sample4 {

    static Connection conn;
    public static void main (String args[]) throws Exception
    {
        String filename = null;
        String tmpfilename = null;

        if (args.length < 1) {
            System.out.println("usage: java sample4 <infile>");
            System.exit(0);
        }
        filename = args[0];
        tmpfilename = "out.tmp";
        System.out.println("JDBC sample application starts...");
        System.out.println("Application tries to register the driver.");

        // this is the recommended way for registering Drivers
        Driver d = (Driver)Class.forName("solid.jdbc.SolidDriver").newInstance();

        System.out.println("Driver succesfully registered.");

        // the user is asked for a connect string 
        System.out.println("Now sample application needs a connectstring in format:\n");
        System.out.println("jdbc:solid://<host>:<port>/<user name>/<password>\n");
        System.out.print("\nPlease enter the connect string >");
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String sCon = reader.readLine();

        // next, the connection is attempted
        System.out.println("Attempting to connect :" + sCon);
        conn = DriverManager.getConnection(sCon);

        System.out.println("SolidDriver succesfully connected.");

        // drop and create table sample4
        createsample4();
        // insert data into it
        Store(filename);
        // and restore it
        Restore(tmpfilename);

        conn.close();
        // and it is all over
        System.out.println("\nSample application finishes.");
    }


    static void Store(String filename) {
        String sql = "insert into sample4 values(?,?)";
        FileInputStream inFileStream ; 
        try {
            File f1 = new File(filename);
            int blobsize = (int)f1.length();
            System.out.println("Inputfile size is "+blobsize);
            inFileStream = new FileInputStream(f1);
        
            PreparedStatement stmt = conn.prepareStatement(sql);
            stmt.setLong(1, System.currentTimeMillis());
            stmt.setBinaryStream(2, inFileStream, blobsize);
            int rows = stmt.executeUpdate();
            stmt.close();
            System.out.println(""+rows+" inserted.");
            conn.commit();
        }
        catch (SQLException ex) {
            printexp(ex);
        }
        catch (java.lang.Exception ex) {
            ex.printStackTrace ();
        }

    }

    static void Restore(String filename) {
        String sql = "select id,blob from sample4";
        FileOutputStream outFileStream ; 
        try {
            File f1 = new File(filename);
            outFileStream = new FileOutputStream(f1);
        
            PreparedStatement stmt = conn.prepareStatement(sql);
            ResultSet rs = stmt.executeQuery();
            int readsize = 0;
            while (rs.next()) {
                InputStream in = rs.getBinaryStream(2);
                byte bytes[] = new byte[8*1024];
                int nRead = in.read(bytes);
                while (nRead != -1) {
                    readsize = readsize + nRead;
                    outFileStream.write(bytes,0,nRead);
                    nRead = in.read(bytes);
                }

            }
            stmt.close();
            System.out.println("Read "+readsize+" bytes from database");
        }
        catch (SQLException ex) {
            printexp(ex);
        }
        catch (java.lang.Exception ex) {
            ex.printStackTrace ();
        }

    }


    static void createsample4() {
        Statement stmt = null;
        String proc = "create table sample4 (" +
                      "id numeric not null primary key,"+
                      "blob long varbinary)";

        try {
            stmt = conn.createStatement();
            stmt.execute("drop table sample4");
        } catch (SQLException ex) {
            printexp(ex);
        }

        try {
            stmt.execute(proc);
        } catch (SQLException ex) {
            printexp(ex);
            System.exit(-1);
        }
    }

    static void printexp(SQLException ex) {
        System.out.println("\n*** SQLException caught ***");
        while (ex != null) {
            System.out.println("SQLState: " + ex.getSQLState());
            System.out.println("Message:  " + ex.getMessage());
            System.out.println("Vendor:   " + ex.getErrorCode());
            ex = ex.getNextException ();
        }
    }

}
