Skip to content

Commit 7593bf4

Browse files
authored
Add the openStream method to the Criteria API to return a Stream (#1111)
1 parent 60eab15 commit 7593bf4

File tree

14 files changed

+221
-16
lines changed

14 files changed

+221
-16
lines changed

doma-core/src/main/java/org/seasar/doma/jdbc/criteria/statement/NativeSqlSelectIntermediate.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,24 +33,31 @@ public SetOperationContext<ELEMENT> getContext() {
3333
return new SetOperationContext.Select<>(declaration.getContext());
3434
}
3535

36+
@Override
37+
public Stream<ELEMENT> openStream() {
38+
NativeSqlSelectTerminal<Stream<ELEMENT>> terminal =
39+
createNativeSqlSelectTerminal(Function.identity(), true);
40+
return terminal.execute();
41+
}
42+
3643
@Override
3744
public <RESULT> RESULT mapStream(Function<Stream<ELEMENT>, RESULT> streamMapper) {
3845
Objects.requireNonNull(streamMapper);
39-
NativeSqlSelectTerminal<RESULT> terminal = createNativeSqlSelectTerminal(streamMapper);
46+
NativeSqlSelectTerminal<RESULT> terminal = createNativeSqlSelectTerminal(streamMapper, false);
4047
return terminal.execute();
4148
}
4249

4350
@Override
4451
protected Command<List<ELEMENT>> createCommand() {
4552
NativeSqlSelectTerminal<List<ELEMENT>> terminal =
46-
createNativeSqlSelectTerminal(stream -> stream.collect(toList()));
53+
createNativeSqlSelectTerminal(stream -> stream.collect(toList()), false);
4754
return terminal.createCommand();
4855
}
4956

5057
private <RESULT> NativeSqlSelectTerminal<RESULT> createNativeSqlSelectTerminal(
51-
Function<Stream<ELEMENT>, RESULT> streamMapper) {
58+
Function<Stream<ELEMENT>, RESULT> streamMapper, boolean returnsStream) {
5259
ResultSetHandler<RESULT> handler =
5360
new MappedResultStreamHandler<>(streamMapper, objectProviderFactory);
54-
return new NativeSqlSelectTerminal<>(config, declaration, handler);
61+
return new NativeSqlSelectTerminal<>(config, declaration, handler, returnsStream);
5562
}
5663
}

doma-core/src/main/java/org/seasar/doma/jdbc/criteria/statement/NativeSqlSelectStarting.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,13 @@ public SetOperationContext<ENTITY> getContext() {
838838
return intermediate.getContext();
839839
}
840840

