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
14const 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 silent_logs! {
48 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 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 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 #[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}