-
Notifications
You must be signed in to change notification settings - Fork 160
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
[RFC] Iterator interface #103
Conversation
I think its a great idea to have that. And that it can be "bolted-on" so easily i great,too. But it makes me wonder if its to far from the core concept the lib has till now, explicitly that we try to have everything as stream-ops. Something like db_itr<int,string,int> itr;
db << "SQL" >> itr; looks more like us i guess. |
@Killili The current library (seems to be) inspired by the Additionally providing iterators without row_view<int, string, int> rows;
db << "SQL" >> rows;
// Use rows.begin() now I think this would be confusing, because we already support Additionally I expect the statement to be reusable after I used |
Maybe we have a misunderstanding here, but youre example is exactly what i meant. And we use the op>> to indicate that we want a result now. We would just store that result in an iterator instead of "using" it then and there. row_set<int,string,int> set;
db << "SQL" >> set;
for( auto res : set ){
if( something ) break;
} I just realized that looks like the stuff i had back in the VisualBasic ODBC days ... |
But with iterators, we don't get a result now. We get a result when we use the iterator. If we store the result in any other way, it becomes independent from the (prepared) statement, but for iterators, the statement can't be reset yet. This can be surprising and lead to bugs. But it I probably isn't be that much of a problem, because you normally don't try to execute the same statement again while still processing the results of the last run. My bigger problem is, that row_set<int> set;
db << "SQL" >> set;
for( auto res : set ){
if( something ) break;
} would be valid, reasonable code. So is vector<int> set;
db << "SQL" >> set;
for( auto res : set ){
if( something ) break;
} They look very similar, but have completely different semantics. |
I see youre point, but i dont think thats a problem in the mind of a programmer that is used to a strongly typed language. In other languages it might be a disaster ;) |
So the other problem would be something like this auto stmt = db << "SQL";
row_set<int,int> set_itr;
stmt >> set_itr;
auto res = set_itr++;
/* some more lines of code... */
row_set<int,int> new_set_itr;
stmt >> new_set_itr; // get new result set
res = set_itr++; // reuse first itr i guess invalidating the itr if the statment gets reused would be the sane thing to do and would be in line with the normal itr handling. Namely invalidating itr on change of the underlying object. |
It's not a disaster for C++ programmers, but I still think it confusing because we map two related, but distinct functionalities to the same syntax. There is an additional problem on the implementation side. The |
We have a lot of different functionality in the op>> The ones i know of:
so i guess having one more does not hurt. |
Replaced by #126. |
I think we need a iterator based method to retrieve the results.
The problem is, that we need to declare the types and number of columns explicitly somewhere, which makes the syntax ugly. So I'm not sure if this is the right way forward.
This is what it looks like (with C++17 structured bindings):
Alternatively it can be implemented by free functions: