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: book_ids: usize - book IDs
-- param: user_id: &str - user ID
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 (# book_ids (usize) : user_id (&str))
" 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.
Note also that parameter order is defined by the
param
declarations. SQL parameters that are present in the SQL code, but that are not declared as one of theparam
s, will be follow theparam
parameters in the order they are found in the SQL code.
§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 (# book_ids ('book_ids usize) : user_id ('user_id &str))
" 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 ")"
}
}