Documentation
use crate::config::ClickHouseConfig;
use crate::static_def::BASE_CONFIG;
use anyhow::Result;
use clickhouse::{Client, RowOwned, RowRead};

/// Clickhouse 查询
pub struct ClickHouseDB {
    client: Client,
}

impl ClickHouseDB {
    pub fn new(config: &ClickHouseConfig) -> Self {
        let client = Client::default()
            .with_user(&config.username)
            .with_password(&config.password)
            .with_database(&config.database)
            .with_url(&config.url);
        log::debug!("ClickHouseDB connected to {}", &config.url);
        Self { client }
    }

    /// 获取期牌数据
    #[inline]
    pub async fn get_drawing_data<T: RowOwned + RowRead>(
        &self,
        tag: i32,
        drawing: i32,
        index: i64,
        count: i64,
    ) -> Result<Vec<T>> {
        Ok(self
            .client
            .query(&format!(
                "select * from {} where tag=? and drawing=? and index>? order by index limit ?",
                BASE_CONFIG.drawing_table
            ))
            .bind(tag)
            .bind(drawing)
            .bind(index)
            .bind(count)
            .fetch_all()
            .await?)
    }

    /// 获取期牌数据
    #[inline]
    pub async fn get_drawing_data_by_index<T: RowOwned + RowRead>(
        &self,
        tag: i32,
        drawing: i32,
        index: i64,
    ) -> Result<Option<T>> {
        Ok(self
            .client
            .query(&format!(
                "select * from {} where tag=? and drawing=? and index=?",
                BASE_CONFIG.drawing_table
            ))
            .bind(tag)
            .bind(drawing)
            .bind(index)
            .fetch_optional()
            .await?)
    }

    /// 获取期牌期数集合
    #[inline]
    pub async fn get_drawing_ids(&self, tag: i32) -> Result<Vec<i32>> {
        Ok(self
            .client
            .query(&format!(
                "SELECT drawing FROM {} WHERE tag = ? GROUP BY drawing, drawing_per order by drawing",BASE_CONFIG.drawing_table
            ))
            .bind(tag)
            .fetch_all()
            .await?)
    }

    /// 获取期牌数量
    #[inline]
    pub async fn get_drawing_per(&self, tag: i32, drawing: i32) -> Result<i64> {
        Ok(self
            .client
            .query(&format!(
                "SELECT drawing_per FROM {} WHERE tag = ? and drawing = ? limit 1",
                BASE_CONFIG.drawing_table
            ))
            .bind(tag)
            .bind(drawing)
            .fetch_one()
            .await?)
    }
}