Skip to main content

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