Skip to content

Commit cb7f08c

Browse files
msrd0Empty2k12
andauthoredMar 17, 2020
Add InfluxDbWriteable procedural derive macro (#23)
* cargo workspace * introduce InfluxDbWriteable * basic derive stuff * first writeable derive attempt * add test for the ci to run * add derive feature in travis * update version to 0.0.5 * fix some stuff * fix failing doc test * no default features, run tests with all features * typo * remove some warnings * cargo fmt * cargo readme * cargo readme is incompetent * Fix build hopefully * Debug CI * Debug Ci 2 * Debug Ci 3 * Debug Ci 4 * Debug Ci 5 * Stop using cargo-travis * Do stuff * tidy up * Test both crates * remove an `&` * travis närvt * first attempt at tags * specify the attributes * add usefull derives to Timestamp * the world is a brocken * that merge went well ..... * Refactor Tests * fix derp * Painstakingly fix tests and make chrono a required dependency * Fix lint warning * Update README * More fixes * apply @Empty2k12's suggestions && fix compile issue with no features * proper difference between field and tag * introduce krate method * progress * add field / tag test * cosmetic updates * fixed * fix clippy and fmt Co-authored-by: Gero Gerke <11deutron11@gmail.com>
1 parent 90f5f95 commit cb7f08c

24 files changed

+516
-236
lines changed
 

‎.travis.yml

+10-5
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,13 @@ matrix:
5151
script:
5252
- bash auxiliary/check_readme_consistency.sh
5353

54-
script: |
55-
export RUST_BACKTRACE=1 &&
56-
cargo build &&
57-
cargo test --all-features &&
58-
cargo doc --no-deps
54+
script:
55+
- export RUST_BACKTRACE=1
56+
- cd influxdb
57+
- cargo build
58+
- cargo test --all --all-features
59+
- cargo doc --no-deps
60+
- cd ../influxdb_derive
61+
- cargo build
62+
- cargo test --all --all-features
63+
- cargo doc --no-deps

‎Cargo.toml

+6-34
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,8 @@
1-
[package]
2-
name = "influxdb"
3-
version = "0.0.6"
4-
authors = ["Gero Gerke <11deutron11@gmail.com>"]
5-
edition = "2018"
6-
description = "InfluxDB Driver for Rust"
7-
keywords = ["influxdb", "database", "influx"]
8-
license = "MIT"
9-
readme = "README.md"
10-
include = ["src/**/*", "tests/**/*", "Cargo.toml", "LICENSE"]
11-
repository = "https://github.com/Empty2k12/influxdb-rust"
1+
# -*- eval: (cargo-minor-mode 1) -*-
122

13-
[badges]
14-
travis-ci = { repository = "Empty2k12/influxdb-rust", branch = "master" }
3+
[workspace]
4+
members = ["influxdb", "influxdb_derive"]
155

16-
[dependencies]
17-
chrono = { version = "0.4.10", optional = true }
18-
failure = "0.1.6"
19-
futures = "0.3.4"
20-
reqwest = { version = "0.10.1", features = ["json"] }
21-
serde = { version = "1.0.104", features = ["derive"], optional = true }
22-
serde_json = { version = "1.0.46", optional = true }
23-
regex = "1.3.4"
24-
lazy_static = "1.4.0"
25-
26-
# This is a temporary work around to fix a Failure-derive compilation error
27-
# Should be removed when https://github.com/Empty2k12/influxdb-rust/issues/48 is being done
28-
quote = "=1.0.2"
29-
30-
[features]
31-
use-serde = ["serde", "serde_json"]
32-
chrono_timestamps = ["chrono"]
33-
default = ["use-serde"]
34-
35-
[dev-dependencies]
36-
tokio = { version = "0.2.11", features = ["macros"] }
6+
[patch.crates-io]
7+
influxdb = { path = "./influxdb" }
8+
influxdb_derive = { path = "./influxdb_derive" }

‎README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,12 @@ Pull requests are always welcome. See [Contributing](https://github.com/Empty2k1
3939
- Optional Serde Support for Deserialization
4040
- Running multiple queries in one request (e.g. `SELECT * FROM weather_berlin; SELECT * FROM weather_london`)
4141
- Authenticated and Unauthenticated Connections
42-
- Optional conversion between `Timestamp` and `Chrono::DateTime<Utc>` via `chrono_timestamps` compilation feature
4342
- `async`/`await` support
43+
- `#[derive(InfluxDbWriteable)]` Derive Macro for Writing / Reading into Structs
4444

4545
### Planned Features
4646

4747
- Read Query Builder instead of supplying raw queries
48-
- `#[derive(InfluxDbReadable)]` and `#[derive(InfluxDbWriteable)]` proc macros
4948

5049
## Quickstart
5150

@@ -59,6 +58,7 @@ For an example with using Serde deserialization, please refer to [serde_integrat
5958

6059
```rust
6160
use influxdb::{Client, Query, Timestamp};
61+
use influxdb::InfluxDbWriteable;
6262

6363
// Create a Client with URL `http://localhost:8086`
6464
// and database name `test`
@@ -67,7 +67,7 @@ let client = Client::new("http://localhost:8086", "test");
6767
// Let's write something to InfluxDB. First we're creating a
6868
// WriteQuery to write some data.
6969
// This creates a query which writes a new measurement into a series called `weather`
70-
let write_query = Query::write_query(Timestamp::Now, "weather")
70+
let write_query = Timestamp::Now.into_query("weather")
7171
.add_field("temperature", 82);
7272

7373
// Submit the query to InfluxDB.

‎auxiliary/check_readme_consistency.sh

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
#!/usr/bin/bash
1+
#!/bin/bash
22

3-
cargo readme > README.md.expected
3+
cargo readme -r influxdb -t ../README.tpl > README.md.expected
44

55
diff README.md README.md.expected
66

@@ -9,6 +9,6 @@ then
99
echo 'README.md is up to date!'
1010
exit 0
1111
else
12-
echo 'README.md out of date. Run "cargo readme > README.md" and commit again.'
12+
echo 'README.md out of date. Run "cargo readme -r influxdb -t ../README.tpl > README.md" and commit again.'
1313
exit 1
14-
fi
14+
fi

‎influxdb/Cargo.toml

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# -*- eval: (cargo-minor-mode 1) -*-
2+
3+
[package]
4+
name = "influxdb"
5+
version = "0.0.6"
6+
authors = ["Gero Gerke <11deutron11@gmail.com>"]
7+
edition = "2018"
8+
description = "InfluxDB Driver for Rust"
9+
keywords = ["influxdb", "database", "influx"]
10+
license = "MIT"
11+
readme = "README.md"
12+
include = ["src/**/*", "tests/**/*", "Cargo.toml", "LICENSE"]
13+
repository = "https://github.com/Empty2k12/influxdb-rust"
14+
15+
[badges]
16+
travis-ci = { repository = "Empty2k12/influxdb-rust", branch = "master" }
17+
18+
[dependencies]
19+
chrono = { version = "0.4.10", features = ["serde"] }
20+
failure = "0.1.6"
21+
futures = "0.3.4"
22+
influxdb_derive = { version = "0.0.1", optional = true }
23+
reqwest = { version = "0.10.1", features = ["json"] }
24+
serde = { version = "1.0.104", features = ["derive"], optional = true }
25+
serde_json = { version = "1.0.46", optional = true }
26+
regex = "1.3.4"
27+
lazy_static = "1.4.0"
28+
29+
[features]
30+
use-serde = ["serde", "serde_json"]
31+
default = ["use-serde"]
32+
derive = ["influxdb_derive"]
33+
34+
[dev-dependencies]
35+
tokio = { version = "0.2.11", features = ["macros"] }

‎influxdb/LICENSE

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../LICENSE

‎influxdb/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../README.md

‎src/client/mod.rs ‎influxdb/src/client/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -162,11 +162,13 @@ impl Client {
162162
///
163163
/// ```rust,no_run
164164
/// use influxdb::{Client, Query, Timestamp};
165+
/// use influxdb::InfluxDbWriteable;
165166
///
166167
/// # #[tokio::main]
167168
/// # async fn main() -> Result<(), failure::Error> {
168169
/// let client = Client::new("http://localhost:8086", "test");
169-
/// let query = Query::write_query(Timestamp::Now, "weather")
170+
/// let query = Timestamp::Now
171+
/// .into_query("weather")
170172
/// .add_field("temperature", 82);
171173
/// let results = client.query(&query).await?;
172174
/// # Ok(())

‎src/error.rs ‎influxdb/src/error.rs

File renamed without changes.

‎src/lib.rs ‎influxdb/src/lib.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,12 @@
1010
//! - Optional Serde Support for Deserialization
1111
//! - Running multiple queries in one request (e.g. `SELECT * FROM weather_berlin; SELECT * FROM weather_london`)
1212
//! - Authenticated and Unauthenticated Connections
13-
//! - Optional conversion between `Timestamp` and `Chrono::DateTime<Utc>` via `chrono_timestamps` compilation feature
1413
//! - `async`/`await` support
14+
//! - `#[derive(InfluxDbWriteable)]` Derive Macro for Writing / Reading into Structs
1515
//!
1616
//! ## Planned Features
1717
//!
1818
//! - Read Query Builder instead of supplying raw queries
19-
//! - `#[derive(InfluxDbReadable)]` and `#[derive(InfluxDbWriteable)]` proc macros
2019
//!
2120
//! # Quickstart
2221
//!
@@ -30,6 +29,7 @@
3029
//!
3130
//! ```rust,no_run
3231
//! use influxdb::{Client, Query, Timestamp};
32+
//! use influxdb::InfluxDbWriteable;
3333
//!
3434
//! # #[tokio::main]
3535
//! # async fn main() {
@@ -40,7 +40,7 @@
4040
//! // Let's write something to InfluxDB. First we're creating a
4141
//! // WriteQuery to write some data.
4242
//! // This creates a query which writes a new measurement into a series called `weather`
43-
//! let write_query = Query::write_query(Timestamp::Now, "weather")
43+
//! let write_query = Timestamp::Now.into_query("weather")
4444
//! .add_field("temperature", 82);
4545
//!
4646
//! // Submit the query to InfluxDB.
@@ -83,7 +83,7 @@ pub use error::Error;
8383
pub use query::{
8484
read_query::ReadQuery,
8585
write_query::{Type, WriteQuery},
86-
Query, QueryType, QueryTypes, Timestamp, ValidQuery,
86+
InfluxDbWriteable, Query, QueryType, QueryTypes, Timestamp, ValidQuery,
8787
};
8888

8989
#[cfg(feature = "use-serde")]
File renamed without changes.

‎src/query/line_proto_term.rs ‎influxdb/src/query/line_proto_term.rs

+42-5
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ lazy_static! {
88
pub static ref COMMAS_SPACES: Regex = Regex::new("[, ]").unwrap();
99
pub static ref COMMAS_SPACES_EQUALS: Regex = Regex::new("[, =]").unwrap();
1010
pub static ref QUOTES_SLASHES: Regex = Regex::new(r#"["\\]"#).unwrap();
11+
pub static ref SLASHES: Regex = Regex::new(r#"(\\|,| |=|")"#).unwrap();
1112
}
1213

1314
pub enum LineProtoTerm<'a> {
1415
Measurement(&'a str), // escape commas, spaces
1516
TagKey(&'a str), // escape commas, equals, spaces
16-
TagValue(&'a str), // escape commas, equals, spaces
17+
TagValue(&'a Type), // escape commas, equals, spaces
1718
FieldKey(&'a str), // escape commas, equals, spaces
1819
FieldValue(&'a Type), // escape quotes, backslashes + quote
1920
}
@@ -23,8 +24,9 @@ impl LineProtoTerm<'_> {
2324
use LineProtoTerm::*;
2425
match self {
2526
Measurement(x) => Self::escape_any(x, &*COMMAS_SPACES),
26-
TagKey(x) | TagValue(x) | FieldKey(x) => Self::escape_any(x, &*COMMAS_SPACES_EQUALS),
27+
TagKey(x) | FieldKey(x) => Self::escape_any(x, &*COMMAS_SPACES_EQUALS),
2728
FieldValue(x) => Self::escape_field_value(x),
29+
TagValue(x) => Self::escape_tag_value(x),
2830
}
2931
}
3032

@@ -42,7 +44,25 @@ impl LineProtoTerm<'_> {
4244
Float(v) => v.to_string(),
4345
SignedInteger(v) => format!("{}i", v),
4446
UnsignedInteger(v) => format!("{}i", v),
45-
Text(v) => format!("\"{}\"", Self::escape_any(v, &*QUOTES_SLASHES)),
47+
Text(v) => format!(r#""{}""#, Self::escape_any(v, &*SLASHES)),
48+
}
49+
}
50+
51+
fn escape_tag_value(v: &Type) -> String {
52+
use Type::*;
53+
match v {
54+
Boolean(v) => {
55+
if *v {
56+
"true"
57+
} else {
58+
"false"
59+
}
60+
}
61+
.to_string(),
62+
Float(v) => format!(r#""{}""#, v.to_string()),
63+
SignedInteger(v) => format!(r#""{}""#, v),
64+
UnsignedInteger(v) => format!(r#""{}""#, v),
65+
Text(v) => format!(r#""{}""#, Self::escape_any(v, &*SLASHES)),
4666
}
4767
}
4868

@@ -58,6 +78,23 @@ mod test {
5878

5979
#[test]
6080
fn test() {
81+
assert_eq!(
82+
TagValue(&Type::Text("this is my special string".into())).escape(),
83+
r#""this\ is\ my\ special\ string""#
84+
);
85+
assert_eq!(
86+
TagValue(&Type::Text("a tag w=i th == tons of escapes".into())).escape(),
87+
r#""a\ tag\ w\=i\ th\ \=\=\ tons\ of\ escapes""#
88+
);
89+
assert_eq!(
90+
TagValue(&Type::Text("no_escapes".into())).escape(),
91+
r#""no_escapes""#
92+
);
93+
assert_eq!(
94+
TagValue(&Type::Text("some,commas,here".into())).escape(),
95+
r#""some\,commas\,here""#
96+
);
97+
6198
assert_eq!(Measurement(r#"wea", ther"#).escape(), r#"wea"\,\ ther"#);
6299
assert_eq!(TagKey(r#"locat\ ,=ion"#).escape(), r#"locat\\ \,\=ion"#);
63100

@@ -75,14 +112,14 @@ mod test {
75112
assert_eq!(FieldValue(&Type::Text("\"".into())).escape(), r#""\"""#);
76113
assert_eq!(
77114
FieldValue(&Type::Text(r#"locat"\ ,=ion"#.into())).escape(),
78-
r#""locat\"\\ ,=ion""#
115+
r#""locat\"\\\ \,\=ion""#
79116
);
80117
}
81118

82119
#[test]
83120
fn test_empty_tag_value() {
84121
// InfluxDB doesn't support empty tag values. But that's a job
85122
// of a calling site to validate an entire write request.
86-
assert_eq!(TagValue("").escape(), "");
123+
assert_eq!(TagValue(&Type::Text("".into())).escape(), r#""""#);
87124
}
88125
}

0 commit comments

Comments
 (0)
Please sign in to comment.