1#![cfg(any(
2 feature = "mysql",
3 feature = "postgres",
4 feature = "sqlite",
5 feature = "mariadb"
6))]
7use std::future::Future;
39
40use futures::{Stream, TryStreamExt};
41pub use ormx_macros::*;
42use sqlx::{Executor, Result};
43
44#[doc(hidden)]
45pub mod exports {
46 pub use futures::Stream;
47
48 pub use crate::query2::map::*;
49}
50
51#[cfg(any(feature = "mysql", feature = "postgres", feature = "mariadb"))]
52mod query2;
53
54#[cfg(any(feature = "mysql", feature = "mariadb"))]
55pub type Db = sqlx::MySql;
56#[cfg(feature = "postgres")]
57pub type Db = sqlx::Postgres;
58#[cfg(feature = "sqlite")]
59pub type Db = sqlx::Sqlite;
60
61pub trait Table
63where
64 Self: Sized + Send + Sync + 'static,
65{
66 type Id: 'static + Copy + Send;
68
69 fn id(&self) -> Self::Id;
71
72 fn insert<'a, 'c: 'a>(
74 #[cfg(not(feature = "mysql"))] db: impl Executor<'c, Database = Db> + 'a,
75 #[cfg(feature = "mysql")] db: &'c mut sqlx::MySqlConnection,
76 row: impl Insert<Table = Self>,
77 ) -> impl Future<Output = Result<Self>> + Send + 'a {
78 row.insert(db)
79 }
80
81 fn get<'a, 'c: 'a>(
83 db: impl Executor<'c, Database = Db> + 'a,
84 id: Self::Id,
85 ) -> impl Future<Output = Result<Self>> + Send + 'a;
86
87 fn stream_all<'a, 'c: 'a>(
91 db: impl Executor<'c, Database = Db> + 'a,
92 ) -> impl Stream<Item = Result<Self>> + Send + 'a;
93
94 fn stream_all_paginated<'a, 'c: 'a>(
98 db: impl Executor<'c, Database = Db> + 'a,
99 offset: i64,
100 limit: i64,
101 ) -> impl Stream<Item = Result<Self>> + Send + 'a;
102
103 fn all<'a, 'c: 'a>(
107 db: impl Executor<'c, Database = Db> + 'a,
108 ) -> impl Future<Output = Result<Vec<Self>>> + Send + 'a {
109 Self::stream_all(db).try_collect()
110 }
111
112 fn all_paginated<'a, 'c: 'a>(
116 db: impl Executor<'c, Database = Db> + 'a,
117 offset: i64,
118 limit: i64,
119 ) -> impl Future<Output = Result<Vec<Self>>> + Send + 'a {
120 Self::stream_all_paginated(db, offset, limit).try_collect()
121 }
122
123 fn patch<'a, 'c: 'a, P>(
125 &'a mut self,
126 db: impl Executor<'c, Database = Db> + 'a,
127 patch: P,
128 ) -> impl Future<Output = Result<()>> + Send + 'a
129 where
130 P: Patch<Table = Self>,
131 {
132 async move {
133 let patch: P = patch;
134 patch.patch_row(db, self.id()).send().await?;
135 patch.apply_to(self);
136 Ok(())
137 }
138 }
139
140 fn update<'a, 'c: 'a>(
142 &'a self,
143 db: impl Executor<'c, Database = Db> + 'a,
144 ) -> impl Future<Output = Result<()>> + Send + 'a;
145
146 fn reload<'a, 'c: 'a>(
148 &'a mut self,
149 db: impl Executor<'c, Database = Db> + 'a,
150 ) -> impl Future<Output = Result<()>> + Send + 'a {
151 async move {
152 *self = Self::get(db, self.id()).send().await?;
153 Ok(())
154 }
155 }
156}
157
158pub trait Delete
159where
160 Self: Table + Sized + Send + Sync + 'static,
161{
162 fn delete_row<'a, 'c: 'a>(
164 db: impl Executor<'c, Database = Db> + 'a,
165 id: Self::Id,
166 ) -> impl Future<Output = Result<()>> + Send + 'a;
167
168 fn delete<'a, 'c: 'a>(
170 self,
171 db: impl Executor<'c, Database = Db> + 'a,
172 ) -> impl Future<Output = Result<()>> + Send + 'a {
173 Self::delete_row(db, self.id())
174 }
175
176 fn delete_ref<'a, 'c: 'a>(
178 &self,
179 db: impl Executor<'c, Database = Db> + 'a,
180 ) -> impl Future<Output = Result<()>> + Send + 'a {
181 Self::delete_row(db, self.id())
182 }
183}
184
185pub trait Patch
187where
188 Self: Sized + Send + Sync + 'static,
189{
190 type Table: Table;
191
192 fn apply_to(self, entity: &mut Self::Table);
195
196 fn patch_row<'a, 'c: 'a>(
198 &'a self,
199 db: impl Executor<'c, Database = Db> + 'a,
200 id: <Self::Table as Table>::Id,
201 ) -> impl Future<Output = Result<()>> + Send + 'a;
202}
203
204pub trait Insert
206where
207 Self: Sized + Send + Sync + 'static,
208{
209 type Table: Table;
210
211 fn insert<'a, 'c: 'a>(
213 self,
214 #[cfg(not(feature = "mysql"))] db: impl Executor<'c, Database = Db> + 'a,
215 #[cfg(feature = "mysql")] db: &'c mut sqlx::MySqlConnection,
216 ) -> impl Future<Output = Result<Self::Table>> + Send + 'a;
217}
218
219trait SendFuture: Future {
221 fn send(self) -> impl Future<Output = Self::Output> + Send
222 where
223 Self: Sized + Send,
224 {
225 self
226 }
227}
228
229impl<T: Future> SendFuture for T {}