tank_tests/readme.rs
1use std::{borrow::Cow, collections::HashSet, sync::LazyLock};
2use tank::{Entity, Executor, Result, expr, stream::TryStreamExt};
3use tokio::sync::Mutex;
4
5static MUTEX: LazyLock<Mutex<()>> = LazyLock::new(|| Mutex::new(()));
6
7#[derive(Entity)]
8#[tank(schema = "army")]
9pub struct Tank {
10 #[tank(primary_key)]
11 pub name: String,
12 pub country: Cow<'static, str>,
13 #[tank(name = "caliber")]
14 pub caliber_mm: u16,
15 #[tank(name = "speed")]
16 pub speed_kmh: f32,
17 pub is_operational: bool,
18 pub units_produced: Option<u32>,
19}
20
21pub async fn readme(connection: &mut impl Executor) -> Result<()> {
22 let _lock = MUTEX.lock();
23
24 let my_tank = Tank {
25 name: "Tiger I".into(),
26 country: "Germany".into(),
27 caliber_mm: 88,
28 speed_kmh: 45.4,
29 is_operational: false,
30 units_produced: Some(1_347),
31 };
32
33 /*
34 * CREATE SCHEMA IF NOT EXISTS "army";
35 * CREATE TABLE IF NOT EXISTS "army"."tank" (
36 * "name" VARCHAR PRIMARY KEY,
37 * "country" VARCHAR NOT NULL,
38 * "caliber" USMALLINT NOT NULL,
39 * "speed" FLOAT NOT NULL,
40 * "is_operational" BOOLEAN NOT NULL,
41 * "units_produced" UINTEGER);
42 */
43 Tank::create_table(connection, true, true).await?;
44
45 /*
46 * INSERT INTO "army"."tank" ("name", "country", "caliber", "speed", "is_operational", "units_produced") VALUES
47 * ('Tiger I', 'Germany', 88, 45.4, false, 1347)
48 * ON CONFLICT ("name") DO UPDATE SET
49 * "country" = EXCLUDED."country",
50 * "caliber" = EXCLUDED."caliber",
51 * "speed" = EXCLUDED."speed",
52 * "is_operational" = EXCLUDED."is_operational",
53 * "units_produced" = EXCLUDED."units_produced";
54 */
55 my_tank.save(connection).await?;
56
57 /*
58 * DuckDB uses the appender API. Other drivers generate an INSERT:
59 * INSERT INTO "army"."tank" ("name", "country", "caliber", "speed", "is_operational", "units_produced") VALUES
60 * ('T-34/85', 'Soviet Union', 85, 53.0, false, 49200),
61 * ('M1 Abrams', 'USA', 120, 72.0, true, NULL);
62 */
63 Tank::insert_many(
64 connection,
65 &[
66 Tank {
67 name: "T-34/85".into(),
68 country: "Soviet Union".into(),
69 caliber_mm: 85,
70 speed_kmh: 53.0,
71 is_operational: false,
72 units_produced: Some(49_200),
73 },
74 Tank {
75 name: "M1 Abrams".into(),
76 country: "USA".into(),
77 caliber_mm: 120,
78 speed_kmh: 72.0,
79 is_operational: true,
80 units_produced: None,
81 },
82 ],
83 )
84 .await?;
85
86 /*
87 * SELECT "name", "country", "caliber", "speed", "is_operational", "units_produced"
88 * FROM "army"."tank"
89 * WHERE "is_operational" = false
90 * LIMIT 1000;
91 */
92 let tanks = Tank::find_many(connection, expr!(Tank::is_operational == false), Some(1000))
93 .try_collect::<Vec<_>>()
94 .await?;
95
96 assert_eq!(
97 tanks
98 .iter()
99 .map(|t| t.name.to_string())
100 .collect::<HashSet<_>>(),
101 HashSet::from_iter(["Tiger I".into(), "T-34/85".into()])
102 );
103 Ok(())
104}