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