prax_query/lib.rs
1//! # prax-query
2//!
3//! Type-safe query builder for the Prax ORM.
4//!
5//! This crate provides the core query building functionality, including:
6//! - Fluent API for building queries (`find_many`, `find_unique`, `create`, `update`, `delete`)
7//! - Type-safe filtering with `where` clauses
8//! - Sorting and pagination
9//! - Relation loading (`include`, `select`)
10//! - Transaction support
11//! - Raw SQL escape hatch
12//! - Middleware system
13//! - Multi-tenant support
14//!
15//! ## Filters
16//!
17//! Build type-safe filters for queries:
18//!
19//! ```rust
20//! use prax_query::{Filter, FilterValue};
21//!
22//! // Equality filter
23//! let filter = Filter::Equals("email".into(), FilterValue::String("test@example.com".into()));
24//!
25//! // Greater than filter
26//! let filter = Filter::Gt("age".into(), FilterValue::Int(18));
27//!
28//! // Contains filter (for strings)
29//! let filter = Filter::Contains("name".into(), FilterValue::String("john".into()));
30//!
31//! // Combine filters with AND/OR
32//! let combined = Filter::and([
33//! Filter::Equals("active".into(), FilterValue::Bool(true)),
34//! Filter::Gt("age".into(), FilterValue::Int(18)),
35//! ]);
36//!
37//! let either = Filter::or([
38//! Filter::Equals("role".into(), FilterValue::String("admin".into())),
39//! Filter::Equals("role".into(), FilterValue::String("moderator".into())),
40//! ]);
41//! ```
42//!
43//! ## Filter Values
44//!
45//! Convert Rust types to filter values:
46//!
47//! ```rust
48//! use prax_query::FilterValue;
49//!
50//! // Integer values
51//! let val: FilterValue = 42.into();
52//! assert!(matches!(val, FilterValue::Int(42)));
53//!
54//! // String values
55//! let val: FilterValue = "hello".into();
56//! assert!(matches!(val, FilterValue::String(_)));
57//!
58//! // Boolean values
59//! let val: FilterValue = true.into();
60//! assert!(matches!(val, FilterValue::Bool(true)));
61//!
62//! // Float values
63//! let val: FilterValue = 3.14f64.into();
64//! assert!(matches!(val, FilterValue::Float(_)));
65//!
66//! // Null values
67//! let val = FilterValue::Null;
68//! ```
69//!
70//! ## Sorting
71//!
72//! Build sort specifications:
73//!
74//! ```rust
75//! use prax_query::{OrderBy, OrderByField, NullsOrder};
76//!
77//! // Ascending order
78//! let order = OrderByField::asc("created_at");
79//!
80//! // Descending order
81//! let order = OrderByField::desc("updated_at");
82//!
83//! // With NULLS FIRST/LAST
84//! let order = OrderByField::asc("name").nulls(NullsOrder::First);
85//! let order = OrderByField::desc("score").nulls(NullsOrder::Last);
86//!
87//! // Combine multiple orderings
88//! let orders = OrderBy::Field(OrderByField::asc("name"))
89//! .then(OrderByField::desc("created_at"));
90//! ```
91//!
92//! ## Raw SQL
93//!
94//! Build raw SQL queries with parameter binding:
95//!
96//! ```rust
97//! use prax_query::Sql;
98//!
99//! // Simple query
100//! let sql = Sql::new("SELECT * FROM users");
101//! assert_eq!(sql.sql(), "SELECT * FROM users");
102//!
103//! // Query with parameter - bind appends placeholder
104//! let sql = Sql::new("SELECT * FROM users WHERE id = ")
105//! .bind(42);
106//! assert_eq!(sql.params().len(), 1);
107//! ```
108//!
109//! ## Connection Strings
110//!
111//! Parse database connection strings:
112//!
113//! ```rust
114//! use prax_query::ConnectionString;
115//!
116//! // PostgreSQL
117//! let conn = ConnectionString::parse("postgres://user:pass@localhost:5432/mydb").unwrap();
118//! assert_eq!(conn.host(), Some("localhost"));
119//! assert_eq!(conn.port(), Some(5432));
120//! assert_eq!(conn.database(), Some("mydb"));
121//!
122//! // MySQL
123//! let conn = ConnectionString::parse("mysql://user:pass@localhost:3306/mydb").unwrap();
124//! ```
125//!
126//! ## Transaction Config
127//!
128//! Configure transaction behavior:
129//!
130//! ```rust
131//! use prax_query::IsolationLevel;
132//!
133//! let level = IsolationLevel::Serializable;
134//! assert_eq!(level.as_sql(), "SERIALIZABLE");
135//! ```
136//!
137//! ## Error Handling
138//!
139//! Work with query errors:
140//!
141//! ```rust
142//! use prax_query::{QueryError, ErrorCode};
143//!
144//! // Create errors
145//! let err = QueryError::not_found("User");
146//! assert_eq!(err.code, ErrorCode::RecordNotFound);
147//! ```
148
149pub mod batch;
150pub mod cache;
151pub mod connection;
152pub mod data;
153pub mod error;
154pub mod filter;
155pub mod intern;
156pub mod lazy;
157pub mod logging;
158#[macro_use]
159pub mod macros;
160pub mod memory;
161pub mod middleware;
162pub mod nested;
163pub mod operations;
164pub mod pagination;
165pub mod pool;
166pub mod query;
167pub mod raw;
168pub mod relations;
169pub mod sql;
170pub mod static_filter;
171pub mod tenant;
172pub mod traits;
173pub mod transaction;
174pub mod typed_filter;
175pub mod types;
176
177pub use error::{QueryError, QueryResult, ErrorCode, ErrorContext, Suggestion};
178pub use filter::{
179 Filter, FilterValue, ScalarFilter, FieldName, ValueList, SmallValueList, LargeValueList,
180 AndFilterBuilder, OrFilterBuilder, FluentFilterBuilder,
181};
182pub use nested::{NestedWrite, NestedWriteBuilder, NestedWriteOperations};
183pub use operations::{
184 CreateOperation, DeleteOperation, FindManyOperation, FindUniqueOperation, UpdateOperation,
185};
186pub use pagination::{Cursor, CursorDirection, Pagination};
187pub use query::QueryBuilder;
188pub use raw::{Sql, RawQueryOperation, RawExecuteOperation};
189pub use relations::{Include, IncludeSpec, RelationLoader, RelationSpec, SelectSpec};
190pub use traits::{Executable, IntoFilter, Model, QueryEngine};
191pub use transaction::{Transaction, TransactionConfig, IsolationLevel};
192pub use types::{NullsOrder, OrderBy, OrderByBuilder, OrderByField, Select, SortOrder, order_patterns};
193
194// Re-export middleware types
195pub use middleware::{
196 LoggingMiddleware, MetricsMiddleware, TimingMiddleware, RetryMiddleware,
197 Middleware, MiddlewareStack, MiddlewareChain, MiddlewareBuilder,
198 QueryContext, QueryMetadata, QueryType, QueryMetrics,
199};
200
201// Re-export connection types
202pub use connection::{
203 ConnectionString, DatabaseConfig, Driver, MultiDatabaseConfig,
204 ConnectionOptions, PoolOptions, PoolConfig, SslMode, SslConfig,
205 EnvExpander, ConnectionError,
206};
207
208// Re-export data types
209pub use data::{
210 CreateData, UpdateData, DataBuilder, FieldValue, ConnectData,
211 BatchCreate, IntoData,
212};
213
214// Re-export tenant types
215pub use tenant::{
216 TenantContext, TenantId, TenantInfo, TenantConfig, TenantConfigBuilder,
217 TenantMiddleware, TenantResolver, StaticResolver, DynamicResolver,
218 IsolationStrategy, RowLevelConfig, SchemaConfig,
219};
220
221// Re-export intern types
222pub use intern::{intern, intern_cow, clear_interned, interned_count, fields};
223
224// Re-export pool types
225pub use pool::{FilterPool, FilterBuilder, PooledFilter, PooledValue, IntoPooledValue};
226
227// Re-export SQL builder types
228pub use sql::{DatabaseType, SqlBuilder, FastSqlBuilder, QueryCapacity, templates};
229
230// Re-export cache types
231pub use cache::{
232 QueryCache, QueryKey, CachedQuery, CacheStats, QueryHash, patterns as cache_patterns,
233 SqlTemplateCache, SqlTemplate, global_template_cache, register_global_template,
234 get_global_template, precompute_query_hash,
235};
236
237// Re-export batch types
238pub use batch::{Batch, BatchBuilder, BatchOperation, BatchResult, OperationResult};
239
240// Re-export lazy loading types
241pub use lazy::{Lazy, LazyRelation, OneToManyLoader, ManyToOneLoader};
242
243// Re-export static filter utilities
244pub use static_filter::{
245 eq, ne, lt, lte, gt, gte, is_null, is_not_null,
246 contains, starts_with, ends_with, in_list, not_in_list,
247 and2, and3, and4, and5, or2, or3, or4, or5, not,
248 StaticFilter, CompactValue,
249 fields as static_fields,
250};
251
252// Re-export typed filter utilities
253pub use typed_filter::{
254 TypedFilter, DirectSql, And, Or, Not as TypedNot,
255 Eq, Ne, Lt, Lte, Gt, Gte,
256 IsNull, IsNotNull, Contains, StartsWith, EndsWith,
257 AndN, OrN, LazyFilter, Maybe,
258 and_n, or_n, lazy,
259 eq as typed_eq, ne as typed_ne, lt as typed_lt, lte as typed_lte,
260 gt as typed_gt, gte as typed_gte,
261 is_null as typed_is_null, is_not_null as typed_is_not_null,
262};
263
264// Re-export memory optimization utilities
265pub use memory::{
266 StringPool, BufferPool, PooledBuffer, PoolStats,
267 CompactFilter, MemoryStats,
268 GLOBAL_STRING_POOL, GLOBAL_BUFFER_POOL,
269 intern as memory_intern, get_buffer,
270};
271
272// Re-export logging utilities
273pub use logging::{
274 is_debug_enabled, get_log_level, get_log_format,
275 init as init_logging, init_with_level, init_debug,
276};
277
278// Re-export smallvec for macros
279pub use smallvec;
280
281/// Prelude module for convenient imports.
282pub mod prelude {
283 pub use crate::error::{QueryError, QueryResult};
284 pub use crate::filter::{Filter, FilterValue, ScalarFilter};
285 pub use crate::nested::{NestedWrite, NestedWriteBuilder, NestedWriteOperations};
286 pub use crate::operations::*;
287 pub use crate::pagination::{Cursor, CursorDirection, Pagination};
288 pub use crate::query::QueryBuilder;
289 pub use crate::raw::{Sql, RawQueryOperation, RawExecuteOperation};
290 pub use crate::relations::{Include, IncludeSpec, RelationSpec, SelectSpec};
291 pub use crate::traits::{Executable, IntoFilter, Model, QueryEngine};
292 pub use crate::transaction::{Transaction, TransactionConfig, IsolationLevel};
293 pub use crate::types::{OrderBy, Select, SortOrder};
294 pub use crate::raw_query;
295
296 // Tenant types
297 pub use crate::tenant::{TenantContext, TenantConfig, TenantMiddleware, IsolationStrategy};
298}
299