Rusty Rel8
This is a WIP library attempting to emulate the Haskell
Rel8 library.
In essence, it allows you to write queries like so:
#[derive(Debug, PartialEq, rust_rel8_derive::TableStruct)]
struct User<'scope, Mode: TableMode> {
id: Mode::T<'scope, i32>,
name: Mode::T<'scope, String>,
age: Mode::T<'scope, i32>,
}
impl<'scope> User<'scope, NameMode> {
const SCHEMA: TableSchema<Self> = TableSchema {
name: "users",
columns: User {
id: "id",
name: "name",
age: "age",
},
};
}
#[derive(Debug, PartialEq, rust_rel8_derive::TableStruct)]
struct Post<'scope, Mode: TableMode> {
id: Mode::T<'scope, i32>,
user_id: Mode::T<'scope, i32>,
contents: Mode::T<'scope, String>,
}
impl<'scope> Post<'scope, NameMode> {
const SCHEMA: TableSchema<Self> = TableSchema {
name: "posts",
columns: Post {
id: "id",
user_id: "user_id",
contents: "contents",
},
};
}
let demo_users = vec![
User::<ValueMode> {id: 0, name: "Undine".to_owned(), age: 3,},
User {id: 1, name: "Leschy".to_owned(), age: 3,},
User {id: 2, name: "Huldra".to_owned(), age: 2,},
];
let demo_posts = vec![
Post::<ValueMode> {id: 0, user_id: 0, contents: "Croak".to_owned(),},
Post {id: 1, user_id: 1, contents: "Quak!".to_owned(),},
Post {id: 2, user_id: 1, contents: "Hello".to_owned(),},
];
let q = query::<(Expr<String>, Expr<String>)>(|q| {
let user = q.q(Query::values(demo_users.shorten_lifetime()));
let post = q.q(Query::values(demo_posts.shorten_lifetime()));
q.where_(user.id.clone().equals(post.user_id.clone()));
(user.name, post.contents)
})
.order_by(|x| (x.clone(), sea_query::Order::Asc));
let rows = q.all(&mut *pool).await.unwrap();
assert_eq!(
vec![
("Leschy".to_owned(), "Hello".to_owned()),
("Leschy".to_owned(), "Quak!".to_owned()),
("Undine".to_owned(), "Croak".to_owned())
],
rows
)
In this query builder, joins are also left to the database to figure out. The
user thinks of each let ... = q.q(...); inside query as being cartesian
produced. The database narrows these cartesian products down to inner or left
joins depending on the where clauses.
I'll add some more examples in the future, but you can also look at the tests in
lib.rs.