Skip to main content

rullst_orm/
lib.rs

1pub use sqlx;
2
3/// Auto-Healing Database Migrations & SQL Interceptor (Milestone 21).
4pub mod auto_healing;
5
6#[cfg(not(any(
7    feature = "strict-postgres",
8    feature = "strict-mysql",
9    feature = "strict-sqlite"
10)))]
11pub use sqlx::AnyPool as RullstPool;
12
13#[cfg(not(any(
14    feature = "strict-postgres",
15    feature = "strict-mysql",
16    feature = "strict-sqlite"
17)))]
18pub use sqlx::any::AnyPoolOptions as RullstPoolOptions;
19
20#[cfg(feature = "strict-postgres")]
21pub use sqlx::PgPool as RullstPool;
22
23#[cfg(feature = "strict-postgres")]
24pub use sqlx::postgres::PgPoolOptions as RullstPoolOptions;
25
26#[cfg(all(feature = "strict-mysql", not(feature = "strict-postgres")))]
27pub use sqlx::MySqlPool as RullstPool;
28
29#[cfg(all(feature = "strict-mysql", not(feature = "strict-postgres")))]
30pub use sqlx::mysql::MySqlPoolOptions as RullstPoolOptions;
31
32#[cfg(all(
33    feature = "strict-sqlite",
34    not(feature = "strict-postgres"),
35    not(feature = "strict-mysql")
36))]
37pub use sqlx::SqlitePool as RullstPool;
38
39#[cfg(all(
40    feature = "strict-sqlite",
41    not(feature = "strict-postgres"),
42    not(feature = "strict-mysql")
43))]
44pub use sqlx::sqlite::SqlitePoolOptions as RullstPoolOptions;
45
46// Hide underlying libraries for macro usage while keeping the public API clean
47#[doc(hidden)]
48pub use async_stream as _async_stream;
49#[doc(hidden)]
50pub use futures as _futures;
51#[doc(hidden)]
52pub use serde as _serde;
53#[doc(hidden)]
54pub use serde_json as _serde_json;
55#[doc(hidden)]
56pub use sqlx as _sqlx;
57#[doc(hidden)]
58pub use tracing as _tracing;
59
60#[cfg(feature = "pgvector")]
61#[doc(hidden)]
62pub use pgvector as _pgvector;
63
64#[cfg(feature = "redis")]
65#[doc(hidden)]
66pub use redis as _redis;
67
68pub mod admin;
69pub mod audit;
70pub mod collection;
71pub mod database;
72pub mod db;
73mod enum_codecs;
74pub mod error;
75pub mod intent;
76pub mod outbox;
77pub mod policy;
78pub mod polyglot;
79pub mod pool;
80pub mod post_commit;
81pub mod privacy;
82#[cfg(feature = "redis")]
83#[doc(hidden)]
84pub mod query_cache;
85pub mod raw;
86#[cfg(feature = "redis")]
87pub mod redis_data;
88pub mod replica;
89pub mod repository;
90pub mod resource;
91pub mod schema;
92pub mod schema_diff;
93pub mod scout;
94#[doc(hidden)]
95pub mod telemetry;
96pub mod tenant;
97pub mod types;
98pub mod value;
99
100#[cfg(test)]
101mod tests;
102
103// Re-exports
104pub use _sqlx::FromRow;
105pub use admin::dashboard_html;
106pub use async_trait::async_trait;
107pub use collection::RullstCollection;
108pub use database::RullstDatabase;
109pub use error::RullstError as Error;
110pub use intent::IntentAnalyzer;
111pub use outbox::{ClaimedOutboxEvent, EnqueuedOutboxEvent, Outbox, OutboxMigration};
112#[cfg(feature = "pgvector")]
113pub use pgvector::Vector;
114pub use policy::Policy;
115pub use polyglot::{
116    Backend, BackendCapabilities, Capability, CollectionName, DocumentEntry, DocumentId,
117    DocumentInventory, DocumentPage, DocumentRecoveryBinding, DocumentRecoveryError,
118    DocumentRecoveryKey, DocumentRecoveryPolicy, DocumentRecoveryReport, DocumentRepository,
119    EncryptedDocumentSnapshot, MockDocumentStore, PolyglotError, export_document_snapshot,
120    restore_document_snapshot,
121};
122#[cfg(feature = "qdrant")]
123pub use polyglot::{
124    QdrantConfig, QdrantStore, VectorCollectionName, VectorDimensions, VectorMatch, VectorPoint,
125    VectorQueryLimit, VectorRepository,
126};
127#[doc(hidden)]
128pub use pool::portable_subquery;
129/// Whether generated builder filters cast `#[derive(Enum)]` values to their
130/// named PostgreSQL type. Only the strict PostgreSQL runtime decodes native
131/// enum columns; under SQLx `Any` such fields live in text columns.
132#[doc(hidden)]
133pub const __NATIVE_ENUM_FILTER_CASTS: bool = cfg!(feature = "strict-postgres");
134pub use pool::{
135    Orm, PaginationResult, RagContext, RullstModel, Seeder, is_lazy_loading_prevented,
136    prevent_lazy_loading, replace_placeholders,
137};
138pub use post_commit::{ModelCommittedEvent, ModelOperation, after_commit};
139pub use privacy::{ComplianceModel, PrivacyReport, SecretString};
140#[cfg(feature = "redis")]
141pub use redis_data::{
142    RedisDataConfig, RedisDataKey, RedisDataStore, RedisField, RedisMember, RedisScanLimit,
143    RedisStructure, RedisStructuresRepository, RedisValue, ScoredRedisMember,
144};
145pub use replica::ReplicaPool;
146pub use repository::{GenericRepository, Repository};
147pub use resource::{ApiResource, JsonResource, ResourceCollection};
148pub use rullst_orm_macros::{Enum, Nexus, Orm, PersonalData, TursoModel, test};
149pub use schema::{DatabaseEnum, JoinClause, SubqueryBuilder};
150#[cfg(feature = "scout-http")]
151pub use scout::{AlgoliaEngine, ElasticsearchEngine, MeilisearchEngine};
152pub use scout::{MockSearchEngine, SearchEngine, get_search_engine, set_search_engine};
153pub use tenant::{get_tenant_id, with_tenant};
154pub use types::Json;
155pub use value::RullstValue;
156
157#[doc(hidden)]
158#[path = "transaction_access.rs"]
159pub mod __transaction_access;
160
161#[doc(hidden)]
162#[path = "eager_limit.rs"]
163pub mod __eager_limit;
164
165tokio::task_local! {
166    pub static CURRENT_TX: std::sync::Arc<tokio::sync::Mutex<Option<crate::db::Transaction<'static>>>>;
167}
168
169/// Serializes SQLite tests generated by `#[rullst_orm::test]` within one test
170/// process. SQLite schema changes can otherwise race with another sandbox
171/// transaction and fail nondeterministically with `SQLITE_LOCKED`.
172#[doc(hidden)]
173pub static TEST_SANDBOX_LOCK: tokio::sync::Mutex<()> = tokio::sync::Mutex::const_new(());
174
175#[macro_export]
176macro_rules! execute_query {
177    ($query:expr, $method:ident, $pool_fn:ident) => {{
178        $crate::__transaction_access::ensure_allowed()?;
179        if let Ok(tx_arc) = $crate::CURRENT_TX.try_with(|tx| tx.clone()) {
180            let mut tx_guard = tx_arc.lock().await;
181            if let Some(tx) = tx_guard.as_mut() {
182                $query.$method(&mut **tx).await
183            } else {
184                let pool = $crate::Orm::$pool_fn()?;
185                $query.$method(pool).await
186            }
187        } else {
188            let pool = $crate::Orm::$pool_fn()?;
189            $query.$method(pool).await
190        }
191    }};
192}
193
194#[macro_export]
195macro_rules! dispatch_executor {
196    ($pool_fn:ident, |$executor:ident| $e:expr) => {{
197        $crate::__transaction_access::ensure_allowed()?;
198        if let Ok(tx_arc) = $crate::CURRENT_TX.try_with(|tx| tx.clone()) {
199            let mut tx_guard = tx_arc.lock().await;
200            if let Some(tx) = tx_guard.as_mut() {
201                let $executor = &mut **tx;
202                $e
203            } else {
204                let $executor = $crate::Orm::$pool_fn()?;
205                $e
206            }
207        } else {
208            let $executor = $crate::Orm::$pool_fn()?;
209            $e
210        }
211    }};
212}