Fields
Struct fields are mapped to Toql query fields and database columns by default in a predictable way:
- Table names are UpperCamelCase.
- Column names are snake_case.
- Toql query fields are lowerCamelCase.
- Toql query paths are lowerCamelCase, separated with an underscore.
Renaming tables and columns
To adjust the default naming to an existing database scheme use the attributes tables
and columns
for a renaming scheme or table
and column
for explicit name.
Supported renaming schemes are
- CamelCase
- snake_case
- SHOUTY_SNAKE_CASE
- mixedCase
Renaming scheme example
# #[tokio::main(flavor="current_thread")] # async fn main() { use toql::prelude::{Toql, ToqlApi, query, Cache}; use toql::mock_db::MockDb; #[derive(Toql)] #[toql(tables="SHOUTY_SNAKE_CASE", columns="CamelCase")] struct User { #[toql(key)] user_id: u32, full_name: String, } let cache = Cache::default(); let mut toql = MockDb::from(&cache); let q = query!(User, "*"); let mut _users = toql.load_many(&q).await.unwrap(); assert_eq!(toql.take_unsafe_sql(), "SELECT user.UserId, user.FullName FROM USER user"); # }
Explicit naming example
Use table
on the struct and column
on fields to set a explicit name.
# #[tokio::main(flavor="current_thread")] # async fn main() { use toql::prelude::{Toql, ToqlApi, query, Cache}; use toql::mock_db::MockDb; #[derive(Toql)] #[toql(table="User")] struct UserRef { #[toql(key, column="id")] user_id: u32, full_name: String, } let cache = Cache::default(); let mut toql = MockDb::from(&cache); let q = query!(UserRef, "*"); let mut _users = toql.load_many(&q).await.unwrap(); assert_eq!(toql.take_unsafe_sql(), "SELECT user.id, user.full_name FROM User user"); # }
Use column
also when mapping a field that is a SQL keyword. Notice the back ticks:
#[toql(column="`order`")]
order: u32
Toql query fields
Toql query fields on a struct are always mixed case, while dependencies are separated with an underscore.
# #[tokio::main(flavor="current_thread")] # async fn main() { use toql::prelude::{Toql, ToqlApi, query, Cache}; use toql::mock_db::MockDb; #[derive(Toql)] #[toql(table="User")] struct UserRef { #[toql(key, column="id")] id: u32, full_name: String, #[toql(join)] country: Country } #[derive(Toql)] struct Country { #[toql(key)] id: u32, name: String, } let cache = Cache::default(); let mut toql = MockDb::from(&cache); let q = query!(UserRef, "id, fullName, country_id"); let mut users = toql.load_many(&q).await.unwrap(); assert_eq!(toql.take_unsafe_sql(), "SELECT user.id, user.full_name, user_country.id, user_country.name \ FROM User user \ JOIN (Country user_country) \ ON (user.country_id = user_country.id)"); # }
Exclusion
Fields can be excluded in several ways
skip
excludes a field completely from the table, use for non-db fields.skip_mut
ensures a field is never updated, automatically added for keys and SQL expressions.skip_wildcard
removes a field from default wildcard selection, use for expensive SQL expressions or soft hiding.
Notice that for skip_wildcard
the field must be selectable (Option<T>
).
Otherwise Toql must always load a value to satisfy the deserializer.
# #[tokio::main(flavor="current_thread")] # async fn main() { use toql::prelude::{Toql, ToqlApi, query, Cache}; use toql::mock_db::MockDb; #[derive(Toql)] #[toql(table="User")] struct UserRef { #[toql(key, column="id")] id: u32, full_name: String, #[toql(skip_wildcard)] middle_name: Option<String>, #[toql(skip)] value: Option<String>, } let cache = Cache::default(); let mut toql = MockDb::from(&cache); let q = query!(UserRef, "*"); let mut users = toql.load_many(&q).await.unwrap(); assert_eq!(toql.take_unsafe_sql(), "SELECT user.id, user.full_name FROM User user"); # }