001package com.identityworksllc.iiq.common.task.export;
002
003import com.identityworksllc.iiq.common.TaskUtil;
004import org.apache.commons.lang.StringEscapeUtils;
005import org.apache.commons.logging.Log;
006import sailpoint.api.SailPointContext;
007import sailpoint.tools.GeneralException;
008
009import java.sql.*;
010import java.util.List;
011
012/**
013 * Partition to gather stats on the tables in an Oracle database
014 */
015public class OracleGatherStatsPartition extends ExportPartition {
016
017    /**
018     * The list of table names on which to gather stats
019     */
020    private final List<String> tableNames;
021
022    /**
023     * Constructs a new gather-stats partition
024     * @param tableNames The table names
025     */
026    public OracleGatherStatsPartition(List<String> tableNames) {
027        this.tableNames = tableNames;
028    }
029
030    /**
031     * Executes the partition, in this case to gather stats
032     * @param context The context
033     * @param connection The connection to the target database
034     * @param logger The logger
035     * @throws GeneralException if anything fails with gathering stats
036     */
037    @Override
038    protected void export(SailPointContext context, Connection connection, Log logger) throws GeneralException {
039        String command = "{ call dbms_stats.gather_table_stats('%s', '%s', cascade=>TRUE) }";
040
041        try {
042            DatabaseMetaData md = connection.getMetaData();
043            String[] types = {"TABLE"};
044            try (ResultSet rs = md.getTables(null, null, "DE_%", types)) {
045                while(rs.next()) {
046                    String tableName = rs.getString("TABLE_NAME");
047                    String tableSchema = rs.getString("TABLE_SCHEM");
048
049                    if (tableNames.contains(tableName)) {
050                        String tableCommand = String.format(command, StringEscapeUtils.escapeSql(tableSchema), StringEscapeUtils.escapeSql(tableName));
051
052                        TaskUtil.withLockedPartitionResult(monitor,
053                                (partitionResult) -> monitor.updateProgress(partitionResult, "Gathering stats on " + tableName, -1));
054
055                        logger.info("Gathering stats on " + tableName);
056
057                        try(CallableStatement cstmt = connection.prepareCall(tableCommand)) {
058                            cstmt.execute();
059                        } catch(SQLException e) {
060                            logger.error("Caught an error gathering stats on table " + tableName, e);
061                            TaskUtil.withLockedPartitionResult(monitor,
062                                    (partitionResult) -> partitionResult.addException(e));
063                        }
064                    }
065                }
066            }
067        } catch(SQLException e) {
068            logger.error("Caught an error gathering stats", e);
069            throw new GeneralException(e);
070        }
071    }
072}