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 advanced;
150pub mod async_optimize;
151pub mod batch;
152pub mod builder;
153pub mod cache;
154pub mod connection;
155pub mod cte;
156pub mod data;
157pub mod data_cache;
158pub mod db_optimize;
159pub mod error;
160pub mod extension;
161pub mod filter;
162pub mod intern;
163pub mod introspection;
164pub mod json;
165pub mod lazy;
166pub mod logging;
167#[macro_use]
168pub mod macros;
169pub mod mem_optimize;
170pub mod memory;
171pub mod middleware;
172pub mod nested;
173pub mod operations;
174pub mod pagination;
175pub mod partition;
176pub mod pool;
177pub mod procedure;
178pub mod profiling;
179pub mod query;
180pub mod raw;
181pub mod relations;
182pub mod replication;
183pub mod row;
184pub mod search;
185pub mod security;
186pub mod sequence;
187pub mod sql;
188pub mod static_filter;
189pub mod tenant;
190pub mod traits;
191pub mod transaction;
192pub mod trigger;
193pub mod typed_filter;
194pub mod types;
195pub mod upsert;
196pub mod window;
197pub mod zero_copy;
198
199pub use error::{ErrorCode, ErrorContext, QueryError, QueryResult, Suggestion};
200pub use extension::{Extension, ExtensionBuilder, Point, Polygon};
201pub use filter::{
202    AndFilterBuilder, FieldName, Filter, FilterValue, FluentFilterBuilder, LargeValueList,
203    OrFilterBuilder, ScalarFilter, SmallValueList, ValueList,
204};
205pub use json::{
206    JsonAgg, JsonFilter, JsonIndex, JsonIndexBuilder, JsonOp, JsonPath, PathSegment,
207};
208pub use nested::{NestedWrite, NestedWriteBuilder, NestedWriteOperations};
209pub use operations::{
210    CreateOperation, DeleteOperation, FindManyOperation, FindUniqueOperation, UpdateOperation,
211    // View operations
212    MaterializedViewAccessor, RefreshMaterializedViewOperation, ViewAccessor, ViewCountOperation,
213    ViewFindFirstOperation, ViewFindManyOperation, ViewQueryBuilder,
214};
215pub use pagination::{Cursor, CursorDirection, Pagination};
216pub use partition::{
217    HashPartitionDef, ListPartitionDef, Partition, PartitionBuilder, PartitionDef, PartitionType,
218    RangeBound, RangePartitionDef,
219};
220pub use procedure::{
221    Parameter, ParameterMode, ProcedureCall, ProcedureCallOperation, ProcedureEngine,
222    ProcedureResult,
223};
224pub use query::QueryBuilder;
225pub use raw::{RawExecuteOperation, RawQueryOperation, Sql};
226pub use relations::{Include, IncludeSpec, RelationLoader, RelationSpec, SelectSpec};
227pub use search::{
228    FullTextIndex, FullTextIndexBuilder, FuzzyOptions, HighlightOptions, RankingOptions,
229    SearchLanguage, SearchMode, SearchQuery, SearchQueryBuilder, SearchSql,
230};
231pub use security::{
232    ConnectionProfile, ConnectionProfileBuilder, DataMask, Grant, GrantBuilder, GrantObject,
233    MaskFunction, PolicyCommand, Privilege, RlsPolicy, RlsPolicyBuilder, Role, RoleBuilder,
234    TenantPolicy, TenantSource,
235};
236pub use sequence::{OwnedBy, Sequence, SequenceBuilder};
237pub use traits::{
238    Executable, IntoFilter, MaterializedView, Model, QueryEngine, View, ViewQueryEngine,
239};
240pub use transaction::{IsolationLevel, Transaction, TransactionConfig};
241pub use trigger::{
242    Trigger, TriggerAction, TriggerBuilder, TriggerCondition, TriggerEvent, TriggerLevel,
243    TriggerTiming, UpdateOf,
244};
245pub use types::{
246    NullsOrder, OrderBy, OrderByBuilder, OrderByField, Select, SortOrder, order_patterns,
247};
248pub use upsert::{
249    Assignment, AssignmentValue, ConflictAction, ConflictTarget, UpdateSpec, Upsert, UpsertBuilder,
250};
251pub use window::{
252    FrameBound, FrameClause, FrameExclude, FrameType, NamedWindow, NullsPosition, OrderSpec,
253    WindowFn, WindowFunction, WindowFunctionBuilder, WindowSpec,
254};
255
256// Re-export middleware types
257pub use middleware::{
258    LoggingMiddleware, MetricsMiddleware, Middleware, MiddlewareBuilder, MiddlewareChain,
259    MiddlewareStack, QueryContext, QueryMetadata, QueryMetrics, QueryType, RetryMiddleware,
260    TimingMiddleware,
261};
262
263// Re-export connection types
264pub use connection::{
265    ConnectionError, ConnectionOptions, ConnectionString, DatabaseConfig, Driver, EnvExpander,
266    MultiDatabaseConfig, PoolConfig, PoolOptions, SslConfig, SslMode,
267};
268pub use cte::{
269    Cte, CteBuilder, CycleClause, Materialized, SearchClause, SearchMethod, WithClause,
270    WithQueryBuilder,
271};
272
273// Re-export advanced query types
274pub use advanced::{
275    BulkOperation, DistinctOn, LateralJoin, LateralJoinBuilder, LateralJoinType, LockStrength,
276    LockWait, ReturnOperation, Returning, ReturningColumn, RowLock, RowLockBuilder, SampleMethod,
277    SampleSize, TableSample, TableSampleBuilder,
278};
279
280// Re-export data types
281pub use data::{
282    BatchCreate, ConnectData, CreateData, DataBuilder, FieldValue, IntoData, UpdateData,
283};
284
285// Re-export introspection types
286pub use introspection::{
287    CheckConstraint, ColumnInfo, DatabaseSchema, EnumInfo, ForeignKeyInfo, IndexColumn, IndexInfo,
288    NormalizedType, ReferentialAction, SequenceInfo, TableInfo, UniqueConstraint, ViewInfo,
289    generate_prax_schema, normalize_type,
290};
291
292// Re-export tenant types
293pub use tenant::{
294    DynamicResolver, IsolationStrategy, RowLevelConfig, SchemaConfig, StaticResolver, TenantConfig,
295    TenantConfigBuilder, TenantContext, TenantId, TenantInfo, TenantMiddleware, TenantResolver,
296};
297
298// Re-export intern types
299pub use intern::{clear_interned, fields, intern, intern_cow, interned_count};
300
301// Re-export pool types
302pub use pool::{FilterBuilder, FilterPool, IntoPooledValue, PooledFilter, PooledValue};
303
304// Re-export SQL builder types
305pub use sql::{
306    AdvancedQueryCapacity, CachedSql, DatabaseType, FastSqlBuilder, LazySql, QueryCapacity,
307    SqlBuilder, SqlTemplateCache as SqlCache, global_sql_cache, keywords, templates,
308};
309
310// Re-export optimized builder types
311pub use builder::{
312    BuilderPool, ColumnList, ColumnNameList, CowColumnList, CowIdentifier, ExprList, Identifier,
313    OptimizedWindowSpec, OrderByList, PartitionByList, ReusableBuilder, WindowFrame,
314    // Note: FrameBound and FrameType are also defined in window module
315    FrameBound as BuilderFrameBound, FrameType as BuilderFrameType,
316};
317
318// Re-export database optimization types
319pub use db_optimize::{
320    BatchConfig, CachedStatement, IndexHint, IndexHintType, JoinHint, JoinMethod,
321    MongoPipelineBuilder, PipelineStage, PreparedStatementCache, PreparedStatementStats, QueryHints,
322    global_statement_cache,
323};
324
325// Re-export zero-copy types
326pub use zero_copy::{
327    CteRef, FrameBoundRef, FrameRef, FrameTypeRef, JsonPathRef, PathSegmentRef, WindowSpecRef,
328    WithClauseRef,
329};
330
331// Re-export cache types
332pub use cache::{
333    CacheStats, CachedQuery, ExecutionPlan, ExecutionPlanCache, PlanHint, QueryCache, QueryHash,
334    QueryKey, SqlTemplate, SqlTemplateCache, get_global_template, global_template_cache,
335    patterns as cache_patterns, precompute_query_hash, register_global_template,
336};
337
338// Re-export batch types
339pub use batch::{
340    Batch, BatchBuilder, BatchOperation, BatchResult, OperationResult, Pipeline, PipelineBuilder,
341    PipelineQuery, PipelineResult, QueryResult as PipelineQueryResult,
342};
343
344// Re-export row deserialization types
345pub use row::{FromColumn, FromRow, FromRowRef, RowData, RowError, RowRef, RowRefIter};
346
347// Re-export lazy loading types
348pub use lazy::{Lazy, LazyRelation, ManyToOneLoader, OneToManyLoader};
349
350// Re-export static filter utilities
351pub use static_filter::{
352    CompactValue, StaticFilter, and2, and3, and4, and5, contains, ends_with, eq,
353    fields as static_fields, gt, gte, in_list, is_not_null, is_null, lt, lte, ne, not, not_in_list,
354    or2, or3, or4, or5, starts_with,
355};
356
357// Re-export typed filter utilities
358pub use typed_filter::{
359    And, AndN, Contains, DirectSql, EndsWith, Eq, Gt, Gte, InI64, InI64Slice, InStr, InStrSlice,
360    IsNotNull, IsNull, LazyFilter, Lt, Lte, Maybe, Ne, Not as TypedNot, NotInI64Slice, Or, OrN,
361    StartsWith, TypedFilter, and_n, eq as typed_eq, gt as typed_gt, gte as typed_gte,
362    in_i64 as typed_in_i64, in_i64_slice, in_str as typed_in_str, in_str_slice,
363    is_not_null as typed_is_not_null, is_null as typed_is_null, lazy, lt as typed_lt,
364    lte as typed_lte, ne as typed_ne, not_in_i64_slice, or_n,
365};
366
367// Re-export memory optimization utilities
368pub use memory::{
369    BufferPool, CompactFilter, GLOBAL_BUFFER_POOL, GLOBAL_STRING_POOL, MemoryStats, PoolStats,
370    PooledBuffer, StringPool, get_buffer, intern as memory_intern,
371};
372
373// Re-export logging utilities
374pub use logging::{
375    get_log_format, get_log_level, init as init_logging, init_debug, init_with_level,
376    is_debug_enabled,
377};
378
379// Re-export replication types
380pub use replication::{
381    ConnectionRouter, HealthStatus, LagMeasurement, LagMonitor, ReadPreference,
382    ReplicaConfig, ReplicaHealth, ReplicaRole, ReplicaSetBuilder, ReplicaSetConfig,
383};
384
385// Re-export async optimization types
386pub use async_optimize::{
387    ConcurrencyConfig, ConcurrentExecutor, ExecutionStats, IntrospectionConfig,
388    IntrospectionResult, PipelineConfig, PipelineError,
389    PipelineResult as AsyncPipelineResult, QueryPipeline, TaskError, TaskResult,
390    concurrent::execute_batch as async_execute_batch,
391    concurrent::execute_chunked as async_execute_chunked,
392    introspect::{
393        BatchIntrospector, ColumnMetadata, ConcurrentIntrospector, ForeignKeyMetadata,
394        IndexMetadata, IntrospectionError, IntrospectionPhase, IntrospectorBuilder,
395        TableMetadata,
396    },
397    pipeline::{BulkInsertPipeline, BulkUpdatePipeline, SimulatedExecutor},
398};
399
400// Re-export memory optimization types
401pub use mem_optimize::{
402    GlobalInterner, IdentifierCache, InternedStr, ScopedInterner,
403    arena::{ArenaScope, ArenaStats, QueryArena, ScopedFilter, ScopedQuery, ScopedValue},
404    interning::{intern as global_intern, intern_component, intern_qualified, get_interned},
405    lazy::{LazyColumn, LazyForeignKey, LazyIndex, LazySchema, LazySchemaStats, LazyTable},
406};
407
408// Re-export profiling types
409pub use profiling::{
410    AllocationRecord, AllocationStats, AllocationTracker, HeapProfiler, HeapReport, HeapStats,
411    LeakDetector, LeakReport, LeakSeverity, MemoryProfiler, MemoryReport, MemorySnapshot,
412    PotentialLeak, SnapshotDiff, TrackedAllocator,
413    enable_profiling, disable_profiling, is_profiling_enabled, with_profiling,
414};
415
416// Re-export smallvec for macros
417pub use smallvec;
418
419/// Prelude module for convenient imports.
420pub mod prelude {
421    pub use crate::error::{QueryError, QueryResult};
422    pub use crate::extension::{Extension, Point, Polygon};
423    pub use crate::filter::{Filter, FilterValue, ScalarFilter};
424    pub use crate::advanced::{LateralJoin, Returning, RowLock, TableSample};
425    pub use crate::cte::{Cte, CteBuilder, WithClause};
426    pub use crate::introspection::{DatabaseSchema, TableInfo, generate_prax_schema};
427    pub use crate::replication::{ConnectionRouter, ReadPreference, ReplicaSetConfig};
428    pub use crate::json::{JsonFilter, JsonOp, JsonPath};
429    pub use crate::nested::{NestedWrite, NestedWriteBuilder, NestedWriteOperations};
430    pub use crate::operations::*;
431    pub use crate::pagination::{Cursor, CursorDirection, Pagination};
432    pub use crate::partition::{Partition, PartitionBuilder, PartitionType, RangeBound};
433    pub use crate::procedure::{
434        Parameter, ParameterMode, ProcedureCall, ProcedureEngine, ProcedureResult,
435    };
436    pub use crate::query::QueryBuilder;
437    pub use crate::raw::{RawExecuteOperation, RawQueryOperation, Sql};
438    pub use crate::raw_query;
439    pub use crate::relations::{Include, IncludeSpec, RelationSpec, SelectSpec};
440    pub use crate::search::{FullTextIndex, SearchMode, SearchQuery, SearchQueryBuilder};
441    pub use crate::security::{Grant, GrantBuilder, RlsPolicy, Role, RoleBuilder};
442    pub use crate::sequence::{Sequence, SequenceBuilder};
443    pub use crate::traits::{
444        Executable, IntoFilter, MaterializedView, Model, QueryEngine, View, ViewQueryEngine,
445    };
446    pub use crate::transaction::{IsolationLevel, Transaction, TransactionConfig};
447    pub use crate::trigger::{
448        Trigger, TriggerAction, TriggerBuilder, TriggerCondition, TriggerEvent, TriggerLevel,
449        TriggerTiming,
450    };
451    pub use crate::types::{OrderBy, Select, SortOrder};
452    pub use crate::upsert::{ConflictAction, ConflictTarget, Upsert, UpsertBuilder};
453    pub use crate::window::{WindowFn, WindowFunction, WindowSpec};
454
455    // Tenant types
456    pub use crate::tenant::{IsolationStrategy, TenantConfig, TenantContext, TenantMiddleware};
457
458    // Async optimization types
459    pub use crate::async_optimize::{
460        ConcurrencyConfig, ConcurrentExecutor, IntrospectionConfig, PipelineConfig, QueryPipeline,
461    };
462
463    // Memory optimization types
464    pub use crate::mem_optimize::{
465        GlobalInterner, InternedStr, QueryArena, LazySchema,
466    };
467
468    // Profiling types
469    pub use crate::profiling::{
470        LeakDetector, MemoryProfiler, MemorySnapshot, enable_profiling, with_profiling,
471    };
472}