elefant_tools/models/
hypertable_compression.rs1use crate::helpers::StringExt;
2use crate::pg_interval::Interval;
3use crate::quoting::AttemptedKeywordUsage::ColumnName;
4use crate::quoting::{IdentifierQuoter, Quotable};
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Eq, PartialEq, Clone, Default, Serialize, Deserialize)]
8pub struct HypertableCompression {
9 pub enabled: bool,
10 pub segment_by_columns: Option<Vec<String>>,
11 pub order_by_columns: Option<Vec<HypertableCompressionOrderedColumn>>,
12 pub chunk_time_interval: Option<Interval>,
13 pub compression_schedule_interval: Option<Interval>,
14 pub compress_after: Option<Interval>,
15}
16
17#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize)]
18pub struct HypertableCompressionOrderedColumn {
19 pub column_name: String,
20 pub descending: bool,
21 pub nulls_first: bool,
22}
23
24impl Default for HypertableCompressionOrderedColumn {
25 fn default() -> Self {
26 Self {
27 column_name: "".to_string(),
28 descending: true,
29 nulls_first: true,
30 }
31 }
32}
33
34impl HypertableCompression {
35 pub fn add_compression_settings(
36 &self,
37 sql: &mut String,
38 escaped_relation_name: &str,
39 identifier_quoter: &IdentifierQuoter,
40 ) {
41 sql.push_str(escaped_relation_name);
42 sql.push_str(" set (\n\ttimescaledb.compress = ");
43 sql.push_str(&self.enabled.to_string());
44
45 if let Some(segment_by) = &self.segment_by_columns {
46 sql.push_str(",\n\ttimescaledb.compress_segmentby = '");
47 sql.push_join(
48 ", ",
49 segment_by
50 .iter()
51 .map(|c| c.quote(identifier_quoter, ColumnName)),
52 );
53 sql.push('\'');
54 }
55
56 if let Some(order_by) = &self.order_by_columns {
57 sql.push_str(",\n\ttimescaledb.compress_orderby = '");
58 for (idx, order_by) in order_by.iter().enumerate() {
59 if idx > 0 {
60 sql.push_str(", ");
61 }
62 sql.push_str(&order_by.column_name.quote(identifier_quoter, ColumnName));
63 if !order_by.descending {
64 sql.push_str(" ASC");
65 } else {
66 sql.push_str(" DESC");
67 }
68 if order_by.nulls_first {
69 sql.push_str(" NULLS FIRST");
70 } else {
71 sql.push_str(" NULLS LAST");
72 }
73 }
74 sql.push('\'');
75 }
76
77 if let Some(chunk_time_interval) = self.chunk_time_interval {
78 sql.push_str(",\n\ttimescaledb.compress_chunk_time_interval = '");
79 sql.push_str(&chunk_time_interval.to_postgres());
80 sql.push('\'');
81 }
82
83 sql.push_str("\n);");
84
85 if let Some(compress_after) = self.compress_after {
86 sql.push_str("\nselect public.add_compression_policy('");
87 sql.push_str(escaped_relation_name);
88 sql.push_str("', compress_after => INTERVAL '");
89 sql.push_str(&compress_after.to_postgres());
90 sql.push('\'');
91
92 if let Some(schedule_interval) = self.compression_schedule_interval {
93 sql.push_str(", schedule_interval => INTERVAL '");
94 sql.push_str(&schedule_interval.to_postgres());
95 sql.push('\'');
96 }
97
98 sql.push_str(");");
99 }
100 }
101}