sqlx_template/
lib.rs

1#![allow(warnings)]
2use proc_macro::TokenStream;
3use quote::quote;
4use sqlx_template::raw;
5use syn::{
6    parse_macro_input, Attribute, AttributeArgs, Data, DeriveInput, Field, Fields, Ident, ItemStruct, Lit, Meta, MetaNameValue, NestedMeta
7};
8
9use crate::sqlx_template::Database;
10
11mod sqlx_template;
12mod columns;
13mod parser;
14
15
16/// `InsertTemplate` is a derive macro designed to automatically generate record insert functions
17/// based on `sqlx`. This macro creates `insert` methods for the struct it is applied to, returning
18/// the number of new records added. It assumes that the columns in the database correspond to the fields in the struct.
19///
20/// # Attributes
21///
22/// `InsertTemplate` accepts the following attributes:
23/// - `table`: Specifies the name of the table in the database (mandatory).
24/// - `debug_slow`: Configures debug logs for the executed query:
25///   - If set to `0`: Only logs the executed query.
26///   - If set to a value greater than `0`: Only logs the query if the execution time exceeds the configured value (in milliseconds).
27///   - If not configured, no debug logs will be generated.
28/// - `auto`: Applied to fields that should be excluded from the insert statement, typically for auto-incrementing primary keys.
29/// - `db`: Specifies the target database type (e.g., `#[db("postgres")]`, `#[db("mysql")]`, `#[db("sqlite")]`).
30///
31/// Additionally, when using PostgreSQL (`#[db("postgres")]`), the library will generate an `insert_return` function that returns the newly inserted record.
32///
33/// # Example
34///
35/// ```rust,no_run
36/// use sqlx_template::InsertTemplate;
37/// use sqlx::Pool;
38///
39/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
40/// # let pool: Pool<sqlx::Postgres> = todo!();
41/// #[derive(InsertTemplate, sqlx::FromRow)]
42/// #[table("users")]
43/// #[db("postgres")]
44/// #[debug_slow = 1000]
45/// pub struct User {
46///     #[auto]
47///     pub id: i32,
48///     pub email: String,
49///     pub password: String,
50/// }
51///
52/// // Insert a new user record
53/// let user = User { id: 0, email: "john.doe@example.com".to_string(), password: "password123".to_string() };
54/// let rows_affected = User::insert(&user, &pool).await?;
55/// println!("Rows affected: {}", rows_affected);
56///
57/// // With PostgreSQL database
58/// #[derive(InsertTemplate, sqlx::FromRow, Debug)]
59/// #[table("users")]
60/// #[db("postgres")]
61/// pub struct UserPg {
62///     #[auto]
63///     pub id: i32,
64///     pub email: String,
65///     pub password: String,
66/// }
67///
68/// let user_pg = UserPg { id: 0, email: "john.doe@example.com".to_string(), password: "password123".to_string() };
69/// let new_user = UserPg::insert_return(&user_pg, &pool).await?;
70/// println!("New user: {:?}", new_user);
71/// # Ok(())
72/// # }
73/// ```
74///
75/// In the example above:
76/// - `table` is set to "users", specifying the table to insert into. (mandatory).
77/// - `debug_slow` is set to 1000 milliseconds, meaning only queries taking longer than 1 second will be logged for debugging.
78/// - The `id` field is marked with `#[auto]`, indicating that it should be excluded from the insert statement, typically for auto-incrementing primary keys.
79///
80
81/// # Note
82///
83/// This macro relies on `sqlx`, so you need to add `sqlx` to your `[dependencies]` in `Cargo.toml`
84/// and properly configure the database connection before using the generated insert methods.
85///
86
87
88#[proc_macro_derive(InsertTemplate, attributes(table, auto, debug_slow, db))]
89pub fn insert_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
90    let input = syn::parse_macro_input!(input as syn::DeriveInput);
91    match sqlx_template::insert::derive_insert(&input, None, sqlx_template::Scope::Struct, None) {
92        Ok(ok) => ok,
93        Err(err) => err.to_compile_error().into(),
94    }
95    .into()
96}
97
98
99/// `UpdateTemplate` is a derive macro designed to automatically generate record update functions
100/// based on `sqlx`. This macro creates `update` methods for the struct it is applied to, reducing
101/// repetitive code and improving the readability and maintainability of your code.
102/// It assumes that the columns in the database correspond to the fields in the struct.
103///
104/// # Attributes
105///
106/// `UpdateTemplate` accepts the following attributes:
107/// - `table`: Specifies the name of the table in the database (mandatory).
108/// - `tp_update`: The main configuration for generating the update function, with the following sub-attributes:
109///   - `by`: List of columns that will be the update condition, will be the function's input (mandatory and non-empty).
110///   - `on`: List of columns that will be updated. If empty, all columns will be updated.
111///   - `where`: Additional WHERE clause with placeholder support (see Placeholder Mapping in SelectTemplate).
112///   - `fn_name`: The name of the generated function. If empty, the library will automatically generate a function name.
113///   - `op_lock`: The name of the column to apply optimistic locking (optional).
114///   - `returning`: Can be set to `true` for returning the full record, or specify specific columns (e.g., `returning = "id, email"`).
115///   - `debug_slow`: Configures debug logs for the executed query:
116///     - If `0`: Only logs the executed query.
117///     - If `> 0`: Only logs the query if the execution time exceeds the configured value (in milliseconds).
118///     - If not configured, no debug logs will be generated.
119/// - `debug_slow`: Configures debug logs for the executed query, with priority given to the value in `tp_update`.
120/// - `db`: Specifies the target database type (e.g., `#[db("postgres")]`).
121/// - `tp_update_builder`: Builder pattern configuration for UPDATE operations with custom WHERE conditions.
122///
123#[doc = include_str!("../docs/builder_pattern.md")]
124///
125/// # Example
126///
127/// ```rust,no_run
128/// use sqlx_template::UpdateTemplate;
129/// use sqlx::Pool;
130///
131/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
132/// # let pool: Pool<sqlx::Sqlite> = todo!();
133/// # let user_id = 1i32;
134/// #[derive(UpdateTemplate, sqlx::FromRow)]
135/// #[table("users")]
136/// #[db("sqlite")]
137/// #[tp_update(by = "id", op_lock = "version", fn_name = "update_user")]
138/// #[tp_update(by = "id", on = "email, password", fn_name = "update_user_password")]
139/// #[tp_update_builder(
140///     with_high_score = "score > :threshold$i32"
141/// )]
142/// pub struct User {
143///     pub id: i32,
144///     pub email: String,
145///     pub password: String,
146///     pub score: i32,
147///     pub version: i32
148/// }
149///
150/// let user = User {
151///     id: 1,
152///     email: "user@example.com".to_string(),
153///     password: "password".to_string(),
154///     score: 85,
155///     version: 1
156/// };
157///
158/// // Traditional update:
159/// User::update_user(&user.version, &user, &pool).await?;
160///
161/// // Builder pattern update:
162/// let affected = User::builder_update()
163///     .on_email("newemail@example.com")?
164///     .on_score(&95)?
165///     .by_id(&user_id)?
166///     .with_high_score(80)?
167///     .execute(&pool)
168///     .await?;
169/// # Ok(())
170/// # }
171/// ```
172///
173
174/// # Note
175///
176/// This macro relies on `sqlx`, so you need to add `sqlx` to your `[dependencies]` in `Cargo.toml`
177/// and properly configure the database connection before using the generated update methods.
178
179#[proc_macro_derive(UpdateTemplate, attributes(table, tp_update, tp_update_builder, debug_slow, db, tp_update_builder))]
180pub fn update_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
181    let input = syn::parse_macro_input!(input as syn::DeriveInput);
182    match sqlx_template::update::derive_update(&input, None, sqlx_template::Scope::Struct, None) {
183        Ok(ok) => ok,
184        Err(err) => err.to_compile_error().into(),
185    }
186    .into()
187}
188
189
190/// `DeleteTemplate` is a derive macro designed to automatically generate record deletion functions
191/// based on `sqlx`. This macro creates `delete` methods for the struct it is applied to, returning
192/// the number of records deleted.
193/// It assumes that the columns in the database correspond to the fields in the struct.
194///
195/// # Attributes
196///
197/// `DeleteTemplate` accepts the following attributes:
198/// - `table`: Specifies the name of the table in the database (mandatory).
199/// - `debug_slow`: Configures debug logs for the executed query:
200///   - If set to `0`: Only logs the executed query.
201///   - If set to a value greater than `0`: Only logs the query if the execution time exceeds the configured value (in milliseconds).
202///   - If not configured, no debug logs will be generated.
203/// - `tp_delete`: The main configuration for generating the delete function, with the following sub-attributes:
204///   - `by`: List of columns that will be the delete condition, will be the function's input (can be empty if `where` is provided).
205///   - `where`: Additional WHERE clause with placeholder support (see Placeholder Mapping in SelectTemplate).
206///   - `fn_name`: The name of the generated function. If empty, the library will automatically generate a function name.
207///   - `returning`: Can be set to `true` for returning the full record, or specify specific columns (e.g., `returning = "id, email"`).
208///   - `debug_slow`: Configures debug logs for the executed query:
209///     - If set to `0`: Only logs the executed query.
210///     - If set to a value greater than `0`: Only logs the query if the execution time exceeds the configured value (in milliseconds).
211///     - If not configured, no debug logs will be generated.
212/// - `db`: Specifies the target database type (e.g., `#[db("postgres")]`).
213/// - `tp_delete_builder`: Builder pattern configuration for DELETE operations with custom WHERE conditions.
214///
215#[doc = include_str!("../docs/builder_pattern.md")]
216///
217/// # Example
218///
219/// ```rust,no_run
220/// use sqlx_template::DeleteTemplate;
221/// use sqlx::Pool;
222///
223/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
224/// # let pool: Pool<sqlx::Sqlite> = todo!();
225/// #[derive(DeleteTemplate, sqlx::FromRow)]
226/// #[table("users")]
227/// #[db("sqlite")]
228/// #[tp_delete(by = "id", fn_name = "delete_user", returning = true)]
229/// #[tp_delete(by = "id")]
230/// #[tp_delete_builder(
231///     with_old_accounts = "created_at < :cutoff_date$String"
232/// )]
233/// pub struct User {
234///     pub id: i32,
235///     pub email: String,
236///     pub password: String,
237///     pub created_at: String,
238/// }
239///
240/// let user = User {
241///     id: 1,
242///     email: "user@example.com".to_string(),
243///     password: "password".to_string(),
244///     created_at: "2024-01-01".to_string()
245/// };
246///
247/// // Traditional delete:
248/// let rows_affected = User::delete_by_id(&user.id, &pool).await?;
249///
250/// // Builder pattern delete:
251/// let deleted = User::builder_delete()
252///     .with_old_accounts("2023-01-01")?
253///     .execute(&pool)
254///     .await?;
255/// # Ok(())
256/// # }
257/// ```
258///
259/// # Note
260///
261/// This macro relies on `sqlx`, so you need to add `sqlx` to your `[dependencies]` in `Cargo.toml`
262/// and properly configure the database connection before using the generated delete methods.
263///
264
265#[proc_macro_derive(DeleteTemplate, attributes(table, tp_delete, tp_delete_builder, debug_slow, db, tp_delete_builder))]
266pub fn delete_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
267    let input = syn::parse_macro_input!(input as syn::DeriveInput);
268    match sqlx_template::delete::derive_delete(&input, None, sqlx_template::Scope::Struct, None) {
269        Ok(ok) => ok,
270        Err(err) => err.to_compile_error().into(),
271    }
272    .into()
273}
274
275
276/// `SelectTemplate` is a derive macro designed to automatically generate record retrieval functions
277/// based on `sqlx`. This macro creates various `query` methods for the struct it is applied to,
278/// returning records from the database, assuming that the columns in the database correspond to the fields in the struct.
279///
280/// # Attributes
281///
282/// `SelectTemplate` accepts the following attributes:
283/// - `table`: Specifies the name of the table in the database (mandatory).
284/// - `debug_slow`: Configures debug logs for the executed query:
285///   - If set to `0`: Only logs the executed query.
286///   - If set to a value greater than `0`: Only logs the query if the execution time exceeds the configured value (in milliseconds).
287///   - If not configured, no debug logs will be generated.
288/// - `tp_select_all`: Generates a function that returns all records as a `Vec<T>`. It has the following sub-attributes:
289///   - `by`: List of columns for the `WHERE` condition, used as function input (can be empty).
290///   - `fn_name`: The name of the generated function. If empty, the library will automatically generate a function name.
291///   - `order`: Adds an `ORDER BY` clause based on the specified columns and order (supports `asc|desc`, default is `asc`).
292///   - `where`: Additional WHERE clause with placeholder support (see Placeholder Mapping section below).
293///   - `debug_slow`: Configures debug logs for the executed query.
294/// - `tp_select_one`: Similar to `tp_select_all`, but returns a single record as `Option<T>`.
295/// - `tp_select_stream`: Similar to `tp_select_all`, but returns an `impl Stream<Item = T>`.
296/// - `tp_select_count`: Similar to `tp_select_all`, but returns the count of records as `i64`.
297/// - `tp_select_page`: Similar to `tp_select_all`, but accepts pagination parameters and returns a tuple of all records and the total count.
298/// - `db`: Specifies the target database type (e.g., `#[db("postgres")]`).
299/// - `tp_select_builder`: Builder pattern configuration for SELECT operations with custom WHERE conditions.
300///
301/// The `debug_slow` attribute at the struct level has priority over the value in `tp_select_*`.
302///
303#[doc = include_str!("../docs/builder_pattern.md")]
304///
305/// # Placeholder Mapping
306///
307/// The `where` attribute supports advanced placeholder mapping with two main cases:
308///
309/// ## Case 1: Column-Mapped Placeholders
310/// When a placeholder (`:name`) appears in a comparison operation (`=`, `!=`, `<`, `>`, `LIKE`)
311/// and is mapped to a struct field, the parameter type is automatically inferred from the struct field:
312/// ```rust,ignore
313/// use sqlx_template::SelectTemplate;
314///
315/// #[derive(SelectTemplate, sqlx::FromRow)]
316/// #[table("users")]
317/// #[db("postgres")]
318/// #[tp_select_all(where = "name = :name and age > :age")]
319/// pub struct User {
320///     pub name: String,  // :name parameter will be &str (String -> &str)
321///     pub age: i32,      // :age parameter will be &i32
322/// }
323/// // Generated: find_all(name: &str, age: &i32, conn: E) -> Result<Vec<User>, sqlx::Error>
324/// ```
325///
326/// ## Case 2: Custom Type Placeholders
327/// Use the format `:name$Type` to specify a custom parameter type:
328/// ```rust,ignore
329/// use sqlx_template::SelectTemplate;
330///
331/// #[derive(SelectTemplate, sqlx::FromRow)]
332/// #[table("users")]
333/// #[db("postgres")]
334/// #[tp_select_all(where = "score > :min_score$f64 and created_at > :since$chrono::DateTime<chrono::Utc>")]
335/// pub struct User {
336///     pub score: f64,
337///     pub created_at: chrono::DateTime<chrono::Utc>,
338/// }
339/// // Generated: find_all(min_score: &f64, since: &chrono::DateTime<chrono::Utc>, conn: E) -> Result<Vec<User>, sqlx::Error>
340/// ```
341///
342/// ## Mixed Usage
343/// You can combine both approaches in the same WHERE clause:
344/// ```rust,ignore
345/// use sqlx_template::SelectTemplate;
346///
347/// #[derive(SelectTemplate, sqlx::FromRow)]
348/// #[table("users")]
349/// #[db("postgres")]
350/// #[tp_select_all(where = "name = :name and score > :min_score$f64")]
351/// pub struct User {
352///     pub name: String,  // :name mapped to column
353///     pub score: f64,    // :min_score$f64 uses custom type
354/// }
355/// // Generated: find_all(name: &str, min_score: &f64, conn: E) -> Result<Vec<User>, sqlx::Error>
356/// ```
357///
358/// **Note:** Placeholders are only mapped when they appear in direct column comparisons.
359/// Placeholders in expressions like `2 * id > :value` or JSON operations `data -> :key` are not mapped.
360///
361/// Additionally, the library will automatically generate the following default functions when `SelectTemplate` is derived:
362/// - `find_all`: Returns all records in the table.
363/// - `count_all`: Counts all records in the table.
364/// - `find_page_all`: Returns all records and the total count in the table based on pagination parameters.
365///
366/// # Example
367///
368/// ```rust,ignore
369/// use sqlx_template::SelectTemplate;
370/// use sqlx::{FromRow, Pool};
371/// use futures_util::StreamExt;
372///
373/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
374/// # let pool: Pool<sqlx::Postgres> = todo!();
375/// #[derive(SelectTemplate, FromRow)]
376/// #[table("users")]
377/// #[db("postgres")]
378/// #[tp_select_one(by = "id", fn_name = "find_user_by_id")]
379/// #[tp_select_one(by = "email", where = "active = :active")]
380/// #[tp_select_all(by = "id, email", order = "id desc", where = "score > :min_score$f64")]
381/// #[tp_select_count(by = "id, email")]
382/// #[tp_select_page(by = "org", order = "id desc, org desc")]
383/// #[tp_select_stream(order = "id desc")]
384/// #[tp_select_builder(
385///     with_email_domain = "email LIKE :domain$String",
386///     with_score_range = "score BETWEEN :min$f64 AND :max$f64"
387/// )]
388/// #[debug_slow = 1000]
389/// pub struct User {
390///     #[auto]
391///     pub id: i32,
392///     pub email: String,
393///     pub password: String,
394///     pub org: Option<i32>,
395///     pub active: bool,
396///     pub score: f64,
397/// }
398///
399/// // Example usage:
400/// // Find user by id
401/// let user = User::find_user_by_id(&1, &pool).await?;
402/// println!("Found user: {:?}", user);
403///
404/// // Find user by email
405/// let user = User::find_one_by_email(&"user@example.com".to_string(), &pool).await?;
406///
407/// // Find all users with conditions
408/// let users = User::find_all_by_id_and_email(&1, &"user@example.com".to_string(), &pool).await?;
409///
410/// // Count users
411/// let user_count = User::count_by_id_and_email(&1, &"user@example.com".to_string(), &pool).await?;
412///
413/// // Find users with pagination
414/// let page_request = (0i64, 10i32, true); // (offset, limit, count)
415/// let (users, total_count) = User::find_page_by_org_order_by_id_desc_and_org_desc(&Some(1), page_request, &pool).await?;
416///
417/// // Stream users
418/// let mut user_stream = User::stream_order_by_id_desc(&pool);
419/// while let Some(Ok(user)) = user_stream.next().await {
420///     println!("Streamed user: {:?}", user);
421/// }
422///
423/// // Builder pattern queries
424/// let users = User::builder_select()
425///     .email("john@example.com")?
426///     .active(&true)?
427///     .with_email_domain("%@company.com")?
428///     .with_score_range(&60.0, &90.0)?
429///     .order_by_score_desc()?
430///     .find_all(&pool)
431///     .await?;
432/// # Ok(())
433/// # }
434/// ```
435///
436/// In the example above:
437/// - `table` is set to "users", specifying the table to query from.
438/// - Various `tp_select_*` configurations generate different types of query functions.
439/// - Function names are automatically generated based on the `by` and `order` parameters.
440///
441
442///
443/// # Note
444///
445/// This macro relies on `sqlx`, so you need to add `sqlx` to your `[dependencies]` in `Cargo.toml`
446/// and properly configure the database connection before using the generated query methods.
447///
448
449#[proc_macro_derive(SelectTemplate, attributes(table, debug_slow, tp_select_all, tp_select_one, tp_select_page, tp_select_stream, tp_select_count, tp_select_builder, db, tp_select_builder, auto))]
450pub fn select_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
451    let input = syn::parse_macro_input!(input as syn::DeriveInput);
452    match sqlx_template::select::derive_select(&input, None, sqlx_template::Scope::Struct, None) {
453        Ok(ok) => ok,
454        Err(err) => err.to_compile_error().into(),
455    }
456    .into()
457}
458
459
460
461/// `Columns` is a derive macro that generates column name constants and utility functions
462/// for database operations. This macro creates static string constants for each field
463/// in the struct, making it easier to reference column names in queries.
464///
465/// # Attributes
466///
467/// `Columns` accepts the following attributes:
468/// - `group`: Groups fields together for specific operations (optional).
469///
470/// # Generated Functions
471///
472/// The macro generates the following for each field:
473/// - A constant with the column name (e.g., `COLUMN_ID` for field `id`)
474/// - Utility functions for accessing column names programmatically
475///
476/// # Example
477///
478/// ```rust,no_run
479/// use sqlx_template::Columns;
480///
481/// #[derive(Columns)]
482/// pub struct User {
483///     pub id: i32,
484///     pub email: String,
485///     #[group = "personal"]
486///     pub name: String,
487///     #[group = "personal"]
488///     pub age: i32,
489/// }
490///
491/// // Usage:
492/// // User::COLUMN_ID returns "id"
493/// // User::COLUMN_EMAIL returns "email"
494/// // User::COLUMN_NAME returns "name"
495/// // User::COLUMN_AGE returns "age"
496/// ```
497///
498/// # Note
499///
500/// This macro is useful for maintaining consistency between struct field names
501/// and database column names, and provides compile-time safety when referencing columns.
502///
503#[proc_macro_derive(Columns, attributes(group))]
504pub fn columns_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
505    let input = syn::parse_macro_input!(input as syn::DeriveInput);
506    match columns::derive(input) {
507        Ok(ok) => ok,
508        Err(err) => err.to_compile_error().into(),
509    }
510    .into()
511}
512
513
514
515/// `DDLTemplate` is a derive macro that generates Data Definition Language (DDL) statements
516/// for creating database tables based on the struct definition. This macro analyzes the struct
517/// fields and their types to generate appropriate CREATE TABLE statements.
518///
519/// # Attributes
520///
521/// `DDLTemplate` accepts the following attributes:
522/// - `table`: Specifies the name of the table in the database (mandatory).
523/// - `column`: Applied to individual fields to customize column properties such as:
524///   - Column type overrides
525///   - Constraints (PRIMARY KEY, NOT NULL, UNIQUE, etc.)
526///   - Default values
527/// - `db`: Specifies the target database type for database-specific DDL generation.
528///
529/// # Generated Functions
530///
531/// The macro generates the following functions:
532/// - `create_table_sql()`: Returns the CREATE TABLE statement as a string
533/// - `drop_table_sql()`: Returns the DROP TABLE statement as a string
534///
535/// # Example
536///
537/// ```rust,ignore
538/// use sqlx_template::DDLTemplate;
539///
540/// #[derive(DDLTemplate)]
541/// #[table("users")]
542/// pub struct User {
543///     #[column(primary_key, auto_increment)]
544///     pub id: i32,
545///     #[column(unique, not_null)]
546///     pub email: String,
547///     #[column(not_null)]
548///     pub password: String,
549///     #[column(default = "true")]
550///     pub active: bool,
551///     pub created_at: Option<chrono::DateTime<chrono::Utc>>,
552/// }
553///
554/// // Usage:
555/// let create_sql = User::create_table_sql();
556/// let drop_sql = User::drop_table_sql();
557/// ```
558///
559/// # Note
560///
561/// This macro is useful for database migrations and schema management.
562/// The generated DDL statements are database-specific and should be tested
563/// with your target database system.
564///
565#[proc_macro_derive(DDLTemplate, attributes(column, table, db))]
566pub fn ddl_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
567    let input = syn::parse_macro_input!(input as syn::DeriveInput);
568    match sqlx_template::ddl::derive(input) {
569        Ok(ok) => ok,
570        Err(err) => err.to_compile_error().into(),
571    }
572    .into()
573}
574
575/// `UpsertTemplate` is a derive macro designed to automatically generate upsert (INSERT ... ON CONFLICT)
576/// functions based on `sqlx`. This macro creates `upsert` methods for the struct it is applied to,
577/// which can either insert a new record or update an existing one based on conflict resolution.
578/// It assumes that the columns in the database correspond to the fields in the struct.
579///
580/// # Attributes
581///
582/// `UpsertTemplate` accepts the following attributes:
583/// - `table`: Specifies the name of the table in the database (mandatory).
584/// - `debug_slow`: Configures debug logs for the executed query:
585///   - If set to `0`: Only logs the executed query.
586///   - If set to a value greater than `0`: Only logs the query if the execution time exceeds the configured value (in milliseconds).
587///   - If not configured, no debug logs will be generated.
588/// - `tp_upsert`: The main configuration for generating the upsert function, with the following sub-attributes:
589///   - `conflict`: Specifies the columns that define the conflict condition (mandatory).
590///   - `update`: List of columns that will be updated on conflict. If empty, all non-conflict columns will be updated.
591///   - `where`: Additional WHERE clause for the ON CONFLICT DO UPDATE with placeholder support (see Placeholder Mapping in SelectTemplate).
592///   - `fn_name`: The name of the generated function. If empty, the library will automatically generate a function name.
593///   - `returning`: If set to true, the generated function will return the upserted record (PostgreSQL only).
594///   - `debug_slow`: Configures debug logs for the executed query (overrides struct-level setting).
595///
596/// # Database Support
597///
598/// Upsert functionality is supported in:
599/// - **PostgreSQL**: Uses `INSERT ... ON CONFLICT ... DO UPDATE` syntax with full RETURNING support
600/// - **SQLite**: Uses `INSERT ... ON CONFLICT ... DO UPDATE` syntax with RETURNING support (SQLite 3.35.0+)
601/// - **MySQL**: Uses `INSERT ... ON DUPLICATE KEY UPDATE` syntax (RETURNING not supported)
602///
603/// # Example
604///
605/// ```rust,ignore
606/// use sqlx_template::UpsertTemplate;
607/// use sqlx::Pool;
608///
609/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
610/// # let pool: Pool<sqlx::Postgres> = todo!();
611/// // PostgreSQL example
612/// #[derive(UpsertTemplate, sqlx::FromRow)]
613/// #[table("users")]
614/// #[tp_upsert(by = "email", update = "password, updated_at", fn_name = "upsert_user")]
615/// #[tp_upsert(by = "id", fn_name = "upsert_by_id", returning = true)]
616/// #[debug_slow = 1000]
617/// #[db("postgres")]
618/// pub struct UserPg {
619///     pub id: i32,
620///     pub email: String,
621///     pub password: String,
622///     pub updated_at: Option<chrono::DateTime<chrono::Utc>>,
623/// }
624///
625/// // SQLite example
626/// #[derive(UpsertTemplate, sqlx::FromRow)]
627/// #[table("users")]
628/// #[tp_upsert(by = "email", update = "password")]
629/// #[db("sqlite")]
630/// pub struct UserSqlite {
631///     pub id: i32,
632///     pub email: String,
633///     pub password: String,
634/// }
635///
636/// // MySQL example
637/// #[derive(UpsertTemplate, sqlx::FromRow)]
638/// #[table("users")]
639/// #[tp_upsert(by = "email", update = "password")]
640/// #[db("mysql")]
641/// pub struct UserMysql {
642///     pub id: i32,
643///     pub email: String,
644///     pub password: String,
645/// }
646///
647/// // Usage:
648/// let user = UserPg { id: 1, email: "john@example.com".to_string(), password: "newpass".to_string(), updated_at: None };
649/// let rows_affected = UserPg::upsert_user(&user, &pool).await?;
650///
651/// // With returning (PostgreSQL and SQLite)
652/// let upserted_user = UserPg::upsert_by_id(&user, &pool).await?;
653/// # Ok(())
654/// # }
655/// ```
656///
657/// # Note
658///
659/// This macro relies on `sqlx` and database-specific upsert syntax. Make sure your target
660/// database supports the generated upsert statements.
661///
662#[proc_macro_derive(UpsertTemplate, attributes(table, tp_upsert, debug_slow, db))]
663pub fn upsert_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
664    let input = syn::parse_macro_input!(input as syn::DeriveInput);
665    match sqlx_template::upsert::derive_upsert(&input, None, sqlx_template::Scope::Struct, None) {
666        Ok(ok) => ok,
667        Err(err) => err.to_compile_error().into(),
668    }
669    .into()
670}
671
672/// `SqlxTemplate` is a comprehensive derive macro that combines all database operation templates
673/// into a single macro. This macro generates functions for insert, update, select, delete, and upsert
674/// operations based on `sqlx`. It's a convenience macro that applies `InsertTemplate`, `UpdateTemplate`,
675/// `SelectTemplate`, `DeleteTemplate`, `UpsertTemplate`, and `TableName` all at once.
676///
677/// # Attributes
678///
679/// `SqlxTemplate` accepts all attributes from the individual template macros:
680/// - `table`: Specifies the name of the table in the database (mandatory).
681/// - `debug_slow`: Global debug configuration for all generated functions.
682/// - `auto`: Applied to fields that should be excluded from insert statements.
683/// - `tp_select_all`, `tp_select_one`, `tp_select_page`, `tp_select_stream`, `tp_select_count`: Select operation configurations.
684/// - `tp_update`: Update operation configurations.
685/// - `tp_delete`: Delete operation configurations.
686/// - `tp_upsert`: Upsert operation configurations.
687/// - `tp_select_builder`, `tp_update_builder`, `tp_delete_builder`: Builder pattern configurations.
688/// - `db`: Specifies the target database type.
689///
690#[doc = include_str!("../docs/builder_pattern.md")]
691///
692/// # Generated Functions
693///
694/// This macro generates all functions from the individual templates:
695/// - Insert operations: `insert()`, `insert_return()` (PostgreSQL only)
696/// - Update operations: Based on `tp_update` configurations
697/// - Select operations: Based on `tp_select_*` configurations, plus default `find_all()`, `count_all()`, `find_page_all()`
698/// - Delete operations: Based on `tp_delete` configurations
699/// - Upsert operations: Based on `tp_upsert` configurations
700/// - Table name function: `table_name()`
701///
702/// # Example
703///
704/// ```rust,ignore
705/// use sqlx_template::SqlxTemplate;
706/// use sqlx::Pool;
707///
708/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
709/// # let pool: Pool<sqlx::Postgres> = todo!();
710/// #[derive(SqlxTemplate, sqlx::FromRow)]
711/// #[table("users")]
712/// #[db("postgres")]
713/// #[debug_slow = 1000]
714/// #[tp_select_one(by = "id", fn_name = "find_by_id")]
715/// #[tp_select_all(by = "email", order = "id desc")]
716/// #[tp_update(by = "id", op_lock = "version")]
717/// #[tp_delete(by = "id")]
718/// #[tp_upsert(by = "email", update = "password")]
719/// pub struct User {
720///     #[auto]
721///     pub id: i32,
722///     pub email: String,
723///     pub password: String,
724///     pub version: i32,
725/// }
726///
727/// let user = User {
728///     id: 1,
729///     email: "user@example.com".to_string(),
730///     password: "password".to_string(),
731///     version: 1
732/// };
733///
734/// // All operations are now available:
735/// let users = User::builder_select()
736///     .find_all(&pool)
737///     .await?;
738/// let affected = User::builder_update()
739///     .execute(&pool)
740///     .await?;
741/// let deleted = User::builder_delete()
742///     .execute(&pool)
743///     .await?;
744/// # Ok(())
745/// # }
746/// ```
747///
748/// # Note
749///
750/// This is the most convenient macro to use when you need comprehensive database operations
751/// for a struct. It combines all individual template macros into one.
752///
753#[proc_macro_derive(SqlxTemplate, attributes(table, tp_upsert, tp_select_all, tp_select_one, tp_select_page, tp_select_stream, tp_select_count, tp_update, tp_delete, tp_update_builder, tp_select_builder, tp_delete_builder, auto, debug_slow, db))]
754pub fn sqlx_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
755    let input = syn::parse_macro_input!(input as syn::DeriveInput);
756    match sqlx_template::derive_all(&input, None, sqlx_template::Scope::Struct, None) {
757        Ok(ok) => ok,
758        Err(err) => err.to_compile_error().into(),
759    }
760    .into()
761}
762
763/// `PostgresTemplate` is a database-specific version of `SqlxTemplate` optimized for PostgreSQL.
764/// This macro generates all database operation functions specifically targeting PostgreSQL features
765/// and syntax. It combines insert, update, select, delete, and upsert operations with PostgreSQL-specific
766/// optimizations and features like RETURNING clauses.
767///
768/// # Attributes
769///
770/// `PostgresTemplate` accepts the same attributes as `SqlxTemplate`:
771/// - `table`: Specifies the name of the table in the database (mandatory).
772/// - `debug_slow`: Global debug configuration for all generated functions.
773/// - `auto`: Applied to fields that should be excluded from insert statements.
774/// - `tp_select_all`, `tp_select_one`, `tp_select_page`, `tp_select_stream`, `tp_select_count`: Select operation configurations.
775/// - `tp_update`: Update operation configurations.
776/// - `tp_delete`: Delete operation configurations.
777/// - `tp_upsert`: Upsert operation configurations.
778/// - `tp_select_builder`, `tp_update_builder`, `tp_delete_builder`: Builder pattern configurations.
779///
780#[doc = include_str!("../docs/builder_pattern.md")]
781///
782/// # PostgreSQL-Specific Features
783///
784/// - Enhanced RETURNING clause support for insert, update, delete, and upsert operations
785/// - Optimized upsert using PostgreSQL's ON CONFLICT syntax
786/// - Better support for PostgreSQL-specific data types
787/// - Optimized query generation for PostgreSQL
788///
789/// # Example
790///
791/// ```rust,ignore
792/// use sqlx_template::PostgresTemplate;
793/// use sqlx::Pool;
794///
795/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
796/// # let pool: Pool<sqlx::Postgres> = todo!();
797/// #[derive(PostgresTemplate, sqlx::FromRow)]
798/// #[table("users")]
799/// #[tp_update(by = "id", returning = true)]
800/// #[tp_delete(by = "id", returning = true)]
801/// #[tp_upsert(by = "email", returning = true)]
802/// pub struct User {
803///     #[auto]
804///     pub id: i32,
805///     pub email: String,
806///     pub password: String,
807/// }
808///
809/// let user = User {
810///     id: 1,
811///     email: "user@example.com".to_string(),
812///     password: "password".to_string()
813/// };
814///
815/// // PostgreSQL-specific features:
816/// let users = User::builder_select()
817///     .find_all(&pool)
818///     .await?;
819/// let affected = User::builder_update()
820///     .execute(&pool)
821///     .await?;
822/// let deleted = User::builder_delete()
823///     .execute(&pool)
824///     .await?;
825/// # Ok(())
826/// # }
827/// ```
828///
829/// # Note
830///
831/// This macro is specifically designed for PostgreSQL and may not work with other databases.
832/// Use `SqlxTemplate` for database-agnostic code or other database-specific templates for other databases.
833///
834#[proc_macro_derive(PostgresTemplate, attributes(table, tp_upsert, tp_select_all, tp_select_one, tp_select_page, tp_select_stream, tp_select_count, tp_update, tp_delete, auto, debug_slow, tp_select_builder, tp_update_builder, tp_delete_builder))]
835pub fn postgres_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
836    let input = syn::parse_macro_input!(input as syn::DeriveInput);
837    match sqlx_template::derive_all(&input, None, sqlx_template::Scope::Struct, Some(Database::Postgres)) {
838        Ok(ok) => ok,
839        Err(err) => err.to_compile_error().into(),
840    }
841    .into()
842}
843
844/// `MysqlTemplate` is a database-specific version of `SqlxTemplate` optimized for MySQL.
845/// This macro generates all database operation functions specifically targeting MySQL features
846/// and syntax. It combines insert, update, select, delete, and upsert operations with MySQL-specific
847/// optimizations and syntax compatibility.
848///
849/// # Attributes
850///
851/// `MysqlTemplate` accepts the same attributes as `SqlxTemplate`:
852/// - `table`: Specifies the name of the table in the database (mandatory).
853/// - `debug_slow`: Global debug configuration for all generated functions.
854/// - `auto`: Applied to fields that should be excluded from insert statements.
855/// - `tp_select_all`, `tp_select_one`, `tp_select_page`, `tp_select_stream`, `tp_select_count`: Select operation configurations.
856/// - `tp_update`: Update operation configurations.
857/// - `tp_delete`: Delete operation configurations.
858/// - `tp_upsert`: Upsert operation configurations.
859/// - `tp_select_builder`, `tp_update_builder`, `tp_delete_builder`: Builder pattern configurations.
860///
861#[doc = include_str!("../docs/builder_pattern.md")]
862///
863/// # MySQL-Specific Features
864///
865/// - Optimized query generation for MySQL syntax
866/// - Support for MySQL-specific data types
867/// - Upsert operations using MySQL's ON DUPLICATE KEY UPDATE syntax
868/// - Proper handling of MySQL's auto-increment columns
869/// - MySQL-compatible LIMIT and OFFSET syntax for pagination
870///
871/// # Example
872///
873/// ```rust,ignore
874/// use sqlx_template::MysqlTemplate;
875/// use sqlx::Pool;
876///
877/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
878/// # let pool: Pool<sqlx::Any> = todo!();
879/// #[derive(MysqlTemplate, sqlx::FromRow)]
880/// #[table("users")]
881/// #[tp_update(by = "id")]
882/// #[tp_delete(by = "id")]
883/// #[tp_upsert(by = "email", update = "password")]
884/// pub struct User {
885///     #[auto]
886///     pub id: i32,
887///     pub email: String,
888///     pub password: String,
889/// }
890///
891/// let user = User {
892///     id: 1,
893///     email: "user@example.com".to_string(),
894///     password: "password".to_string()
895/// };
896///
897/// // MySQL-optimized operations:
898/// let users = User::builder_select()
899///     .find_all(&pool)
900///     .await?;
901/// let affected = User::builder_update()
902///     .execute(&pool)
903///     .await?;
904/// let deleted = User::builder_delete()
905///     .execute(&pool)
906///     .await?;
907/// # Ok(())
908/// # }
909/// ```
910///
911/// # Note
912///
913/// This macro is specifically designed for MySQL and generates MySQL-compatible SQL syntax.
914/// Use `SqlxTemplate` for database-agnostic code or other database-specific templates for other databases.
915///
916#[proc_macro_derive(MysqlTemplate, attributes(table, tp_upsert, tp_select_all, tp_select_one, tp_select_page, tp_select_stream, tp_select_count, tp_update, tp_delete, auto, debug_slow, tp_select_builder, tp_update_builder, tp_delete_builder))]
917pub fn mysql_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
918    let input = syn::parse_macro_input!(input as syn::DeriveInput);
919    match sqlx_template::derive_all(&input, None, sqlx_template::Scope::Struct, Some(Database::Mysql)) {
920        Ok(ok) => ok,
921        Err(err) => err.to_compile_error().into(),
922    }
923    .into()
924}
925
926/// `SqliteTemplate` is a database-specific version of `SqlxTemplate` optimized for SQLite.
927/// This macro generates all database operation functions specifically targeting SQLite features
928/// and syntax. It combines insert, update, select, delete, and upsert operations with SQLite-specific
929/// optimizations and syntax compatibility.
930///
931/// # Attributes
932///
933/// `SqliteTemplate` accepts the same attributes as `SqlxTemplate`:
934/// - `table`: Specifies the name of the table in the database (mandatory).
935/// - `debug_slow`: Global debug configuration for all generated functions.
936/// - `auto`: Applied to fields that should be excluded from insert statements.
937/// - `tp_select_all`, `tp_select_one`, `tp_select_page`, `tp_select_stream`, `tp_select_count`: Select operation configurations.
938/// - `tp_update`: Update operation configurations.
939/// - `tp_delete`: Delete operation configurations.
940/// - `tp_upsert`: Upsert operation configurations.
941/// - `tp_select_builder`: Builder pattern configuration for SELECT operations.
942/// - `tp_update_builder`: Builder pattern configuration for UPDATE operations.
943/// - `tp_delete_builder`: Builder pattern configuration for DELETE operations.
944///
945#[doc = include_str!("../docs/builder_pattern.md")]
946///
947/// # SQLite-Specific Features
948///
949/// - Optimized query generation for SQLite syntax
950/// - Support for SQLite-specific data types and functions
951/// - Upsert operations using SQLite's INSERT ... ON CONFLICT syntax
952/// - Proper handling of SQLite's ROWID and auto-increment columns
953/// - SQLite-compatible LIMIT and OFFSET syntax for pagination
954/// - Builder pattern with compile-time optimized SQL generation
955///
956/// # Example
957///
958/// ```rust,no_run
959/// use sqlx_template::SqliteTemplate;
960/// use sqlx::Pool;
961///
962/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
963/// # let pool: Pool<sqlx::Sqlite> = todo!();
964/// #[derive(SqliteTemplate, sqlx::FromRow)]
965/// #[table("users")]
966/// #[tp_select_builder(
967///     with_email_domain = "email LIKE :domain$String",
968///     with_score_range = "score BETWEEN :min$i32 AND :max$i32"
969/// )]
970/// #[tp_update(by = "id")]
971/// #[tp_delete(by = "id")]
972/// #[tp_upsert(by = "email", update = "password")]
973/// pub struct User {
974///     #[auto]
975///     pub id: i32,
976///     pub email: String,
977///     pub password: String,
978///     pub score: i32,
979///     pub active: bool,
980/// }
981///
982/// let user = User {
983///     id: 1,
984///     email: "john@example.com".to_string(),
985///     password: "password".to_string(),
986///     score: 85,
987///     active: true
988/// };
989///
990/// // Traditional operations:
991/// // User::insert(&user, &pool).await?;
992/// // User::update_by_id(&user, &pool).await?;
993/// // User::delete_by_id(&1, &pool).await?;
994/// // User::upsert_by_email(&user, &pool).await?;
995///
996/// // Builder pattern operations:
997/// let users = User::builder_select()
998///     .email("john@example.com")?
999///     .active(&true)?
1000///     .with_email_domain("%@company.com")?
1001///     .order_by_score_desc()?
1002///     .find_all(&pool)
1003///     .await?;
1004/// # Ok(())
1005/// # }
1006/// ```
1007///
1008/// # Note
1009///
1010/// This macro is specifically designed for SQLite and generates SQLite-compatible SQL syntax.
1011/// Use `SqlxTemplate` for database-agnostic code or other database-specific templates for other databases.
1012///
1013#[proc_macro_derive(SqliteTemplate, attributes(table, tp_upsert, tp_select_all, tp_select_one, tp_select_page, tp_select_stream, tp_select_count, tp_update, tp_delete, auto, debug_slow, tp_select_builder, tp_update_builder, tp_delete_builder))]
1014pub fn sqlite_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
1015    let input = syn::parse_macro_input!(input as syn::DeriveInput);
1016    match sqlx_template::derive_all(&input, None, sqlx_template::Scope::Struct, Some(Database::Sqlite)) {
1017        Ok(ok) => ok,
1018        Err(err) => err.to_compile_error().into(),
1019    }
1020    .into()
1021}
1022
1023/// `AnyTemplate` is a database-agnostic version of `SqlxTemplate` that generates
1024/// database operations compatible with multiple database types. This macro generates
1025/// functions that work across different databases by using the most common SQL syntax.
1026///
1027/// # Attributes
1028///
1029/// `AnyTemplate` accepts the same attributes as `SqlxTemplate`:
1030/// - `table`: Specifies the name of the table in the database (mandatory).
1031/// - `debug_slow`: Global debug configuration for all generated functions.
1032/// - `auto`: Applied to fields that should be excluded from insert statements.
1033/// - `tp_select_all`, `tp_select_one`, `tp_select_page`, `tp_select_stream`, `tp_select_count`: Select operation configurations.
1034/// - `tp_update`: Update operation configurations.
1035/// - `tp_delete`: Delete operation configurations.
1036/// - `tp_upsert`: Upsert operation configurations.
1037/// - `tp_select_builder`, `tp_update_builder`, `tp_delete_builder`: Builder pattern configurations.
1038///
1039#[doc = include_str!("../docs/builder_pattern.md")]
1040///
1041/// # Database Compatibility Features
1042///
1043/// - Generates SQL syntax compatible with multiple database types
1044/// - Uses standard SQL features that work across databases
1045/// - Avoids database-specific syntax and functions
1046/// - Compatible with sqlx::Any database driver
1047///
1048/// # Example
1049///
1050/// ```rust,ignore
1051/// use sqlx_template::AnyTemplate;
1052/// use sqlx::Pool;
1053///
1054/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
1055/// # let pool: Pool<sqlx::Any> = todo!();
1056/// #[derive(AnyTemplate, sqlx::FromRow)]
1057/// #[table("users")]
1058/// #[tp_update(by = "id")]
1059/// #[tp_delete(by = "id")]
1060/// #[tp_select_one(by = "email")]
1061/// pub struct User {
1062///     #[auto]
1063///     pub id: i32,
1064///     pub email: String,
1065///     pub password: String,
1066/// }
1067///
1068/// let user = User {
1069///     id: 1,
1070///     email: "user@example.com".to_string(),
1071///     password: "password".to_string()
1072/// };
1073///
1074/// // Database operations work across different database types
1075/// let users = User::builder_select()
1076///     .find_all(&pool)
1077///     .await?;
1078/// # Ok(())
1079/// # }
1080///
1081/// // Database-agnostic operations:
1082/// // User::insert(&user, &pool).await?;
1083/// // User::update_by_id(&user, &pool).await?;
1084/// // User::delete_by_id(&1, &pool).await?;
1085/// // User::find_one_by_email(&"user@example.com".to_string(), &pool).await?;
1086/// ```
1087///
1088/// # Note
1089///
1090/// This macro is designed for maximum database compatibility but may not take advantage
1091/// of database-specific optimizations. Use database-specific templates for better performance
1092/// when targeting a single database type.
1093///
1094#[proc_macro_derive(AnyTemplate, attributes(table, tp_upsert, tp_select_all, tp_select_one, tp_select_page, tp_select_stream, tp_select_count, tp_update, tp_delete, auto, debug_slow))]
1095pub fn any_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
1096    let input = syn::parse_macro_input!(input as syn::DeriveInput);
1097    match sqlx_template::derive_all(&input, None, sqlx_template::Scope::Struct, Some(Database::Any)) {
1098        Ok(ok) => ok,
1099        Err(err) => err.to_compile_error().into(),
1100    }
1101    .into()
1102}
1103
1104
1105/// `tp_gen` is a procedural macro attribute that provides advanced code generation capabilities
1106/// for database operations. This macro allows for more complex and customizable generation
1107/// of database-related functions beyond what the derive macros provide.
1108///
1109/// # Syntax
1110///
1111/// ```rust,ignore
1112/// use sqlx_template::tp_gen;
1113///
1114/// #[tp_gen(table = "users")]
1115/// pub struct User {
1116///     pub id: i32,
1117///     pub name: String,
1118/// }
1119/// ```
1120///
1121/// # Attributes
1122///
1123/// The specific attributes and configuration options for `tp_gen` depend on the implementation
1124/// and can include various database operation configurations.
1125///
1126/// # Example Usage
1127///
1128/// ```rust,ignore
1129/// use sqlx_template::tp_gen;
1130///
1131/// #[tp_gen(table = "users")]
1132/// pub struct User {
1133///     pub id: i32,
1134///     pub name: String,
1135///     pub email: String,
1136/// }
1137/// ```
1138///
1139/// # Note
1140///
1141/// This is an advanced macro for specialized use cases. For most common database operations,
1142/// consider using the individual derive macros like `InsertTemplate`, `UpdateTemplate`, etc.,
1143/// or the comprehensive `SqlxTemplate` macro.
1144///
1145#[proc_macro_attribute]
1146pub fn tp_gen(args: TokenStream, item: TokenStream) -> proc_macro::TokenStream {
1147    let input = syn::parse_macro_input!(item as syn::DeriveInput);
1148    let args = parse_macro_input!(args as AttributeArgs);
1149    match sqlx_template::proc::proc_gen(input, args) {
1150        Ok(ok) => ok,
1151        Err(err) => err.to_compile_error().into(),
1152    }
1153    .into()
1154}
1155
1156
1157/// The `TableName` derive macro automatically generates a `table_name` function
1158/// for a struct, returning the value specified in the `table` attribute.
1159///
1160/// # Syntax
1161///
1162/// ```rust,no_run
1163/// use sqlx_template::TableName;
1164///
1165/// #[derive(TableName)]
1166/// #[table("users")]
1167/// pub struct User {
1168///     pub id: i32,
1169///     pub name: String,
1170/// }
1171/// ```
1172///
1173/// # Attributes
1174///
1175/// - `table`: Specifies the name of the table as a string (e.g., `#[table("users")]`).
1176///
1177/// # Function Signature
1178///
1179/// The macro generates a const function named `table_name()` which returns a `&'static str` containing the table name.
1180///
1181/// # Example Usage
1182///
1183/// ```rust,no_run
1184/// use sqlx_template::TableName;
1185///
1186/// #[derive(TableName)]
1187/// #[table("users")]
1188/// pub struct User {
1189///     pub id: i32,
1190///     pub name: String,
1191///     pub age: i32,
1192/// }
1193///
1194/// fn main() {
1195///     assert_eq!(User::table_name(), "users");
1196/// }
1197/// ```
1198///
1199/// # Note
1200///
1201/// This macro is often used in combination with other sqlx-template macros to provide
1202/// a consistent way to reference table names throughout your application.
1203#[proc_macro_derive(TableName, attributes(table))]
1204pub fn table_name_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
1205    let input = syn::parse_macro_input!(input as syn::DeriveInput);
1206    match sqlx_template::table_name_derive(&input) {
1207        Ok(ok) => ok,
1208        Err(err) => err.to_compile_error().into(),
1209    }
1210    .into()
1211}
1212
1213/// The `multi_query` procedural macro transforms a series of SQL queries with named parameters into
1214/// an asynchronous function that interacts with the database. It provides various
1215/// features, including debugging options, and is designed to handle multiple SQL statements with no return value (`void`).
1216///
1217/// # Syntax
1218///
1219/// ```rust,ignore
1220/// use sqlx_template::multi_query;
1221///
1222/// #[multi_query(
1223///     sql = "UPDATE users SET active = true WHERE id = :id",
1224///     debug = 100,
1225///     db = "sqlite"
1226/// )]
1227/// pub async fn activate_user(id: i32) {}
1228/// ```
1229///
1230/// # Attributes
1231///
1232/// - `sql`: Specifies the SQL queries to be executed. This can be:
1233///   - A raw SQL query as a string (e.g., `sql = "BEGIN; UPDATE user SET age = :age WHERE name = :name; COMMIT;"`).
1234///   - A path to a file containing the SQL queries (e.g., `file = "path/to/queries.sql"`).
1235///   - The queries directly as a string without the `sql` or `file` keyword.
1236///
1237///   **Constraints:**
1238///   - The queries can contain multiple SQL statements.
1239///   - Named parameters (if exist) must be in the format `:<param_name>` and must correspond to the function's parameters.
1240///
1241/// - `debug`: Controls the debug behavior of the macro. It can be:
1242///   - An integer value. If not provided, the default is no debugging.
1243///   - `0`: Prints the queries before execution.
1244///   - Greater than `0`: Prints the queries and execution time if it exceeds the specified number of milliseconds.
1245///
1246/// # Function Signature
1247///
1248/// The macro generates an asynchronous function with the following characteristics:
1249/// - The function signature remains unchanged (e.g., `pub async fn <function_name>`).
1250/// - The function parameters are preserved in their original order.
1251/// - An additional parameter for the database connection is required.
1252///
1253/// # Return Types
1254///
1255/// The macro only supports the void return type:
1256///
1257/// - **Void:**
1258///   - : Returns nothing.
1259///
1260/// # Example Usage
1261///
1262/// ```rust,ignore
1263/// use sqlx_template::multi_query;
1264///
1265/// #[multi_query(
1266///     sql = "BEGIN; UPDATE user SET age = :age WHERE name = :name; DELETE FROM session WHERE user_name = :name; COMMIT;",
1267///     debug = 100,
1268///     db = "sqlite"
1269/// )]
1270/// pub async fn update_user_and_clear_sessions(name: &str, age: i32) {}
1271///
1272/// #[multi_query(
1273///     sql = "INSERT INTO user (name, age) VALUES (:name, :age); INSERT INTO log (user_name, action) VALUES (:name, 'created')",
1274///     debug = 0,
1275///     db = "sqlite"
1276/// )]
1277/// pub async fn insert_user_with_log(name: &str, age: i32) {}
1278/// ```
1279///
1280
1281
1282#[proc_macro_attribute]
1283pub fn multi_query(args: TokenStream, item: TokenStream) -> proc_macro::TokenStream {
1284    let input = syn::parse_macro_input!(item as syn::ItemFn);
1285    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
1286    match raw::multi_query_derive(input, args, None, None) {
1287        Ok(ok) => ok,
1288        Err(err) => err.to_compile_error().into(),
1289    }
1290    .into()
1291}
1292
1293/// Same as [crate::multi_query] proc macro, but specified for Postgres database
1294#[proc_macro_attribute]
1295pub fn postgres_multi_query(args: TokenStream, item: TokenStream) -> proc_macro::TokenStream {
1296    let input = syn::parse_macro_input!(item as syn::ItemFn);
1297    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
1298    match raw::multi_query_derive(input, args, None, Some(Database::Postgres)) {
1299        Ok(ok) => ok,
1300        Err(err) => err.to_compile_error().into(),
1301    }
1302    .into()
1303}
1304
1305/// Same as [crate::multi_query] proc macro, but specified for MySQL database
1306#[proc_macro_attribute]
1307pub fn mysql_multi_query(args: TokenStream, item: TokenStream) -> proc_macro::TokenStream {
1308    let input = syn::parse_macro_input!(item as syn::ItemFn);
1309    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
1310    match raw::multi_query_derive(input, args, None, Some(Database::Mysql)) {
1311        Ok(ok) => ok,
1312        Err(err) => err.to_compile_error().into(),
1313    }
1314    .into()
1315}
1316
1317/// Same as [crate::multi_query] proc macro, but specified for SQLite database
1318#[proc_macro_attribute]
1319pub fn sqlite_multi_query(args: TokenStream, item: TokenStream) -> proc_macro::TokenStream {
1320    let input = syn::parse_macro_input!(item as syn::ItemFn);
1321    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
1322    match raw::multi_query_derive(input, args, None, Some(Database::Sqlite)) {
1323        Ok(ok) => ok,
1324        Err(err) => err.to_compile_error().into(),
1325    }
1326    .into()
1327}
1328
1329
1330
1331/// The `query` procedural macro transforms an SQL query with named parameters into
1332/// an asynchronous function that interacts with the database. It provides various
1333/// features, including debugging options and support for multiple return types.
1334///
1335/// # Syntax
1336///
1337/// ```rust,ignore
1338/// use sqlx_template::query;
1339///
1340/// struct User {
1341///     pub id: i32,
1342///     pub name: String,
1343/// }
1344///
1345/// #[query(
1346///     sql = "SELECT * FROM users WHERE id = :id",
1347///     debug = 100
1348/// )]
1349/// pub async fn get_user_by_id(id: i32) -> Option<User> {}
1350/// ```
1351///
1352/// # Attributes
1353///
1354/// - `sql`: Specifies the SQL query to be executed. This can be:
1355///   - A raw SQL query as a string (e.g., `sql = "SELECT * FROM user WHERE (name = :name and age = :age) OR name LIKE '%:name%'"`).
1356///   - A path to a file containing the SQL query (e.g., `file = "path/to/query.sql"`).
1357///   - The query directly as a string without the `sql` or `file` keyword.
1358///
1359///   **Constraints:**
1360///   - The query must contain a single SQL statement.
1361///   - Named parameters (if exist) must be in the format `:<param_name>` and must correspond to the function's parameters.
1362///
1363/// - `debug`: Controls the debug behavior of the macro. It can be:
1364///   - An integer value. If not provided, the default is no debugging.
1365///   - `0`: Prints the query before execution.
1366///   - Greater than `0`: Prints the query and execution time if it exceeds the specified number of milliseconds.
1367///
1368/// # Function Signature
1369///
1370/// The macro generates an asynchronous function with the following characteristics:
1371/// - The function signature remains unchanged (e.g., `pub async fn <function_name>`).
1372/// - The function parameters are preserved in their original order.
1373/// - An additional parameter for the database connection is required.
1374///
1375/// # Return Types
1376///
1377/// The macro supports various return types based on the SQL query:
1378///
1379/// - **Single Record:**
1380///   - `T`: Returns a single record, which must be present. If no record is found, an error is returned.
1381///   - `Option<T>`: Returns a single record if present, or `None` if no record is found.
1382///
1383/// - **Multiple Records:**
1384///   - `Vec<T>`: Returns all matching records as a vector.
1385///
1386/// - **Asynchronous Stream:**
1387///   - `Stream<T>`: Returns an asynchronous stream of records.
1388///
1389/// - **Paged Records:**
1390///   - `Page<T>`: Returns paginated results. Requires an additional parameter for pagination (e.g., `impl Into<(i64, i32, bool)>`). The function returns a tuple `(Vec<T>, Option<i64>)`, where the vector contains the paginated records, and the optional value represents the total number of records if requested.
1391///
1392/// - **Scalar Value:**
1393///   - `Scalar<T>`: Returns a single scalar value from the query.
1394///
1395/// - **Affected Rows:**
1396///   - `RowAffected`: Returns the number of affected rows.
1397///
1398/// - **Void:**
1399///   - : Returns nothing.
1400///
1401/// # Example Usage
1402///
1403/// ```rust,ignore
1404/// use sqlx_template::query;
1405///
1406/// struct UserInfo {
1407///     pub name: String,
1408///     pub age: i32,
1409/// }
1410///
1411/// type RowAffected = u64;
1412///
1413/// #[query(
1414///     sql = "SELECT * FROM user WHERE (name = :name and age = :age) OR name LIKE '%:name%'",
1415///     db = "postgres",
1416///     debug = 100
1417/// )]
1418/// pub async fn query_user_info(name: &str, age: i32) -> Vec<UserInfo> {}
1419///
1420/// #[query(
1421///     sql = "INSERT INTO user (name, age) VALUES (:name, :age)",
1422///     db = "postgres",
1423///     debug = 0
1424/// )]
1425/// pub async fn insert_user(name: &str, age: i32) -> RowAffected {}
1426///
1427/// #[query("DELETE FROM user WHERE name = :name", debug = 0, db = "postgres")]
1428/// pub async fn delete_user(name: &str) {}
1429/// ```
1430///
1431
1432#[proc_macro_attribute]
1433pub fn query(args: TokenStream, item: TokenStream) -> proc_macro::TokenStream {
1434    let input = syn::parse_macro_input!(item as syn::ItemFn);
1435    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
1436    match raw::query_derive(input, args, None, None) {
1437        Ok(ok) => ok,
1438        Err(err) => err.to_compile_error().into(),
1439    }
1440    .into()
1441}
1442
1443
1444/// Same as [crate::query] proc macro, but specified for Postgres database
1445#[proc_macro_attribute]
1446pub fn postgres_query(args: TokenStream, item: TokenStream) -> proc_macro::TokenStream {
1447    let input = syn::parse_macro_input!(item as syn::ItemFn);
1448    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
1449    match raw::query_derive(input, args, None, Some(Database::Postgres)) {
1450        Ok(ok) => ok,
1451        Err(err) => err.to_compile_error().into(),
1452    }
1453    .into()
1454}
1455
1456/// Same as [crate::query] proc macro, but specified for MySQL database
1457#[proc_macro_attribute]
1458pub fn mysql_query(args: TokenStream, item: TokenStream) -> proc_macro::TokenStream {
1459    let input = syn::parse_macro_input!(item as syn::ItemFn);
1460    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
1461    match raw::query_derive(input, args, None, Some(Database::Mysql)) {
1462        Ok(ok) => ok,
1463        Err(err) => err.to_compile_error().into(),
1464    }
1465    .into()
1466}
1467
1468/// Same as [crate::query] proc macro, but specified for SQLite database  
1469#[proc_macro_attribute]
1470pub fn sqlite_query(args: TokenStream, item: TokenStream) -> proc_macro::TokenStream {
1471    let input = syn::parse_macro_input!(item as syn::ItemFn);
1472    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
1473    match raw::query_derive(input, args, None, Some(Database::Sqlite)) {
1474        Ok(ok) => ok,
1475        Err(err) => err.to_compile_error().into(),
1476    }
1477    .into()
1478}
1479
1480
1481/// The `select` procedural macro transforms a SQL query with named parameters into
1482/// an asynchronous function that interacts with the database. It provides various
1483/// features, including debugging options and support for multiple return types.
1484///
1485/// # Syntax
1486///
1487/// ```rust,ignore
1488/// use sqlx_template::select;
1489///
1490/// struct User {
1491///     pub id: i32,
1492///     pub active: bool,
1493/// }
1494///
1495/// #[select(
1496///     sql = "SELECT * FROM users WHERE active = :active",
1497///     db = "postgres",
1498///     debug = 100
1499/// )]
1500/// pub async fn get_active_users(active: bool) -> Vec<User> {}
1501/// ```
1502///
1503/// # Attributes
1504///
1505/// - `sql`: Specifies the SQL query to be executed. This can be:
1506///   - A raw SQL query as a string (e.g., `sql = "SELECT * FROM user WHERE (name = :name and age = :age) OR name LIKE '%:name%'`).
1507///   - A path to a file containing the SQL query (e.g., `file = "path/to/query.sql"`).
1508///   - The query directly as a string without the `sql` or `file` keyword.
1509///
1510///   **Constraints:**
1511///   - The query must contain a single SQL SELECT statement.
1512///   - Named parameters (if exist) must be in the format `:<param_name>` and must correspond to the function's parameters.
1513///
1514/// - `debug`: Controls the debug behavior of the macro. It can be:
1515///   - An integer value. If not provided, the default is no debugging.
1516///   - `0`: Prints the query before execution.
1517///   - Greater than `0`: Prints the query and execution time if it exceeds the specified number of milliseconds.
1518///
1519/// # Function Signature
1520///
1521/// The macro generates an asynchronous function with the following characteristics:
1522/// - The function signature remains unchanged (e.g., `pub async fn <function_name>`).
1523/// - The function parameters are preserved in their original order.
1524/// - An additional parameter for the database connection is required.
1525///
1526/// # Return Types
1527///
1528/// The macro supports various return types based on the SQL query:
1529///
1530/// - **Single Record:**
1531///   - `T`: Returns a single record, which must be present. If no record is found, an error is returned.
1532///   - `Option<T>`: Returns a single record if present, or `None` if no record is found.
1533///
1534/// - **Multiple Records:**
1535///   - `Vec<T>`: Returns all matching records as a vector.
1536///
1537/// - **Asynchronous Stream:**
1538///   - `Stream<T>`: Returns an asynchronous stream of records.
1539///
1540/// - **Paged Records:**
1541///   - `Page<T>`: Returns paginated results. Requires an additional parameter for pagination (e.g., `impl Into<(i64, i32, bool)>`). The function returns a tuple `(Vec<T>, Option<i64>)`, where the vector contains the paginated records, and the optional value represents the total number of records if requested.
1542///
1543/// - **Scalar Value:**
1544///   - `Scalar<T>`: Returns a single scalar value from the query.
1545///
1546/// - **Affected Rows:**
1547///   - `RowAffected`: Returns the number of affected rows.
1548///
1549/// - **Void:**
1550///   - : Returns nothing.
1551/// # Example Usage
1552///
1553/// ```rust,ignore
1554/// use sqlx_template::select;
1555///
1556/// struct UserInfo {
1557///     pub name: String,
1558///     pub age: i32,
1559/// }
1560///
1561/// #[select(
1562///     sql = "
1563///     SELECT *
1564///     FROM user
1565///     WHERE (name = :name and age = :age) OR name LIKE '%:name%'
1566/// ",
1567///     db = "postgres",
1568///     debug = 100
1569/// )]
1570/// pub async fn query_user_info(name: &str, age: i32) -> Vec<UserInfo> {}
1571
1572#[proc_macro_attribute]
1573pub fn select(args: TokenStream, item: TokenStream) -> proc_macro::TokenStream {
1574    let input = syn::parse_macro_input!(item as syn::ItemFn);
1575    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
1576    match raw::query_derive(input, args, Some(parser::Mode::Select), None) {
1577        Ok(ok) => ok,
1578        Err(err) => err.to_compile_error().into(),
1579    }
1580    .into()
1581}
1582
1583/// Same as [crate::select] proc macro, but specified for Postgres database
1584#[proc_macro_attribute]
1585pub fn postgres_select(args: TokenStream, item: TokenStream) -> proc_macro::TokenStream {
1586    let input = syn::parse_macro_input!(item as syn::ItemFn);
1587    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
1588    match raw::query_derive(input, args, Some(parser::Mode::Select), Some(Database::Postgres)) {
1589        Ok(ok) => ok,
1590        Err(err) => err.to_compile_error().into(),
1591    }
1592    .into()
1593}
1594/// Same as [crate::select] proc macro, but specified for MySQL database
1595#[proc_macro_attribute]
1596pub fn mysql_select(args: TokenStream, item: TokenStream) -> proc_macro::TokenStream {
1597    let input = syn::parse_macro_input!(item as syn::ItemFn);
1598    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
1599    match raw::query_derive(input, args, Some(parser::Mode::Select), Some(Database::Mysql)) {
1600        Ok(ok) => ok,
1601        Err(err) => err.to_compile_error().into(),
1602    }
1603    .into()
1604}
1605
1606/// Same as [crate::select] proc macro, but specified for SQLite database
1607#[proc_macro_attribute]
1608pub fn sqlite_select(args: TokenStream, item: TokenStream) -> proc_macro::TokenStream {
1609    let input = syn::parse_macro_input!(item as syn::ItemFn);
1610    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
1611    match raw::query_derive(input, args, Some(parser::Mode::Select), Some(Database::Sqlite)) {
1612        Ok(ok) => ok,
1613        Err(err) => err.to_compile_error().into(),
1614    }
1615    .into()
1616}
1617
1618
1619/// The `update` procedural macro transforms an SQL `UPDATE` query with named parameters into
1620/// an asynchronous function that interacts with the database. It provides various
1621/// features, including debugging options and support for returning the number of affected rows.
1622///
1623/// # Syntax
1624///
1625/// ```rust,ignore
1626/// use sqlx_template::update;
1627///
1628/// #[update(
1629///     sql = "UPDATE users SET active = :active WHERE id = :id",
1630///     db = "postgres",
1631///     debug = 100
1632/// )]
1633/// pub async fn update_user_status(id: i32, active: bool) -> u64 {}
1634/// ```
1635///
1636/// # Attributes
1637///
1638/// - `sql`: Specifies the SQL `UPDATE` query to be executed. This can be:
1639///   - A raw SQL query as a string (e.g., `sql = "UPDATE user SET age = :age WHERE name = :name"`).
1640///   - A path to a file containing the SQL query (e.g., `file = "path/to/query.sql"`).
1641///   - The query directly as a string without the `sql` or `file` keyword.
1642///
1643///   **Constraints:**
1644///   - The query must be a single SQL `UPDATE` statement.
1645///   - Named parameters (if exist) must be in the format `:<param_name>` and must correspond to the function's parameters.
1646///
1647/// - `debug`: Controls the debug behavior of the macro. It can be:
1648///   - An integer value. If not provided, the default is no debugging.
1649///   - `0`: Prints the query before execution.
1650///   - Greater than `0`: Prints the query and execution time if it exceeds the specified number of milliseconds.
1651///
1652/// # Function Signature
1653///
1654/// The macro generates an asynchronous function with the following characteristics:
1655/// - The function signature remains unchanged (e.g., `pub async fn <function_name>`).
1656/// - The function parameters are preserved in their original order.
1657/// - An additional parameter for the database connection is required.
1658///
1659/// # Return Types
1660///
1661/// The macro supports the following return type based on the SQL query:
1662///
1663/// - **Single Record:**
1664///   - `T`: Returns a single record, which must be present. If no record is found, an error is returned.
1665///   - `Option<T>`: Returns a single record if present, or `None` if no record is found.
1666///
1667/// - **Multiple Records:**
1668///   - `Vec<T>`: Returns all matching records as a vector.
1669///
1670/// - **Asynchronous Stream:**
1671///   - `Stream<T>`: Returns an asynchronous stream of records.
1672///
1673/// - **Paged Records:**
1674///   - `Page<T>`: Returns paginated results. Requires an additional parameter for pagination (e.g., `impl Into<(i64, i32, bool)>`). The function returns a tuple `(Vec<T>, Option<i64>)`, where the vector contains the paginated records, and the optional value represents the total number of records if requested.
1675///
1676/// - **Scalar Value:**
1677///   - `Scalar<T>`: Returns a single scalar value from the query.
1678///
1679/// - **Affected Rows:**
1680///   - `RowAffected`: Returns the number of affected rows.
1681/// 
1682/// - **Void:**
1683///   - : Returns nothing.
1684///
1685/// # Example Usage
1686///
1687/// ```rust,ignore
1688/// use sqlx_template::update;
1689///
1690/// type RowAffected = u64;
1691///
1692/// #[update(
1693///     sql = "UPDATE user SET age = :age WHERE name = :name",
1694///     db = "postgres",
1695///     debug = 100
1696/// )]
1697/// pub async fn update_user_age(name: &str, age: i32) -> RowAffected {}
1698/// ```
1699///
1700
1701
1702#[proc_macro_attribute]
1703pub fn update(args: TokenStream, item: TokenStream) -> proc_macro::TokenStream {
1704    let input = syn::parse_macro_input!(item as syn::ItemFn);
1705    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
1706    match raw::query_derive(input, args, Some(parser::Mode::Update), None) {
1707        Ok(ok) => ok,
1708        Err(err) => err.to_compile_error().into(),
1709    }
1710    .into()
1711}
1712
1713/// Same as [crate::update] proc macro, but specified for Postgres database
1714#[proc_macro_attribute]
1715pub fn postgres_update(args: TokenStream, item: TokenStream) -> proc_macro::TokenStream {
1716    let input = syn::parse_macro_input!(item as syn::ItemFn);
1717    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
1718    match raw::query_derive(input, args, Some(parser::Mode::Update), Some(Database::Postgres)) {
1719        Ok(ok) => ok,
1720        Err(err) => err.to_compile_error().into(),
1721    }
1722    .into()
1723}
1724
1725/// Same as [crate::update] proc macro, but specified for MySQL database
1726#[proc_macro_attribute]
1727pub fn mysql_update(args: TokenStream, item: TokenStream) -> proc_macro::TokenStream {
1728    let input = syn::parse_macro_input!(item as syn::ItemFn);
1729    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
1730    match raw::query_derive(input, args, Some(parser::Mode::Update), Some(Database::Mysql)) {
1731        Ok(ok) => ok,
1732        Err(err) => err.to_compile_error().into(),
1733    }
1734    .into()
1735}
1736
1737/// Same as [crate::update] proc macro, but specified for SQLite database
1738#[proc_macro_attribute]
1739pub fn sqlite_update(args: TokenStream, item: TokenStream) -> proc_macro::TokenStream {
1740    let input = syn::parse_macro_input!(item as syn::ItemFn);
1741    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
1742    match raw::query_derive(input, args, Some(parser::Mode::Update), Some(Database::Sqlite)) {
1743        Ok(ok) => ok,
1744        Err(err) => err.to_compile_error().into(),
1745    }
1746    .into()
1747}
1748
1749
1750/// The `insert` procedural macro transforms an SQL `INSERT` query with named parameters into
1751/// an asynchronous function that interacts with the database. It provides various
1752/// features, including debugging options and support for returning the number of affected rows
1753/// or no return value (`void`).
1754///
1755/// # Syntax
1756///
1757/// ```rust,ignore
1758/// use sqlx_template::insert;
1759///
1760/// #[insert(
1761///     sql = "INSERT INTO users (name, email) VALUES (:name, :email)",
1762///     debug = 100,
1763///     db = "sqlite"
1764/// )]
1765/// pub async fn create_user(name: &str, email: &str) -> u64 {}
1766/// ```
1767///
1768/// # Attributes
1769///
1770/// - `sql`: Specifies the SQL `INSERT` query to be executed. This can be:
1771///   - A raw SQL query as a string (e.g., `sql = "INSERT INTO user (name, age) VALUES (:name, :age)"`).
1772///   - A path to a file containing the SQL query (e.g., `file = "path/to/query.sql"`).
1773///   - The query directly as a string without the `sql` or `file` keyword.
1774///
1775///   **Constraints:**
1776///   - The query must be a single SQL `INSERT` statement.
1777///   - Named parameters (if exist) must be in the format `:<param_name>` and must correspond to the function's parameters.
1778///
1779/// - `debug`: Controls the debug behavior of the macro. It can be:
1780///   - An integer value. If not provided, the default is no debugging.
1781///   - `0`: Prints the query before execution.
1782///   - Greater than `0`: Prints the query and execution time if it exceeds the specified number of milliseconds.
1783///
1784/// # Function Signature
1785///
1786/// The macro generates an asynchronous function with the following characteristics:
1787/// - The function signature remains unchanged (e.g., `pub async fn <function_name>`).
1788/// - The function parameters are preserved in their original order.
1789/// - An additional parameter for the database connection is required.
1790///
1791/// # Return Types
1792///
1793/// The macro supports the following return type based on the SQL query:
1794///
1795/// - **Single Record:**
1796///   - `T`: Returns a single record, which must be present. If no record is found, an error is returned.
1797///   - `Option<T>`: Returns a single record if present, or `None` if no record is found.
1798///
1799/// - **Multiple Records:**
1800///   - `Vec<T>`: Returns all matching records as a vector.
1801///
1802/// - **Asynchronous Stream:**
1803///   - `Stream<T>`: Returns an asynchronous stream of records.
1804///
1805/// - **Paged Records:**
1806///   - `Page<T>`: Returns paginated results. Requires an additional parameter for pagination (e.g., `impl Into<(i64, i32, bool)>`). The function returns a tuple `(Vec<T>, Option<i64>)`, where the vector contains the paginated records, and the optional value represents the total number of records if requested.
1807///
1808/// - **Scalar Value:**
1809///   - `Scalar<T>`: Returns a single scalar value from the query.
1810///
1811/// - **Affected Rows:**
1812///   - `RowAffected`: Returns the number of affected rows.
1813/// 
1814/// - **Void:**
1815///   - : Returns nothing.
1816///
1817/// # Example Usage
1818///
1819/// ```rust,ignore
1820/// use sqlx_template::insert;
1821///
1822/// type RowAffected = u64;
1823///
1824/// #[insert(
1825///     sql = "INSERT INTO user (name, age) VALUES (:name, :age)",
1826///     debug = 100,
1827///     db = "sqlite"
1828/// )]
1829/// pub async fn insert_user(name: &str, age: i32) -> RowAffected {}
1830///
1831/// #[insert("INSERT INTO user (name, age) VALUES (:name, :age)", db = "sqlite")]
1832/// pub async fn insert_user_no_return(name: &str, age: i32) {}
1833/// ```
1834///
1835
1836
1837#[proc_macro_attribute]
1838pub fn insert(args: TokenStream, item: TokenStream) -> proc_macro::TokenStream {
1839    let input = syn::parse_macro_input!(item as syn::ItemFn);
1840    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
1841    match raw::query_derive(input, args, Some(parser::Mode::Insert), None) {
1842        Ok(ok) => ok,
1843        Err(err) => err.to_compile_error().into(),
1844    }
1845    .into()
1846}
1847
1848/// Same as [crate::insert] proc macro, but specified for Postgres database
1849#[proc_macro_attribute]
1850pub fn postgres_insert(args: TokenStream, item: TokenStream) -> proc_macro::TokenStream {
1851    let input = syn::parse_macro_input!(item as syn::ItemFn);
1852    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
1853    match raw::query_derive(input, args, Some(parser::Mode::Insert), Some(Database::Postgres)) {
1854        Ok(ok) => ok,
1855        Err(err) => err.to_compile_error().into(),
1856    }
1857    .into()
1858}
1859
1860/// Same as [crate::insert] proc macro, but specified for MySQL database
1861#[proc_macro_attribute]
1862pub fn mysql_insert(args: TokenStream, item: TokenStream) -> proc_macro::TokenStream {
1863    let input = syn::parse_macro_input!(item as syn::ItemFn);
1864    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
1865    match raw::query_derive(input, args, Some(parser::Mode::Insert), Some(Database::Mysql)) {
1866        Ok(ok) => ok,
1867        Err(err) => err.to_compile_error().into(),
1868    }
1869    .into()
1870}
1871
1872/// Same as [crate::insert] proc macro, but specified for SQLite database
1873#[proc_macro_attribute]
1874pub fn sqlite_insert(args: TokenStream, item: TokenStream) -> proc_macro::TokenStream {
1875    let input = syn::parse_macro_input!(item as syn::ItemFn);
1876    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
1877    match raw::query_derive(input, args, Some(parser::Mode::Insert), Some(Database::Sqlite)) {
1878        Ok(ok) => ok,
1879        Err(err) => err.to_compile_error().into(),
1880    }
1881    .into()
1882}
1883
1884/// The `delete` procedural macro transforms an SQL `DELETE` query with named parameters into
1885/// an asynchronous function that interacts with the database. It provides various
1886/// features, including debugging options and support for returning the number of affected rows
1887/// or no return value (`void`).
1888///
1889/// # Syntax
1890///
1891/// ```rust,ignore
1892/// use sqlx_template::delete;
1893///
1894/// #[delete(
1895///     sql = "DELETE FROM users WHERE id = :id",
1896///     debug = 100,
1897///     db = "sqlite"
1898/// )]
1899/// pub async fn remove_user(id: i32) -> u64 {}
1900/// ```
1901///
1902/// # Attributes
1903///
1904/// - `sql`: Specifies the SQL `DELETE` query to be executed. This can be:
1905///   - A raw SQL query as a string (e.g., `sql = "DELETE FROM user WHERE name = :name"`).
1906///   - A path to a file containing the SQL query (e.g., `file = "path/to/query.sql"`).
1907///   - The query directly as a string without the `sql` or `file` keyword.
1908///
1909///   **Constraints:**
1910///   - The query must be a single SQL `DELETE` statement.
1911///   - Named parameters (if exist) must be in the format `:<param_name>` and must correspond to the function's parameters.
1912///
1913/// - `debug`: Controls the debug behavior of the macro. It can be:
1914///   - An integer value. If not provided, the default is no debugging.
1915///   - `0`: Prints the query before execution.
1916///   - Greater than `0`: Prints the query and execution time if it exceeds the specified number of milliseconds.
1917///
1918/// # Function Signature
1919///
1920/// The macro generates an asynchronous function with the following characteristics:
1921/// - The function signature remains unchanged (e.g., `pub async fn <function_name>`).
1922/// - The function parameters are preserved in their original order.
1923/// - An additional parameter for the database connection is required.
1924///
1925/// # Return Types
1926///
1927/// The macro supports the following return type based on the SQL query:
1928///
1929/// - **Single Record:**
1930///   - `T`: Returns a single record, which must be present. If no record is found, an error is returned.
1931///   - `Option<T>`: Returns a single record if present, or `None` if no record is found.
1932///
1933/// - **Multiple Records:**
1934///   - `Vec<T>`: Returns all matching records as a vector.
1935///
1936/// - **Asynchronous Stream:**
1937///   - `Stream<T>`: Returns an asynchronous stream of records.
1938///
1939/// - **Paged Records:**
1940///   - `Page<T>`: Returns paginated results. Requires an additional parameter for pagination (e.g., `impl Into<(i64, i32, bool)>`). The function returns a tuple `(Vec<T>, Option<i64>)`, where the vector contains the paginated records, and the optional value represents the total number of records if requested.
1941///
1942/// - **Scalar Value:**
1943///   - `Scalar<T>`: Returns a single scalar value from the query.
1944///
1945/// - **Affected Rows:**
1946///   - `RowAffected`: Returns the number of affected rows.
1947/// 
1948/// - **Void:**
1949///   - : Returns nothing.
1950///
1951/// # Example Usage
1952///
1953/// ```rust,ignore
1954/// use sqlx_template::delete;
1955///
1956/// type RowAffected = u64;
1957///
1958/// #[delete(
1959///     sql = "DELETE FROM user WHERE name = :name",
1960///     debug = 100,
1961///     db = "sqlite"
1962/// )]
1963/// pub async fn delete_user(name: &str) -> RowAffected {}
1964///
1965/// #[delete(
1966///     sql = "DELETE FROM user WHERE name = :name",
1967///     debug = 0,
1968///     db = "sqlite"
1969/// )]
1970/// pub async fn delete_user_no_return(name: &str) {}
1971/// ```
1972///
1973
1974#[proc_macro_attribute]
1975pub fn delete(args: TokenStream, item: TokenStream) -> proc_macro::TokenStream {
1976    let input = syn::parse_macro_input!(item as syn::ItemFn);
1977    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
1978    match raw::query_derive(input, args, Some(parser::Mode::Delete), None) {
1979        Ok(ok) => ok,
1980        Err(err) => err.to_compile_error().into(),
1981    }
1982    .into()
1983}
1984
1985/// Same as [crate::delete] proc macro, but specified for Postgres database
1986#[proc_macro_attribute]
1987pub fn postgres_delete(args: TokenStream, item: TokenStream) -> proc_macro::TokenStream {
1988    let input = syn::parse_macro_input!(item as syn::ItemFn);
1989    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
1990    match raw::query_derive(input, args, Some(parser::Mode::Delete), Some(Database::Postgres)) {
1991        Ok(ok) => ok,
1992        Err(err) => err.to_compile_error().into(), 
1993    }
1994    .into()
1995}
1996
1997/// Same as [crate::delete] proc macro, but specified for MySQL database
1998#[proc_macro_attribute]
1999pub fn mysql_delete(args: TokenStream, item: TokenStream) -> proc_macro::TokenStream {
2000    let input = syn::parse_macro_input!(item as syn::ItemFn);
2001    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
2002    match raw::query_derive(input, args, Some(parser::Mode::Delete), Some(Database::Mysql)) {
2003        Ok(ok) => ok,
2004        Err(err) => err.to_compile_error().into(),
2005    }
2006    .into() 
2007}
2008
2009/// Same as [crate::delete] proc macro, but specified for SQLite database
2010#[proc_macro_attribute]
2011pub fn sqlite_delete(args: TokenStream, item: TokenStream) -> proc_macro::TokenStream {
2012    let input = syn::parse_macro_input!(item as syn::ItemFn);
2013    let args = syn::parse_macro_input!(args as syn::AttributeArgs);
2014    match raw::query_derive(input, args, Some(parser::Mode::Delete), Some(Database::Sqlite)) {
2015        Ok(ok) => ok,
2016        Err(err) => err.to_compile_error().into(),
2017    }
2018    .into()
2019}
2020
2021
2022
2023
2024