[#4339] Add DSLContext.fetchStream(...) similar to the existing

DSLContext.fetchLazy(...) API
This commit is contained in:
lukaseder 2015-06-01 10:26:44 +02:00
parent d660727821
commit f17a3c48c7
3 changed files with 290 additions and 14 deletions

View File

@ -70,6 +70,7 @@ import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Stream;
import javax.annotation.Generated;
@ -619,13 +620,126 @@ public interface DSLContext extends Scope {
* parts can be injected
* @param parts The {@link QueryPart} objects that are rendered at the
* {numbered placeholder} locations
* @return The results from the executed query
* @return The results from the executed query. This is never
* <code>null</code>, even if the database returns no
* {@link ResultSet}
* @throws DataAccessException if something went wrong executing the query
*/
@Support
@PlainSQL
Cursor<Record> fetchLazy(String sql, QueryPart... parts) throws DataAccessException;
/* [java-8] */
/**
* Execute a new query holding plain SQL and "lazily" return the generated
* result.
* <p>
* The returned {@link Stream} holds a reference to the executed
* {@link PreparedStatement} and the associated {@link ResultSet}. Data can
* be fetched (or iterated over) lazily, fetching records from the
* {@link ResultSet} one by one.
* <p>
* Example (Postgres):
* <p>
* <code><pre>
* String sql = "FETCH ALL IN \"<unnamed cursor 1>\"";</pre></code> Example
* (SQLite):
* <p>
* <code><pre>
* String sql = "pragma table_info('my_table')";</pre></code>
* <p>
* <b>NOTE</b>: When inserting plain SQL into jOOQ objects, you must
* guarantee syntax integrity. You may also create the possibility of
* malicious SQL injection. Be sure to properly use bind variables and/or
* escape literals when concatenated into SQL clauses!
*
* @param sql The SQL
* @return The results from the executed query. This is never
* <code>null</code>, even if the database returns no
* {@link ResultSet}
* @throws DataAccessException if something went wrong executing the query
*/
@Support
@PlainSQL
Stream<Record> fetchStream(String sql) throws DataAccessException;
/**
* Execute a new query holding plain SQL and "lazily" return the generated
* result.
* <p>
* There must be as many bind variables contained in the SQL, as passed in
* the bindings parameter
* <p>
* The returned {@link Stream} holds a reference to the executed
* {@link PreparedStatement} and the associated {@link ResultSet}. Data can
* be fetched (or iterated over) lazily, fetching records from the
* {@link ResultSet} one by one.
* <p>
* Example (Postgres):
* <p>
* <code><pre>
* String sql = "FETCH ALL IN \"<unnamed cursor 1>\"";</pre></code> Example
* (SQLite):
* <p>
* <code><pre>
* String sql = "pragma table_info('my_table')";</pre></code>
* <p>
* <b>NOTE</b>: When inserting plain SQL into jOOQ objects, you must
* guarantee syntax integrity. You may also create the possibility of
* malicious SQL injection. Be sure to properly use bind variables and/or
* escape literals when concatenated into SQL clauses!
*
* @param sql The SQL
* @param bindings The bindings
* @return The results from the executed query. This is never
* <code>null</code>, even if the database returns no
* {@link ResultSet}
* @throws DataAccessException if something went wrong executing the query
*/
@Support
@PlainSQL
Stream<Record> fetchStream(String sql, Object... bindings) throws DataAccessException;
/**
* Execute a new query holding plain SQL and "lazily" return the generated
* result.
* <p>
* The returned {@link Stream} holds a reference to the executed
* {@link PreparedStatement} and the associated {@link ResultSet}. Data can
* be fetched (or iterated over) lazily, fetching records from the
* {@link ResultSet} one by one.
* <p>
* Unlike {@link #stream(String, Object...)}, the SQL passed to this
* method should not contain any bind variables. Instead, you can pass
* {@link QueryPart} objects to the method which will be rendered at indexed
* locations of your SQL string as such: <code><pre>
* // The following query
* fetchLazy("select {0}, {1} from {2}", val(1), inline("test"), name("DUAL"));
*
* // Will execute this SQL on an Oracle database with RenderNameStyle.QUOTED:
* select ?, 'test' from "DUAL"
* </pre></code>
* <p>
* <b>NOTE</b>: When inserting plain SQL into jOOQ objects, you must
* guarantee syntax integrity. You may also create the possibility of
* malicious SQL injection. Be sure to properly use bind variables and/or
* escape literals when concatenated into SQL clauses! One way to escape
* literals is to use {@link DSL#name(String...)} and similar methods
*
* @param sql The SQL clause, containing {numbered placeholders} where query
* parts can be injected
* @param parts The {@link QueryPart} objects that are rendered at the
* {numbered placeholder} locations
* @return The results from the executed query. This is never
* <code>null</code>, even if the database returns no
* {@link ResultSet}
* @throws DataAccessException if something went wrong executing the query
*/
@Support
@PlainSQL
Stream<Record> fetchStream(String sql, QueryPart... parts) throws DataAccessException;
/* [/java-8] */
/**
* Execute a new query holding plain SQL, possibly returning several result
* sets.
@ -1872,6 +1986,72 @@ public interface DSLContext extends Scope {
@Support
Cursor<Record> fetchLazy(ResultSet rs, Class<?>... types) throws DataAccessException;
/* [java-8] */
/**
* Wrap a JDBC {@link ResultSet} into a jOOQ {@link Stream}.
* <p>
* Use {@link #fetch(ResultSet)}, to load the entire <code>ResultSet</code>
* into a jOOQ <code>Result</code> at once.
*
* @param rs The JDBC ResultSet to fetch data from
* @return The resulting stream
* @throws DataAccessException if something went wrong executing the query
*/
@Support
Stream<Record> fetchStream(ResultSet rs) throws DataAccessException;
/**
* Wrap a JDBC {@link ResultSet} into a jOOQ {@link Stream}.
* <p>
* Use {@link #fetch(ResultSet)}, to load the entire <code>ResultSet</code>
* into a jOOQ <code>Result</code> at once.
* <p>
* The additional <code>fields</code> argument is used by jOOQ to coerce
* field names and data types to the desired output
*
* @param rs The JDBC ResultSet to fetch data from
* @param fields The fields to use in the desired output
* @return The resulting stream
* @throws DataAccessException if something went wrong executing the query
*/
@Support
Stream<Record> fetchStream(ResultSet rs, Field<?>... fields) throws DataAccessException;
/**
* Wrap a JDBC {@link ResultSet} into a jOOQ {@link Stream}.
* <p>
* Use {@link #fetch(ResultSet)}, to load the entire <code>ResultSet</code>
* into a jOOQ <code>Result</code> at once.
* <p>
* The additional <code>types</code> argument is used by jOOQ to coerce data
* types to the desired output
*
* @param rs The JDBC ResultSet to fetch data from
* @param types The data types to use in the desired output
* @return The resulting stream
* @throws DataAccessException if something went wrong executing the query
*/
@Support
Stream<Record> fetchStream(ResultSet rs, DataType<?>... types) throws DataAccessException;
/**
* Wrap a JDBC {@link ResultSet} into a jOOQ {@link Stream}.
* <p>
* Use {@link #fetch(ResultSet)}, to load the entire <code>ResultSet</code>
* into a jOOQ <code>Result</code> at once.
* <p>
* The additional <code>types</code> argument is used by jOOQ to coerce data
* types to the desired output
*
* @param rs The JDBC ResultSet to fetch data from
* @param types The data types to use in the desired output
* @return The resulting stream
* @throws DataAccessException if something went wrong executing the query
*/
@Support
Stream<Record> fetchStream(ResultSet rs, Class<?>... types) throws DataAccessException;
/* [/java-8] */
/**
* Fetch all data from a formatted string.
* <p>
@ -6425,6 +6605,19 @@ public interface DSLContext extends Scope {
*/
<R extends Record> Cursor<R> fetchLazy(ResultQuery<R> query) throws DataAccessException;
/* [java-8] */
/**
* Execute a {@link ResultQuery} in the context of this <code>DSLContext</code> and return
* a stream.
*
* @param query The query to execute
* @return The stream
* @throws DataAccessException if something went wrong executing the query
* @see ResultQuery#stream()
*/
<R extends Record> Stream<R> fetchStream(ResultQuery<R> query) throws DataAccessException;
/* [/java-8] */
/**
* Execute a {@link ResultQuery} in the context of this <code>DSLContext</code> and return
* a cursor.
@ -6755,6 +6948,34 @@ public interface DSLContext extends Scope {
@Support
<R extends Record> Cursor<R> fetchLazy(Table<R> table, Condition condition) throws DataAccessException;
/* [java-8] */
/**
* Execute and return all records lazily for
* <code><pre>SELECT * FROM [table]</pre></code>.
* <p>
* The result and its contained records are attached to this
* {@link Configuration} by default. Use {@link Settings#isAttachRecords()}
* to override this behaviour.
*
* @throws DataAccessException if something went wrong executing the query
*/
@Support
<R extends Record> Stream<R> fetchStream(Table<R> table) throws DataAccessException;
/**
* Execute and return all records lazily for
* <code><pre>SELECT * FROM [table] WHERE [condition] </pre></code>.
* <p>
* The result and its contained records are attached to this
* {@link Configuration} by default. Use {@link Settings#isAttachRecords()}
* to override this behaviour.
*
* @throws DataAccessException if something went wrong executing the query
*/
@Support
<R extends Record> Stream<R> fetchStream(Table<R> table, Condition condition) throws DataAccessException;
/* [/java-8] */
/**
* Insert one record.
* <p>

View File

@ -60,13 +60,10 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import org.jooq.Configuration;
import org.jooq.Converter;
@ -317,16 +314,7 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
/* [java-8] */
@Override
public final Stream<R> stream() throws DataAccessException {
Cursor<R> c = fetchLazy();
return StreamSupport.stream(
Spliterators.spliterator(
c.iterator(),
0,
Spliterator.ORDERED | Spliterator.NONNULL
),
false
).onClose(() -> c.close());
return fetchLazy().stream();
}
/* [/java-8] */

View File

@ -70,6 +70,7 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.stream.Stream;
import javax.annotation.Generated;
import javax.sql.DataSource;
@ -522,6 +523,23 @@ public class DefaultDSLContext extends AbstractScope implements DSLContext, Seri
return resultQuery(sql, parts).fetchLazy();
}
/* [java-8] */
@Override
public Stream<Record> fetchStream(String sql) {
return resultQuery(sql).stream();
}
@Override
public Stream<Record> fetchStream(String sql, Object... bindings) {
return resultQuery(sql, bindings).stream();
}
@Override
public Stream<Record> fetchStream(String sql, QueryPart... parts) {
return resultQuery(sql, parts).stream();
}
/* [/java-8] */
@Override
public List<Result<Record>> fetchMany(String sql) {
return resultQuery(sql).fetchMany();
@ -816,6 +834,28 @@ public class DefaultDSLContext extends AbstractScope implements DSLContext, Seri
return fetchLazy(rs, Utils.dataTypes(types));
}
/* [java-8] */
@Override
public Stream<Record> fetchStream(ResultSet rs) {
return fetchLazy(rs).stream();
}
@Override
public Stream<Record> fetchStream(ResultSet rs, Field<?>... fields) {
return fetchLazy(rs, fields).stream();
}
@Override
public Stream<Record> fetchStream(ResultSet rs, DataType<?>... types) {
return fetchLazy(rs, types).stream();
}
@Override
public Stream<Record> fetchStream(ResultSet rs, Class<?>... types) {
return fetchLazy(rs, types).stream();
}
/* [/java-8] */
@Override
public Result<Record> fetchFromTXT(String string) {
return fetchFromTXT(string, "{null}");
@ -2376,6 +2416,21 @@ public class DefaultDSLContext extends AbstractScope implements DSLContext, Seri
}
}
/* [java-8] */
@Override
public <R extends Record> Stream<R> fetchStream(ResultQuery<R> query) {
final Configuration previous = Utils.getConfiguration(query);
try {
query.attach(configuration());
return query.stream();
}
finally {
query.attach(previous);
}
}
/* [/java-8] */
@Override
public <R extends Record> List<Result<Record>> fetchMany(ResultQuery<R> query) {
final Configuration previous = Utils.getConfiguration(query);
@ -2548,6 +2603,18 @@ public class DefaultDSLContext extends AbstractScope implements DSLContext, Seri
return selectFrom(table).where(condition).fetchLazy();
}
/* [java-8] */
@Override
public <R extends Record> Stream<R> fetchStream(Table<R> table) {
return fetchStream(table, trueCondition());
}
@Override
public <R extends Record> Stream<R> fetchStream(Table<R> table, Condition condition) {
return selectFrom(table).where(condition).stream();
}
/* [/java-8] */
@Override
public <R extends TableRecord<R>> int executeInsert(R record) {
InsertQuery<R> insert = insertQuery(record.getTable());