1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
use sqlx::postgres::Postgres;
use sqlx::query_builder::QueryBuilder;
use sqlx::Executor;
use sqlx::Type;
use sqlx::{Either, Execute};
use sqlx_test::new;
#[test]
fn test_new() {
let qb: QueryBuilder<'_, Postgres> = QueryBuilder::new("SELECT * FROM users");
assert_eq!(qb.sql(), "SELECT * FROM users");
}
#[test]
fn test_push() {
let mut qb: QueryBuilder<'_, Postgres> = QueryBuilder::new("SELECT * FROM users");
let second_line = " WHERE last_name LIKE '[A-N]%';";
qb.push(second_line);
assert_eq!(
qb.sql(),
"SELECT * FROM users WHERE last_name LIKE '[A-N]%';".to_string(),
);
}
#[test]
#[should_panic]
fn test_push_panics_after_build_without_reset() {
let mut qb: QueryBuilder<'_, Postgres> = QueryBuilder::new("SELECT * FROM users;");
let _query = qb.build();
qb.push("SELECT * FROM users;");
}
#[test]
fn test_push_bind() {
let mut qb: QueryBuilder<'_, Postgres> = QueryBuilder::new("SELECT * FROM users WHERE id = ");
qb.push_bind(42i32)
.push(" OR membership_level = ")
.push_bind(3i32);
assert_eq!(
qb.sql(),
"SELECT * FROM users WHERE id = $1 OR membership_level = $2"
);
}
#[test]
fn test_build() {
let mut qb: QueryBuilder<'_, Postgres> = QueryBuilder::new("SELECT * FROM users");
qb.push(" WHERE id = ").push_bind(42i32);
let query = qb.build();
assert_eq!(query.sql(), "SELECT * FROM users WHERE id = $1");
assert_eq!(Execute::persistent(&query), true);
}
#[test]
fn test_reset() {
let mut qb: QueryBuilder<'_, Postgres> = QueryBuilder::new("");
let _query = qb
.push("SELECT * FROM users WHERE id = ")
.push_bind(42i32)
.build();
qb.reset();
assert_eq!(qb.sql(), "");
}
#[test]
fn test_query_builder_reuse() {
let mut qb: QueryBuilder<'_, Postgres> = QueryBuilder::new("");
let _query = qb
.push("SELECT * FROM users WHERE id = ")
.push_bind(42i32)
.build();
qb.reset();
let query = qb.push("SELECT * FROM users WHERE id = 99").build();
assert_eq!(query.sql(), "SELECT * FROM users WHERE id = 99");
}
#[test]
fn test_query_builder_with_args() {
let mut qb: QueryBuilder<'_, Postgres> = QueryBuilder::new("");
let mut query = qb
.push("SELECT * FROM users WHERE id = ")
.push_bind(42i32)
.build();
let mut qb: QueryBuilder<'_, Postgres> =
QueryBuilder::with_arguments(query.sql(), query.take_arguments().unwrap().unwrap());
let query = qb.push(" OR membership_level = ").push_bind(3i32).build();
assert_eq!(
query.sql(),
"SELECT * FROM users WHERE id = $1 OR membership_level = $2"
);
}
#[sqlx::test]
async fn test_max_number_of_binds() -> anyhow::Result<()> {
// The maximum number of binds is 65535 (u16::MAX), not 32567 (i16::MAX)
// as the protocol documentation would imply
//
// https://github.com/launchbadge/sqlx/issues/3464
let mut qb: QueryBuilder<'_, Postgres> = QueryBuilder::new("SELECT ARRAY[");
let mut elements = qb.separated(',');
let max_bind = u16::MAX as i32;
for i in 1..=max_bind {
elements.push_bind(i);
}
qb.push("]::int4[]");
let mut conn = new::<Postgres>().await?;
// Indirectly ensures the macros support this many binds since this is what they use.
let describe = conn.describe(qb.sql()).await?;
match describe
.parameters
.expect("describe() returned no parameter information")
{
Either::Left(params) => {
assert_eq!(params.len(), 65535);
for param in params {
assert_eq!(param, <i32 as Type<Postgres>>::type_info())
}
}
Either::Right(num_params) => {
assert_eq!(num_params, 65535);
}
}
let values: Vec<i32> = qb.build_query_scalar().fetch_one(&mut conn).await?;
assert_eq!(values.len(), 65535);
for (idx, (i, j)) in (1..=max_bind).zip(values).enumerate() {
assert_eq!(i, j, "mismatch at index {idx}");
}
Ok(())
}
|