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
use serde::{Deserialize, Serialize};
use std::time::Duration;

#[derive(Debug, Default, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TimePartitioning {
    /// [Optional] Number of milliseconds for which to keep the storage for partitions in the table. The storage in a partition will have an expiration time of its partition time plus this value.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub expiration_ms: Option<String>,
    /// [Beta] [Optional] If not set, the table is partitioned by pseudo column, referenced via either '_PARTITIONTIME' as TIMESTAMP type, or '_PARTITIONDATE' as DATE type. If field is specified, the table is instead partitioned by this field. The field must be a top-level TIMESTAMP or DATE field. Its mode must be NULLABLE or REQUIRED.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub field: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub require_partition_filter: Option<bool>,
    /// [Required] The supported types are DAY, HOUR, MONTH, and YEAR, which will generate one partition per day, hour, month, and year, respectively. When the type is not specified, the default behavior is DAY.
    #[serde(rename = "type")]
    pub r#type: String,
}

impl TimePartitioning {
    /// Creates a new time partitioning.
    /// # Argument
    /// * `type` - The type of the partitioning (HOUR, DAY, MONTH or YEAR)
    pub fn new(r#type: String) -> Self {
        Self {
            expiration_ms: None,
            field: None,
            require_partition_filter: None,
            r#type,
        }
    }

    /// Creates a time partitioning per hour.
    pub fn per_hour() -> Self {
        Self {
            expiration_ms: None,
            field: None,
            require_partition_filter: None,
            r#type: "HOUR".to_string(),
        }
    }

    /// Creates a time partitioning per day.
    pub fn per_day() -> Self {
        Self {
            expiration_ms: None,
            field: None,
            require_partition_filter: None,
            r#type: "DAY".to_string(),
        }
    }

    /// Creates a time partitioning per month.
    pub fn per_month() -> Self {
        Self {
            expiration_ms: None,
            field: None,
            require_partition_filter: None,
            r#type: "MONTH".to_string(),
        }
    }

    /// Creates a time partitioning per year.
    pub fn per_year() -> Self {
        Self {
            expiration_ms: None,
            field: None,
            require_partition_filter: None,
            r#type: "YEAR".to_string(),
        }
    }

    /// Sets the expiration time per partition
    pub fn expiration_ms(mut self, duration: Duration) -> Self {
        self.expiration_ms = Some(duration.as_millis().to_string());
        self
    }

    /// Sets the field used for the time partitioning
    pub fn field(mut self, field: &str) -> Self {
        self.field = Some(field.to_string());
        self
    }
}