Skip to content

Commit 23b6ff8

Browse files
committed
note about c++20
1 parent 59871ef commit 23b6ff8

File tree

5 files changed

+155
-46
lines changed

5 files changed

+155
-46
lines changed

.github/workflows/ci.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ jobs:
4444
- name: Run tests
4545
run: |
4646
./scripts/test.sh
47+
48+
- name: Run demo
49+
run: |
50+
./scripts/run-demo.sh
4751
4852
- name: Stop InfluxDB
4953
if: always()
@@ -157,6 +161,10 @@ jobs:
157161
run: |
158162
./scripts/test.sh
159163
164+
- name: Run demo
165+
run: |
166+
./scripts/run-demo.sh
167+
160168
- name: Stop InfluxDB
161169
if: always()
162170
run: |
@@ -215,6 +223,10 @@ jobs:
215223
- name: Run tests
216224
run: |
217225
scripts\test.bat
226+
227+
- name: Run demo
228+
run: |
229+
scripts\run-demo.bat
218230
219231
- name: Stop InfluxDB
220232
if: always()

README.md

Lines changed: 62 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,21 @@
44

55
A modern C++20 [InfluxDB](https://www.influxdata.com/time-series-platform/influxdb/) client via [C++ REST SDK](https://github.com/Microsoft/cpprestsdk) + a C wrapper of the asynchronous API as a shared library.
66

7+
## C++ Standard Requirements
8+
9+
**This project requires C++20 or later.**
10+
11+
- Minimum compiler versions:
12+
- GCC 11+
13+
- Clang 14+
14+
- MSVC 2019+ (19.29+) with `/std:c++20` or later
15+
- The project uses C++20
16+
- All dependencies are C++20 compatible
17+
- **Note:** The legacy C++03 version is available in the [`v0.0.1-legacy`](https://github.com/d-led/influxdb-cpp-rest/releases/tag/v0.0.1-legacy) tag
18+
719
See [the demo source](src/demo/main.cpp) for the current api example.
820

9-
The unbatched aprroach (and without connection reuse) may not be sufficient in some situations, as without batching, about 200 lines/sec can be inserted.
21+
The unbatched approach (and without connection reuse) may not be sufficient in some situations, as without batching, about 200 lines/sec can be inserted.
1022

1123
A batching api leans towards thousands inserts per second. Behind the scenes, the API uses [RxCpp](https://github.com/Reactive-Extensions/RxCpp) and [cppformat](https://github.com/fmtlib/fmt).
1224

@@ -19,25 +31,35 @@ A batching api leans towards thousands inserts per second. Behind the scenes, th
1931
## Synchronous insertion
2032

2133
```cpp
22-
influxdb::api::simple_db simpledb("http://localhost:8086", "my_db");
34+
using namespace influxdb::api;
35+
using namespace std::string_literals;
36+
37+
auto db = simple_db("http://localhost:8086"s, "my_db"s);
2338
db.insert(
24-
line("log", key_value_pairs("my_tag", 42L), key_value_pairs("value", "hello world!")));
39+
line("log"s,
40+
key_value_pairs("my_tag"s, 42L),
41+
key_value_pairs("value"s, "hello world!"s)));
2542
```
2643
2744
## Asynchronous insertion
2845
2946
The asynchronous API inserts the points on an active object with automatic batching, thus increasing throughput.
3047
3148
```cpp
32-
influxdb::async_api::simple_db asyncdb("http://localhost:8086", "my_db");
33-
34-
for (int i = 0; i < 123456; i++) {
35-
asyncdb.insert(
36-
line(
37-
"my_measurements",
38-
key_value_pairs("my_count", i % MAX_VALUES_PER_TAG),
39-
key_value_pairs("value", "hi!")
40-
));
49+
using namespace influxdb::api; // For line, key_value_pairs
50+
using namespace std::string_literals;
51+
using async_db = influxdb::async_api::simple_db; // Type alias to avoid ambiguity
52+
53+
auto db = async_db("http://localhost:8086"s, "my_db"s);
54+
55+
for (auto i = 0; i < 123456; ++i) {
56+
db.insert(
57+
line(
58+
"my_measurements"s,
59+
key_value_pairs("my_count"s, i % MAX_VALUES_PER_TAG),
60+
key_value_pairs("value"s, "hi!"s)
61+
)
62+
);
4163
}
4264
```
4365

@@ -51,13 +73,15 @@ Timestamps can be added as the last parameter to the `line` constructor, and onl
5173
a serializable value on `TTimestamp::now()`. There is a default `std::chrono`-based implementation:
5274

5375
```cpp
54-
line(
55-
"my_measurements",
56-
key_value_pairs("my_count", i % MAX_VALUES_PER_TAG),
57-
key_value_pairs("value", "hi!"),
58-
default_timestamp()
59-
// ^^^^^^^^^^^^^^^^^^^
60-
)
76+
using namespace influxdb::api;
77+
using namespace std::string_literals;
78+
79+
line(
80+
"my_measurements"s,
81+
key_value_pairs("my_count"s, 42),
82+
key_value_pairs("value"s, "hi!"s),
83+
default_timestamp() // Optional: uses std::chrono for timestamps
84+
)
6185
```
6286

6387
`MAX_VALUES_PER_TAG` for demo purposes here, as there [is such a maximum](https://docs.influxdata.com/influxdb/v1.4/administration/config#max-values-per-tag-100000) and it has to be observed by the clients.
@@ -67,17 +91,23 @@ a serializable value on `TTimestamp::now()`. There is a default `std::chrono`-ba
6791
Add lines using the `()` operator on the line:
6892

6993
```cpp
70-
line
71-
("multiple", key_value_pairs("v1", 1), key_value_pairs())
72-
("multiple", key_value_pairs("v2", 2), key_value_pairs())
94+
using namespace influxdb::api;
95+
using namespace std::string_literals;
96+
97+
line
98+
("multiple"s, key_value_pairs("v1"s, 1), key_value_pairs())
99+
("multiple"s, key_value_pairs("v2"s, 2), key_value_pairs())
73100
```
74101
75102
## Query
76103
77104
```cpp
78-
influxdb::raw::db_utf8 raw_db("http://localhost:8086", "my_db");
79-
auto query = std::string("select count(*) from my_db..my_measurements");
80-
auto json_response = raw_db.get(query);
105+
using namespace influxdb::raw;
106+
using namespace std::string_literals;
107+
108+
auto db = db_utf8("http://localhost:8086"s, "my_db"s);
109+
auto query = "select count(*) from my_db..my_measurements"s;
110+
auto json_response = db.get(query);
81111
```
82112

83113
&darr;
@@ -88,12 +118,15 @@ auto json_response = raw_db.get(query);
88118

89119
## Authentication
90120

91-
Basic authentication can be used with all API variants
121+
Basic authentication can be used with all API variants:
92122

93123
```cpp
94-
influxdb::raw::db_utf8 raw_db("http://localhost:8086", "my_db");
95-
raw_db.with_authentication(username, password);
96-
auto query = ...
124+
using namespace influxdb::raw;
125+
using namespace std::string_literals;
126+
127+
auto db = db_utf8("http://localhost:8086"s, "my_db"s);
128+
db.with_authentication("username"s, "password"s);
129+
auto response = db.get("select * from my_measurements");
97130
```
98131
99132
## Error Handling

scripts/run-demo.bat

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
@echo off
2+
setlocal enabledelayedexpansion
3+
4+
set BUILD_DIR=%BUILD_DIR%
5+
if "%BUILD_DIR%"=="" set BUILD_DIR=build
6+
7+
set BUILD_TYPE=%BUILD_TYPE%
8+
if "%BUILD_TYPE%"=="" set BUILD_TYPE=Release
9+
10+
set BIN_DIR=%BUILD_DIR%\bin\%BUILD_TYPE%
11+
set BIN_DIR_ALT=%BUILD_DIR%\bin
12+
13+
REM Build if not already built
14+
if not exist "%BIN_DIR%\demo.exe" if not exist "%BIN_DIR_ALT%\demo.exe" (
15+
echo Building demo...
16+
scripts\build.bat %BUILD_TYPE%
17+
)
18+
19+
REM Find and run the demo
20+
if exist "%BIN_DIR%\demo.exe" (
21+
echo Running %BIN_DIR%\demo.exe...
22+
"%BIN_DIR%\demo.exe"
23+
exit /b %errorlevel%
24+
)
25+
26+
if exist "%BIN_DIR_ALT%\demo.exe" (
27+
echo Running %BIN_DIR_ALT%\demo.exe...
28+
"%BIN_DIR_ALT%\demo.exe"
29+
exit /b %errorlevel%
30+
)
31+
32+
echo ERROR: Demo executable not found. Build it first with: scripts\build.bat
33+
exit /b 1
34+

scripts/run-demo.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
BUILD_DIR="${BUILD_DIR:-build}"
5+
BUILD_TYPE="${BUILD_TYPE:-Release}"
6+
7+
# Build if not already built
8+
if [ ! -f "${BUILD_DIR}/bin/demo" ] && [ ! -f "${BUILD_DIR}/bin/${BUILD_TYPE}/demo" ] && [ ! -f "${BUILD_DIR}/${BUILD_TYPE}/bin/demo" ]; then
9+
echo "Building demo..."
10+
./scripts/build.sh "${BUILD_TYPE}"
11+
fi
12+
13+
# Find and run the demo
14+
for demo_path in "${BUILD_DIR}/bin/demo" "${BUILD_DIR}/bin/${BUILD_TYPE}/demo" "${BUILD_DIR}/${BUILD_TYPE}/bin/demo" "${BUILD_DIR}/demo"; do
15+
if [ -f "${demo_path}" ] && [ -x "${demo_path}" ]; then
16+
echo "Running ${demo_path}..."
17+
"${demo_path}"
18+
exit 0
19+
fi
20+
done
21+
22+
echo "ERROR: Demo executable not found. Build it first with: ./scripts/build.sh"
23+
exit 1
24+

src/demo/main.cpp

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,37 @@
88
#include <iostream>
99
#include <thread>
1010
#include <chrono>
11+
#include <string>
1112

1213
using namespace influxdb::api;
14+
using namespace influxdb::raw;
15+
using namespace std::string_literals;
1316

14-
int main(int argc, char* argv[])
17+
using async_db = influxdb::async_api::simple_db;
18+
19+
int main(int, char**)
1520
{
16-
try
17-
{
18-
const char* url = "http://localhost:8086";
19-
influxdb::raw::db_utf8 db(url, "demo");
20-
influxdb::api::simple_db api(url, "demo");
21-
influxdb::async_api::simple_db async_api(url, "demo");
21+
try {
22+
const auto url = "http://localhost:8086"s;
23+
const auto db_name = "demo"s;
24+
25+
auto db = db_utf8(url, db_name);
26+
auto api = simple_db(url, db_name);
27+
auto async_api = async_db(url, db_name);
2228

2329
api.drop();
2430
api.create();
2531

2632
// {"results":[{"series":[{"columns":["name"],"name":"databases","values":[["_internal"],["mydb"]]}]}]}
27-
std::cout << db.get("show databases") << std::endl;
33+
std::cout << db.get("show databases"s) << '\n';
2834

29-
async_api.insert(line("test", key_value_pairs(), key_value_pairs("value", 41)));
30-
api.insert(line("test", key_value_pairs(), key_value_pairs("value", 42)));
35+
async_api.insert(line("test"s, key_value_pairs(), key_value_pairs("value"s, 41)));
36+
api.insert(line("test"s, key_value_pairs(), key_value_pairs("value"s, 42)));
3137

3238
std::this_thread::sleep_for(std::chrono::milliseconds(101));
3339

3440
// {"results":[{"series":[{"columns":["time","value"],"name":"test","values":[["2016-10-28T22:11:22.8110348Z",42]]}]}]}
35-
std::cout << db.get("select * from demo..test") << std::endl;
41+
std::cout << db.get("select * from demo..test"s) << '\n';
3642

3743
// or if the async call passes through:
3844
// {"results":[{"series":[{"name":"test","columns":["time","value"],
@@ -44,13 +50,13 @@ int main(int argc, char* argv[])
4450
// multiple,v1=1i
4551
// multiple,v2=2i
4652
std::cout << line
47-
("multiple", key_value_pairs("v1", 1), key_value_pairs())
48-
("multiple", key_value_pairs("v2", 2), key_value_pairs())
49-
.get() << std::endl;
53+
("multiple"s, key_value_pairs("v1"s, 1), key_value_pairs())
54+
("multiple"s, key_value_pairs("v2"s, 2), key_value_pairs())
55+
.get() << '\n';
5056
}
51-
catch (std::exception const& e)
52-
{
53-
std::cerr << e.what() << std::endl;
57+
catch (const std::exception& e) {
58+
std::cerr << e.what() << '\n';
59+
return 1;
5460
}
5561

5662
return 0;

0 commit comments

Comments
 (0)