/*
 * $Source: /usr/local/cvsroot/erserver/erserver/java/src/com/postgres/replic/tools/desc/SequenceDesc.java,v $
 * $Author: asullivan $ $Revision: 1.1.1.1 $ $Date: 2003/08/26 19:02:26 $
 *
 */

package com.postgres.replic.tools.desc;

import com.postgres.replic.tools.*;
import java.sql.*;

public class SequenceDesc extends GeneratorDescriptor {

    private static final String SEQ = "_seq_";
    public static final int DROP = 1;
    public static final int CREATE = 2;
    public static final int T_NO = -1;
    protected int mode = DROP + CREATE;

    public SequenceDesc(boolean print) {
        this.print = print;
    }

    public SequenceDesc(boolean print, int mode) throws Exception{
        this.print = print;
        this.mode = mode;
        validateMode();
    }

    public SequenceDesc(boolean print, Connection conn, int mode) throws Exception{
        this.print = print;
        if (conn == null ) {
            throw new Exception("SequenceDesc:: connection may not be null");
        }
        this.conn = conn;
        this.mode = mode;
        validateMode();
    }

    /** <p>
     *   This one we should probably use
    */
    public SequenceDesc(boolean print, Connection conn) throws Exception{
        this(print, conn, DROP + CREATE);
    }


    private void validateMode() throws Exception {
        if ( !( ((mode & DROP) > 0) || ((mode & CREATE) > 0) ) ) {
             throw new Exception("SequenceDesc::validateMode: wrong mode=" +mode);
        }
    }

    public boolean tableOnly() {
        return true;
    }

    protected String getDropSeq(String table) throws Exception {
        return "drop sequence " + getSeqName(table)+ ";";
    }

    protected String getCreateSeq(String table) throws Exception {

        String minValue = "";
        if (conn != null) {
            int count = getCount(table) + 1;
            minValue = " minvalue "  +  count;
        }

        return "create sequence " + getSeqName(table) + minValue + ";";
    }

    private int getCount(String table)  {
        Statement stmt = null;
        ResultSet rs = null;
        int count = T_NO;

        try {
            stmt = getConnection().createStatement();
            String sql = "select count(1) from " + table;
            if (getDebug()) System.out.println("::getCount: sql = "+ sql);
            rs = stmt.executeQuery(sql);
            while (rs.next()) {
                count = rs.getInt(1);
                if (getDebug()) System.out.println("::getCount: rs.getInt(1) = "+ count);
            }
        } catch (Exception e) {
            System.out.println("SequenceDesc::getCount" + e.toString());
        } finally {
            if (stmt != null) {
                 try { stmt.close(); } catch (Exception e) {};
            }

            if (rs != null) {
                 try { rs.close(); } catch (Exception e) {};
            }
        }

        return count;
    }

    public String getSeqName(String table) throws Exception {
        if (table == null || table.trim().equals("")) {
            throw new Exception("SequenceDesc::getSeqName: table name may not be empty!" );
        }

        return ToolKitConst.GLOBAL_PREFIX + getFiller(table) + SEQ;
    }

    public String getLine(String table) throws Exception {
        //System.out.println("::getLine: BEGIN master="+master);
        if (table.toLowerCase().startsWith(ToolKitConst.GLOBAL_PREFIX)) {
            return "";
        }

        String createLine = "";
        String dropLine = "";

        if (getDebug()) System.out.println("SequenceDesc::getLine mode="+mode);

        if ((mode & DROP) > 0) {
             dropLine = getDropSeq(table);
             if (getDebug()) System.out.println("SequenceDesc::getLine (mode & DROP) > 0; dropLine="+dropLine);
             if (print) {
                  System.out.println(dropLine);
             }
        }

        if ((mode & CREATE) > 0) {
             createLine = getCreateSeq(table);
             if (getDebug()) System.out.println("SequenceDesc::getLine (mode & CREATE) > 0; createLine="+createLine);
             if (print) {
                  System.out.println(createLine);
             }
        }

        return dropLine + "\n" + createLine;
    }
}

