br.fgv.dao.ResultadosDAO.java Source code

Java tutorial

Introduction

Here is the source code for br.fgv.dao.ResultadosDAO.java

Source

/**
 * Copyright (c) 20012-2013 "FGV - CEPESP" [http://cepesp.fgv.br]
 *
 * This file is part of CEPESP-DATA.
 *
 * CEPESP-DATA is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * CEPESP-DATA is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with CEPESP-DATA. If not, see <http://www.gnu.org/licenses/>.
 */
package br.fgv.dao;

import static br.fgv.model.Tabela.CO_DIM_CANDIDATOS_CARGO_COD;
import static br.fgv.model.Tabela.CO_DIM_CANDIDATOS_NOME;
import static br.fgv.model.Tabela.CO_DIM_CANDIDATOS_TITULO;
import static br.fgv.model.Tabela.CO_DIM_CARGO_CD;
import static br.fgv.model.Tabela.CO_DIM_CARGO_DS;
import static br.fgv.model.Tabela.CO_DIM_ESTADOS_ID;
import static br.fgv.model.Tabela.CO_DIM_ESTADOS_NOME;
import static br.fgv.model.Tabela.CO_DIM_MACROREGIAO_COD;
import static br.fgv.model.Tabela.CO_DIM_MACROREGIAO_NOME;
import static br.fgv.model.Tabela.CO_DIM_MESOREGIAO_ID;
import static br.fgv.model.Tabela.CO_DIM_MESOREGIAO_NOME;
import static br.fgv.model.Tabela.CO_DIM_MICROREGIAO_ID;
import static br.fgv.model.Tabela.CO_DIM_MICROREGIAO_NOME;
import static br.fgv.model.Tabela.CO_DIM_MUNICIPIO_COD;
import static br.fgv.model.Tabela.CO_DIM_MUNICIPIO_NOME;
import static br.fgv.model.Tabela.CO_DIM_MUNICIPIO_SIGLA_UF;
import static br.fgv.model.Tabela.CO_DIM_PARTIDOS_ANO;
import static br.fgv.model.Tabela.CO_DIM_PARTIDOS_COD;
import static br.fgv.model.Tabela.CO_DIM_PARTIDOS_SIGLA;
import static br.fgv.model.Tabela.CO_FACT_VOTOS_MUN_COD_CARGO;
import static br.fgv.model.Tabela.CO_FACT_VOTOS_MUN_QNT_VOTOS;
import static br.fgv.model.Tabela.CO_FACT_VOTOS_MUN_TIPO_VOTAVEL;
import static br.fgv.model.Tabela.CO_FACT_VOTOS_MUN_TURNO;
import static br.fgv.model.Tabela.CO_SIS_ANOS_ANO;
import static br.fgv.model.Tabela.CO_SIS_ANO_CARGO_ANO;
import static br.fgv.model.Tabela.CO_SIS_ANO_CARGO_COD_CARGO;
import static br.fgv.model.Tabela.REF_FACT;
import static br.fgv.model.Tabela.TB_DIM_CANDIDATOS;
import static br.fgv.model.Tabela.TB_DIM_CARGO;
import static br.fgv.model.Tabela.TB_DIM_ESTADOS;
import static br.fgv.model.Tabela.TB_DIM_MACROREGIAO;
import static br.fgv.model.Tabela.TB_DIM_MESOREGIAO;
import static br.fgv.model.Tabela.TB_DIM_MICROREGIAO;
import static br.fgv.model.Tabela.TB_DIM_MUNICIPIO;
import static br.fgv.model.Tabela.TB_DIM_PARTIDOS;
import static br.fgv.model.Tabela.TB_FACT_VOTOS_MUN;
import static br.fgv.model.Tabela.TB_SIS_ANOS;
import static br.fgv.model.Tabela.TB_SIS_ANO_CARGO;
import static br.fgv.model.Tabela.VOTO_LEGENDA;
import static br.fgv.model.Tabela.VOTO_LEGENDA_COD;
import static br.fgv.model.Tabela.VOTO_NOMINAL;
import static br.fgv.model.Tabela.VOTO_NOMINAL_COD;
import static br.fgv.model.Tabela.VOTO_TOTAL;
import static br.fgv.util.QueryBuilder.EQ;
import static br.fgv.util.QueryBuilder.IFF;
import static br.fgv.util.QueryBuilder._ORDER_BY_;
import static br.fgv.util.QueryBuilder.a;
import static br.fgv.util.QueryBuilder.p;
import static br.fgv.util.QueryBuilder.s;

