Giter Club home page Giter Club logo

Comments (7)

thed636 avatar thed636 commented on June 2, 2024 2

Well, the INSERT query parameters are completely different from the SELECT query result. But, you may use boost::hana to construct a query from an adapted structure using the query builder. E.g., something similar to:

namespace hana = boost::hana;
using namespace hana::literals;

//...

my_row row;

//...

constexpr auto keys = hana::keys(row);

constexpr auto fields = hana::fold(keys, ""_s, [](auto state, auto x) {
    if constexpr (hana::is_empty(state)) {
        return x;
    } else {
        return state + ", "_s + x;
    }
});

auto query = "INSERT into my_table("_SQL 
    + ozo::make_query_text(fields) 
    + ") VALUES ("_SQL 
    + ozo::make_query_builder(hana::unpack(keys, [&](auto ...xs) {
        return hana::make_tuple(ozo::make_query_param(std::cref(hana::at_key(row, xs)))...);
    }))
    + ");"_SQL;

ozo::request(conn_info[io], query, ozo::into(res),
    [&](ozo::error_code ec, auto conn) {
    //...
});

I didn't check this snippet, but it looks like the idea should work. Try to play around with it. I hope that helps.

from ozo.

elsid avatar elsid commented on June 2, 2024 1

I can also recommend to look on this one that covers how to insert values instead of constants, make a query template and use composite types.

from ozo.

thed636 avatar thed636 commented on June 2, 2024

Hi!
Could you please give me a little bit more information and clarify what do you mean under "how to insert a row with Boost.Hana"? What kind of problem do you want to highlight or solve with such an example?

The INSERT query may be found here. This is a simple query statement like SELECT or CALL. From this point of view there is no difference between them.

Here is issue #267 for inserting multiple rows, you may find some useful info there.

from ozo.

treehaqr avatar treehaqr commented on June 2, 2024

Hi,

First I'd like thank you for making this library available and answer my question :)

My question was inspired by your how to doc: https://github.com/yandex/ozo/blob/master/docs/howto.md. You have an example for SELECT here which i think is beautifully done:
struct my_row {
std::int64_t id;
std::optionalstd::string name;
};
BOOST_HANA_ADAPT_STRUCT(my_row, id, name);
int main() {
std::vector<my_row> res;
const auto query = "SELECT id, name FROM users_info WHERE amount>="_SQL + std::int64_t(25);
ozo::request(ozo::make_connector(io, conn_info), query, ozo::into(res),
[&](ozo::error_code ec, auto conn) {
...
});
}

In this example Boost.Hana allows the result to be written into my_row without having to pay close attention to the ordering of the columns (id, name). I suspect it would have easily worked if you had (name, id).

However, I haven't found a way to do that when you do an insert. Suppose i have my_row that way, how do I perform an insert without painstakingly pay close attention to the ordering in constructing a query?

Thank you again!

from ozo.

treehaqr avatar treehaqr commented on June 2, 2024

Thank you! I will give it a try.

from ozo.

thed636 avatar thed636 commented on June 2, 2024

@treehaqr I'm closing the issue since no activity there for more than a week. Please feel free to reopen it if needed.

from ozo.

dimilar avatar dimilar commented on June 2, 2024
#include <iostream>
#include <string_view>


namespace hana = boost::hana;
namespace asio = boost::asio;
using namespace std::chrono_literals;
using namespace ozo::literals;
using namespace boost::hana::literals;

struct my_row {
  std::int64_t id;
  std::string name;
};

BOOST_HANA_ADAPT_STRUCT(my_row, id, name);

int main(int argc, char **argv) {
  my_row row = {2, “ozo”};
 
  constexpr auto keys = hana::keys(row);
  
  constexpr auto fields = hana::fold(keys, ""_s, [](auto state, auto x) {
    if constexpr (hana::is_empty(state)) {
      return x;
    } else {
      return state + ", "_s + x;
    }
  });

  auto demo = "INSERT into my_table("_SQL +
              ozo::make_query_text(fields) +
              ") VALUES "_SQL +
              ozo::make_query_builder(hana::unpack(keys, [&](auto ...xs) {
                return hana::append(
                    hana::insert(hana::intersperse(
                        hana::make_tuple(ozo::make_query_param(std::cref(hana::at_key(row, xs)))...),
                        ozo::make_query_text(BOOST_HANA_STRING(","))), 0_c, ozo::make_query_text(BOOST_HANA_STRING("("))),
                    ozo::make_query_text(BOOST_HANA_STRING(")")));
              })) +
              " returning id;"_SQL;

  std::cout << std::string_view(hana::to<const char*>(demo.build().text)) << std::endl;

  asio::io_context io;
  const ozo::connection_info connection_info(argv[1]);
  ozo::connection_pool_config connection_pool_config;
  connection_pool_config.capacity = 1;
  connection_pool_config.queue_capacity = 10;
  connection_pool_config.idle_timeout = std::chrono::seconds(60);
  connection_pool_config.lifespan = std::chrono::hours(24);

  ozo::connection_pool connection_pool(connection_info, connection_pool_config);

  asio::spawn(io, [&] (asio::yield_context yield) {
    ozo::error_code ec;
    ozo::rows_of<std::int64_t> result;
    const auto connection = ozo::request(connection_pool[io], demo, 1s, ozo::into(result), yield[ec]);
    for (auto value : result)
      std::cout << "row: " << std::get<0>(value) << std::endl;
  });
  io.run();
  
  return 0;
}

@thed636 refer to your snippet, I wrote a working insert code, but I still want to know how to build the query if I do not know the number of rows in advance. e.g. rows
stored in a std::vector. how to dynamic create a big hana::tuple in order to build the query?

from ozo.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.