drizzle_macros/
lib.rs

1//! # Drizzle RS Procedural Macros
2//!
3//! This crate provides the procedural macros for Drizzle RS, a type-safe SQL query builder for Rust.
4//!
5//! ## Core Macros
6//!
7//! ### SQLite
8//! - [`SQLiteTable`] - Define SQLite table schemas with type safety
9//! - [`SQLiteEnum`] - Define enums that can be stored in SQLite
10//! - [`SQLiteIndex`] - Define indexes on SQLite tables
11//! - [`SQLiteSchema`] - Derive macro to group tables and indexes into a schema
12//!
13//! ### PostgreSQL
14//! - [`PostgresTable`] - Define PostgreSQL table schemas with type safety
15//! - [`PostgresEnum`] - Define enums for PostgreSQL (text, integer, or native ENUM)
16//! - [`PostgresIndex`] - Define indexes on PostgreSQL tables
17//! - [`PostgresSchema`] - Derive macro to group tables and indexes into a schema
18//!
19//! ### Shared
20//! - [`FromRow`] - Derive automatic row-to-struct conversion
21//! - [`sql!`] - Build SQL queries with embedded expressions
22//!
23//! ## Example Usage
24//!
25//! ```ignore
26//! use drizzle::prelude::*;
27//! use drizzle::rusqlite::Drizzle;
28//!
29//! // Define your table
30//! #[SQLiteTable(name = "users")]
31//! struct Users {
32//!     #[integer(primary, autoincrement)]
33//!     id: i32,
34//!     #[text]
35//!     name: String,
36//!     #[text]
37//!     email: Option<String>,
38//! }
39//!
40//! // Define your schema
41//! #[derive(SQLiteSchema)]
42//! struct Schema {
43//!     users: Users,
44//! }
45//!
46//! // Connect and use
47//! let conn = rusqlite::Connection::open_in_memory()?;
48//! let (db, Schema { users }) = Drizzle::new(conn, Schema::new());
49//! db.create()?;
50//!
51//! // Insert data
52//! db.insert(users)
53//!     .values([InsertUsers::new("Alice").with_email("alice@example.com")])
54//!     .execute()?;
55//!
56//! // Query data
57//! let all_users: Vec<SelectUsers> = db.select(()).from(users).all()?;
58//! ```
59//!
60//! For more detailed documentation, see the individual macro documentation below.
61
62extern crate proc_macro;
63
64mod drizzle_test;
65mod fromrow;
66mod generators;
67mod sql;
68mod utils;
69
70#[cfg(feature = "sqlite")]
71mod sqlite;
72
73#[cfg(feature = "rusqlite")]
74mod rusqlite;
75
76#[cfg(feature = "postgres")]
77mod postgres;
78
79use proc_macro::TokenStream;
80use syn::parse_macro_input;
81
82/// Derive macro for creating SQLite-compatible enums.
83///
84/// This macro allows enums to be stored in SQLite databases as either TEXT (variant names)
85/// or INTEGER (discriminant values) depending on the column attribute used.
86///
87/// The enum can be used with `#[text(enum)]` or `#[integer(enum)]` column attributes.
88///
89/// # Requirements
90///
91/// - Enum must have at least one variant
92/// - For `#[integer(enum)]`, variants can have explicit discriminants
93/// - Must derive `Default` to specify the default variant
94///
95/// # Examples
96///
97/// ## Text Storage (Variant Names)
98///
99/// ```
100/// use drizzle::prelude::*;
101///
102/// #[derive(SQLiteEnum, Default, Clone, PartialEq, Debug)]
103/// enum UserRole {
104///     #[default]
105///     User,      // Stored as "User"
106///     Admin,     // Stored as "Admin"
107///     Moderator, // Stored as "Moderator"
108/// }
109///
110/// #[SQLiteTable(name = "users")]
111/// struct Users {
112///     #[integer(primary, autoincrement)]
113///     id: i32,
114///     #[text(enum)] // Stores variant names as TEXT
115///     role: UserRole,
116/// }
117///
118/// // The enum can be converted to/from strings
119/// assert_eq!(UserRole::Admin.to_string(), "Admin");
120/// ```
121///
122/// ## Integer Storage (Discriminants)
123///
124/// ```
125/// use drizzle::prelude::*;
126///
127/// #[derive(SQLiteEnum, Default, Clone, PartialEq, Debug)]
128/// enum Priority {
129///     #[default]
130///     Low = 1,    // Stored as 1
131///     Medium = 5, // Stored as 5
132///     High = 10,  // Stored as 10
133/// }
134///
135/// #[SQLiteTable(name = "tasks")]
136/// struct Tasks {
137///     #[integer(primary, autoincrement)]
138///     id: i32,
139///     #[integer(enum)] // Stores discriminants as INTEGER
140///     priority: Priority,
141/// }
142///
143/// // The enum can be converted to/from integers
144/// let p: i64 = Priority::High.into();
145/// assert_eq!(p, 10);
146/// ```
147///
148/// ## Generated Implementations
149///
150/// The macro automatically implements:
151/// - `std::fmt::Display` - For TEXT representation
152/// - `TryFrom<i64>` - For INTEGER representation  
153/// - `Into<i64>` - For INTEGER representation
154/// - `From<EnumType>` for `SQLiteValue` - Database conversion
155/// - `TryFrom<SQLiteValue>` for `EnumType` - Database conversion
156#[cfg(feature = "sqlite")]
157#[proc_macro_derive(SQLiteEnum)]
158pub fn sqlite_enum_derive(input: TokenStream) -> TokenStream {
159    use quote::quote;
160    use syn::{Data, DeriveInput, parse_macro_input};
161
162    let input = parse_macro_input!(input as DeriveInput);
163    let name = &input.ident;
164
165    // Check if this is an enum or tuple struct
166    match &input.data {
167        Data::Enum(data) => {
168            // Check if the enum has any variants
169            if data.variants.is_empty() {
170                return quote! {
171                    compile_error!("SQLiteEnum cannot be derived for empty enums");
172                }
173                .into();
174            }
175
176            // Generate implementation for enum
177            match crate::sqlite::r#enum::generate_enum_impl(name, data) {
178                Ok(ts) => ts.into(),
179                Err(e) => e.to_compile_error().into(),
180            }
181        }
182        _ => quote! {
183            compile_error!("SQLiteEnum can only be derived for enums and tuple structs");
184        }
185        .into(),
186    }
187}
188
189/// Define a SQLite table schema with type-safe column definitions.
190///
191/// This attribute macro transforms a Rust struct into a complete SQLite table definition
192/// with generated types for INSERT, SELECT, and UPDATE operations.
193///
194/// See [SQLite CREATE TABLE documentation](https://sqlite.org/lang_createtable.html) for
195/// the underlying SQL concepts.
196///
197/// # Table Attributes
198///
199/// - `name = "table_name"` - Custom table name (defaults to struct name in snake_case)
200/// - `strict` - Enable [SQLite STRICT mode](https://sqlite.org/stricttables.html)  
201/// - `without_rowid` - Create a [WITHOUT ROWID table](https://sqlite.org/withoutrowid.html)
202///
203/// # Field Attributes
204///
205/// ## Column Types
206/// - `#[integer]` - SQLite INTEGER type
207/// - `#[text]` - SQLite TEXT type
208/// - `#[real]` - SQLite REAL type
209/// - `#[blob]` - SQLite BLOB type
210/// - `#[boolean]` - Stored as INTEGER (0/1)
211///
212/// ## Constraints
213/// - `primary` - Primary key constraint
214/// - `autoincrement` - Auto-increment (INTEGER PRIMARY KEY only)
215/// - `unique` - Unique constraint
216///
217/// ## Defaults
218/// - `default = value` - Compile-time default value
219/// - `default_fn = function` - Runtime default function (called at insert time)
220///
221/// ## Special Types
222/// - `enum` - Store enum as TEXT or INTEGER (requires `SQLiteEnum` derive)
223/// - `json` - JSON serialization (requires `serde` feature)
224/// - `references = Table::column` - Foreign key reference
225///
226/// # Examples
227///
228/// ## Basic Table
229///
230/// ```no_run
231/// use drizzle::prelude::*;
232/// use drizzle::rusqlite::Drizzle;
233///
234/// #[SQLiteTable(name = "users")]
235/// struct Users {
236///     #[integer(primary, autoincrement)]
237///     id: i32,
238///     #[text]
239///     name: String,
240///     #[text(unique)]
241///     email: String,
242///     #[integer]
243///     age: Option<i32>, // Nullable field
244/// }
245///
246/// #[derive(SQLiteSchema)]
247/// struct Schema {
248///     users: Users,
249/// }
250///
251/// fn main() -> drizzle::Result<()> {
252///     // Usage
253///     let conn = rusqlite::Connection::open_in_memory()?;
254///     let (db, Schema { users }) = Drizzle::new(conn, Schema::new());
255///     db.create()?;
256///
257///     // Insert using generated InsertUsers type
258///     db.insert(users)
259///         .values([InsertUsers::new("Alice", "alice@example.com").with_age(25)])
260///         .execute()?;
261///
262///     // Query using generated SelectUsers type
263///     let all_users: Vec<SelectUsers> = db.select(()).from(users).all()?;
264///     Ok(())
265/// }
266/// ```
267///
268/// ## Table with Defaults
269///
270/// ```
271/// use drizzle::prelude::*;
272///
273/// #[SQLiteTable(name = "posts", strict)]
274/// struct Posts {
275///     #[integer(primary, autoincrement)]
276///     id: i32,
277///     #[text]
278///     title: String,
279///     #[text(default = "draft")]
280///     status: String,
281/// }
282///
283/// // Default value is used when not specified
284/// let post = InsertPosts::new("My Title");
285/// ```
286///
287/// ## Enums and JSON
288///
289/// ```ignore
290/// use drizzle::prelude::*;
291/// use serde::{Serialize, Deserialize};
292///
293/// #[derive(SQLiteEnum, Default, Clone, PartialEq, Debug)]
294/// enum Role {
295///     #[default]
296///     User,
297///     Admin,
298/// }
299///
300/// #[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Default)]
301/// struct Metadata {
302///     theme: String,
303/// }
304///
305/// #[SQLiteTable(name = "accounts")]
306/// struct Accounts {
307///     #[integer(primary, autoincrement)]
308///     id: i32,
309///     #[text(enum)]     // Store enum variant name as TEXT
310///     role: Role,
311///     #[text(json)]     // Serialize struct as JSON TEXT
312///     metadata: Option<Metadata>,
313/// }
314/// ```
315///
316/// ## Foreign Key References
317///
318/// ```
319/// use drizzle::prelude::*;
320///
321/// #[SQLiteTable(name = "users")]
322/// struct Users {
323///     #[integer(primary, autoincrement)]
324///     id: i32,
325///     #[text]
326///     name: String,
327/// }
328///
329/// #[SQLiteTable(name = "posts")]
330/// struct Posts {
331///     #[integer(primary, autoincrement)]
332///     id: i32,
333///     #[integer(references = Users::id)]  // Foreign key to users.id
334///     author_id: i32,
335///     #[text]
336///     title: String,
337/// }
338/// ```
339///
340/// # Generated Types
341///
342/// For a table `Users`, the macro generates:
343/// - `SelectUsers` - For SELECT operations (derives `FromRow`)
344/// - `InsertUsers` - Builder for INSERT operations with `new()` and `with_*()` methods
345/// - `UpdateUsers` - Builder for UPDATE operations with `set_*()` methods
346///
347/// # Nullability
348///
349/// Use `Option<T>` for nullable fields. Non-optional fields get a NOT NULL constraint:
350///
351/// ```
352/// use drizzle::prelude::*;
353///
354/// #[SQLiteTable]
355/// struct Example {
356///     #[integer(primary, autoincrement)]
357///     id: i32,               // NOT NULL, auto-generated
358///     #[text]
359///     name: String,          // NOT NULL (required in InsertExample::new())
360///     #[text]
361///     email: Option<String>, // NULL allowed (set via with_email())
362/// }
363///
364/// // Non-optional, non-primary fields are required in new()
365/// let insert = InsertExample::new("Alice").with_email("alice@example.com");
366/// ```
367#[cfg(feature = "sqlite")]
368#[allow(non_snake_case)]
369#[proc_macro_attribute]
370pub fn SQLiteTable(attr: TokenStream, item: TokenStream) -> TokenStream {
371    let input = syn::parse_macro_input!(item as syn::DeriveInput);
372    let attr_result = syn::parse_macro_input!(attr as crate::sqlite::table::TableAttributes);
373
374    match crate::sqlite::table::table_attr_macro(input, attr_result) {
375        Ok(tokens) => tokens.into(),
376        Err(err) => err.to_compile_error().into(),
377    }
378}
379
380/// Attribute macro for creating SQLite indexes.
381///
382/// This macro generates SQLite-specific index definitions for columns in your tables.
383/// Indexes improve query performance when filtering or sorting by the indexed columns.
384///
385/// # Attributes
386///
387/// - `unique` - Create a unique index (enforces uniqueness constraint)
388/// - No attributes for standard index
389///
390/// # Examples
391///
392/// ## Unique Index
393///
394/// ```
395/// use drizzle::prelude::*;
396///
397/// #[SQLiteTable(name = "users")]
398/// struct Users {
399///     #[integer(primary, autoincrement)]
400///     id: i32,
401///     #[text]
402///     email: String,
403/// }
404///
405/// #[SQLiteIndex(unique)]
406/// struct UserEmailIdx(Users::email);
407///
408/// #[derive(SQLiteSchema)]
409/// struct Schema {
410///     users: Users,
411///     user_email_idx: UserEmailIdx,
412/// }
413/// ```
414///
415/// ## Composite Index
416///
417/// Index on multiple columns:
418///
419/// ```
420/// use drizzle::prelude::*;
421///
422/// #[SQLiteTable(name = "posts")]
423/// struct Posts {
424///     #[integer(primary, autoincrement)]
425///     id: i32,
426///     #[integer]
427///     author_id: i32,
428///     #[text]
429///     status: String,
430/// }
431///
432/// #[SQLiteIndex]
433/// struct PostAuthorStatusIdx(Posts::author_id, Posts::status);
434/// ```
435///
436/// ## Standard (Non-Unique) Index
437///
438/// ```
439/// use drizzle::prelude::*;
440///
441/// #[SQLiteTable(name = "logs")]
442/// struct Logs {
443///     #[integer(primary, autoincrement)]
444///     id: i32,
445///     #[text]
446///     created_at: String,
447/// }
448///
449/// #[SQLiteIndex]
450/// struct LogsCreatedAtIdx(Logs::created_at);
451/// ```
452#[cfg(feature = "sqlite")]
453#[allow(non_snake_case)]
454#[proc_macro_attribute]
455pub fn SQLiteIndex(attr: TokenStream, item: TokenStream) -> TokenStream {
456    let input = syn::parse_macro_input!(item as syn::DeriveInput);
457    let attr_input = syn::parse_macro_input!(attr as crate::sqlite::index::IndexAttributes);
458
459    match crate::sqlite::index::sqlite_index_attr_macro(attr_input, input) {
460        Ok(tokens) => tokens.into(),
461        Err(err) => err.to_compile_error().into(),
462    }
463}
464
465/// Automatically implements row-to-struct conversion for database result types.
466///
467/// This derive macro generates `TryFrom` implementations for all enabled SQLite database
468/// drivers, allowing seamless conversion from database rows to Rust structs.
469///
470/// # Supported Drivers
471///
472/// Implementations are generated based on enabled features:
473/// - **rusqlite** - `TryFrom<&rusqlite::Row<'_>>` (sync)
474/// - **libsql** - `TryFrom<&libsql::Row>` (async)
475/// - **turso** - `TryFrom<&turso::Row>` (async)
476///
477/// # Supported Types
478///
479/// The macro automatically handles type conversion for:
480///
481/// | Rust Type | SQLite Type | Notes |
482/// |-----------|-------------|-------|
483/// | `i8`, `i16`, `i32`, `i64` | INTEGER | Auto-converts from i64 |
484/// | `u8`, `u16`, `u32`, `u64` | INTEGER | Auto-converts from i64 |
485/// | `f32`, `f64` | REAL | Auto-converts from f64 |
486/// | `bool` | INTEGER | 0 = false, non-zero = true |
487/// | `String` | TEXT | |
488/// | `Vec<u8>` | BLOB | |
489/// | `uuid::Uuid` | BLOB | Requires `uuid` feature |
490/// | `Option<T>` | Any | Nullable columns |
491///
492/// # Field Attributes
493///
494/// - `#[column(Table::field)]` - Map to a specific table column (useful for JOINs)
495/// - `#[json]` - Deserialize JSON from TEXT column (requires `serde` feature, libsql/turso only)
496/// - No attribute - Maps to column with same name as the field
497///
498/// # Struct Types
499///
500/// Both named structs and tuple structs are supported:
501/// - Named structs map fields by column name
502/// - Tuple structs map fields by column index (0-based)
503///
504/// # Examples
505///
506/// ## Basic Usage
507///
508/// ```
509/// use drizzle::prelude::*;
510///
511/// #[derive(FromRow, Debug, Default)]
512/// struct User {
513///     id: i32,
514///     name: String,
515///     email: Option<String>,  // Nullable column
516///     active: bool,           // INTEGER 0/1 -> bool
517/// }
518/// ```
519///
520/// ## Custom Column Mapping (for JOINs)
521///
522/// When joining tables with columns of the same name, use `#[column(...)]` to
523/// specify which table's column to use:
524///
525/// ```
526/// use drizzle::prelude::*;
527///
528/// #[SQLiteTable(name = "users")]
529/// struct Users {
530///     #[integer(primary)]
531///     id: i32,
532///     #[text]
533///     name: String,
534/// }
535///
536/// #[SQLiteTable(name = "posts")]
537/// struct Posts {
538///     #[integer(primary)]
539///     id: i32,
540///     #[integer(references = Users::id)]
541///     user_id: i32,
542///     #[text]
543///     title: String,
544/// }
545///
546/// #[derive(FromRow, Debug, Default)]
547/// struct UserPost {
548///     #[column(Users::id)]     // Explicitly use users.id
549///     user_id: i32,
550///     #[column(Users::name)]
551///     user_name: String,
552///     #[column(Posts::id)]     // Explicitly use posts.id
553///     post_id: i32,
554///     #[column(Posts::title)]
555///     title: String,
556/// }
557/// ```
558///
559/// ## Tuple Structs
560///
561/// For simple single-column or multi-column results:
562///
563/// ```
564/// use drizzle::prelude::*;
565///
566/// // Single column result
567/// #[derive(FromRow, Default)]
568/// struct Count(i64);
569///
570/// // Multiple columns by index
571/// #[derive(FromRow, Default)]
572/// struct IdAndName(i32, String);
573/// ```
574///
575/// ## With UUID (requires `uuid` feature)
576///
577/// ```ignore
578/// use drizzle::prelude::*;
579/// use uuid::Uuid;
580///
581/// #[derive(FromRow, Debug)]
582/// struct UserWithId {
583///     id: Uuid,        // Stored as BLOB (16 bytes)
584///     name: String,
585/// }
586/// ```
587///
588/// ## With JSON (requires `serde` feature, libsql/turso)
589///
590/// ```ignore
591/// use drizzle::prelude::*;
592/// use serde::{Serialize, Deserialize};
593///
594/// #[derive(Serialize, Deserialize, Debug)]
595/// struct Profile {
596///     bio: String,
597///     website: Option<String>,
598/// }
599///
600/// #[derive(FromRow, Debug)]
601/// struct UserWithProfile {
602///     id: i32,
603///     name: String,
604///     #[json]  // Deserialize from JSON TEXT
605///     profile: Profile,
606/// }
607/// ```
608///
609/// ## Tuple Structs
610///
611/// ```ignore
612/// use drizzle::prelude::*;
613///
614/// #[derive(FromRow, Default)]
615/// struct NameOnly(String);
616///
617/// let names: Vec<NameOnly> = db.select(users.name).from(users).all()?;
618/// ```
619#[proc_macro_derive(FromRow, attributes(column))]
620pub fn from_row_derive(input: TokenStream) -> TokenStream {
621    let input = parse_macro_input!(input as syn::DeriveInput);
622
623    match crate::fromrow::generate_from_row_impl(input) {
624        Ok(tokens) => tokens.into(),
625        Err(err) => err.to_compile_error().into(),
626    }
627}
628
629/// Derive macro for creating schema structures that manage tables and indexes.
630///
631/// This macro analyzes struct fields to automatically detect tables and indexes,
632/// then generates methods to create all database objects in the correct order.
633///
634/// The schema provides:
635/// - `Schema::new()` - Creates a new schema instance with all tables and indexes
636/// - Integration with `Drizzle::new()` for database operations
637/// - Automatic table and index creation via `db.create()`
638///
639/// # Examples
640///
641/// ## Basic Schema
642///
643/// ```no_run
644/// use drizzle::prelude::*;
645/// use drizzle::rusqlite::Drizzle;
646///
647/// #[SQLiteTable(name = "users")]
648/// struct Users {
649///     #[integer(primary, autoincrement)]
650///     id: i32,
651///     #[text]
652///     email: String,
653/// }
654///
655/// #[derive(SQLiteSchema)]
656/// struct Schema {
657///     users: Users,
658/// }
659///
660/// fn main() -> drizzle::Result<()> {
661///     // Create connection and schema
662///     let conn = rusqlite::Connection::open_in_memory()?;
663///     let (db, Schema { users }) = Drizzle::new(conn, Schema::new());
664///
665///     // Create all tables
666///     db.create()?;
667///
668///     // Use the schema
669///     db.insert(users)
670///         .values([InsertUsers::new("alice@example.com")])
671///         .execute()?;
672///     Ok(())
673/// }
674/// ```
675///
676/// ## Schema with Indexes
677///
678/// ```no_run
679/// use drizzle::prelude::*;
680/// use drizzle::rusqlite::Drizzle;
681///
682/// #[SQLiteTable(name = "users")]
683/// struct Users {
684///     #[integer(primary, autoincrement)]
685///     id: i32,
686///     #[text]
687///     email: String,
688///     #[text]
689///     name: String,
690/// }
691///
692/// #[SQLiteIndex(unique)]
693/// struct UserEmailIdx(Users::email);
694///
695/// #[derive(SQLiteSchema)]
696/// struct Schema {
697///     users: Users,
698///     user_email_idx: UserEmailIdx,
699/// }
700///
701/// fn main() -> drizzle::Result<()> {
702///     let conn = rusqlite::Connection::open_in_memory()?;
703///     let (db, schema) = Drizzle::new(conn, Schema::new());
704///
705///     // Creates tables first, then indexes
706///     db.create()?;
707///     Ok(())
708/// }
709/// ```
710///
711/// ## Async Drivers (libsql, turso)
712///
713/// ```ignore
714/// use drizzle::prelude::*;
715/// use drizzle::libsql::Drizzle;  // or drizzle::turso::Drizzle
716///
717/// #[SQLiteTable]
718/// struct Users {
719///     #[integer(primary)]
720///     id: i32,
721///     #[text]
722///     name: String,
723/// }
724///
725/// #[derive(SQLiteSchema)]
726/// struct Schema {
727///     users: Users,
728/// }
729///
730/// #[tokio::main]
731/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
732///     let db_builder = libsql::Builder::new_local(":memory:").build().await?;
733///     let conn = db_builder.connect()?;
734///     let (db, Schema { users }) = Drizzle::new(conn, Schema::new());
735///
736///     // Async create
737///     db.create().await?;
738///
739///     // Async operations
740///     db.insert(users)
741///         .values([InsertUsers::new("Alice")])
742///         .execute()
743///         .await?;
744///
745///     Ok(())
746/// }
747/// ```
748#[cfg(feature = "sqlite")]
749#[proc_macro_derive(SQLiteSchema)]
750pub fn sqlite_schema_derive(input: TokenStream) -> TokenStream {
751    let input = parse_macro_input!(input as syn::DeriveInput);
752
753    match crate::sqlite::schema::generate_schema_derive_impl(input) {
754        Ok(tokens) => tokens.into(),
755        Err(err) => err.to_compile_error().into(),
756    }
757}
758
759#[cfg(feature = "postgres")]
760#[proc_macro_derive(PostgresSchema)]
761pub fn postgres_schema_derive(input: TokenStream) -> TokenStream {
762    let input = parse_macro_input!(input as syn::DeriveInput);
763
764    match crate::postgres::generate_postgres_schema_derive_impl(input) {
765        Ok(tokens) => tokens.into(),
766        Err(err) => err.to_compile_error().into(),
767    }
768}
769
770/// A procedural macro for building SQL queries with embedded expressions.
771///
772/// This macro supports two different syntax forms:
773/// 1. **String literal syntax**: `sql!("SELECT * FROM {table}")`
774/// 2. **Printf-style syntax**: `sql!("SELECT * FROM {} WHERE {} = {}", table, column, value)`
775///
776/// The macro parses SQL templates and generates type-safe SQL code by:
777/// - Converting literal text to `SQL::text()` calls
778/// - Converting expressions in `{braces}` to `.to_sql()` calls on the expression
779///
780/// # Syntax Forms
781///
782/// ## String Literal Syntax
783///
784/// Embed expressions directly in the SQL string using `{expression}`:
785///
786/// ```ignore
787/// use drizzle::{sql, prelude::*};
788/// use drizzle::rusqlite::Drizzle;
789///
790/// #[SQLiteTable(name = "users")]
791/// pub struct Users {
792///     #[integer(primary)]
793///     pub id: i32,
794///     #[text]
795///     pub name: String,
796/// }
797///
798/// #[derive(SQLiteSchema)]
799/// pub struct Schema { pub users: Users }
800///
801/// let conn = rusqlite::Connection::open_in_memory()?;
802/// let (db, Schema { users }) = Drizzle::new(conn, Schema::new());
803///
804/// let query = sql!("SELECT * FROM {users} WHERE {users.id} = 42");
805/// ```
806///
807/// ## Printf-Style Syntax
808///
809/// Use `{}` placeholders with arguments after the string:
810///
811/// ```ignore
812/// use drizzle::{sql, prelude::*};
813/// use drizzle::rusqlite::Drizzle;
814///
815/// #[SQLiteTable(name = "users")]
816/// pub struct Users {
817///     #[integer(primary)]
818///     pub id: i32,
819/// }
820///
821/// #[derive(SQLiteSchema)]
822/// pub struct Schema { pub users: Users }
823///
824/// let conn = rusqlite::Connection::open_in_memory()?;
825/// let (db, Schema { users }) = Drizzle::new(conn, Schema::new());
826///
827/// let query = sql!("SELECT * FROM {} WHERE {} = {}", users, users.id, 42);
828/// ```
829///
830/// # Examples
831///
832/// ## Basic Usage
833///
834/// ```
835/// use drizzle::{sql, prelude::*};
836///
837/// #[SQLiteTable(name = "users")]
838/// pub struct Users {
839///     #[integer(primary)]
840///     pub id: i32,
841/// }
842///
843/// let users = Users::new();
844/// let query = sql!("SELECT * FROM {users}");
845/// // Generates: SQL::text("SELECT * FROM ").append(users.to_sql())
846/// ```
847///
848/// ## Multiple Expressions
849///
850/// ```
851/// use drizzle::{sql, prelude::*};
852///
853/// #[SQLiteTable(name = "users")]
854/// pub struct Users {
855///     #[integer(primary)]
856///     pub id: i32,
857/// }
858///
859/// #[SQLiteTable(name = "posts")]
860/// pub struct Posts {
861///     #[integer(primary)]
862///     pub id: i32,
863///     #[integer]
864///     pub author_id: i32,
865/// }
866///
867/// let users = Users::new();
868/// let posts = Posts::new();
869/// let query = sql!("SELECT * FROM {users} WHERE {users.id} = {posts.author_id}");
870/// ```
871///
872/// ## Escaped Braces
873///
874/// Use `{{` and `}}` for literal braces in the SQL:
875///
876/// ```
877/// use drizzle::{sql, prelude::*};
878///
879/// #[SQLiteTable(name = "users")]
880/// pub struct Users {
881///     #[integer(primary)]
882///     pub id: i32,
883/// }
884///
885/// let users = Users::new();
886/// let query = sql!("SELECT JSON_OBJECT('key', {{literal}}) FROM {users}");
887/// // Generates: SQL::text("SELECT JSON_OBJECT('key', {literal}) FROM ").append(users.to_sql())
888/// ```
889///
890/// # Requirements
891///
892/// All expressions within `{braces}` must implement the `ToSQL` trait.
893#[proc_macro]
894pub fn sql(input: TokenStream) -> TokenStream {
895    let input = parse_macro_input!(input as crate::sql::SqlInput);
896
897    match crate::sql::sql_impl(input) {
898        Ok(output) => output.into(),
899        Err(err) => err.into_compile_error().into(),
900    }
901}
902
903/// Generates test functions for all enabled SQLite drivers.
904///
905/// This macro creates separate test functions for rusqlite, libsql, and turso drivers,
906/// each with proper async/sync handling and driver-specific setup.
907///
908/// # Syntax
909///
910/// ```ignore
911/// drizzle_test!(test_name, SchemaType, {
912///     // Test body - uses `db` and `schema` variables
913///     let SchemaType { my_table } = schema;
914///     let result = drizzle_exec!(db.insert(my_table).values([data]).execute());
915///     assert_eq!(result, 1);
916/// });
917/// ```
918///
919/// # Generated Functions
920///
921/// For a test named `my_test`, this generates:
922/// - `my_test_rusqlite()` - Sync test for rusqlite (when `rusqlite` feature enabled)
923/// - `my_test_libsql()` - Async test for libsql (when `libsql` feature enabled)
924/// - `my_test_turso()` - Async test for turso (when `turso` feature enabled)
925///
926/// # Available Macros in Test Body
927///
928/// - `drizzle_exec!(operation)` - Execute operation with proper async/sync handling
929/// - `drizzle_try!(operation)` - Try operation, returns early on error
930/// - `drizzle_tx!(tx_type, { body })` - Execute transaction with proper async/sync handling
931///
932/// # Variables Available in Test Body
933///
934/// - `db` - The Drizzle instance for the current driver
935/// - `schema` - The schema instance with all tables
936/// - `tx` - The transaction instance (within `drizzle_tx!` blocks)
937///
938/// # Example
939///
940/// ```ignore
941/// use drizzle::prelude::*;
942/// use drizzle_macros::drizzle_test;
943///
944/// #[SQLiteTable(name = "users")]
945/// struct Users {
946///     #[integer(primary, autoincrement)]
947///     id: i32,
948///     #[text]
949///     name: String,
950/// }
951///
952/// #[derive(SQLiteSchema)]
953/// struct TestSchema {
954///     users: Users,
955/// }
956///
957/// drizzle_test!(insert_and_select, TestSchema, {
958///     let TestSchema { users } = schema;
959///
960///     // Insert a user
961///     drizzle_exec!(db.insert(users)
962///         .values([InsertUsers::new("Alice")])
963///         .execute());
964///
965///     // Select all users
966///     let results: Vec<SelectUsers> = drizzle_exec!(
967///         db.select(()).from(users).all()
968///     );
969///
970///     assert_eq!(results.len(), 1);
971///     assert_eq!(results[0].name, "Alice");
972/// });
973/// ```
974#[proc_macro]
975pub fn drizzle_test(input: TokenStream) -> TokenStream {
976    crate::drizzle_test::drizzle_test_impl(input)
977}
978
979/// Derive macro for creating PostgreSQL-compatible enums.
980///
981/// This macro allows enums to be stored in PostgreSQL databases in three ways:
982/// - **TEXT** - Store variant names as text (`#[text(enum)]`)
983/// - **INTEGER** - Store discriminant values as integers (`#[integer(enum)]`)
984/// - **Native ENUM** - Use PostgreSQL's native ENUM type (`#[enum(EnumType)]`)
985///
986/// # Requirements
987///
988/// - Enum must have at least one variant
989/// - For `#[integer(enum)]`, variants can have explicit discriminants
990/// - Must derive `Default` to specify the default variant
991///
992/// # Examples
993///
994/// ## Text Storage (Variant Names)
995///
996/// ```ignore
997/// use drizzle::prelude::*;
998///
999/// #[derive(PostgresEnum, Default, Clone, PartialEq, Debug)]
1000/// enum UserRole {
1001///     #[default]
1002///     User,      // Stored as "User"
1003///     Admin,     // Stored as "Admin"
1004///     Moderator, // Stored as "Moderator"
1005/// }
1006///
1007/// #[PostgresTable(name = "users")]
1008/// struct Users {
1009///     #[serial(primary)]
1010///     id: i32,
1011///     #[text(enum)]  // Stores variant names as TEXT
1012///     role: UserRole,
1013/// }
1014/// ```
1015///
1016/// ## Integer Storage (Discriminants)
1017///
1018/// ```ignore
1019/// use drizzle::prelude::*;
1020///
1021/// #[derive(PostgresEnum, Default, Clone, PartialEq, Debug)]
1022/// enum Priority {
1023///     #[default]
1024///     Low = 1,    // Stored as 1
1025///     Medium = 5, // Stored as 5
1026///     High = 10,  // Stored as 10
1027/// }
1028///
1029/// #[PostgresTable(name = "tasks")]
1030/// struct Tasks {
1031///     #[serial(primary)]
1032///     id: i32,
1033///     #[integer(enum)]  // Stores discriminants as INTEGER
1034///     priority: Priority,
1035/// }
1036/// ```
1037///
1038/// ## Native PostgreSQL ENUM Type
1039///
1040/// PostgreSQL supports native ENUM types which are more efficient and type-safe:
1041///
1042/// ```ignore
1043/// use drizzle::prelude::*;
1044///
1045/// #[derive(PostgresEnum, Default, Clone, PartialEq, Debug)]
1046/// enum Color {
1047///     #[default]
1048///     Red,
1049///     Green,
1050///     Blue,
1051/// }
1052///
1053/// #[PostgresTable(name = "items")]
1054/// struct Items {
1055///     #[serial(primary)]
1056///     id: i32,
1057///     #[r#enum(Color)]  // Uses PostgreSQL native ENUM type
1058///     color: Color,
1059/// }
1060/// ```
1061///
1062/// ## Generated Implementations
1063///
1064/// The macro automatically implements:
1065/// - `std::fmt::Display` - For TEXT representation
1066/// - `TryFrom<i64>` - For INTEGER representation
1067/// - `Into<i64>` - For INTEGER representation
1068/// - `From<EnumType>` for `PostgresValue` - Database conversion
1069/// - `TryFrom<PostgresValue>` for `EnumType` - Database conversion
1070#[cfg(feature = "postgres")]
1071#[proc_macro_derive(PostgresEnum)]
1072pub fn postgres_enum_derive(input: TokenStream) -> TokenStream {
1073    use quote::quote;
1074    use syn::{Data, DeriveInput, parse_macro_input};
1075
1076    let input = parse_macro_input!(input as DeriveInput);
1077    let name = &input.ident;
1078
1079    // Check if this is an enum
1080    match &input.data {
1081        Data::Enum(data) => {
1082            // Check if the enum has any variants
1083            if data.variants.is_empty() {
1084                return quote! {
1085                    compile_error!("PostgresEnum cannot be derived for empty enums");
1086                }
1087                .into();
1088            }
1089
1090            // Generate implementation for enum
1091            match crate::postgres::r#enum::generate_enum_impl(name, data) {
1092                Ok(ts) => ts.into(),
1093                Err(e) => e.to_compile_error().into(),
1094            }
1095        }
1096        _ => quote! {
1097            compile_error!("PostgresEnum can only be derived for enums");
1098        }
1099        .into(),
1100    }
1101}
1102
1103/// Define a PostgreSQL table schema with type-safe column definitions.
1104///
1105/// This attribute macro transforms a Rust struct into a complete PostgreSQL table definition
1106/// with generated types for INSERT, SELECT, and UPDATE operations.
1107///
1108/// See [PostgreSQL CREATE TABLE documentation](https://www.postgresql.org/docs/current/sql-createtable.html) for
1109/// the underlying SQL concepts.
1110///
1111/// # Table Attributes
1112///
1113/// - `name = "table_name"` - Custom table name (defaults to struct name in snake_case)
1114/// - `unlogged` - Create UNLOGGED table for better performance  
1115/// - `temporary` - Create TEMPORARY table
1116/// - `if_not_exists` - Add IF NOT EXISTS clause
1117///
1118/// # Field Attributes
1119///
1120/// ## Column Types
1121/// - `#[integer]` - PostgreSQL INTEGER type
1122/// - `#[bigint]` - PostgreSQL BIGINT type
1123/// - `#[smallint]` - PostgreSQL SMALLINT type
1124/// - `#[serial]` - PostgreSQL SERIAL type (auto-increment)
1125/// - `#[bigserial]` - PostgreSQL BIGSERIAL type
1126/// - `#[text]` - PostgreSQL TEXT type
1127/// - `#[varchar(n)]` - PostgreSQL VARCHAR(n) type
1128/// - `#[real]` - PostgreSQL REAL type
1129/// - `#[double_precision]` - PostgreSQL DOUBLE PRECISION type
1130/// - `#[boolean]` - PostgreSQL BOOLEAN type
1131/// - `#[bytea]` - PostgreSQL BYTEA type (binary data)
1132/// - `#[uuid]` - PostgreSQL UUID type (requires `uuid` feature)
1133/// - `#[json]` - PostgreSQL JSON type (requires `serde` feature)
1134/// - `#[jsonb]` - PostgreSQL JSONB type (requires `serde` feature)
1135/// - `#[enum(MyEnum)]` - PostgreSQL native ENUM type
1136///
1137/// ## Constraints
1138/// - `primary` - Primary key constraint
1139/// - `unique` - Unique constraint
1140///
1141/// ## Defaults
1142/// - `default = value` - Compile-time default value
1143/// - `default_fn = function` - Runtime default function
1144///
1145/// ## Special Types
1146/// - `enum` - Store enum as TEXT or INTEGER (`#[text(enum)]` or `#[integer(enum)]`)
1147/// - `json` - JSON serialization (`#[text(json)]` or `#[jsonb]`)
1148/// - `references = Table::column` - Foreign key reference
1149///
1150/// # Examples
1151///
1152/// ## Basic Table
1153///
1154/// ```ignore
1155/// use drizzle::prelude::*;
1156///
1157/// #[PostgresTable(name = "users")]
1158/// struct Users {
1159///     #[serial(primary)]
1160///     id: i32,
1161///     #[text]
1162///     name: String,
1163///     #[text(unique)]
1164///     email: String,
1165///     #[integer]
1166///     age: Option<i32>,  // Nullable field
1167/// }
1168///
1169/// #[derive(PostgresSchema)]
1170/// struct Schema {
1171///     users: Users,
1172/// }
1173/// ```
1174///
1175/// ## Enums (Text, Integer, and Native)
1176///
1177/// ```ignore
1178/// use drizzle::prelude::*;
1179///
1180/// #[derive(PostgresEnum, Default, Clone, PartialEq, Debug)]
1181/// enum Status {
1182///     #[default]
1183///     Draft,
1184///     Published,
1185///     Archived,
1186/// }
1187///
1188/// #[derive(PostgresEnum, Default, Clone, PartialEq, Debug)]
1189/// enum Priority {
1190///     #[default]
1191///     Low,
1192///     Medium,
1193///     High,
1194/// }
1195///
1196/// #[PostgresTable(name = "posts")]
1197/// struct Posts {
1198///     #[serial(primary)]
1199///     id: i32,
1200///     #[text]
1201///     title: String,
1202///     #[text(enum)]       // Store as TEXT: "Draft", "Published", etc.
1203///     status: Status,
1204///     #[r#enum(Priority)] // Native PostgreSQL ENUM type
1205///     priority: Priority,
1206/// }
1207/// ```
1208///
1209/// ## JSON and JSONB
1210///
1211/// ```ignore
1212/// use drizzle::prelude::*;
1213/// use serde::{Serialize, Deserialize};
1214///
1215/// #[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Default)]
1216/// struct Metadata {
1217///     theme: String,
1218///     notifications: bool,
1219/// }
1220///
1221/// #[PostgresTable(name = "settings")]
1222/// struct Settings {
1223///     #[serial(primary)]
1224///     id: i32,
1225///     #[jsonb]  // Binary JSON for faster queries
1226///     config: Metadata,
1227///     #[json]   // Standard JSON
1228///     raw_data: Option<serde_json::Value>,
1229/// }
1230/// ```
1231///
1232/// # Generated Types
1233///
1234/// For a table `Users`, the macro generates:
1235/// - `SelectUsers` - For SELECT operations (derives `FromRow`)
1236/// - `InsertUsers` - Builder for INSERT operations with `new()` and `with_*()` methods
1237/// - `UpdateUsers` - Builder for UPDATE operations with `set_*()` methods
1238///
1239/// # Nullability
1240///
1241/// Use `Option<T>` for nullable fields. Non-optional fields get a NOT NULL constraint.
1242#[cfg(feature = "postgres")]
1243#[allow(non_snake_case)]
1244#[proc_macro_attribute]
1245pub fn PostgresTable(attr: TokenStream, item: TokenStream) -> TokenStream {
1246    let input = syn::parse_macro_input!(item as syn::DeriveInput);
1247    let attr_result = syn::parse_macro_input!(attr as crate::postgres::table::TableAttributes);
1248
1249    match crate::postgres::table::table_attr_macro(input, attr_result) {
1250        Ok(tokens) => tokens.into(),
1251        Err(err) => err.to_compile_error().into(),
1252    }
1253}
1254
1255/// Attribute macro for creating PostgreSQL indexes.
1256///
1257/// This macro generates PostgreSQL-specific index definitions with support for
1258/// various PostgreSQL index features.
1259///
1260/// # Attributes
1261///
1262/// - `unique` - Create a unique index
1263/// - No attributes for standard index
1264///
1265/// # Examples
1266///
1267/// ## Unique Index
1268///
1269/// ```ignore
1270/// use drizzle::prelude::*;
1271///
1272/// #[PostgresTable(name = "users")]
1273/// struct Users {
1274///     #[serial(primary)]
1275///     id: i32,
1276///     #[text]
1277///     email: String,
1278/// }
1279///
1280/// #[PostgresIndex(unique)]
1281/// struct UserEmailIdx(Users::email);
1282///
1283/// #[derive(PostgresSchema)]
1284/// struct Schema {
1285///     users: Users,
1286///     user_email_idx: UserEmailIdx,
1287/// }
1288/// ```
1289///
1290/// ## Composite Index
1291///
1292/// ```ignore
1293/// use drizzle::prelude::*;
1294///
1295/// #[PostgresTable(name = "users")]
1296/// struct Users {
1297///     #[serial(primary)]
1298///     id: i32,
1299///     #[text]
1300///     email: String,
1301///     #[integer]
1302///     organization_id: i32,
1303/// }
1304///
1305/// #[PostgresIndex(unique)]
1306/// struct UserOrgIdx(Users::email, Users::organization_id);
1307/// ```
1308#[cfg(feature = "postgres")]
1309#[allow(non_snake_case)]
1310#[proc_macro_attribute]
1311pub fn PostgresIndex(attr: TokenStream, item: TokenStream) -> TokenStream {
1312    let input = syn::parse_macro_input!(item as syn::DeriveInput);
1313    let attr_input = syn::parse_macro_input!(attr as crate::postgres::index::IndexAttributes);
1314
1315    match crate::postgres::index::postgres_index_attr_macro(attr_input, input) {
1316        Ok(tokens) => tokens.into(),
1317        Err(err) => err.to_compile_error().into(),
1318    }
1319}