1use std::future::Future;
4use std::pin::Pin;
5
6use crate::error::QueryResult;
7use crate::filter::Filter;
8
9pub trait Model: Sized + Send + Sync {
11 const MODEL_NAME: &'static str;
13
14 const TABLE_NAME: &'static str;
16
17 const PRIMARY_KEY: &'static [&'static str];
19
20 const COLUMNS: &'static [&'static str];
22}
23
24pub trait IntoFilter {
26 fn into_filter(self) -> Filter;
28}
29
30impl IntoFilter for Filter {
31 fn into_filter(self) -> Filter {
32 self
33 }
34}
35
36impl<F: FnOnce() -> Filter> IntoFilter for F {
37 fn into_filter(self) -> Filter {
38 self()
39 }
40}
41
42pub trait Executable {
44 type Output;
46
47 fn exec(self) -> impl Future<Output = QueryResult<Self::Output>> + Send;
49}
50
51pub type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
53
54pub trait QueryEngine: Send + Sync + Clone + 'static {
60 fn query_many<T: Model + Send + 'static>(
62 &self,
63 sql: &str,
64 params: Vec<crate::filter::FilterValue>,
65 ) -> BoxFuture<'_, QueryResult<Vec<T>>>;
66
67 fn query_one<T: Model + Send + 'static>(
69 &self,
70 sql: &str,
71 params: Vec<crate::filter::FilterValue>,
72 ) -> BoxFuture<'_, QueryResult<T>>;
73
74 fn query_optional<T: Model + Send + 'static>(
76 &self,
77 sql: &str,
78 params: Vec<crate::filter::FilterValue>,
79 ) -> BoxFuture<'_, QueryResult<Option<T>>>;
80
81 fn execute_insert<T: Model + Send + 'static>(
83 &self,
84 sql: &str,
85 params: Vec<crate::filter::FilterValue>,
86 ) -> BoxFuture<'_, QueryResult<T>>;
87
88 fn execute_update<T: Model + Send + 'static>(
90 &self,
91 sql: &str,
92 params: Vec<crate::filter::FilterValue>,
93 ) -> BoxFuture<'_, QueryResult<Vec<T>>>;
94
95 fn execute_delete(
97 &self,
98 sql: &str,
99 params: Vec<crate::filter::FilterValue>,
100 ) -> BoxFuture<'_, QueryResult<u64>>;
101
102 fn execute_raw(
104 &self,
105 sql: &str,
106 params: Vec<crate::filter::FilterValue>,
107 ) -> BoxFuture<'_, QueryResult<u64>>;
108
109 fn count(
111 &self,
112 sql: &str,
113 params: Vec<crate::filter::FilterValue>,
114 ) -> BoxFuture<'_, QueryResult<u64>>;
115}
116
117pub trait ModelAccessor<E: QueryEngine>: Send + Sync {
121 type Model: Model;
123
124 fn engine(&self) -> &E;
126
127 fn find_many(&self) -> crate::operations::FindManyOperation<E, Self::Model>;
129
130 fn find_unique(&self) -> crate::operations::FindUniqueOperation<E, Self::Model>;
132
133 fn find_first(&self) -> crate::operations::FindFirstOperation<E, Self::Model>;
135
136 fn create(
138 &self,
139 data: <Self::Model as CreateData>::Data,
140 ) -> crate::operations::CreateOperation<E, Self::Model>
141 where
142 Self::Model: CreateData;
143
144 fn update(&self) -> crate::operations::UpdateOperation<E, Self::Model>;
146
147 fn delete(&self) -> crate::operations::DeleteOperation<E, Self::Model>;
149
150 fn upsert(
152 &self,
153 create: <Self::Model as CreateData>::Data,
154 update: <Self::Model as UpdateData>::Data,
155 ) -> crate::operations::UpsertOperation<E, Self::Model>
156 where
157 Self::Model: CreateData + UpdateData;
158
159 fn count(&self) -> crate::operations::CountOperation<E, Self::Model>;
161}
162
163pub trait CreateData: Model {
165 type Data: Send + Sync;
167}
168
169pub trait UpdateData: Model {
171 type Data: Send + Sync;
173}
174
175pub trait UpsertData: CreateData + UpdateData {}
177
178impl<T: CreateData + UpdateData> UpsertData for T {}
179
180pub trait WithRelations: Model {
182 type Include;
184
185 type Select;
187}
188
189#[cfg(test)]
190mod tests {
191 use super::*;
192
193 struct TestModel;
194
195 impl Model for TestModel {
196 const MODEL_NAME: &'static str = "TestModel";
197 const TABLE_NAME: &'static str = "test_models";
198 const PRIMARY_KEY: &'static [&'static str] = &["id"];
199 const COLUMNS: &'static [&'static str] = &["id", "name", "email"];
200 }
201
202 #[test]
203 fn test_model_trait() {
204 assert_eq!(TestModel::MODEL_NAME, "TestModel");
205 assert_eq!(TestModel::TABLE_NAME, "test_models");
206 assert_eq!(TestModel::PRIMARY_KEY, &["id"]);
207 }
208
209 #[test]
210 fn test_into_filter() {
211 let filter = Filter::Equals("id".into(), crate::filter::FilterValue::Int(1));
212 let converted = filter.clone().into_filter();
213 assert_eq!(converted, filter);
214 }
215}