15
15
//! assert_eq!(client.database_name(), "test");
16
16
//! ```
17
17
18
- use futures:: { Future , Stream } ;
19
- use reqwest:: r#async:: { Client as ReqwestClient , Decoder } ;
20
- use reqwest:: { StatusCode , Url } ;
21
-
22
- use std:: mem;
18
+ use futures:: prelude:: * ;
19
+ use reqwest:: { self , Client as ReqwestClient , StatusCode , Url } ;
23
20
24
21
use crate :: query:: QueryTypes ;
25
22
use crate :: Error ;
@@ -130,29 +127,27 @@ impl Client {
130
127
/// Pings the InfluxDB Server
131
128
///
132
129
/// Returns a tuple of build type and version number
133
- pub fn ping ( & self ) -> impl Future < Item = ( String , String ) , Error = Error > + Send {
134
- ReqwestClient :: new ( )
135
- . get ( format ! ( "{}/ping" , self . url) . as_str ( ) )
136
- . send ( )
137
- . map ( |res| {
138
- let build = res
139
- . headers ( )
140
- . get ( "X-Influxdb-Build" )
141
- . unwrap ( )
142
- . to_str ( )
143
- . unwrap ( ) ;
144
- let version = res
145
- . headers ( )
146
- . get ( "X-Influxdb-Version" )
147
- . unwrap ( )
148
- . to_str ( )
149
- . unwrap ( ) ;
150
-
151
- ( String :: from ( build) , String :: from ( version) )
152
- } )
130
+ pub async fn ping ( & self ) -> Result < ( String , String ) , Error > {
131
+ let res = reqwest:: get ( format ! ( "{}/ping" , self . url) . as_str ( ) )
132
+ . await
153
133
. map_err ( |err| Error :: ProtocolError {
154
134
error : format ! ( "{}" , err) ,
155
- } )
135
+ } ) ?;
136
+
137
+ let build = res
138
+ . headers ( )
139
+ . get ( "X-Influxdb-Build" )
140
+ . unwrap ( )
141
+ . to_str ( )
142
+ . unwrap ( ) ;
143
+ let version = res
144
+ . headers ( )
145
+ . get ( "X-Influxdb-Version" )
146
+ . unwrap ( )
147
+ . to_str ( )
148
+ . unwrap ( ) ;
149
+
150
+ Ok ( ( build. to_owned ( ) , version. to_owned ( ) ) )
156
151
}
157
152
158
153
/// Sends a [`ReadQuery`](crate::ReadQuery) or [`WriteQuery`](crate::WriteQuery) to the InfluxDB Server.
@@ -165,56 +160,47 @@ impl Client {
165
160
///
166
161
/// # Examples
167
162
///
168
- /// ```rust
163
+ /// ```rust,no_run
169
164
/// use influxdb::{Client, Query, Timestamp};
170
165
///
166
+ /// # #[tokio::main]
167
+ /// # async fn main() -> Result<(), failure::Error> {
171
168
/// let client = Client::new("http://localhost:8086", "test");
172
- /// let _future = client.query(
173
- /// &Query::write_query(Timestamp::Now, "weather")
174
- /// .add_field("temperature", 82)
175
- /// );
169
+ /// let query = Query::write_query(Timestamp::Now, "weather")
170
+ /// .add_field("temperature", 82);
171
+ /// let results = client.query(&query).await?;
172
+ /// # Ok(())
173
+ /// # }
176
174
/// ```
177
175
/// # Errors
178
176
///
179
177
/// If the function can not finish the query,
180
178
/// a [`Error`] variant will be returned.
181
179
///
182
180
/// [`Error`]: enum.Error.html
183
- pub fn query < ' q , Q > ( & self , q : & ' q Q ) -> Box < dyn Future < Item = String , Error = Error > + Send >
181
+ pub async fn query < ' q , Q > ( & self , q : & ' q Q ) -> Result < String , Error >
184
182
where
185
183
Q : Query ,
186
184
& ' q Q : Into < QueryTypes < ' q > > ,
187
185
{
188
- use futures:: future;
189
-
190
- let query = match q. build ( ) {
191
- Err ( err) => {
192
- let error = Error :: InvalidQueryError {
193
- error : format ! ( "{}" , err) ,
194
- } ;
195
- return Box :: new ( future:: err :: < String , Error > ( error) ) ;
196
- }
197
- Ok ( query) => query,
198
- } ;
186
+ let query = q. build ( ) . map_err ( |err| Error :: InvalidQueryError {
187
+ error : format ! ( "{}" , err) ,
188
+ } ) ?;
199
189
200
190
let basic_parameters: Vec < ( String , String ) > = self . into ( ) ;
201
191
202
192
let client = match q. into ( ) {
203
193
QueryTypes :: Read ( _) => {
204
194
let read_query = query. get ( ) ;
205
- let mut url = match Url :: parse_with_params (
195
+ let mut url = Url :: parse_with_params (
206
196
format ! ( "{url}/query" , url = self . database_url( ) ) . as_str ( ) ,
207
197
basic_parameters,
208
- ) {
209
- Ok ( url) => url,
210
- Err ( err) => {
211
- let error = Error :: UrlConstructionError {
212
- error : format ! ( "{}" , err) ,
213
- } ;
214
- return Box :: new ( future:: err :: < String , Error > ( error) ) ;
215
- }
216
- } ;
217
- url. query_pairs_mut ( ) . append_pair ( "q" , & read_query. clone ( ) ) ;
198
+ )
199
+ . map_err ( |err| Error :: UrlConstructionError {
200
+ error : format ! ( "{}" , err) ,
201
+ } ) ?;
202
+
203
+ url. query_pairs_mut ( ) . append_pair ( "q" , & read_query) ;
218
204
219
205
if read_query. contains ( "SELECT" ) || read_query. contains ( "SHOW" ) {
220
206
ReqwestClient :: new ( ) . get ( url)
@@ -223,65 +209,44 @@ impl Client {
223
209
}
224
210
}
225
211
QueryTypes :: Write ( write_query) => {
226
- let mut url = match Url :: parse_with_params (
212
+ let mut url = Url :: parse_with_params (
227
213
format ! ( "{url}/write" , url = self . database_url( ) ) . as_str ( ) ,
228
214
basic_parameters,
229
- ) {
230
- Ok ( url) => url,
231
- Err ( err) => {
232
- let error = Error :: InvalidQueryError {
233
- error : format ! ( "{}" , err) ,
234
- } ;
235
- return Box :: new ( future:: err :: < String , Error > ( error) ) ;
236
- }
237
- } ;
215
+ )
216
+ . map_err ( |err| Error :: InvalidQueryError {
217
+ error : format ! ( "{}" , err) ,
218
+ } ) ?;
219
+
238
220
url. query_pairs_mut ( )
239
221
. append_pair ( "precision" , & write_query. get_precision ( ) ) ;
222
+
240
223
ReqwestClient :: new ( ) . post ( url) . body ( query. get ( ) )
241
224
}
242
225
} ;
243
- Box :: new (
244
- client
245
- . send ( )
246
- . map_err ( |err| Error :: ConnectionError { error : err } )
247
- . and_then (
248
- |res| -> future:: FutureResult < reqwest:: r#async:: Response , Error > {
249
- match res. status ( ) {
250
- StatusCode :: UNAUTHORIZED => {
251
- futures:: future:: err ( Error :: AuthorizationError )
252
- }
253
- StatusCode :: FORBIDDEN => {
254
- futures:: future:: err ( Error :: AuthenticationError )
255
- }
256
- _ => futures:: future:: ok ( res) ,
257
- }
258
- } ,
259
- )
260
- . and_then ( |mut res| {
261
- let body = mem:: replace ( res. body_mut ( ) , Decoder :: empty ( ) ) ;
262
- body. concat2 ( ) . map_err ( |err| Error :: ProtocolError {
263
- error : format ! ( "{}" , err) ,
264
- } )
265
- } )
266
- . and_then ( |body| {
267
- if let Ok ( utf8) = std:: str:: from_utf8 ( & body) {
268
- let s = utf8. to_owned ( ) ;
269
-
270
- // todo: improve error parsing without serde
271
- if s. contains ( "\" error\" " ) {
272
- return futures:: future:: err ( Error :: DatabaseError {
273
- error : format ! ( "influxdb error: \" {}\" " , s) ,
274
- } ) ;
275
- }
276
-
277
- return futures:: future:: ok ( s) ;
278
- }
279
-
280
- futures:: future:: err ( Error :: DeserializationError {
281
- error : "response could not be converted to UTF-8" . to_string ( ) ,
282
- } )
283
- } ) ,
284
- )
226
+
227
+ let res = client
228
+ . send ( )
229
+ . map_err ( |err| Error :: ConnectionError { error : err } )
230
+ . await ?;
231
+
232
+ match res. status ( ) {
233
+ StatusCode :: UNAUTHORIZED => return Err ( Error :: AuthorizationError ) ,
234
+ StatusCode :: FORBIDDEN => return Err ( Error :: AuthenticationError ) ,
235
+ _ => { }
236
+ }
237
+
238
+ let s = res. text ( ) . await . map_err ( |_| Error :: DeserializationError {
239
+ error : "response could not be converted to UTF-8" . to_string ( ) ,
240
+ } ) ?;
241
+
242
+ // todo: improve error parsing without serde
243
+ if s. contains ( "\" error\" " ) {
244
+ return Err ( Error :: DatabaseError {
245
+ error : format ! ( "influxdb error: \" {}\" " , s) ,
246
+ } ) ;
247
+ }
248
+
249
+ Ok ( s)
285
250
}
286
251
}
287
252
0 commit comments