import java.io.IOException;
import java.io.InputStream;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;

import br.fgv.CepespDataException;
import br.fgv.business.AgregacaoPolitica;
import br.fgv.business.AgregacaoRegional;
import br.fgv.model.Coluna;
import br.fgv.model.Tabela;
import br.fgv.util.ArgumentosBusca;
import br.fgv.util.CSVBuilder;
import br.fgv.util.Par;
import br.fgv.util.QueryBuilder;

public class ResultadosDAO {

    private static final Logger LOGGER = Logger.getLogger(ResultadosDAO.class);

    private final Session session;

    public ResultadosDAO(Session session) {
        this.session = session;
    }

    private Session getSession() {
        return session;
    }

    @SuppressWarnings("unchecked")
    private List<Integer> getAnosDisponiveis() {
        List<Integer> list = null;

        try {
            QueryBuilder qb = new QueryBuilder();

            qb.select_().coluna(CO_SIS_ANOS_ANO)._from_().tabela(TB_SIS_ANOS)._order_by_().coluna(CO_SIS_ANOS_ANO);

            Query query = getSession().createSQLQuery(qb.toString());

            list = (List<Integer>) query.list();

        } catch (RuntimeException e) {
            LOGGER.error("Falhou ao tentar obter anos disponiveis.", e);
        }

        return list;
    }

    public List<Par> getAnosDisponiveisList() {
        List<Par> pares = new ArrayList<Par>();
        List<Integer> list = null;

        list = getAnosDisponiveis();

        for (Integer item : list) {
            String i = String.valueOf(item);
            pares.add(new Par(i, i));
        }

        return pares;
    }

    public List<Par> getCargosList() {
        List<Integer> anos = getAnosDisponiveis();

        List<String> queries = new ArrayList<String>();

        for (Integer ano : anos) {
            queries.add(getQueryCargosPorAnoList(Integer.toString(ano)));
        }

        String completeQuery = QueryBuilder.unionDistinct(queries) + _ORDER_BY_ + CO_SIS_ANO_CARGO_COD_CARGO;

        System.out.println(">> QUERY COMPLETA");
        System.out.println(completeQuery);
        System.out.println("<< QUERY COMPLETA");

        List<Par> pares = new ArrayList<Par>();
        List<Object[]> list = null;

        try {

            Query query = getSession().createSQLQuery(completeQuery);

            list = (List<Object[]>) query.list();

            for (Object[] item : list) {
                String chave = String.valueOf(item[0]);
                String valor = String.valueOf(item[1]);

                pares.add(new Par(chave, valor));
            }
        } catch (RuntimeException e) {
            LOGGER.error("Falhou ao tentar obter cargos disponiveis.", e);
        }

        return pares;
    }

    @SuppressWarnings("unchecked")
    public List<Par> getCargosPorAnoList(String ano) {
        List<Par> pares = new ArrayList<Par>();
        List<Object[]> list = null;

        try {
            String queryString = getQueryCargosPorAnoList(ano);

            Query query = getSession().createSQLQuery(queryString);

            list = (List<Object[]>) query.list();

            for (Object[] item : list) {
                String chave = String.valueOf(item[0]);
                String valor = String.valueOf(item[1]);

                pares.add(new Par(chave, valor));
            }

        } catch (RuntimeException e) {
            LOGGER.error("Falhou ao tentar obter cargos disponiveis por ano.", e);
        }

        return pares;
    }

    public String getQueryCargosPorAnoList(String ano) {
        QueryBuilder qb = new QueryBuilder();

        qb.select_().colunas(CO_SIS_ANO_CARGO_COD_CARGO, CO_DIM_CARGO_DS)._from_().declareRef(TB_SIS_ANO_CARGO, s)
                .comma_().declareRef(TB_DIM_CARGO, a)._where_().ref(CO_SIS_ANO_CARGO_COD_CARGO, s)._eq_()
                .ref(CO_DIM_CARGO_CD, a)._and_().ref(CO_SIS_ANO_CARGO_ANO, s)._eq_().valor(ano);

        return qb.toString();
    }

