Macro include_sql::include_sql
source · [−]include_sql!() { /* proc-macro */ }
Expand description
Reads and parses the specified SQL file, and generates impl_sql
macro call.
For example, if the SQL file “library.sql” has these 2 statements:
-- name: get_loaned_books?
-- Returns the list of books loaned to a patron
-- # Parameters
-- param: user_id: &str - user ID
SELECT book_title FROM library WHERE loaned_to = :user_id ORDER BY 1;
-- name: loan_books
-- Updates the book records to reflect loan to a patron
-- # Parameters
-- param: user_id: &str - user ID
-- param: book_ids: usize - book IDs
UPDATE library SET loaned_to = :user_id, loaned_on = current_timestamp WHERE book_id IN ( :book_ids );
This method would generate:
impl_sql!{ LibrarySql =
{
? get_loaned_books (:user_id (&str))
" Returns the list of books loaned to a patron\n # Parameters\n * `user_id` - user ID"
$ "SELECT book_title FROM library WHERE loaned_to = " :user_id "ORDER BY 1"
},
{
! loan_books (:user_id (&str) #book_ids (usize))
" Updates the book records to reflect loan to a patron\n # Parameters\n * `user_id` - user ID\n * `book_ids` - book IDs"
$ "UPDATE library SET loaned_to = " :user_id ", loaned_on = current_timestamp WHERE book_id IN ( " #book_ids " )"
}
}
Where:
LibrarySql
is a camel-casedident
derived from the SQL file name. It might be used byimpl_sql
to generate a trait (like include-postgres-sql and include-sqlite-sql do).?
or!
is a statement variant selectorget_loaned_books
andloan_books
areident
s created from the statement names that can be used to name generated methodsuser_id
andbook_ids
areident
s that represent parameter names.:
and#
in front of the parameter names are parameter variant tags::
indicates that the following parameter is a scalar#
tags IN-list parameters.
- The following
(&str)
and(usize)
are Rust parameter types as declared in the SQL. $
is a helper token that could be used to generate repetitions if generated artifacts are macros.
Note that
param:
types are passed as parenthesized types. This is done to allowimpl_sql
match them as token trees. If a parameter type is not defined in SQL,_
will be used in its place (this_
drives the need to match parameter types as token trees) for whichimpl_sql
is expected to generate an appropriate generic type.
Async
When include-sql is built with the async
feature, impl_sql
macro will be generated with additional lifetimes for reference parameters.
For example, the above LibrarySql
example will look like this:
impl_sql!{ LibrarySql =
{
? get_loaned_books (:user_id ('user_id &str))
" Returns the list of books loaned to a patron\n # Parameters\n * `user_id` - user ID"
$ "SELECT book_title FROM library WHERE loaned_to = " :user_id "ORDER BY 1"
},
{
! loan_books (:user_id ('user_id &str) #book_ids ('book_ids usize))
" Updates the book records to reflect loan to a patron\n # Parameters\n * `user_id` - user ID\n * `book_ids` - book IDs"
$ "UPDATE library SET loaned_to = " :user_id ", loaned_on = current_timestamp WHERE book_id IN ( " #book_ids " )"
}
}
Note that for IN list parameters where the list item is a reference itself additional lifetime that covers list items is also generated. For example, for this query:
-- name: get_users_who_loaned_books?
-- Returns names patrons that at one time or another have loaned specified books
-- # Parameters
-- param: book_titles: &str - book titles
SELECT DISTINCT first_name, last_name
FROM patrons
JOIN library ON library.loaned_to = patrons.user_id
WHERE book_title IN (:book_titles);
include-sql will generate:
impl_sql!{ LibrarySql =
{
? get_users_who_loaned_books (#book_titles ('book_titles 'book_titles_item &str))
" Returns names patrons that at one time or another have loaned specified books\n # Parameters\n * `book_titles` - book titles"
$ "SELECT DISTINCT first_name, last_name FROM patrons JOIN library ON library.loaned_to = patrons.user_id WHERE book_title IN (" #book_titles ")"
}
}