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