-
Notifications
You must be signed in to change notification settings - Fork 478
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
soci::RowSet support for social::Blob #922
Comments
Hello guys. @vadz answered me on the PR:
I will answer it here since the conversation seems to go beyond my initial expectations. I will explain what I mean. First things first, thanks once again for your reply! It seems that everything is well connected inside the code, which is good, but sometimes takes a simple modification a long journey into the code. Which is good to learn the philosophy adopted here. Yes, I want to implement these tests for the other backends. I need it working at very least on However, while I was reading the code related to You said you are using Currently, it seems that USE 1: { // For SQLite3 and Firebird
blob b(sql);
sql << "select img from soci_test where id = 7", into(b);
CHECK(b.get_len() == 0);
b.write(0, buf, sizeof(buf));
CHECK(b.get_len() == sizeof(buf));
b.append(buf, sizeof(buf));
CHECK(b.get_len() == 2 * sizeof(buf));
sql << "update soci_test set img=:blob where id = 7", use(b); // Save it on DB
} a similar code can be seen here. USE 2: While { // For Oracle and Postgres
blob b(sql);
sql << "select img from soci_test where id = 7", into(b);
CHECK(b.get_len() == 0);
b.write(0, buf, sizeof(buf)); // Save it on DB
CHECK(b.get_len() == sizeof(buf));
b.append(buf, sizeof(buf)); // Save it on DB
CHECK(b.get_len() == 2 * sizeof(buf));
} code copied from here. Which forces the user to first create a dump empty {
// Create a empty `blob` on `Postgres`
sql << "insert into soci_test(id, img) values(7, lo_creat(-1))";
// Create a empty `blob` on `Oracle`
sql << "insert into soci_test (id, img) values (7, empty_blob())";
} code copied from here and here. Which doesn't make too much sense to me.... In order to insert a new information you have to run an The version implemented on One could argue that After digging the code, it seems to me that there is a confusion on the roles of USE 3: Also, for the other variable types, {
statement st1 = (sql.prepare <<
"insert into soci_test (id, name) values (:id, :name)",
use(id), use(name));
id = 1; name = "John"; st1.execute(1);
id = 2; name = "Anna"; st1.execute(1);
id = 3; name = "Mike"; st1.execute(1);
} code copied from here. Which currently will not work with Actually, the simple fact of re-using a { // Another issue on Firebird (I believe that it doesn't affect SQLite3)
blob b(sql);
b.write(0, buf, sizeof(buf));
CHECK(b.get_len() == sizeof(buf));
sql << "insert into soci_test(id, img) values(1, :blob)", use(b); // Saves the blob on db.
sql << "insert into soci_test(id, img) values(2, :blob)", use(b); // Saves an empty blob
} I am adding this test on the tests batch and fixing where it is happening. Only a suggestion: Talking about "later evaluation". It would be nice if we could have a { // Only a suggestion
std::vector<int> vec1 = {1, 2, 3, 4}
statement st1 = (sql.prepare <<
"insert into soci_test (id, m_list) values (:id, :blob)",
use(id), use(blob(vec1)));
id = 1; st1.execute(1); // Saves {1, 2, 3, 4}
id = 2; vec1.push_back(5); st1.execute(1); // Saves {1, 2, 3, 4, 5}
}
{
std::vector<int> vec2;
sql << "select m_list from soci_test where id = 1", into(blob(vec2));
print_vector(vec2); // Prints {1, 2, 3, 4}
} I think it is doable, but it is out of scope of the discussion here and/or my initial motivation. I am letting it here just as a suggestion. My initial goal was to support In short (or in tables). Current
Where I am aiming:
OBS 1: If you wanna follow the CI tests, I am running them here. This repo has a good CI pipeline implemented for GitHub Actions, idk why it is not running on my PR here. So I forked the project to run it there. |
Sorry, I didn't have time to look at this in details yet, but we do use BLOBs (or at least CLOBs, for XML storage, but I think they are very similar) with Firebird, Oracle and PostgreSQL, so I am not sure what the problem is. I don't think we ever reuse them, however, so there could be bugs when doing it. Another question I have is what exactly do you mean by "good CI pipeline", i.e. how is it better than what we have? If you have any improvements to suggest for our CI workflow, please don't hesitate to make (another) PR for it, TIA! |
I mean your CI pipeline, the GitHub actions one. For some reason, yours GitHub actions is not running on that PR, so I created a fork just to run yours GitHub Actions CI pipeline. In my case here, we need a library that runs the exactly same code on different backends, which is not the case for If you think it is not from |
The CI should run now, it just had to be manually authorized for the first run by a new contributor. And of course all the backends should work the same, ideally. Anyhow, let's wait until your PR is finalized and discuss the final version when it's ready. |
looking forward to this! |
Hello Gabriel. It is almost done for all engines. I am missing just oracle. But I work got me and I ended letting it aside for a time. If you would like to help finish and/or would like to use to another backend, be my guest to checkout on my branch. Kind regards |
I think all of the mentioned features here (except for the "tell soci to use arbitrary objects as blob-like data") are implemented in #992 |
@schvarcz Have all these suggestions been implemented? Thanks |
Hello everyone.
First, thanks for this very useful library. We are really looking to use this library on our company due the support to several backends.
However, I see some room for improvement where I hope I can help.
On our case, we have heavily use the
soci::blob
. Right now, I am in a situation where I have to use it withsoci::rowset
. However, when I do something likem_rowset.get<blob>("m_blob")
,soci
returns the error:I do understand the nature of the problem and why
soci::blob
needs to be initialised withsoci::session
. I also can see that similar issues were raised in the past, with the same nature.Since I can't see another way to retrieve
soci::blob
objects in a bulk way, I had to dig into it.I believe that we have 3 main points to check when we are talking about retrieving information with blob:
For the first case, the solution seems to rely direct on the
core
, sincesoci::rowset
has a pointer tosoci:statement
; andsoci::statement
has a public pointer tosoci::session
.If we can rearrange
soci::rowset
andsoci::row
so thesoci::session
pointer can reach the final class, we might solve the issue for the first case. (Ps: we also should be careful for the cases ofsoci::rowset<soci::blob>
.I would like to know what do you think about this solution. It seems to me that we are supposed to have a method to retrieve blob data in a bulk manner, since it is available to all other types and it seems to be a recurrent issue report here. If you agree with this implementation, I can work on that this week and submit a PR. Otherwise, I am open to other solutions.
Very likely I will dig into the case 2. in the near future.
Kind regards
The text was updated successfully, but these errors were encountered: