dbcli 0.1.0

Convert SQL query results to JSON without struct mapping, supporting MySQL/PostgreSQL/SQLite/Odbc
Documentation
//! # dbcli
//!
//! A utility library that automatically converts SQL query results (`sqlx` Row) into
//! [`serde_json::Value`] without requiring struct mappings.
//!
//! Supports generating JSON arrays directly from database query results, eliminating
//! the need to define structs manually. Suitable for dynamic queries, report exports,
//! and generic API scenarios.
//!
//! ## Supported Databases
//!
//! | Database    | Feature flag |
//! |------------|--------------|
//! | MySQL      | `mysql`      |
//! | PostgreSQL | `postgres`   |
//! | SQLite     | `sqlite`     |
//! | ODBC       | `odbc`       |
//!
//! ## Feature Flags
//!
//! Enable the corresponding feature in `Cargo.toml` as needed:
//!
//! ```toml
//! [dependencies]
//! dbcli = { path = "...", features = ["postgres"] }
//! # Or enable multiple features at once
//! dbcli = { path = "...", features = ["mysql", "sqlite"] }
//! ```
//!
//! Each feature automatically pulls in the corresponding `sqlx` driver and dependencies
//! such as `chrono` and `rust_decimal`:
//! - `mysql` / `postgres`: includes `chrono`, `rust_decimal`, `base64`, `encoding_rs`
//! - `sqlite`: includes only `base64` (SQLite dates are stored as TEXT, no chrono needed)
//! - `odbc`: includes `odbc-api`, `base64`, `encoding_rs`, `tokio` (requires system unixODBC)
//!
//! ## Quick Usage Example
//!
//! ```rust,no_run
//! use sqlx::PgPool;
//!
//! async fn query_to_json(pool: &PgPool) -> anyhow::Result<()> {
//!     use dbcli::to_json::postgres::to_json;
//!
//!     let rows = sqlx::query("SELECT id, name, created_at FROM users")
//!         .fetch_all(pool)
//!         .await?;
//!
//!     // data: Vec<serde_json::Value>, each element is a JSON object for one row
//!     // columns: Vec<ColumnBaseInfo>, containing column name, type, and index info
//!     let (data, columns) = to_json(rows)?;
//!     println!("{}", serde_json::to_string_pretty(&data)?);
//!     Ok(())
//! }
//! ```
//!
//! ## Custom Parsing Example
//!
//! By implementing the [`to_json::ToJsonCustomizer`] trait, you can override the default
//! conversion logic for specific types:
//!
//! ```rust,no_run
//! use dbcli::to_json::{ToJsonCustomizer, set_to_json_customizer};
//!
//! struct MyCustomizer;
//!
//! impl ToJsonCustomizer for MyCustomizer {
//!     #[cfg(feature = "postgres")]
//!     fn customize_pg(
//!         &self,
//!         type_name: &str,
//!     ) -> Option<fn(&sqlx::postgres::PgRow, usize) -> serde_json::Value> {
//!         match type_name {
//!             // Format TIMESTAMP as ISO 8601
//!             "TIMESTAMP" => Some(|row, idx| {
//!                 use sqlx::Row;
//!                 use chrono::NaiveDateTime;
//!                 match row.try_get::<Option<NaiveDateTime>, _>(idx) {
//!                     Ok(Some(dt)) => serde_json::Value::String(
//!                         dt.format("%Y-%m-%dT%H:%M:%S").to_string()
//!                     ),
//!                     _ => serde_json::Value::Null,
//!                 }
//!             }),
//!             _ => None,
//!         }
//!     }
//! }
//!
//! // Register globally once at application startup
//! fn init() {
//!     set_to_json_customizer(Box::new(MyCustomizer));
//! }
//! ```

pub mod to_json;

#[cfg(any(feature = "mysql", feature = "postgres", feature = "odbc"))]
pub mod decode;

pub mod column_info;

pub mod sql_result;
pub use sql_result::SqlResult;

pub mod execute;