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