|
1 | 1 | #![allow(dead_code)]
|
2 | 2 |
|
| 3 | +#[macro_use] |
| 4 | +extern crate failure; |
| 5 | + |
3 | 6 | use futures::Future;
|
4 | 7 | use itertools::Itertools;
|
5 | 8 | use reqwest::r#async::Client;
|
6 | 9 |
|
| 10 | +#[derive(Debug, Fail)] |
| 11 | +enum InfluxDbError { |
| 12 | + #[fail(display = "query must contain at least one field")] |
| 13 | + InvalidQueryError, |
| 14 | +} |
| 15 | + |
| 16 | +#[derive(Debug)] |
| 17 | +struct ValidQuery(String); |
| 18 | +impl From<String> for ValidQuery { |
| 19 | + fn from(s: String) -> ValidQuery { |
| 20 | + ValidQuery(s) |
| 21 | + } |
| 22 | +} |
| 23 | +impl PartialEq<String> for ValidQuery { |
| 24 | + fn eq(&self, other: &String) -> bool { |
| 25 | + &self.0 == other |
| 26 | + } |
| 27 | +} |
| 28 | +impl PartialEq<&str> for ValidQuery { |
| 29 | + fn eq(&self, other: &&str) -> bool { |
| 30 | + &self.0 == other |
| 31 | + } |
| 32 | +} |
| 33 | + |
7 | 34 | trait InfluxDbQuery {
|
8 |
| - fn build<'a>(self) -> String; |
| 35 | + fn build<'a>(self) -> Result<ValidQuery, InfluxDbError>; |
9 | 36 | }
|
10 | 37 |
|
11 | 38 | impl InfluxDbQuery {
|
12 |
| - pub fn write() -> InfluxDbWrite { |
| 39 | + pub fn write<S>(measurement: S) -> InfluxDbWrite |
| 40 | + where |
| 41 | + S: Into<String>, |
| 42 | + { |
13 | 43 | InfluxDbWrite {
|
14 |
| - measurement: String::from("marina_3"), |
| 44 | + measurement: measurement.into(), |
15 | 45 | fields: Vec::new(),
|
16 | 46 | tags: Vec::new(),
|
17 | 47 | }
|
@@ -45,32 +75,40 @@ impl InfluxDbWrite {
|
45 | 75 | }
|
46 | 76 | }
|
47 | 77 |
|
| 78 | +// todo: fuse_with(other: ValidQuery), so multiple queries can be run at the same time |
48 | 79 | impl InfluxDbQuery for InfluxDbWrite {
|
49 | 80 | // fixme: time (with precision) and measurement
|
50 |
| - fn build<'a>(self) -> String { |
| 81 | + fn build<'a>(self) -> Result<ValidQuery, InfluxDbError> { |
| 82 | + if self.fields.is_empty() { |
| 83 | + return Err(InfluxDbError::InvalidQueryError); |
| 84 | + } |
| 85 | + |
51 | 86 | let tags = self
|
52 | 87 | .tags
|
53 | 88 | .into_iter()
|
54 | 89 | .map(|(tag, value)| format!("{tag}={value}", tag = tag, value = value))
|
55 |
| - .join(","); |
| 90 | + .join(",") |
| 91 | + + " "; |
56 | 92 | let fields = self
|
57 | 93 | .fields
|
58 | 94 | .into_iter()
|
59 | 95 | .map(|(field, value)| format!("{field}={value}", field = field, value = value))
|
60 |
| - .join(","); |
| 96 | + .join(",") |
| 97 | + + " "; |
61 | 98 |
|
62 |
| - format!( |
63 |
| - "measurement,{tags} {fields} time", |
| 99 | + Ok(ValidQuery::from(format!( |
| 100 | + "{measurement},{tags}{fields}time", |
| 101 | + measurement = self.measurement, |
64 | 102 | tags = tags,
|
65 | 103 | fields = fields
|
66 |
| - ) |
| 104 | + ))) |
67 | 105 | }
|
68 | 106 | }
|
69 | 107 |
|
70 | 108 | pub struct InfluxDbClient {
|
71 | 109 | url: String,
|
72 | 110 | database: String,
|
73 |
| - // _auth: InfluxDbAuthentication | NoAuthentication |
| 111 | + // auth: Option<InfluxDbAuthentication> |
74 | 112 | }
|
75 | 113 |
|
76 | 114 | pub fn main() {}
|
@@ -129,67 +167,62 @@ mod tests {
|
129 | 167 | println!("build: {} version: {}", build, version);
|
130 | 168 | }
|
131 | 169 |
|
| 170 | + #[test] |
| 171 | + fn test_write_builder_empty_query() { |
| 172 | + let query = InfluxDbQuery::write("marina_3").build(); |
| 173 | + |
| 174 | + assert!(query.is_err(), "Query was not empty"); |
| 175 | + } |
| 176 | + |
132 | 177 | #[test]
|
133 | 178 | fn test_write_builder_single_field() {
|
134 |
| - let query = InfluxDbQuery::write().add_field("water_level", "2"); |
| 179 | + let query = InfluxDbQuery::write("marina_3") |
| 180 | + .add_field("water_level", "2") |
| 181 | + .build(); |
135 | 182 |
|
136 |
| - assert_eq!(query.build(), "measurement, water_level=2 time"); |
| 183 | + assert!(query.is_ok(), "Query was empty"); |
| 184 | + assert_eq!(query.unwrap(), "marina_3, water_level=2 time"); |
137 | 185 | }
|
138 | 186 |
|
139 | 187 | #[test]
|
140 | 188 | fn test_write_builder_multiple_fields() {
|
141 |
| - let query = InfluxDbQuery::write() |
| 189 | + let query = InfluxDbQuery::write("marina_3") |
142 | 190 | .add_field("water_level", "2")
|
143 | 191 | .add_field("boat_count", "31")
|
144 |
| - .add_field("algae_content", "0.85"); |
| 192 | + .add_field("algae_content", "0.85") |
| 193 | + .build(); |
145 | 194 |
|
| 195 | + assert!(query.is_ok(), "Query was empty"); |
146 | 196 | assert_eq!(
|
147 |
| - query.build(), |
148 |
| - "measurement, water_level=2,boat_count=31,algae_content=0.85 time" |
| 197 | + query.unwrap(), |
| 198 | + "marina_3, water_level=2,boat_count=31,algae_content=0.85 time" |
149 | 199 | );
|
150 | 200 | }
|
151 | 201 |
|
152 |
| - // fixme: double space |
153 | 202 | // fixme: quoting / escaping of long strings
|
154 | 203 | #[test]
|
155 |
| - fn test_write_builder_single_tag() { |
156 |
| - let query = InfluxDbQuery::write().add_tag("marina_manager", "Smith"); |
157 |
| - |
158 |
| - assert_eq!(query.build(), "measurement,marina_manager=Smith time"); |
159 |
| - } |
160 |
| - |
161 |
| - #[test] |
162 |
| - fn test_write_builder_multiple_tags() { |
163 |
| - let query = InfluxDbQuery::write() |
| 204 | + fn test_write_builder_only_tags() { |
| 205 | + let query = InfluxDbQuery::write("marina_3") |
164 | 206 | .add_tag("marina_manager", "Smith")
|
165 |
| - .add_tag("manager_to_the_marina_manager", "Jonson"); |
| 207 | + .build(); |
166 | 208 |
|
167 |
| - assert_eq!( |
168 |
| - query.build(), |
169 |
| - "measurement,marina_manager=Smith,manager_to_the_marina_manager=Jonson time" |
170 |
| - ); |
| 209 | + assert!(query.is_err(), "Query missing one or more fields"); |
171 | 210 | }
|
172 | 211 |
|
173 | 212 | #[test]
|
174 | 213 | fn test_write_builder_full_query() {
|
175 |
| - let query = InfluxDbQuery::write() |
| 214 | + let query = InfluxDbQuery::write("marina_3") |
176 | 215 | .add_field("water_level", "2")
|
177 | 216 | .add_field("boat_count", "31")
|
178 | 217 | .add_field("algae_content", "0.85")
|
179 | 218 | .add_tag("marina_manager", "Smith")
|
180 |
| - .add_tag("manager_to_the_marina_manager", "Jonson"); |
| 219 | + .add_tag("manager_to_the_marina_manager", "Jonson") |
| 220 | + .build(); |
181 | 221 |
|
| 222 | + assert!(query.is_ok(), "Query was empty"); |
182 | 223 | assert_eq!(
|
183 |
| - query.build(), |
184 |
| - "measurement,marina_manager=Smith,manager_to_the_marina_manager=Jonson water_level=2,boat_count=31,algae_content=0.85 time" |
| 224 | + query.unwrap(), |
| 225 | + "marina_3,marina_manager=Smith,manager_to_the_marina_manager=Jonson water_level=2,boat_count=31,algae_content=0.85 time" |
185 | 226 | );
|
186 | 227 | }
|
187 |
| - |
188 |
| - #[test] |
189 |
| - fn test_test() { |
190 |
| - InfluxDbQuery::write() |
191 |
| - .add_field("test", "1") |
192 |
| - .add_tag("my_tag", "0.85") |
193 |
| - .build(); |
194 |
| - } |
195 | 228 | }
|
0 commit comments