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