Skip to content
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

Question: how can I use the API without linked calls? #8

Open
j-e-f-f-williams opened this issue Oct 19, 2018 · 14 comments
Open

Question: how can I use the API without linked calls? #8

j-e-f-f-williams opened this issue Oct 19, 2018 · 14 comments

Comments

@j-e-f-f-williams
Copy link

Hello,

I have history with C and relatively new to C++ and your API is a pattern I have not seen before. I have the test app working fine with the call like:
int ret = influxdb_cpp::builder() .meas("imu") .tag("track", "Home Testing") .field("ax", ax) .field("ay", ay) .field("az", az) .field("gx", gx) .field("gy", gy) .field("gz", gz) .field("yaw", yaw) .field("pitch", pitch) .field("roll", roll) .field("temperature", temperature) .field("pressure", pressure) .field("altitude", altitude) .timestamp( std::chrono::duration_cast<std::chrono::nanoseconds>(clock.now().time_since_epoch()).count() ) .post_http(si, &resp);

but I have a thread pool that handle a queue I have created. The queue contain a generic payload for more than 1 type of measures. The fields and tags are passed in as maps in the format { tag name, tag value}

So therefore I need to iterate over the map and call .field or .tag APIs.

I can't seem to figure out a calling mechanism to support this where I create the builder and then add details to it iterating over my map(s) and then calling the post_http.

Thought I would post this here for some help. In the mean time I will dig deeper to see if I can understand the way your API works.

Thanks, Jeff

@j-e-f-f-williams j-e-f-f-williams changed the title Question: how can I use the API without liked calls? Question: how can I use the API without linked calls? Oct 19, 2018
@orca-zhang
Copy link
Owner

Hi,

Great to hear from you.

Your scene and suggestion is really good.

The cue I could give you is the member variant lines_.

What chain-able call finished is to build lines_ that to be send.

Apologize for my busy working these days, otherwise I'll add this feature ASAP.

Looking forward to your reply.

Thank you, Orca

@jha
Copy link
Contributor

jha commented Dec 21, 2018

Without even needing to look into the source for the datatypes, you could probably just use cpp's auto feature. In pseudocode, something along the lines of

auto& m = influxdb_cpp::builder().meas("imu").tag("track", "Home Testing");
foreach key, value in std::map {
    m = m.field(key, value);
}
...
m.post_http(si, &resp);

If you need a separate map for tags, you should create an additional loop before the fields loop as well.

@JBongJ
Copy link

JBongJ commented May 22, 2019

Without even needing to look into the source for the datatypes, you could probably just use cpp's auto feature. In pseudocode, something along the lines of

auto& m = influxdb_cpp::builder().meas("imu").tag("track", "Home Testing");
foreach key, value in std::map {
    m = m.field(key, value);
}
...
m.post_http(si, &resp);

If you need a separate map for tags, you should create an additional loop before the fields loop as well.

I followed your suggestion, but I got an error message like this.

error: use of deleted function 'influxdb_cpp::detail::tag_caller& influxdb_cpp::detail::tag_caller::operator=(const influxdb_cpp::detail::tag_caller&)'

Could you help me?

@orca-zhang
Copy link
Owner

Without even needing to look into the source for the datatypes, you could probably just use cpp's auto feature. In pseudocode, something along the lines of

auto& m = influxdb_cpp::builder().meas("imu").tag("track", "Home Testing");
foreach key, value in std::map {
    m = m.field(key, value);
}
...
m.post_http(si, &resp);

If you need a separate map for tags, you should create an additional loop before the fields loop as well.

I followed your suggestion, but I got an error message like this.

error: use of deleted function 'influxdb_cpp::detail::tag_caller& influxdb_cpp::detail::tag_caller::operator=(const influxdb_cpp::detail::tag_caller&)'

Could you help me?

Do some small modifications.
Try the code belong, remove the assignment when setting fields would be OK.

auto& m = influxdb_cpp::builder().meas("imu").tag("track", "Home Testing");
foreach key, value in std::map {
    m.field(key, value); // notice this line please
}
...
m.post_http(si, &resp);

@axiaoxin
Copy link

axiaoxin commented Jul 8, 2019

I use the linked call like this:

     43             std::string dataId = i.first;
     44             map<std::string, int> countMap = dataIdCountMap[dataId];
     45
     46             auto& m = influxdb_cpp::builder().meas("gather")
     47                         .tag("system_name", systemName.c_str())
     48                         .tag("data_id", dataId.c_str());
     49             for (const auto& j: countMap) {
     50                 m.field(j.first, j.second);
     51             }
                     int ret = m.post_http(si, &resp);

but compile error:

error: 'struct influxdb_cpp::detail::tag_caller' has no member named 'post_http'
             int ret = m.post_http(si, &resp);
                         ^

