d1_orm/lib.rs
1//! # d1-orm
2//!
3//! A lightweight ORM and SQL builder for Rust, perfectly suited for Cloudflare D1 and SQLite.
4//!
5//! ## Features
6//!
7//! - **Backend Agnostic**: Bring your own database driver or use the built-in integrations for Cloudflare D1 (via `worker` crate) and SQLite (via `rusqlite`).
8//! - **Type-Safe SQL Builder**: `define_sql!` macro for type-safe parameter binding and zero-overhead declarative SQL queries.
9//! - **Model Definition**: `define_model!` macro for defining structs, mapping database models, and generating update structs automatically.
10//! - **WASM Compatible**: Works flawlessly within WASM targets like Cloudflare Workers (non-Send environments).
11//! - **Migration System**: Built-in generic `migrate` utility to effortlessly apply schema modifications.
12//! - **Async Trait**: Implements an ecosystem agnostic `DatabaseExecutor` trait for async database operations.
13//!
14//! ## Modules
15//!
16//! - `error`: Error types.
17//! - `types`: Core types like `DatabaseValue`.
18//! - `traits`: Core traits like `DatabaseExecutor`, `Query`.
19//! - `builder`: SQL builder functions.
20//! - `macros`: Helper macros.
21//!
22//! ## Backends
23//!
24//! - `d1`: Cloudflare D1 backend (requires `d1` feature).
25//! - `sqlite`: SQLite backend (requires `sqlite` feature).
26//!
27//! ## Example usage
28//!
29//! For a complete, runnable example using an in-memory SQL store, see [`examples/basic.rs`](https://github.com/Asutorufa/housou/blob/main/crates/d1-orm/examples/basic.rs).
30//!
31//! ```rust,no_run
32//! use d1_orm::sqlite::SqliteExecutor;
33//! use d1_orm::{build_update_sql, define_model, define_sql, DatabaseExecutor};
34//!
35//! // 1. Define your model and update struct
36//! define_model!(
37//! /// A user in the system
38//! User,
39//! UserField,
40//! UserUpdate {
41//! id: i32 [pk],
42//! username: String,
43//! email: String,
44//! }
45//! );
46//!
47//! // 2. Define your SQL queries
48//! define_sql!(
49//! MySql
50//!
51//! // Simple parameterized query
52//! GetUser { id: i32 } => "SELECT * FROM users WHERE id = ?",
53//!
54//! // Insert query with multiple parameters
55//! CreateUser { username: &'a str, email: &'a str } =>
56//! "INSERT INTO users (username, email) VALUES (?, ?)",
57//!
58//! // Dynamic update query using the generated UserUpdate enum
59//! UpdateUser { updates: Vec<UserUpdate> [skip_primary_key], id: i32 } =>
60//! build_update_sql("users", "id", &updates),
61//! );
62//!
63//! #[tokio::main]
64//! async fn main() -> Result<(), d1_orm::Error> {
65//! // 3. Initialize the database backend (SQLite in this case)
66//! let conn = rusqlite::Connection::open_in_memory().unwrap();
67//!
68//! conn.execute(
69//! "CREATE TABLE users (id INTEGER PRIMARY KEY, username TEXT NOT NULL, email TEXT NOT NULL)",
70//! [],
71//! ).unwrap();
72//!
73//! let executor = SqliteExecutor::new(conn);
74//!
75//! // 4. Execute queries using the type-safe builder
76//! executor.execute(MySql::CreateUser {
77//! username: "alice",
78//! email: "alice@example.com",
79//! }).await?;
80//!
81//! // 5. Query results into strongly-typed models
82//! let user: Option<User> = executor.query_first(MySql::GetUser { id: 1 }).await?;
83//! println!("Found user: {:?}", user);
84//!
85//! // 6. Dynamic Updates programmatically crafted
86//! executor.execute(MySql::UpdateUser {
87//! updates: vec![UserUpdate::email("alice.new@example.com".to_string())],
88//! id: 1,
89//! }).await?;
90//!
91//! Ok(())
92//! }
93//! ```
94
95pub mod builder;
96pub mod error;
97pub mod macros;
98pub mod migration;
99pub mod traits;
100pub mod types;
101
102#[cfg(feature = "d1")]
103pub mod d1;
104#[cfg(feature = "sqlite")]
105pub mod sqlite;
106
107pub use builder::{build_update_sql, build_upsert_sql, UpsertConfig};
108pub use error::Error;
109pub use migration::{migrate, Migration};
110pub use traits::{
111 DatabaseExecutor, FieldMeta, FieldUpdate, IntoResultCow, MigrationInfo, MigrationMeta, Query,
112 QueryExt, SqlBackend, ToParams,
113};
114pub use types::DatabaseValue;