Skip to main content

easy_sql/
lib.rs

1#![cfg_attr(docsrs, feature(doc_cfg))]
2
3// Compile README.docify.md to README.md
4#[cfg(feature = "_generate_readme")]
5docify::compile_markdown!("README.docify.md", "README.md");
6
7mod database_structs;
8pub mod markers;
9mod traits;
10
11mod drivers;
12pub use drivers::*;
13
14pub use {
15    database_structs::{Connection, EasySqlTables, PoolTransaction, Transaction},
16    traits::{
17        DatabaseSetup, Driver, EasyExecutor, EasyExecutorInto, Insert, Output, Table, ToDefault,
18        Update,
19    },
20};
21#[allow(rustdoc::broken_intra_doc_links)]
22/// Driver-facing traits and helper types.
23///
24/// This module re-exports the low-level driver traits and capability markers used when
25/// implementing a custom backend. Most application code will use the concrete drivers (like
26/// [`Postgres`] or [`Sqlite`]) rather than these internals.
27pub mod driver {
28    pub use crate::database_structs::{AlterTable, AlterTableSingle, TableField};
29    pub use crate::markers::driver::*;
30    pub use crate::traits::{
31        DriverArguments, DriverConnection, DriverQueryResult, DriverRow, DriverTypeInfo,
32        InternalDriver, SetupSql,
33    };
34    /// Implement a built-in SQL function support marker for specific argument counts.
35    ///
36    /// This macro is intended for **custom drivers** to opt into the built-in SQL functions that
37    /// [`query!`](crate::query)/[`query_lazy!`](crate::query_lazy) validate at compile time (e.g.
38    /// `COUNT`, `SUBSTRING`, `DATE`). See [`supported`](crate::driver::supported) for which functions are available.
39    ///
40    /// ## Syntax
41    /// ```rust,ignore
42    /// impl_supports_fn!(DriverType, SupportsTrait, arg_count0, arg_count1, ...);
43    /// ```
44    ///
45    /// - `SupportsTrait` comes from [`crate::markers::functions`] (for example [`SupportsCount`](crate::driver::SupportsCount)).
46    /// - Provide one or more argument counts.
47    /// - Use `-1` for functions that appear without parentheses (like `CURRENT_TIMESTAMP`).
48    /// - Use [`impl_supports_fn_any`] for variadic functions.
49    /// - For custom SQL functions (not built-ins), use [`custom_sql_function!`](crate::custom_sql_function).
50    ///
51    /// ## Example
52    #[doc = docify::embed!(
53		"src/tests/general/documentation/impl_supports_fn_macro.rs",
54		impl_supports_fn_basic_example
55	)]
56    pub use easy_sql_macros::impl_supports_fn;
57    /// Implement a built-in SQL function support marker for any argument count.
58    ///
59    /// Useful for variadic functions like `COALESCE` or `CONCAT`. This macro implements the
60    /// corresponding marker trait for all `const ARGS: isize` counts, so
61    /// [`query!`](crate::query)/[`query_lazy!`](crate::query_lazy) accept any number of arguments.  
62    /// See [`supported`](crate::driver::supported) for which functions are available.
63    ///
64    /// ## Syntax
65    /// ```rust,ignore
66    /// impl_supports_fn_any!(DriverType, SupportsTrait);
67    /// ```
68    ///
69    /// ## Example
70    #[doc = docify::embed!(
71		"src/tests/general/documentation/impl_supports_fn_macro.rs",
72		impl_supports_fn_any_example
73	)]
74    pub use easy_sql_macros::impl_supports_fn_any;
75}
76
77pub mod supported;
78
79#[cfg(test)]
80mod tests;
81
82#[doc(hidden)]
83pub mod macro_support;
84
85/// Type-safe SQL macro that builds and executes a query with compile-time checks.
86///
87/// Validates table/column names, binds arguments, and executes immediately, returns awaitable [anyhow](https://crates.io/crates/anyhow)::Result.
88///
89/// Notes:
90/// - For INSERT/UPDATE/DELETE without `RETURNING`, the output is driver-specific (generally the
91/// number of rows affected).
92/// - Input syntax highlighting is applied in IDE's, but on documentation page it is not.
93///
94/// ## Syntax
95/// ```rust,ignore
96/// query!(<Driver> conn, SQL)
97/// ```
98///
99/// - `<Driver>` is optional, if omitted the driver is inferred from `conn`.
100/// - `conn` is generally a connection or transaction implementing [`EasyExecutor`], available for
101///   mutable easy-sql connections/transactions and compatible sqlx executor types. The macro generates
102///   a mutable borrow internally.
103///
104///  Example:
105#[doc = docify::embed!("src/tests/general/documentation/query_macro.rs", query_basic_example)]
106///
107/// - SQL keywords are case-insensitive.
108/// - `{value}` inserts an external Rust value as a bound argument.
109/// - See below for more info about the accepted SQL.
110///
111/// ## Query forms
112///
113/// ### SELECT
114/// `SELECT OutputType FROM TableType ...` returns `OutputType`, a single row implementing [`Output`].
115/// The `Output` trait also covers `Vec<T>` and `Option<T>` for multiple or optional rows.
116#[doc = docify::embed!("src/tests/general/documentation/query_macro.rs", select_examples)]
117///
118/// Use `Table.column` or `OutputType.column` for column references. With the
119/// `use_output_columns` feature, bare column names are validated against the output type instead of the Table type.
120#[doc = docify::embed!("src/tests/general/documentation/query_macro.rs", select_output_columns_example)]
121///
122/// Accepted Clauses: `WHERE`, `GROUP BY`, `HAVING`, `ORDER BY`, `LIMIT`, `DISTINCT`
123///
124/// ### INSERT
125/// `INSERT INTO TableType VALUES {data}` inserts one value or a collection. `{data}` must implement [`Insert`].
126#[doc = docify::embed!("src/tests/general/documentation/query_macro.rs", insert_example)]
127///
128/// Use `RETURNING OutputType` to return inserted data, OutputType needs to implement [`Output`].
129#[doc = docify::embed!("src/tests/general/documentation/query_macro.rs", insert_returning_example)]
130///
131///
132/// ### UPDATE
133/// `UPDATE TableType SET {update}` uses a struct implementing [Update], or
134/// `SET field = value` for inline updates.
135#[doc = docify::embed!("src/tests/general/documentation/query_macro.rs", update_struct_example)]
136#[doc = docify::embed!("src/tests/general/documentation/query_macro.rs", update_inline_example)]
137///
138/// Use `RETURNING OutputType` to return rows, OutputType needs to implement [`Output`].
139#[doc = docify::embed!("src/tests/general/documentation/query_macro.rs", update_returning_example)]
140///
141/// Accepted Clauses: `WHERE`, `RETURNING`
142///
143/// ### DELETE
144/// `DELETE FROM TableType ...` removes rows.
145#[doc = docify::embed!("src/tests/general/documentation/query_macro.rs", delete_example)]
146///
147/// Use `RETURNING OutputType` to return rows, OutputType needs to implement [`Output`]
148#[doc = docify::embed!("src/tests/general/documentation/query_macro.rs", delete_returning_example)]
149///
150/// Accepted Clauses: `WHERE`, `RETURNING`
151///
152/// ### EXISTS
153/// `EXISTS TableType WHERE ...` returns `bool`.
154#[doc = docify::embed!("src/tests/general/documentation/query_macro.rs", exists_example)]
155///
156/// Accepted Clauses: `WHERE`, `GROUP BY`, `HAVING`, `ORDER BY`, `LIMIT`
157///
158/// ### Table joins
159/// Use [`table_join!`](crate::table_join) to define joins, then reference joined columns with
160/// `JoinedTable.column`.
161#[doc = docify::embed!("src/tests/general/documentation/query_macro.rs", table_joins_example)]
162///
163/// ### SQL functions
164/// Built-in functions (like `COUNT`, `SUM`, `LOWER`) are available, and custom ones can be
165/// registered with [`custom_sql_function!`](crate::custom_sql_function).
166#[doc = docify::embed!("src/tests/general/documentation/query_macro.rs", sql_function_builtin_example)]
167#[doc = docify::embed!("src/tests/general/documentation/query_macro.rs", sql_function_custom_example)]
168///
169/// ### `IN {vec}` parameter binding
170/// `IN {vec}` expands placeholders at runtime. The value must implement `IntoIterator` and
171/// `len()` (e.g., `Vec<T>`, `&[T]`). Use `IN {&vec}` if you need to reuse the collection.
172#[doc = docify::embed!("src/tests/general/documentation/query_macro.rs", in_vec_example)]
173///
174/// ## Generic connection
175/// `*conn` syntax might be needed when using `&mut EasyExecutor<D>` as connection
176#[doc = docify::embed!("src/tests/general/documentation/query_macro.rs", generic_connection_example)]
177pub use easy_sql_macros::query;
178
179/// Type-safe SQL macro that builds a lazy query and returns a stream on execution.
180///
181/// Like [`query!`], this macro validates table/column names and binds arguments at compile time,
182/// but it does **not** execute immediately. Instead it returns a lazy query builder that can be
183/// stored, moved, and executed later.
184///
185/// `?` (handling result) is required to build the lazy query.
186///
187/// ## Syntax
188/// ```rust,ignore
189/// query_lazy!(<Driver> SQL)
190/// ```
191///
192/// - `<Driver>` is optional; if omitted the default driver is taken from the build script via
193///   [`sql_build::build`](https://docs.rs/sql-build/latest/sql_build/fn.build.html).
194///   If multiple (or zero) defaults are configured, you must specify the driver explicitly.
195/// - Uses the same SQL syntax and helpers as [`query!`]
196/// - There is **no connection parameter** in the macro call; pass it when fetching.
197///
198/// ### Return value
199/// returns a `anyhow::Result<LazyQueryResult>` with the following method:
200/// - `fetch(impl EasyExecutorInto)`
201///     - with a generic `conn: &mut impl EasyExecutor`, use `fetch(&mut *conn)` when you need to
202///       use `conn` again later in the same scope
203///         - on the final use in that scope, `fetch(conn)` is valid and shorter
204///     - otherwise pass a connection or transaction directly (e.g., `fetch(conn)` or `fetch(&mut transaction)`)
205///
206/// Both return `futures::Stream<Item = anyhow::Result<Output>>`. The stream borrows the
207/// connection; drop or fully consume it before reusing the connection.
208///
209/// ### Output and query forms
210/// - Output must be a **single-row type** implementing [`Output`]. To return multiple rows,
211///   iterate/collect the stream yourself.
212/// - Supported query forms: `SELECT`, `INSERT`, `UPDATE`, `DELETE`.
213/// - `INSERT`/`UPDATE`/`DELETE` **must** include `RETURNING` (because results are streamed).
214/// - `EXISTS` is **not** supported; use [`query!`] instead.
215///
216/// ## Examples
217#[doc = docify::embed!("src/tests/general/documentation/query_lazy_macro.rs", query_lazy_basic_example)]
218#[doc = docify::embed!("src/tests/general/documentation/query_lazy_macro.rs", query_lazy_streaming_example)]
219#[doc = docify::embed!("src/tests/general/documentation/query_lazy_macro.rs", generic_executor_example)]
220pub use easy_sql_macros::query_lazy;
221
222/// Defines a SQL table schema.
223///
224/// Implements [`Table`], [`DatabaseSetup`], [`Output`], [`Insert`], and [`Update`] for the struct,
225/// for usage inside of `query!` macros. Table names default to the struct
226/// name converted to `snake_case`.
227///
228/// ## Basic usage
229#[doc = docify::embed!("src/tests/general/documentation/table_macro.rs", table_basic_example)]
230///
231/// ## Field attributes
232/// - `#[sql(primary_key)]` marks a column as part of the primary key.
233/// - `#[sql(auto_increment)]` enables auto-increment for the column (driver-dependent).
234/// - `#[sql(unique)]` adds a `UNIQUE` constraint.
235/// - `#[sql(default = expr)]` sets a column default (the expression is type-checked).
236/// - `#[sql(bytes)]` stores the field as a binary blob using [`bincode`](https://crates.io/crates/bincode) + [`serde`](https://crates.io/crates/serde).
237/// - `#[sql(foreign_key = TableStruct)]` creates a foreign key to another table.
238/// - `#[sql(foreign_key = TableStruct, cascade)]` enables `ON DELETE/UPDATE CASCADE`.
239///
240/// `Option<T>` fields are treated as nullable; all other fields are `NOT NULL` by default.
241///
242/// ### Foreign keys
243#[doc = docify::embed!("src/tests/general/documentation/table_macro.rs", table_foreign_key_example)]
244///
245/// ### Composite primary keys
246#[doc = docify::embed!(
247	"src/tests/general/documentation/table_macro.rs",
248	table_composite_primary_key_example
249)]
250///
251/// ## Table attributes
252/// - `#[sql(table_name = "...")]` overrides the generated `snake_case` name.
253/// - `#[sql(drivers = Driver1, Driver2)]` sets the supported drivers when no default driver is
254///   configured in the build script via
255///   [`sql_build::build`](https://docs.rs/sql-build/latest/sql_build/fn.build.html).
256/// - `#[sql(no_version)]` disables migrations for this table (feature `migrations`).
257/// - `#[sql(version = 1)]` enables migrations and sets the table version (feature `migrations`).
258/// - `#[sql(unique_id = "...")]` is auto generated and used by the build script for migration tracking.
259/// - `#[sql(version_test = 1)]` sets a temporary version for migration testing, requires `unique_id`.
260///
261/// ## Notes
262/// - Some drivers require at least one primary key; if none is specified, compilation will fail.
263/// - Auto-increment may be restricted when using composite primary keys, depending on the driver.
264/// - `#[sql(bytes)]` requires the field type to implement [`serde::Serialize`](https://docs.rs/serde/latest/serde/trait.Serialize.html)/[`Deserialize`](https://docs.rs/serde/latest/serde/trait.Deserialize.html).
265pub use easy_sql_macros::Table;
266
267/// Defines insertable data for a table.
268///
269/// Implements [`Insert`] for the `Struct` and `&Struct`, for use in [`query!`](crate::query) and [`query_lazy!`](crate::query_lazy).
270/// Field names map to table columns, and you can provide a subset of columns as long as the
271/// missing ones are declared as defaults.
272///
273/// ## Basic usage
274#[doc = docify::embed!("src/tests/general/documentation/insert_macro.rs", insert_basic_example)]
275///
276/// ## Defaults for omitted columns
277/// Use `#[sql(default = field1, field2)]` to declare table columns that are **not** present in the
278/// insert struct (for example, auto-increment primary keys or columns with SQL defaults). All
279/// omitted columns must be listed so the macro can validate the table schema at compile time.
280#[doc = docify::embed!("src/tests/general/documentation/insert_macro.rs", insert_defaults_example)]
281///
282/// ## Field attributes
283/// - `#[sql(bytes)]` must match `#[sql(bytes)]` on table struct, stores the field as a binary blob using [`bincode`](https://crates.io/crates/bincode) + [`serde`](https://crates.io/crates/serde).
284///
285/// ## Notes
286/// - `#[sql(table = TableStruct)]` is required and must point to a [`Table`] type.
287/// - You can insert a single value, borrow or a collection (`&T`, `Vec<T>`, `&Vec<T>`, `&[T]`).
288pub use easy_sql_macros::Insert;
289/// Defines a SQL output mapping.
290///
291/// Implements [`Output`] for the struct, enabling type-safe selection and decoding of rows in
292/// [`query!`] and [`query_lazy!`]. Column names are validated at compile time against the table
293/// or joined tables.
294///
295/// ## Basic usage
296#[doc = docify::embed!("src/tests/general/documentation/output_macro.rs", output_basic_example)]
297///
298/// ## Custom select expressions
299/// Use `#[sql(select = ...)]` to map a field to a SQL expression. The expression is emitted into
300/// the `SELECT` list with an alias matching the field name.
301#[doc = docify::embed!("src/tests/general/documentation/output_macro.rs", output_custom_select_example)]
302///
303/// ### Custom select arguments
304/// Use `{arg0}`, `{arg1}`, ... inside `#[sql(select = ...)]` and pass arguments in the query as
305/// `SELECT OutputType(arg0, arg1) ...` or `RETURNING OutputType(arg0, arg1)`.
306#[doc = docify::embed!("src/tests/general/documentation/output_macro.rs", output_custom_select_args_example)]
307///
308/// ## Joined output fields
309/// For [`table_join!`](crate::table_join) results, map fields to joined columns with `#[sql(field = Table.column)]` or `#[sql(select = ...)]`.
310#[doc = docify::embed!("src/tests/general/documentation/output_macro.rs", output_joined_fields_example)]
311///
312/// ## Field attributes
313/// - `#[sql(select = ...)]` maps the field to a custom SQL expression.
314/// - `#[sql(field = Table.column)]` maps the field to a joined table column.
315/// - `#[sql(bytes)]` decodes the field from binary data (matches table field settings).
316///
317/// ## Table attributes
318/// - `#[sql(table = TableStruct)]` is required and sets the base table for validation.
319///
320/// ## Notes
321/// - Output structs represent a **single row**; wrap in `Vec<T>` or `Option<T>` for multiple or
322///   optional rows.
323/// - With `use_output_columns`, you can reference `OutputType.column` (or bare columns) in
324///   `query!` expressions.
325/// - Custom select arguments must be sequential (`arg0`, `arg1`, ...).
326pub use easy_sql_macros::Output;
327
328/// Defines update data for a table.
329///
330/// Implements [`Update`] for the struct and `&Struct`, for use in [`query!`](crate::query) and
331/// [`query_lazy!`](crate::query_lazy). Field names map to table columns, and only the fields you
332/// define are updated. `Option<T>` values are bound as-is, so `None` sets the column to `NULL`.
333///
334/// ## Basic usage
335#[doc = docify::embed!("src/tests/general/documentation/update_macro.rs", update_basic_example)]
336///
337/// ## Partial updates
338/// Define a smaller update struct to update a subset of columns. Use `&data` if you need to reuse
339/// the update payload for multiple queries.
340#[doc = docify::embed!("src/tests/general/documentation/update_macro.rs", update_partial_example)]
341///
342/// ## Field attributes
343/// - `#[sql(bytes)]` must match `#[sql(bytes)]` on the table struct, stores the field as a binary
344///   blob using [`bincode`](https://crates.io/crates/bincode) + [`serde`](https://crates.io/crates/serde).
345/// - `#[sql(maybe_update)]` / `#[sql(maybe)]` marks an `Option<T>` field as optional: `None` skips the update while
346///   `Some(value)` updates the column. For nullable columns you can also use `Option<Option<T>>`
347///   to allow `Some(None)` to set `NULL`.
348///
349/// ## Notes
350/// - `#[sql(table = TableStruct)]` is required and must point to a [`Table`] type.
351pub use easy_sql_macros::Update;
352
353/// Composes database structure from nested types.
354///
355/// Implements [`DatabaseSetup`] by calling `setup` on each field (in order), which makes it easy
356/// to group tables or other setup structs into reusable schemas.
357///
358/// - Works with named **or tuple** structs.
359/// - Use `#[sql(drivers = Driver1, Driver2)]` to select supported drivers when no defaults are
360///   configured in the build script via
361///   [`sql_build::build`](https://docs.rs/sql-build/latest/sql_build/fn.build.html).
362/// - Errors include the field name and type to help trace failing setup calls.
363///
364/// ## Basic usage
365#[doc = docify::embed!(
366	"src/tests/general/documentation/database_setup_macro.rs",
367	database_setup_basic_example
368)]
369///
370/// ## Nested setup groups
371#[doc = docify::embed!(
372	"src/tests/general/documentation/database_setup_macro.rs",
373	database_setup_nested_example
374)]
375///
376/// ## Notes
377/// - Every field must implement [`DatabaseSetup`] for the selected driver(s).
378/// - Setup order follows field order;
379pub use easy_sql_macros::DatabaseSetup;
380
381/// Defines a joined table type for use in [`query!`](crate::query) and [`query_lazy!`](crate::query_lazy).
382///
383/// `table_join!` creates a lightweight type that implements [`Table`] with a generated join clause.
384/// Use it as the table name in queries and as the `#[sql(table = ...)]` target for [`Output`].
385///
386/// ## Syntax
387/// ```rust,ignore
388/// table_join!(<Driver1, Driver2> JoinedTableStructName | TableA INNER JOIN TableB ON TableA.id = TableB.a_id)
389/// ```
390///
391/// - The driver list is optional; when omitted, default drivers from the build script via
392///   [`sql_build::build`](https://docs.rs/sql-build/latest/sql_build/fn.build.html) are used.
393/// - Supported join types: `INNER JOIN`, `LEFT JOIN`, `RIGHT JOIN`, `CROSS JOIN`.
394/// - `CROSS JOIN` omits the `ON` clause.
395/// - Multiple joins can be chained after the main table.
396///
397/// ## Output mapping
398/// - Use `#[sql(field = Table.column)]` or `#[sql(select = ...)]` in [`Output`] structs.
399/// - `LEFT JOIN` makes the joined table optional; map its fields as `Option<T>`.
400/// - `RIGHT JOIN` makes tables to the **left** optional; map their fields as `Option<T>`.
401///
402/// ## Examples
403#[doc = docify::embed!(
404	"src/tests/general/documentation/table_join_macro.rs",
405	table_join_basic_example
406)]
407#[doc = docify::embed!(
408	"src/tests/general/documentation/table_join_macro.rs",
409	table_join_left_example
410)]
411pub use easy_sql_macros::table_join;
412
413/// Define a custom SQL function for use in [`query!`](crate::query) and [`query_lazy!`](crate::query_lazy).
414///
415/// Registers a SQL function name and argument-count validation so the query macros can parse
416/// calls like `MyFunc(column, "arg")` and enforce argument counts at compile time.
417///
418/// ## Syntax
419/// ```rust,ignore
420/// custom_sql_function!(FunctionName; "SQL_FUNCTION_NAME"; 0 | 1 | 2 | Any);
421/// ```
422///
423/// - `FunctionName`: Rust identifier used to generate the macro name.
424/// - `"SQL_FUNCTION_NAME"`: SQL function name emitted in generated SQL.
425/// - `args`: Argument count specification:
426///   - A number (e.g., `2`) for exact argument count
427///   - Multiple numbers separated by `|` (e.g., `1 | 2`) for multiple allowed counts
428///   - `Any` for any number of arguments
429///
430/// ## Examples
431#[doc = docify::embed!(
432	"src/tests/general/documentation/custom_sql_function_macro.rs",
433	custom_sql_function_basic_example
434)]
435#[doc = docify::embed!(
436	"src/tests/general/documentation/custom_sql_function_macro.rs",
437	custom_sql_function_multiple_args_example
438)]
439#[doc = docify::embed!(
440	"src/tests/general/documentation/custom_sql_function_macro.rs",
441	custom_sql_function_any_args_example
442)]
443///
444/// ## Notes
445/// - Function names are case-insensitive in queries, but the emitted SQL name preserves casing.
446/// - The macro only validates SQL syntax; the function must exist in your database.
447/// - `Any` disables argument-count validation; otherwise invalid counts cause a compile-time error.
448pub use easy_sql_macros::custom_sql_function;