Skip to main content

easy_sql/
lib.rs

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