#![cfg(any(feature = "postgres-sync", feature = "tokio-postgres"))]
use crate::common::schema::postgres::*;
use drizzle::core::expr::*;
use drizzle::postgres::prelude::*;
#[allow(dead_code)]
#[cfg(feature = "uuid")]
#[derive(Debug, PostgresFromRow)]
struct PgComplexResult {
id: uuid::Uuid,
name: String,
email: Option<String>,
age: Option<i32>,
active: bool,
}
#[drizzle::test]
fn update_single_row(db: &mut TestDb<SimpleSchema>) {
let SimpleSchema { simple } = schema;
let stmt = db.insert(simple).values([InsertSimple::new("Original")]);
stmt.execute();
let stmt = db
.update(simple)
.set(UpdateSimple::default().with_name("Updated"))
.r#where(eq(simple.name, "Original"));
stmt.execute();
let stmt = db.select((simple.id, simple.name)).from(simple);
let results: Vec<SelectSimple> = stmt.all();
assert_eq!(results.len(), 1);
assert_eq!(results[0].name, "Updated");
}
#[drizzle::test]
fn update_multiple_rows(db: &mut TestDb<SimpleSchema>) {
let SimpleSchema { simple } = schema;
let stmt = db.insert(simple).values([
InsertSimple::new("test_one"),
InsertSimple::new("test_two"),
InsertSimple::new("other"),
]);
stmt.execute();
let stmt = db
.update(simple)
.set(UpdateSimple::default().with_name("updated"))
.r#where(like(simple.name, "test%"));
stmt.execute();
let stmt = db
.select((simple.id, simple.name))
.from(simple)
.r#where(eq(simple.name, "updated"));
let results: Vec<SelectSimple> = stmt.all();
assert_eq!(results.len(), 2);
let stmt = db
.select((simple.id, simple.name))
.from(simple)
.r#where(eq(simple.name, "other"));
let results: Vec<SelectSimple> = stmt.all();
assert_eq!(results.len(), 1);
}
#[cfg(feature = "uuid")]
#[drizzle::test]
fn update_multiple_columns(db: &mut TestDb<ComplexSchema>) {
let ComplexSchema { complex, .. } = schema;
let stmt = db
.insert(complex)
.values([InsertComplex::new("Alice", true, Role::User)
.with_email("old@example.com")
.with_age(25)]);
stmt.execute();
let stmt = db
.update(complex)
.set(
UpdateComplex::default()
.with_email("new@example.com")
.with_age(30)
.with_active(false),
)
.r#where(eq(complex.name, "Alice"));
stmt.execute();
let stmt = db.select(()).from(complex);
let results: Vec<PgComplexResult> = stmt.all();
assert_eq!(results.len(), 1);
assert_eq!(results[0].name, "Alice");
assert_eq!(results[0].email, Some("new@example.com".to_string()));
assert_eq!(results[0].age, Some(30));
assert!(!results[0].active);
}
#[cfg(feature = "uuid")]
#[drizzle::test]
fn update_with_complex_where(db: &mut TestDb<ComplexSchema>) {
let ComplexSchema { complex, .. } = schema;
let stmt = db.insert(complex).values([
InsertComplex::new("Young", true, Role::User).with_age(16),
InsertComplex::new("Adult", true, Role::User).with_age(25),
InsertComplex::new("Senior", true, Role::User).with_age(70),
]);
stmt.execute();
let stmt = db
.update(complex)
.set(UpdateComplex::default().with_active(false))
.r#where(and(gte(complex.age, 18), lte(complex.age, 65)));
stmt.execute();
let stmt = db
.select(())
.from(complex)
.r#where(eq(complex.active, false));
let results: Vec<PgComplexResult> = stmt.all();
assert_eq!(results.len(), 1);
assert_eq!(results[0].name, "Adult");
}
#[drizzle::test]
fn update_with_in_condition(db: &mut TestDb<SimpleSchema>) {
let SimpleSchema { simple } = schema;
let stmt = db.insert(simple).values([
InsertSimple::new("Alice"),
InsertSimple::new("Bob"),
InsertSimple::new("Charlie"),
InsertSimple::new("David"),
]);
stmt.execute();
let stmt = db
.update(simple)
.set(UpdateSimple::default().with_name("Updated"))
.r#where(in_array(simple.name, ["Alice", "Charlie"]));
stmt.execute();
let stmt = db
.select((simple.id, simple.name))
.from(simple)
.r#where(eq(simple.name, "Updated"));
let results: Vec<SelectSimple> = stmt.all();
assert_eq!(results.len(), 2);
let stmt = db
.select((simple.id, simple.name))
.from(simple)
.r#where(in_array(simple.name, ["Bob", "David"]));
let results: Vec<SelectSimple> = stmt.all();
assert_eq!(results.len(), 2);
}
#[drizzle::test]
fn update_no_matching_rows(db: &mut TestDb<SimpleSchema>) {
let SimpleSchema { simple } = schema;
let stmt = db.insert(simple).values([InsertSimple::new("Alice")]);
stmt.execute();
let stmt = db
.update(simple)
.set(UpdateSimple::default().with_name("Updated"))
.r#where(eq(simple.name, "NonExistent"));
stmt.execute();
let stmt = db.select((simple.id, simple.name)).from(simple);
let results: Vec<SelectSimple> = stmt.all();
assert_eq!(results.len(), 1);
assert_eq!(results[0].name, "Alice");
}
#[drizzle::test]
fn update_with_placeholders_sql(db: &mut TestDb<SimpleSchema>) {
let SimpleSchema { simple } = schema;
let new_name = simple.name.placeholder("new_name");
let old_name = simple.name.placeholder("old_name");
let update = UpdateSimple::default().with_name(new_name);
let stmt = db
.update(simple)
.set(update)
.r#where(eq(simple.name, old_name));
let sql = stmt.to_sql();
let sql_string = sql.sql();
assert!(
sql_string.starts_with("UPDATE"),
"Should be an UPDATE statement, got: {}",
sql_string
);
assert!(
sql_string.contains("\"simple\""),
"Should reference the simple table, got: {}",
sql_string
);
assert!(
sql_string.contains("$1"),
"Expected first PostgreSQL placeholder in SQL, got: {}",
sql_string
);
assert!(
sql_string.contains("$2"),
"Expected second PostgreSQL placeholder in SQL, got: {}",
sql_string
);
let params: Vec<_> = sql.params().collect();
assert!(
params.is_empty(),
"Should have no bound params when using placeholders, got {}",
params.len()
);
}
#[drizzle::test]
fn update_with_placeholders_execute(db: &mut TestDb<SimpleSchema>) {
let SimpleSchema { simple } = schema;
db.insert(simple)
.values([InsertSimple::new("original_name")])
.execute();
let new_name = simple.name.placeholder("new_name");
let old_name = simple.name.placeholder("old_name");
let update = UpdateSimple::default().with_name(new_name);
let prepared = db
.update(simple)
.set(update)
.r#where(eq(simple.name, old_name))
.prepare()
.into_owned();
let updated = prepared.execute(
drizzle_client!(),
[
new_name.bind("updated_name"),
old_name.bind("original_name"),
],
);
assert_eq!(updated, 1);
let stmt = db
.select((simple.id, simple.name))
.from(simple)
.r#where(eq(simple.name, "updated_name"));
let rows: Vec<SelectSimple> = stmt.all();
assert_eq!(rows.len(), 1);
assert_eq!(rows[0].name, "updated_name");
}