#![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, InsertComplex, InsertPost, Post};
use crate::common::schema::sqlite::{InsertSimple, Simple};
use drizzle::core::expr::*;
use drizzle::sqlite::prelude::*;
use crate::common::schema::sqlite::SimpleSchema;
#[cfg(feature = "uuid")]
use crate::common::schema::sqlite::{ComplexPostSchema, ComplexSchema};
#[allow(dead_code)]
#[derive(SQLiteFromRow, Debug)]
struct SimpleResult {
id: i32,
name: String,
}
#[cfg(feature = "uuid")]
#[derive(SQLiteFromRow, Debug)]
struct JoinResult {
user_name: String,
post_title: String,
}
#[cfg(feature = "uuid")]
#[derive(SQLiteFromRow, Debug)]
struct NamePair {
name1: String,
name2: String,
}
tag!(AliasS, "s");
tag!(AliasSimple, "s_alias");
#[cfg(feature = "uuid")]
tag!(AliasC1, "c1");
#[cfg(feature = "uuid")]
tag!(AliasC2, "c2");
#[cfg(feature = "uuid")]
tag!(AliasU, "u");
#[cfg(feature = "uuid")]
struct AliasP;
#[cfg(feature = "uuid")]
impl drizzle::core::Tag for AliasP {
const NAME: &'static str = "p";
}
#[drizzle::test]
fn basic_table_alias(db: &mut TestDb<SimpleSchema>) {
let SimpleSchema { simple } = schema;
let test_data = vec![
InsertSimple::new("alice"),
InsertSimple::new("bob"),
InsertSimple::new("charlie"),
];
db.insert(simple).values(test_data).execute();
let s = Simple::alias::<AliasS>();
let stmt = db
.select(SimpleResult::Select)
.from(s)
.r#where(eq(s.name, "bob"));
let results: Vec<SimpleResult> = stmt.all();
assert_eq!(results.len(), 1);
assert_eq!(results[0].name, "bob");
}
#[drizzle::test]
fn table_alias_with_conditions(db: &mut TestDb<SimpleSchema>) {
let SimpleSchema { simple } = schema;
let test_data = vec![
InsertSimple::new("test1"),
InsertSimple::new("test2"),
InsertSimple::new("test3"),
];
db.insert(simple).values(test_data).execute();
let s_alias = Simple::alias::<AliasSimple>();
let stmt = db
.select((s_alias.id, s_alias.name))
.from(s_alias)
.r#where(and(gt(s_alias.id, 1), neq(s_alias.name, "test3")));
let results: Vec<SimpleResult> = stmt.all();
assert_eq!(results.len(), 1);
assert_eq!(results[0].name, "test2");
}
#[cfg(feature = "uuid")]
#[drizzle::test]
fn self_join_with_aliases(db: &mut TestDb<ComplexSchema>) {
let ComplexSchema { complex, .. } = schema;
let test_data = vec![
InsertComplex::new("user1", true, Role::User)
.with_id(uuid::Uuid::new_v4())
.with_email("test@example.com"),
InsertComplex::new("user2", true, Role::User)
.with_id(uuid::Uuid::new_v4())
.with_email("test@example.com"),
InsertComplex::new("user3", true, Role::User)
.with_id(uuid::Uuid::new_v4())
.with_email("other@domain.com"),
];
db.insert(complex).values(test_data).execute();
let c1 = Complex::alias::<AliasC1>();
let c2 = Complex::alias::<AliasC2>();
let stmt = db
.select((c1.name.alias("name1"), c2.name.alias("name2")))
.from(c1)
.inner_join((c2, eq(c1.email, c2.email)))
.r#where(neq(c1.id, c2.id));
let results: Vec<NamePair> = stmt.all();
assert_eq!(results.len(), 2);
let names: Vec<String> = results
.iter()
.flat_map(|pair| vec![pair.name1.clone(), pair.name2.clone()])
.collect();
assert!(names.contains(&"user1".to_string()));
assert!(names.contains(&"user2".to_string()));
}
#[cfg(feature = "uuid")]
#[drizzle::test]
fn multiple_table_aliases_join(db: &mut TestDb<ComplexPostSchema>) {
let ComplexPostSchema { complex, post } = schema;
let user_id1 = uuid::Uuid::new_v4();
let user_id2 = uuid::Uuid::new_v4();
let users = vec![
InsertComplex::new("author1", true, Role::User).with_id(user_id1),
InsertComplex::new("author2", true, Role::User).with_id(user_id2),
];
db.insert(complex).values(users).execute();
let posts = vec![
InsertPost::new("First Post", true).with_author_id(user_id1),
InsertPost::new("Second Post", true).with_author_id(user_id2),
InsertPost::new("Third Post", false).with_author_id(user_id1),
];
db.insert(post).values(posts).execute();
let u = Complex::alias::<AliasU>();
let p = Post::alias::<AliasP>();
let stmt = db
.select((u.name.alias("user_name"), p.title.alias("post_title")))
.from(u)
.inner_join((p, eq(u.id, p.author_id)))
.r#where(eq(p.published, true))
.order_by([asc(u.name)]);
let results: Vec<JoinResult> = stmt.all();
assert_eq!(results.len(), 2);
assert_eq!(results[0].user_name, "author1");
assert_eq!(results[0].post_title, "First Post");
assert_eq!(results[1].user_name, "author2");
assert_eq!(results[1].post_title, "Second Post");
}
#[drizzle::test]
fn alias_with_original_table_comparison(db: &mut TestDb<SimpleSchema>) {
let SimpleSchema { simple } = schema;
let test_data = vec![InsertSimple::new("original"), InsertSimple::new("aliased")];
db.insert(simple).values(test_data).execute();
let original_results: Vec<SimpleResult> = db
.select((simple.id, simple.name))
.from(simple)
.r#where(eq(simple.name, "original"))
.all();
let s_alias = Simple::alias::<AliasSimple>();
let alias_stmt = db
.select((s_alias.id, s_alias.name))
.from(s_alias)
.r#where(eq(s_alias.name, "aliased"));
let alias_results: Vec<SimpleResult> = alias_stmt.all();
assert_eq!(original_results.len(), 1);
assert_eq!(original_results[0].name, "original");
assert_eq!(alias_results.len(), 1);
assert_eq!(alias_results[0].name, "aliased");
}
#[drizzle::test]
fn tagged_alias_forwards_alias_metadata(db: &mut TestDb<SimpleSchema>) {
let tagged = Simple::alias::<AliasSimple>();
let _base = Simple::new();
assert_eq!(tagged.name(), "s_alias");
}