1515//! assert_eq!(client.database_name(), "test");
1616//! ```
1717
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 } ;
2320
2421use crate :: query:: QueryTypes ;
2522use crate :: Error ;
@@ -130,29 +127,27 @@ impl Client {
130127 /// Pings the InfluxDB Server
131128 ///
132129 /// 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
153133 . map_err ( |err| Error :: ProtocolError {
154134 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 ( ) ) )
156151 }
157152
158153 /// Sends a [`ReadQuery`](crate::ReadQuery) or [`WriteQuery`](crate::WriteQuery) to the InfluxDB Server.
@@ -165,56 +160,47 @@ impl Client {
165160 ///
166161 /// # Examples
167162 ///
168- /// ```rust
163+ /// ```rust,no_run
169164 /// use influxdb::{Client, Query, Timestamp};
170165 ///
166+ /// # #[tokio::main]
167+ /// # async fn main() -> Result<(), failure::Error> {
171168 /// 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+ /// # }
176174 /// ```
177175 /// # Errors
178176 ///
179177 /// If the function can not finish the query,
180178 /// a [`Error`] variant will be returned.
181179 ///
182180 /// [`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 >
184182 where
185183 Q : Query ,
186184 & ' q Q : Into < QueryTypes < ' q > > ,
187185 {
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+ } ) ?;
199189
200190 let basic_parameters: Vec < ( String , String ) > = self . into ( ) ;
201191
202192 let client = match q. into ( ) {
203193 QueryTypes :: Read ( _) => {
204194 let read_query = query. get ( ) ;
205- let mut url = match Url :: parse_with_params (
195+ let mut url = Url :: parse_with_params (
206196 format ! ( "{url}/query" , url = self . database_url( ) ) . as_str ( ) ,
207197 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) ;
218204
219205 if read_query. contains ( "SELECT" ) || read_query. contains ( "SHOW" ) {
220206 ReqwestClient :: new ( ) . get ( url)
@@ -223,65 +209,44 @@ impl Client {
223209 }
224210 }
225211 QueryTypes :: Write ( write_query) => {
226- let mut url = match Url :: parse_with_params (
212+ let mut url = Url :: parse_with_params (
227213 format ! ( "{url}/write" , url = self . database_url( ) ) . as_str ( ) ,
228214 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+
238220 url. query_pairs_mut ( )
239221 . append_pair ( "precision" , & write_query. get_precision ( ) ) ;
222+
240223 ReqwestClient :: new ( ) . post ( url) . body ( query. get ( ) )
241224 }
242225 } ;
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)
285250 }
286251}
287252
0 commit comments