    public List<Par> getAnosParaCargoList(String cargo) {
        List<Par> pares = new ArrayList<Par>();
        List<Integer> list = null;

        try {
            QueryBuilder qb = new QueryBuilder();

            qb.select_()._distinct_().colunas(CO_SIS_ANO_CARGO_ANO)._from_().tabela(TB_SIS_ANO_CARGO)._where_()
                    .coluna(CO_SIS_ANO_CARGO_COD_CARGO)._eq_().valor(cargo)._order_by_()
                    .coluna(CO_SIS_ANO_CARGO_ANO);

            Query query = getSession().createSQLQuery(qb.toString());

            list = (List<Integer>) query.list();

            for (Integer item : list) {
                String chave = String.valueOf(item);
                String valor = String.valueOf(item);

                pares.add(new Par(chave, valor));
            }

        } catch (RuntimeException e) {
            LOGGER.error("Falhou ao tentar obter cargos disponiveis por ano.", e);
        }

        return pares;
    }

    QueryBuilder appendFiltroPolitico(QueryBuilder query, AgregacaoPolitica agregacaoPolitica,
            String[] filtroPolitico) {

        // nesses casos o nivel  fora do intervalo...
        if (agregacaoPolitica == null || filtroPolitico == null || filtroPolitico.length == 0) {
            // do nothing
        } else {
            query._and_().valor(agregacaoPolitica.getNome()).in(filtroPolitico);
        }

        return query;
    }

    QueryBuilder appendFiltroRegional(QueryBuilder query, AgregacaoRegional agregacaoRegional,
            String[] filtroRegional) {

        if (agregacaoRegional == null || filtroRegional == null || filtroRegional.length == 0) {
            // do nothing
        } else {
            query._and_().valor(agregacaoRegional.getCamposAgregar()).in(filtroRegional);
        }

        return query;
    }

    String getStringQueryFato(ArgumentosBusca args, String ano) {

        String reg = args.getNivelRegional().getCamposAgregar();
        String pol = args.getNivelAgrecacaoPolitica().getNome();

        QueryBuilder qb = new QueryBuilder();

        // SELECT
        qb.select_().comma(CO_FACT_VOTOS_MUN_TURNO, reg, pol);
        qb.comma_().sum(IFF(EQ(CO_FACT_VOTOS_MUN_TIPO_VOTAVEL, VOTO_NOMINAL_COD), CO_FACT_VOTOS_MUN_QNT_VOTOS, 0))
                ._as_().valor(VOTO_NOMINAL);
        qb.comma_().sum(CO_FACT_VOTOS_MUN_QNT_VOTOS)._as_().valor(VOTO_TOTAL);

        if (AgregacaoPolitica.PARTIDO.equals(args.getNivelAgrecacaoPolitica())
                || AgregacaoPolitica.COLIGACAO.equals(args.getNivelAgrecacaoPolitica())) {
            qb.comma_()
                    .sum(IFF(EQ(CO_FACT_VOTOS_MUN_TIPO_VOTAVEL, VOTO_LEGENDA_COD), CO_FACT_VOTOS_MUN_QNT_VOTOS, 0))
                    ._as_().valor(VOTO_LEGENDA);
        }

        qb._from_().tabela(TB_FACT_VOTOS_MUN);

        // WHERE
        qb._where_().eq(CO_FACT_VOTOS_MUN_COD_CARGO, args.getFiltroCargo())._and_().eq(CO_FACT_VOTOS_MUN_TURNO,
                args.getTurno());

        appendFiltroRegional(qb, args.getNivelFiltroRegional(), args.getFiltroRegional());
        appendFiltroPolitico(qb, AgregacaoPolitica.PARTIDO, args.getFiltroPartido());
        // filtro candidato agora  feito na tabela resultado. Veja metodo aplicarFiltros

        // GROUP BY
        qb._group_by_().comma(reg, pol, CO_FACT_VOTOS_MUN_TURNO)._order_by_().comma(reg, pol,
                CO_FACT_VOTOS_MUN_TURNO);

        return qb.toString(ano);
    }

