package org.sfm.benchmark.db.jooq;

import java.util.List;

import org.jooq.DSLContext;
import org.jooq.Record;
import org.jooq.Result;
import org.jooq.impl.DSL;
import org.jooq.impl.DefaultConfiguration;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.infra.Blackhole;
import org.sfm.beans.SmallBenchmarkObject;
import org.sfm.benchmark.db.jmh.ConnectionParam;
import org.sfm.benchmark.db.jmh.DbTarget;
import org.sfm.benchmark.db.jmh.LimitParam;
import org.sfm.jooq.SfmRecordMapperProvider;
import org.sfm.jooq.beans.tables.TestSmallBenchmarkObject;
import org.sfm.jooq.beans.tables.records.TestSmallBenchmarkObjectRecord;

@State(Scope.Benchmark)
public class JooqBenchmark {

	@Param(value = "MOCK")
	private DbTarget db;
	private DSLContext dslNoSfmMapping;
	private DSLContext dslSfmMapping;

	@Setup
	public void init() throws Exception {
		ConnectionParam cp = new ConnectionParam();
		cp.db = db;
		cp.init();
		dslNoSfmMapping = DSL.using(new DefaultConfiguration().set(cp.dataSource).set(
				db.getSqlDialect()));
		
		dslSfmMapping = DSL.
				using(new DefaultConfiguration().set(cp.dataSource)
						.set(db.getSqlDialect())
						.set(new SfmRecordMapperProvider()));
	}

	
	@Benchmark
	public void testFetchRecord(LimitParam limit, final Blackhole blackhole, ConnectionParam connectionParam) throws Exception {
        Result<Record> result = dslNoSfmMapping.select().from(TestSmallBenchmarkObject.TEST_SMALL_BENCHMARK_OBJECT).limit(limit.limit).fetch();
        for(Record o : result) {
        	TestSmallBenchmarkObjectRecord sbo = (TestSmallBenchmarkObjectRecord) o;
        	blackhole.consume(sbo);
        }
	}
	
	@Benchmark
	public void testSqlWithJooqMapper(LimitParam limit, final Blackhole blackhole, ConnectionParam connectionParam) throws Exception {
        List<SmallBenchmarkObject> result = dslNoSfmMapping.select().from("test_small_benchmark_object").limit(limit.limit).fetch().into(SmallBenchmarkObject.class);
        for(SmallBenchmarkObject o : result) {
        	blackhole.consume(o);
        }
	}
	
	@Benchmark
	public void testSqlSmfMapper(LimitParam limit, final Blackhole blackhole, ConnectionParam connectionParam) throws Exception {
        List<SmallBenchmarkObject> result = dslSfmMapping.select().from("test_small_benchmark_object").limit(limit.limit).fetch().into(SmallBenchmarkObject.class);
        for(SmallBenchmarkObject o : result) {
        	blackhole.consume(o);
        }
	}

}

@@ -626,24 +626,95 @@
 LimitParam;%0A
+import org.sfm.jdbc.JdbcMapper;%0Aimport org.sfm.jdbc.JdbcMapperFactory;%0A
 import org.s
@@ -742,24 +742,24 @@
 erProvider;%0A
-
 import org.s
@@ -877,16 +877,49 @@
 tRecord;
+%0Aimport org.sfm.utils.RowHandler;
 %0A%0A@State
@@ -1085,16 +1085,139 @@
 pping;%0A%0A
+%09private JdbcMapper%3CSmallBenchmarkObject%3E mapper = JdbcMapperFactory.newInstance().newMapper(SmallBenchmarkObject.class);%0A%0A
 %09@Setup%0A
@@ -2483,10 +2483,20 @@
 SqlS
-m
 f
+mAsProvider
 Mapp
@@ -2850,11 +2850,485 @@
    %7D%0A%09%7D%0A
+%09@Benchmark%0A%09public void testSqlSfmMapperOnResultSet(LimitParam limit, final Blackhole blackhole, ConnectionParam connectionParam) throws Exception %7B%0A%09%09mapper.forEach(dslSfmMapping.select().from(%22test_small_benchmark_object%22).limit(limit.limit).fetchResultSet(),%0A%0A%09%09%09%09new RowHandler%3CSmallBenchmarkObject%3E() %7B%0A%09%09%09%09%09@Override%0A%09%09%09%09%09public void handle(SmallBenchmarkObject smallBenchmarkObject) throws Exception %7B%0A%09%09%09%09%09%09blackhole.consume(smallBenchmarkObject);%0A%09%09%09%09%09%7D%0A%09%09%09%09%7D);%0A%09%7D
 %0A%7D%0A

add jooq fetch result set bench