boostorg / mysql

MySQL C++ client based on Boost.Asio
https://www.boost.org/doc/libs/master/libs/mysql
Boost Software License 1.0
258 stars 33 forks source link

How to dynamic create a FieldLikeTuple #110

Closed nesc1 closed 1 year ago

nesc1 commented 1 year ago

Hi, my last code executes a list of dynamic params and used a std::vector for that on the old code. Now when I try to execute a statement execution with a vector it gives me a compilation error.

My question is how do I create a dynamic FieldLikeTuple?

I tried with std::tuple_cat with no success because i can't save the new tuple on the same variable...

anarthal commented 1 year ago

Hi,

You can't. FieldLikeTuples are std::tuples, which are static.

I'd recommend you using statement::start_execution, which accepts an arbitrary iterator range.

If you're upgrading from 0.2.0 to master, a few things to note:

Example code:

// prepare the statement
tcp_ssl_statement stmt;
conn.prepare_statement("SELECT * FROM...", stmt);

// execute it
std::vector<field> params; // get it from wherever
execution_state st;
stmt.start_execution(params.begin(), params.end(), st);

// read rows
while (!st.complete()) {
    rows_view batch = conn.read_some_rows(st);
    // batch will contain an indeterminate number of rows. Use it however you want
}

I wasn't expecting a lot of interest in the iterator version of statement execution, so I only implemented it as start_execution, and not as execute. Would you mind answering a couple questions about your use case, so I can direct my implementation efforts?

I've also seen that the new docs have -4 of SEO and aren't shown on google searches, so I'll include a link here: https://www.boost.org/doc/libs/master/libs/mysql/doc/html/index.html

If you have any further question or request regarding migration, I'll be happy to help.

Thanks for using the library!

nesc1 commented 1 year ago

Hi @anarthal thank you once more for the detailed answer.

Then I will try the iterator version, I come up with a solution yesterday for the FieldLikeTuple way but I really don't like it, is based on a static detection of the size of the vector and build the tuple according to that.

Trying to answer to your questions the best way I can:

> Does your statement generate any rows? (i.e. is it a SELECT vs an INSERT). yes it normally generates, because normally I have conditions to filter the select, example: getMyUsers(bool filterBySex, std::optional country.... etc)

> If it does, are you reading them one by one (i.e. with the old resultset::read_one) or all of them at once (i.e.with the old resultset::read_all). yes I'm reading all, the old resultset::read_all yes

>What is the requirement that prevents you from knowing the number of parameters at compile time? is like I said, normally is for using filters in my query's, more generic filters less parameters, more specific filters more parameters..

(thank you for the link, yes is not easy to find the documentation no, thank you)

Thank you again for providing the library, Best regards, Nuno

anarthal commented 1 year ago

Hi @nesc1,

Thank you for your answers, they will guide me. One more question, how are you handling these filters? Do you have a single different prepared statement for each possible combination of filters, or are you building the prepared statement SQL dynamically depending on whether the fields are present or not?

With the data I have, I'd say that the option I presented you yesterday is the best one. You will have to read rows in batches as I showed you. I've opened #111 to implement the equivalent to FieldLikeTuples, but with iterators.

Regards, Ruben.

nesc1 commented 1 year ago

Hi @anarthal

No, for dynamic queries I never use prepared statements, I use prepared statements but not dynamically. Yes normally I build SQL dynamically depending on whether the fields are present or not, yes.

Yes I will test that code suggestion for my case, thank you. Regards, Nuno

anarthal commented 1 year ago

Thanks for the info. Closing this as we have #111 to track the feature request.