@@ -8,18 +8,16 @@ use itertools::Itertools;
8
8
use reqwest:: r#async:: Client ;
9
9
10
10
#[ derive( Debug , Fail ) ]
11
- enum InfluxDbError {
11
+ /// Errors that might happen in the crate
12
+ pub enum InfluxDbError {
12
13
#[ fail( display = "query must contain at least one field" ) ]
14
+ /// Error happens when query has zero fields
13
15
InvalidQueryError ,
14
16
}
15
17
16
18
#[ derive( Debug ) ]
17
- struct ValidQuery ( String ) ;
18
- impl From < String > for ValidQuery {
19
- fn from ( s : String ) -> ValidQuery {
20
- ValidQuery ( s)
21
- }
22
- }
19
+ #[ doc( hidden) ]
20
+ pub struct ValidQuery ( String ) ;
23
21
impl PartialEq < String > for ValidQuery {
24
22
fn eq ( & self , other : & String ) -> bool {
25
23
& self . 0 == other
@@ -31,16 +29,56 @@ impl PartialEq<&str> for ValidQuery {
31
29
}
32
30
}
33
31
34
- trait InfluxDbQuery {
32
+ /// Used to create read or [`InfluxDbWriteQuery`] queries to InfluxDB
33
+ ///
34
+ /// # Examples
35
+ ///
36
+ /// ```rust
37
+ /// use influxdb::InfluxDbQuery;
38
+ ///
39
+ /// let write_query = InfluxDbQuery::write_query("measurement")
40
+ /// .add_field("field1", "5")
41
+ /// .add_tag("tag1", "Gero")
42
+ /// .build();
43
+ ///
44
+ /// assert!(query.is_ok());
45
+ ///
46
+ /// //todo: document read query once it's implemented.
47
+ /// ```
48
+ pub trait InfluxDbQuery {
49
+ /// Builds valid InfluxSQL which can be run against the Database.
50
+ /// In case no fields have been specified, it will return an error,
51
+ /// as that is invalid InfluxSQL syntax.
52
+ ///
53
+ /// # Examples
54
+ ///
55
+ /// ```rust
56
+ /// use influxdb::InfluxDbQuery;
57
+ ///
58
+ /// let invalid_query = InfluxDbQuery::write_query("measurement").build();
59
+ /// assert!(query.is_err());
60
+ ///
61
+ /// let valid_query = InfluxDbQuery::write_query("measurement").add_field("myfield1", "11").build();
62
+ /// assert!(query.is_ok());
63
+ /// ```
35
64
fn build < ' a > ( self ) -> Result < ValidQuery , InfluxDbError > ;
36
65
}
37
66
38
67
impl InfluxDbQuery {
39
- pub fn write < S > ( measurement : S ) -> InfluxDbWrite
68
+ /// Returns a [`InfluxDbWriteQuery`] builder.
69
+ ///
70
+ /// # Examples
71
+ ///
72
+ /// ```rust
73
+ /// use influxdb::InfluxDbQuery;
74
+ ///
75
+ /// InfluxDbQuery::write_query("measurement"); // Is of type [`InfluxDbWriteQuery`]
76
+ /// ```
77
+ pub fn write_query < S > ( measurement : S ) -> InfluxDbWriteQuery
40
78
where
41
79
S : Into < String > ,
42
80
{
43
- InfluxDbWrite {
81
+ InfluxDbWriteQuery {
44
82
measurement : measurement. into ( ) ,
45
83
fields : Vec :: new ( ) ,
46
84
tags : Vec :: new ( ) ,
@@ -50,23 +88,48 @@ impl InfluxDbQuery {
50
88
// pub fn read() {}
51
89
}
52
90
53
- pub struct InfluxDbWrite {
91
+ /// Write Query Builder returned by [InfluxDbQuery::write_query]()
92
+ ///
93
+ /// Can only be instantiated by using [InfluxDbQuery::write_query]()
94
+ pub struct InfluxDbWriteQuery {
54
95
fields : Vec < ( String , String ) > ,
55
96
tags : Vec < ( String , String ) > ,
56
97
measurement : String ,
57
98
// precision: Precision
58
99
}
59
100
60
- impl InfluxDbWrite {
61
- fn add_field < ' a , S > ( mut self , point : S , value : S ) -> Self
101
+ impl InfluxDbWriteQuery {
102
+ /// Adds a field to the [`InfluxDbWriteQuery`]
103
+ ///
104
+ /// # Examples
105
+ ///
106
+ /// ```rust
107
+ /// use influxdb::InfluxDbQuery;
108
+ ///
109
+ /// InfluxDbQuery::write_query("measurement").add_field("field1", "5").build();
110
+ /// ```
111
+ pub fn add_field < ' a , S > ( mut self , point : S , value : S ) -> Self
62
112
where
63
113
S : Into < String > ,
64
114
{
65
115
self . fields . push ( ( point. into ( ) , value. into ( ) ) ) ;
66
116
self
67
117
}
68
118
69
- fn add_tag < ' a , S > ( mut self , tag : S , value : S ) -> Self
119
+ /// Adds a tag to the [`InfluxDbWriteQuery`]
120
+ ///
121
+ /// Please note that a [`InfluxDbWriteQuery`] requires at least one field. Composing a query with
122
+ /// only tags will result in a failure building the query.
123
+ ///
124
+ /// # Examples
125
+ ///
126
+ /// ```rust
127
+ /// use influxdb::InfluxDbQuery;
128
+ ///
129
+ /// InfluxDbQuery::write_query("measurement")
130
+ /// .add_tag("field1", "5"); // calling `.build()` now would result in a `Err(InfluxDbError::InvalidQueryError)`
131
+ /// ```
132
+ pub fn add_tag < ' a , S > ( mut self , tag : S , value : S ) -> Self
70
133
where
71
134
S : Into < String > ,
72
135
{
@@ -76,8 +139,8 @@ impl InfluxDbWrite {
76
139
}
77
140
78
141
// todo: fuse_with(other: ValidQuery), so multiple queries can be run at the same time
79
- impl InfluxDbQuery for InfluxDbWrite {
80
- // fixme : time (with precision) and measurement
142
+ impl InfluxDbQuery for InfluxDbWriteQuery {
143
+ // todo : time (with precision)
81
144
fn build < ' a > ( self ) -> Result < ValidQuery , InfluxDbError > {
82
145
if self . fields . is_empty ( ) {
83
146
return Err ( InfluxDbError :: InvalidQueryError ) ;
@@ -96,7 +159,7 @@ impl InfluxDbQuery for InfluxDbWrite {
96
159
. join ( "," )
97
160
+ " " ;
98
161
99
- Ok ( ValidQuery :: from ( format ! (
162
+ Ok ( ValidQuery ( format ! (
100
163
"{measurement},{tags}{fields}time" ,
101
164
measurement = self . measurement,
102
165
tags = tags,
@@ -105,15 +168,61 @@ impl InfluxDbQuery for InfluxDbWrite {
105
168
}
106
169
}
107
170
171
+ /// Client which can read and write data from InfluxDB.
172
+ ///
173
+ /// # Arguments
174
+ ///
175
+ /// * `url`: The URL where InfluxDB is running (ex. `http://localhost:8086`).
176
+ /// * `database`: The Database against which queries and writes will be run.
177
+ ///
178
+ /// # Examples
179
+ ///
180
+ /// ```rust
181
+ /// use influxdb::InfluxDbClient;
182
+ ///
183
+ /// let client = InfluxDbClient::new("http://localhost:8086", "test");
184
+ ///
185
+ /// assert_eq!(client.get_database_name(), "test");
186
+ /// ```
108
187
pub struct InfluxDbClient {
109
188
url : String ,
110
189
database : String ,
111
190
// auth: Option<InfluxDbAuthentication>
112
191
}
113
192
114
- pub fn main ( ) { }
115
-
116
193
impl InfluxDbClient {
194
+ /// Instantiates a new [`InfluxDbClient`]
195
+ ///
196
+ /// # Arguments
197
+ ///
198
+ /// * `url`: The URL where InfluxDB is running (ex. `http://localhost:8086`).
199
+ /// * `database`: The Database against which queries and writes will be run.
200
+ ///
201
+ /// # Examples
202
+ ///
203
+ /// ```rust
204
+ /// use influxdb::InfluxDbClient;
205
+ ///
206
+ /// let _client = InfluxDbClient::new("http://localhost:8086", "test");
207
+ /// ```
208
+ pub fn new < S > ( url : S , database : S ) -> Self
209
+ where
210
+ S : Into < String > ,
211
+ {
212
+ InfluxDbClient {
213
+ url : url. into ( ) ,
214
+ database : database. into ( ) ,
215
+ }
216
+ }
217
+
218
+ pub fn get_database_name ( self ) -> String {
219
+ self . database
220
+ }
221
+
222
+ pub fn get_database_url ( self ) -> String {
223
+ self . url
224
+ }
225
+
117
226
pub fn ping ( & self ) -> impl Future < Item = ( String , String ) , Error = ( ) > {
118
227
Client :: new ( )
119
228
. get ( format ! ( "{}/ping" , self . url) . as_str ( ) )
@@ -138,6 +247,8 @@ impl InfluxDbClient {
138
247
}
139
248
}
140
249
250
+ pub fn main ( ) { }
251
+
141
252
#[ cfg( test) ]
142
253
mod tests {
143
254
use super :: { InfluxDbClient , InfluxDbQuery } ;
@@ -148,10 +259,7 @@ mod tests {
148
259
}
149
260
150
261
fn create_client ( ) -> InfluxDbClient {
151
- InfluxDbClient {
152
- url : String :: from ( "http://localhost:8086" ) ,
153
- database : String :: from ( "test" ) ,
154
- }
262
+ InfluxDbClient :: new ( "http://localhost:8086" , "test" )
155
263
}
156
264
157
265
#[ test]
@@ -169,14 +277,14 @@ mod tests {
169
277
170
278
#[ test]
171
279
fn test_write_builder_empty_query ( ) {
172
- let query = InfluxDbQuery :: write ( "marina_3" ) . build ( ) ;
280
+ let query = InfluxDbQuery :: write_query ( "marina_3" ) . build ( ) ;
173
281
174
282
assert ! ( query. is_err( ) , "Query was not empty" ) ;
175
283
}
176
284
177
285
#[ test]
178
286
fn test_write_builder_single_field ( ) {
179
- let query = InfluxDbQuery :: write ( "marina_3" )
287
+ let query = InfluxDbQuery :: write_query ( "marina_3" )
180
288
. add_field ( "water_level" , "2" )
181
289
. build ( ) ;
182
290
@@ -186,7 +294,7 @@ mod tests {
186
294
187
295
#[ test]
188
296
fn test_write_builder_multiple_fields ( ) {
189
- let query = InfluxDbQuery :: write ( "marina_3" )
297
+ let query = InfluxDbQuery :: write_query ( "marina_3" )
190
298
. add_field ( "water_level" , "2" )
191
299
. add_field ( "boat_count" , "31" )
192
300
. add_field ( "algae_content" , "0.85" )
@@ -202,7 +310,7 @@ mod tests {
202
310
// fixme: quoting / escaping of long strings
203
311
#[ test]
204
312
fn test_write_builder_only_tags ( ) {
205
- let query = InfluxDbQuery :: write ( "marina_3" )
313
+ let query = InfluxDbQuery :: write_query ( "marina_3" )
206
314
. add_tag ( "marina_manager" , "Smith" )
207
315
. build ( ) ;
208
316
@@ -211,7 +319,7 @@ mod tests {
211
319
212
320
#[ test]
213
321
fn test_write_builder_full_query ( ) {
214
- let query = InfluxDbQuery :: write ( "marina_3" )
322
+ let query = InfluxDbQuery :: write_query ( "marina_3" )
215
323
. add_field ( "water_level" , "2" )
216
324
. add_field ( "boat_count" , "31" )
217
325
. add_field ( "algae_content" , "0.85" )
0 commit comments