1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
use std::{
    borrow::Cow,
    fmt::{self, Display},
};

use derive_builder::Builder;
use itertools::Itertools;
use log::*;
use thiserror::Error;

#[cfg(not(feature = "rest"))]
pub mod bindings;

#[cfg(not(feature = "rest"))]
mod util;
#[cfg(not(feature = "rest"))]
pub(crate) use util::*;

mod error;
mod timestamp;
pub use timestamp::*;

pub mod field;
#[cfg(feature = "rest")]
mod rest;
#[cfg(feature = "rest")]
pub use rest::*;

#[cfg(not(feature = "rest"))]
mod client;
#[cfg(not(feature = "rest"))]
pub use client::*;

#[cfg(all(not(feature = "rest"), feature = "stmt"))]
pub mod stmt;

pub use error::*;
pub use field::*;

#[derive(Error, Debug)]
pub enum Error {
    #[error("cannot get TDengine connection")]
    ConnectionInvalid,
    #[error("taos error: {0}")]
    RawTaosError(#[from] TaosError),
    #[cfg(feature = "rest")]
    #[error("rest error: {0}")]
    RestApiError(#[from] reqwest::Error),
}

#[derive(Error, Debug)]
pub struct TaosError {
    pub code: TaosCode,
    pub err: Cow<'static, str>,
}

impl Display for TaosError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "[{}] {}", self.code, self.err)
    }
}

#[derive(Builder, Debug)]
#[builder(setter(into))]
pub struct TaosCfg {
    ip: String,
    user: String,
    pass: String,
    #[builder(setter(strip_option))]
    db: Option<String>,
    port: u16,
}

impl TaosCfg {
    #[cfg(feature = "rest")]
    pub fn connect(&self) -> Result<Taos, Error> {
        Ok(Taos::new(
            format!("http://{}:{}/rest/sql", self.ip, self.port + 11),
            self.user.clone(),
            self.pass.clone(),
        ))
    }

    #[cfg(not(feature = "rest"))]
    pub fn connect(&self) -> Result<Taos, Error> {
        let default_db = "log".to_string();
        Taos::new(
            &self.ip,
            &self.user,
            &self.pass,
            self.db.as_ref().unwrap_or(&default_db),
            self.port,
        )
    }
}

#[cfg(feature = "r2d2")]
pub type TaosPool = r2d2::Pool<TaosCfg>;

#[cfg(feature = "r2d2")]
impl r2d2::ManageConnection for TaosCfg {
    type Connection = Taos;
    type Error = Error;

    fn connect(&self) -> Result<Self::Connection, Self::Error> {
        self.connect()
    }

    fn is_valid(&self, conn: &mut Self::Connection) -> Result<(), Self::Error> {
        Ok(())
    }

    fn has_broken(&self, _: &mut Self::Connection) -> bool {
        false
    }
}

#[cfg(test)]
pub mod test;