Skip to main content

rsiot/components/cmp_tsdb_writer/
config.rs

1use std::time::Duration;
2
3use crate::message::MsgDataBound;
4
5use super::{Error, QueryStat};
6
7// ANCHOR: Config
8/// Конфигурация компонента cmp_timescaledb
9#[derive(Clone, Debug)]
10pub struct Config<TMsg>
11where
12    TMsg: MsgDataBound,
13{
14    /// Строка подключения к БД
15    ///
16    /// Примеры:
17    ///
18    /// - ```String::from("postgres://user:password@localhost:5432/db_name")```
19    pub connection_string: String,
20
21    /// Максимальное количество подключений к БД
22    ///
23    /// Можно выставить значение "10"
24    pub max_connections: u32,
25
26    /// Название таблицы для сохранения данных
27    pub tables: Vec<ConfigTable<TMsg>>,
28
29    /// Отправить в базу данных, если в кеше присутствует больше указанного количества строк
30    pub save_by_row_count: usize,
31
32    /// Отправить в базу даннных, если с последнего сохранения прошло более указанного времени
33    ///
34    /// Предпочтительно, чтобы данные сохранялись в БД по полю `save_by_row_count`
35    pub save_by_period: Duration,
36
37    /// Функция для вывода статистики выполнения запросов
38    pub fn_query_stat: fn(QueryStat),
39}
40// ANCHOR: Config
41
42/// Конфигурация таблицы для сохранения данных в БД
43#[derive(Clone, Debug)]
44pub struct ConfigTable<TMsg>
45where
46    TMsg: MsgDataBound,
47{
48    /// Проект
49    pub prj: String,
50
51    /// Хост
52    pub hst: String,
53
54    /// Сервис
55    pub svc: String,
56
57    /// Компонент
58    pub cmp: String,
59
60    /// Тег
61    pub tag: String,
62
63    /// Разделение на части по времени
64    pub chunk_interval: Duration,
65
66    /// Сжимать данные через указанный интервал после записи
67    pub compress_interval: Duration,
68
69    /// Удалять данные старше указанного интервала. Если не указано, то данные не удаляются
70    pub retention_interval: Option<Duration>,
71
72    /// Поля таблицы
73    pub fields: Vec<ConfigTableField>,
74
75    /// Функция преобразования сообщений в строки для Timescaledb
76    pub fn_input: fn(&TMsg) -> Result<Option<String>, Error>,
77
78    /// Удалить таблицу перед записью
79    pub delete_before_write: bool,
80}
81impl<TMsg> ConfigTable<TMsg>
82where
83    TMsg: MsgDataBound,
84{
85    /// Название таблицы в БД
86    pub fn table_name(&self) -> String {
87        format!(
88            "{}${}${}${}${}",
89            self.prj, self.hst, self.svc, self.cmp, self.tag
90        )
91    }
92}
93
94/// Конфигурация поля таблицы
95#[derive(Clone, Debug)]
96pub struct ConfigTableField {
97    /// Название поля таблицы
98    pub field_name: String,
99
100    /// Тип поля таблицы
101    pub data_type: ConfigTableFieldType,
102}
103
104/// Тип поля таблицы
105#[derive(Clone, Debug)]
106pub enum ConfigTableFieldType {
107    /// Произвольный текст
108    CharacterText,
109
110    /// 4 байта
111    NumericInteger,
112
113    /// 8 байт
114    NumericDoublePrecision,
115
116    /// 1 байт
117    Boolean,
118}
119impl ConfigTableFieldType {
120    /// Преобразование типа поля в тип PostgreSQL
121    pub fn into_pg_type(&self) -> &'static str {
122        match self {
123            Self::CharacterText => "TEXT",
124            Self::NumericInteger => "INTEGER",
125            Self::NumericDoublePrecision => "DOUBLE PRECISION",
126            Self::Boolean => "BOOLEAN",
127        }
128    }
129}
130
131pub(crate) struct ConfigTableForSetup {
132    pub table_name: String,
133    pub delete_before_write: bool,
134    pub chunk_interval: Duration,
135    pub compress_interval: Duration,
136    pub retention_interval: Option<Duration>,
137    pub values: Vec<ConfigTableField>,
138}
139
140impl<TMsg> From<&ConfigTable<TMsg>> for ConfigTableForSetup
141where
142    TMsg: MsgDataBound,
143{
144    fn from(config_table: &ConfigTable<TMsg>) -> Self {
145        ConfigTableForSetup {
146            table_name: config_table.table_name(),
147            delete_before_write: config_table.delete_before_write,
148            chunk_interval: config_table.chunk_interval,
149            compress_interval: config_table.compress_interval,
150            retention_interval: config_table.retention_interval,
151            values: config_table.fields.clone(),
152        }
153    }
154}