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