#![allow(clippy::too_many_arguments)]
#![allow(clippy::type_complexity)]
#![allow(clippy::large_enum_variant)]

pub mod column;
pub mod condition;
pub mod driver;
pub mod error;
pub mod handler;
pub mod middleware;
pub mod model;
pub mod relation;
pub mod sql_fragment;
pub mod transaction;
pub mod types;
pub mod values;

#[cfg(feature = "postgres")]
#[doc(hidden)]
pub use tokio_postgres as __tokio_postgres;

/// Generates the `pg_row_converter()` override for Model, enabling direct PG row deserialization.
/// When the `postgres` feature is enabled, produces a function that converts `tokio_postgres::Row`
/// directly into the model struct via `PgGet`, bypassing the intermediate HashMap.
/// When the feature is disabled, expands to nothing.
#[cfg(feature = "postgres")]
#[doc(hidden)]
#[macro_export]
macro_rules! __pg_row_converter_impl {
    ($struct_name:ident, { $($field:ident => $col:expr),* $(,)? }, { $($default_field:ident),* $(,)? }) => {
        fn pg_row_converter() -> ::core::option::Option<fn(&$crate::__tokio_postgres::Row) -> ::core::option::Option<Self>> {
            fn __convert(row: &$crate::__tokio_postgres::Row) -> ::core::option::Option<$struct_name> {
                use $crate::model::PgGet;
                ::core::option::Option::Some($struct_name {
                    $($field: <_ as PgGet>::pg_get(row, $col)?,)*
                    $($default_field: ::core::default::Default::default(),)*
                })
            }
            ::core::option::Option::Some(__convert)
        }
    };
}

#[cfg(not(feature = "postgres"))]
#[doc(hidden)]
#[macro_export]
macro_rules! __pg_row_converter_impl {
    ($struct_name:ident, { $($field:ident => $col:expr),* $(,)? }, { $($default_field:ident),* $(,)? }) => {};
}

/// Prelude: import everything commonly needed.
pub mod prelude {
    pub use crate::column::{
        order_to_sql, Column, ColumnValue, ColumnValueKind, IntoCondition, NullsOrder,
        OrderDirection, OrderSpec,
    };
    pub use crate::condition::{
        compile_conditions, correlated_exists, exists, in_subquery, model_in_subquery,
        model_not_in_subquery, not_exists, not_in_subquery, or, CompiledCondition, Condition,
    };
    pub use crate::error::{Error, Result};
    pub use crate::handler::{
        DbHandler, DbHandlerBuilder, DbScope, Pool, TransactionExecutor, WriterExecutor,
    };
    pub use crate::middleware::{
        Middleware, MiddlewareChain, NextExecute, OperationType, RequestContext,
        StatisticsMiddleware,
    };
    pub use crate::model::{
        build_count_sql, build_delete_sql, build_insert_sql, build_select_sql, build_update_sql,
        count, create, create_many, delete, find, find_by_id, find_one, query, query_raw, update,
        update_many, ColumnMeta, Executor, FromRow, IntoColumnValues, Model,
    };
    #[cfg(feature = "postgres")]
    pub use crate::model::{FromPgRow, PgGet};
    pub use crate::relation::{
        batch_load_has_many, batch_load_has_many_composite, batch_load_one,
        batch_load_one_composite, column_list, group_by_key, hash_by_key, Relation, RelationBatch,
        RelationConfig, RelationMeta, RelationType,
    };
    pub use crate::sql_fragment::{SqlCondition, SqlFragment, SqlRaw, SqlRef};
    pub use crate::types::{
        with_query, CteClause, DbConfig, DbConfigOptions, DeleteOptions, DriverType, ExecuteResult,
        InsertOptions, LimitConfig, PkeyResult, SelectOptions, TransactionOptions,
        UpdateManyOptions, UpdateOptions,
    };
    pub use crate::values::{
        db_cast, db_cast_in, db_dynamic, db_false, db_immediate, db_in, db_not_null, db_now,
        db_null, db_raw, db_true, db_tuple_in, db_tuple_in_pg, db_uuid, db_uuid_in, parent_ref,
        FromValue, Value,
    };

    pub use litedbmodel_macros::sql;
    pub use litedbmodel_macros::Model;

    pub use crate::conds;
    pub use crate::opts;
    pub use crate::or;
    pub use crate::set;
}
