1use crate::schema::{metric_keys, metrics};
3use crate::{MetricsError, Result};
4use ::metrics::Unit;
5use diesel::prelude::*;
6use std::borrow::Cow;
7
8#[derive(Insertable, Debug)]
10#[diesel(table_name = metrics)]
11pub struct NewMetric {
12 pub timestamp: f64,
14 pub metric_key_id: i64,
16 pub value: f64,
18}
19
20#[derive(Insertable, Debug)]
22#[diesel(table_name = metric_keys)]
23pub struct NewMetricKey<'a> {
24 pub key: Cow<'a, str>,
26 pub unit: Cow<'a, str>,
28 pub description: Cow<'a, str>,
30}
31
32#[derive(Queryable, Debug, Identifiable)]
34#[cfg_attr(feature = "serde", derive(serde::Serialize))]
35pub struct MetricKey<'a> {
36 pub id: i64,
38 pub key: Cow<'a, str>,
40 pub unit: Cow<'a, str>,
42 pub description: Cow<'a, str>,
44}
45impl<'a> MetricKey<'a> {
46 pub(crate) fn create_or_update(
47 key_name: &str,
48 unit: Option<Unit>,
49 description: Option<&'a str>,
50 db: &mut SqliteConnection,
51 ) -> Result<MetricKey<'a>> {
52 let key = Self::key_by_name(key_name, db)?;
53 let unit_value = unit
54 .map(|u| Cow::Owned(u.as_str().to_string()))
55 .unwrap_or(Cow::Borrowed(""));
56 let description = description.map(Cow::Borrowed).unwrap_or(Cow::Borrowed(""));
57 Self::update(key.id, unit_value, description, db)?;
58 Ok(key)
59 }
60 fn update(
61 id_value: i64,
62 unit_value: Cow<'a, str>,
63 description_value: Cow<'a, str>,
64 db: &mut SqliteConnection,
65 ) -> Result<()> {
66 use crate::schema::metric_keys::dsl::*;
67 diesel::update(metric_keys.filter(id.eq(id_value)))
68 .set((unit.eq(unit_value), description.eq(description_value)))
69 .execute(db)?;
70 Ok(())
71 }
72 pub(crate) fn key_by_name(key_name: &str, db: &mut SqliteConnection) -> Result<MetricKey<'a>> {
73 use crate::schema::metric_keys::dsl::metric_keys;
74 match Self::key_by_name_inner(key_name, db) {
75 Ok(key) => Ok(key),
76 Err(MetricsError::KeyNotFound(_)) => {
77 let new_key = NewMetricKey {
79 key: Cow::Borrowed(key_name),
80 unit: Cow::Borrowed(""),
81 description: Cow::Borrowed(""),
82 };
83 new_key.insert_into(metric_keys).execute(db)?;
84 Self::key_by_name_inner(key_name, db)
86 }
87 Err(e) => Err(e),
88 }
89 }
90 fn key_by_name_inner(key_name: &str, db: &mut SqliteConnection) -> Result<MetricKey<'a>> {
91 use crate::schema::metric_keys::dsl::*;
92 let query = metric_keys.filter(key.eq(key_name));
93 let keys = query.load::<MetricKey>(db)?;
94 keys.into_iter()
95 .next()
96 .ok_or_else(|| MetricsError::KeyNotFound(key_name.to_string()))
97 }
98}
99
100#[derive(Queryable, Debug, Identifiable, Associations)]
102#[diesel(belongs_to(MetricKey<'_>))]
103#[cfg_attr(feature = "serde", derive(serde::Serialize))]
104pub struct Metric {
105 pub id: i64,
107 pub timestamp: f64,
109 pub metric_key_id: i64,
111 pub value: f64,
113}