Skip to main content

tank_tests/
limits.rs

1#![allow(unused_imports)]
2use crate::silent_logs;
3use core::f64;
4use std::{pin::pin, sync::LazyLock};
5use tank::{
6    Driver, DynQuery, Entity, Executor, Interval, QueryBuilder, QueryResult, RawQuery,
7    RowsAffected, SqlWriter, expr, stream::StreamExt,
8};
9use time::{Date, Month, Time};
10use tokio::sync::Mutex;
11
12static MUTEX: LazyLock<Mutex<()>> = LazyLock::new(|| Mutex::new(()));
13
14// Safe max value
15const F32_MAX: f32 = 3.4e+38_f32;
16
17#[derive(Entity)]
18struct Limits {
19    #[tank(primary_key)]
20    id: usize,
21    boolean: bool,
22    int8: i8,
23    uint8: u8,
24    int16: i16,
25    uint16: u16,
26    int32: i32,
27    uint32: u32,
28    int64: i64,
29    #[cfg(not(feature = "disable-large-integers"))]
30    uint64: u64,
31    #[cfg(not(feature = "disable-large-integers"))]
32    int128: i128,
33    #[cfg(not(feature = "disable-large-integers"))]
34    uint128: u128,
35    float32: f32,
36    float64: f64,
37    time: Time,
38    date: Date,
39    #[cfg(not(feature = "disable-intervals"))]
40    interval: Interval,
41}
42
43pub async fn limits(executor: &mut impl Executor) {
44    let _lock = MUTEX.lock().await;
45
46    // Setup
47    silent_logs! {
48        // Silent logs for Valkey/Redis
49        Limits::drop_table(executor, true, false)
50            .await
51            .expect("Failed to drop SimpleNullFields table");
52    }
53    Limits::create_table(executor, true, true)
54        .await
55        .expect("Failed to create SimpleNullFields table");
56
57    // Minimals
58    Limits::delete_many(executor, expr!(id == 1))
59        .await
60        .expect("Failed to clear the Limits table");
61    let minimals = Limits {
62        id: 1,
63        boolean: false,
64        int8: -127,
65        uint8: 0,
66        int16: -32_768,
67        uint16: 0,
68        int32: -2_147_483_648,
69        uint32: 0,
70        int64: -9_223_372_036_854_775_808,
71        #[cfg(not(feature = "disable-large-integers"))]
72        uint64: 0,
73        #[cfg(not(feature = "disable-large-integers"))]
74        int128: -170_141_183_460_469_231_731_687_303_715_884_105_728,
75        #[cfg(not(feature = "disable-large-integers"))]
76        uint128: 0,
77        float32: f32::MIN_POSITIVE,
78        #[cfg(not(feature = "disable-infinity"))]
79        float64: f64::NEG_INFINITY,
80        #[cfg(feature = "disable-infinity")]
81        float64: f64::MIN,
82        time: Time::from_hms(0, 0, 0).expect("All zero must be correct time"),
83        #[cfg(not(feature = "disable-old-dates"))]
84        date: Date::from_calendar_date(-2000, Month::January, 01)
85            .expect("Very old date must be correct"),
86        #[cfg(feature = "disable-old-dates")]
87        date: Date::from_calendar_date(1970, Month::January, 01)
88            .expect("Very old date must be correct"),
89        #[cfg(not(feature = "disable-intervals"))]
90        interval: Interval::from_micros(1),
91    };
92    Limits::insert_one(executor, &minimals)
93        .await
94        .expect("Failed to save minimals entity");
95    let loaded = Limits::find_one(executor, expr!(id == 1))
96        .await
97        .expect("Failed to query simple 2")
98        .expect("Failed to find simple 2");
99    assert_eq!(loaded.id, 1);
100    assert_eq!(loaded.boolean, false);
101    assert_eq!(loaded.int8, -127);
102    assert_eq!(loaded.uint8, 0);
103    assert_eq!(loaded.int16, -32_768);
104    assert_eq!(loaded.uint16, 0);
105    assert_eq!(loaded.int32, -2_147_483_648);
106    assert_eq!(loaded.uint32, 0);
107    assert_eq!(loaded.int64, -9_223_372_036_854_775_808);
108    #[cfg(not(feature = "disable-large-integers"))]
109    assert_eq!(loaded.uint64, 0);
110    #[cfg(not(feature = "disable-large-integers"))]
111    assert_eq!(
112        loaded.int128,
113        -170_141_183_460_469_231_731_687_303_715_884_105_728
114    );
115    #[cfg(not(feature = "disable-large-integers"))]
116    assert_eq!(loaded.uint128, 0);
117    assert!((loaded.float32 - f32::MIN_POSITIVE).abs() < 0.0001);
118    #[cfg(not(feature = "disable-infinity"))]
119    assert_eq!(loaded.float64, f64::NEG_INFINITY);
120    #[cfg(feature = "disable-infinity")]
121    assert_eq!(loaded.float64, f64::MIN);
122    assert_eq!(loaded.time, Time::from_hms(0, 0, 0).unwrap());
123    #[cfg(not(feature = "disable-old-dates"))]
124    assert_eq!(
125        loaded.date,
126        Date::from_calendar_date(-2000, Month::January, 01).unwrap()
127    );
128    #[cfg(feature = "disable-old-dates")]
129    assert_eq!(
130        loaded.date,
131        Date::from_calendar_date(1970, Month::January, 01).unwrap()
132    );
133    #[cfg(not(feature = "disable-intervals"))]
134    assert_eq!(loaded.interval, Interval::from_micros(1));
135
136    // Maximals
137    Limits::delete_many(executor, expr!(Limits::id == 1))
138        .await
139        .expect("Failed to clear the Limits table");
140    let maximals = Limits {
141        id: 2,
142        boolean: true,
143        int8: 127,
144        uint8: 255,
145        int16: 32_767,
146        uint16: 65_535,
147        int32: 2_147_483_647,
148        uint32: 4_294_967_295,
149        int64: 9_223_372_036_854_775_807,
150        #[cfg(not(feature = "disable-large-integers"))]
151        uint64: 18_446_744_073_709_551_615,
152        #[cfg(not(feature = "disable-large-integers"))]
153        int128: 170_141_183_460_469_231_731_687_303_715_884_105_727,
154        #[cfg(not(feature = "disable-large-integers"))]
155        uint128: 340_282_366_920_938_463_463_374_607_431_768_211_455,
156        float32: F32_MAX,
157        #[cfg(not(feature = "disable-infinity"))]
158        float64: f64::INFINITY,
159        #[cfg(feature = "disable-infinity")]
160        float64: f64::MAX,
161        time: Time::from_hms_micro(23, 59, 59, 999_999)
162            .expect("Close to midnight time must be correct"),
163        date: Date::from_calendar_date(9999, Month::December, 31)
164            .expect("Very old date must be correct"),
165        #[cfg(all(
166            not(feature = "disable-intervals"),
167            not(feature = "disable-large-intervals"),
168        ))]
169        interval: Interval::from_years(1_000_000),
170        #[cfg(all(
171            not(feature = "disable-intervals"),
172            feature = "disable-large-intervals"
173        ))]
174        interval: Interval::from_days(31) + Interval::from_mins(5),
175    };
176    Limits::insert_one(executor, &maximals)
177        .await
178        .expect("Failed to save maximals entity");
179    let loaded = Limits::find_one(executor, expr!(Limits::id == 2))
180        .await
181        .expect("Failed to query simple 2")
182        .expect("Failed to find simple 2");
183    assert_eq!(loaded.id, 2);
184    assert_eq!(loaded.boolean, true);
185    assert_eq!(loaded.int8, 127);
186    assert_eq!(loaded.uint8, 255);
187    assert_eq!(loaded.int16, 32_767);
188    assert_eq!(loaded.uint16, 65_535);
189    assert_eq!(loaded.int32, 2_147_483_647);
190    assert_eq!(loaded.uint32, 4_294_967_295);
191    assert_eq!(loaded.int64, 9_223_372_036_854_775_807);
192    #[cfg(not(feature = "disable-large-integers"))]
193    assert_eq!(loaded.uint64, 18_446_744_073_709_551_615);
194    #[cfg(not(feature = "disable-large-integers"))]
195    assert_eq!(
196        loaded.int128,
197        170_141_183_460_469_231_731_687_303_715_884_105_727
198    );
199    #[cfg(not(feature = "disable-large-integers"))]
200    assert_eq!(
201        loaded.uint128,
202        340_282_366_920_938_463_463_374_607_431_768_211_455
203    );
204    assert!((loaded.float32 - F32_MAX).abs() < 0.001);
205    #[cfg(not(feature = "disable-infinity"))]
206    assert_eq!(loaded.float64, f64::INFINITY);
207    #[cfg(feature = "disable-infinity")]
208    assert_eq!(loaded.float64, f64::MAX);
209    assert!(
210        (loaded.time - Time::from_hms_micro(23, 59, 59, 999_999).unwrap()).abs()
211            < time::Duration::milliseconds(1),
212    );
213    assert_eq!(
214        loaded.date,
215        Date::from_calendar_date(9999, Month::December, 31).unwrap()
216    );
217    #[cfg(all(
218        not(feature = "disable-intervals"),
219        not(feature = "disable-large-intervals"),
220    ))]
221    assert_eq!(loaded.interval, Interval::from_years(1_000_000));
222    #[cfg(all(
223        not(feature = "disable-intervals"),
224        feature = "disable-large-intervals"
225    ))]
226    assert_eq!(
227        loaded.interval,
228        Interval::from_days(31) + Interval::from_mins(5)
229    );
230
231    // Multiple statements
232    #[cfg(not(feature = "disable-multiple-statements"))]
233    {
234        let mut query = DynQuery::default();
235        let writer = executor.driver().sql_writer();
236        writer.write_delete::<Limits>(&mut query, true);
237        writer.write_insert(&mut query, &[minimals, maximals], false);
238        writer.write_select(
239            &mut query,
240            &QueryBuilder::new()
241                .select(Limits::columns())
242                .from(Limits::table())
243                .where_expr(expr!(!Limits::boolean)),
244        );
245        writer.write_select(
246            &mut query,
247            &QueryBuilder::new()
248                .select(Limits::columns())
249                .from(Limits::table())
250                .where_expr(expr!(Limits::boolean)),
251        );
252        let mut stream = pin!(executor.run(query));
253        let Some(Ok(QueryResult::Affected(RowsAffected { rows_affected, .. }))) =
254            stream.next().await
255        else {
256            panic!("Could not get the result of the first statement");
257        };
258        if let Some(rows_affected) = rows_affected {
259            assert_eq!(rows_affected, 1, "Should have deleted one row");
260        }
261        let Some(Ok(QueryResult::Affected(RowsAffected { rows_affected, .. }))) =
262            stream.next().await
263        else {
264            panic!("Could not get the result of the second statement");
265        };
266        if let Some(rows_affected) = rows_affected {
267            assert_eq!(rows_affected, 2, "Should have inserted two rows");
268        }
269        let Some(Ok(QueryResult::Row(row))) = stream.next().await else {
270            panic!("Could not get the row of the third statement");
271        };
272        let loaded = Limits::from_row(row).expect("Could not decode the Limits from minimals row");
273        assert_eq!(loaded.boolean, false);
274        assert_eq!(loaded.int8, -127);
275        assert_eq!(loaded.uint8, 0);
276        assert_eq!(loaded.int16, -32_768);
277        assert_eq!(loaded.uint16, 0);
278        assert_eq!(loaded.int32, -2_147_483_648);
279        assert_eq!(loaded.uint32, 0);
280        assert_eq!(loaded.int64, -9_223_372_036_854_775_808);
281        #[cfg(not(feature = "disable-large-integers"))]
282        assert_eq!(loaded.uint64, 0);
283        #[cfg(not(feature = "disable-large-integers"))]
284        assert_eq!(
285            loaded.int128,
286            -170_141_183_460_469_231_731_687_303_715_884_105_728
287        );
288        #[cfg(not(feature = "disable-large-integers"))]
289        assert_eq!(loaded.uint128, 0);
290        assert!((loaded.float32 - f32::MIN_POSITIVE).abs() < 0.0001);
291        #[cfg(not(feature = "disable-infinity"))]
292        assert_eq!(loaded.float64, f64::NEG_INFINITY);
293        #[cfg(feature = "disable-infinity")]
294        assert_eq!(loaded.float64, f64::MIN);
295        assert_eq!(loaded.time, Time::from_hms(0, 0, 0).unwrap());
296        assert_eq!(
297            loaded.date,
298            Date::from_calendar_date(-2000, Month::January, 01).unwrap()
299        );
300        let Some(Ok(QueryResult::Row(row))) = stream.next().await else {
301            panic!("Could not get the row of the third statement");
302        };
303        let loaded = Limits::from_row(row).expect("Could not decode the Limits from maximals row");
304        assert_eq!(loaded.boolean, true);
305        assert_eq!(loaded.int8, 127);
306        assert_eq!(loaded.uint8, 255);
307        assert_eq!(loaded.int16, 32_767);
308        assert_eq!(loaded.uint16, 65_535);
309        assert_eq!(loaded.int32, 2_147_483_647);
310        assert_eq!(loaded.uint32, 4_294_967_295);
311        assert_eq!(loaded.int64, 9_223_372_036_854_775_807);
312        #[cfg(not(feature = "disable-large-integers"))]
313        assert_eq!(loaded.uint64, 18_446_744_073_709_551_615);
314        #[cfg(not(feature = "disable-large-integers"))]
315        assert_eq!(
316            loaded.int128,
317            170_141_183_460_469_231_731_687_303_715_884_105_727
318        );
319        #[cfg(not(feature = "disable-large-integers"))]
320        assert_eq!(
321            loaded.uint128,
322            340_282_366_920_938_463_463_374_607_431_768_211_455
323        );
324        assert!((loaded.float32 - F32_MAX).abs() < 1E35 && loaded.float32 > 1E38);
325        #[cfg(not(feature = "disable-infinity"))]
326        assert_eq!(loaded.float64, f64::INFINITY);
327        #[cfg(feature = "disable-infinity")]
328        assert_eq!(loaded.float64, f64::MIN);
329        assert_eq!(
330            loaded.time,
331            Time::from_hms_micro(23, 59, 59, 999_999).unwrap()
332        );
333        assert_eq!(
334            loaded.date,
335            Date::from_calendar_date(9999, Month::December, 31).unwrap()
336        );
337        #[cfg(all(
338            not(feature = "disable-intervals"),
339            not(feature = "disable-large-intervals"),
340        ))]
341        assert_eq!(loaded.interval, Interval::from_years(1_000_000));
342        #[cfg(all(
343            not(feature = "disable-intervals"),
344            feature = "disable-large-intervals"
345        ))]
346        assert_eq!(
347            loaded.interval,
348            Interval::from_days(31) + Interval::from_mins(5)
349        );
350    }
351}