841+
@Override
842+
public Stream<ENTITY> openStream() {
843+
NativeSqlSelectIntermediate<ENTITY> intermediate =
844+
new NativeSqlSelectIntermediate<>(config, declaration, createEntityProviderFactory());
845+
return intermediate.openStream();
846+
}
847+
841848
@Override
842849
public <RESULT> RESULT mapStream(Function<Stream<ENTITY>, RESULT> streamMapper) {
843850
NativeSqlSelectIntermediate<ENTITY> intermediate =

doma-core/src/main/java/org/seasar/doma/jdbc/criteria/statement/NativeSqlSelectTerminal.java

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.seasar.doma.jdbc.criteria.statement;
22

33
import java.util.Objects;
4+
import org.seasar.doma.FetchType;
45
import org.seasar.doma.jdbc.Config;
56
import org.seasar.doma.jdbc.PreparedSql;
67
import org.seasar.doma.jdbc.command.Command;
@@ -18,11 +19,22 @@ public class NativeSqlSelectTerminal<RESULT>
1819
private final SelectFromDeclaration declaration;
1920
private final ResultSetHandler<RESULT> resultSetHandler;
2021

22+
private final Boolean returnsStream;
23+
2124
public NativeSqlSelectTerminal(
2225
Config config, SelectFromDeclaration declaration, ResultSetHandler<RESULT> resultSetHandler) {
26+
this(config, declaration, resultSetHandler, false);
27+
}
28+
29+
public NativeSqlSelectTerminal(
30+
Config config,
31+
SelectFromDeclaration declaration,
32+
ResultSetHandler<RESULT> resultSetHandler,
33+
boolean returnsStream) {
2334
super(Objects.requireNonNull(config));
2435
this.declaration = Objects.requireNonNull(declaration);
2536
this.resultSetHandler = Objects.requireNonNull(resultSetHandler);
37+
this.returnsStream = returnsStream;
2638
}
2739

2840
/**
@@ -46,10 +58,7 @@ protected Command<RESULT> createCommand() {
4658
new SelectBuilder(
4759
config, context, createCommenter(settings.getComment()), settings.getSqlLogType());
4860
PreparedSql sql = builder.build();
49-
CriteriaQuery query = new CriteriaQuery(config, sql, getClass().getName(), EXECUTE_METHOD_NAME);
50-
query.setFetchSize(settings.getFetchSize());
51-
query.setMaxRows(settings.getMaxRows());
52-
query.setQueryTimeout(settings.getQueryTimeout());
61+
CriteriaQuery query = createCriteriaQuery(sql, settings);
5362
return new SelectCommand<RESULT>(query, resultSetHandler) {
5463
@Override
5564
public RESULT execute() {
@@ -62,4 +71,24 @@ public RESULT execute() {
6271
}
6372
};
6473
}
74+
75+
private CriteriaQuery createCriteriaQuery(PreparedSql sql, SelectSettings settings) {
76+
CriteriaQuery query =
77+
new CriteriaQuery(config, sql, getClass().getName(), EXECUTE_METHOD_NAME) {
78+
79+
@Override
80+
public boolean isResultStream() {
81+
return returnsStream;
82+
}
83+
84+
@Override
85+
public FetchType getFetchType() {
86+
return returnsStream ? FetchType.LAZY : FetchType.EAGER;
87+
}
88+
};
89+
query.setFetchSize(settings.getFetchSize());
90+
query.setMaxRows(settings.getMaxRows());
91+
query.setQueryTimeout(settings.getQueryTimeout());
92+
return query;
93+
}
6594
}

doma-core/src/main/java/org/seasar/doma/jdbc/criteria/statement/NativeSqlSetStarting.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,24 +43,31 @@ public SetOperationContext<ELEMENT> getContext() {
4343
return context;
4444
}
4545

46+
@Override
47+
public Stream<ELEMENT> openStream() {
48+
NativeSqlSetTerminal<Stream<ELEMENT>> terminal =
49+
createNativeSqlSetTerminal(Function.identity(), true);
50+
return terminal.execute();
51+
}
52+
4653
@Override
4754
public <RESULT> RESULT mapStream(Function<Stream<ELEMENT>, RESULT> streamMapper) {
4855
Objects.requireNonNull(streamMapper);
49-
NativeSqlSetTerminal<RESULT> terminal = createNativeSqlSetTerminal(streamMapper);
56+
NativeSqlSetTerminal<RESULT> terminal = createNativeSqlSetTerminal(streamMapper, false);
5057
return terminal.execute();
5158
}
5259

5360
@Override
5461
protected Command<List<ELEMENT>> createCommand() {
5562
NativeSqlSetTerminal<List<ELEMENT>> terminal =
56-
createNativeSqlSetTerminal(stream -> stream.collect(toList()));
63+
createNativeSqlSetTerminal(stream -> stream.collect(toList()), false);
5764
return terminal.createCommand();
5865
}
5966

6067
private <RESULT> NativeSqlSetTerminal<RESULT> createNativeSqlSetTerminal(
61-
Function<Stream<ELEMENT>, RESULT> streamMapper) {
68+
Function<Stream<ELEMENT>, RESULT> streamMapper, boolean returnsStream) {
6269
ResultSetHandler<RESULT> handler =
6370
new MappedResultStreamHandler<>(streamMapper, objectProviderFactory);
64-
return new NativeSqlSetTerminal<>(config, context, handler);
71+
return new NativeSqlSetTerminal<>(config, context, handler, returnsStream);
6572
}
6673
}

doma-core/src/main/java/org/seasar/doma/jdbc/criteria/statement/NativeSqlSetTerminal.java

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.seasar.doma.jdbc.criteria.statement;
22

33
import java.util.Objects;
4+
import org.seasar.doma.FetchType;
45
import org.seasar.doma.jdbc.Config;
56
import org.seasar.doma.jdbc.PreparedSql;
67
import org.seasar.doma.jdbc.command.Command;
@@ -17,11 +18,22 @@ public class NativeSqlSetTerminal<RESULT>
1718
private final SetOperationContext<?> context;
1819
private final ResultSetHandler<RESULT> resultSetHandler;
1920

21+
private final boolean returnsStream;
22+
2023
public NativeSqlSetTerminal(
2124
Config config, SetOperationContext<?> context, ResultSetHandler<RESULT> resultSetHandler) {
25+
this(config, context, resultSetHandler, false);
26+
}
27+
28+
public NativeSqlSetTerminal(
29+
Config config,
30+
SetOperationContext<?> context,
31+
ResultSetHandler<RESULT> resultSetHandler,
32+
boolean returnsStream) {
2233
super(Objects.requireNonNull(config));
2334
this.context = Objects.requireNonNull(context);
2435
this.resultSetHandler = Objects.requireNonNull(resultSetHandler);
36+
this.returnsStream = returnsStream;
2537
}
2638

2739
/**
@@ -42,11 +54,28 @@ protected Command<RESULT> createCommand() {
4254
new SetOperationBuilder(
4355
config, context, createCommenter(settings.getComment()), settings.getSqlLogType());
4456
PreparedSql sql = builder.build();
45-
CriteriaQuery query = new CriteriaQuery(config, sql, getClass().getName(), EXECUTE_METHOD_NAME);
57+
CriteriaQuery query = createCriteriaQuery(sql, settings);
58+
return new SelectCommand<>(query, resultSetHandler);
59+
}
60+
61+
private CriteriaQuery createCriteriaQuery(PreparedSql sql, SelectSettings settings) {
62+
CriteriaQuery query =
63+
new CriteriaQuery(config, sql, getClass().getName(), EXECUTE_METHOD_NAME) {
64+
65+
@Override
66+
public boolean isResultStream() {
67+
return returnsStream;
68+
}
69+
70+
@Override
71+
public FetchType getFetchType() {
72+
return returnsStream ? FetchType.LAZY : FetchType.EAGER;
73+
}
74+
};
4675
query.setFetchSize(settings.getFetchSize());
4776
query.setMaxRows(settings.getMaxRows());
4877
query.setQueryTimeout(settings.getQueryTimeout());
49-
return new SelectCommand<>(query, resultSetHandler);
78+
return query;
5079
}
5180

5281
private SelectSettings findSettings() {

doma-core/src/main/java/org/seasar/doma/jdbc/criteria/statement/StreamMappable.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@
1414
*/
1515
public interface StreamMappable<ELEMENT> extends Listable<ELEMENT> {
1616

17+
/**
18+
* Open a stream.
19+
*
20+
* <p>You must close the stream after using it.
21+
*
22+
* @return the opened stream
23+
*/
24+
Stream<ELEMENT> openStream();
25+
1726
/**
1827
* Map a stream.
1928
*

doma-core/src/test/java/org/seasar/doma/jdbc/criteria/NativeSqlSelectTest.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package org.seasar.doma.jdbc.criteria;
22

33
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertFalse;
45
import static org.junit.jupiter.api.Assertions.assertThrows;
6+
import static org.junit.jupiter.api.Assertions.assertTrue;
57
import static org.seasar.doma.jdbc.criteria.expression.Expressions.alias;
68
import static org.seasar.doma.jdbc.criteria.expression.Expressions.avg;
79
import static org.seasar.doma.jdbc.criteria.expression.Expressions.avgAsDouble;
@@ -24,6 +26,7 @@
2426
import java.math.BigDecimal;
2527
import java.util.Arrays;
2628
import java.util.List;
29+
import java.util.stream.Stream;
2730
import org.junit.jupiter.api.Test;
2831
import org.seasar.doma.DomaException;
2932
import org.seasar.doma.internal.jdbc.mock.MockConfig;
@@ -57,7 +60,9 @@
5760

5861
class NativeSqlSelectTest {
5962

60-
private final NativeSql nativeSql = new NativeSql(new MockConfig());
63+
private final MockConfig config = new MockConfig();
64+
65+
private final NativeSql nativeSql = new NativeSql(config);
6166

6267
@Test
6368
void from() {
@@ -1607,4 +1612,24 @@ private static UserDefinedExpression<Long> countDistinctMultiple(
16071612
c.appendSql("))");
16081613
});
16091614
}
1615+
1616+
@Test
1617+
void openStream() {
1618+
Emp_ e = new Emp_();
1619+
1620+
Stream<Emp> stream = nativeSql.from(e).openStream();
1621+
assertFalse(config.dataSource.connection.closed);
1622+
stream.close();
1623+
assertTrue(config.dataSource.connection.closed);
1624+
}
1625+
1626+
@Test
1627+
void openStream_union() {
1628+
Emp_ e = new Emp_();
1629+
1630+
Stream<Emp> stream = nativeSql.from(e).union(nativeSql.from(e)).openStream();
1631+
assertFalse(config.dataSource.connection.closed);
1632+
stream.close();
1633+
assertTrue(config.dataSource.connection.closed);
1634+
}
16101635
}

doma-kotlin/src/main/kotlin/org/seasar/doma/kotlin/jdbc/criteria/statement/KNativeSqlSelectIntermediate.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,18 @@ package org.seasar.doma.kotlin.jdbc.criteria.statement
33
import org.seasar.doma.jdbc.Sql
44
import org.seasar.doma.jdbc.criteria.context.SetOperationContext
55
import org.seasar.doma.jdbc.criteria.statement.SetOperand
6+
import java.util.stream.Stream
67
import kotlin.streams.asSequence
78

89
class KNativeSqlSelectIntermediate<ELEMENT>(private val statement: SetOperand<ELEMENT>) : KStatement<List<ELEMENT>>, KSetOperand<ELEMENT> {
910

1011
override val context: SetOperationContext<ELEMENT>
1112
get() = statement.context
1213

14+
override fun openStream(): Stream<ELEMENT> {
15+
return statement.openStream()
16+
}
17+
1318
override fun <RESULT> mapSequence(sequenceMapper: (Sequence<ELEMENT>) -> RESULT): RESULT {
1419
return statement.mapStream {
1520
sequenceMapper(it.asSequence())

doma-kotlin/src/main/kotlin/org/seasar/doma/kotlin/jdbc/criteria/statement/KNativeSqlSelectStarting.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import org.seasar.doma.kotlin.jdbc.criteria.declaration.KJoinDeclaration
2626
import org.seasar.doma.kotlin.jdbc.criteria.declaration.KOrderByNameDeclaration
2727
import org.seasar.doma.kotlin.jdbc.criteria.declaration.KWhereDeclaration
2828
import java.util.function.Function
29+
import java.util.stream.Stream
2930
import kotlin.streams.asSequence
3031

3132
class KNativeSqlSelectStarting<ENTITY>(private val statement: NativeSqlSelectStarting<ENTITY>) :
@@ -401,6 +402,10 @@ class KNativeSqlSelectStarting<ENTITY>(private val statement: NativeSqlSelectSta
401402
return statement.execute()
402403
}
403404

405+
override fun openStream(): Stream<ENTITY> {
406+
return statement.openStream()
407+
}
408+
404409
override fun <RESULT> mapSequence(sequenceMapper: (Sequence<ENTITY>) -> RESULT): RESULT {
405410
return statement.mapStream {
406411
sequenceMapper(it.asSequence())

doma-kotlin/src/main/kotlin/org/seasar/doma/kotlin/jdbc/criteria/statement/KNativeSqlSetStarting.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import org.seasar.doma.jdbc.criteria.context.SetOperationContext
55
import org.seasar.doma.jdbc.criteria.statement.SetOperand
66
import org.seasar.doma.jdbc.criteria.statement.SetOperator
77
import org.seasar.doma.kotlin.jdbc.criteria.declaration.KOrderByIndexDeclaration
8+
import java.util.stream.Stream
89
import kotlin.streams.asSequence
910

1011
class KNativeSqlSetStarting<ELEMENT>(val statement: SetOperator<ELEMENT>) : KSetOperator<ELEMENT> {
@@ -27,6 +28,17 @@ class KNativeSqlSetStarting<ELEMENT>(val statement: SetOperator<ELEMENT>) : KSet
2728
return statement.asSql()
2829
}
2930

31+
/**
32+
* Open a stream.
33+
*
34+
* You must close the stream after using it.
35+
*
36+
* @return the opened stream
37+
*/
38+
override fun openStream(): Stream<ELEMENT> {
39+
return statement.openStream()
40+
}
41+
3042
override fun <RESULT> mapSequence(sequenceMapper: (Sequence<ELEMENT>) -> RESULT): RESULT {
3143
return statement.mapStream {
3244
sequenceMapper(it.asSequence())

0 commit comments

Comments
 (0)