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 row;
170pub mod sql;
171pub mod static_filter;
172pub mod tenant;
173pub mod traits;
174pub mod transaction;
175pub mod typed_filter;
176pub mod types;
177
178pub use error::{ErrorCode, ErrorContext, QueryError, QueryResult, Suggestion};
179pub use filter::{
180    AndFilterBuilder, FieldName, Filter, FilterValue, FluentFilterBuilder, LargeValueList,
181    OrFilterBuilder, ScalarFilter, SmallValueList, ValueList,
182};
183pub use nested::{NestedWrite, NestedWriteBuilder, NestedWriteOperations};
184pub use operations::{
185    CreateOperation, DeleteOperation, FindManyOperation, FindUniqueOperation, UpdateOperation,
186};
187pub use pagination::{Cursor, CursorDirection, Pagination};
188pub use query::QueryBuilder;
189pub use raw::{RawExecuteOperation, RawQueryOperation, Sql};
190pub use relations::{Include, IncludeSpec, RelationLoader, RelationSpec, SelectSpec};
191pub use traits::{Executable, IntoFilter, Model, QueryEngine};
192pub use transaction::{IsolationLevel, Transaction, TransactionConfig};
193pub use types::{
194    NullsOrder, OrderBy, OrderByBuilder, OrderByField, Select, SortOrder, order_patterns,
195};
196
197// Re-export middleware types
198pub use middleware::{
199    LoggingMiddleware, MetricsMiddleware, Middleware, MiddlewareBuilder, MiddlewareChain,
200    MiddlewareStack, QueryContext, QueryMetadata, QueryMetrics, QueryType, RetryMiddleware,
201    TimingMiddleware,
202};
203
204// Re-export connection types
205pub use connection::{
206    ConnectionError, ConnectionOptions, ConnectionString, DatabaseConfig, Driver, EnvExpander,
207    MultiDatabaseConfig, PoolConfig, PoolOptions, SslConfig, SslMode,
208};
209
210// Re-export data types
211pub use data::{
212    BatchCreate, ConnectData, CreateData, DataBuilder, FieldValue, IntoData, UpdateData,
213};
214
215// Re-export tenant types
216pub use tenant::{
217    DynamicResolver, IsolationStrategy, RowLevelConfig, SchemaConfig, StaticResolver, TenantConfig,
218    TenantConfigBuilder, TenantContext, TenantId, TenantInfo, TenantMiddleware, TenantResolver,
219};
220
221// Re-export intern types
222pub use intern::{clear_interned, fields, intern, intern_cow, interned_count};
223
224// Re-export pool types
225pub use pool::{FilterBuilder, FilterPool, IntoPooledValue, PooledFilter, PooledValue};
226
227// Re-export SQL builder types
228pub use sql::{DatabaseType, FastSqlBuilder, QueryCapacity, SqlBuilder, templates};
229
230// Re-export cache types
231pub use cache::{
232    CacheStats, CachedQuery, ExecutionPlan, ExecutionPlanCache, PlanHint, QueryCache, QueryHash,
233    QueryKey, SqlTemplate, SqlTemplateCache, get_global_template, global_template_cache,
234    patterns as cache_patterns, precompute_query_hash,
235    register_global_template,
236};
237
238// Re-export batch types
239pub use batch::{
240    Batch, BatchBuilder, BatchOperation, BatchResult, OperationResult, Pipeline, PipelineBuilder,
241    PipelineQuery, PipelineResult, QueryResult as PipelineQueryResult,
242};
243
244// Re-export row deserialization types
245pub use row::{FromColumn, FromRow, FromRowRef, RowData, RowError, RowRef, RowRefIter};
246
247// Re-export lazy loading types
248pub use lazy::{Lazy, LazyRelation, ManyToOneLoader, OneToManyLoader};
249
250// Re-export static filter utilities
251pub use static_filter::{
252    CompactValue, StaticFilter, and2, and3, and4, and5, contains, ends_with, eq,
253    fields as static_fields, gt, gte, in_list, is_not_null, is_null, lt, lte, ne, not, not_in_list,
254    or2, or3, or4, or5, starts_with,
255};
256
257// Re-export typed filter utilities
258pub use typed_filter::{
259    And, AndN, Contains, DirectSql, EndsWith, Eq, Gt, Gte, InI64, InI64Slice, InStr, InStrSlice,
260    IsNotNull, IsNull, LazyFilter, Lt, Lte, Maybe, Ne, Not as TypedNot, NotInI64Slice, Or, OrN,
261    StartsWith, TypedFilter, and_n, eq as typed_eq, gt as typed_gt, gte as typed_gte,
262    in_i64 as typed_in_i64, in_i64_slice, in_str as typed_in_str, in_str_slice,
263    is_not_null as typed_is_not_null, is_null as typed_is_null, lazy, lt as typed_lt,
264    lte as typed_lte, ne as typed_ne, not_in_i64_slice, or_n,
265};
266
267// Re-export memory optimization utilities
268pub use memory::{
269    BufferPool, CompactFilter, GLOBAL_BUFFER_POOL, GLOBAL_STRING_POOL, MemoryStats, PoolStats,
270    PooledBuffer, StringPool, get_buffer, intern as memory_intern,
271};
272
273// Re-export logging utilities
274pub use logging::{
275    get_log_format, get_log_level, init as init_logging, init_debug, init_with_level,
276    is_debug_enabled,
277};
278
279// Re-export smallvec for macros
280pub use smallvec;
281
282/// Prelude module for convenient imports.
283pub mod prelude {
284    pub use crate::error::{QueryError, QueryResult};
285    pub use crate::filter::{Filter, FilterValue, ScalarFilter};
286    pub use crate::nested::{NestedWrite, NestedWriteBuilder, NestedWriteOperations};
287    pub use crate::operations::*;
288    pub use crate::pagination::{Cursor, CursorDirection, Pagination};
289    pub use crate::query::QueryBuilder;
290    pub use crate::raw::{RawExecuteOperation, RawQueryOperation, Sql};
291    pub use crate::raw_query;
292    pub use crate::relations::{Include, IncludeSpec, RelationSpec, SelectSpec};
293    pub use crate::traits::{Executable, IntoFilter, Model, QueryEngine};
294    pub use crate::transaction::{IsolationLevel, Transaction, TransactionConfig};
295    pub use crate::types::{OrderBy, Select, SortOrder};
296
297    // Tenant types
298    pub use crate::tenant::{IsolationStrategy, TenantConfig, TenantContext, TenantMiddleware};
299}