package org.sfm.jdbc.impl;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Iterator;
//IFJAVA8_START
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import java.util.Spliterator;
import java.util.Spliterators;
//IFJAVA8_END

import org.sfm.jdbc.JdbcMapper;
import org.sfm.map.MappingException;
import org.sfm.map.RowHandlerErrorHandler;
import org.sfm.map.impl.FieldMapper;
import org.sfm.map.impl.MapperImpl;
import org.sfm.reflect.Instantiator;
import org.sfm.utils.RowHandler;

public final class JdbcMapperImpl<T> extends MapperImpl<ResultSet, T> implements JdbcMapper<T> {

	
	private final RowHandlerErrorHandler errorHandler; 
	
	public JdbcMapperImpl(final FieldMapper<ResultSet, T>[] mappers, final Instantiator<ResultSet, T> instantiator, final RowHandlerErrorHandler errorHandler) {
		super(mappers, instantiator);
		this.errorHandler = errorHandler;
	}

	@Override
	public <H extends RowHandler<T>> H forEach(final ResultSet rs, final H handler)
			throws SQLException, MappingException {
		while(rs.next()) {
			T t = map(rs);
			try {
				handler.handle(t);
			} catch(Throwable error) {
				errorHandler.handlerError(error, t);
			}
		}
		return handler;
	}

	@Override
	public Iterator<T> iterate(ResultSet rs) throws SQLException,
			MappingException {
		return new ResultSetIterator<T>(rs, this);
	}

	//IFJAVA8_START
	@Override
	public Stream<T> stream(ResultSet rs) throws SQLException, MappingException {
		Spliterator<T> spliterator = Spliterators.spliteratorUnknownSize(iterate(rs), Spliterator.DISTINCT | Spliterator.ORDERED);
		return StreamSupport.stream(spliterator, false);
	}
	//IFJAVA8_END
}

@@ -21,16 +21,44 @@
 .impl;%0A%0A
+import java.io.IOException;%0A
 import j
@@ -76,16 +76,16 @@
 ultSet;%0A
-
 import j
@@ -149,16 +149,52 @@
 8_START%0A
+import java.util.function.Consumer;%0A
 import j
@@ -332,16 +332,93 @@
 A8_END%0A%0A
+import org.sfm.csv.parser.CellConsumer;%0Aimport org.sfm.csv.parser.CsvReader;%0A
 import o
@@ -1616,24 +1616,92 @@
 %7B%0A%09%09
-Spliterator%3CT%3E s
+return StreamSupport.stream(new JdbcSpliterator(rs), false);%0A%09%7D%0A%0A%09public class JdbcS
 plit
@@ -1707,17 +1707,26 @@
 terator 
-=
+implements
  Spliter
@@ -1733,145 +1733,1066 @@
 ator
-s.spliteratorUnknownSize(iterate(rs), Spliterator.DISTINCT %7C Spliterator.ORDERED);%0A%09%09return StreamSupport.stream(spliterator, false)
+%3CT%3E %7B%0A%09%09private final ResultSet resultSet;%0A%0A%09%09public JdbcSpliterator(ResultSet resultSet) %7B%0A%09%09%09this.resultSet = resultSet;%0A%09%09%7D%0A%0A%09%09@Override%0A%09%09public boolean tryAdvance(Consumer%3C? super T%3E action) %7B%0A%09%09%09try %7B%0A%09%09%09%09if (resultSet.next()) %7B%0A                    action.accept(map(resultSet));%0A                    return true;%0A                %7D%0A%09%09%09%7D catch (SQLException e) %7B%0A%09%09%09%09throw new RuntimeException(e);%0A%09%09%09%7D%0A%09%09%09return false;%0A%09%09%7D%0A%0A%09%09@Override%0A%09%09public void forEachRemaining(Consumer%3C? super T%3E action) %7B%0A%09%09%09try %7B%0A%09%09%09%09forEach(resultSet, new RowHandler%3CT%3E() %7B%0A                    @Override%0A                    public void handle(T t) throws Exception %7B%0A                        action.accept(t);%0A                    %7D%0A                %7D);%0A%09%09%09%7D catch (SQLException e) %7B%0A%09%09%09%09throw new RuntimeException(e);%0A%09%09%09%7D%0A%09%09%7D%0A%0A%09%09@Override%0A%09%09public Spliterator%3CT%3E trySplit() %7B%0A%09%09%09return null;%0A%09%09%7D%0A%0A%09%09@Override%0A%09%09public long estimateSize() %7B%0A%09%09%09return Long.MAX_VALUE;%0A%09%09%7D%0A%0A%09%09@Override%0A%09%09public int characteristics() %7B%0A%09%09%09return Spliterator.ORDERED %7C Spliterator.NONNULL
 ;%0A
+%09
 %09%7D%0A
+%09%7D%0A%0A
 %09//I

implement own spliterator for jdbc