    String getStringQueryDim(String queryFato, String anoEleicao, String[] camposEscolhidos,
            AgregacaoPolitica agregacaoPolitica) {

        SortedSet<String> tabelasARelacionar = new TreeSet<String>(new Comparator<String>() {
            public int compare(String o1, String o2) {
                Tabela t1 = Tabela.byName(o1);
                Tabela t2 = Tabela.byName(o2);
                return t1.compareTo(t2);
            }
        });

        for (String campo : camposEscolhidos) {
            String tabela = campo.substring(0, campo.indexOf("."));
            if (Tabela.byName(tabela) != null)
                tabelasARelacionar.add(tabela);
        }

        SortedSet<String> camposFiltrados = new TreeSet<String>(new Comparator<String>() {
            public int compare(String campo1, String campo2) {
                campo1 = zonaWorkaround(campo1);
                campo2 = zonaWorkaround(campo2);

                String nomeTab1 = campo1.substring(0, campo1.indexOf('.'));
                String nomeCol1 = campo1.substring(campo1.indexOf('.') + 1);

                String nomeTab2 = campo2.substring(0, campo2.indexOf('.'));
                String nomeCol2 = campo2.substring(campo2.indexOf('.') + 1);

                Tabela t1 = Tabela.byName(nomeTab1);
                Tabela t2 = Tabela.byName(nomeTab2);

                if (nomeTab1.equals(nomeTab2)) {
                    // compara coluna
                    Coluna c1 = t1.getColuna(nomeCol1);
                    Coluna c2 = t2.getColuna(nomeCol2);
                    return c1.compareTo(c2);
                }

                return t1.compareTo(t2);
            }

            private String zonaWorkaround(String campo) {
                if (campo.startsWith("zona"))
                    return TB_DIM_MUNICIPIO.getNome() + "." + CO_DIM_MUNICIPIO_NOME.getNome();
                return campo;
            }
        });
        for (String c : camposEscolhidos) {
            if (c.startsWith("zona.")) {
                camposFiltrados.add("zona");
            } else if (c.startsWith("votos.")) {
                // nao inclui
            } else {
                camposFiltrados.add(c);
            }

        }

        QueryBuilder qb = new QueryBuilder();
        qb.select_().valor(anoEleicao + " AS \"anoEleicao\", ").valor(CO_FACT_VOTOS_MUN_TURNO + " AS \"turno\", ")
                .commaWithTrailing(camposFiltrados.toArray()).comma(agregacaoPolitica.getColunas())._from_()
                .par(queryFato)._as_().valor(REF_FACT);

        for (String nomeTabela : tabelasARelacionar) {
            Tabela tabela = Tabela.byName(nomeTabela);
            if (tabela != null && tabela.getRelacao() != null && !nomeTabela.equals("zona")) {
                qb._left_join_().tabela(tabela)._on_().valor(replace(tabela.getRelacao(), anoEleicao));
            }
        }

        String ret = qb.toString(anoEleicao);

        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Query DIM:\t" + ret);
        }

