SqliteModernCpp / sqlite_modern_cpp

The C++14 wrapper around sqlite library
MIT License
904 stars 156 forks source link

Suggestion to improve granularity when parsing #158

Open badiozam opened 6 years ago

badiozam commented 6 years ago

Greetings! I have a small suggestion: in the course of using the library I discovered that I wasn't able to use the get_col_from_db(..) methods for accessing individual columns in a multi-row setting.

I added a step() function which solved the issue for me. I'm new to this library so I'm not sure if there's another way to achieve the same thing but I figured I'd shared the snippet I wrote:

    bool step() {
        if (!used()) {
            _start_execute();
        }

        int hresult = sqlite3_step(_stmt.get());

        if ( hresult == SQLITE_ROW )    {
            return true;
        }
        else if (hresult != SQLITE_DONE ) {
            errors::throw_sqlite_error(hresult, sql());
            return false; // Need unreachable return to make "not all paths" error go away
        }
        else {
            return false;
        }
    }

The workflow I'm using is:

auto selectStmnt = *_db << ss.str();
TestDBClass fromDb;
while ( selectStmnt.step() )    {
    mapper.deserialize(selectStmnt, fromDb);
            // Decided whether to continue parsing other rows here or to break out
}
    // selectStmnt goes out of scope and gets cleaned up automatically

Like I said earlier, perhaps there's already a built-in method which I'm not aware of and in that case if you could point me in the right direction I'd be much obliged. Thanks!

aminroosta commented 6 years ago

@badiozam That is a really good point, thanks for opening an issue here. Our implementation has changed in dev branch which will be the base for next version. https://github.com/SqliteModernCpp/sqlite_modern_cpp/blob/dev/hdr/sqlite_modern_cpp.h#L260

@zauguin Do you think we can support an interface that will break up the look if the user returns false on the lambda?

db << "select name,age from user" >> [](string name, int age) {
     // use name, age
     return false; // stop extracting the remaining rows.
});
zauguin commented 6 years ago

@aminroosta The change would be easy. The iterators on the dev branch also allow something quite near to the proposed while:

for(auto &&row : db << "select age,name,weight from user where age > ? ;" << 21) {
  // Do something with `row`, for example
  string name; int age;
  row >> name >> age;
  cout << name << ": " << age << '\n';
  if(something) break; // maybe stop extracting the remaining rows.
}