16
16
//! ```
17
17
18
18
use futures:: prelude:: * ;
19
- use reqwest :: { self , Client as ReqwestClient , StatusCode } ;
19
+ use surf :: { self , Client as SurfClient , StatusCode } ;
20
20
21
21
use crate :: query:: QueryTypes ;
22
22
use crate :: Error ;
23
23
use crate :: Query ;
24
+ use std:: collections:: HashMap ;
24
25
use std:: sync:: Arc ;
25
26
26
27
#[ derive( Clone , Debug ) ]
27
28
/// Internal Representation of a Client
28
29
pub struct Client {
29
30
pub ( crate ) url : Arc < String > ,
30
- pub ( crate ) parameters : Arc < Vec < ( & ' static str , String ) > > ,
31
- pub ( crate ) client : ReqwestClient ,
31
+ pub ( crate ) parameters : Arc < HashMap < & ' static str , String > > ,
32
+ pub ( crate ) client : SurfClient ,
32
33
}
33
34
34
35
impl Client {
@@ -51,10 +52,12 @@ impl Client {
51
52
S1 : Into < String > ,
52
53
S2 : Into < String > ,
53
54
{
55
+ let mut parameters = HashMap :: < & str , String > :: new ( ) ;
56
+ parameters. insert ( "db" , database. into ( ) ) ;
54
57
Client {
55
58
url : Arc :: new ( url. into ( ) ) ,
56
- parameters : Arc :: new ( vec ! [ ( "db" , database . into ( ) ) ] ) ,
57
- client : ReqwestClient :: new ( ) ,
59
+ parameters : Arc :: new ( parameters ) ,
60
+ client : SurfClient :: new ( ) ,
58
61
}
59
62
}
60
63
@@ -78,16 +81,16 @@ impl Client {
78
81
S2 : Into < String > ,
79
82
{
80
83
let mut with_auth = self . parameters . as_ref ( ) . clone ( ) ;
81
- with_auth. push ( ( "u" , username. into ( ) ) ) ;
82
- with_auth. push ( ( "p" , password. into ( ) ) ) ;
84
+ with_auth. insert ( "u" , username. into ( ) ) ;
85
+ with_auth. insert ( "p" , password. into ( ) ) ;
83
86
self . parameters = Arc :: new ( with_auth) ;
84
87
self
85
88
}
86
89
87
90
/// Returns the name of the database the client is using
88
91
pub fn database_name ( & self ) -> & str {
89
92
// safe to unwrap: we always set the database name in `Self::new`
90
- & self . parameters . first ( ) . unwrap ( ) . 1
93
+ self . parameters . get ( "db" ) . unwrap ( )
91
94
}
92
95
93
96
/// Returns the URL of the InfluxDB installation the client is using
@@ -109,18 +112,8 @@ impl Client {
109
112
error : format ! ( "{}" , err) ,
110
113
} ) ?;
111
114
112
- let build = res
113
- . headers ( )
114
- . get ( "X-Influxdb-Build" )
115
- . unwrap ( )
116
- . to_str ( )
117
- . unwrap ( ) ;
118
- let version = res
119
- . headers ( )
120
- . get ( "X-Influxdb-Version" )
121
- . unwrap ( )
122
- . to_str ( )
123
- . unwrap ( ) ;
115
+ let build = res. header ( "X-Influxdb-Build" ) . unwrap ( ) . as_str ( ) ;
116
+ let version = res. header ( "X-Influxdb-Version" ) . unwrap ( ) . as_str ( ) ;
124
117
125
118
Ok ( ( build. to_owned ( ) , version. to_owned ( ) ) )
126
119
}
@@ -140,7 +133,7 @@ impl Client {
140
133
/// use influxdb::InfluxDbWriteable;
141
134
/// use std::time::{SystemTime, UNIX_EPOCH};
142
135
///
143
- /// # #[tokio ::main]
136
+ /// # #[async_std ::main]
144
137
/// # async fn main() -> Result<(), influxdb::Error> {
145
138
/// let start = SystemTime::now();
146
139
/// let since_the_epoch = start
@@ -169,60 +162,55 @@ impl Client {
169
162
& ' q Q : Into < QueryTypes < ' q > > ,
170
163
{
171
164
let query = q. build ( ) . map_err ( |err| Error :: InvalidQueryError {
172
- error : format ! ( "{}" , err) ,
165
+ error : err. to_string ( ) ,
173
166
} ) ?;
174
167
175
168
let request_builder = match q. into ( ) {
176
169
QueryTypes :: Read ( _) => {
177
170
let read_query = query. get ( ) ;
178
171
let url = & format ! ( "{}/query" , & self . url) ;
179
- let query = [ ( "q" , & read_query) ] ;
172
+ let mut parameters = self . parameters . as_ref ( ) . clone ( ) ;
173
+ parameters. insert ( "q" , read_query. clone ( ) ) ;
180
174
181
175
if read_query. contains ( "SELECT" ) || read_query. contains ( "SHOW" ) {
182
- self . client
183
- . get ( url)
184
- . query ( self . parameters . as_ref ( ) )
185
- . query ( & query)
176
+ self . client . get ( url) . query ( & parameters)
186
177
} else {
187
- self . client
188
- . post ( url)
189
- . query ( self . parameters . as_ref ( ) )
190
- . query ( & query)
178
+ self . client . post ( url) . query ( & parameters)
191
179
}
192
180
}
193
181
QueryTypes :: Write ( write_query) => {
194
182
let url = & format ! ( "{}/write" , & self . url) ;
195
- let precision = [ ( "precision" , write_query. get_precision ( ) ) ] ;
183
+ let mut parameters = self . parameters . as_ref ( ) . clone ( ) ;
184
+ parameters. insert ( "precision" , write_query. get_precision ( ) ) ;
196
185
197
- self . client
198
- . post ( url)
199
- . query ( self . parameters . as_ref ( ) )
200
- . query ( & precision)
201
- . body ( query. get ( ) )
186
+ self . client . post ( url) . body ( query. get ( ) ) . query ( & parameters)
202
187
}
203
- } ;
204
-
205
- let request = request_builder
206
- . build ( )
207
- . map_err ( |err| Error :: UrlConstructionError {
208
- error : format ! ( "{}" , & err) ,
209
- } ) ?;
188
+ }
189
+ . map_err ( |err| Error :: UrlConstructionError {
190
+ error : err. to_string ( ) ,
191
+ } ) ?;
210
192
211
- let res = self
193
+ let request = request_builder. build ( ) ;
194
+ let mut res = self
212
195
. client
213
- . execute ( request)
214
- . map_err ( |err| Error :: ConnectionError { error : err } )
196
+ . send ( request)
197
+ . map_err ( |err| Error :: ConnectionError {
198
+ error : err. to_string ( ) ,
199
+ } )
215
200
. await ?;
216
201
217
202
match res. status ( ) {
218
- StatusCode :: UNAUTHORIZED => return Err ( Error :: AuthorizationError ) ,
219
- StatusCode :: FORBIDDEN => return Err ( Error :: AuthenticationError ) ,
203
+ StatusCode :: Unauthorized => return Err ( Error :: AuthorizationError ) ,
204
+ StatusCode :: Forbidden => return Err ( Error :: AuthenticationError ) ,
220
205
_ => { }
221
206
}
222
207
223
- let s = res. text ( ) . await . map_err ( |_| Error :: DeserializationError {
224
- error : "response could not be converted to UTF-8" . to_string ( ) ,
225
- } ) ?;
208
+ let s = res
209
+ . body_string ( )
210
+ . await
211
+ . map_err ( |_| Error :: DeserializationError {
212
+ error : "response could not be converted to UTF-8" . to_string ( ) ,
213
+ } ) ?;
226
214
227
215
// todo: improve error parsing without serde
228
216
if s. contains ( "\" error\" " ) {
@@ -249,16 +237,13 @@ mod tests {
249
237
#[ test]
250
238
fn test_with_auth ( ) {
251
239
let client = Client :: new ( "http://localhost:8068" , "database" ) ;
252
- assert_eq ! ( vec![ ( "db" , "database" . to_string( ) ) ] , * client. parameters) ;
240
+ assert_eq ! ( client. parameters. len( ) , 1 ) ;
241
+ assert_eq ! ( client. parameters. get( "db" ) . unwrap( ) , "database" ) ;
253
242
254
243
let with_auth = client. with_auth ( "username" , "password" ) ;
255
- assert_eq ! (
256
- vec![
257
- ( "db" , "database" . to_string( ) ) ,
258
- ( "u" , "username" . to_string( ) ) ,
259
- ( "p" , "password" . to_string( ) )
260
- ] ,
261
- * with_auth. parameters
262
- ) ;
244
+ assert_eq ! ( with_auth. parameters. len( ) , 3 ) ;
245
+ assert_eq ! ( with_auth. parameters. get( "db" ) . unwrap( ) , "database" ) ;
246
+ assert_eq ! ( with_auth. parameters. get( "u" ) . unwrap( ) , "username" ) ;
247
+ assert_eq ! ( with_auth. parameters. get( "p" ) . unwrap( ) , "password" ) ;
263
248
}
264
249
}
0 commit comments