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