001/*
002 *  Copyright 2010 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.plugins.externaldata.data.sql;
017
018import java.sql.ResultSet;
019import java.sql.ResultSetMetaData;
020import java.sql.SQLException;
021import java.util.ArrayList;
022import java.util.Collection;
023import java.util.Iterator;
024import java.util.List;
025
026import org.ametys.plugins.externaldata.data.DataInclusionException;
027import org.ametys.plugins.externaldata.data.QueryResult;
028import org.ametys.plugins.externaldata.data.QueryResultRow;
029import org.ametys.plugins.externaldata.data.Query.ResultType;
030
031/**
032 * SQL query result.
033 */
034public class SqlQueryResult implements QueryResult
035{
036    
037    /** The result type. */
038    protected ResultType _resultType;
039    
040    /** The result rows. */
041    protected List<QueryResultRow> _rows;
042    
043    /** The column names. */
044    private Collection<String> _columnNames;
045    
046    /**
047     * Constructs a query result around a ResultSet.
048     * @param resultSet the result set
049     */
050    public SqlQueryResult(ResultSet resultSet)
051    {
052        try
053        {
054            _extractResults(resultSet);
055        }
056        catch (SQLException e)
057        {
058            throw new RuntimeException(e);
059        }
060    }
061    
062    @Override
063    public ResultType getType()
064    {
065        return _resultType;
066    }
067    
068    @Override
069    public int getSize()
070    {
071        return _rows.size();
072    }
073    
074    /**
075     * Set the result type.
076     * @param resultType the result type.
077     */
078    public void setType(ResultType resultType)
079    {
080        this._resultType = resultType;
081    }
082    
083    @Override
084    public Collection<String> getColumnNames() throws DataInclusionException
085    {
086        return _columnNames;
087    }
088    
089    @Override
090    public Iterator<QueryResultRow> iterator()
091    {
092        return _rows.iterator();
093    }
094    
095    @Override
096    public void close()
097    {
098        // Does nothing.
099    }
100    
101    /**
102     * Extract the column names and results from a JDBC result set.
103     * @param resultSet the JDBC result set.
104     * @throws SQLException if an error occurs when manipulating the result set
105     */
106    protected void _extractResults(ResultSet resultSet) throws SQLException
107    {
108        ResultSetMetaData rsMeta = resultSet.getMetaData();
109        int count = rsMeta.getColumnCount();
110        
111        // First, extract the column names.
112        _columnNames = new ArrayList<>(count);
113        for (int i = 1; i <= count; i++)
114        {
115            String columnLabel = rsMeta.getColumnLabel(i);
116            // Exclude 'rnum' which is used for pagination of Oracle results
117            if (!"rnum".equals(columnLabel.toLowerCase())) 
118            {
119                _columnNames.add(rsMeta.getColumnLabel(i));
120            }
121        }
122        
123        // Then, extract the results.
124        _rows = new ArrayList<>();
125        while (resultSet.next())
126        {
127            SqlQueryResultRow row = new SqlQueryResultRow();
128            
129            for (String colName : _columnNames)
130            {
131                String value = resultSet.getString(colName);
132                row.put(colName, value);
133            }
134            
135            _rows.add(row);
136        }
137    }
138    
139}