From 9cd527a297c7bb3f5b2243d017761284861e2ba6 Mon Sep 17 00:00:00 2001 From: Julien Enoch Date: Tue, 17 Nov 2020 15:43:03 +0100 Subject: [PATCH 1/9] Fix deserialization of Series in case of no values (#75) --- influxdb/src/integrations/serde_integration/de.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/influxdb/src/integrations/serde_integration/de.rs b/influxdb/src/integrations/serde_integration/de.rs index fd9bf99..cb6106d 100644 --- a/influxdb/src/integrations/serde_integration/de.rs +++ b/influxdb/src/integrations/serde_integration/de.rs @@ -80,7 +80,8 @@ where } } let name = name.ok_or_else(|| Error::missing_field("name"))?; - let values = values.ok_or_else(|| Error::missing_field("values"))?; + let values = values.unwrap_or_default(); + Ok(Series { name, values }) } } From 28870030b9665414426348d5baf55a5c0f23e27a Mon Sep 17 00:00:00 2001 From: msrd0 Date: Mon, 14 Dec 2020 21:32:34 +0000 Subject: [PATCH 2/9] CI: test against MSRV (#77) * ci: test against msrv * MSRV: bump to 1.41 due to subtle dependency * MSRV: bump to 1.42 due to http-types dependency * MSRV: bump to 1.45 ... --- .github/workflows/rust.yml | 29 +++++++++-------------------- README.md | 4 ++-- README.tpl | 4 ++-- influxdb_derive/src/lib.rs | 2 -- 4 files changed, 13 insertions(+), 26 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 00a7eef..f353041 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -12,23 +12,18 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - toolchain: nightly - override: true + - uses: dtolnay/rust-toolchain@nightly - run: bash ./auxiliary/update_cargo-readme.sh - run: bash ./auxiliary/check_readme_consistency.sh style: name: Style Checks (stable/ubuntu-latest) runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - uses: hecrj/setup-rust-action@v1 + - uses: actions/checkout@v1 + - uses: dtolnay/rust-toolchain@nightly with: components: "rustfmt,clippy" - - uses: actions/checkout@v1 - name: Check code formatting run: cargo fmt --all -- --check - name: Check Clippy lints @@ -39,14 +34,14 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - rust_release: [nightly, stable] + rust_release: [1.45, stable, nightly] os: [ubuntu-latest, windows-latest, macOS-latest] steps: - - uses: actions/checkout@master - - uses: hecrj/setup-rust-action@v1 + - uses: actions/checkout@v1 + - uses: dtolnay/rust-toolchain@master with: - rust-version: ${{ matrix.rust_release }} + toolchain: ${{ matrix.rust_release }} - name: Build run: cargo build --verbose @@ -71,11 +66,5 @@ jobs: steps: - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - toolchain: nightly - override: true - - uses: actions-rs/cargo@v1 - with: - command: test - args: --package influxdb --package influxdb_derive --all-features --no-fail-fast \ No newline at end of file + - uses: dtolnay/rust-toolchain@nightly + - run: cargo test --package influxdb --package influxdb_derive --all-features --no-fail-fast diff --git a/README.md b/README.md index 4c2c669..73c3ace 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,8 @@ Build with Rust - - Minimum Rust Version + + Minimum Rust Version

diff --git a/README.tpl b/README.tpl index 950b79b..e0160b3 100644 --- a/README.tpl +++ b/README.tpl @@ -22,8 +22,8 @@ Build with Rust - - Minimum Rust Version + + Minimum Rust Version

diff --git a/influxdb_derive/src/lib.rs b/influxdb_derive/src/lib.rs index 2bfe464..6c4b02d 100644 --- a/influxdb_derive/src/lib.rs +++ b/influxdb_derive/src/lib.rs @@ -1,5 +1,3 @@ -extern crate proc_macro; - use proc_macro::TokenStream; use proc_macro2::TokenStream as TokenStream2; use quote::quote; From f176db5ef3d08d63ee51e2c2c6c87f52d883b9e8 Mon Sep 17 00:00:00 2001 From: msrd0 Date: Mon, 14 Dec 2020 22:04:48 +0000 Subject: [PATCH 3/9] ci: enable code coverage with tarpaulin uploading to gh-pages (#78) --- .github/workflows/rust.yml | 95 +++++++++++++++++++++++++++++++++++++- README.md | 3 ++ README.tpl | 3 ++ 3 files changed, 100 insertions(+), 1 deletion(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index f353041..a615602 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -66,5 +66,98 @@ jobs: steps: - uses: actions/checkout@v1 - - uses: dtolnay/rust-toolchain@nightly + - uses: dtolnay/rust-toolchain@stable - run: cargo test --package influxdb --package influxdb_derive --all-features --no-fail-fast + + coverage: + name: Code Coverage (stable/ubuntu-20.04) + runs-on: ubuntu-20.04 + services: + influxdb: + image: influxdb + ports: + - 8086:8086 + authed_influxdb: + image: influxdb + ports: + - 9086:8086 + env: + INFLUXDB_HTTP_AUTH_ENABLED: true + INFLUXDB_ADMIN_USER: admin + INFLUXDB_ADMIN_PASSWORD: password + INFLUXDB_USER: nopriv_user + INFLUXDB_USER_PASSWORD: password + + steps: + - uses: actions/checkout@v2 + - uses: dtolnay/rust-toolchain@stable + + - name: Get Rust Version + id: rust-version + run: echo "::set-output name=VERSION::$(cargo -V | head -n1 | awk '{print $2}')" + + - name: Get Tarpaulin Version + id: tarpaulin-version + run: echo "::set-output name=VERSION::$(wget -qO- 'https://api.github.com/repos/xd009642/tarpaulin/releases/latest' | jq -r '.tag_name')" + + - uses: actions/cache@v2 + with: + path: | + ~/.cargo/bin + ~/.cargo/git + ~/.cargo/registry + target + key: ${{ runner.os }}-cargo-${{ steps.rust-version.outputs.VERSION }}-tarpaulin-${{ steps.tarpaulin-version.outputs.VERSION }} }} + + - name: Install Tarpaulin + run: | + ls -lh ~/.cargo || true + ls -lh ~/.cargo/bin || true + cargo install cargo-tarpaulin --version ${{ steps.tarpaulin-version.outputs.VERSION }} + + - name: Run Tarpaulin coverage tests + run: | + cargo tarpaulin -v \ + --target-dir target/tarpaulin \ + --workspace \ + --all-features \ + --exclude-files 'derive/*' \ + --exclude-files 'target/*' \ + --ignore-panics --ignore-tests \ + --out Html --out Json + env: + RUST_BACKTRACE: 1 + RUST_LOG: info + + - uses: actions/upload-artifact@v2 + with: + name: tarpaulin-report + path: | + tarpaulin-report.json + tarpaulin-report.html + + pages: + runs-on: ubuntu-20.04 + needs: + - coverage + if: github.ref == 'refs/heads/master' + steps: + - uses: actions/checkout@v2 + with: + ref: gh-pages + + - uses: actions/download-artifact@v2 + with: + name: tarpaulin-report + + - run: | + coverage=$(jq '.files | { covered: map(.covered) | add, coverable: map(.coverable) | add } | .covered / .coverable * 10000 | round | . / 100' tarpaulin-report.json) + color=$([[ $coverage < 80 ]] && printf yellow || printf brightgreen) + wget -qO coverage.svg "https://img.shields.io/badge/coverage-$coverage%25-$color" + + git add coverage.svg tarpaulin-report.html + git status + + - uses: stefanzweifel/git-auto-commit-action@v4 + with: + commit_message: "GitHub Pages for ${{ github.sha }}" diff --git a/README.md b/README.md index 73c3ace..452997a 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,9 @@ Build Status + + Coverage Report + Documentation Status diff --git a/README.tpl b/README.tpl index e0160b3..0647cd3 100644 --- a/README.tpl +++ b/README.tpl @@ -16,6 +16,9 @@ Build Status + + Coverage Report + Documentation Status From 5ed13476ca5e2dafb6f02c787a9bc30b05961dfd Mon Sep 17 00:00:00 2001 From: msrd0 Date: Tue, 15 Dec 2020 13:45:23 +0000 Subject: [PATCH 4/9] CI: make tarpaulin ignore test code (#79) * tarpaulin does not recognize async_std::test or tokio::test, so we'll ignore them manually * CI: fix weird caching issue * new attempt at tarpaulin ignoring tests * tarpaulin ist dumm --- .github/workflows/rust.yml | 21 ++++++++++----------- influxdb/tests/derive_integration_tests.rs | 2 ++ influxdb/tests/integration_tests.rs | 13 +++++++++++++ influxdb/tests/utilities.rs | 6 ++++++ 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index a615602..4687b57 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -103,7 +103,7 @@ jobs: - uses: actions/cache@v2 with: path: | - ~/.cargo/bin + ~/.cargo/bin/cargo-tarpaulin ~/.cargo/git ~/.cargo/registry target @@ -111,20 +111,19 @@ jobs: - name: Install Tarpaulin run: | - ls -lh ~/.cargo || true - ls -lh ~/.cargo/bin || true - cargo install cargo-tarpaulin --version ${{ steps.tarpaulin-version.outputs.VERSION }} + ls -lh ~/.cargo/bin + test -e ~/.cargo/bin/cargo-tarpaulin || cargo install cargo-tarpaulin --version ${{ steps.tarpaulin-version.outputs.VERSION }} - name: Run Tarpaulin coverage tests run: | cargo tarpaulin -v \ - --target-dir target/tarpaulin \ - --workspace \ - --all-features \ - --exclude-files 'derive/*' \ - --exclude-files 'target/*' \ - --ignore-panics --ignore-tests \ - --out Html --out Json + --target-dir target/tarpaulin \ + --workspace \ + --all-features \ + --exclude-files 'derive/*' \ + --exclude-files 'target/*' \ + --ignore-panics --ignore-tests \ + --out Html --out Json env: RUST_BACKTRACE: 1 RUST_LOG: info diff --git a/influxdb/tests/derive_integration_tests.rs b/influxdb/tests/derive_integration_tests.rs index 9c136b2..4e507c5 100644 --- a/influxdb/tests/derive_integration_tests.rs +++ b/influxdb/tests/derive_integration_tests.rs @@ -44,6 +44,7 @@ fn test_build_query() { /// /// This integration tests that writing data and retrieving the data again is working #[async_std::test] +#[cfg(not(tarpaulin_include))] async fn test_derive_simple_write() { const TEST_NAME: &str = "test_derive_simple_write"; @@ -73,6 +74,7 @@ async fn test_derive_simple_write() { #[cfg(feature = "derive")] #[cfg(feature = "use-serde")] #[async_std::test] +#[cfg(not(tarpaulin_include))] async fn test_write_and_read_option() { const TEST_NAME: &str = "test_write_and_read_option"; diff --git a/influxdb/tests/integration_tests.rs b/influxdb/tests/integration_tests.rs index 47bb1d1..4dd7020 100644 --- a/influxdb/tests/integration_tests.rs +++ b/influxdb/tests/integration_tests.rs @@ -13,6 +13,7 @@ use influxdb::{Client, Error, Query, Timestamp}; /// /// This test case tests whether the InfluxDB server can be connected to and gathers info about it - tested with async_std #[async_std::test] +#[cfg(not(tarpaulin_include))] async fn test_ping_influx_db_async_std() { let client = create_client("notusedhere"); let result = client.ping().await; @@ -29,6 +30,7 @@ async fn test_ping_influx_db_async_std() { /// /// This test case tests whether the InfluxDB server can be connected to and gathers info about it * tested with tokio #[tokio::test] +#[cfg(not(tarpaulin_include))] async fn test_ping_influx_db_tokio() { let client = create_client("notusedhere"); let result = client.ping().await; @@ -45,6 +47,7 @@ async fn test_ping_influx_db_tokio() { /// /// This test case tests connection error #[async_std::test] +#[cfg(not(tarpaulin_include))] async fn test_connection_error() { let test_name = "test_connection_error"; let client = @@ -65,6 +68,7 @@ async fn test_connection_error() { /// /// This test case tests the Authentication #[async_std::test] +#[cfg(not(tarpaulin_include))] async fn test_authed_write_and_read() { const TEST_NAME: &str = "test_authed_write_and_read"; @@ -112,6 +116,7 @@ async fn test_authed_write_and_read() { /// /// This test case tests the Authentication #[async_std::test] +#[cfg(not(tarpaulin_include))] async fn test_wrong_authed_write_and_read() { const TEST_NAME: &str = "test_wrong_authed_write_and_read"; @@ -181,6 +186,7 @@ async fn test_wrong_authed_write_and_read() { /// /// This test case tests the Authentication #[async_std::test] +#[cfg(not(tarpaulin_include))] async fn test_non_authed_write_and_read() { const TEST_NAME: &str = "test_non_authed_write_and_read"; @@ -235,6 +241,7 @@ async fn test_non_authed_write_and_read() { /// /// This integration tests that writing data and retrieving the data again is working #[async_std::test] +#[cfg(not(tarpaulin_include))] async fn test_write_and_read_field() { const TEST_NAME: &str = "test_write_field"; @@ -268,6 +275,7 @@ async fn test_write_and_read_field() { /// This integration tests that writing data and retrieving the data again is working #[async_std::test] #[cfg(feature = "use-serde")] +#[cfg(not(tarpaulin_include))] async fn test_write_and_read_option() { use serde::Deserialize; @@ -329,6 +337,7 @@ async fn test_write_and_read_option() { /// is equal to the data which was written to the database #[async_std::test] #[cfg(feature = "use-serde")] +#[cfg(not(tarpaulin_include))] async fn test_json_query() { use serde::Deserialize; @@ -380,6 +389,7 @@ async fn test_json_query() { // deserialize_next_tagged into a tags struct #[async_std::test] #[cfg(feature = "use-serde")] +#[cfg(not(tarpaulin_include))] async fn test_json_query_tagged() { use serde::Deserialize; @@ -444,6 +454,7 @@ async fn test_json_query_tagged() { /// (tested with tokio) #[tokio::test] #[cfg(feature = "use-serde")] +#[cfg(not(tarpaulin_include))] async fn test_json_query_vec() { use serde::Deserialize; @@ -494,6 +505,7 @@ async fn test_json_query_vec() { /// This integration test tests whether using the wrong query method fails building the query #[async_std::test] #[cfg(feature = "use-serde")] +#[cfg(not(tarpaulin_include))] async fn test_serde_multi_query() { use serde::Deserialize; @@ -570,6 +582,7 @@ async fn test_serde_multi_query() { /// This integration test tests whether using the wrong query method fails building the query #[async_std::test] #[cfg(feature = "use-serde")] +#[cfg(not(tarpaulin_include))] async fn test_wrong_query_errors() { let client = create_client("test_name"); let result = client diff --git a/influxdb/tests/utilities.rs b/influxdb/tests/utilities.rs index 11a498a..92d4e0e 100644 --- a/influxdb/tests/utilities.rs +++ b/influxdb/tests/utilities.rs @@ -3,14 +3,17 @@ use influxdb::{Client, Error, Query}; use std::panic::{AssertUnwindSafe, UnwindSafe}; #[allow(dead_code)] +#[cfg(not(tarpaulin_include))] pub fn assert_result_err(result: &Result) { result.as_ref().expect_err("assert_result_err failed"); } +#[cfg(not(tarpaulin_include))] pub fn assert_result_ok(result: &Result) { result.as_ref().expect("assert_result_ok failed"); } +#[cfg(not(tarpaulin_include))] pub fn create_client(db_name: T) -> Client where T: Into, @@ -18,6 +21,7 @@ where Client::new("http://localhost:8086", db_name) } +#[cfg(not(tarpaulin_include))] pub async fn create_db(name: T) -> Result where T: Into, @@ -29,6 +33,7 @@ where .await } +#[cfg(not(tarpaulin_include))] pub async fn delete_db(name: T) -> Result where T: Into, @@ -40,6 +45,7 @@ where .await } +#[cfg(not(tarpaulin_include))] pub async fn run_test(test_fn: F, teardown: T) where F: FnOnce() -> Fut1 + UnwindSafe, From 614316a7aeb62c76c389efe3fc9dd4a83e38480e Mon Sep 17 00:00:00 2001 From: Blas Rodriguez Irizar Date: Thu, 17 Dec 2020 16:05:46 +0100 Subject: [PATCH 5/9] implement #[influxdb(tag)] and #[influxdb(ignore)] (#81) * first failed attempt to implement #[influx_aware()] * change influx_aware to influxdb * remove clone * remove references to #[tag] * add missing field * fix test_write_and_read_option * handle ignore field in deserialized struct --- README.md | 2 +- benches/client.rs | 2 +- influxdb/src/lib.rs | 2 +- influxdb/tests/derive_integration_tests.rs | 30 +++++++---- influxdb_derive/src/lib.rs | 2 +- influxdb_derive/src/writeable.rs | 58 ++++++++++++++++++++-- 6 files changed, 77 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 452997a..0e3f033 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ async fn main() { struct WeatherReading { time: DateTime, humidity: i32, - #[tag] wind_direction: String, + #[influxdb(tag)] wind_direction: String, } // Let's write some data into a measurement called `weather` diff --git a/benches/client.rs b/benches/client.rs index a94c987..2b8ca5d 100644 --- a/benches/client.rs +++ b/benches/client.rs @@ -11,7 +11,7 @@ use tokio::sync::Semaphore; struct WeatherReading { time: DateTime, humidity: i32, - #[tag] + #[influxdb(tag)] wind_direction: String, } diff --git a/influxdb/src/lib.rs b/influxdb/src/lib.rs index 2e5eebb..5aec3a4 100644 --- a/influxdb/src/lib.rs +++ b/influxdb/src/lib.rs @@ -39,7 +39,7 @@ //! struct WeatherReading { //! time: DateTime, //! humidity: i32, -//! #[tag] wind_direction: String, +//! #[influxdb(tag)] wind_direction: String, //! } //! //! // Let's write some data into a measurement called `weather` diff --git a/influxdb/tests/derive_integration_tests.rs b/influxdb/tests/derive_integration_tests.rs index 4e507c5..463fed9 100644 --- a/influxdb/tests/derive_integration_tests.rs +++ b/influxdb/tests/derive_integration_tests.rs @@ -14,11 +14,20 @@ use utilities::{assert_result_ok, create_client, create_db, delete_db, run_test} #[derive(Debug, PartialEq)] #[cfg_attr(feature = "derive", derive(InfluxDbWriteable))] -#[cfg_attr(feature = "use-serde", derive(Deserialize))] struct WeatherReading { time: DateTime, + #[influxdb(ignore)] humidity: i32, - #[tag] + pressure: i32, + #[influxdb(tag)] + wind_strength: Option, +} + +#[derive(Debug)] +#[cfg_attr(feature = "use-serde", derive(Deserialize))] +struct WeatherReadingWithoutIgnored { + time: DateTime, + pressure: i32, wind_strength: Option, } @@ -27,15 +36,14 @@ fn test_build_query() { let weather_reading = WeatherReading { time: Timestamp::Hours(1).into(), humidity: 30, + pressure: 100, wind_strength: Some(5), }; - let query = weather_reading - .into_query("weather_reading") - .build() - .unwrap(); + let query = weather_reading.into_query("weather_reading"); + let query = query.build().unwrap(); assert_eq!( query.get(), - "weather_reading,wind_strength=5 humidity=30i 3600000000000" + "weather_reading,wind_strength=5 pressure=100i 3600000000000" ); } @@ -56,6 +64,7 @@ async fn test_derive_simple_write() { time: Timestamp::Nanoseconds(0).into(), humidity: 30, wind_strength: Some(5), + pressure: 100, }; let query = weather_reading.into_query("weather_reading"); let result = client.query(&query).await; @@ -86,20 +95,21 @@ async fn test_write_and_read_option() { time: Timestamp::Hours(11).into(), humidity: 30, wind_strength: None, + pressure: 100, }; let write_result = client .query(&weather_reading.into_query("weather_reading".to_string())) .await; assert_result_ok(&write_result); let query = - Query::raw_read_query("SELECT time, humidity, wind_strength FROM weather_reading"); + Query::raw_read_query("SELECT time, pressure, wind_strength FROM weather_reading"); let result = client.json_query(query).await.and_then(|mut db_result| { println!("{:?}", db_result); - db_result.deserialize_next::() + db_result.deserialize_next::() }); assert_result_ok(&result); let result = result.unwrap(); - assert_eq!(result.series[0].values[0].humidity, 30); + assert_eq!(result.series[0].values[0].pressure, 100); assert_eq!(result.series[0].values[0].wind_strength, None); }, || async move { diff --git a/influxdb_derive/src/lib.rs b/influxdb_derive/src/lib.rs index 6c4b02d..a6bbba8 100644 --- a/influxdb_derive/src/lib.rs +++ b/influxdb_derive/src/lib.rs @@ -9,7 +9,7 @@ fn krate() -> TokenStream2 { quote!(::influxdb) } -#[proc_macro_derive(InfluxDbWriteable, attributes(tag))] +#[proc_macro_derive(InfluxDbWriteable, attributes(influxdb))] pub fn derive_writeable(tokens: TokenStream) -> TokenStream { expand_writeable(tokens) } diff --git a/influxdb_derive/src/writeable.rs b/influxdb_derive/src/writeable.rs index f42c333..04a7bb0 100644 --- a/influxdb_derive/src/writeable.rs +++ b/influxdb_derive/src/writeable.rs @@ -1,32 +1,79 @@ use proc_macro::TokenStream; -use proc_macro2::TokenStream as TokenStream2; +use proc_macro2::{TokenStream as TokenStream2, TokenTree}; use quote::{format_ident, quote}; use syn::{parse_macro_input, Field, Fields, Ident, ItemStruct}; +#[derive(Debug)] struct WriteableField { ident: Ident, is_tag: bool, + is_ignore: bool, } impl From for WriteableField { fn from(field: Field) -> WriteableField { let ident = field.ident.expect("fields without ident are not supported"); - let is_tag = field.attrs.iter().any(|attr| { + + let check_influx_aware = |attr: &syn::Attribute| -> bool { attr.path .segments .iter() .last() .map(|seg| seg.ident.to_string()) .unwrap_or_default() - == "tag" + == "influxdb" + }; + + let check_for_attr = |token_tree, ident_cmp: &str| -> bool { + match token_tree { + TokenTree::Group(group) => group + .stream() + .into_iter() + .next() + .map(|token_tree| match token_tree { + TokenTree::Ident(ident) => ident == ident_cmp, + _ => false, + }) + .unwrap(), + _ => false, + } + }; + + let is_ignore = field.attrs.iter().any(|attr| { + if !check_influx_aware(attr) { + return false; + } + + attr.tokens + .clone() + .into_iter() + .next() + .map(|token_tree| check_for_attr(token_tree, "ignore")) + .unwrap() }); - WriteableField { ident, is_tag } + + let is_tag = field.attrs.iter().any(|attr| { + if !check_influx_aware(attr) { + return false; + } + attr.tokens + .clone() + .into_iter() + .next() + .map(|token_tree| check_for_attr(token_tree, "tag")) + .unwrap() + }); + + WriteableField { + ident, + is_tag, + is_ignore, + } } } pub fn expand_writeable(tokens: TokenStream) -> TokenStream { let krate = super::krate(); - let input = parse_macro_input!(tokens as ItemStruct); let ident = input.ident; let generics = input.generics; @@ -38,6 +85,7 @@ pub fn expand_writeable(tokens: TokenStream) -> TokenStream { .named .into_iter() .map(WriteableField::from) + .filter(|field| !field.is_ignore) .filter(|field| field.ident.to_string() != time_field.to_string()) .map(|field| { let ident = field.ident; From 7931c8958557dc45a9374963c7e81f3cfd0fd42b Mon Sep 17 00:00:00 2001 From: Rodolfo Stephano Castillo Mateluna Date: Sun, 27 Dec 2020 15:46:15 -0300 Subject: [PATCH 6/9] Assertion should consider case-insensitive keywords (#83) --- influxdb/src/integrations/serde_integration/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/influxdb/src/integrations/serde_integration/mod.rs b/influxdb/src/integrations/serde_integration/mod.rs index 7168469..3a734af 100644 --- a/influxdb/src/integrations/serde_integration/mod.rs +++ b/influxdb/src/integrations/serde_integration/mod.rs @@ -129,8 +129,9 @@ impl Client { })?; let read_query = query.get(); + let read_query_lower = read_query.to_lowercase(); - if !read_query.contains("SELECT") && !read_query.contains("SHOW") { + if !read_query_lower.contains("select") && !read_query_lower.contains("show") { let error = Error::InvalidQueryError { error: String::from( "Only SELECT and SHOW queries supported with JSON deserialization", From 1950876edc16d27e90bed34ba44d79a7999f4007 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Sat, 6 Mar 2021 23:19:35 +0800 Subject: [PATCH 7/9] Batch write support (#87) * (feat) add support for batching writes * (refactor) hold precision in WriteQuery type * (test) fix test for new query type enum * (test) add test for batch query * (chore) stick to influxdb 1.8 for integration test * (fix) fix lint warnings --- .github/workflows/rust.yml | 34 +++++++------- influxdb/src/client/mod.rs | 11 ++--- .../src/integrations/serde_integration/de.rs | 8 ++-- influxdb/src/lib.rs | 2 +- influxdb/src/query/mod.rs | 27 ++--------- influxdb/src/query/write_query.rs | 47 ++++++++++++++++++- influxdb/tests/integration_tests.rs | 24 +++++----- 7 files changed, 89 insertions(+), 64 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 4687b57..7e8a994 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -50,11 +50,11 @@ jobs: runs-on: ubuntu-latest services: influxdb: - image: influxdb + image: influxdb:1.8 ports: - 8086:8086 authed_influxdb: - image: influxdb + image: influxdb:1.8 ports: - 9086:8086 env: @@ -68,17 +68,17 @@ jobs: - uses: actions/checkout@v1 - uses: dtolnay/rust-toolchain@stable - run: cargo test --package influxdb --package influxdb_derive --all-features --no-fail-fast - + coverage: name: Code Coverage (stable/ubuntu-20.04) runs-on: ubuntu-20.04 services: influxdb: - image: influxdb + image: influxdb:1.8 ports: - 8086:8086 authed_influxdb: - image: influxdb + image: influxdb:1.8 ports: - 9086:8086 env: @@ -87,19 +87,19 @@ jobs: INFLUXDB_ADMIN_PASSWORD: password INFLUXDB_USER: nopriv_user INFLUXDB_USER_PASSWORD: password - + steps: - uses: actions/checkout@v2 - uses: dtolnay/rust-toolchain@stable - + - name: Get Rust Version id: rust-version run: echo "::set-output name=VERSION::$(cargo -V | head -n1 | awk '{print $2}')" - + - name: Get Tarpaulin Version id: tarpaulin-version run: echo "::set-output name=VERSION::$(wget -qO- 'https://api.github.com/repos/xd009642/tarpaulin/releases/latest' | jq -r '.tag_name')" - + - uses: actions/cache@v2 with: path: | @@ -108,12 +108,12 @@ jobs: ~/.cargo/registry target key: ${{ runner.os }}-cargo-${{ steps.rust-version.outputs.VERSION }}-tarpaulin-${{ steps.tarpaulin-version.outputs.VERSION }} }} - + - name: Install Tarpaulin run: | ls -lh ~/.cargo/bin test -e ~/.cargo/bin/cargo-tarpaulin || cargo install cargo-tarpaulin --version ${{ steps.tarpaulin-version.outputs.VERSION }} - + - name: Run Tarpaulin coverage tests run: | cargo tarpaulin -v \ @@ -127,14 +127,14 @@ jobs: env: RUST_BACKTRACE: 1 RUST_LOG: info - + - uses: actions/upload-artifact@v2 with: name: tarpaulin-report path: | tarpaulin-report.json tarpaulin-report.html - + pages: runs-on: ubuntu-20.04 needs: @@ -144,19 +144,19 @@ jobs: - uses: actions/checkout@v2 with: ref: gh-pages - + - uses: actions/download-artifact@v2 with: name: tarpaulin-report - + - run: | coverage=$(jq '.files | { covered: map(.covered) | add, coverable: map(.coverable) | add } | .covered / .coverable * 10000 | round | . / 100' tarpaulin-report.json) color=$([[ $coverage < 80 ]] && printf yellow || printf brightgreen) wget -qO coverage.svg "https://img.shields.io/badge/coverage-$coverage%25-$color" - + git add coverage.svg tarpaulin-report.html git status - + - uses: stefanzweifel/git-auto-commit-action@v4 with: commit_message: "GitHub Pages for ${{ github.sha }}" diff --git a/influxdb/src/client/mod.rs b/influxdb/src/client/mod.rs index 5874978..468b0ae 100644 --- a/influxdb/src/client/mod.rs +++ b/influxdb/src/client/mod.rs @@ -18,7 +18,7 @@ use futures::prelude::*; use surf::{self, Client as SurfClient, StatusCode}; -use crate::query::QueryTypes; +use crate::query::QueryType; use crate::Error; use crate::Query; use std::collections::HashMap; @@ -159,14 +159,13 @@ impl Client { pub async fn query<'q, Q>(&self, q: &'q Q) -> Result where Q: Query, - &'q Q: Into>, { let query = q.build().map_err(|err| Error::InvalidQueryError { error: err.to_string(), })?; - let request_builder = match q.into() { - QueryTypes::Read(_) => { + let request_builder = match q.get_type() { + QueryType::ReadQuery => { let read_query = query.get(); let url = &format!("{}/query", &self.url); let mut parameters = self.parameters.as_ref().clone(); @@ -178,10 +177,10 @@ impl Client { self.client.post(url).query(¶meters) } } - QueryTypes::Write(write_query) => { + QueryType::WriteQuery(precision) => { let url = &format!("{}/write", &self.url); let mut parameters = self.parameters.as_ref().clone(); - parameters.insert("precision", write_query.get_precision()); + parameters.insert("precision", precision); self.client.post(url).body(query.get()).query(¶meters) } diff --git a/influxdb/src/integrations/serde_integration/de.rs b/influxdb/src/integrations/serde_integration/de.rs index cb6106d..82eb607 100644 --- a/influxdb/src/integrations/serde_integration/de.rs +++ b/influxdb/src/integrations/serde_integration/de.rs @@ -22,11 +22,11 @@ where Name, Columns, Values, - }; + } struct SeriesVisitor { _inner_type: PhantomData, - }; + } impl<'de, T> Visitor<'de> for SeriesVisitor where @@ -115,12 +115,12 @@ where Tags, Columns, Values, - }; + } struct SeriesVisitor { _tag_type: PhantomData, _value_type: PhantomData, - }; + } impl<'de, TAG, T> Visitor<'de> for SeriesVisitor where diff --git a/influxdb/src/lib.rs b/influxdb/src/lib.rs index 5aec3a4..350362e 100644 --- a/influxdb/src/lib.rs +++ b/influxdb/src/lib.rs @@ -82,7 +82,7 @@ pub use error::Error; pub use query::{ read_query::ReadQuery, write_query::{Type, WriteQuery}, - InfluxDbWriteable, Query, QueryType, QueryTypes, Timestamp, ValidQuery, + InfluxDbWriteable, Query, QueryType, Timestamp, ValidQuery, }; #[cfg(feature = "use-serde")] diff --git a/influxdb/src/query/mod.rs b/influxdb/src/query/mod.rs index 8fb0c0b..de08f19 100644 --- a/influxdb/src/query/mod.rs +++ b/influxdb/src/query/mod.rs @@ -55,9 +55,9 @@ impl fmt::Display for Timestamp { } } -impl Into> for Timestamp { - fn into(self) -> DateTime { - match self { +impl From for DateTime { + fn from(ts: Timestamp) -> DateTime { + match ts { Timestamp::Hours(h) => { let nanos = h * MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MILLIS_PER_SECOND * NANOS_PER_MILLI; @@ -93,24 +93,6 @@ where } } -/// Internal enum used to represent either type of query. -pub enum QueryTypes<'a> { - Read(&'a ReadQuery), - Write(&'a WriteQuery), -} - -impl<'a> From<&'a ReadQuery> for QueryTypes<'a> { - fn from(query: &'a ReadQuery) -> Self { - Self::Read(query) - } -} - -impl<'a> From<&'a WriteQuery> for QueryTypes<'a> { - fn from(query: &'a WriteQuery) -> Self { - Self::Write(query) - } -} - pub trait Query { /// Builds valid InfluxSQL which can be run against the Database. /// In case no fields have been specified, it will return an error, @@ -192,7 +174,8 @@ impl PartialEq<&str> for ValidQuery { #[derive(PartialEq, Debug)] pub enum QueryType { ReadQuery, - WriteQuery, + /// write query with precision + WriteQuery(String), } #[cfg(test)] diff --git a/influxdb/src/query/write_query.rs b/influxdb/src/query/write_query.rs index 51ea723..cc5fd0c 100644 --- a/influxdb/src/query/write_query.rs +++ b/influxdb/src/query/write_query.rs @@ -205,7 +205,29 @@ impl Query for WriteQuery { } fn get_type(&self) -> QueryType { - QueryType::WriteQuery + QueryType::WriteQuery(self.get_precision()) + } +} + +impl Query for Vec { + fn build(&self) -> Result { + let mut qlines = Vec::new(); + + for q in self { + let valid_query = q.build()?; + qlines.push(valid_query.0); + } + + Ok(ValidQuery(qlines.join("\n"))) + } + + fn get_type(&self) -> QueryType { + QueryType::WriteQuery( + self.get(0) + .map(|q| q.get_precision()) + // use "ms" as placeholder if query is empty + .unwrap_or_else(|| "ms".to_owned()), + ) } } @@ -296,7 +318,7 @@ mod tests { .add_tag("location", "us-midwest") .add_tag("season", "summer"); - assert_eq!(query.get_type(), QueryType::WriteQuery); + assert_eq!(query.get_type(), QueryType::WriteQuery("h".to_owned())); } #[test] @@ -318,4 +340,25 @@ mod tests { r#"wea\,\ ther=,location=us-midwest,loc\,\ \="ation=us\,\ \"mid\=west temperature=82i,"temp\=era\,t\ ure"="too\"\\\\hot",float=82 11"# ); } + + #[test] + fn test_batch() { + let q0 = Timestamp::Hours(11) + .into_query("weather") + .add_field("temperature", 82) + .add_tag("location", "us-midwest"); + + let q1 = Timestamp::Hours(12) + .into_query("weather") + .add_field("temperature", 65) + .add_tag("location", "us-midwest"); + + let query = vec![q0, q1].build(); + + assert_eq!( + query.unwrap().get(), + r#"weather,location=us-midwest temperature=82i 11 +weather,location=us-midwest temperature=65i 12"# + ); + } } diff --git a/influxdb/tests/integration_tests.rs b/influxdb/tests/integration_tests.rs index 4dd7020..e02a81c 100644 --- a/influxdb/tests/integration_tests.rs +++ b/influxdb/tests/integration_tests.rs @@ -57,10 +57,10 @@ async fn test_connection_error() { assert_result_err(&read_result); match read_result { Err(Error::ConnectionError { .. }) => {} - _ => panic!(format!( + _ => panic!( "Should cause a ConnectionError: {}", read_result.unwrap_err() - )), + ), } } @@ -139,10 +139,10 @@ async fn test_wrong_authed_write_and_read() { assert_result_err(&write_result); match write_result { Err(Error::AuthorizationError) => {} - _ => panic!(format!( + _ => panic!( "Should be an AuthorizationError: {}", write_result.unwrap_err() - )), + ), } let read_query = Query::raw_read_query("SELECT * FROM weather"); @@ -150,10 +150,10 @@ async fn test_wrong_authed_write_and_read() { assert_result_err(&read_result); match read_result { Err(Error::AuthorizationError) => {} - _ => panic!(format!( + _ => panic!( "Should be an AuthorizationError: {}", read_result.unwrap_err() - )), + ), } let client = Client::new("http://localhost:9086", TEST_NAME) @@ -163,10 +163,10 @@ async fn test_wrong_authed_write_and_read() { assert_result_err(&read_result); match read_result { Err(Error::AuthenticationError) => {} - _ => panic!(format!( + _ => panic!( "Should be an AuthenticationError: {}", read_result.unwrap_err() - )), + ), } }, || async move { @@ -207,10 +207,10 @@ async fn test_non_authed_write_and_read() { assert_result_err(&write_result); match write_result { Err(Error::AuthorizationError) => {} - _ => panic!(format!( + _ => panic!( "Should be an AuthorizationError: {}", write_result.unwrap_err() - )), + ), } let read_query = Query::raw_read_query("SELECT * FROM weather"); @@ -218,10 +218,10 @@ async fn test_non_authed_write_and_read() { assert_result_err(&read_result); match read_result { Err(Error::AuthorizationError) => {} - _ => panic!(format!( + _ => panic!( "Should be an AuthorizationError: {}", read_result.unwrap_err() - )), + ), } }, || async move { From 9a08144dd839042c4c4830ad44621f9e310ddac1 Mon Sep 17 00:00:00 2001 From: Julien Enoch Date: Mon, 8 Mar 2021 20:10:54 +0100 Subject: [PATCH 8/9] Add h1-client-rustls feature (#88) * Add h1-client-rustls feature * Update README part in lib.rs * Remove test of wasm-client feature (requires wasm-pack) * Replaced localhost with 127.0.0.1 in tests (workaround for Github actions) * Fix typo --- .github/workflows/rust.yml | 5 ++++- README.md | 26 ++++++++++++++++++++++++++ influxdb/Cargo.toml | 3 ++- influxdb/src/lib.rs | 26 ++++++++++++++++++++++++++ influxdb/tests/integration_tests.rs | 22 +++++++++++----------- influxdb/tests/utilities.rs | 2 +- 6 files changed, 70 insertions(+), 14 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 7e8a994..209fcae 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -48,6 +48,9 @@ jobs: integration_test: name: Integration Tests (stable/ubuntu-latest) runs-on: ubuntu-latest + strategy: + matrix: + http-backend: [curl-client, h1-client, h1-client-rustls, hyper-client] services: influxdb: image: influxdb:1.8 @@ -67,7 +70,7 @@ jobs: steps: - uses: actions/checkout@v1 - uses: dtolnay/rust-toolchain@stable - - run: cargo test --package influxdb --package influxdb_derive --all-features --no-fail-fast + - run: cargo test --manifest-path=./influxdb/Cargo.toml --no-default-features --features 'use-serde derive ${{ matrix.http-backend }}' --no-fail-fast coverage: name: Code Coverage (stable/ubuntu-20.04) diff --git a/README.md b/README.md index 0e3f033..60915c1 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,7 @@ Pull requests are always welcome. See [Contributing](https://github.com/Empty2k1 - `#[derive(InfluxDbWriteable)]` Derive Macro for Writing / Reading into Structs - `GROUP BY` support - Tokio and async-std support (see example below) or [available backends](https://github.com/Empty2k12/influxdb-rust/blob/master/influxdb/Cargo.toml) +- Swappable HTTP backends ([see below](#Choice-of-HTTP-backend)) ## Quickstart @@ -98,6 +99,31 @@ async fn main() { For further examples, check out the Integration Tests in `tests/integration_tests.rs` in the repository. +## Choice of HTTP backend + +To communicate with InfluxDB, you can choose the HTTP backend to be used configuring the appropriate feature: + +- **[hyper](https://github.com/hyperium/hyper)** (used by default) + ```toml + influxdb = { version = "0.3.0", features = ["derive"] } + ``` +- **[curl](https://github.com/alexcrichton/curl-rust)**, using [libcurl](https://curl.se/libcurl/) + ```toml + influxdb = { version = "0.3.0", default-features = false, features = ["derive", "use-serde", "curl-client"] } + ``` +- **[async-h1](https://github.com/http-rs/async-h1)** with native TLS (OpenSSL) + ```toml + influxdb = { version = "0.3.0", default-features = false, features = ["derive", "use-serde", "h1-client"] } + ``` +- **[async-h1](https://github.com/http-rs/async-h1)** with [rustls](https://github.com/ctz/rustls) + ```toml + influxdb = { version = "0.3.0", default-features = false, features = ["derive", "use-serde", "h1-client-rustls"] } + ``` +- WebAssembly's `window.fetch`, via `web-sys` and **[wasm-bindgen](https://github.com/rustwasm/wasm-bindgen)** + ```toml + influxdb = { version = "0.3.0", default-features = false, features = ["derive", "use-serde", "wasm-client"] } + ``` + ## License [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) diff --git a/influxdb/Cargo.toml b/influxdb/Cargo.toml index 637a5b7..efc77d3 100644 --- a/influxdb/Cargo.toml +++ b/influxdb/Cargo.toml @@ -21,7 +21,7 @@ futures = "0.3.4" lazy_static = "1.4.0" influxdb_derive = { version = "0.3.0", optional = true } regex = "1.3.5" -surf = { version = "2.1.0", default-features = false } +surf = { version = "2.2.0", default-features = false } serde = { version = "1.0.104", features = ["derive"], optional = true } serde_json = { version = "1.0.48", optional = true } thiserror = "1.0" @@ -30,6 +30,7 @@ thiserror = "1.0" use-serde = ["serde", "serde_json"] curl-client = ["surf/curl-client"] h1-client = ["surf/h1-client"] +h1-client-rustls = ["surf/h1-client-rustls"] hyper-client = ["surf/hyper-client"] wasm-client = ["surf/wasm-client"] default = ["use-serde", "hyper-client"] diff --git a/influxdb/src/lib.rs b/influxdb/src/lib.rs index 350362e..1c5b012 100644 --- a/influxdb/src/lib.rs +++ b/influxdb/src/lib.rs @@ -13,6 +13,7 @@ //! - `#[derive(InfluxDbWriteable)]` Derive Macro for Writing / Reading into Structs //! - `GROUP BY` support //! - Tokio and async-std support (see example below) or [available backends](https://github.com/Empty2k12/influxdb-rust/blob/master/influxdb/Cargo.toml) +//! - Swappable HTTP backends ([see below](#Choice-of-HTTP-backend)) //! //! # Quickstart //! @@ -66,6 +67,31 @@ //! For further examples, check out the Integration Tests in `tests/integration_tests.rs` //! in the repository. //! +//! # Choice of HTTP backend +//! +//! To communicate with InfluxDB, you can choose the HTTP backend to be used configuring the appropriate feature: +//! +//! - **[hyper](https://github.com/hyperium/hyper)** (used by default) +//! ```toml +//! influxdb = { version = "0.3.0", features = ["derive"] } +//! ``` +//! - **[curl](https://github.com/alexcrichton/curl-rust)**, using [libcurl](https://curl.se/libcurl/) +//! ```toml +//! influxdb = { version = "0.3.0", default-features = false, features = ["derive", "use-serde", "curl-client"] } +//! ``` +//! - **[async-h1](https://github.com/http-rs/async-h1)** with native TLS (OpenSSL) +//! ```toml +//! influxdb = { version = "0.3.0", default-features = false, features = ["derive", "use-serde", "h1-client"] } +//! ``` +//! - **[async-h1](https://github.com/http-rs/async-h1)** with [rustls](https://github.com/ctz/rustls) +//! ```toml +//! influxdb = { version = "0.3.0", default-features = false, features = ["derive", "use-serde", "h1-client-rustls"] } +//! ``` +//! - WebAssembly's `window.fetch`, via `web-sys` and **[wasm-bindgen](https://github.com/rustwasm/wasm-bindgen)** +//! ```toml +//! influxdb = { version = "0.3.0", default-features = false, features = ["derive", "use-serde", "wasm-client"] } +//! ``` +//! //! # License //! //! [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) diff --git a/influxdb/tests/integration_tests.rs b/influxdb/tests/integration_tests.rs index e02a81c..d92f405 100644 --- a/influxdb/tests/integration_tests.rs +++ b/influxdb/tests/integration_tests.rs @@ -51,7 +51,7 @@ async fn test_ping_influx_db_tokio() { async fn test_connection_error() { let test_name = "test_connection_error"; let client = - Client::new("http://localhost:10086", test_name).with_auth("nopriv_user", "password"); + Client::new("http://127.0.0.1:10086", test_name).with_auth("nopriv_user", "password"); let read_query = Query::raw_read_query("SELECT * FROM weather"); let read_result = client.query(&read_query).await; assert_result_err(&read_result); @@ -75,7 +75,7 @@ async fn test_authed_write_and_read() { run_test( || async move { let client = - Client::new("http://localhost:9086", TEST_NAME).with_auth("admin", "password"); + Client::new("http://127.0.0.1:9086", TEST_NAME).with_auth("admin", "password"); let query = format!("CREATE DATABASE {}", TEST_NAME); client .query(&Query::raw_read_query(query)) @@ -83,7 +83,7 @@ async fn test_authed_write_and_read() { .expect("could not setup db"); let client = - Client::new("http://localhost:9086", TEST_NAME).with_auth("admin", "password"); + Client::new("http://127.0.0.1:9086", TEST_NAME).with_auth("admin", "password"); let write_query = Timestamp::Hours(11) .into_query("weather") .add_field("temperature", 82); @@ -100,7 +100,7 @@ async fn test_authed_write_and_read() { }, || async move { let client = - Client::new("http://localhost:9086", TEST_NAME).with_auth("admin", "password"); + Client::new("http://127.0.0.1:9086", TEST_NAME).with_auth("admin", "password"); let query = format!("DROP DATABASE {}", TEST_NAME); client @@ -123,7 +123,7 @@ async fn test_wrong_authed_write_and_read() { run_test( || async move { let client = - Client::new("http://localhost:9086", TEST_NAME).with_auth("admin", "password"); + Client::new("http://127.0.0.1:9086", TEST_NAME).with_auth("admin", "password"); let query = format!("CREATE DATABASE {}", TEST_NAME); client .query(&Query::raw_read_query(query)) @@ -131,7 +131,7 @@ async fn test_wrong_authed_write_and_read() { .expect("could not setup db"); let client = - Client::new("http://localhost:9086", TEST_NAME).with_auth("wrong_user", "password"); + Client::new("http://127.0.0.1:9086", TEST_NAME).with_auth("wrong_user", "password"); let write_query = Timestamp::Hours(11) .into_query("weather") .add_field("temperature", 82); @@ -156,7 +156,7 @@ async fn test_wrong_authed_write_and_read() { ), } - let client = Client::new("http://localhost:9086", TEST_NAME) + let client = Client::new("http://127.0.0.1:9086", TEST_NAME) .with_auth("nopriv_user", "password"); let read_query = Query::raw_read_query("SELECT * FROM weather"); let read_result = client.query(&read_query).await; @@ -171,7 +171,7 @@ async fn test_wrong_authed_write_and_read() { }, || async move { let client = - Client::new("http://localhost:9086", TEST_NAME).with_auth("admin", "password"); + Client::new("http://127.0.0.1:9086", TEST_NAME).with_auth("admin", "password"); let query = format!("DROP DATABASE {}", TEST_NAME); client .query(&Query::raw_read_query(query)) @@ -193,13 +193,13 @@ async fn test_non_authed_write_and_read() { run_test( || async move { let client = - Client::new("http://localhost:9086", TEST_NAME).with_auth("admin", "password"); + Client::new("http://127.0.0.1:9086", TEST_NAME).with_auth("admin", "password"); let query = format!("CREATE DATABASE {}", TEST_NAME); client .query(&Query::raw_read_query(query)) .await .expect("could not setup db"); - let non_authed_client = Client::new("http://localhost:9086", TEST_NAME); + let non_authed_client = Client::new("http://127.0.0.1:9086", TEST_NAME); let write_query = Timestamp::Hours(11) .into_query("weather") .add_field("temperature", 82); @@ -226,7 +226,7 @@ async fn test_non_authed_write_and_read() { }, || async move { let client = - Client::new("http://localhost:9086", TEST_NAME).with_auth("admin", "password"); + Client::new("http://127.0.0.1:9086", TEST_NAME).with_auth("admin", "password"); let query = format!("DROP DATABASE {}", TEST_NAME); client .query(&Query::raw_read_query(query)) diff --git a/influxdb/tests/utilities.rs b/influxdb/tests/utilities.rs index 92d4e0e..b850d2d 100644 --- a/influxdb/tests/utilities.rs +++ b/influxdb/tests/utilities.rs @@ -18,7 +18,7 @@ pub fn create_client(db_name: T) -> Client where T: Into, { - Client::new("http://localhost:8086", db_name) + Client::new("http://127.0.0.1:8086", db_name) } #[cfg(not(tarpaulin_include))] From 7cad292f914dcc1ed21efaf741bcc2019417ae86 Mon Sep 17 00:00:00 2001 From: Gero Gerke Date: Mon, 8 Mar 2021 20:52:26 +0100 Subject: [PATCH 9/9] Release v0.4.0 --- CHANGELOG.md | 43 +++++++++++++++++++++++++++++++++++++- README.md | 14 ++++++------- influxdb/Cargo.toml | 4 ++-- influxdb/src/lib.rs | 14 ++++++------- influxdb_derive/Cargo.toml | 2 +- 5 files changed, 59 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19a0c1f..920eb58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,46 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.4.0] - 2021-03-08 + +### Fixed + +- Fix deserialization of Series in case of no values ([@JEnoch](https://github.com/JEnoch) in [#75](https://github.com/Empty2k12/influxdb-rust/pull/75)) + +### Added + +- implement `#[influxdb(tag)]` and `#[influxdb(ignore)]` ([@blasrodri](https://github.com/blasrodri) in [#81](https://github.com/Empty2k12/influxdb-rust/pull/81)) + + `#[tag]` is now `#[influxdb(tag)]` and fields can be ignored with `#[influxdb(ignore)]` + +- Batch write support ([@sunng87](https://github.com/sunng87) in [#87](https://github.com/Empty2k12/influxdb-rust/pull/87)) + + Build a query containing mutliple rows to be inserted + ``` + let q0 = Timestamp::Hours(11) + .into_query("weather") + .add_field("temperature", 82) + .add_tag("location", "us-midwest"); + + let q1 = Timestamp::Hours(12) + .into_query("weather") + .add_field("temperature", 65) + .add_tag("location", "us-midwest"); + + let query = vec![q0, q1].build(); + ``` + +### Changed + +- Assertion should consider case-insensitive keywords ([@rcastill](https://github.com/rcastill) in [#83](https://github.com/Empty2k12/influxdb-rust/pull/83)) + + `#[tag]` is now `#[influxdb(tag)]` and fields can be ignored with `#[influxdb(ignore)]` + +- Add h1-client-rustls feature ([@JEnoch](https://github.com/JEnoch) in [#88](https://github.com/Empty2k12/influxdb-rust/pull/88)) + + Switch between multiple http backends as described in the [README.md](README.md#Choice-of-HTTP-backend) + + ## [0.3.0] - 2020-11-15 ### Changed @@ -120,7 +160,8 @@ This release removes the prefix `InfluxDb` of most types in this library and ree - Improved Test Coverage: There's now even more tests verifying correctness of the crate (#5) - It's no longer necessary to supply a wildcard generic when working with serde*integration: `client.json_query::(query)` instead of `client.json_query::(query)` -[unreleased]: https://github.com/Empty2k12/influxdb-rust/compare/v0.3.0...HEAD +[unreleased]: https://github.com/Empty2k12/influxdb-rust/compare/v0.4.0...HEAD +[0.4.0]: https://github.com/Empty2k12/influxdb-rust/compare/v0.3.0...v0.4.0 [0.3.0]: https://github.com/Empty2k12/influxdb-rust/compare/v0.2.0...v0.3.0 [0.2.0]: https://github.com/Empty2k12/influxdb-rust/compare/v0.1.0...v0.2.0 [0.1.0]: https://github.com/Empty2k12/influxdb-rust/compare/v0.0.6...v0.1.0 diff --git a/README.md b/README.md index 60915c1..96b4aa1 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ This library is a work in progress. This means a feature you might need is not implemented yet or could be handled better. -Pull requests are always welcome. See [Contributing](https://github.com/Empty2k12/influxdb-rust/blob/master/CONTRIBUTING.md) and [Code of Conduct](https://github.com/Empty2k12/influxdb-rust/blob/master/CODE_OF_CONDUCT.md). +Pull requests are always welcome. See [Contributing](https://github.com/Empty2k12/influxdb-rust/blob/master/CONTRIBUTING.md) and [Code of Conduct](https://github.com/Empty2k12/influxdb-rust/blob/master/CODE_OF_CONDUCT.md). For a list of past changes, see [CHANGELOG.md](https://github.com/Empty2k12/influxdb-rust/blob/master/CHANGELOG.md). ### Currently Supported Features @@ -52,7 +52,7 @@ Pull requests are always welcome. See [Contributing](https://github.com/Empty2k1 Add the following to your `Cargo.toml` ```toml -influxdb = { version = "0.3.0", features = ["derive"] } +influxdb = { version = "0.4.0", features = ["derive"] } ``` For an example with using Serde deserialization, please refer to [serde_integration](crate::integrations::serde_integration) @@ -105,23 +105,23 @@ To communicate with InfluxDB, you can choose the HTTP backend to be used configu - **[hyper](https://github.com/hyperium/hyper)** (used by default) ```toml - influxdb = { version = "0.3.0", features = ["derive"] } + influxdb = { version = "0.4.0", features = ["derive"] } ``` - **[curl](https://github.com/alexcrichton/curl-rust)**, using [libcurl](https://curl.se/libcurl/) ```toml - influxdb = { version = "0.3.0", default-features = false, features = ["derive", "use-serde", "curl-client"] } + influxdb = { version = "0.4.0", default-features = false, features = ["derive", "use-serde", "curl-client"] } ``` - **[async-h1](https://github.com/http-rs/async-h1)** with native TLS (OpenSSL) ```toml - influxdb = { version = "0.3.0", default-features = false, features = ["derive", "use-serde", "h1-client"] } + influxdb = { version = "0.4.0", default-features = false, features = ["derive", "use-serde", "h1-client"] } ``` - **[async-h1](https://github.com/http-rs/async-h1)** with [rustls](https://github.com/ctz/rustls) ```toml - influxdb = { version = "0.3.0", default-features = false, features = ["derive", "use-serde", "h1-client-rustls"] } + influxdb = { version = "0.4.0", default-features = false, features = ["derive", "use-serde", "h1-client-rustls"] } ``` - WebAssembly's `window.fetch`, via `web-sys` and **[wasm-bindgen](https://github.com/rustwasm/wasm-bindgen)** ```toml - influxdb = { version = "0.3.0", default-features = false, features = ["derive", "use-serde", "wasm-client"] } + influxdb = { version = "0.4.0", default-features = false, features = ["derive", "use-serde", "wasm-client"] } ``` ## License diff --git a/influxdb/Cargo.toml b/influxdb/Cargo.toml index efc77d3..6ebbf5a 100644 --- a/influxdb/Cargo.toml +++ b/influxdb/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "influxdb" -version = "0.3.0" +version = "0.4.0" authors = ["Gero Gerke <11deutron11@gmail.com>"] edition = "2018" description = "InfluxDB Driver for Rust" @@ -19,7 +19,7 @@ travis-ci = { repository = "Empty2k12/influxdb-rust", branch = "master" } chrono = { version = "0.4.11", features = ["serde"] } futures = "0.3.4" lazy_static = "1.4.0" -influxdb_derive = { version = "0.3.0", optional = true } +influxdb_derive = { version = "0.4.0", optional = true } regex = "1.3.5" surf = { version = "2.2.0", default-features = false } serde = { version = "1.0.104", features = ["derive"], optional = true } diff --git a/influxdb/src/lib.rs b/influxdb/src/lib.rs index 1c5b012..117f07f 100644 --- a/influxdb/src/lib.rs +++ b/influxdb/src/lib.rs @@ -1,7 +1,7 @@ //! This library is a work in progress. This means a feature you might need is not implemented //! yet or could be handled better. //! -//! Pull requests are always welcome. See [Contributing](https://github.com/Empty2k12/influxdb-rust/blob/master/CONTRIBUTING.md) and [Code of Conduct](https://github.com/Empty2k12/influxdb-rust/blob/master/CODE_OF_CONDUCT.md). +//! Pull requests are always welcome. See [Contributing](https://github.com/Empty2k12/influxdb-rust/blob/master/CONTRIBUTING.md) and [Code of Conduct](https://github.com/Empty2k12/influxdb-rust/blob/master/CODE_OF_CONDUCT.md). For a list of past changes, see [CHANGELOG.md](https://github.com/Empty2k12/influxdb-rust/blob/master/CHANGELOG.md). //! //! ## Currently Supported Features //! @@ -20,7 +20,7 @@ //! Add the following to your `Cargo.toml` //! //! ```toml -//! influxdb = { version = "0.3.0", features = ["derive"] } +//! influxdb = { version = "0.4.0", features = ["derive"] } //! ``` //! //! For an example with using Serde deserialization, please refer to [serde_integration](crate::integrations::serde_integration) @@ -73,23 +73,23 @@ //! //! - **[hyper](https://github.com/hyperium/hyper)** (used by default) //! ```toml -//! influxdb = { version = "0.3.0", features = ["derive"] } +//! influxdb = { version = "0.4.0", features = ["derive"] } //! ``` //! - **[curl](https://github.com/alexcrichton/curl-rust)**, using [libcurl](https://curl.se/libcurl/) //! ```toml -//! influxdb = { version = "0.3.0", default-features = false, features = ["derive", "use-serde", "curl-client"] } +//! influxdb = { version = "0.4.0", default-features = false, features = ["derive", "use-serde", "curl-client"] } //! ``` //! - **[async-h1](https://github.com/http-rs/async-h1)** with native TLS (OpenSSL) //! ```toml -//! influxdb = { version = "0.3.0", default-features = false, features = ["derive", "use-serde", "h1-client"] } +//! influxdb = { version = "0.4.0", default-features = false, features = ["derive", "use-serde", "h1-client"] } //! ``` //! - **[async-h1](https://github.com/http-rs/async-h1)** with [rustls](https://github.com/ctz/rustls) //! ```toml -//! influxdb = { version = "0.3.0", default-features = false, features = ["derive", "use-serde", "h1-client-rustls"] } +//! influxdb = { version = "0.4.0", default-features = false, features = ["derive", "use-serde", "h1-client-rustls"] } //! ``` //! - WebAssembly's `window.fetch`, via `web-sys` and **[wasm-bindgen](https://github.com/rustwasm/wasm-bindgen)** //! ```toml -//! influxdb = { version = "0.3.0", default-features = false, features = ["derive", "use-serde", "wasm-client"] } +//! influxdb = { version = "0.4.0", default-features = false, features = ["derive", "use-serde", "wasm-client"] } //! ``` //! //! # License diff --git a/influxdb_derive/Cargo.toml b/influxdb_derive/Cargo.toml index 0fd812b..a2c1e06 100644 --- a/influxdb_derive/Cargo.toml +++ b/influxdb_derive/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "influxdb_derive" -version = "0.3.0" +version = "0.4.0" authors = ["Gero Gerke <11deutron11@gmail.com>"] edition = "2018" description = "InfluxDB Driver for Rust - Derive" pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy