Optional fields
A Toql query can select individual fields from a struct. However fields must be Option
for this, otherwise they will always be selected in the SQL statement, regardless of the query.
Example:
# #[tokio::main(flavor="current_thread")] # async fn main() { use toql::prelude::{Toql, ToqlApi, query, Cache}; use toql::mock_db::MockDb; #[derive(Toql)] struct User { #[toql(key)] id: u32, // Always selected in SQL (keys must not be optional) age: u8, // Always selected in SQL firstname: Option<String>, // Selectable field of non nullable column middlename: Option<Option<String>>,// Selectable field of nullable column #[toql(preselect)] lastname: Option<String> // Always selected in SQL, nullable column } let cache = Cache::default(); let mut toql = MockDb::from(&cache); // Load preselected fields let q = query!(User, "id"); let mut _users = toql.load_many(&q).await.unwrap(); assert_eq!(toql.take_unsafe_sql(), "SELECT user.id, user.age, user.lastname FROM User user"); # }
You noticed it: Nullable columns that should always be selected must be annotated with preselect
.
Preselection and joins
Preselected fields on joined structs are selected, if
- A join itself is preselected
- or at least one field on that join is selected
Preselection example
# #[tokio::main(flavor="current_thread")] # async fn main() { use toql::prelude::{Toql, ToqlApi, query, Cache}; use toql::mock_db::MockDb; #[derive(Toql)] struct User { #[toql(key)] id: u32, #[toql(join())] native_language: Language, // Preselected inner join #[toql(join())] foreign_language: Option<Option<Language>>, } #[derive(Toql)] struct Language { #[toql(key)] id: u32, code: Option<String> } let cache = Cache::default(); let mut toql = MockDb::from(&cache); // Load preselected fields let q = query!(User, "id"); let mut _users = toql.load_many(&q).await.unwrap(); assert_eq!(toql.take_unsafe_sql(), "SELECT user.id, user_nativeLanguage.id \ FROM User user \ JOIN (Language user_nativeLanguage) \ ON (user.native_language_id = user_nativeLanguage.id)"); # }
Above id
in User
is always selected, because it's not Option
.
As native_language
is a preselected (inner) join, its id
will also always be selected.
But on the contrary foreign_language
is a selectable (left) join. id
will only be selected if the query requests any other field from that join. For example with foreignLanguage_code
.
Preselection on parent paths
One more thing: If a field on a related struct is selected, all preselected fields from the path line will be selected too.
Lets assume we have a user that has an address, which contains country information.
The query
address_country_code
would therefore
- select
code
from the tableCountry
- select all preseleted fields from table
Country
- select all preseleted fields from table
Address
- select all preseleted fields from table
User