16
16
//! ```
17
17
18
18
use futures:: prelude:: * ;
19
- use reqwest:: { self , Client as ReqwestClient , StatusCode , Url } ;
19
+ use reqwest:: { self , Client as ReqwestClient , StatusCode } ;
20
20
21
21
use crate :: query:: QueryTypes ;
22
22
use crate :: Error ;
23
23
use crate :: Query ;
24
-
25
- #[ derive( Clone , Debug ) ]
26
- /// Internal Authentication representation
27
- pub ( crate ) struct Authentication {
28
- pub username : String ,
29
- pub password : String ,
30
- }
24
+ use std:: sync:: Arc ;
31
25
32
26
#[ derive( Clone , Debug ) ]
33
27
/// Internal Representation of a Client
34
28
pub struct Client {
35
- url : String ,
36
- database : String ,
37
- auth : Option < Authentication > ,
38
- }
39
-
40
- impl Into < Vec < ( String , String ) > > for Client {
41
- fn into ( self ) -> Vec < ( String , String ) > {
42
- let mut vec: Vec < ( String , String ) > = Vec :: new ( ) ;
43
- vec. push ( ( "db" . to_string ( ) , self . database ) ) ;
44
- if let Some ( auth) = self . auth {
45
- vec. push ( ( "u" . to_string ( ) , auth. username ) ) ;
46
- vec. push ( ( "p" . to_string ( ) , auth. password ) ) ;
47
- }
48
- vec
49
- }
50
- }
51
-
52
- impl < ' a > Into < Vec < ( String , String ) > > for & ' a Client {
53
- fn into ( self ) -> Vec < ( String , String ) > {
54
- let mut vec: Vec < ( String , String ) > = Vec :: new ( ) ;
55
- vec. push ( ( "db" . to_string ( ) , self . database . to_owned ( ) ) ) ;
56
- if let Some ( auth) = & self . auth {
57
- vec. push ( ( "u" . to_string ( ) , auth. username . to_owned ( ) ) ) ;
58
- vec. push ( ( "p" . to_string ( ) , auth. password . to_owned ( ) ) ) ;
59
- }
60
- vec
61
- }
29
+ pub ( crate ) url : Arc < String > ,
30
+ pub ( crate ) parameters : Arc < Vec < ( & ' static str , String ) > > ,
31
+ pub ( crate ) client : ReqwestClient ,
62
32
}
63
33
64
34
impl Client {
@@ -82,9 +52,9 @@ impl Client {
82
52
S2 : Into < String > ,
83
53
{
84
54
Client {
85
- url : url. into ( ) ,
86
- database : database. into ( ) ,
87
- auth : None ,
55
+ url : Arc :: new ( url. into ( ) ) ,
56
+ parameters : Arc :: new ( vec ! [ ( "db" , database. into( ) ) ] ) ,
57
+ client : ReqwestClient :: new ( ) ,
88
58
}
89
59
}
90
60
@@ -93,7 +63,7 @@ impl Client {
93
63
/// # Arguments
94
64
///
95
65
/// * username: The Username for InfluxDB.
96
- /// * password: THe Password for the user.
66
+ /// * password: The Password for the user.
97
67
///
98
68
/// # Examples
99
69
///
@@ -107,16 +77,17 @@ impl Client {
107
77
S1 : Into < String > ,
108
78
S2 : Into < String > ,
109
79
{
110
- self . auth = Some ( Authentication {
111
- username : username . into ( ) ,
112
- password : password . into ( ) ,
113
- } ) ;
80
+ let mut with_auth = self . parameters . as_ref ( ) . clone ( ) ;
81
+ with_auth . push ( ( "u" , username. into ( ) ) ) ;
82
+ with_auth . push ( ( "p" , password. into ( ) ) ) ;
83
+ self . parameters = Arc :: new ( with_auth ) ;
114
84
self
115
85
}
116
86
117
87
/// Returns the name of the database the client is using
118
88
pub fn database_name ( & self ) -> & str {
119
- & self . database
89
+ // safe to unwrap: we always set the database name in `Self::new`
90
+ & self . parameters . first ( ) . unwrap ( ) . 1
120
91
}
121
92
122
93
/// Returns the URL of the InfluxDB installation the client is using
@@ -128,7 +99,11 @@ impl Client {
128
99
///
129
100
/// Returns a tuple of build type and version number
130
101
pub async fn ping ( & self ) -> Result < ( String , String ) , Error > {
131
- let res = reqwest:: get ( format ! ( "{}/ping" , self . url) . as_str ( ) )
102
+ let url = & format ! ( "{}/ping" , self . url) ;
103
+ let res = self
104
+ . client
105
+ . get ( url)
106
+ . send ( )
132
107
. await
133
108
. map_err ( |err| Error :: ProtocolError {
134
109
error : format ! ( "{}" , err) ,
@@ -197,45 +172,45 @@ impl Client {
197
172
error : format ! ( "{}" , err) ,
198
173
} ) ?;
199
174
200
- let basic_parameters: Vec < ( String , String ) > = self . into ( ) ;
201
-
202
- let client = match q. into ( ) {
175
+ let request_builder = match q. into ( ) {
203
176
QueryTypes :: Read ( _) => {
204
177
let read_query = query. get ( ) ;
205
- let mut url = Url :: parse_with_params (
206
- format ! ( "{url}/query" , url = self . database_url( ) ) . as_str ( ) ,
207
- basic_parameters,
208
- )
209
- . map_err ( |err| Error :: UrlConstructionError {
210
- error : format ! ( "{}" , err) ,
211
- } ) ?;
212
-
213
- url. query_pairs_mut ( ) . append_pair ( "q" , & read_query) ;
178
+ let url = & format ! ( "{}/query" , & self . url) ;
179
+ let query = [ ( "q" , & read_query) ] ;
214
180
215
181
if read_query. contains ( "SELECT" ) || read_query. contains ( "SHOW" ) {
216
- ReqwestClient :: new ( ) . get ( url)
182
+ self . client
183
+ . get ( url)
184
+ . query ( self . parameters . as_ref ( ) )
185
+ . query ( & query)
217
186
} else {
218
- ReqwestClient :: new ( ) . post ( url)
187
+ self . client
188
+ . post ( url)
189
+ . query ( self . parameters . as_ref ( ) )
190
+ . query ( & query)
219
191
}
220
192
}
221
193
QueryTypes :: Write ( write_query) => {
222
- let mut url = Url :: parse_with_params (
223
- format ! ( "{url}/write" , url = self . database_url( ) ) . as_str ( ) ,
224
- basic_parameters,
225
- )
226
- . map_err ( |err| Error :: InvalidQueryError {
227
- error : format ! ( "{}" , err) ,
228
- } ) ?;
229
-
230
- url. query_pairs_mut ( )
231
- . append_pair ( "precision" , & write_query. get_precision ( ) ) ;
232
-
233
- ReqwestClient :: new ( ) . post ( url) . body ( query. get ( ) )
194
+ let url = & format ! ( "{}/write" , & self . url) ;
195
+ let precision = [ ( "precision" , write_query. get_precision ( ) ) ] ;
196
+
197
+ self . client
198
+ . post ( url)
199
+ . query ( self . parameters . as_ref ( ) )
200
+ . query ( & precision)
201
+ . body ( query. get ( ) )
234
202
}
235
203
} ;
236
204
237
- let res = client
238
- . send ( )
205
+ let request = request_builder
206
+ . build ( )
207
+ . map_err ( |err| Error :: UrlConstructionError {
208
+ error : format ! ( "{}" , & err) ,
209
+ } ) ?;
210
+
211
+ let res = self
212
+ . client
213
+ . execute ( request)
239
214
. map_err ( |err| Error :: ConnectionError { error : err } )
240
215
. await ?;
241
216
@@ -262,67 +237,28 @@ impl Client {
262
237
263
238
#[ cfg( test) ]
264
239
mod tests {
265
- use crate :: Client ;
240
+ use super :: Client ;
266
241
267
242
#[ test]
268
243
fn test_fn_database ( ) {
269
244
let client = Client :: new ( "http://localhost:8068" , "database" ) ;
270
- assert_eq ! ( "database" , client. database_name( ) ) ;
245
+ assert_eq ! ( client. database_name( ) , "database" ) ;
246
+ assert_eq ! ( client. database_url( ) , "http://localhost:8068" ) ;
271
247
}
272
248
273
249
#[ test]
274
250
fn test_with_auth ( ) {
275
251
let client = Client :: new ( "http://localhost:8068" , "database" ) ;
276
- assert_eq ! ( client. url, "http://localhost:8068" ) ;
277
- assert_eq ! ( client. database, "database" ) ;
278
- assert ! ( client. auth. is_none( ) ) ;
279
- let with_auth = client. with_auth ( "username" , "password" ) ;
280
- assert ! ( with_auth. auth. is_some( ) ) ;
281
- let auth = with_auth. auth . unwrap ( ) ;
282
- assert_eq ! ( & auth. username, "username" ) ;
283
- assert_eq ! ( & auth. password, "password" ) ;
284
- }
285
-
286
- #[ test]
287
- fn test_into_impl ( ) {
288
- let client = Client :: new ( "http://localhost:8068" , "database" ) ;
289
- assert ! ( client. auth. is_none( ) ) ;
290
- let basic_parameters: Vec < ( String , String ) > = client. into ( ) ;
291
- assert_eq ! (
292
- vec![ ( "db" . to_string( ) , "database" . to_string( ) ) ] ,
293
- basic_parameters
294
- ) ;
295
-
296
- let with_auth =
297
- Client :: new ( "http://localhost:8068" , "database" ) . with_auth ( "username" , "password" ) ;
298
- let basic_parameters_with_auth: Vec < ( String , String ) > = with_auth. into ( ) ;
299
- assert_eq ! (
300
- vec![
301
- ( "db" . to_string( ) , "database" . to_string( ) ) ,
302
- ( "u" . to_string( ) , "username" . to_string( ) ) ,
303
- ( "p" . to_string( ) , "password" . to_string( ) )
304
- ] ,
305
- basic_parameters_with_auth
306
- ) ;
307
-
308
- let client = Client :: new ( "http://localhost:8068" , "database" ) ;
309
- assert ! ( client. auth. is_none( ) ) ;
310
- let basic_parameters: Vec < ( String , String ) > = ( & client) . into ( ) ;
311
- assert_eq ! (
312
- vec![ ( "db" . to_string( ) , "database" . to_string( ) ) ] ,
313
- basic_parameters
314
- ) ;
252
+ assert_eq ! ( vec![ ( "db" , "database" . to_string( ) ) ] , * client. parameters) ;
315
253
316
- let with_auth =
317
- Client :: new ( "http://localhost:8068" , "database" ) . with_auth ( "username" , "password" ) ;
318
- let basic_parameters_with_auth: Vec < ( String , String ) > = ( & with_auth) . into ( ) ;
254
+ let with_auth = client. with_auth ( "username" , "password" ) ;
319
255
assert_eq ! (
320
256
vec![
321
- ( "db" . to_string ( ) , "database" . to_string( ) ) ,
322
- ( "u" . to_string ( ) , "username" . to_string( ) ) ,
323
- ( "p" . to_string ( ) , "password" . to_string( ) )
257
+ ( "db" , "database" . to_string( ) ) ,
258
+ ( "u" , "username" . to_string( ) ) ,
259
+ ( "p" , "password" . to_string( ) )
324
260
] ,
325
- basic_parameters_with_auth
261
+ * with_auth . parameters
326
262
) ;
327
263
}
328
264
}
0 commit comments