Rust连接Clickhouse

Clickhouse兼容Rust的官网有三种方式,以下方式是唯一可以调通的,希望对大家有帮助

use core::panic;

use actix_http::Request;
use chrono::Utc;
use futures::StreamExt;
use klickhouse::*;
use std::collections::HashMap;
use std::collections::HashSet;
use actix_web::*;
use serde::{Deserialize, Serialize};
use serde_json::json;
use tracing::{error, info};
use crate::error::{RecloudError, StandardResp};
use crate::server;

use super::super::AppState;

use klickhouse::{Client, Row};
// use clickhouse::{Client, Row};

pub async fn query<T: Row>(sql: &str, client: &Client) -> anyhow::Result<Option<Vec<T>>> {
    let mut result = Vec::new();
    let mut rows = client.query::<T>(sql).await?;
    while let Some(row) = rows.next().await {
        result.push(row?);
    }
    if result.len() == 0 {
        return Ok(None);
    }
    Ok(Some(result))
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Resp {
    pub data: Vec<Option<Vec<ChRes>>>,
}

#[derive(Debug, Serialize, Deserialize, Row, Clone)]
pub struct ChRes {
    pub carno: String,
    pub mile: f64,
}

#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct CkData {
    car_no_list: Vec<String>,
    durations: Vec<Vec<String>>,
}



#[post("/get_ck_info")]
pub async fn get_ck_info(
    // data: web::Data<AppState>,
    request: web::Json<CkData>,
) -> std::result::Result<HttpResponse, RecloudError> {
    let tmp = (1, "", true);
    println!("{:?}", tmp.1);

    info!("inside get_ck_info");
    let client = Client::connect("172.16.xxx.xx:9000", ClientOptions::default())
        .await
        .unwrap();


    let car_no_list = request
        .car_no_list
        .iter()
        .map(|carno: &String| format!("'{}'", carno))
        .collect::<Vec<_>>()
        .join(",");

    let mut res_map: HashMap<String, Vec<f64>> = HashMap::new();
    let carno = request.car_no_list[0].clone();
    let mut res_list: Vec<f64> = vec![];

    for duration in &request.durations {
        let sql = format!(
            r#"select carno,
                    max(acc_power_left) - min(acc_power_left) as mile
                from table
                where carno in ({}) 
                and car_time >= '{}'
                and car_time <= '{}'
                group by carno
                "#,
            car_no_list, duration[0], duration[1]
        );
    
        let res = query::<ChRes>(&sql, &client).await;
        
        match res {
            Ok(Some(vec)) => {
                info!("{:?}", vec);
                res_list.extend(vec.iter().map(|r| r.mile.clone()).collect::<Vec<f64>>());
            }
            Ok(None) => {
                println!("Option is None");
            }
            Err(e) => return Err(RecloudError::QueryError),
        }
    }
    res_map.insert(carno.clone(), res_list);
    Ok(HttpResponse::Ok().json(StandardResp::success(Some(json!(res_map)))))
}



pub fn get_ck_info_api() -> Scope {
    web::scope("").service(get_ck_info)
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值