        return ret;
    }

    private String replace(String relacao, String anoEleicao) {
        return relacao.replace(Tabela.HOLDER_ANO_ELEICAO, anoEleicao);
    }

    public ResultSetWork queryFato(ArgumentosBusca args) {

        String[] anos = args.getAnoEleicao();

        List<String> queries = new ArrayList<String>();

        for (String ano : anos) {
            String queryFato = getStringQueryFato(args, ano);
            String queryTotal = getStringQueryDim(queryFato, ano, args.getCamposEscolhidos(),
                    args.getNivelAgrecacaoPolitica());
            String queryFinal = aplicarFiltros(queryTotal, args);

            queries.add(queryFinal);

            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("Query para ano:\t" + ano);
                LOGGER.debug("Query fato:\t" + queryFato);
                LOGGER.debug("Query total:\t" + queryTotal);
                LOGGER.debug("Query total:\t" + queryFinal);
            }
        }

        String union = QueryBuilder.unionAll(queries);

        ResultSetWork ra = new ResultSetWork();

        ra.setQuery(union);
        session.doWork(ra);

        return ra;
    }

    String aplicarFiltros(String queryTotal, ArgumentosBusca args) {
        // por agora, apenas filtro de candidato... os outros podem ser feito
        // direto na fato.
        QueryBuilder qb = new QueryBuilder();
        String[] filtroCandidato = args.getFiltroCandidato();
        if (filtroCandidato != null && filtroCandidato.length > 0) {
            qb.select_()._star_()._from_().declareRef(queryTotal, "T")._where_().ref(CO_DIM_CANDIDATOS_TITULO, "T")
                    .in(filtroCandidato);
        } else {
            return queryTotal;
        }

        return qb.toString();
    }

    public InputStream doWorkResult(ArgumentosBusca args) throws CepespDataException {

        long start = System.currentTimeMillis();
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug(">>> doWorkResult");
        }

        final ResultSetWork ra = queryFato(args);
        final ResultSet rs = ra.getResultSet();

        if (LOGGER.isInfoEnabled()) {
            LOGGER.info("Consulta concluida. Tempo (s): " + (System.currentTimeMillis() - start) / 1000.0);
        }

        InputStream is = null;
        try {
            final CSVBuilder csv = CSVBuilder.getInstance();
            csv.setSource(ra, rs);
            csv.start();

            is = csv.getAsInputStream();

        } catch (IOException e) {
            LOGGER.error("IOException ao montar output.", e);
        } catch (RuntimeException e) {
            LOGGER.error("RuntimeException ao montar output.", e);
        }

        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("<<< doWorkResult");
        }

        return is;
    }

    public String getCargoByID(String codCargo) {
        String ret = null;

        try {
            QueryBuilder qb = new QueryBuilder();
            qb.select_().coluna(CO_DIM_CARGO_DS)._from_().declareRef(TB_DIM_CARGO, a)._where_()
                    .ref(CO_DIM_CARGO_CD, a)._eq_().valor(codCargo);

            Query query = getSession().createSQLQuery(qb.toString());

            ret = (String) query.uniqueResult();
            if (ret == null || ret.isEmpty()) {
                LOGGER.error("Nao pude obter cargo para id: " + codCargo);
            }

        } catch (RuntimeException e) {
            LOGGER.error("Exception ao tentar obter cargo para id: " + codCargo, e);
        }

        return ret;
    }

    public List<Par> getPartidosPorAnoList(String ano) {
        String[] anos = { ano };
        return getPartidosPorAnoList(anos);
    }

    @SuppressWarnings("unchecked")
    public List<Par> getPartidosPorAnoList(String[] anosList) {
        List<Par> pares = new ArrayList<Par>();
        List<Object[]> list = null;

        List<String> partialQueries = new ArrayList<String>(anosList.length);

        for (String ano : anosList) {
            QueryBuilder qb = new QueryBuilder();
            qb.select_().colunas(CO_DIM_PARTIDOS_COD, CO_DIM_PARTIDOS_SIGLA)._from_().declareRef(TB_DIM_PARTIDOS, p)
                    ._where_().ref(CO_DIM_PARTIDOS_ANO, p)._eq_().valor(ano);

            partialQueries.add(qb.toString());
        }

        String queryStr = QueryBuilder.unionDistinct(partialQueries) + _ORDER_BY_ + CO_DIM_PARTIDOS_COD;

        try {

            Query query = getSession().createSQLQuery(queryStr);

            list = (List<Object[]>) query.list();

            for (Object[] item : list) {
                String chave = String.valueOf(item[0]);
                String valor = String.valueOf(item[1] + " (" + item[0] + ")");

                pares.add(new Par(chave, valor));
            }

        } catch (RuntimeException e) {
            LOGGER.error("Exception ao tentar obter partidos por: " + Arrays.toString(anosList), e);
        }

        return pares;
    }

    @SuppressWarnings("unchecked")
    private List<Par> getParList(Query query) {
        List<Par> pares = new ArrayList<Par>();
        List<Object[]> list = null;

        try {
            list = (List<Object[]>) query.list();

            for (Object[] item : list) {
                String chave = String.valueOf(item[0]);
                String valor = String.valueOf(item[1]);

                pares.add(new Par(chave, valor));
            }

        } catch (RuntimeException e) {
            LOGGER.error("Exception ao tentar executar query!", e);
        }

        return pares;
    }

    @SuppressWarnings("unchecked")
    private List<Par> getParChaveList(Query query) {
        List<Par> pares = new ArrayList<Par>();
        List<Object[]> list = null;

        try {
            list = (List<Object[]>) query.list();

            for (Object[] item : list) {
                String chave = String.valueOf(item[0]);
                String valor = String.valueOf(item[1]);

                pares.add(new Par(chave, valor + " (" + chave + ")"));
            }

        } catch (RuntimeException e) {
            LOGGER.error("Exception ao tentar executar query!", e);
        }

        return pares;
    }

    public List<Par> getMacroRegiaoList() {
        QueryBuilder qb = new QueryBuilder();

        qb.select_().colunas(CO_DIM_MACROREGIAO_COD, CO_DIM_MACROREGIAO_NOME)._from_().tabela(TB_DIM_MACROREGIAO);

        Query query = getSession().createSQLQuery(qb.toString());

        return getParList(query);
    }

    public List<Par> getEstadosList() {
        QueryBuilder qb = new QueryBuilder();

        qb.select_().colunas(CO_DIM_ESTADOS_ID, CO_DIM_ESTADOS_NOME)._from_().tabela(TB_DIM_ESTADOS);

        Query query = getSession().createSQLQuery(qb.toString());
        return getParList(query);
    }

    public List<Par> getMesoRegiaoList(String filtro) {
        QueryBuilder qb = new QueryBuilder();

        qb.select_().colunas(CO_DIM_MESOREGIAO_ID, CO_DIM_MESOREGIAO_NOME)._from_().tabela(TB_DIM_MESOREGIAO)
                ._where_().coluna(CO_DIM_MESOREGIAO_NOME).like(filtro);

        Query query = getSession().createSQLQuery(qb.toString());
        return getParList(query);
    }

    public List<Par> getMicroRegiaoList(String filtro) {
        QueryBuilder qb = new QueryBuilder();

        qb.select_().colunas(CO_DIM_MICROREGIAO_ID, CO_DIM_MICROREGIAO_NOME)._from_().tabela(TB_DIM_MICROREGIAO)
                ._where_().coluna(CO_DIM_MICROREGIAO_NOME).like(filtro);

        Query query = getSession().createSQLQuery(qb.toString());
        return getParList(query);
    }

    public List<Par> getMunicipioList(String filtro) {
        QueryBuilder qb = new QueryBuilder();

        qb.select_().coluna(CO_DIM_MUNICIPIO_COD).comma_()
                .concat(CO_DIM_MUNICIPIO_NOME, "'-'", CO_DIM_MUNICIPIO_SIGLA_UF)._as_().valor("des")._from_()
                .tabela(TB_DIM_MUNICIPIO)._where_().coluna(CO_DIM_MUNICIPIO_NOME).like(filtro);

        Query query = getSession().createSQLQuery(qb.toString());
        return getParList(query);
    }

    //   public List<Par> getCandidatosPorAnoList(String filtro, String ano) {
    //
    //      QueryBuilder qb = new QueryBuilder();
    //
    //      qb.select_().colunas(CO_DIM_CANDIDATOS_SURROGATEKEY, CO_DIM_CANDIDATOS_NOME)
    //         ._from_().tabela(TB_DIM_CANDIDATOS)
    //         ._where_().coluna(CO_DIM_CANDIDATOS_NOME).like(filtro);
    //
    //
    //      Query query = getSession().createSQLQuery(qb.toString(ano));
    //      return getParList(query);
    //   }

    public List<Par> getCandidatosPorAnoList(String filtro, String ano) {
        String[] anos = { ano };
        return getCandidatosPorAnoList(filtro, anos, null);
    }

    public List<Par> getCandidatosPorAnoList(String filtro, String[] anos, String codCargo) {

        List<String> partialQueries = new ArrayList<String>(anos.length);

        for (String ano : anos) {
            QueryBuilder qb = new QueryBuilder();

            qb.select_()._distinct_().colunas(CO_DIM_CANDIDATOS_TITULO, CO_DIM_CANDIDATOS_NOME)._from_()
                    .tabela(TB_DIM_CANDIDATOS)._where_().coluna(CO_DIM_CANDIDATOS_NOME).like(filtro);
            if (codCargo != null && codCargo.length() > 0) {
                qb._and_().coluna(CO_DIM_CANDIDATOS_CARGO_COD)._eq_().valor(codCargo);
            }
            partialQueries.add(qb.toString(ano));
        }

        String queryStr = QueryBuilder.unionDistinct(partialQueries);

        Query query = getSession().createSQLQuery(queryStr);
        return getParChaveList(query);
    }

    public List<Date> getDataCarga() {
        StringBuilder select = new StringBuilder();
        select.append("SELECT distinct data_etl FROM info_cepespdata.datas");

        Query query = getSession().createSQLQuery(select.toString());

        @SuppressWarnings("unchecked")
        List<Date> datas = (List<Date>) query.list();

        return datas;
    }

    public Date getDataCand(String carga, int ano) {
        StringBuilder select = new StringBuilder();
        select.append("select data_tse_cand from info_cepespdata.datas where data_etl = '" + carga
                + "' and ano_eleicao = " + ano);

        Query query = getSession().createSQLQuery(select.toString());

        List<Date> datas = (List<Date>) query.list();

        return datas.get(0);
    }

    public Date getDataVoto(String carga, int ano) {
        StringBuilder select = new StringBuilder();
        select.append("select data_tse_voto from info_cepespdata.datas where data_etl = '" + carga
                + "' and ano_eleicao = " + ano);

        Query query = getSession().createSQLQuery(select.toString());

        List<Date> datas = (List<Date>) query.list();

        return datas.get(0);
    }
}