Class ResultSetIterator

  • All Implemented Interfaces:
    AutoCloseable, Iterator<Object[]>

    public final class ResultSetIterator
    extends Object
    implements Iterator<Object[]>, AutoCloseable
    An adapter that translates a java.sql.ResultSet to Sailpoint Reporting’s preferred Iterator<Object[]>.

    This class also exposes several utility methods that can be used to implement standard ResultSet behavior outside of this iterator context.

    The constructor requires that you provide a list of column detail objects. These can be:

    • A String, which will be parsed as a ColumnToken (if it contains a ‘:’) or as a simple column name.

    • An instance of ColumnConfig, which can be used to specify column data in greater detail.

    • An instance of Sailpoint’s ReportColumnConfig class, which contains vastly more options for reporting purposes than are used here.

    Column tokens are case-sensitive. Column names are not.

    After obtaining an instance of this class, the query itself will be invoked on the first call to hasNext().

    You may obtain the next row of results as an Object[] using next() or as a Map (where the key is the column’s field name) using nextRow().

    • Constructor Detail

      • ResultSetIterator

        public ResultSetIterator​(ResultSet resultSet,
                                 sailpoint.api.SailPointContext context)
                          throws SQLException
        Constructs an iterator over the ResultSet, inferring the column names from the ResultSet’s metadata object.

        Columns will be returned in the order specified by the ResultSet.

        No special parsing or object conversion options are available via this constructor.

        Parameters:
        resultSet - The result set to iterate over
        context - The sailopint context
        Throws:
        SQLException - if anything goes wrong parsing the column names
      • ResultSetIterator

        public ResultSetIterator​(ResultSet resultSet,
                                 List<?> columns,
                                 sailpoint.api.SailPointContext context)
                          throws SQLException
        Adapts a ResultSet into Iterator<Object[]> form.

        The columns argument must be a list of objects that can be passed to ColumnConfig(Object).

        Parameters:
        resultSet - The result set to adapt
        columns - The ordered list of columns to include in the results
        context - The IIQ context
        Throws:
        SQLException - if something goes wrong with checking column names
    • Method Detail

      • addTypeHandler

        public static void addTypeHandler​(int type,
                                          ResultSetIterator.CustomTypeHandler handler)
        API method to add a new type handler, where the type is not handled out of box.
        Parameters:
        type - The type integer (from, e,g. Types.
        handler - The handler to execute
      • deriveTypedValue

        public static Object deriveTypedValue​(sailpoint.api.SailPointContext context,
                                              Object input,
                                              ColumnToken token)
                                       throws sailpoint.tools.GeneralException
        TODO invert this so we can use multiple arguments

        A variant of deriveTypedValue that takes in a ColumnToken object rather than a String.

        This prevents us from having to repeatedly parse the string.

        Parameters:
        context - The current Sailpoint context context
        input - The input from which to derive a proper value
        token - The parsed column token
        Returns:
        The resulting derived value as described in deriveTypedValue(SailPointContext, Object, String)
        Throws:
        sailpoint.tools.GeneralException - if any failures occur
      • deriveTypedValue

        public static Object deriveTypedValue​(sailpoint.api.SailPointContext context,
                                              Object input,
                                              String inputDerivedType)
                                       throws sailpoint.tools.GeneralException
        Static implementation of deriveTypedValue so it can be reused elsewhere.

        Derived types take the form [type]:[optional argument], similar to AngularJS filters. The valid types are ‘xml’, ‘timestamp’, boolean’, ‘object’, or any SailPointObject subclass name (e.g., Identity, Link).

        Examples:

        ‘col1’: Returns the value of result set field ‘col1’ as is

        ‘col1:xml’: Parses the string value of result set column ‘col1’ as SailPoint XML and returns the resulting object.

        ‘col1:xml:firstname’: Parses the string value of result set column ‘col1’ as SailPoint XML, then (if not null) returns the value of the property ‘firstname’ on that object.

        Types and arguments indicate:

        ‘xml’: The value will be parsed as an XML string. If an argument is present, Utilities.getProperty() will be used to dot-walk to that property of the parsed object. Otherwise, the parsed object itself will be returned.

        ‘timestamp’: The value will be parsed as a Long timestamp. The output will be a Date object. If an argument is present, it will be interpreted as a SimpleDateFormat format string and the output will be the formatted String.

        ‘boolean’: If the value is a String, it will be considered true if it is equal to the strings ‘true’, ‘1’, or ‘yes’. If the value is a Number, it will be considered true if it is non-zero. All other values are false.

        ‘object’: The value will be handled as a Java object of an arbitrary type. The argument will be used via Utilities.getProperty() to dot-walk to any arbitrary property.

        ‘script’: The value will be passed to the script provided as an argument, and the output of the Script will become the new value.

        ‘rule’: The value will be passed to the Rule specified by name in the argument, and the output of the Rule will become the new value. This is more efficient than the ‘script’ version because the parsed Beanshell can be cached by the RuleRunner.

        Any SailPointObject type: If the value is a String, it will be used as an ID to look up the actual object in the current context. The argument’s function is the same as the ‘object’ type.

        Parameters:
        context - The sailpoint context
        input - The input object
        inputDerivedType - The derived type to use
        Returns:
        The output object, which may be the same as the input
        Throws:
        sailpoint.tools.GeneralException - if any derivation failures occur
      • extractColumnValue

        public static ResultSetIterator.ColumnOutput extractColumnValue​(ResultSet resultSet,
                                                                        String columnToken,
                                                                        Integer type)
                                                                 throws SQLException,
                                                                        sailpoint.tools.GeneralException
        Processes the resulting column by extracting an appropriate object from the result set, returning the combination of the value and a derived type which can be passed to deriveTypedValue.
        Parameters:
        resultSet - Result set to read the column from
        columnToken - The column token, potentially including derived types
        type - The type of the column
        Returns:
        The derived type of the result, if any
        Throws:
        SQLException - on any database issues
        sailpoint.tools.GeneralException - on any Sailpoint issues
      • getFieldHeaderMap

        public Map<String,​StringgetFieldHeaderMap()
        Gets the map from field name to header.

        In many basic configurations, the field name and header will be identical, and both will be the same as the property name.

        This is a ListOrderedMap and the keys will be in order.

        Returns:
        The map from field name to header
      • hasNext

        public boolean hasNext()
        Returns true if the ResultSet has another row, advancing the ResultSet in the process.
        Specified by:
        hasNext in interface Iterator<Object[]>
        Returns:
        True if the ResultSet has another row
      • next

        public Object[] next()
        Retrieves the next row from the result set as an Object[], given the column configs.

        This method also populates the lastRow object returned by nextRow().

        Specified by:
        next in interface Iterator<Object[]>
        Returns:
        The columns in the current row in order
        Throws:
        NoSuchElementException - if this class has been closed or if a previous call to hasNext() returned false
      • nextRow

        public Map<String,​ObjectnextRow()
        To be used in place of next(), returns a Map structure with the column ‘field’ names instead of an Object[].

        See ColumnConfig.getField() for detail on which keys will be used.

        This method advances the iterator by internally invoking next().

        Returns:
        A Map representing the next row read by next()