#![cfg(any(feature = "rusqlite", feature = "turso", feature = "libsql"))]
#[cfg(feature = "uuid")]
use crate::common::schema::sqlite::Role;
#[cfg(feature = "uuid")]
use crate::common::schema::sqlite::{Complex, ComplexSchema, InsertComplex, UpdateComplex};
use crate::common::schema::sqlite::{
InsertSimple, SelectSimple, Simple, SimpleSchema, UpdateSimple,
};
#[cfg(all(feature = "serde", feature = "uuid"))]
use crate::common::schema::sqlite::{UserConfig, UserMetadata};
use drizzle::core::expr::*;
use drizzle::sqlite::prelude::*;
#[cfg(feature = "uuid")]
#[allow(dead_code)]
#[derive(SQLiteFromRow, Debug)]
struct ComplexResult {
id: uuid::Uuid,
name: String,
email: Option<String>,
age: Option<i32>,
description: Option<String>,
}
#[drizzle::test]
fn simple_update(db: &mut TestDb<SimpleSchema>) {
let SimpleSchema { simple } = schema;
let insert_data = InsertSimple::new("original");
let insert_result = db.insert(simple).values([insert_data]).execute();
assert_eq!(insert_result, 1);
let stmt = db
.update(simple)
.set(UpdateSimple::default().with_name("updated"))
.r#where(eq(Simple::name, "original"));
let update_result = stmt.execute();
assert_eq!(update_result, 1);
let results: Vec<SelectSimple> = db
.select((simple.id, simple.name))
.from(simple)
.r#where(eq(simple.name, "updated"))
.all();
assert_eq!(results.len(), 1);
assert_eq!(results[0].name, "updated");
let old_results: Vec<SelectSimple> = db
.select((simple.id, simple.name))
.from(simple)
.r#where(eq(simple.name, "original"))
.all();
assert_eq!(old_results.len(), 0);
}
#[drizzle::test]
fn update_returning_star(db: &mut TestDb<SimpleSchema>) {
let SimpleSchema { simple } = schema;
db.insert(simple)
.values([InsertSimple::new("before_returning").with_id(102)])
.execute();
let stmt = db
.update(simple)
.set(UpdateSimple::default().with_name("after_returning"))
.r#where(eq(simple.id, 102))
.returning(());
assert_eq!(
stmt.to_sql().sql(),
r#"UPDATE "simple" SET "name" = ? WHERE "simple"."id" = ? RETURNING *"#
);
let rows: Vec<SelectSimple> = stmt.all();
assert_eq!(rows.len(), 1);
assert_eq!(rows[0].id, 102);
assert_eq!(rows[0].name, "after_returning");
}
#[cfg(feature = "uuid")]
#[drizzle::test]
fn complex_update(db: &mut TestDb<ComplexSchema>) {
let ComplexSchema { complex } = schema;
#[cfg(not(feature = "uuid"))]
let insert_data = InsertComplex::new("user", true, Role::User)
.with_email("old@example.com".to_string())
.with_age(25)
.with_description("Original description".to_string());
#[cfg(feature = "uuid")]
let insert_data = InsertComplex::new("user", true, Role::User)
.with_id(uuid::Uuid::new_v4())
.with_email("old@example.com".to_string())
.with_age(25)
.with_description("Original description".to_string());
let insert_result = db.insert(complex).values([insert_data]).execute();
assert_eq!(insert_result, 1);
let stmt = db
.update(complex)
.set(
UpdateComplex::default()
.with_email("new@example.com".to_string())
.with_age(30)
.with_description("Updated description".to_string()),
)
.r#where(eq(Complex::name, "user"));
let update_result = stmt.execute();
assert_eq!(update_result, 1);
let results: Vec<ComplexResult> = db
.select((
complex.id,
complex.name,
complex.email,
complex.age,
complex.description,
))
.from(complex)
.r#where(eq(complex.name, "user"))
.all();
assert_eq!(results.len(), 1);
assert_eq!(results[0].name, "user");
assert_eq!(results[0].email, Some("new@example.com".to_string()));
assert_eq!(results[0].age, Some(30));
assert_eq!(
results[0].description,
Some("Updated description".to_string())
);
}
#[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 results: Vec<SelectSimple> = db
.select((simple.id, simple.name))
.from(simple)
.r#where(eq(simple.name, "updated"))
.all();
assert_eq!(results.len(), 2);
let results: Vec<SelectSimple> = db
.select((simple.id, simple.name))
.from(simple)
.r#where(eq(simple.name, "other"))
.all();
assert_eq!(results.len(), 1);
}
#[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_id(uuid::Uuid::new_v4())
.with_age(16),
InsertComplex::new("Adult", true, Role::User)
.with_id(uuid::Uuid::new_v4())
.with_age(25),
InsertComplex::new("Senior", true, Role::User)
.with_id(uuid::Uuid::new_v4())
.with_age(70),
]);
stmt.execute();
let stmt = db
.update(complex)
.set(UpdateComplex::default().with_name("matched"))
.r#where(and(gte(complex.age, 18), lte(complex.age, 65)));
stmt.execute();
let results: Vec<ComplexResult> = db
.select((
complex.id,
complex.name,
complex.email,
complex.age,
complex.description,
))
.from(complex)
.r#where(eq(complex.name, "matched"))
.all();
assert_eq!(results.len(), 1);
assert_eq!(results[0].name, "matched");
}
#[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 results: Vec<SelectSimple> = db
.select((simple.id, simple.name))
.from(simple)
.r#where(eq(simple.name, "Updated"))
.all();
assert_eq!(results.len(), 2);
let results: Vec<SelectSimple> = db
.select((simple.id, simple.name))
.from(simple)
.r#where(in_array(simple.name, ["Bob", "David"]))
.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 results: Vec<SelectSimple> = db.select((simple.id, simple.name)).from(simple).all();
assert_eq!(results.len(), 1);
assert_eq!(results[0].name, "Alice");
}
#[cfg(all(feature = "serde", feature = "uuid"))]
#[drizzle::test]
fn feature_gated_update(db: &mut TestDb<ComplexSchema>) {
let ComplexSchema { complex } = schema;
let test_id = uuid::Uuid::new_v4();
let insert_data = InsertComplex::new("feature_user", true, Role::User)
.with_id(test_id)
.with_metadata(UserMetadata {
preferences: vec!["user_mode".to_string()],
last_login: Some("2023-01-15".to_string()),
theme: "light".to_string(),
})
.with_config(UserConfig {
notifications: true,
language: "en".to_string(),
settings: std::collections::HashMap::new(),
});
let insert_result = db.insert(complex).values([insert_data]).execute();
assert_eq!(insert_result, 1);
let stmt = db
.update(complex)
.set(
UpdateComplex::default()
.with_metadata(UserMetadata {
preferences: vec!["admin_mode".to_string(), "updated".to_string()],
last_login: Some("2023-12-15".to_string()),
theme: "admin".to_string(),
})
.with_config(UserConfig {
notifications: false,
language: "en".to_string(),
settings: std::collections::HashMap::from([(
"updated".to_string(),
"true".to_string(),
)]),
}),
)
.r#where(eq(Complex::id, test_id));
let update_result = stmt.execute();
assert_eq!(update_result, 1);
let results: Vec<ComplexResult> = db
.select((
complex.id,
complex.name,
complex.email,
complex.age,
complex.description,
))
.from(complex)
.r#where(eq(complex.id, test_id))
.all();
assert_eq!(results.len(), 1);
assert_eq!(results[0].name, "feature_user");
assert_eq!(results[0].id, test_id);
}