rust_query/
lib.rs

1#![allow(private_bounds, private_interfaces)]
2#![doc = include_str!("../README.md")]
3
4extern crate self as rust_query;
5
6#[macro_use]
7extern crate static_assertions;
8
9mod alias;
10mod ast;
11mod async_db;
12mod db;
13mod joinable;
14mod lazy;
15mod migrate;
16mod mutable;
17#[cfg(feature = "mutants")]
18mod mutants;
19mod mymap;
20mod pool;
21mod query;
22mod rows;
23mod schema;
24mod select;
25mod transaction;
26mod value;
27mod writable;
28
29pub use async_db::DatabaseAsync;
30pub use db::TableRow;
31pub use lazy::Lazy;
32use private::Reader;
33pub use rust_query_macros::{FromExpr, Select};
34use schema::from_macro::TypBuilder;
35pub use select::{IntoSelect, Select};
36pub use transaction::{Database, Transaction, TransactionWeak};
37use value::MyTyp;
38#[expect(deprecated)]
39pub use value::UnixEpoch;
40pub use value::aggregate::aggregate;
41pub use value::trivial::FromExpr;
42pub use value::{Expr, IntoExpr, optional::optional};
43pub use writable::Update;
44
45use crate::alias::JoinableTable;
46
47/// Types that are used as closure arguments.
48///
49/// You generally don't need to import these types.
50pub mod args {
51    pub use crate::query::{OrderBy, Query};
52    pub use crate::rows::Rows;
53    pub use crate::value::aggregate::Aggregate;
54    pub use crate::value::optional::Optional;
55}
56
57/// Types to declare schemas and migrations.
58///
59/// A good starting point is too look at [crate::migration::schema].
60pub mod migration {
61    pub use crate::migrate::{
62        Migrator,
63        config::{Config, ForeignKeys, Synchronous},
64        migration::{Migrated, TransactionMigrate},
65    };
66    #[cfg(feature = "dev")]
67    pub use crate::schema::dev::hash_schema;
68    pub use rust_query_macros::schema;
69}
70
71/// These items are only exposed for use by the proc macros.
72/// Direct use is unsupported.
73#[doc(hidden)]
74pub mod private {
75    use std::marker::PhantomData;
76
77    pub use crate::joinable::Joinable;
78    pub use crate::migrate::{
79        Schema, SchemaMigration, TableTypBuilder,
80        migration::{Migration, SchemaBuilder},
81    };
82    pub use crate::query::get_plan;
83    pub use crate::schema::from_macro::TypBuilder;
84    pub use crate::value::{
85        DynTypedExpr, MyTyp, Typed, ValueBuilder, adhoc_expr, new_column, unique_from_joinable,
86    };
87    pub use crate::writable::{Reader, TableInsert};
88
89    pub struct Lazy<'t>(PhantomData<&'t ()>);
90    pub struct Ignore;
91    pub struct Custom<T>(PhantomData<T>);
92    pub struct AsUpdate;
93    pub struct AsExpr<'t>(PhantomData<&'t ()>);
94
95    pub trait Apply {
96        type Out<T: MyTyp, S>;
97    }
98
99    impl<'t> Apply for Lazy<'t> {
100        type Out<T: MyTyp, S> = T::Lazy<'t>;
101    }
102
103    impl Apply for Ignore {
104        type Out<T: MyTyp, S> = ();
105    }
106
107    impl<X> Apply for Custom<X> {
108        type Out<T: MyTyp, S> = X;
109    }
110
111    impl Apply for AsUpdate {
112        type Out<T: MyTyp, S> = crate::Update<S, T>;
113    }
114
115    impl<'t> Apply for AsExpr<'t> {
116        type Out<T: MyTyp, S> = crate::Expr<'t, S, T>;
117    }
118
119    pub trait UpdateOrUnit<S, T>: Default {}
120    impl<S, T: MyTyp> UpdateOrUnit<S, T> for crate::Update<S, T> {}
121    impl<S, T> UpdateOrUnit<S, T> for () {}
122
123    pub mod doctest {
124        use crate::{Database, Transaction, migrate::config::Config, migration};
125
126        #[migration::schema(Empty)]
127        pub mod vN {
128            pub struct User {
129                #[unique]
130                pub name: String,
131            }
132        }
133        pub use v0::*;
134
135        #[cfg_attr(test, mutants::skip)] // this function is only used in doc tests
136        pub fn get_txn(f: impl Send + FnOnce(&'static mut Transaction<Empty>)) {
137            let db = Database::new(Config::open_in_memory());
138            db.transaction_mut_ok(|txn| {
139                txn.insert(User { name: "Alice" }).unwrap();
140                f(txn)
141            })
142        }
143    }
144}
145
146/// This trait is implemented for all table types as generated by the [crate::migration::schema] macro.
147///
148/// **You can not implement this trait yourself!**
149pub trait Table: Sized + 'static {
150    #[doc(hidden)]
151    type Ext2<'t>;
152
153    #[doc(hidden)]
154    fn covariant_ext<'x, 't>(val: &'x Self::Ext2<'static>) -> &'x Self::Ext2<'t>;
155
156    #[doc(hidden)]
157    fn build_ext2<'t>(val: &Expr<'t, Self::Schema, Self>) -> Self::Ext2<'t>;
158
159    /// The schema that this table is a part of.
160    type Schema;
161
162    #[doc(hidden)]
163    /// The table that this table can be migrated from.
164    type MigrateFrom: MyTyp;
165
166    /// The type of conflict that can result from inserting a row in this table.
167    /// This is the same type that is used for row updates too.
168    type Conflict;
169
170    /// The type of updates used by [Transaction::update_ok].
171    type UpdateOk;
172    /// The type of updates used by [Transaction::update].
173    type Update;
174    /// The type of error when a delete fails due to a foreign key constraint.
175    type Referer;
176
177    #[doc(hidden)]
178    type Mutable;
179    #[doc(hidden)]
180    type Lazy<'t>;
181    #[doc(hidden)]
182    type Insert;
183
184    #[doc(hidden)]
185    fn read(val: &Self::Insert, f: &mut Reader<Self::Schema>);
186
187    #[doc(hidden)]
188    fn get_conflict_unchecked(
189        txn: &Transaction<Self::Schema>,
190        val: &Self::Insert,
191    ) -> Self::Conflict;
192
193    #[doc(hidden)]
194    fn select_mutable(
195        val: Expr<'_, Self::Schema, Self>,
196    ) -> Select<'_, Self::Schema, (Self::Mutable, TableRow<Self>)>;
197
198    #[doc(hidden)]
199    fn mutable_into_update(val: Self::Mutable) -> Self::UpdateOk;
200
201    #[doc(hidden)]
202    fn update_into_try_update(val: Self::UpdateOk) -> Self::Update;
203
204    #[doc(hidden)]
205    fn apply_try_update(val: Self::Update, old: Expr<'static, Self::Schema, Self>) -> Self::Insert;
206
207    #[doc(hidden)]
208    fn get_referer_unchecked() -> Self::Referer;
209
210    #[doc(hidden)]
211    fn get_lazy<'t>(txn: &'t Transaction<Self::Schema>, row: TableRow<Self>) -> Self::Lazy<'t>;
212
213    #[doc(hidden)]
214    fn typs(f: &mut TypBuilder<Self::Schema>);
215
216    #[doc(hidden)]
217    const SPAN: (usize, usize);
218
219    #[doc(hidden)]
220    const ID: &'static str;
221    #[doc(hidden)]
222    const NAME: &'static str;
223}
224
225trait CustomJoin: Table {
226    fn name(&self) -> JoinableTable;
227}
228
229#[test]
230fn compile_tests() {
231    let t = trybuild::TestCases::new();
232    t.compile_fail("tests/compile/*.rs");
233}