diesel_derives/lib.rs
1// Clippy lints
2#![allow(
3 clippy::needless_doctest_main,
4 clippy::needless_pass_by_value,
5 clippy::map_unwrap_or
6)]
7#![warn(
8 clippy::mut_mut,
9 clippy::non_ascii_literal,
10 clippy::similar_names,
11 clippy::unicode_not_nfc,
12 clippy::if_not_else,
13 clippy::items_after_statements,
14 clippy::used_underscore_binding,
15 missing_copy_implementations
16)]
17#![cfg_attr(feature = "nightly", feature(proc_macro_diagnostic))]
18
19extern crate diesel_table_macro_syntax;
20extern crate proc_macro;
21extern crate proc_macro2;
22extern crate quote;
23extern crate syn;
24
25use proc_macro::TokenStream;
26use sql_function::ExternSqlBlock;
27use syn::parse_quote;
28
29mod attrs;
30mod deprecated;
31mod field;
32mod model;
33mod parsers;
34mod util;
35
36mod as_changeset;
37mod as_expression;
38mod associations;
39mod diesel_for_each_tuple;
40mod diesel_numeric_ops;
41mod diesel_public_if;
42mod from_sql_row;
43mod has_query;
44mod identifiable;
45mod insertable;
46mod multiconnection;
47mod query_id;
48mod queryable;
49mod queryable_by_name;
50mod selectable;
51mod sql_function;
52mod sql_type;
53mod table;
54#[cfg(test)]
55mod tests;
56mod valid_grouping;
57
58/// Implements `AsChangeset`
59///
60/// To implement `AsChangeset` this derive needs to know the corresponding table
61/// type. By default, it uses the `snake_case` type name with an added `s` from
62/// the current scope.
63/// It is possible to change this default by using `#[diesel(table_name = something)]`.
64///
65/// If a field name of your struct differs
66/// from the name of the corresponding column, you can annotate the field with
67/// `#[diesel(column_name = some_column_name)]`.
68///
69/// Your struct can also contain fields which implement `AsChangeset`. This is
70/// useful when you want to have one field map to more than one column (for
71/// example, an enum that maps to a label and a value column). Add
72/// `#[diesel(embed)]` to any such fields.
73///
74/// To provide custom serialization behavior for a field, you can use
75/// `#[diesel(serialize_as = SomeType)]`. If this attribute is present, Diesel
76/// will call `.into` on the corresponding field and serialize the instance of `SomeType`,
77/// rather than the actual field on your struct. This can be used to add custom behavior for a
78/// single field, or use types that are otherwise unsupported by Diesel.
79/// Normally, Diesel produces two implementations of the `AsChangeset` trait for your
80/// struct using this derive: one for an owned version and one for a borrowed version.
81/// Using `#[diesel(serialize_as)]` implies a conversion using `.into` which consumes the underlying value.
82/// Hence, once you use `#[diesel(serialize_as)]`, Diesel can no longer update a borrowed
83/// versions of your struct.
84///
85/// By default, any `Option` fields on the struct are skipped if their value is
86/// `None`. If you would like to assign `NULL` to the field instead, you can
87/// annotate your struct with `#[diesel(treat_none_as_null = true)]`.
88///
89/// # Attributes
90///
91/// ## Optional container attributes
92///
93/// * `#[diesel(treat_none_as_null = true)]`, specifies that
94/// the derive should treat `None` values as `NULL`. By default
95/// `Option::<T>::None` is just skipped. To insert a `NULL` using default
96/// behavior use `Option::<Option<T>>::Some(None)`
97/// * `#[diesel(table_name = path::to::table)]`, specifies a path to the table for which the
98/// current type is a changeset. The path is relative to the current module.
99/// If this attribute is not used, the type name converted to
100/// `snake_case` with an added `s` is used as table name.
101/// * `#[diesel(primary_key(id1, id2))]` to specify the struct field that
102/// that corresponds to the primary key. If not used, `id` will be
103/// assumed as primary key field
104///
105/// ## Optional field attributes
106///
107/// * `#[diesel(column_name = some_column_name)]`, overrides the column name
108/// of the current field to `some_column_name`. By default, the field
109/// name is used as column name.
110/// * `#[diesel(embed)]`, specifies that the current field maps not only
111/// to a single database field, but is a struct that implements `AsChangeset`.
112/// * `#[diesel(serialize_as = SomeType)]`, instead of serializing the actual
113/// field type, Diesel will convert the field into `SomeType` using `.into` and
114/// serialize that instead. By default, this derive will serialize directly using
115/// the actual field type.
116/// * `#[diesel(treat_none_as_null = true/false)]`, overrides the container-level
117/// `treat_none_as_null` attribute for the current field.
118/// * `#[diesel(skip_update)]`, skips updating this field. Useful for working with
119/// generated columns.
120#[cfg_attr(diesel_docsrs, doc = include_str!(concat!(env!("OUT_DIR"), "/as_changeset.md")))]
121#[cfg_attr(
122 all(not(feature = "without-deprecated"), feature = "with-deprecated"),
123 proc_macro_derive(
124 AsChangeset,
125 attributes(diesel, table_name, column_name, primary_key, changeset_options)
126 )
127)]
128#[cfg_attr(
129 any(feature = "without-deprecated", not(feature = "with-deprecated")),
130 proc_macro_derive(AsChangeset, attributes(diesel))
131)]
132pub fn derive_as_changeset(input: TokenStream) -> TokenStream {
133 derive_as_changeset_inner(input.into()).into()
134}
135
136fn derive_as_changeset_inner(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
137 syn::parse2(input)
138 .and_then(as_changeset::derive)
139 .unwrap_or_else(syn::Error::into_compile_error)
140}
141
142/// Implements all required variants of `AsExpression`
143///
144/// This derive will generate the following impls:
145///
146/// - `impl AsExpression<SqlType> for YourType`
147/// - `impl AsExpression<Nullable<SqlType>> for YourType`
148/// - `impl AsExpression<SqlType> for &'a YourType`
149/// - `impl AsExpression<Nullable<SqlType>> for &'a YourType`
150/// - `impl AsExpression<SqlType> for &'a &'b YourType`
151/// - `impl AsExpression<Nullable<SqlType>> for &'a &'b YourType`
152///
153/// If your type is unsized,
154/// you can specify this by adding the annotation `#[diesel(not_sized)]`
155/// as attribute on the type. This will skip the impls for non-reference types.
156///
157/// Using this derive requires implementing the `ToSql` trait for your type.
158///
159/// # Attributes:
160///
161/// ## Required container attributes
162///
163/// * `#[diesel(sql_type = SqlType)]`, to specify the sql type of the
164/// generated implementations. If the attribute exists multiple times
165/// impls for each sql type is generated.
166///
167/// ## Optional container attributes
168///
169/// * `#[diesel(not_sized)]`, to skip generating impls that require
170/// that the type is `Sized`
171///
172#[cfg_attr(diesel_docsrs, doc = include_str!(concat!(env!("OUT_DIR"), "/as_expression.md")))]
173#[cfg_attr(
174 all(not(feature = "without-deprecated"), feature = "with-deprecated"),
175 proc_macro_derive(AsExpression, attributes(diesel, sql_type))
176)]
177#[cfg_attr(
178 any(feature = "without-deprecated", not(feature = "with-deprecated")),
179 proc_macro_derive(AsExpression, attributes(diesel))
180)]
181pub fn derive_as_expression(input: TokenStream) -> TokenStream {
182 derive_as_expression_inner(input.into()).into()
183}
184
185fn derive_as_expression_inner(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
186 syn::parse2(input)
187 .and_then(as_expression::derive)
188 .unwrap_or_else(syn::Error::into_compile_error)
189}
190
191/// Implement required traits for the associations API
192///
193/// This derive implements support for Diesel's associations api. Check the
194/// module level documentation of the `diesel::associations` module for details.
195///
196/// This derive generates the following impls:
197/// * `impl BelongsTo<Parent> for YourType`
198/// * `impl BelongsTo<&'a Parent> for YourType`
199///
200/// # Attributes
201///
202/// # Required container attributes
203///
204/// * `#[diesel(belongs_to(User))]`, to specify a child-to-parent relationship
205/// between the current type and the specified parent type (`User`).
206/// If this attribute is given multiple times, multiple relationships
207/// are generated. `#[diesel(belongs_to(User, foreign_key = mykey))]` variant
208/// allows us to specify the name of the foreign key. If the foreign key
209/// is not specified explicitly, the remote lower case type name with
210/// appended `_id` is used as a foreign key name. (`user_id` in this example
211/// case)
212///
213/// # Optional container attributes
214///
215/// * `#[diesel(table_name = path::to::table)]` specifies a path to the table this
216/// type belongs to. The path is relative to the current module.
217/// If this attribute is not used, the type name converted to
218/// `snake_case` with an added `s` is used as table name.
219///
220/// # Optional field attributes
221///
222/// * `#[diesel(column_name = some_column_name)]`, overrides the column the current
223/// field maps to `some_column_name`. By default, the field name is used
224/// as a column name.
225///
226#[cfg_attr(diesel_docsrs, doc = include_str!(concat!(env!("OUT_DIR"), "/associations.md")))]
227#[cfg_attr(
228 all(not(feature = "without-deprecated"), feature = "with-deprecated"),
229 proc_macro_derive(Associations, attributes(diesel, belongs_to, column_name, table_name))
230)]
231#[cfg_attr(
232 any(feature = "without-deprecated", not(feature = "with-deprecated")),
233 proc_macro_derive(Associations, attributes(diesel, belongs_to, column_name, table_name))
234)]
235pub fn derive_associations(input: TokenStream) -> TokenStream {
236 derive_associations_inner(input.into()).into()
237}
238
239fn derive_associations_inner(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
240 syn::parse2(input)
241 .and_then(associations::derive)
242 .unwrap_or_else(syn::Error::into_compile_error)
243}
244
245/// Implement numeric operators for the current query node
246#[proc_macro_derive(DieselNumericOps)]
247pub fn derive_diesel_numeric_ops(input: TokenStream) -> TokenStream {
248 derive_diesel_numeric_ops_inner(input.into()).into()
249}
250
251fn derive_diesel_numeric_ops_inner(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
252 syn::parse2(input)
253 .map(diesel_numeric_ops::derive)
254 .unwrap_or_else(syn::Error::into_compile_error)
255}
256
257/// Implements `Queryable` for types that correspond to a single SQL type. The type must implement `FromSql`.
258///
259/// This derive is mostly useful to implement support deserializing
260/// into rust types not supported by Diesel itself.
261///
262/// There are no options or special considerations needed for this derive.
263///
264#[cfg_attr(diesel_docsrs, doc = include_str!(concat!(env!("OUT_DIR"), "/from_sql_row.md")))]
265#[proc_macro_derive(FromSqlRow, attributes(diesel))]
266pub fn derive_from_sql_row(input: TokenStream) -> TokenStream {
267 derive_from_sql_row_inner(input.into()).into()
268}
269
270fn derive_from_sql_row_inner(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
271 syn::parse2(input)
272 .and_then(from_sql_row::derive)
273 .unwrap_or_else(syn::Error::into_compile_error)
274}
275
276/// Implements `Identifiable` for references of the current type
277///
278/// By default, the primary key field is assumed to be a single field called `id`.
279/// If it isn't, you can put `#[diesel(primary_key(your_id))]` on your struct.
280/// If you have a composite primary key, the syntax is `#[diesel(primary_key(id1, id2))]`.
281///
282/// By default, `#[derive(Identifiable)]` will assume that your table is
283/// in scope and its name is the plural form of your struct name.
284/// Diesel uses basic pluralization rules.
285/// It only adds an `s` to the end, and converts `CamelCase` to `snake_case`.
286/// If your table name doesn't follow this convention or is not in scope,
287/// you can specify a path to the table with `#[diesel(table_name = path::to::table)]`.
288/// Our rules for inferring table names are considered public API.
289/// It will never change without a major version bump.
290///
291/// This derive generates the following impls:
292/// * `impl Identifiable for &'a YourType`
293/// * `impl Identifiable for &'_ &'a YourType`
294///
295/// # Attributes
296///
297/// ## Optional container attributes
298///
299/// * `#[diesel(table_name = path::to::table)]` specifies a path to the table this
300/// type belongs to. The path is relative to the current module.
301/// If this attribute is not used, the type name converted to
302/// `snake_case` with an added `s` is used as table name
303/// * `#[diesel(primary_key(id1, id2))]` to specify the struct field that
304/// that corresponds to the primary key. If not used, `id` will be
305/// assumed as primary key field
306///
307/// # Optional field attributes
308///
309/// * `#[diesel(column_name = some_column_name)]`, overrides the column the current
310/// field maps to `some_column_name`. By default, the field name is used
311/// as a column name.
312///
313#[cfg_attr(diesel_docsrs, doc = include_str!(concat!(env!("OUT_DIR"), "/identifiable.md")))]
314#[cfg_attr(
315 all(not(feature = "without-deprecated"), feature = "with-deprecated"),
316 proc_macro_derive(Identifiable, attributes(diesel, table_name, column_name, primary_key))
317)]
318#[cfg_attr(
319 any(feature = "without-deprecated", not(feature = "with-deprecated")),
320 proc_macro_derive(Identifiable, attributes(diesel))
321)]
322pub fn derive_identifiable(input: TokenStream) -> TokenStream {
323 derive_identifiable_inner(input.into()).into()
324}
325
326fn derive_identifiable_inner(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
327 syn::parse2(input)
328 .and_then(identifiable::derive)
329 .unwrap_or_else(syn::Error::into_compile_error)
330}
331
332/// Implements `Insertable`
333///
334/// To implement `Insertable` this derive needs to know the corresponding table
335/// type. By default, it uses the `snake_case` type name with an added `s`
336/// from the current scope.
337/// It is possible to change this default by using `#[diesel(table_name = something)]`.
338/// If `table_name` attribute is given multiple times, impls for each table are generated.
339///
340/// If a field name of your
341/// struct differs from the name of the corresponding column,
342/// you can annotate the field with `#[diesel(column_name = some_column_name)]`.
343///
344/// Your struct can also contain fields which implement `Insertable`. This is
345/// useful when you want to have one field map to more than one column (for
346/// example, an enum that maps to a label and a value column). Add
347/// `#[diesel(embed)]` to any such fields.
348///
349/// To provide custom serialization behavior for a field, you can use
350/// `#[diesel(serialize_as = SomeType)]`. If this attribute is present, Diesel
351/// will call `.into` on the corresponding field and serialize the instance of `SomeType`,
352/// rather than the actual field on your struct. This can be used to add custom behavior for a
353/// single field, or use types that are otherwise unsupported by Diesel.
354/// Using `#[diesel(serialize_as)]` is **incompatible** with `#[diesel(embed)]`.
355/// Normally, Diesel produces two implementations of the `Insertable` trait for your
356/// struct using this derive: one for an owned version and one for a borrowed version.
357/// Using `#[diesel(serialize_as)]` implies a conversion using `.into` which consumes the underlying value.
358/// Hence, once you use `#[diesel(serialize_as)]`, Diesel can no longer insert borrowed
359/// versions of your struct. Call `.values(your_struct)` instead of `.values(&your_struct)`
360/// in that case.
361///
362/// # Attributes
363///
364/// ## Optional container attributes
365///
366/// * `#[diesel(table_name = path::to::table)]`, specifies a path to the table this type
367/// is insertable into. The path is relative to the current module.
368/// If this attribute is not used, the type name converted to
369/// `snake_case` with an added `s` is used as table name
370/// * `#[diesel(treat_none_as_default_value = false)]`, specifies that `None` values
371/// should be converted to `NULL` values on the SQL side instead of being treated as `DEFAULT`
372/// value primitive. *Note*: This option may control if your query is stored in the
373/// prepared statement cache or not*
374///
375/// ## Optional field attributes
376///
377/// * `#[diesel(column_name = some_column_name)]`, overrides the column the current
378/// field maps to `some_column_name`. By default, the field name is used
379/// as column name
380/// * `#[diesel(embed)]`, specifies that the current field maps not only
381/// to a single database field, but is a struct that implements `Insertable`
382/// * `#[diesel(serialize_as = SomeType)]`, instead of serializing the actual
383/// field type, Diesel will convert the field into `SomeType` using `.into` and
384/// serialize that instead. By default, this derive will serialize directly using
385/// the actual field type.
386/// * `#[diesel(treat_none_as_default_value = true/false)]`, overrides the container-level
387/// `treat_none_as_default_value` attribute for the current field.
388/// * `#[diesel(skip_insertion)]`, skips insertion of this field. Useful for working with
389/// generated columns.
390///
391/// # Examples
392///
393/// If we want to customize the serialization during insert, we can use `#[diesel(serialize_as)]`.
394///
395/// ```rust
396/// # extern crate diesel;
397/// # extern crate dotenvy;
398/// # include!("../../diesel/src/doctest_setup.rs");
399/// # use diesel::{prelude::*, serialize::{ToSql, Output, self}, deserialize::{FromSqlRow}, expression::AsExpression, sql_types, backend::Backend};
400/// # use schema::users;
401/// # use std::io::Write;
402/// #
403/// #[derive(Debug, FromSqlRow, AsExpression)]
404/// #[diesel(sql_type = sql_types::Text)]
405/// struct UppercaseString(pub String);
406///
407/// impl Into<UppercaseString> for String {
408/// fn into(self) -> UppercaseString {
409/// UppercaseString(self.to_uppercase())
410/// }
411/// }
412///
413/// impl<DB> ToSql<sql_types::Text, DB> for UppercaseString
414/// where
415/// DB: Backend,
416/// String: ToSql<sql_types::Text, DB>,
417/// {
418/// fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result {
419/// self.0.to_sql(out)
420/// }
421/// }
422///
423/// #[derive(Insertable, PartialEq, Debug)]
424/// #[diesel(table_name = users)]
425/// struct InsertableUser {
426/// id: i32,
427/// #[diesel(serialize_as = UppercaseString)]
428/// name: String,
429/// }
430///
431/// # fn main() {
432/// # run_test();
433/// # }
434/// #
435/// # fn run_test() -> QueryResult<()> {
436/// # use schema::users::dsl::*;
437/// # let connection = &mut connection_no_data();
438/// # diesel::sql_query("CREATE TEMPORARY TABLE users (id INTEGER PRIMARY KEY, name VARCHAR(255) NOT NULL)")
439/// # .execute(connection)
440/// # .unwrap();
441/// let user = InsertableUser {
442/// id: 1,
443/// name: "thomas".to_string(),
444/// };
445///
446/// diesel::insert_into(users)
447/// .values(user)
448/// .execute(connection)
449/// .unwrap();
450///
451/// assert_eq!(
452/// Ok("THOMAS".to_string()),
453/// users.select(name).first(connection)
454/// );
455/// # Ok(())
456/// # }
457/// ```
458///
459#[cfg_attr(diesel_docsrs, doc = include_str!(concat!(env!("OUT_DIR"), "/insertable.md")))]
460#[cfg_attr(
461 all(not(feature = "without-deprecated"), feature = "with-deprecated"),
462 proc_macro_derive(Insertable, attributes(diesel, table_name, column_name))
463)]
464#[cfg_attr(
465 any(feature = "without-deprecated", not(feature = "with-deprecated")),
466 proc_macro_derive(Insertable, attributes(diesel))
467)]
468pub fn derive_insertable(input: TokenStream) -> TokenStream {
469 derive_insertable_inner(input.into()).into()
470}
471
472fn derive_insertable_inner(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
473 syn::parse2(input)
474 .and_then(insertable::derive)
475 .unwrap_or_else(syn::Error::into_compile_error)
476}
477
478/// Implements `QueryId`
479///
480/// For example, given this struct:
481///
482/// ```rust
483/// # extern crate diesel;
484/// #[derive(diesel::query_builder::QueryId)]
485/// pub struct And<Left, Right> {
486/// left: Left,
487/// right: Right,
488/// }
489/// ```
490///
491/// the following implementation will be generated
492///
493/// ```rust
494/// # extern crate diesel;
495/// # struct And<Left, Right>(Left, Right);
496/// # use diesel::query_builder::QueryId;
497/// impl<Left, Right> QueryId for And<Left, Right>
498/// where
499/// Left: QueryId,
500/// Right: QueryId,
501/// {
502/// type QueryId = And<Left::QueryId, Right::QueryId>;
503///
504/// const HAS_STATIC_QUERY_ID: bool = Left::HAS_STATIC_QUERY_ID && Right::HAS_STATIC_QUERY_ID;
505/// }
506/// ```
507///
508/// If the SQL generated by a struct is not uniquely identifiable by its type,
509/// meaning that `HAS_STATIC_QUERY_ID` should always be false,
510/// you shouldn't derive this trait.
511/// In that case, you should implement it manually instead.
512///
513#[cfg_attr(diesel_docsrs, doc = include_str!(concat!(env!("OUT_DIR"), "/query_id.md")))]
514#[proc_macro_derive(QueryId, attributes(diesel))]
515pub fn derive_query_id(input: TokenStream) -> TokenStream {
516 derive_query_id_inner(input.into()).into()
517}
518
519fn derive_query_id_inner(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
520 syn::parse2(input)
521 .map(query_id::derive)
522 .unwrap_or_else(syn::Error::into_compile_error)
523}
524
525/// Implements `Queryable` to load the result of statically typed queries
526///
527/// This trait can only be derived for structs, not enums.
528///
529/// **Note**: When this trait is derived, it will assume that __all fields on
530/// your struct__ matches __all fields in the query__, including the order and
531/// count. This means that field order is significant if you're using
532/// `#[derive(Queryable)]`. __Field name has no effect__. If you see errors while
533/// loading data into a struct that derives `Queryable`: Consider using
534/// [`#[derive(Selectable)]`] + `#[diesel(check_for_backend(YourBackendType))]`
535/// to check for mismatching fields at compile-time.
536///
537/// To provide custom deserialization behavior for a field, you can use
538/// `#[diesel(deserialize_as = SomeType)]`. If this attribute is present, Diesel
539/// will deserialize the corresponding field into `SomeType`, rather than the
540/// actual field type on your struct and then call
541/// [`.try_into`](https://doc.rust-lang.org/stable/std/convert/trait.TryInto.html#tymethod.try_into)
542/// to convert it to the actual field type. This can be used to add custom behavior for a
543/// single field, or use types that are otherwise unsupported by Diesel.
544/// (Note: all types that have `Into<T>` automatically implement `TryInto<T>`,
545/// for cases where your conversion is not fallible.)
546///
547/// # Attributes
548///
549/// ## Optional field attributes
550///
551/// * `#[diesel(deserialize_as = Type)]`, instead of deserializing directly
552/// into the field type, the implementation will deserialize into `Type`.
553/// Then `Type` is converted via
554/// `.try_into()` call into the field type. By default, this derive will deserialize directly into the field type
555/// The `try_into()` method can be provided by:
556/// + Implementing any of the [`TryInto`]/[`TryFrom`]/[`Into`]/[`From`] traits
557/// + Using an method on the type directly (Useful if it's not possible to implement the traits mentioned above
558/// due to the orphan rule)
559///
560/// [`TryInto`]: https://doc.rust-lang.org/stable/std/convert/trait.TryInto.html
561/// [`TryFrom`]: https://doc.rust-lang.org/stable/std/convert/trait.TryFrom.html
562/// [`Into`]: https://doc.rust-lang.org/stable/std/convert/trait.Into.html
563/// [`From`]: https://doc.rust-lang.org/stable/std/convert/trait.From.html
564///
565/// # Examples
566///
567/// If we just want to map a query to our struct, we can use `derive`.
568///
569/// ```rust
570/// # extern crate diesel;
571/// # extern crate dotenvy;
572/// # include!("../../diesel/src/doctest_setup.rs");
573/// #
574/// #[derive(Queryable, PartialEq, Debug)]
575/// struct User {
576/// id: i32,
577/// name: String,
578/// }
579///
580/// # fn main() {
581/// # run_test();
582/// # }
583/// #
584/// # fn run_test() -> QueryResult<()> {
585/// # use schema::users::dsl::*;
586/// # let connection = &mut establish_connection();
587/// let first_user = users.first(connection)?;
588/// let expected = User {
589/// id: 1,
590/// name: "Sean".into(),
591/// };
592/// assert_eq!(expected, first_user);
593/// # Ok(())
594/// # }
595/// ```
596///
597/// If we want to do additional work during deserialization, we can use
598/// `deserialize_as` to use a different implementation.
599///
600/// ```rust
601/// # extern crate diesel;
602/// # extern crate dotenvy;
603/// # include!("../../diesel/src/doctest_setup.rs");
604/// #
605/// # use schema::users;
606/// # use diesel::backend::{self, Backend};
607/// # use diesel::deserialize::{self, Queryable, FromSql};
608/// # use diesel::sql_types::Text;
609/// #
610/// struct LowercaseString(String);
611///
612/// impl Into<String> for LowercaseString {
613/// fn into(self) -> String {
614/// self.0
615/// }
616/// }
617///
618/// impl<DB> Queryable<Text, DB> for LowercaseString
619/// where
620/// DB: Backend,
621/// String: FromSql<Text, DB>,
622/// {
623/// type Row = String;
624///
625/// fn build(s: String) -> deserialize::Result<Self> {
626/// Ok(LowercaseString(s.to_lowercase()))
627/// }
628/// }
629///
630/// #[derive(Queryable, PartialEq, Debug)]
631/// struct User {
632/// id: i32,
633/// #[diesel(deserialize_as = LowercaseString)]
634/// name: String,
635/// }
636///
637/// # fn main() {
638/// # run_test();
639/// # }
640/// #
641/// # fn run_test() -> QueryResult<()> {
642/// # use schema::users::dsl::*;
643/// # let connection = &mut establish_connection();
644/// let first_user = users.first(connection)?;
645/// let expected = User {
646/// id: 1,
647/// name: "sean".into(),
648/// };
649/// assert_eq!(expected, first_user);
650/// # Ok(())
651/// # }
652/// ```
653///
654/// Alternatively, we can implement the trait for our struct manually.
655///
656/// ```rust
657/// # extern crate diesel;
658/// # extern crate dotenvy;
659/// # include!("../../diesel/src/doctest_setup.rs");
660/// #
661/// use diesel::deserialize::{self, FromSqlRow, Queryable};
662/// use diesel::row::Row;
663/// use schema::users;
664///
665/// # /*
666/// type DB = diesel::sqlite::Sqlite;
667/// # */
668/// #[derive(PartialEq, Debug)]
669/// struct User {
670/// id: i32,
671/// name: String,
672/// }
673///
674/// impl Queryable<users::SqlType, DB> for User
675/// where
676/// (i32, String): FromSqlRow<users::SqlType, DB>,
677/// {
678/// type Row = (i32, String);
679///
680/// fn build((id, name): Self::Row) -> deserialize::Result<Self> {
681/// Ok(User {
682/// id,
683/// name: name.to_lowercase(),
684/// })
685/// }
686/// }
687///
688/// # fn main() {
689/// # run_test();
690/// # }
691/// #
692/// # fn run_test() -> QueryResult<()> {
693/// # use schema::users::dsl::*;
694/// # let connection = &mut establish_connection();
695/// let first_user = users.first(connection)?;
696/// let expected = User {
697/// id: 1,
698/// name: "sean".into(),
699/// };
700/// assert_eq!(expected, first_user);
701/// # Ok(())
702/// # }
703/// ```
704///
705#[cfg_attr(diesel_docsrs, doc = include_str!(concat!(env!("OUT_DIR"), "/queryable.md")))]
706#[cfg_attr(
707 all(not(feature = "without-deprecated"), feature = "with-deprecated"),
708 proc_macro_derive(Queryable, attributes(diesel, column_name))
709)]
710#[cfg_attr(
711 any(feature = "without-deprecated", not(feature = "with-deprecated")),
712 proc_macro_derive(Queryable, attributes(diesel))
713)]
714pub fn derive_queryable(input: TokenStream) -> TokenStream {
715 derive_queryable_inner(input.into()).into()
716}
717
718fn derive_queryable_inner(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
719 syn::parse2(input)
720 .and_then(queryable::derive)
721 .unwrap_or_else(syn::Error::into_compile_error)
722}
723
724/// Implements `QueryableByName` for untyped sql queries, such as that one generated
725/// by `sql_query`
726///
727/// To derive this trait, Diesel needs to know the SQL type of each field.
728/// It can get the data from the corresponding table type.
729/// It uses the `snake_case` type name with an added `s`.
730/// It is possible to change this default by using `#[diesel(table_name = something)]`.
731/// If you define use the table type, the SQL type will be
732/// `diesel::dsl::SqlTypeOf<table_name::column_name>`. In cases which there are no table type,
733/// you can do the same by annotating each field with `#[diesel(sql_type = SomeType)]`.
734///
735/// If the name of a field on your struct is different from the column in your
736/// `table!` declaration, or if you're deriving this trait on a tuple struct,
737/// you can annotate the field with `#[diesel(column_name = some_column)]`. For tuple
738/// structs, all fields must have this annotation.
739///
740/// If a field is another struct which implements `QueryableByName`,
741/// instead of a column, you can annotate that with `#[diesel(embed)]`.
742/// Then all fields contained by that inner struct are loaded into the embedded struct.
743///
744/// To provide custom deserialization behavior for a field, you can use
745/// `#[diesel(deserialize_as = SomeType)]`. If this attribute is present, Diesel
746/// will deserialize the corresponding field into `SomeType`, rather than the
747/// actual field type on your struct and then call `.into` to convert it to the
748/// actual field type. This can be used to add custom behavior for a
749/// single field, or use types that are otherwise unsupported by Diesel.
750///
751/// # Attributes
752///
753/// ## Optional container attributes
754///
755/// * `#[diesel(table_name = path::to::table)]`, to specify that this type contains
756/// columns for the specified table. The path is relative to the current module.
757/// If no field attributes are specified the derive will use the sql type of
758/// the corresponding column.
759/// * `#[diesel(check_for_backend(diesel::pg::Pg, diesel::mysql::Mysql))]`, instructs
760/// the derive to generate additional code to identify potential type mismatches.
761/// It accepts a list of backend types to check the types against. Using this option
762/// will result in much better error messages in cases where some types in your `QueryableByName`
763/// struct don't match. You need to specify the concrete database backend
764/// this specific struct is indented to be used with, as otherwise rustc can't correctly
765/// identify the required deserialization implementation.
766///
767/// ## Optional field attributes
768///
769/// * `#[diesel(column_name = some_column)]`, overrides the column name for
770/// a given field. If not set, the name of the field is used as a column
771/// name. This attribute is required on tuple structs, if
772/// `#[diesel(table_name = some_table)]` is used, otherwise it's optional.
773/// * `#[diesel(sql_type = SomeType)]`, assumes `SomeType` as sql type of the
774/// corresponding field. These attributes have precedence over all other
775/// variants to specify the sql type.
776/// * `#[diesel(deserialize_as = Type)]`, instead of deserializing directly
777/// into the field type, the implementation will deserialize into `Type`.
778/// Then `Type` is converted via `.into()` into the field type. By default,
779/// this derive will deserialize directly into the field type
780/// * `#[diesel(embed)]`, specifies that the current field maps not only
781/// a single database column, but it is a type that implements
782/// `QueryableByName` on its own
783///
784/// # Examples
785///
786/// If we just want to map a query to our struct, we can use `derive`.
787///
788/// ```rust
789/// # extern crate diesel;
790/// # extern crate dotenvy;
791/// # include!("../../diesel/src/doctest_setup.rs");
792/// # use schema::users;
793/// # use diesel::sql_query;
794/// #
795/// #[derive(QueryableByName, PartialEq, Debug)]
796/// struct User {
797/// id: i32,
798/// name: String,
799/// }
800///
801/// # fn main() {
802/// # run_test();
803/// # }
804/// #
805/// # fn run_test() -> QueryResult<()> {
806/// # let connection = &mut establish_connection();
807/// let first_user = sql_query("SELECT * FROM users ORDER BY id LIMIT 1").get_result(connection)?;
808/// let expected = User {
809/// id: 1,
810/// name: "Sean".into(),
811/// };
812/// assert_eq!(expected, first_user);
813/// # Ok(())
814/// # }
815/// ```
816///
817/// If we want to do additional work during deserialization, we can use
818/// `deserialize_as` to use a different implementation.
819///
820/// ```rust
821/// # extern crate diesel;
822/// # extern crate dotenvy;
823/// # include!("../../diesel/src/doctest_setup.rs");
824/// # use diesel::sql_query;
825/// # use schema::users;
826/// # use diesel::backend::{self, Backend};
827/// # use diesel::deserialize::{self, FromSql};
828/// #
829/// struct LowercaseString(String);
830///
831/// impl Into<String> for LowercaseString {
832/// fn into(self) -> String {
833/// self.0
834/// }
835/// }
836///
837/// impl<DB, ST> FromSql<ST, DB> for LowercaseString
838/// where
839/// DB: Backend,
840/// String: FromSql<ST, DB>,
841/// {
842/// fn from_sql(bytes: DB::RawValue<'_>) -> deserialize::Result<Self> {
843/// String::from_sql(bytes).map(|s| LowercaseString(s.to_lowercase()))
844/// }
845/// }
846///
847/// #[derive(QueryableByName, PartialEq, Debug)]
848/// struct User {
849/// id: i32,
850/// #[diesel(deserialize_as = LowercaseString)]
851/// name: String,
852/// }
853///
854/// # fn main() {
855/// # run_test();
856/// # }
857/// #
858/// # fn run_test() -> QueryResult<()> {
859/// # let connection = &mut establish_connection();
860/// let first_user = sql_query("SELECT * FROM users ORDER BY id LIMIT 1").get_result(connection)?;
861/// let expected = User {
862/// id: 1,
863/// name: "sean".into(),
864/// };
865/// assert_eq!(expected, first_user);
866/// # Ok(())
867/// # }
868/// ```
869///
870/// The custom derive generates impls similar to the following one
871///
872/// ```rust
873/// # extern crate diesel;
874/// # extern crate dotenvy;
875/// # include!("../../diesel/src/doctest_setup.rs");
876/// # use schema::users;
877/// # use diesel::sql_query;
878/// # use diesel::deserialize::{self, QueryableByName, FromSql};
879/// # use diesel::row::NamedRow;
880/// # use diesel::backend::Backend;
881/// #
882/// #[derive(PartialEq, Debug)]
883/// struct User {
884/// id: i32,
885/// name: String,
886/// }
887///
888/// impl<DB> QueryableByName<DB> for User
889/// where
890/// DB: Backend,
891/// i32: FromSql<diesel::dsl::SqlTypeOf<users::id>, DB>,
892/// String: FromSql<diesel::dsl::SqlTypeOf<users::name>, DB>,
893/// {
894/// fn build<'a>(row: &impl NamedRow<'a, DB>) -> deserialize::Result<Self> {
895/// let id = NamedRow::get::<diesel::dsl::SqlTypeOf<users::id>, _>(row, "id")?;
896/// let name = NamedRow::get::<diesel::dsl::SqlTypeOf<users::name>, _>(row, "name")?;
897///
898/// Ok(Self { id, name })
899/// }
900/// }
901///
902/// # fn main() {
903/// # run_test();
904/// # }
905/// #
906/// # fn run_test() -> QueryResult<()> {
907/// # let connection = &mut establish_connection();
908/// let first_user = sql_query("SELECT * FROM users ORDER BY id LIMIT 1").get_result(connection)?;
909/// let expected = User {
910/// id: 1,
911/// name: "Sean".into(),
912/// };
913/// assert_eq!(expected, first_user);
914/// # Ok(())
915/// # }
916/// ```
917///
918#[cfg_attr(diesel_docsrs, doc = include_str!(concat!(env!("OUT_DIR"), "/queryable_by_name.md")))]
919#[cfg_attr(
920 all(not(feature = "without-deprecated"), feature = "with-deprecated"),
921 proc_macro_derive(QueryableByName, attributes(diesel, table_name, column_name, sql_type))
922)]
923#[cfg_attr(
924 any(feature = "without-deprecated", not(feature = "with-deprecated")),
925 proc_macro_derive(QueryableByName, attributes(diesel))
926)]
927pub fn derive_queryable_by_name(input: TokenStream) -> TokenStream {
928 derive_queryable_by_name_inner(input.into()).into()
929}
930
931fn derive_queryable_by_name_inner(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
932 syn::parse2(input)
933 .and_then(queryable_by_name::derive)
934 .unwrap_or_else(syn::Error::into_compile_error)
935}
936
937/// Implements `Selectable`
938///
939/// To implement `Selectable` this derive needs to know the corresponding table
940/// type. By default, it uses the `snake_case` type name with an added `s`.
941/// It is possible to change this default by using `#[diesel(table_name = something)]`.
942///
943/// If the name of a field on your struct is different from the column in your
944/// `table!` declaration, or if you're deriving this trait on a tuple struct,
945/// you can annotate the field with `#[diesel(column_name = some_column)]`. For tuple
946/// structs, all fields must have this annotation.
947///
948/// If a field is another struct which implements `Selectable`,
949/// instead of a column, you can annotate that with `#[diesel(embed)]`.
950/// Then all fields contained by that inner struct are selected as separate tuple.
951/// Fields from an inner struct can come from a different table, as long as the
952/// select clause is valid in the current query.
953///
954/// The derive enables using the `SelectableHelper::as_select` method to construct
955/// select clauses, in order to use LoadDsl, you might also check the
956/// `Queryable` trait and derive.
957///
958/// # Attributes
959///
960/// ## Type attributes
961///
962/// * `#[diesel(table_name = path::to::table)]`, specifies a path to the table for which the
963/// current type is selectable. The path is relative to the current module.
964/// If this attribute is not used, the type name converted to
965/// `snake_case` with an added `s` is used as table name.
966///
967/// ## Optional Type attributes
968///
969/// * `#[diesel(check_for_backend(diesel::pg::Pg, diesel::mysql::Mysql))]`, instructs
970/// the derive to generate additional code to identify potential type mismatches.
971/// It accepts a list of backend types to check the types against. Using this option
972/// will result in much better error messages in cases where some types in your `Queryable`
973/// struct don't match. You need to specify the concrete database backend
974/// this specific struct is indented to be used with, as otherwise rustc can't correctly
975/// identify the required deserialization implementation.
976///
977/// ## Field attributes
978///
979/// * `#[diesel(column_name = some_column)]`, overrides the column name for
980/// a given field. If not set, the name of the field is used as column
981/// name.
982/// * `#[diesel(embed)]`, specifies that the current field maps not only
983/// a single database column, but is a type that implements
984/// `Selectable` on its own
985/// * `#[diesel(select_expression = some_custom_select_expression)]`, overrides
986/// the entire select expression for the given field. It may be used to select with
987/// custom tuples, or specify `select_expression = my_table::some_field.is_not_null()`,
988/// or separate tables...
989/// It may be used in conjunction with `select_expression_type` (described below)
990/// * `#[diesel(select_expression_type = the_custom_select_expression_type]`, should be used
991/// in conjunction with `select_expression` (described above) if the type is too complex
992/// for diesel to infer it automatically. This will be required if select_expression is a custom
993/// function call that doesn't have the corresponding associated type defined at the same path.
994/// Example use (this would actually be inferred):
995/// `#[diesel(select_expression_type = dsl::IsNotNull<my_table::some_field>)]`
996///
997#[cfg_attr(diesel_docsrs, doc = include_str!(concat!(env!("OUT_DIR"), "/selectable.md")))]
998#[proc_macro_derive(Selectable, attributes(diesel))]
999pub fn derive_selectable(input: TokenStream) -> TokenStream {
1000 derive_selectable_inner(input.into()).into()
1001}
1002
1003fn derive_selectable_inner(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
1004 syn::parse2(input)
1005 .and_then(|i| selectable::derive(i, None))
1006 .unwrap_or_else(syn::Error::into_compile_error)
1007}
1008
1009/// Implement necessary traits for adding a new sql type
1010///
1011/// This trait implements all necessary traits to define a
1012/// new sql type. This is useful for adding support for unsupported
1013/// or custom types on the sql side. The sql type will be usable for
1014/// all backends you specified via the attributes listed below.
1015///
1016/// This derive will implement `NotNull`, `HasSqlType` and `SingleValue`.
1017/// When using this derive macro,
1018/// you need to specify how the type is represented on various backends.
1019/// You don't need to specify every backend,
1020/// only the ones supported by your type.
1021///
1022/// For PostgreSQL, add `#[diesel(postgres_type(name = "pg_type_name", schema = "pg_schema_name"))]`
1023/// or `#[diesel(postgres_type(oid = "some_oid", array_oid = "some_oid"))]` for
1024/// builtin types.
1025/// For MySQL, specify which variant of `MysqlType` should be used
1026/// by adding `#[diesel(mysql_type(name = "Variant"))]`.
1027/// For SQLite, specify which variant of `SqliteType` should be used
1028/// by adding `#[diesel(sqlite_type(name = "Variant"))]`.
1029///
1030/// # Attributes
1031///
1032/// ## Type attributes
1033///
1034/// * `#[diesel(postgres_type(name = "TypeName", schema = "public"))]` specifies support for
1035/// a postgresql type with the name `TypeName` in the schema `public`. Prefer this variant
1036/// for types with no stable OID (== everything but the builtin types). It is possible to leaf
1037/// of the `schema` part. In that case, Diesel defaults to the default postgres search path.
1038/// * `#[diesel(postgres_type(oid = 42, array_oid = 142))]`, specifies support for a
1039/// postgresql type with the given `oid` and `array_oid`. This variant
1040/// should only be used with types that have a stable OID.
1041/// * `#[diesel(sqlite_type(name = "TypeName"))]`, specifies support for a sqlite type
1042/// with the given name. `TypeName` needs to be one of the possible values
1043/// in `SqliteType`
1044/// * `#[diesel(mysql_type(name = "TypeName"))]`, specifies support for a mysql type
1045/// with the given name. `TypeName` needs to be one of the possible values
1046/// in `MysqlType`
1047///
1048#[cfg_attr(diesel_docsrs, doc = include_str!(concat!(env!("OUT_DIR"), "/sql_type.md")))]
1049#[cfg_attr(
1050 all(not(feature = "without-deprecated"), feature = "with-deprecated"),
1051 proc_macro_derive(SqlType, attributes(diesel, postgres, sqlite_type, mysql_type))
1052)]
1053#[cfg_attr(
1054 any(feature = "without-deprecated", not(feature = "with-deprecated")),
1055 proc_macro_derive(SqlType, attributes(diesel))
1056)]
1057pub fn derive_sql_type(input: TokenStream) -> TokenStream {
1058 derive_sql_type_inner(input.into()).into()
1059}
1060
1061fn derive_sql_type_inner(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
1062 syn::parse2(input)
1063 .and_then(sql_type::derive)
1064 .unwrap_or_else(syn::Error::into_compile_error)
1065}
1066
1067/// Implements `ValidGrouping`
1068///
1069/// This trait can be automatically derived for structs with no type parameters
1070/// which are never aggregate, as well as for structs which are `NonAggregate`
1071/// when all type parameters are `NonAggregate`. For example:
1072///
1073/// ```ignore
1074/// #[derive(ValidGrouping)]
1075/// struct LiteralOne;
1076///
1077/// #[derive(ValidGrouping)]
1078/// struct Plus<Lhs, Rhs>(Lhs, Rhs);
1079///
1080/// // The following impl will be generated:
1081///
1082/// impl<GroupByClause> ValidGrouping<GroupByClause> for LiteralOne {
1083/// type IsAggregate = is_aggregate::Never;
1084/// }
1085///
1086/// impl<Lhs, Rhs, GroupByClause> ValidGrouping<GroupByClause> for Plus<Lhs, Rhs>
1087/// where
1088/// Lhs: ValidGrouping<GroupByClause>,
1089/// Rhs: ValidGrouping<GroupByClause>,
1090/// Lhs::IsAggregate: MixedAggregates<Rhs::IsAggregate>,
1091/// {
1092/// type IsAggregate = <Lhs::IsAggregate as MixedAggregates<Rhs::IsAggregate>>::Output;
1093/// }
1094/// ```
1095///
1096/// For types which are always considered aggregate (such as an aggregate
1097/// function), annotate your struct with `#[diesel(aggregate)]` to set `IsAggregate`
1098/// explicitly to `is_aggregate::Yes`.
1099///
1100/// # Attributes
1101///
1102/// ## Optional container attributes
1103///
1104/// * `#[diesel(aggregate)]` for cases where the type represents an aggregating
1105/// SQL expression
1106///
1107#[cfg_attr(diesel_docsrs, doc = include_str!(concat!(env!("OUT_DIR"), "/valid_grouping.md")))]
1108#[proc_macro_derive(ValidGrouping, attributes(diesel))]
1109pub fn derive_valid_grouping(input: TokenStream) -> TokenStream {
1110 derive_valid_grouping_inner(input.into()).into()
1111}
1112
1113fn derive_valid_grouping_inner(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
1114 syn::parse2(input)
1115 .and_then(valid_grouping::derive)
1116 .unwrap_or_else(syn::Error::into_compile_error)
1117}
1118
1119/// Declare a sql function for use in your code.
1120///
1121/// Diesel only provides support for a very small number of SQL functions.
1122/// This macro enables you to add additional functions from the SQL standard,
1123/// as well as any custom functions your application might have.
1124///
1125/// This is a legacy variant of the [`#[declare_sql_function]`] attribute macro, which
1126/// should be preferred instead. It will generate the same code as the attribute macro
1127/// and also it will accept the same syntax as the other macro.
1128///
1129/// The syntax for this macro is very similar to that of a normal Rust function,
1130/// except the argument and return types will be the SQL types being used.
1131/// Typically, these types will come from [`diesel::sql_types`](../diesel/sql_types/index.html)
1132///
1133/// This macro will generate two items. A function with the name that you've
1134/// given, and a module with a helper type representing the return type of your
1135/// function. For example, this invocation:
1136///
1137/// ```ignore
1138/// define_sql_function!(fn lower(x: Text) -> Text);
1139/// ```
1140///
1141/// will generate this code:
1142///
1143/// ```ignore
1144/// pub fn lower<X>(x: X) -> lower<X> {
1145/// ...
1146/// }
1147///
1148/// pub type lower<X> = ...;
1149/// ```
1150///
1151/// Most attributes given to this macro will be put on the generated function
1152/// (including doc comments).
1153///
1154/// # Adding Doc Comments
1155///
1156/// ```no_run
1157/// # extern crate diesel;
1158/// # use diesel::*;
1159/// #
1160/// # table! { crates { id -> Integer, name -> VarChar, } }
1161/// #
1162/// use diesel::sql_types::Text;
1163///
1164/// define_sql_function! {
1165/// /// Represents the `canon_crate_name` SQL function, created in
1166/// /// migration ....
1167/// fn canon_crate_name(a: Text) -> Text;
1168/// }
1169///
1170/// # fn main() {
1171/// # use self::crates::dsl::*;
1172/// let target_name = "diesel";
1173/// crates.filter(canon_crate_name(name).eq(canon_crate_name(target_name)));
1174/// // This will generate the following SQL
1175/// // SELECT * FROM crates WHERE canon_crate_name(crates.name) = canon_crate_name($1)
1176/// # }
1177/// ```
1178///
1179/// # Special Attributes
1180///
1181/// There are a handful of special attributes that Diesel will recognize. They
1182/// are:
1183///
1184/// - `#[aggregate]`
1185/// - Indicates that this is an aggregate function, and that `NonAggregate`
1186/// shouldn't be implemented.
1187/// - `#[sql_name = "name"]`
1188/// - The SQL to be generated is different from the Rust name of the function.
1189/// This can be used to represent functions which can take many argument
1190/// types, or to capitalize function names.
1191///
1192#[cfg_attr(diesel_docsrs, doc = include_str!(concat!(env!("OUT_DIR"), "/define_sql_function.md")))]
1193#[proc_macro]
1194pub fn define_sql_function(input: TokenStream) -> TokenStream {
1195 define_sql_function_inner(input.into()).into()
1196}
1197
1198fn define_sql_function_inner(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
1199 syn::parse2(input)
1200 .map(|input| sql_function::expand(vec![input], false, false))
1201 .unwrap_or_else(syn::Error::into_compile_error)
1202}
1203
1204/// A legacy version of [`define_sql_function!`].
1205///
1206/// The difference is that it makes the helper type available in a module named the exact same as
1207/// the function:
1208///
1209/// ```ignore
1210/// sql_function!(fn lower(x: Text) -> Text);
1211/// ```
1212///
1213/// will generate this code:
1214///
1215/// ```ignore
1216/// pub fn lower<X>(x: X) -> lower::HelperType<X> {
1217/// ...
1218/// }
1219///
1220/// pub(crate) mod lower {
1221/// pub type HelperType<X> = ...;
1222/// }
1223/// ```
1224///
1225/// This turned out to be an issue for the support of the `auto_type` feature, which is why
1226/// [`define_sql_function!`] was introduced (and why this is deprecated).
1227///
1228/// SQL functions declared with this version of the macro will not be usable with `#[auto_type]`
1229/// or `Selectable` `select_expression` type inference.
1230#[deprecated(since = "2.2.0", note = "Use [`define_sql_function`] instead")]
1231#[proc_macro]
1232#[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))]
1233pub fn sql_function_proc(input: TokenStream) -> TokenStream {
1234 sql_function_proc_inner(input.into()).into()
1235}
1236
1237#[cfg(all(feature = "with-deprecated", not(feature = "without-deprecated")))]
1238fn sql_function_proc_inner(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
1239 syn::parse2(input)
1240 .map(|i| sql_function::expand(vec![i], true, false))
1241 .unwrap_or_else(syn::Error::into_compile_error)
1242}
1243
1244/// This is an internal diesel macro that
1245/// helps to implement all traits for tuples of
1246/// various sizes
1247#[doc(hidden)]
1248#[proc_macro]
1249pub fn __diesel_for_each_tuple(input: TokenStream) -> TokenStream {
1250 __diesel_for_each_tuple_inner(input.into()).into()
1251}
1252
1253fn __diesel_for_each_tuple_inner(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
1254 syn::parse2(input)
1255 .map(diesel_for_each_tuple::expand)
1256 .unwrap_or_else(syn::Error::into_compile_error)
1257}
1258
1259/// This is an internal diesel macro that
1260/// helps to restrict the visibility of an item based
1261/// on a feature flag
1262#[doc(hidden)]
1263#[proc_macro_attribute]
1264pub fn __diesel_public_if(attrs: TokenStream, input: TokenStream) -> TokenStream {
1265 __diesel_public_if_inner(attrs.into(), input.into()).into()
1266}
1267
1268fn __diesel_public_if_inner(
1269 attrs: proc_macro2::TokenStream,
1270 input: proc_macro2::TokenStream,
1271) -> proc_macro2::TokenStream {
1272 syn::parse2(input)
1273 .and_then(|input| syn::parse2(attrs).map(|a| (a, input)))
1274 .map(|(a, i)| diesel_public_if::expand(a, i))
1275 .unwrap_or_else(syn::Error::into_compile_error)
1276}
1277
1278/// Specifies that a table exists, and what columns it has. This will create a
1279/// new public module, with the same name, as the name of the table. In this
1280/// module, you will find a unit struct named `table`, and a unit struct with the
1281/// name of each column.
1282///
1283/// By default, this allows a maximum of 32 columns per table.
1284/// You can increase this limit to 64 by enabling the `64-column-tables` feature.
1285/// You can increase it to 128 by enabling the `128-column-tables` feature.
1286/// You can decrease it to 16 columns,
1287/// which improves compilation time,
1288/// by disabling the default features of Diesel.
1289/// Note that enabling 64 column tables or larger will substantially increase
1290/// the compile time of Diesel.
1291///
1292/// Example usage
1293/// -------------
1294///
1295/// ```rust
1296/// # extern crate diesel;
1297///
1298/// diesel::table! {
1299/// users {
1300/// id -> Integer,
1301/// name -> VarChar,
1302/// favorite_color -> Nullable<VarChar>,
1303/// }
1304/// }
1305/// ```
1306///
1307/// You may also specify a primary key if it is called something other than `id`.
1308/// Tables with no primary key aren't supported.
1309///
1310/// ```rust
1311/// # extern crate diesel;
1312///
1313/// diesel::table! {
1314/// users (non_standard_primary_key) {
1315/// non_standard_primary_key -> Integer,
1316/// name -> VarChar,
1317/// favorite_color -> Nullable<VarChar>,
1318/// }
1319/// }
1320/// ```
1321///
1322/// For tables with composite primary keys, list all the columns in the primary key.
1323///
1324/// ```rust
1325/// # extern crate diesel;
1326///
1327/// diesel::table! {
1328/// followings (user_id, post_id) {
1329/// user_id -> Integer,
1330/// post_id -> Integer,
1331/// favorited -> Bool,
1332/// }
1333/// }
1334/// # fn main() {
1335/// # use diesel::prelude::Table;
1336/// # use self::followings::dsl::*;
1337/// # // Poor man's assert_eq! -- since this is type level this would fail
1338/// # // to compile if the wrong primary key were generated
1339/// # let (user_id {}, post_id {}) = followings.primary_key();
1340/// # }
1341/// ```
1342///
1343/// If you are using types that aren't from Diesel's core types, you can specify
1344/// which types to import.
1345///
1346/// ```
1347/// # extern crate diesel;
1348/// # mod diesel_full_text_search {
1349/// # #[derive(diesel::sql_types::SqlType)]
1350/// # pub struct TsVector;
1351/// # }
1352///
1353/// diesel::table! {
1354/// use diesel::sql_types::*;
1355/// # use crate::diesel_full_text_search::*;
1356/// # /*
1357/// use diesel_full_text_search::*;
1358/// # */
1359///
1360/// posts {
1361/// id -> Integer,
1362/// title -> Text,
1363/// keywords -> TsVector,
1364/// }
1365/// }
1366/// # fn main() {}
1367/// ```
1368///
1369/// If you want to add documentation to the generated code, you can use the
1370/// following syntax:
1371///
1372/// ```
1373/// # extern crate diesel;
1374///
1375/// diesel::table! {
1376/// /// The table containing all blog posts
1377/// posts {
1378/// /// The post's unique id
1379/// id -> Integer,
1380/// /// The post's title
1381/// title -> Text,
1382/// }
1383/// }
1384/// ```
1385///
1386/// If you have a column with the same name as a Rust reserved keyword, you can use
1387/// the `sql_name` attribute like this:
1388///
1389/// ```
1390/// # extern crate diesel;
1391///
1392/// diesel::table! {
1393/// posts {
1394/// id -> Integer,
1395/// /// This column is named `mytype` but references the table `type` column.
1396/// #[sql_name = "type"]
1397/// mytype -> Text,
1398/// }
1399/// }
1400/// ```
1401///
1402/// This module will also contain several helper types:
1403///
1404/// dsl
1405/// ---
1406///
1407/// This simply re-exports the table, renamed to the same name as the module,
1408/// and each of the columns. This is useful to glob import when you're dealing
1409/// primarily with one table, to allow writing `users.filter(name.eq("Sean"))`
1410/// instead of `users::table.filter(users::name.eq("Sean"))`.
1411///
1412/// `all_columns`
1413/// -----------
1414///
1415/// A constant will be assigned called `all_columns`. This is what will be
1416/// selected if you don't otherwise specify a select clause. It's type will be
1417/// `table::AllColumns`. You can also get this value from the
1418/// `Table::all_columns` function.
1419///
1420/// star
1421/// ----
1422///
1423/// This will be the qualified "star" expression for this table (e.g.
1424/// `users.*`). Internally, we read columns by index, not by name, so this
1425/// column is not safe to read data out of, and it has had its SQL type set to
1426/// `()` to prevent accidentally using it as such. It is sometimes useful for
1427/// counting statements, however. It can also be accessed through the `Table.star()`
1428/// method.
1429///
1430/// `SqlType`
1431/// -------
1432///
1433/// A type alias called `SqlType` will be created. It will be the SQL type of
1434/// `all_columns`. The SQL type is needed for things like returning boxed
1435/// queries.
1436///
1437/// `BoxedQuery`
1438/// ----------
1439///
1440/// ```ignore
1441/// pub type BoxedQuery<'a, DB, ST = SqlType> = BoxedSelectStatement<'a, ST, table, DB>;
1442/// ```
1443///
1444#[cfg_attr(diesel_docsrs, doc = include_str!(concat!(env!("OUT_DIR"), "/table.md")))]
1445#[proc_macro]
1446pub fn table_proc(input: TokenStream) -> TokenStream {
1447 table_proc_inner(input.into()).into()
1448}
1449
1450fn table_proc_inner(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
1451 // include the input in the error output so that rust-analyzer is happy
1452 let tokenstream2 = input.clone();
1453 match syn::parse2(input) {
1454 Ok(input) => table::expand(input),
1455 Err(_) => quote::quote! {
1456 compile_error!(
1457 "invalid `table!` syntax \nhelp: please see the `table!` macro docs for more info\n\
1458 help: docs available at: `https://docs.diesel.rs/master/diesel/macro.table.html`\n"
1459 );
1460 #tokenstream2
1461 },
1462 }
1463}
1464
1465/// This derives implements `diesel::Connection` and related traits for an enum of
1466/// connections to different databases.
1467///
1468/// By applying this derive to such an enum, you can use the enum as a connection type in
1469/// any location all the inner connections are valid. This derive supports enum
1470/// variants containing a single tuple field. Each tuple field type must implement
1471/// `diesel::Connection` and a number of related traits. Connection types form Diesel itself
1472/// as well as third party connection types are supported by this derive.
1473///
1474/// The implementation of `diesel::Connection::establish` tries to establish
1475/// a new connection with the given connection string in the order the connections
1476/// are specified in the enum. If one connection fails, it tries the next one and so on.
1477/// That means that as soon as more than one connection type accepts a certain connection
1478/// string the first matching type in your enum will always establish the connection. This
1479/// is especially important if one of the connection types is `diesel::SqliteConnection`
1480/// as this connection type accepts arbitrary paths. It should normally place as last entry
1481/// in your enum. If you want control of which connection type is created, just construct the
1482/// corresponding enum manually by first establishing the connection via the inner type and then
1483/// wrap the result into the enum.
1484///
1485/// # Example
1486/// ```
1487/// # extern crate diesel;
1488/// # use diesel::result::QueryResult;
1489/// use diesel::prelude::*;
1490///
1491/// #[derive(diesel::MultiConnection)]
1492/// pub enum AnyConnection {
1493/// # #[cfg(feature = "postgres")]
1494/// Postgresql(diesel::PgConnection),
1495/// # #[cfg(feature = "mysql")]
1496/// Mysql(diesel::MysqlConnection),
1497/// # #[cfg(feature = "sqlite")]
1498/// Sqlite(diesel::SqliteConnection),
1499/// }
1500///
1501/// diesel::table! {
1502/// users {
1503/// id -> Integer,
1504/// name -> Text,
1505/// }
1506/// }
1507///
1508/// fn use_multi(conn: &mut AnyConnection) -> QueryResult<()> {
1509/// // Use the connection enum as any other connection type
1510/// // for inserting/updating/loading/…
1511/// diesel::insert_into(users::table)
1512/// .values(users::name.eq("Sean"))
1513/// .execute(conn)?;
1514///
1515/// let users = users::table.load::<(i32, String)>(conn)?;
1516///
1517/// // Match on the connection type to access
1518/// // the inner connection. This allows us then to use
1519/// // backend specific methods.
1520/// # #[cfg(feature = "postgres")]
1521/// if let AnyConnection::Postgresql(ref mut conn) = conn {
1522/// // perform a postgresql specific query here
1523/// let users = users::table.load::<(i32, String)>(conn)?;
1524/// }
1525///
1526/// Ok(())
1527/// }
1528///
1529/// # fn main() {}
1530/// ```
1531///
1532/// # Limitations
1533///
1534/// The derived connection implementation can only cover the common subset of
1535/// all inner connection types. So, if one backend doesn't support certain SQL features,
1536/// like for example, returning clauses, the whole connection implementation doesn't
1537/// support this feature. In addition, only a limited set of SQL types is supported:
1538///
1539/// * `diesel::sql_types::SmallInt`
1540/// * `diesel::sql_types::Integer`
1541/// * `diesel::sql_types::BigInt`
1542/// * `diesel::sql_types::Double`
1543/// * `diesel::sql_types::Float`
1544/// * `diesel::sql_types::Text`
1545/// * `diesel::sql_types::Date`
1546/// * `diesel::sql_types::Time`
1547/// * `diesel::sql_types::Timestamp`
1548///
1549/// Support for additional types can be added by providing manual implementations of
1550/// `HasSqlType`, `FromSql` and `ToSql` for the corresponding type, all databases included
1551/// in your enum, and the backend generated by this derive called `MultiBackend`.
1552/// For example to support a custom enum `MyEnum` with the custom SQL type `MyInteger`:
1553/// ```
1554/// extern crate diesel;
1555/// use diesel::backend::Backend;
1556/// use diesel::deserialize::{self, FromSql, FromSqlRow};
1557/// use diesel::serialize::{self, IsNull, ToSql};
1558/// use diesel::AsExpression;
1559/// use diesel::sql_types::{HasSqlType, SqlType};
1560/// use diesel::prelude::*;
1561///
1562/// #[derive(diesel::MultiConnection)]
1563/// pub enum AnyConnection {
1564/// # #[cfg(feature = "postgres")]
1565/// Postgresql(diesel::PgConnection),
1566/// # #[cfg(feature = "mysql")]
1567/// Mysql(diesel::MysqlConnection),
1568/// # #[cfg(feature = "sqlite")]
1569/// Sqlite(diesel::SqliteConnection),
1570/// }
1571///
1572/// // defining an custom SQL type is optional
1573/// // you can also use types from `diesel::sql_types`
1574/// #[derive(Copy, Clone, Debug, SqlType)]
1575/// #[diesel(postgres_type(name = "Int4"))]
1576/// #[diesel(mysql_type(name = "Long"))]
1577/// #[diesel(sqlite_type(name = "Integer"))]
1578/// struct MyInteger;
1579///
1580///
1581/// // our custom enum
1582/// #[repr(i32)]
1583/// #[derive(Debug, Clone, Copy, AsExpression, FromSqlRow)]
1584/// #[diesel(sql_type = MyInteger)]
1585/// pub enum MyEnum {
1586/// A = 1,
1587/// B = 2,
1588/// }
1589///
1590/// // The `MultiBackend` type is generated by `#[derive(diesel::MultiConnection)]`
1591/// // This part is only required if you define a custom sql type
1592/// impl HasSqlType<MyInteger> for MultiBackend {
1593/// fn metadata(lookup: &mut Self::MetadataLookup) -> Self::TypeMetadata {
1594/// // The `lookup_sql_type` function is exposed by the `MultiBackend` type
1595/// MultiBackend::lookup_sql_type::<MyInteger>(lookup)
1596/// }
1597/// }
1598///
1599/// impl FromSql<MyInteger, MultiBackend> for MyEnum {
1600/// fn from_sql(bytes: <MultiBackend as Backend>::RawValue<'_>) -> deserialize::Result<Self> {
1601/// // The `from_sql` function is exposed by the `RawValue` type of the
1602/// // `MultiBackend` type
1603/// // This requires a `FromSql` impl for each backend
1604/// bytes.from_sql::<MyEnum, MyInteger>()
1605/// }
1606/// }
1607///
1608/// impl ToSql<MyInteger, MultiBackend> for MyEnum {
1609/// fn to_sql<'b>(&'b self, out: &mut serialize::Output<'b, '_, MultiBackend>) -> serialize::Result {
1610/// /// `set_value` expects a tuple consisting of the target SQL type
1611/// /// and self for `MultiBackend`
1612/// /// This requires a `ToSql` impl for each backend
1613/// out.set_value((MyInteger, self));
1614/// Ok(IsNull::No)
1615/// }
1616/// }
1617/// # #[cfg(feature = "postgres")]
1618/// # impl ToSql<MyInteger, diesel::pg::Pg> for MyEnum {
1619/// # fn to_sql<'b>(&'b self, out: &mut serialize::Output<'b, '_, diesel::pg::Pg>) -> serialize::Result { todo!() }
1620/// # }
1621/// # #[cfg(feature = "mysql")]
1622/// # impl ToSql<MyInteger, diesel::mysql::Mysql> for MyEnum {
1623/// # fn to_sql<'b>(&'b self, out: &mut serialize::Output<'b, '_, diesel::mysql::Mysql>) -> serialize::Result { todo!() }
1624/// # }
1625/// # #[cfg(feature = "sqlite")]
1626/// # impl ToSql<MyInteger, diesel::sqlite::Sqlite> for MyEnum {
1627/// # fn to_sql<'b>(&'b self, out: &mut serialize::Output<'b, '_, diesel::sqlite::Sqlite>) -> serialize::Result { todo!() }
1628/// # }
1629/// # #[cfg(feature = "postgres")]
1630/// # impl FromSql<MyInteger, diesel::pg::Pg> for MyEnum {
1631/// # fn from_sql(bytes: <diesel::pg::Pg as Backend>::RawValue<'_>) -> deserialize::Result<Self> { todo!() }
1632/// # }
1633/// # #[cfg(feature = "mysql")]
1634/// # impl FromSql<MyInteger, diesel::mysql::Mysql> for MyEnum {
1635/// # fn from_sql(bytes: <diesel::mysql::Mysql as Backend>::RawValue<'_>) -> deserialize::Result<Self> { todo!() }
1636/// # }
1637/// # #[cfg(feature = "sqlite")]
1638/// # impl FromSql<MyInteger, diesel::sqlite::Sqlite> for MyEnum {
1639/// # fn from_sql(bytes: <diesel::sqlite::Sqlite as Backend>::RawValue<'_>) -> deserialize::Result<Self> { todo!() }
1640/// # }
1641/// # fn main() {}
1642/// ```
1643///
1644#[cfg_attr(diesel_docsrs, doc = include_str!(concat!(env!("OUT_DIR"), "/multiconnection.md")))]
1645#[proc_macro_derive(MultiConnection)]
1646pub fn derive_multiconnection(input: TokenStream) -> TokenStream {
1647 derive_multiconnection_inner(input.into()).into()
1648}
1649
1650fn derive_multiconnection_inner(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
1651 syn::parse2(input)
1652 .map(multiconnection::derive)
1653 .unwrap_or_else(syn::Error::into_compile_error)
1654}
1655
1656/// Automatically annotates return type of a query fragment function
1657///
1658/// This may be useful when factoring out common query fragments into functions.
1659/// If not using this, it would typically involve explicitly writing the full
1660/// type of the query fragment function, which depending on the length of said
1661/// query fragment can be quite difficult (especially to maintain) and verbose.
1662///
1663/// # Example
1664///
1665/// ```rust
1666/// # extern crate diesel;
1667/// # include!("../../diesel/src/doctest_setup.rs");
1668/// # use schema::{users, posts};
1669/// use diesel::dsl;
1670///
1671/// # fn main() {
1672/// # run_test().unwrap();
1673/// # }
1674/// #
1675/// # fn run_test() -> QueryResult<()> {
1676/// # let conn = &mut establish_connection();
1677/// #
1678/// #[dsl::auto_type]
1679/// fn user_has_post() -> _ {
1680/// dsl::exists(posts::table.filter(posts::user_id.eq(users::id)))
1681/// }
1682///
1683/// let users_with_posts: Vec<String> = users::table
1684/// .filter(user_has_post())
1685/// .select(users::name)
1686/// .load(conn)?;
1687///
1688/// assert_eq!(
1689/// &["Sean", "Tess"] as &[_],
1690/// users_with_posts
1691/// .iter()
1692/// .map(|s| s.as_str())
1693/// .collect::<Vec<_>>()
1694/// );
1695/// # Ok(())
1696/// # }
1697/// ```
1698/// # Limitations
1699///
1700/// While this attribute tries to support as much of diesels built-in DSL as possible it's
1701/// unfortunately not possible to support everything. Notable unsupported types are:
1702///
1703/// * Update statements
1704/// * Insert from select statements
1705/// * Query constructed by `diesel::sql_query`
1706/// * Expressions using `diesel::dsl::sql`
1707///
1708/// For these cases a manual type annotation is required. See the "Annotating Types" section below
1709/// for details.
1710///
1711///
1712/// # Advanced usage
1713///
1714/// By default, the macro will:
1715/// - Generate a type alias for the return type of the function, named the
1716/// exact same way as the function itself.
1717/// - Assume that functions, unless otherwise annotated, have a type alias for
1718/// their return type available at the same path as the function itself
1719/// (including case). (e.g. for the `dsl::not(x)` call, it expects that there
1720/// is a `dsl::not<X>` type alias available)
1721/// - Assume that methods, unless otherwise annotated, have a type alias
1722/// available as `diesel::dsl::PascalCaseOfMethodName` (e.g. for the
1723/// `x.and(y)` call, it expects that there is a `diesel::dsl::And<X, Y>` type
1724/// alias available)
1725///
1726/// The defaults can be changed by passing the following attributes to the
1727/// macro:
1728/// - `#[auto_type(no_type_alias)]` to disable the generation of the type alias.
1729/// - `#[auto_type(dsl_path = "path::to::dsl")]` to change the path where the
1730/// macro will look for type aliases for methods. This is required if you mix your own
1731/// custom query dsl extensions with diesel types. In that case, you may use this argument to
1732/// reference a module defined like so:
1733/// ```ignore
1734/// mod dsl {
1735/// /// export all of diesel dsl
1736/// pub use diesel::dsl::*;
1737///
1738/// /// Export your extension types here
1739/// pub use crate::your_extension::dsl::YourType;
1740/// }
1741/// ```
1742/// - `#[auto_type(type_case = "snake_case")]` to change the case of the
1743/// method type alias.
1744///
1745/// The `dsl_path` attribute in particular may be used to declare an
1746/// intermediate module where you would define the few additional needed type
1747/// aliases that can't be inferred automatically.
1748///
1749/// ## Annotating types
1750///
1751/// Sometimes the macro can't infer the type of a particular sub-expression. In
1752/// that case, you can annotate the type of the sub-expression:
1753///
1754/// ```rust
1755/// # extern crate diesel;
1756/// # include!("../../diesel/src/doctest_setup.rs");
1757/// # use schema::{users, posts};
1758/// use diesel::dsl;
1759///
1760/// # fn main() {
1761/// # run_test().unwrap();
1762/// # }
1763/// #
1764/// # fn run_test() -> QueryResult<()> {
1765/// # let conn = &mut establish_connection();
1766/// #
1767/// // This will generate a `user_has_post_with_id_greater_than` type alias
1768/// #[dsl::auto_type]
1769/// fn user_has_post_with_id_greater_than(id_greater_than: i32) -> _ {
1770/// dsl::exists(
1771/// posts::table
1772/// .filter(posts::user_id.eq(users::id))
1773/// .filter(posts::id.gt(id_greater_than)),
1774/// )
1775/// }
1776///
1777/// #[dsl::auto_type]
1778/// fn users_with_posts_with_id_greater_than(id_greater_than: i32) -> _ {
1779/// // If we didn't specify the type for this query fragment, the macro would infer it as
1780/// // `user_has_post_with_id_greater_than<i32>`, which would be incorrect because there is
1781/// // no generic parameter.
1782/// let filter: user_has_post_with_id_greater_than =
1783/// user_has_post_with_id_greater_than(id_greater_than);
1784/// // The macro inferring that it has to pass generic parameters is still the convention
1785/// // because it's the most general case, as well as the common case within Diesel itself,
1786/// // and because annotating this way is reasonably simple, while the other way around
1787/// // would be hard.
1788///
1789/// users::table.filter(filter).select(users::name)
1790/// }
1791///
1792/// let users_with_posts: Vec<String> = users_with_posts_with_id_greater_than(2).load(conn)?;
1793///
1794/// assert_eq!(
1795/// &["Tess"] as &[_],
1796/// users_with_posts
1797/// .iter()
1798/// .map(|s| s.as_str())
1799/// .collect::<Vec<_>>()
1800/// );
1801/// # Ok(())
1802/// # }
1803/// ```
1804///
1805#[cfg_attr(diesel_docsrs, doc = include_str!(concat!(env!("OUT_DIR"), "/auto_type.md")))]
1806#[proc_macro_attribute]
1807pub fn auto_type(
1808 attr: proc_macro::TokenStream,
1809 input: proc_macro::TokenStream,
1810) -> proc_macro::TokenStream {
1811 auto_type_inner(attr.into(), input.into()).into()
1812}
1813
1814fn auto_type_inner(
1815 attr: proc_macro2::TokenStream,
1816 input: proc_macro2::TokenStream,
1817) -> proc_macro2::TokenStream {
1818 dsl_auto_type::auto_type_proc_macro_attribute(
1819 attr,
1820 input,
1821 dsl_auto_type::DeriveSettings::builder()
1822 .default_dsl_path(parse_quote!(diesel::dsl))
1823 .default_generate_type_alias(true)
1824 .default_method_type_case(AUTO_TYPE_DEFAULT_METHOD_TYPE_CASE)
1825 .default_function_type_case(AUTO_TYPE_DEFAULT_FUNCTION_TYPE_CASE)
1826 .build(),
1827 )
1828}
1829
1830const AUTO_TYPE_DEFAULT_METHOD_TYPE_CASE: dsl_auto_type::Case = dsl_auto_type::Case::UpperCamel;
1831const AUTO_TYPE_DEFAULT_FUNCTION_TYPE_CASE: dsl_auto_type::Case = dsl_auto_type::Case::DoNotChange;
1832
1833/// Declare a sql function for use in your code.
1834///
1835/// Diesel only provides support for a very small number of SQL functions.
1836/// This macro enables you to add additional functions from the SQL standard,
1837/// as well as any custom functions your application might have.
1838///
1839/// The syntax for this attribute macro is designed to be applied to `extern "SQL"` blocks
1840/// with function definitions. These function typically use types
1841/// from [`diesel::sql_types`](../diesel/sql_types/index.html) as arguments and return types.
1842/// You can use such definitions to declare bindings to unsupported SQL functions.
1843///
1844/// For each function in this `extern` block the macro will generate two items.
1845/// A function with the name that you've given, and a module with a helper type
1846/// representing the return type of your function. For example, this invocation:
1847///
1848/// ```ignore
1849/// #[declare_sql_function]
1850/// extern "SQL" {
1851/// fn lower(x: Text) -> Text
1852/// }
1853/// ```
1854///
1855/// will generate this code:
1856///
1857/// ```ignore
1858/// pub fn lower<X>(x: X) -> lower<X> {
1859/// ...
1860/// }
1861///
1862/// pub type lower<X> = ...;
1863/// ```
1864///
1865/// Most attributes given to this macro will be put on the generated function
1866/// (including doc comments).
1867///
1868/// If the `generate_return_type_helpers` attribute is specified, an additional module named
1869/// `return_type_helpers` will be generated, containing all return type helpers. For more
1870/// information, refer to the `Helper types generation` section.
1871///
1872/// # Adding Doc Comments
1873///
1874/// ```no_run
1875/// # extern crate diesel;
1876/// # use diesel::*;
1877/// # use diesel::expression::functions::declare_sql_function;
1878/// #
1879/// # table! { crates { id -> Integer, name -> VarChar, } }
1880/// #
1881/// use diesel::sql_types::Text;
1882///
1883/// #[declare_sql_function]
1884/// extern "SQL" {
1885/// /// Represents the `canon_crate_name` SQL function, created in
1886/// /// migration ....
1887/// fn canon_crate_name(a: Text) -> Text;
1888/// }
1889///
1890/// # fn main() {
1891/// # use self::crates::dsl::*;
1892/// let target_name = "diesel";
1893/// crates.filter(canon_crate_name(name).eq(canon_crate_name(target_name)));
1894/// // This will generate the following SQL
1895/// // SELECT * FROM crates WHERE canon_crate_name(crates.name) = canon_crate_name($1)
1896/// # }
1897/// ```
1898///
1899/// # Special Attributes
1900///
1901/// There are a handful of special attributes that Diesel will recognize. They
1902/// are:
1903///
1904/// - `#[aggregate]`
1905/// - Indicates that this is an aggregate function, and that `NonAggregate`
1906/// shouldn't be implemented.
1907/// - `#[sql_name = "name"]`
1908/// - The SQL to be generated is different from the Rust name of the function.
1909/// This can be used to represent functions which can take many argument
1910/// types, or to capitalize function names.
1911/// - `#[variadic(argument_count)]`
1912/// - Indicates that this is a variadic function, where `argument_count` is a
1913/// nonnegative integer representing the number of variadic arguments the
1914/// function accepts.
1915///
1916/// Functions can also be generic. Take the definition of `sum`, for example:
1917///
1918/// ```no_run
1919/// # extern crate diesel;
1920/// # use diesel::*;
1921/// # use diesel::expression::functions::declare_sql_function;
1922/// #
1923/// # table! { crates { id -> Integer, name -> VarChar, } }
1924/// #
1925/// use diesel::sql_types::Foldable;
1926///
1927/// #[declare_sql_function]
1928/// extern "SQL" {
1929/// #[aggregate]
1930/// #[sql_name = "SUM"]
1931/// fn sum<ST: Foldable>(expr: ST) -> ST::Sum;
1932/// }
1933///
1934/// # fn main() {
1935/// # use self::crates::dsl::*;
1936/// crates.select(sum(id));
1937/// # }
1938/// ```
1939///
1940/// # SQL Functions without Arguments
1941///
1942/// A common example is ordering a query using the `RANDOM()` sql function,
1943/// which can be implemented using `define_sql_function!` like this:
1944///
1945/// ```rust
1946/// # extern crate diesel;
1947/// # use diesel::*;
1948/// # use diesel::expression::functions::declare_sql_function;
1949/// #
1950/// # table! { crates { id -> Integer, name -> VarChar, } }
1951/// #
1952/// #[declare_sql_function]
1953/// extern "SQL" {
1954/// fn random() -> Text;
1955/// }
1956///
1957/// # fn main() {
1958/// # use self::crates::dsl::*;
1959/// crates.order(random());
1960/// # }
1961/// ```
1962///
1963/// # Use with SQLite
1964///
1965/// On most backends, the implementation of the function is defined in a
1966/// migration using `CREATE FUNCTION`. On SQLite, the function is implemented in
1967/// Rust instead. You must call `register_impl` or
1968/// `register_nondeterministic_impl` (in the generated function's `_internals`
1969/// module) with every connection before you can use the function.
1970///
1971/// These functions will only be generated if the `sqlite` feature is enabled,
1972/// and the function is not generic.
1973/// SQLite doesn't support generic functions and variadic functions.
1974///
1975/// ```rust
1976/// # extern crate diesel;
1977/// # use diesel::*;
1978/// # use diesel::expression::functions::declare_sql_function;
1979/// #
1980/// # #[cfg(feature = "sqlite")]
1981/// # fn main() {
1982/// # run_test().unwrap();
1983/// # }
1984/// #
1985/// # #[cfg(not(feature = "sqlite"))]
1986/// # fn main() {
1987/// # }
1988/// #
1989/// use diesel::sql_types::{Double, Integer};
1990///
1991/// #[declare_sql_function]
1992/// extern "SQL" {
1993/// fn add_mul(x: Integer, y: Integer, z: Double) -> Double;
1994/// }
1995///
1996/// # #[cfg(feature = "sqlite")]
1997/// # fn run_test() -> Result<(), Box<dyn std::error::Error>> {
1998/// let connection = &mut SqliteConnection::establish(":memory:")?;
1999///
2000/// add_mul_utils::register_impl(connection, |x: i32, y: i32, z: f64| (x + y) as f64 * z)?;
2001///
2002/// let result = select(add_mul(1, 2, 1.5)).get_result::<f64>(connection)?;
2003/// assert_eq!(4.5, result);
2004/// # Ok(())
2005/// # }
2006/// ```
2007///
2008/// ## Panics
2009///
2010/// If an implementation of the custom function panics and unwinding is enabled, the panic is
2011/// caught and the function returns to libsqlite with an error. It can't propagate the panics due
2012/// to the FFI boundary.
2013///
2014/// This is the same for [custom aggregate functions](#custom-aggregate-functions).
2015///
2016/// ## Custom Aggregate Functions
2017///
2018/// Custom aggregate functions can be created in SQLite by adding an `#[aggregate]`
2019/// attribute inside `define_sql_function`. `register_impl` (in the generated function's `_utils`
2020/// module) needs to be called with a type implementing the
2021/// [SqliteAggregateFunction](../diesel/sqlite/trait.SqliteAggregateFunction.html)
2022/// trait as a type parameter as shown in the examples below.
2023///
2024/// ```rust
2025/// # extern crate diesel;
2026/// # use diesel::*;
2027/// # use diesel::expression::functions::declare_sql_function;
2028/// #
2029/// # #[cfg(feature = "sqlite")]
2030/// # fn main() {
2031/// # run().unwrap();
2032/// # }
2033/// #
2034/// # #[cfg(not(feature = "sqlite"))]
2035/// # fn main() {
2036/// # }
2037/// use diesel::sql_types::Integer;
2038/// # #[cfg(feature = "sqlite")]
2039/// use diesel::sqlite::SqliteAggregateFunction;
2040///
2041/// #[declare_sql_function]
2042/// extern "SQL" {
2043/// #[aggregate]
2044/// fn my_sum(x: Integer) -> Integer;
2045/// }
2046///
2047/// #[derive(Default)]
2048/// struct MySum { sum: i32 }
2049///
2050/// # #[cfg(feature = "sqlite")]
2051/// impl SqliteAggregateFunction<i32> for MySum {
2052/// type Output = i32;
2053///
2054/// fn step(&mut self, expr: i32) {
2055/// self.sum += expr;
2056/// }
2057///
2058/// fn finalize(aggregator: Option<Self>) -> Self::Output {
2059/// aggregator.map(|a| a.sum).unwrap_or_default()
2060/// }
2061/// }
2062/// # table! {
2063/// # players {
2064/// # id -> Integer,
2065/// # score -> Integer,
2066/// # }
2067/// # }
2068///
2069/// # #[cfg(feature = "sqlite")]
2070/// fn run() -> Result<(), Box<dyn (::std::error::Error)>> {
2071/// # use self::players::dsl::*;
2072/// let connection = &mut SqliteConnection::establish(":memory:")?;
2073/// # diesel::sql_query("create table players (id integer primary key autoincrement, score integer)")
2074/// # .execute(connection)
2075/// # .unwrap();
2076/// # diesel::sql_query("insert into players (score) values (10), (20), (30)")
2077/// # .execute(connection)
2078/// # .unwrap();
2079///
2080/// my_sum_utils::register_impl::<MySum, _>(connection)?;
2081///
2082/// let total_score = players.select(my_sum(score))
2083/// .get_result::<i32>(connection)?;
2084///
2085/// println!("The total score of all the players is: {}", total_score);
2086///
2087/// # assert_eq!(60, total_score);
2088/// Ok(())
2089/// }
2090/// ```
2091///
2092/// With multiple function arguments, the arguments are passed as a tuple to `SqliteAggregateFunction`
2093///
2094/// ```rust
2095/// # extern crate diesel;
2096/// # use diesel::*;
2097/// # use diesel::expression::functions::declare_sql_function;
2098/// #
2099/// # #[cfg(feature = "sqlite")]
2100/// # fn main() {
2101/// # run().unwrap();
2102/// # }
2103/// #
2104/// # #[cfg(not(feature = "sqlite"))]
2105/// # fn main() {
2106/// # }
2107/// use diesel::sql_types::{Float, Nullable};
2108/// # #[cfg(feature = "sqlite")]
2109/// use diesel::sqlite::SqliteAggregateFunction;
2110///
2111/// #[declare_sql_function]
2112/// extern "SQL" {
2113/// #[aggregate]
2114/// fn range_max(x0: Float, x1: Float) -> Nullable<Float>;
2115/// }
2116///
2117/// #[derive(Default)]
2118/// struct RangeMax<T> { max_value: Option<T> }
2119///
2120/// # #[cfg(feature = "sqlite")]
2121/// impl<T: Default + PartialOrd + Copy + Clone> SqliteAggregateFunction<(T, T)> for RangeMax<T> {
2122/// type Output = Option<T>;
2123///
2124/// fn step(&mut self, (x0, x1): (T, T)) {
2125/// # let max = if x0 >= x1 {
2126/// # x0
2127/// # } else {
2128/// # x1
2129/// # };
2130/// #
2131/// # self.max_value = match self.max_value {
2132/// # Some(current_max_value) if max > current_max_value => Some(max),
2133/// # None => Some(max),
2134/// # _ => self.max_value,
2135/// # };
2136/// // Compare self.max_value to x0 and x1
2137/// }
2138///
2139/// fn finalize(aggregator: Option<Self>) -> Self::Output {
2140/// aggregator?.max_value
2141/// }
2142/// }
2143/// # table! {
2144/// # student_avgs {
2145/// # id -> Integer,
2146/// # s1_avg -> Float,
2147/// # s2_avg -> Float,
2148/// # }
2149/// # }
2150///
2151/// # #[cfg(feature = "sqlite")]
2152/// fn run() -> Result<(), Box<dyn (::std::error::Error)>> {
2153/// # use self::student_avgs::dsl::*;
2154/// let connection = &mut SqliteConnection::establish(":memory:")?;
2155/// # diesel::sql_query("create table student_avgs (id integer primary key autoincrement, s1_avg float, s2_avg float)")
2156/// # .execute(connection)
2157/// # .unwrap();
2158/// # diesel::sql_query("insert into student_avgs (s1_avg, s2_avg) values (85.5, 90), (79.8, 80.1)")
2159/// # .execute(connection)
2160/// # .unwrap();
2161///
2162/// range_max_utils::register_impl::<RangeMax<f32>, _, _>(connection)?;
2163///
2164/// let result = student_avgs.select(range_max(s1_avg, s2_avg))
2165/// .get_result::<Option<f32>>(connection)?;
2166///
2167/// if let Some(max_semester_avg) = result {
2168/// println!("The largest semester average is: {}", max_semester_avg);
2169/// }
2170///
2171/// # assert_eq!(Some(90f32), result);
2172/// Ok(())
2173/// }
2174/// ```
2175///
2176/// ## Variadic functions
2177///
2178/// Since Rust does not support variadic functions, the SQL variadic functions are
2179/// handled differently. For example, consider the variadic function `json_array`.
2180/// To add support for it, you can use the `#[variadic]` attribute:
2181///
2182/// ```rust
2183/// # extern crate diesel;
2184/// # use diesel::sql_types::*;
2185/// # use diesel::expression::functions::declare_sql_function;
2186/// #
2187/// # fn main() {
2188/// # // Without the main function this code will be wrapped in the auto-generated
2189/// # // `main` function and `#[declare_sql_function]` won't work properly.
2190/// # }
2191///
2192/// # #[cfg(feature = "sqlite")]
2193/// #[declare_sql_function]
2194/// extern "SQL" {
2195/// #[variadic(1)]
2196/// fn json_array<V: SqlType + SingleValue>(value: V) -> Json;
2197/// }
2198/// ```
2199///
2200/// This will generate multiple implementations, one for each possible argument
2201/// count (up to a predefined limit). For instance, it will generate functions like
2202/// `json_array_0`, `json_array_1`, and so on, which are equivalent to:
2203///
2204/// ```rust
2205/// # extern crate diesel;
2206/// # use diesel::sql_types::*;
2207/// # use diesel::expression::functions::declare_sql_function;
2208/// #
2209/// # fn main() {
2210/// # // Without the main function this code will be wrapped in the auto-generated
2211/// # // `main` function and `#[declare_sql_function]` won't work properly.
2212/// # }
2213///
2214/// # #[cfg(feature = "sqlite")]
2215/// #[declare_sql_function]
2216/// extern "SQL" {
2217/// #[sql_name = "json_array"]
2218/// fn json_array_0() -> Json;
2219///
2220/// #[sql_name = "json_array"]
2221/// fn json_array_1<V1: SqlType + SingleValue>(value_1: V1) -> Json;
2222///
2223/// #[sql_name = "json_array"]
2224/// fn json_array_2<V1: SqlType + SingleValue, V2: SqlType + SingleValue>(
2225/// value_1: V1,
2226/// value_2: V2,
2227/// ) -> Json;
2228///
2229/// // ...
2230/// }
2231/// ```
2232///
2233/// The argument to the `variadic` attribute specifies the number of trailing arguments to repeat.
2234/// For example, if you have a variadic function `foo(a: A, b: B, c: C)` and want `b: B` and `c: C`
2235/// to repeat, you would write:
2236///
2237/// ```ignore
2238/// #[declare_sql_function]
2239/// extern "SQL" {
2240/// #[variadic(2)]
2241/// fn foo<A, B, C>(a: A, b: B, c: C) -> Text;
2242/// }
2243/// ```
2244///
2245/// Which will be equivalent to
2246///
2247/// ```ignore
2248/// #[declare_sql_function]
2249/// extern "SQL" {
2250/// #[sql_name = "foo"]
2251/// fn foo_0<A>(a: A) -> Text;
2252///
2253/// #[sql_name = "foo"]
2254/// fn foo_1<A, B1, C1>(a: A, b_1: B1, c_1: C1) -> Text;
2255///
2256/// #[sql_name = "foo"]
2257/// fn foo_2<A, B1, C1, B2, C2>(a: A, b_1: B1, c_1: C1, b_2: B2, c_2: C2) -> Text;
2258///
2259/// ...
2260/// }
2261/// ```
2262///
2263/// ### Controlling the generation of variadic function variants
2264///
2265/// By default, only variants with 0, 1, and 2 repetitions of variadic arguments are generated. To
2266/// generate more variants, set the `DIESEL_VARIADIC_FUNCTION_ARGS` environment variable to the
2267/// desired number of variants.
2268///
2269/// For a greater convenience this environment variable can also be set in a `.cargo/config.toml`
2270/// file as described in the [cargo documentation](https://doc.rust-lang.org/cargo/reference/config.html#env).
2271///
2272/// ## Helper types generation
2273///
2274/// When the `generate_return_type_helpers` attribute is specified, for each function defined inside
2275/// an `extern "SQL"` block, a return type alias with the same name as the function is created and
2276/// placed in the `return_type_helpers` module:
2277///
2278/// ```rust
2279/// # extern crate diesel;
2280/// # use diesel::expression::functions::declare_sql_function;
2281/// # use diesel::sql_types::*;
2282/// #
2283/// # fn main() {
2284/// # // Without the main function this code will be wrapped in the auto-generated
2285/// # // `main` function and `#[declare_sql_function]` won't work properly.
2286/// # }
2287/// #
2288/// #[declare_sql_function(generate_return_type_helpers = true)]
2289/// extern "SQL" {
2290/// fn f<V: SqlType + SingleValue>(arg: V);
2291/// }
2292///
2293/// type return_type_helper_for_f<V> = return_type_helpers::f<V>;
2294/// ```
2295///
2296/// If you want to skip generating a type alias for a specific function, you can use the
2297/// `#[skip_return_type_helper]` attribute, like this:
2298///
2299/// ```compile_fail
2300/// # extern crate diesel;
2301/// # use diesel::expression::functions::declare_sql_function;
2302/// #
2303/// # fn main() {
2304/// # // Without the main function this code will be wrapped in the auto-generated
2305/// # // `main` function and `#[declare_sql_function]` won't work properly.
2306/// # }
2307/// #
2308/// #[declare_sql_function(generate_return_type_helpers = true)]
2309/// extern "SQL" {
2310/// #[skip_return_type_helper]
2311/// fn f();
2312/// }
2313///
2314/// # type skipped_type = return_type_helpers::f;
2315/// ```
2316///
2317#[cfg_attr(diesel_docsrs, doc = include_str!(concat!(env!("OUT_DIR"), "/declare_sql_function.md")))]
2318#[proc_macro_attribute]
2319pub fn declare_sql_function(
2320 attr: proc_macro::TokenStream,
2321 input: proc_macro::TokenStream,
2322) -> proc_macro::TokenStream {
2323 declare_sql_function_inner(attr.into(), input.into()).into()
2324}
2325
2326fn declare_sql_function_inner(
2327 attr: proc_macro2::TokenStream,
2328 input: proc_macro2::TokenStream,
2329) -> proc_macro2::TokenStream {
2330 let attr = crate::sql_function::DeclareSqlFunctionArgs::parse_from_macro_input(attr);
2331
2332 let result = syn::parse2::<ExternSqlBlock>(input.clone()).map(|res| {
2333 sql_function::expand(
2334 res.function_decls,
2335 false,
2336 attr.as_ref()
2337 .map(|attr| attr.generate_return_type_helpers)
2338 .unwrap_or(true),
2339 )
2340 });
2341
2342 let mut output = match result {
2343 Ok(token_stream) => token_stream,
2344 Err(e) => {
2345 let mut output = input;
2346 output.extend(e.into_compile_error());
2347 output
2348 }
2349 };
2350 if let Err(e) = attr {
2351 output.extend(e.into_compile_error());
2352 }
2353 output
2354}
2355
2356/// Implements `HasQuery`
2357///
2358/// This derive implements a common entry point for building queries
2359/// based on a model like Rust struct. It enables you to always have a certain base query
2360/// associated with a given type. This derive is designed to easily couple your query with
2361/// your Rust type. It's important to note that for Diesel this mapping happens always
2362/// on query and not on table level, which enables you to write several queries related to the
2363/// same table, while a single query could be related to zero or multiple tables.
2364///
2365/// By default this derive will use the equivalent of `SELECT your, fields FROM your_types`
2366/// which implies that it needs to know the corresponding table type. As with any other
2367/// diesel derive it uses the `snake_case` type name with an added `s` if no other
2368/// name is specified.
2369/// It is possible to change this default by using `#[diesel(table_name = something)]`.
2370///
2371/// If you would like to use a more complex query as base query you can overwrite the standard
2372/// query by using the `#[diesel(base_query = your_type::table.filter(your_type::is_admin.eq(true)))]`
2373/// attribute to overwrite the automatically generated base query. This derive will still apply
2374/// a select clause that matches your type. By default it also tries to infer the correct
2375/// type of that query. This type can be overwritten by using the `#[diesel(base_query_type)]`
2376/// attribute.
2377///
2378/// This derive will internally implement the following traits:
2379///
2380/// * `HasQuery`
2381/// * `Selectable` (for building the selection)
2382/// * `Queryable` (for allowing to load results from the database)
2383///
2384/// For the later two traits see their corresponding derives for supported options:
2385///
2386/// * [Queryable]
2387/// * [Selectable]
2388///
2389/// Any option documented there is also supported by this derive
2390///
2391/// In contrast to `#[derive(Selectable)]` this derive automatically enables
2392/// `#[diesel(check_for_backend(_))]` with all backends enabled at compile time
2393/// if no explicit `#[diesel(check_for_backend(_))]` attribute is given. This
2394/// will lead to better error messages. You
2395/// can use `#[diesel(check_for_backend(disable = true))]` to disable this behaviour
2396/// for that particular instance.
2397///
2398/// # Attributes
2399///
2400/// ## Optional Type attributes
2401///
2402/// * `#[diesel(base_query = _)]` specifies a base query associated with this type.
2403/// It may be used in conjunction with `base_query_type` (described below)
2404/// * `#[diesel(base_query_type = _)]` the Rust type described by the `base_query`
2405/// attribute. Usually diesel is able to infer this type, but for complex types such an
2406/// annotation might be required. This will be required if a custom
2407/// function call that doesn't have the corresponding associated type defined at the same path
2408/// appears in your query.
2409/// * `#[diesel(table_name = path::to::table)]`, specifies a path to the table for which the
2410/// current type is selectable. The path is relative to the current module.
2411/// If this attribute is not used, the type name converted to
2412/// `snake_case` with an added `s` is used as table name.
2413/// * `#[diesel(check_for_backend(diesel::pg::Pg, diesel::mysql::Mysql))]`, instructs
2414/// the derive to generate additional code to identify potential type mismatches.
2415/// It accepts a list of backend types to check the types against. If this option
2416/// is not set this derive automatically uses all backends enabled at compile time
2417/// for this check. You can disable this behaviour via `#[diesel(check_for_backend(disable = true))]`
2418///
2419/// ## Optional Field Attributes
2420///
2421/// * `#[diesel(column_name = some_column)]`, overrides the column name for
2422/// a given field. If not set, the name of the field is used as column
2423/// name.
2424/// * `#[diesel(embed)]`, specifies that the current field maps not only
2425/// a single database column, but is a type that implements
2426/// `Selectable` on its own
2427/// * `#[diesel(select_expression = some_custom_select_expression)]`, overrides
2428/// the entire select expression for the given field. It may be used to select with
2429/// custom tuples, or specify `select_expression = my_table::some_field.is_not_null()`,
2430/// or separate tables...
2431/// It may be used in conjunction with `select_expression_type` (described below)
2432/// * `#[diesel(select_expression_type = the_custom_select_expression_type]`, should be used
2433/// in conjunction with `select_expression` (described above) if the type is too complex
2434/// for diesel to infer it automatically. This will be required if select_expression is a custom
2435/// function call that doesn't have the corresponding associated type defined at the same path.
2436/// Example use (this would actually be inferred):
2437/// `#[diesel(select_expression_type = dsl::IsNotNull<my_table::some_field>)]`
2438/// * `#[diesel(deserialize_as = Type)]`, instead of deserializing directly
2439/// into the field type, the implementation will deserialize into `Type`.
2440/// Then `Type` is converted via
2441/// [`.try_into`](https://doc.rust-lang.org/stable/std/convert/trait.TryInto.html#tymethod.try_into)
2442/// into the field type. By default, this derive will deserialize directly into the field type
2443///
2444/// # Examples
2445///
2446/// ## Basic usage
2447///
2448///
2449/// ```rust
2450/// # extern crate diesel;
2451/// # extern crate dotenvy;
2452/// # include!("../../diesel/src/doctest_setup.rs");
2453/// #
2454///
2455/// // it's important to have the right table in scope
2456/// use schema::users;
2457///
2458/// #[derive(HasQuery, PartialEq, Debug)]
2459/// struct User {
2460/// id: i32,
2461/// name: String,
2462/// }
2463///
2464/// # fn main() -> QueryResult<()> {
2465/// #
2466/// # let connection = &mut establish_connection();
2467/// // equivalent to `users::table.select(User::as_select()).first(connection)?;
2468/// let first_user = User::query().first(connection)?;
2469/// let expected = User { id: 1, name: "Sean".into() };
2470/// assert_eq!(expected, first_user);
2471///
2472/// # Ok(())
2473/// # }
2474/// ```
2475///
2476/// ## Custom base query
2477///
2478/// ```rust
2479/// # extern crate diesel;
2480/// # extern crate dotenvy;
2481/// # include!("../../diesel/src/doctest_setup.rs");
2482/// #
2483///
2484/// // it's important to have the right table in scope
2485/// use schema::{users, posts};
2486///
2487/// #[derive(HasQuery, PartialEq, Debug)]
2488/// struct Post {
2489/// id: i32,
2490/// user_id: i32,
2491/// title: String,
2492/// }
2493///
2494/// #[derive(HasQuery, PartialEq, Debug)]
2495/// #[diesel(base_query = users::table.inner_join(posts::table).order_by(users::id))]
2496/// // that's required to let the derive understand
2497/// // from which table the columns should be selected
2498/// #[diesel(table_name = users)]
2499/// struct UserWithPost {
2500/// id: i32,
2501/// name: String,
2502/// #[diesel(embed)]
2503/// post: Post,
2504/// }
2505///
2506/// # fn main() -> QueryResult<()> {
2507/// #
2508/// # let connection = &mut establish_connection();
2509/// // equivalent to users::table.inner_join(posts::table)
2510/// // .order_by(users::id)
2511/// // .select(UserWithPost::as_select()).first(connection)?;
2512/// let first_user = UserWithPost::query().first(connection)?;
2513/// let expected = UserWithPost { id: 1, name: "Sean".into(), post: Post {id: 1, user_id: 1, title: "My first post".into() } };
2514/// assert_eq!(expected, first_user);
2515///
2516/// # Ok(())
2517/// # }
2518/// ```
2519///
2520#[cfg_attr(diesel_docsrs, doc = include_str!(concat!(env!("OUT_DIR"), "/has_query.md")))]
2521#[proc_macro_derive(HasQuery, attributes(diesel))]
2522pub fn derive_has_query(input: TokenStream) -> TokenStream {
2523 derive_has_query_inner(input.into()).into()
2524}
2525
2526fn derive_has_query_inner(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
2527 syn::parse2(input)
2528 .and_then(has_query::derive)
2529 .unwrap_or_else(syn::Error::into_compile_error)
2530}