### Clorinde CLI Command Examples Source: https://halcyonnouveau.github.io/clorinde/print Demonstrates the usage of the Clorinde CLI for different database management and code generation workflows. Includes examples for `schema`, `live`, and `fresh` commands with various options. ```bash # Using schema command with container management clorinde schema schema.sql # Using live command with existing database clorinde live postgresql://user:pass@localhost/mydb # Using fresh command with existing server clorinde fresh schema.sql --url postgresql://user:pass@localhost # Using fresh command with custom database name and search path clorinde fresh schema.sql --url postgresql://user:pass@localhost \ --db-name my_temp_db \ --search-path public,custom_schema ``` -------------------------------- ### Clorinde CLI Command Examples Source: https://halcyonnouveau.github.io/clorinde/using_clorinde/cli Demonstrates the usage of Clorinde's `schema`, `live`, and `fresh` commands with various options for database connection and configuration. ```bash clorinde schema schema.sql # Using live command with existing database clorinde live postgresql://user:pass@localhost/mydb # Using fresh command with existing server clorinde fresh schema.sql --url postgresql://user:pass@localhost # Using fresh command with custom database name and search path clorinde fresh schema.sql --url postgresql://user:pass@localhost \ --db-name my_temp_db \ --search-path public,custom_schema ``` -------------------------------- ### TOML: Static File Organization Example Source: https://halcyonnouveau.github.io/clorinde/configuration This TOML example demonstrates organizing static files into subdirectories and renaming them. It copies `LICENSE` as-is, renames `template.env` to `.env.example`, moves `api.md` to `documentation/`, and places `build.sh` in `tools/`. ```toml static = [ # Copy LICENSE to root as-is "LICENSE", # Rename during copy { path = "template.env", destination = ".env.example" }, # Organize into subdirectories { path = "docs/api.md", destination = "documentation/api.md" }, { path = "scripts/build.sh", destination = "tools/build.sh" } ] ``` -------------------------------- ### Clorinde TOML for Publishing Generated Crates Source: https://halcyonnouveau.github.io/clorinde/introduction/migration_from_cornucopia This example demonstrates how to use a `clorinde.toml` file to configure the `Cargo.toml` of a generated Clorinde query crate. This is necessary for publishing crates with path dependencies, allowing customization of the package metadata like name, version, and license. ```toml [manifest.package] name = "my-clorinde-queries" version = "0.1.0" license = "MIT" homepage = "https://github.com/furina/my-repo" repository = "https://github.com/furina/my-repo" publish = true ``` -------------------------------- ### Cargo.toml Dependency for Clorinde Crate Source: https://halcyonnouveau.github.io/clorinde/print Example of how to add the generated Clorinde crate as a dependency in your project's `Cargo.toml` file. This allows you to import and use the generated query items. ```toml [dependencies] clorinde = { path = "clorinde" } ``` -------------------------------- ### Clorinde Error Reporting Example Source: https://halcyonnouveau.github.io/clorinde/print Illustrates Clorinde's error reporting mechanism, specifically for unknown fields when declaring nullable fields. It shows a compile-time error message with the error location, a hint, and suggestions for correct field names. ```sql --! author: (age?) SELECT * FROM author; ``` -------------------------------- ### Selecting Rows with Clorinde Query Execution Methods Source: https://halcyonnouveau.github.io/clorinde/using_queries/using_queries Provides examples of using Clorinde's methods to select a specific number of rows from query results: `opt` (one or zero), `one` (exactly one), `iter` (iterator), and `all` (collects into a Vec). ```rust #![allow(unused)] fn main() { author_by_id().bind(&client, &0).opt().await?; author_by_id().bind(&client, &0).one().await?; // Error if this author id doesn't exist authors().bind(&client).all().await?; authors().bind(&client).iter().await?.collect::>(); // Acts the same as the previous line } ``` -------------------------------- ### Rust: Bind Parameter Example with String Types Source: https://halcyonnouveau.github.io/clorinde/using_queries/ergonomic_parameters Demonstrates how Clorinde's umbrella traits allow passing different string-like types (like &str and String) as bind parameters to a SQL query. This enhances flexibility by not requiring strict type adherence for string inputs. ```rust #![allow(unused)] fn main() { authors_by_first_name.bind(&client, &"John").all(); // This works authors_by_first_name.bind(&client, &String::from("John")).all(); // This also works } ``` -------------------------------- ### Transform Query Results with map() (Rust) Source: https://halcyonnouveau.github.io/clorinde/print Illustrates using the `map` method on Clorinde query objects to transform returned rows without intermediate allocations. This example shows mapping author data into a `CustomAuthor` struct with a custom `Country` enum, demonstrating inline data transformation. ```rust #![allow(unused)] fn main() { enum Country { Greece, TheRest } impl<'a> From<&'a str> for Country { fn from(s: &'a str) -> Self { if s == "Greece" { Self::Greece } else { Self::TheRest } } } struct CustomAuthor { full_name: String, country: Country, age: usize, } authors() .bind(&client) .map(|author| { let full_name = format!( "{:.2}, {}", author.last_name.to_uppercase(), author.first_name ); let country = Country::from(author.country); CustomAuthor { full_name, country, age: author.age, } }); } ``` -------------------------------- ### Rust: Accessing Row Struct Field Metadata Source: https://halcyonnouveau.github.io/clorinde/configuration This example shows how to obtain and use the static field metadata from a specific row struct, `clorinde::queries::lock_info::LockInfo`. The metadata can be cast to a static slice of `FieldMetadata` for further processing. ```rust #![allow(unused)] fn main() { let meta: &'static [clorinde::types::FieldMetadata] = clorinde::queries::lock_info::LockInfo::field_metadata(); } ``` -------------------------------- ### Define and Use Type Annotations for Structs Source: https://halcyonnouveau.github.io/clorinde/writing_queries/type_annotations Declare custom structs using the '--:' syntax, specifying nullable columns. These types can be reused across multiple queries. The example defines an 'Author' struct and uses it for two different SELECT statements. ```SQL --: Author(age?) --! authors : Author SELECT name, age FROM authors; --! authors_from_country (country?) : Author SELECT name, age FROM authors WHERE authors.nationality = :country; ``` -------------------------------- ### Transforming Query Results with `map()` in Clorinde Source: https://halcyonnouveau.github.io/clorinde/using_queries/using_queries Shows how to use the `map()` method on Clorinde query objects to transform returned rows without intermediate allocation. This example defines a custom `Country` enum and `CustomAuthor` struct to restructure author data. ```rust #![allow(unused)] fn main() { enum Country { Greece, TheRest } impl<'a> From<&'a str> for Country { fn from(s: &'a str) -> Self { if s == "Greece" { Self::Greece } else { Self::TheRest } } } struct CustomAuthor { full_name: String, country: Country, age: usize, } authors() .bind(&client) .map(|author| { let full_name = format!( "{}, {}", author.last_name.to_uppercase(), author.first_name ); let country = Country::from(author.country); CustomAuthor { full_name, country, age: author.age, } }); } ``` -------------------------------- ### Apply Derive Traits to Specific PostgreSQL Types Source: https://halcyonnouveau.github.io/clorinde/print Allows specifying derive traits for particular custom PostgreSQL types, offering more granular control than global settings. This example adds `serde::Deserialize` only to the `fontaine_region` type. PostgreSQL type names are case-insensitive unless quoted. ```TOML [types] # Applied to all generated structs and postgres types derive-traits = ["Default"] [types.type-traits-mapping] # Applied to specfic custom postgres types (eg. enums, domains, composites) fontaine_region = ["serde::Deserialize"] ``` -------------------------------- ### Rust: Get Field Metadata for a Row Struct Source: https://halcyonnouveau.github.io/clorinde/configuration This function demonstrates how to retrieve static field metadata for a given row struct. The metadata includes the field's name, Rust type, and PostgreSQL type. This is useful for dynamically inspecting database schema information at runtime. ```rust #![allow(unused)] fn main() { pub fn field_metadata() -> &'static [FieldMetadata] } ``` -------------------------------- ### TOML: Advanced Static File Configuration Source: https://halcyonnouveau.github.io/clorinde/configuration This TOML configuration showcases advanced static file handling, including renaming files, placing them in subdirectories, and using hard links. It demonstrates copying `README.md` to the root, renaming `config.template.toml` to `config.toml`, placing `logo.png` in `static/images/`, and using hard links for large assets. ```toml static = [ # Simple copy (copies to root with original filename) "README.md", # Rename file during copy { path = "config.template.toml", destination = "config.toml" }, # Place file in subdirectory { path = "assets/logo.png", destination = "static/images/logo.png" }, # Hard link instead of copy (saves disk space for large files) { path = "large_asset.bin", "hard-link" = true }, # Combine renaming with hard linking { path = "data.json", destination = "resources/app_data.json", "hard-link" = true } ] ``` -------------------------------- ### Configure Static File Copying with Renaming and Subdirectories Source: https://halcyonnouveau.github.io/clorinde/print Provides advanced configuration for the `static` option, allowing files to be copied, renamed, placed in subdirectories, or hard-linked into the generated crate. This enhances flexibility for including assets and configurations. ```TOML static = [ # Simple copy (copies to root with original filename) "README.md", # Rename file during copy { path = "config.template.toml", destination = "config.toml" }, # Place file in subdirectory { path = "assets/logo.png", destination = "static/images/logo.png" }, # Hard link instead of copy (saves disk space for large files) { path = "large_asset.bin", hard-link = true }, # Combine renaming with hard linking { path = "data.json", destination = "resources/app_data.json", hard-link = true } ] ``` -------------------------------- ### Execute Queries with bind() or prepare() (Rust) Source: https://halcyonnouveau.github.io/clorinde/print Explains two execution strategies for Clorinde queries. The default `bind()` method handles statement preparation intelligently, caching when possible, making it ideal for most applications and connection pools. Explicit `prepare()` is for queries executed multiple times with varying parameters, offering better performance in specific scenarios without built-in caching. ```rust #![allow(unused)] fn main() { authors().bind(&client, Some("Greece")).all().await?; } ``` ```rust #![allow(unused)] fn main() { let prepared = authors().prepare(&client).await?; // Reuse the prepared statement multiple times for country in ["Greece", "Italy", "Spain"] { let results = prepared.bind(&client, Some(country)).all().await?; // Process results... } } ``` -------------------------------- ### Query Annotation with Documentation Comments Source: https://halcyonnouveau.github.io/clorinde/writing_queries/query_annotations Demonstrates adding documentation to Clorinde queries using `---` comments immediately after the query annotation. These comments are converted to Rust doc strings (///) in the generated code, providing descriptions of the query purpose and parameters. ```sql --! authors_from_country --- Finds all authors from a specific country. --- Parameters: --- country: The nationality to filter by SELECT id, name, age FROM authors WHERE authors.nationality = :country; ``` -------------------------------- ### TOML: Simple Static File Copy Source: https://halcyonnouveau.github.io/clorinde/configuration This TOML configuration defines a simple static file copy operation. It specifies an array of filenames to be copied directly into the root of the generated crate directory, such as `LICENSE.txt` and `build.rs`. ```toml # Simple copy of files to the root of the generated directory static = ["LICENSE.txt", "build.rs"] ``` -------------------------------- ### Configure Cargo.toml manifest for generated crate Source: https://halcyonnouveau.github.io/clorinde/configuration Configure the [manifest] section to customize the generated Cargo.toml including package metadata and dependencies. Clorinde automatically merges your custom configuration with required PostgreSQL dependencies based on SQL query types. ```toml [manifest.package] name = "furinapp-queries" version = "1.0.0" description = "Today I wanted to eat a *quaso*." license = "MIT" edition = "2021" [manifest.dependencies] serde = { version = "1.0", features = ["derive"] } my_custom_types = { path = "../types" } ``` -------------------------------- ### Building Query Objects with Clorinde Source: https://halcyonnouveau.github.io/clorinde/using_queries/using_queries Shows two methods for building Clorinde query objects: using the query function directly or using a generated parameter struct for more explicit parameter handling. Requires importing `clorinde::client::Params` trait for the `params` method. ```rust #![allow(unused)] fn main() { authors().bind(&client, Some("Greece")); } ``` ```rust #![allow(unused)] fn main() { use clorinde::{ client::Params, queries::{authors, AuthorsParams} }; authors().params( &client, AuthorsParams { country: Some("Greece") } ); } ``` -------------------------------- ### Executing Clorinde Queries with `bind()` Source: https://halcyonnouveau.github.io/clorinde/using_queries/using_queries Illustrates the default method for executing Clorinde queries using the `bind()` function. This method intelligently handles statement preparation, caching statements if the client supports it, or executing without preparation for one-off queries. Recommended for most applications, especially with connection pools. ```rust #![allow(unused)] fn main() { authors().bind(&client, Some("Greece")).all().await?; } ``` -------------------------------- ### Explicitly Preparing Clorinde Statements with `prepare()` Source: https://halcyonnouveau.github.io/clorinde/using_queries/using_queries Demonstrates how to explicitly prepare a Clorinde statement using the `prepare()` method. This is beneficial for queries executed multiple times with different parameters, offering better performance by ensuring the statement is prepared only once. Useful when not using a connection pool with built-in caching. ```rust #![allow(unused)] fn main() { let prepared = authors().prepare(&client).await?; // Reuse the prepared statement multiple times for country in ["Greece", "Italy", "Spain"] { let results = prepared.bind(&client, Some(country)).all().await?; // Process results... } } ``` -------------------------------- ### Clorinde Configuration for Serialization Source: https://halcyonnouveau.github.io/clorinde/using_clorinde/cli Shows how to configure Clorinde to derive `Serialize` for row types using a `clorinde.toml` file, which is the recommended approach over the deprecated `--serialize` flag. ```toml [types] derive-traits = ["serde::Serialize"] ``` -------------------------------- ### Basic Clorinde Query Annotation Source: https://halcyonnouveau.github.io/clorinde/writing_queries/query_annotations Demonstrates the simplest Clorinde query annotation syntax using the `--!` token followed by a query name. Clorinde automatically infers parameter types and return column types from the SQL schema, requiring only the query name in most cases. ```sql --! authors_from_country SELECT id, name, age FROM authors WHERE authors.nationality = :country; ``` -------------------------------- ### Build Query Object with Function or Struct (Rust) Source: https://halcyonnouveau.github.io/clorinde/print Demonstrates two methods for building a query object in Clorinde: using a query function like `authors()` or a generated parameter struct. The function approach is suitable for few parameters, while the struct is more explicit. Importing `clorinde::client::Params` is necessary for the `params` method. ```rust #![allow(unused)] fn main() { authors().bind(&client, Some("Greece")); } ``` ```rust #![allow(unused)] fn main() { use clorinde:: client::Params, queries::{authors, AuthorsParams}; authors().params( &client, AuthorsParams { country: Some("Greece") } ); } ``` -------------------------------- ### Importing Clorinde Queries in Rust Source: https://halcyonnouveau.github.io/clorinde/using_queries/using_queries Demonstrates how to import generated query modules from a Clorinde-generated Rust crate. Assumes the crate has been added to Cargo.toml. ```rust #![allow(unused)] fn main() { use clorinde::queries::authors; } ``` -------------------------------- ### Customizing Clorinde Type Mappings from Chrono to Time Source: https://halcyonnouveau.github.io/clorinde/introduction/migration_from_cornucopia This configuration snippet shows how to map PostgreSQL date and time types to the `time` crate instead of Clorinde's default `chrono` crate. This is achieved using the `[types.mapping]` section for direct type mapping and `[manifest.dependencies]` to include and configure the `time` crate and related features for `postgres` and `tokio-postgres`. ```toml [types.mapping] "pg_catalog.timestamp" = "time::PrimitiveDateTime" "pg_catalog.timestamptz" = "time::OffsetDateTime" "pg_catalog.time" = "time::Time" "pg_catalog.date" = "time::Date" [manifest.dependencies] time = { version = "0.3", features = ["serde"] } # enable the time feature of postgres and tokio-postgres postgres = { version = "0.19", features = [ "with-time-0_3", "with-serde_json-1", ] } tokio-postgres = { version = "0.7", features = [ "with-time-0_3", "with-serde_json-1", ] } ``` -------------------------------- ### Use Podman as Container Manager with `--podman` Flag Source: https://halcyonnouveau.github.io/clorinde/print Clorinde can utilize Podman as its container manager. This is enabled by passing the `-p` or `--podman` flag when running Clorinde. ```bash clorinde --podman your_queries.sql ``` -------------------------------- ### Clorinde Dependency Replacement for Cornucopia Source: https://halcyonnouveau.github.io/clorinde/introduction/migration_from_cornucopia This snippet shows how Clorinde simplifies dependencies compared to Cornucopia. Instead of listing individual crates like `postgres-types`, `cornucopia_async`, `tokio-postgres`, etc., Clorinde uses a single path dependency on the generated 'clorinde' crate. ```toml [dependencies] # Required postgres-types = { version = "*", features = ["derive"] } # Async cornucopia_async = { version = "*", features = ["with-serde_json-1"] } tokio = { version = "*", features = ["full"] } tokio-postgres = { version = "*", features = [ "with-serde_json-1", "with-time-0_3", "with-uuid-1", "with-eui48-1", ] } futures = "*" # Async connection pooling deadpool-postgres = { version = "*" } # Row serialization serde = { version = "*", features = ["derive"] } # Extra types serde_json = "*" time = "*" uuid = "*" eui48 = "*" rust_decimal = { version = "*", features = ["db-postgres"] } ``` ```toml [dependencies] clorinde = { path = "clorinde" } ``` -------------------------------- ### PostgreSQL to Rust Type Mappings Source: https://halcyonnouveau.github.io/clorinde/print This table outlines the direct mapping between PostgreSQL data types and their corresponding Rust types as supported by Clorinde. It covers primitive types, strings, byte arrays, timestamps, dates, times, JSON, UUIDs, IP addresses, MAC addresses, and decimals. ```markdown PostgreSQL type| Rust type ---|--- `bool`, `boolean`| `bool` `char`| `i8` `smallint`, `int2`, `smallserial`, `serial2`| `i16` `int`, `int4`, `serial`, `serial4`| `i32` `bigint`, `int8`, `bigserial`, `serial8`| `i64` `real`, `float4`| `f32` `double precision`, `float8`| `f64` `text`| `String` `varchar`| `String` `bpchar`| `String` `bytea`| `Vec` `timestamp without time zone`, `timestamp`| `chrono::NaiveDateTime` `timestamp with time zone`, `timestamptz`| `chrono::DateTime` `date`| `chrono::NaiveDate` `time`| `chrono::NaiveTime` `json`| `serde_json::Value` `jsonb`| `serde_json::Value` `uuid`| `uuid::Uuid` `inet`| `std::net::IpAddr` `macaddr`| `eui48::MacAddress` `numeric`| `rust_decimal::Decimal` ``` -------------------------------- ### Rust: Mapping Field Metadata to UI Headers Source: https://halcyonnouveau.github.io/clorinde/configuration This snippet illustrates mapping field metadata names to user-facing headers for a UI. It iterates over the metadata of `LockInfo` and collects the `name` field of each metadata entry. This approach ensures UI elements remain consistent with database schema changes. ```rust #![allow(unused)] fn main() { let headers: Vec<&str> = clorinde::queries::lock_info::LockInfo::field_metadata() .iter() .map(|m| m.name) .collect(); } ``` -------------------------------- ### Add Clorinde Dependency to Cargo.toml Source: https://halcyonnouveau.github.io/clorinde/using_clorinde/using_clorinde This snippet shows how to add the Clorinde crate as a local dependency in your project's Cargo.toml file. This is typically done after Clorinde has generated the necessary code for your queries. ```toml [dependencies] clorinde = { path = "clorinde" } ``` -------------------------------- ### Implement ToSql and FromSql Traits for Custom Types Source: https://halcyonnouveau.github.io/clorinde/print Provides a Rust code structure for implementing the `ToSql` and `FromSql` traits required for custom PostgreSQL types to be compatible with Clorinde and the `postgres-types` crate. ```Rust #![allow(unused)] fn main() { use postgres_types::{ToSql, FromSql}; impl ToSql for CustomType { // ... } impl FromSql for CustomType { // ... } } ``` -------------------------------- ### Select Expected Number of Rows (Rust) Source: https://halcyonnouveau.github.io/clorinde/print Shows how to select a specific number of rows from a Clorinde query result using methods like `opt` (one or zero), `one` (exactly one), `iter` (iterator), and `all` (collects into Vec). These methods are called after building and binding the query. ```rust #![allow(unused)] fn main() { author_by_id().bind(&client, &0).opt().await?; author_by_id().bind(&client, &0).one().await?; authors().bind(&client).all().await?; authors().bind(&client).iter().await?.collect::>(); } ``` -------------------------------- ### Query Annotation with Nullable Parameters and Columns Source: https://halcyonnouveau.github.io/clorinde/writing_queries/query_annotations Shows how to use the `?` syntax to specify nullable parameters and returned columns in Clorinde annotations. The question mark indicates that a parameter or column should be inferred as nullable (Option type in Rust), and can be applied to nested composite fields and array elements. ```sql --! authors_from_country (country?) : (age?) SELECT id, name, age FROM authors WHERE authors.nationality = :country; ``` ```sql --! example_query : (compos?.some_field?, arr?[?]) SELECT compos, arr FROM example ``` -------------------------------- ### Implement ToSql and FromSql traits for custom types Source: https://halcyonnouveau.github.io/clorinde/configuration Custom PostgreSQL types must implement the ToSql and FromSql traits from the postgres-types crate to enable proper serialization and deserialization with PostgreSQL's wire format. ```rust use postgres_types::{ToSql, FromSql}; impl ToSql for CustomType { // ... } impl FromSql for CustomType { // ... } ``` -------------------------------- ### Configure workspace dependencies integration Source: https://halcyonnouveau.github.io/clorinde/configuration Use the use-workspace-deps option to integrate the generated crate with workspace dependency management. When enabled, Clorinde sets workspace = true for dependencies found in the workspace manifest and falls back to regular declarations for others. ```toml # Use workspace dependencies from the current directory's Cargo.toml use-workspace-deps = true # Use workspace dependencies from a specific Cargo.toml use-workspace-deps = "../../Cargo.toml" ``` -------------------------------- ### Configure custom PostgreSQL type mappings Source: https://halcyonnouveau.github.io/clorinde/configuration Use the [types.mapping] section to map PostgreSQL types to custom Rust types, allowing you to override default mappings or add support for unsupported types from extensions. Custom types must implement ToSql and FromSql traits from postgres-types crate. ```toml [manifest.dependencies] ctypes = { path = "../ctypes" } postgres_range = { version = "0.11.1", features = ["with-chrono-0_4"] } [types.mapping] "pg_catalog.date" = "ctypes::date::Date" "pg_catalog.tstzrange" = "postgres_range::Range>" ``` -------------------------------- ### Generated Rust Function from Query Annotation Source: https://halcyonnouveau.github.io/clorinde/writing_queries/query_annotations Shows the Rust code generated from a Clorinde query annotation with documentation comments. The generated function includes doc comments converted from the `---` annotations and returns a query statement object. ```rust #![allow(unused)] fn main() { /// Finds all authors from a specific country. /// Parameters: /// country: The nationality to filter by pub fn authors_from_country() -> AuthorsFromCountryStmt { // ... } } ``` -------------------------------- ### Map PostgreSQL Types to Custom Rust Types Source: https://halcyonnouveau.github.io/clorinde/print Demonstrates how to map PostgreSQL data types to custom Rust types using the `types.mapping` configuration. This allows overriding default mappings or adding support for custom PostgreSQL types. Custom types must implement `ToSql` and `FromSql` traits. ```TOML "pg_catalog.date" = "ctypes::date::Date" "pg_catalog.tstzrange" = "postgres_range::Range>" ``` -------------------------------- ### Query Annotation with Custom Rust Attributes Source: https://halcyonnouveau.github.io/clorinde/writing_queries/query_annotations Illustrates using the `--#` syntax to add custom Rust attributes to generated query functions. These attributes can include deprecation warnings, conditional compilation directives, or any other valid Rust attributes, and must appear after the query annotation. ```sql --! authors_from_country --# deprecated = "Use authors_from_country_v2 instead" --# allow(dead_code) SELECT id, name, age FROM authors WHERE authors.nationality = :country; ``` -------------------------------- ### Enable field metadata generation for result-row structs Source: https://halcyonnouveau.github.io/clorinde/configuration Add the generate-field-metadata option to clorinde.toml to enable generation of lightweight metadata about each result-row struct. This is an opt-in feature. ```toml generate-field-metadata = true ``` -------------------------------- ### Generate Synchronous Code with `--sync` Flag Source: https://halcyonnouveau.github.io/clorinde/print By default, Clorinde generates asynchronous Rust code. The `--sync` flag can be used to instruct Clorinde to generate synchronous code instead. ```bash clorinde --sync your_queries.sql ``` -------------------------------- ### Define Custom Type Mappings with `[types.mapping]` Source: https://halcyonnouveau.github.io/clorinde/print Enables the definition of custom type mappings for PostgreSQL columns to Rust types. This section allows users to specify how specific database types should be represented in the generated Rust code, potentially requiring additional dependencies. ```toml [manifest.dependencies] # Dependencies required for custom type mappings ctypes = { path = "../ctypes" } postgres_range = { version = "0.11.1", features = ["with-chrono-0_4"] } [types.mapping] ``` -------------------------------- ### Generated Rust Function with Custom Attributes Source: https://halcyonnouveau.github.io/clorinde/writing_queries/query_annotations Demonstrates the resulting Rust code generated from a query annotation with custom `--#` attributes. The generated function includes the specified attributes decorating the public function definition. ```rust #![allow(unused)] fn main() { #[deprecated = "Use authors_from_country_v2 instead"] #[allow(dead_code)] pub fn authors_from_country() -> AuthorsFromCountryStmt { // ... } } ``` -------------------------------- ### Configure derive traits for generated structs Source: https://halcyonnouveau.github.io/clorinde/configuration Use the [types] derive-traits field to specify which traits should be derived for all generated structs. Adding serde traits automatically adds serde as a dependency in the package manifest. ```toml [types] derive-traits = ["serde::Serialize", "serde::Deserialize", "Hash"] ``` -------------------------------- ### Add Custom Attributes to Generated Query Functions in Rust Source: https://halcyonnouveau.github.io/clorinde/print Demonstrates how to use the `--#` syntax to add custom Rust attributes like deprecation warnings or conditional compilation directives to generated query functions. This allows for fine-grained control over the generated code. ```sql --! authors_from_country --# deprecated = "Use authors_from_country_v2 instead" --# allow(dead_code) SELECT id, name, age FROM authors WHERE authors.nationality = :country; ``` ```rust #![allow(unused)] fn main() { #[deprecated = "Use authors_from_country_v2 instead"] #[allow(dead_code)] pub fn authors_from_country() -> AuthorsFromCountryStmt { // ... } } ``` -------------------------------- ### Configure type-specific derive traits for PostgreSQL types Source: https://halcyonnouveau.github.io/clorinde/configuration Use [types.type-traits-mapping] for granular control to apply derive traits to specific custom PostgreSQL types (enums, domains, composites). These traits are merged with global derive-traits configuration. ```toml [types] derive-traits = ["Default"] [types.type-traits-mapping] fontaine_region = ["serde::Deserialize"] ``` -------------------------------- ### Define Inline Types for Single Queries Source: https://halcyonnouveau.github.io/clorinde/writing_queries/type_annotations Define types directly within the query using a compact syntax with parentheses for nullable columns. This is useful for simple, non-reusable type definitions. ```SQL --! authors_from_country (country?) : Author() SELECT id, name, age FROM authors WHERE authors.nationality = :country; ``` -------------------------------- ### Generated Rust Structs with Custom Attributes Source: https://halcyonnouveau.github.io/clorinde/writing_queries/type_annotations This Rust code shows the output of Clorinde's code generation based on the provided SQL type annotations and custom attributes. It includes both an owned `Author` struct and a borrowed `AuthorBorrowed` struct. ```Rust #![allow(unused)] fn main() { #[derive(Default, serde::Deserialize, PartialEq)] #[doc = "Represents an author in the system"] #[derive(Clone)] pub struct Author { pub name: String, pub age: Option, pub bio: String, } #[derive(Debug)] #[cfg_attr(feature = "graphql", derive(async_graphql::SimpleObject))] pub struct AuthorBorrowed<'a> { pub name: &'a str, pub age: Option, pub bio: &'a str, } } ``` -------------------------------- ### Access Field Metadata from Generated Structs Source: https://halcyonnouveau.github.io/clorinde/print Shows how to access the generated field metadata from a row struct. The `FieldMetadata` struct contains `name`, `rust_type`, and `pg_type`. Each row struct implements a `field_metadata()` method returning a slice of `FieldMetadata`. ```Rust #![allow(unused)] fn main() { pub fn field_metadata() -> &'static [FieldMetadata] } ``` ```Rust #![allow(unused)] fn main() { let meta: &'static [clorinde::types::FieldMetadata] = clorinde::queries::lock_info::LockInfo::field_metadata(); } ``` -------------------------------- ### Apply Custom Attributes to Owned and Borrowed Structs Source: https://halcyonnouveau.github.io/clorinde/writing_queries/type_annotations Use '--#' for owned struct attributes and '--&' for borrowed struct attributes to add Rust attributes like documentation or conditional compilation directives. This is particularly useful for types with non-`Copy` fields. ```SQL --: Author(age?, bio) : serde::Deserialize --# doc = "Represents an author in the system" --& cfg_attr(feature = "graphql", derive(async_graphql::SimpleObject)) --! authors : Author SELECT name, age, bio FROM authors; ``` -------------------------------- ### Add Custom Attributes to Generated Structs (Owned and Borrowed) in Rust Source: https://halcyonnouveau.github.io/clorinde/print Demonstrates using `--#` for owned struct attributes and `--&` for borrowed struct attributes to add documentation, conditional compilation, or other Rust attributes. This is useful when dealing with non-`Copy` fields that result in both owned and borrowed variants. ```sql --: Author(age?, bio) : serde::Deserialize --# doc = "Represents an author in the system" --& cfg_attr(feature = "graphql", derive(async_graphql::SimpleObject)) --! authors : Author SELECT name, age, bio FROM authors; ``` ```rust #![allow(unused)] fn main() { #[derive(Default, serde::Deserialize, PartialEq)] #[doc = "Represents an author in the system"] #[derive(Clone)] pub struct Author { pub name: String, pub age: Option, pub bio: String, } #[derive(Debug)] #[cfg_attr(feature = "graphql", derive(async_graphql::SimpleObject))] pub struct AuthorBorrowed<'a> { pub name: &'a str, pub age: Option, pub bio: &'a str, } } ``` -------------------------------- ### Add Derive Traits to Generated Structs Source: https://halcyonnouveau.github.io/clorinde/writing_queries/type_annotations Specify additional `#[derive]` traits for generated structs by appending them after the type annotation. This allows for easy integration with Rust's standard library and other crates. ```SQL --: Author(age?) : Default, serde::Deserialize --! authors : Author SELECT name, age FROM authors; ```