package javacodebook.jdbc.rowcounter;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class RowCounter {

    public static void main(String[] args) {

        try {
            Class.forName("org.postgresql.Driver");
            Connection con =
                DriverManager.getConnection(
                    "jdbc:postgresql:test",
                    "postgres",
                    "postgres");

            Statement statement = con.createStatement();
            System.out.println("Default ResulSet features:");
            checkStatement(statement);

            // Die Anzahl der Datensätze lassen sich leider nur
            // mit einem extra Counter durchzählen
            ResultSet result =
                statement.executeQuery("SELECT * FROM employees");
            int rows = 0;
            while (result.next()) {
                rows++;
            }
            System.out.println(
                "ResulSet contains " + rows + " rows");

            // Man kann die Anzahl der Datensätze nur dann vorher
            // ermitteln, wenn man das ResultSet wieder
            // zurückspulen kann
            if (statement.getResultSetType()
                == ResultSet.TYPE_FORWARD_ONLY) {
                System.out.println(
                    "You may have a Exception soon /"
                        + " ResultSets are of Type 'forward only'");
            }
            result.beforeFirst();

            // Das ResultSet ist jetzt im gleichen Zustand wie 
            // direkt nach executeQuery
            while (result.next()) {
                System.out.println(
                    result.getString("firstname")
                        + " "
                        + result.getString("lastname"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Analysiert bei einem Statement, welche Typen von ResultSet
     * es liefern kann.
     * @param statement
     * @throws SQLException
     */
    public static void checkStatement(Statement statement)
        throws SQLException {
        int type = statement.getResultSetType();
        switch (type) {
            case ResultSet.TYPE_FORWARD_ONLY :
                System.out.println(
                    "ResultSets of type 'forward only'");
                break;
            case ResultSet.TYPE_SCROLL_SENSITIVE :
                System.out.println(
                    "ResultSets of type 'scroll sensitive'");
                break;
            case ResultSet.TYPE_SCROLL_INSENSITIVE :
                System.out.println(
                    "ResultSets of type 'scroll insensitive'");
                break;
        }

        int concurtype = statement.getResultSetConcurrency();
        switch (concurtype) {
            case ResultSet.CONCUR_READ_ONLY :
                System.out.println("ResultSets are read-only");
                break;
            case ResultSet.CONCUR_UPDATABLE :
                System.out.println("ResultSets are updatable");
                break;
        }

        try {
            int holdtype = statement.getResultSetHoldability();
            switch (holdtype) {
                case ResultSet.HOLD_CURSORS_OVER_COMMIT :
                    System.out.println(
                        "ResultSets hold cursors over a commit");
                    break;
                case ResultSet.CLOSE_CURSORS_AT_COMMIT :
                    System.out.println(
                        "ResultSets should be closed after a"
                            + " commit");
                    break;
            }
        } catch (Throwable e) {
            System.out.println(
                "Statement.getResultSetHoldability() "
                    + "not supported");
        }

    }
}