@orca-zhang @jha Could you help me?

@ghost
Copy link

ghost commented Jul 13, 2019

I came up with a solution using std::optional (C++17). Rather messy, but it gets the job done.

void Test(influxdb_cpp::server_info& si)
{
   std::unordered_map<std::string, float> kvps;

   auto m = influxdb_cpp::builder();
   std::optional<std::reference_wrapper<std::decay_t<decltype(m.meas("").field("",""))>>> field;

   for (auto it = kvps.begin(); it != kvps.end(); ++it)
   {
      const auto& key = it->first;
      const auto& value = it->second;

      if (field.has_value())
         field = field->get().field(key.c_str(), value);
      else
         field = m.meas("imu").tag("track", "Home Testing").field(key.c_str(), value);
   }

   if (kvps.empty())
     return;

   field->get().post_http(si);
}

@Andrew15381
Copy link

Andrew15381 commented Oct 6, 2019

When meas_caller will be implemented?

@jguiban
Copy link

jguiban commented Jan 9, 2020

Same compilation error for me when building the following code:

 auto &m = influxdb_cpp::builder().meas("test");

    m.field("val", 10); // notice this line please
    //m.timestamp(1578569518);
    m.post_http(si, &resp);
 

error: ‘struct influxdb_cpp::detail::tag_caller’ has no member named ‘post_http’
m.post_http(si, &resp);

Any incoming fix or workaround for this issue ?

@orca-zhang
Copy link
Owner

auto &m = influxdb_cpp::builder().meas("test");
auto & f = m.field("val", 10);
f.post_http(si, &resp);

@oallaire
Copy link

oallaire commented Mar 6, 2020

I was having trouble with this part. To prevent using deleted references, I recommend using:

influxdb_cpp::builder builder;
auto &m = builder.meas("test");
auto & f = m.field("val", 10);
f.post_http(si, &resp);

@sjtuzwj
Copy link

sjtuzwj commented Jan 13, 2021

`
auto & builder = influxdb_cpp::builder()
.meas(request->measure());

    for(int i = 0; i< request->tags_size(); i++)
    {
        auto & tag = request->tags(i);
        builder.tag(tag.key(),tag.val());
    }
//!!!!!!!!!!!!!!important, becasue field use ',' but tag use ' '
auto & field_builder = (influxdb_cpp::detail::field_caller&)builder;
  
    for(int i = 0; i< request->intfs_size(); i++)
    {
        auto & intf = request->intfs(i);
        builder.field(intf.key(),intf.val());
    }
  
    for(int i = 0; i< request->boolfs_size(); i++)
    {
        auto & boolf = request->boolfs(i);
        builder.field(boolf.key(),boolf.val());
    }
    for(int i = 0; i< request->stringfs_size(); i++)
    {
        auto & stringf = request->stringfs(i);
        builder.field(stringf.key(),stringf.val());
    }
    for(int i = 0; i< request->floatfs_size(); i++)
    {
        auto & floatf = request->floatfs(i);
        builder.field(floatf.key(),floatf.val());
    } 

    std::string resp;
    int ret = field_builder
    .timestamp(request->timestamp())
    .post_http(si_, &resp);

`
After tag(), typecast to field_caller is important, because tag_caller and field_caller behave differently(delim is , or blank)

@sunnyinchina
Copy link

auto &m = influxdb_cpp::builder().meas("test");
auto & f = m.field("val", 10);
f.post_http(si, &resp);

after above, it doesn't act, can you help me?

@sunnyinchina
Copy link

I was having trouble with this part. To prevent using deleted references, I recommend using:

influxdb_cpp::builder builder;
auto &m = builder.meas("test");
auto & f = m.field("val", 10);
f.post_http(si, &resp);

As you mentioned, one field is ok, but two or more field is wrong, how to resolve it?

@fyr233
Copy link

fyr233 commented Mar 13, 2024

Hi, I have a similar need.
I noticed multiple insert is supported.

influxdb_cpp::builder()
    .meas("foo")  // series 1
    .field("x", 10)

    .meas("bar")  // series 2
    .field("y", 10.3)
    .send_udp("127.0.0.1", 8091);

I hope to implement a caching mechanism to save post_http overhead
For example:

class MyLogger {
    void Write2DB(...) {
        buffer
            .meas("foo")
            .tag("k", "v")
            .tag("x", "y")
            .field("x", 10)
            .field("y", 10.3, 2)
            .field("z", 10.3456)
            .field("b", !!10)
            .timestamp(1512722735522840439);
        bufferSize++;
        if (bufferSize > 10) {
            buffer.post_http(si);
            buffer = ...; // a new object
            bufferSize = 0;
        }
    }
    auto buffer = ...; // something like influxdb_cpp::builder
    int bufferSize = 0;
}

Is there any way to achieve this now?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests