Skip to main content

tank_tests/
interval.rs

1#![allow(dead_code)]
2#![allow(unused_imports)]
3use crate::silent_logs;
4use std::{pin::pin, sync::LazyLock, time::Duration};
5use tank::{
6    Driver, DynQuery, Entity, Executor, Interval, QueryBuilder, QueryResult, RawQuery,
7    RowsAffected, SqlWriter,
8    stream::{StreamExt, TryStreamExt},
9};
10use tokio::sync::Mutex;
11
12static MUTEX: LazyLock<Mutex<()>> = LazyLock::new(|| Mutex::new(()));
13
14#[derive(Entity)]
15struct Intervals {
16    #[tank(primary_key)]
17    pk: u32,
18    first: time::Duration,
19    second: Interval,
20    third: Duration,
21}
22
23pub async fn interval(executor: &mut impl Executor) {
24    let _lock = MUTEX.lock().await;
25
26    // Setup
27    Intervals::drop_table(executor, true, false)
28        .await
29        .expect("Failed to drop Intervals table");
30    Intervals::create_table(executor, true, true)
31        .await
32        .expect("Failed to create Intervals table");
33
34    Intervals::insert_one(
35        executor,
36        &Intervals {
37            pk: 1,
38            first: Default::default(),
39            second: Default::default(),
40            third: Default::default(),
41        },
42    )
43    .await
44    .expect("Insert zero intervals failed");
45    let value = Intervals::find_one(executor, true)
46        .await
47        .expect("Failed to retrieve zero intervals")
48        .expect("Missing zero interval row");
49    assert_eq!(value.pk, 1);
50    assert_eq!(value.first, time::Duration::default());
51    assert_eq!(value.second, Interval::default());
52    assert_eq!(value.third, Duration::default());
53    Intervals::delete_many(executor, true)
54        .await
55        .expect("Could not delete the intervals");
56
57    Intervals::insert_one(
58        executor,
59        &Intervals {
60            pk: 2,
61            first: time::Duration::minutes(1) + time::Duration::days(1),
62            #[cfg(not(feature = "disable-large-intervals"))]
63            second: Interval::from_years(1_000),
64            #[cfg(feature = "disable-large-intervals")]
65            second: Interval::from_mins(5) + Interval::from_secs(24) + Interval::from_millis(33),
66            third: Duration::from_micros(1) + Duration::from_hours(6),
67        },
68    )
69    .await
70    .expect("Could not insert the interval");
71    let value = Intervals::find_one(executor, true)
72        .await
73        .expect("Could not retrieve the intervals row")
74        .expect("There was no interval inserted in the table intervals");
75    assert_eq!(value.pk, 2);
76    assert_eq!(value.first, time::Duration::minutes(1 + 24 * 60));
77    #[cfg(not(feature = "disable-large-intervals"))]
78    assert_eq!(value.second, Interval::from_months(1_000 * 12));
79    #[cfg(feature = "disable-large-intervals")]
80    assert_eq!(
81        value.second,
82        Interval::from_mins(5) + Interval::from_secs(24) + Interval::from_millis(33)
83    );
84    assert_eq!(value.third, Duration::from_micros(1 + 6 * 3600 * 1_000_000));
85    Intervals::delete_many(executor, true)
86        .await
87        .expect("Could not delete the intervals");
88
89    Intervals::insert_one(
90        executor,
91        &Intervals {
92            pk: 3,
93            #[cfg(not(feature = "disable-large-intervals"))]
94            first: time::Duration::weeks(52) + time::Duration::hours(3),
95            #[cfg(feature = "disable-large-intervals")]
96            first: time::Duration::weeks(1) + time::Duration::seconds(1),
97            second: Interval::from_days(-11),
98            third: Duration::from_micros(999_999_999),
99        },
100    )
101    .await
102    .expect("Insert large intervals failed");
103    let mut value = Intervals::find_one(executor, true)
104        .await
105        .expect("Failed to retrieve large intervals")
106        .expect("Missing large interval row");
107    assert_eq!(value.pk, 3);
108    #[cfg(not(feature = "disable-large-intervals"))]
109    assert_eq!(
110        value.first,
111        time::Duration::weeks(52) + time::Duration::hours(3)
112    );
113    #[cfg(feature = "disable-large-intervals")]
114    assert_eq!(
115        value.first,
116        time::Duration::weeks(1) + time::Duration::seconds(1),
117    );
118    assert_eq!(value.second, -Interval::from_days(11));
119    assert_eq!(value.third, Duration::from_micros(999_999_999));
120    value.third += Duration::from_micros(1);
121
122    // Multiple statements
123    #[cfg(not(feature = "disable-multiple-statements"))]
124    {
125        let mut query = DynQuery::default();
126        let writer = executor.driver().sql_writer();
127        writer.write_delete::<Intervals>(&mut query, true);
128        writer.write_insert(
129            &mut query,
130            &[
131                Intervals {
132                    pk: 4,
133                    first: time::Duration::weeks(4) + time::Duration::hours(5),
134                    #[cfg(not(feature = "disable-large-intervals"))]
135                    second: Interval::from_years(20_000) + Interval::from_millis(300),
136                    #[cfg(feature = "disable-large-intervals")]
137                    second: Interval::from_hours(3) + Interval::from_millis(300),
138                    third: Duration::from_secs(0),
139                },
140                Intervals {
141                    pk: 5,
142                    first: time::Duration::minutes(20) + time::Duration::milliseconds(1),
143                    second: Interval::from_months(4) + Interval::from_days(2),
144                    third: Duration::from_nanos(5000),
145                },
146            ],
147            false,
148        );
149        writer.write_select(
150            &mut query,
151            &QueryBuilder::new()
152                .select(Intervals::columns())
153                .from(Intervals::table())
154                .where_expr(true),
155        );
156        let mut stream = pin!(executor.run(query));
157
158        // DELETE
159        let Some(Ok(QueryResult::Affected(RowsAffected { rows_affected, .. }))) =
160            stream.next().await
161        else {
162            panic!("Could not get the result of deleting the rows")
163        };
164        if let Some(rows_affected) = rows_affected {
165            assert_eq!(rows_affected, 1);
166        }
167
168        // INSERT
169        let Some(Ok(QueryResult::Affected(RowsAffected { rows_affected, .. }))) =
170            stream.next().await
171        else {
172            panic!("Could not get the result of inserting the rows")
173        };
174        if let Some(rows_affected) = rows_affected {
175            assert_eq!(rows_affected, 2);
176        }
177
178        // SELECT
179        let mut intervals = Vec::new();
180        let Some(Ok(QueryResult::Row(row))) = stream.next().await else {
181            panic!("Could not get the result of selecting the rows")
182        };
183        intervals.push(Intervals::from_row(row).expect("Could not decode the first Intervals row"));
184        let Some(Ok(QueryResult::Row(row))) = stream.next().await else {
185            panic!("Could not get the result of selecting the rows")
186        };
187        intervals
188            .push(Intervals::from_row(row).expect("Could not decode the second Intervals row"));
189        intervals.sort_by(|a, b| a.pk.cmp(&b.pk));
190
191        // Row 1
192        let interval = &intervals[0];
193        assert_eq!(interval.pk, 4);
194        assert_eq!(interval.first, time::Duration::hours(4 * 7 * 24 + 5));
195        #[cfg(not(feature = "disable-large-intervals"))]
196        assert_eq!(
197            interval.second,
198            Interval::from_months(20000 * 12) + Interval::from_micros(300_000)
199        );
200        #[cfg(feature = "disable-large-intervals")]
201        assert_eq!(
202            interval.second,
203            Interval::from_hours(3) + Interval::from_millis(300),
204        );
205        assert_eq!(interval.third, Duration::ZERO);
206
207        // Row 2
208        let interval = &intervals[1];
209        assert_eq!(interval.pk, 5);
210        assert_eq!(interval.first, time::Duration::milliseconds(1200001));
211        assert_eq!(
212            interval.second,
213            Interval::from_months(4) + Interval::from_hours(48)
214        );
215        assert_eq!(interval.third, Duration::from_nanos(5000));
216    }
217}