Skip to content

Lazy iteration over JDBC ResultSet #1487

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

eric-maynard
Copy link
Contributor

@eric-maynard eric-maynard commented Apr 28, 2025

In DatasourceOperations.executeSelect, we currently return a List after copying the entire ResultSet into a List. We provide a few arguments so the caller can supply a limit, a transformer, and a filter.

Instead, we can let the caller provide a Consumer over an Iterator / Stream of the data, keeping the logic in DatasourceOperations strictly persistence-related and affording the caller greater flexibility.

This will help in #273 so we can push the page token down into the query but still do client filtering without having to make a copy of the entire ResultSet.

Copy link
Collaborator

@singhpk234 singhpk234 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much for this improvement @eric-maynard !

.map(ModelEntity::toEntity)
.filter(entityFilter)
.limit(limit)
.forEach(results::add);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a way to do toList() ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the loan pattern, we aren't returning anything so we need to get the list as a side effect. Unfortunately, there is a restriction in Java that variables pulled in to the scope of a lambda must be "effectively final", so we can't do like results = ...toList() in the lambda

Comment on lines 47 to 48
hasNext = false;
throw new RuntimeException(e);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interesting, if it's a SQLException shouldn't we throw it as SQLException to inspect the error code ? any other exception other than SQLException is considered as RTE for now in the caller.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the real problem here is ResultSetIterator.next(), which can't throw an exception so long as we're implementing Iterator.

For now I'll have the constructor throw a SQLException so we have a chance of finding a SQLException, but we'd still wrap SQLExceptions that happen after the first ResultSet.next() call. If that's an issue, we can move away from implementing Iterator or fix the caller to unwrap the exception.

Copy link
Collaborator

@singhpk234 singhpk234 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants