package com.queplix.tools.fkchecker.kernel.sources;

import com.queplix.tools.fkchecker.kernel.types.ForeignKey;
import com.queplix.tools.fkchecker.kernel.types.KeyPair;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

/**
 * @author dmitry.antonov
 */
public class MsSqlSource extends AbstractDBSource {

    private PreparedStatement tableNameGetter;
    private PreparedStatement columnNameGetter;


    public static ForeignKeysSource[] createSources(Properties properties) {
        return new ForeignKeysSource[]{new MsSqlSource(properties)};
    }

    private MsSqlSource(Properties properties) {
        super(properties);
    }

    protected void prepareParsing(Connection con) throws SQLException {
        fkeys = con.createStatement().executeQuery("select so.name, sfk.fkeyid, " +
                "sfk.rkeyid, sfk.fkey, sfk.rkey from sysforeignkeys sfk join sysobjects so on so.id=sfk.constid");
        tableNameGetter = con.prepareStatement("select name from sysobjects where id=?");
        columnNameGetter = con.prepareStatement("select name from syscolumns where id=? and colid=?");
    }

    protected boolean hasNext() throws SQLException {
        return fkeys.next();
    }

    private String executeGetter(PreparedStatement ps, int... param) throws SQLException {
        for (int i = 0; i < param.length; i++) {
            ps.setInt(i+1, param[i]);
        }
        ResultSet rs = ps.executeQuery();
        rs.next();
        return rs.getString(1); 
    }

    private KeyPair getKeyPair(int tableId, int columnId) throws SQLException {
        return new KeyPair(executeGetter(tableNameGetter, tableId), 
                executeGetter(columnNameGetter, tableId, columnId));

    }

    protected ForeignKey nextForeignKey(Connection con) throws SQLException {
        return new ForeignKey(fkeys.getString(1), getKeyPair(fkeys.getInt(2), fkeys.getInt(4)),
                getKeyPair(fkeys.getInt(3), fkeys.getInt(5))); 
    }
}
