/*
 * $Source: /usr/local/cvsroot/erserver/erserver/java/src/com/postgres/replic/util/struct/TableMap.java,v $
 * $Author: asullivan $ $Revision: 1.1.1.1 $ $Date: 2003/08/26 19:02:31 $
 *
 */

package com.postgres.replic.util.struct;

import java.util.*;

public class TableMap implements DataConst {
    private static final int ELEM_NUM = 5;
    private HashMap tableMap = new HashMap();
    private String [] elements = new String[ELEM_NUM];
    private String [] currentRow = new String[ELEM_NUM];
    private String [] prevRow = new String[ELEM_NUM];
    // rowKey - oid for Master table map & tableName for Slave one: 
    private String currentRowKey = null;
    private String prevRowKey = null;

    // Element types (number of elem types == ELEM_NUM):
    private static final int RELNAME = 0;
    private static final int ATTNAME = 1;
    private static final int KEY = 2;
    private static final int OID = 3;
    private static final int KEY_TYPE = 4;

    private Iterator iterator;

    public TableMap setIterator(){
         iterator = tableMap.keySet().iterator();
         return this;
    }

    public boolean hasNext() throws Exception {
        if(iterator == null) {
            throw new Exception("TableMap::hasNext: Iterator is not set");
        }
        return iterator.hasNext();
    }

    public String nextRowKey() throws Exception {
        if(iterator == null) {
            throw new Exception("TableMap::nextRowKey: Iterator is not set");
        }
        return (String) iterator.next();
    }



    /* it is possible to do something like:
     * tableMap.addElement(rowKey).setOid(oid).setRelName(relName).setAttName(attName).setKey(key);
    */
    public TableMap addElement(String rowKey) throws Exception {
        if (rowKey == null || rowKey.trim().equals("")) {
             throw new Exception("TableMap::addElement: rowKey may not be empty");
        }
        String [] elements = new String[ELEM_NUM];
        tableMap.put(rowKey, elements);
        return setRow(rowKey) ;
    }

    /*
    */
    public TableMap setOid(String oid) throws Exception {
        if (oid == null || oid.trim().equals("")) {
             throw new Exception("TableMap::setOid: oid may not be empty");
        }
        String [] elements = (String []) tableMap.get(currentRowKey);
        elements[OID] = oid;
        return this;
    }

    public TableMap setRelName(String relName) throws Exception {
        if (relName == null || relName.trim().equals("")) {
             throw new Exception("TableMap::setRelName: relName may not be empty");
        }
        String [] elements = (String []) tableMap.get(currentRowKey);
        elements[RELNAME] = relName;
        return this;
    }

    public TableMap setAttName(String attName) throws Exception {
        if (attName == null || attName.trim().equals("")) {
             throw new Exception("TableMap::setAttName: attName may not be empty");
        }
        String [] elements = (String []) tableMap.get(currentRowKey);
        elements[ATTNAME] = attName;
        return this;
    }

    public TableMap setKey(String key) throws Exception {
        if (key == null || key.trim().equals("")) {
             throw new Exception("TableMap::setKey: key may not be empty");
        }
        String [] elements = (String []) tableMap.get(currentRowKey);
        elements[KEY] = key;
        return this;
    }

    public TableMap setKeyType(String key) throws Exception {
        if (key == null || key.trim().equals("")) {
             throw new Exception("TableMap::setKeyType: key may not be empty");
        }
        String [] elements = (String []) tableMap.get(currentRowKey);
        elements[KEY_TYPE] = key;
        return this;
    }


    /* can be used like:
        relName = tableMap.setRow(rowKey).getRelName();
    */
    public TableMap setRow(String rowKey) throws Exception {
        if (rowKey == null || rowKey.trim().equals("")) {
            throw new Exception("TableMap::setRow: rowKey may not be empty");
        }

        prevRowKey = rowKey;
        currentRowKey = rowKey;
        prevRow = currentRow;
        currentRow = (String[]) tableMap.get(rowKey);
        if (currentRow == null) {
            currentRow = prevRow;
            currentRowKey = prevRowKey;
            throw new Exception("TableMap::setRow: no such row!");
        }

        return this;
    }

    public boolean rowExists(String rowKey) {
        return tableMap.containsKey(rowKey);
    }

    public String getCurrentRowKey() throws Exception {
        validateRow();
        return currentRowKey;
    }

    public String getOid() throws Exception {
        validateRow();
        return currentRow[OID];
    }

    public String getRelName() throws Exception {
        validateRow();
        return currentRow[RELNAME];
    }

    public String getAttName() throws Exception {
        validateRow();
        return currentRow[ATTNAME];
    }

    public String getKey() throws Exception {
        validateRow();
        return currentRow[KEY];
    }

    public String getKeyType() throws Exception {
        validateRow();
        return currentRow[KEY_TYPE];
    }

    public long getOidInt() throws Exception {
        validateRow();
        return (new Integer(currentRowKey)).intValue();
    }

    public long getKeyLong() throws Exception {
        validateRow();
        return (currentRow[KEY] == null ? T_NO :
            (new Long(currentRow[KEY])).longValue());
    }

    public int getKeyInt() throws Exception {
        validateRow();
        return (currentRow[KEY] == null ? T_NO :
            (new Integer(currentRow[KEY])).intValue());
    }

    private void validateRow() throws Exception {
        if (currentRow == null || currentRowKey == null) {
            throw new Exception("TableMap::validateRow: Current row is not set");
        }
    }

}
