Skip to main content

tank_tests/
other.rs

1use std::{pin::pin, sync::LazyLock};
2use tank::{
3    DynQuery, Entity, Executor, QueryBuilder, cols, expr,
4    stream::{StreamExt, TryStreamExt},
5};
6use tokio::sync::Mutex;
7
8static MUTEX: LazyLock<Mutex<()>> = LazyLock::new(|| Mutex::new(()));
9
10#[derive(Entity, PartialEq, Debug)]
11pub struct ATable {
12    #[tank(primary_key)]
13    a_column: String,
14}
15
16#[derive(Entity, PartialEq, Debug)]
17pub struct CharTable {
18    #[tank(primary_key)]
19    id: i32,
20    letter: char,
21}
22
23pub async fn other(executor: &mut impl Executor) {
24    let _lock = MUTEX.lock().await;
25
26    // Setup
27    ATable::drop_table(executor, true, false)
28        .await
29        .expect("Failed to drop ATable table");
30    ATable::create_table(executor, true, true)
31        .await
32        .expect("Failed to create ATable table");
33    ATable::insert_one(
34        executor,
35        &ATable {
36            a_column: "".into(),
37        },
38    )
39    .await
40    .expect("Could not save a row");
41
42    // SELECT NULL
43    let stream = executor
44        .fetch(
45            QueryBuilder::new()
46                .select(cols!(NULL))
47                .from(ATable::table())
48                .where_expr(true)
49                .build(&executor.driver()),
50        )
51        .map_ok(|v| v.values.into_iter().nth(0).unwrap());
52    let value = pin!(stream)
53        .next()
54        .await
55        .expect("No result returned from the stream")
56        .expect("Could not query for NULL");
57    assert!(value.is_null());
58
59    // InsertIntoQueryBuilder::build and build_into should produce identical SQL
60    let rows = vec![ATable {
61        a_column: "test".into(),
62    }];
63    let query = QueryBuilder::new().insert_into::<ATable>().values(&rows);
64    let from_build = query.build(&executor.driver());
65    let mut out = DynQuery::default();
66    query.build_into(&executor.driver(), &mut out);
67    let from_build_into: String = out.into();
68    assert_eq!(
69        from_build, from_build_into,
70        "build() and build_into() should produce the same SQL"
71    );
72
73    // Multi byte char
74    CharTable::drop_table(executor, true, false)
75        .await
76        .expect("Failed to drop CharTable");
77    CharTable::create_table(executor, true, true)
78        .await
79        .expect("Failed to create CharTable");
80    CharTable::insert_one(
81        executor,
82        &CharTable {
83            id: 1, letter: 'é'
84        },
85    )
86    .await
87    .expect("Could not insert multi-byte char");
88    let row = CharTable::find_one(executor, expr!(CharTable::id == 1))
89        .await
90        .expect("Failed to query CharTable")
91        .expect("Row with id=1 not found");
92    assert_eq!(
93        row.letter, 'é',
94        "Multi-byte char should round-trip correctly"
95    );
96}