001/*
002 * ============================================================================
003 * Copyright © 2002-2022 by Thomas Thrien.
004 * All Rights Reserved.
005 * ============================================================================
006 *
007 * Licensed to the public under the agreements of the GNU Lesser General Public
008 * License, version 3.0 (the "License"). You may obtain a copy of the License at
009 *
010 *      http://www.gnu.org/licenses/lgpl.html
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
014 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
015 * License for the specific language governing permissions and limitations
016 * under the License.
017 */
018
019package org.tquadrat.foundation.sql.internal;
020
021import static org.apiguardian.api.API.Status.INTERNAL;
022import static org.tquadrat.foundation.lang.Objects.requireNonNullArgument;
023
024import java.sql.ResultSet;
025import java.sql.SQLException;
026import java.util.Optional;
027import java.util.Spliterator;
028import java.util.function.Consumer;
029
030import org.apiguardian.api.API;
031import org.tquadrat.foundation.annotation.ClassVersion;
032
033/**
034 *  An implementation of
035 *  {@link Spliterator}
036 *  for instances of
037 *  {@link ResultSet}.
038 *
039 *  @extauthor Thomas Thrien - thomas.thrien@tquadrat.org
040 *  @version $Id: ResultSetSpliterator.java 1030 2022-04-06 13:42:02Z tquadrat $
041 *  @since 0.0.1
042 *
043 *  @UMLGraph.link
044 */
045@ClassVersion( sourceVersion = "$Id: ResultSetSpliterator.java 1030 2022-04-06 13:42:02Z tquadrat $" )
046@API( status = INTERNAL, since = "0.0.1" )
047public final class ResultSetSpliterator implements Spliterator<ResultSet>
048{
049        /*---------------*\
050    ====** Inner Classes **====================================================
051        \*---------------*/
052    /**
053     *  The wrapper for the result set that disallows several methods to be
054     *  called.
055     *
056     *  @extauthor Thomas Thrien - thomas.thrien@tquadrat.org
057     *  @version $Id: ResultSetSpliterator.java 1030 2022-04-06 13:42:02Z tquadrat $
058     *  @since 0.0.1
059     *
060     *  @UMLGraph.link
061     */
062    @ClassVersion( sourceVersion = "$Id: ResultSetSpliterator.java 1030 2022-04-06 13:42:02Z tquadrat $" )
063    @API( status = INTERNAL, since = "0.0.1" )
064    private class InternalResultSet extends ResultSetWrapper
065    {
066            /*--------------*\
067        ====** Constructors **=================================================
068            \*--------------*/
069        /**
070         *  Creates a new {@code InternalResultSet} instance.
071         */
072        public InternalResultSet() { super( m_ResultSet ); }
073    }
074    //  class InternalResultSet
075
076        /*------------*\
077    ====** Attributes **=======================================================
078        \*------------*/
079    /**
080     *  The last exception that was caught on a call to
081     *  {@link ResultSet#next()}.
082     */
083    private SQLException m_LastError = null;
084
085    /**
086     *  The result set.
087     */
088    private final ResultSet m_ResultSet;
089
090    /**
091     *  The wrapped result set.
092     */
093    @SuppressWarnings( "UseOfConcreteClass" )
094    private final InternalResultSet m_WrappedResultSet;
095
096        /*--------------*\
097    ====** Constructors **=====================================================
098        \*--------------*/
099    /**
100     *  Creates a new {@code ResultSetSpliterator} instance.
101     *
102     *  @param  resultSet   The result set.
103     */
104    public ResultSetSpliterator( final ResultSet resultSet )
105    {
106        m_ResultSet = requireNonNullArgument( resultSet, "resultSet" );
107        m_WrappedResultSet = new InternalResultSet();
108    }   //  ResultSetSpliterator()
109
110        /*---------*\
111    ====** Methods **==========================================================
112        \*---------*/
113    /**
114     *  {@inheritDoc}
115     */
116    @SuppressWarnings( "ConstantExpression" )
117    @Override
118    public final int characteristics() { return IMMUTABLE | NONNULL; }
119
120    /**
121     *  {@inheritDoc}
122     */
123    @Override
124    public final long estimateSize() { return Long.MAX_VALUE; }
125
126    /**
127     *  Returns the last error that was caught on a call to
128     *  {@link ResultSet#next()}.
129     *
130     *  @return An instance of
131     *      {@link Optional}
132     *      that holds the exception; will be
133     *      {@linkplain Optional#empty() empty}
134     *      if there had not been an error so far.
135     */
136    public final Optional<SQLException> getLastError() { return Optional.ofNullable( m_LastError ); }
137
138    /**
139     *  {@inheritDoc}
140     */
141    @Override
142    public final boolean tryAdvance( final Consumer<? super ResultSet> action )
143    {
144        boolean retValue;
145        try
146        {
147            retValue = m_ResultSet.next();
148        }
149        catch( final SQLException e )
150        {
151            m_LastError = e;
152            retValue = false;
153        }
154        if( retValue ) action.accept( m_WrappedResultSet );
155
156        //---* Done *----------------------------------------------------------
157        return retValue;
158    }   //  tryAdvance()
159
160    /**
161     *  {@inheritDoc}
162     */
163    @Override
164    public final Spliterator<ResultSet> trySplit() { return null; }
165}
166//  class ResultSetSpliterator
167
168/*
169 *  End of File
170 */