1use crate::{
2 ColumnDef, Context, DataSet, Driver, Error, Executor, Expression, Result, Row, RowLabeled,
3 RowsAffected, TableRef, Value, stream::Stream, writer::SqlWriter,
4};
5use futures::{FutureExt, StreamExt, TryFutureExt};
6use log::Level;
7use std::{future::Future, pin::pin};
8
9pub trait Entity {
10 type PrimaryKey<'a>;
11
12 fn table_ref() -> &'static TableRef;
13 fn columns() -> &'static [ColumnDef];
14 fn primary_key_def() -> impl ExactSizeIterator<Item = &'static ColumnDef>;
15 fn unique_defs()
16 -> impl ExactSizeIterator<Item = impl ExactSizeIterator<Item = &'static ColumnDef>>;
17
18 fn from_row(row: RowLabeled) -> Result<Self>
19 where
20 Self: Sized;
21
22 fn create_table<Exec: Executor>(
23 executor: &mut Exec,
24 if_not_exists: bool,
25 create_schema: bool,
26 ) -> impl Future<Output = Result<()>> + Send;
27
28 fn drop_table<Exec: Executor>(
29 executor: &mut Exec,
30 if_exists: bool,
31 drop_schema: bool,
32 ) -> impl Future<Output = Result<()>> + Send;
33
34 fn insert_one<Exec: Executor, E: Entity>(
35 executor: &mut Exec,
36 entity: &E,
37 ) -> impl Future<Output = Result<RowsAffected>> + Send;
38
39 fn insert_many<'a, Exec, It>(
40 executor: &mut Exec,
41 items: It,
42 ) -> impl Future<Output = Result<RowsAffected>> + Send
43 where
44 Self: 'a,
45 Exec: Executor,
46 It: IntoIterator<Item = &'a Self> + Send;
47
48 fn find_pk<Exec: Executor>(
49 executor: &mut Exec,
50 primary_key: &Self::PrimaryKey<'_>,
51 ) -> impl Future<Output = Result<Option<Self>>> + Send
52 where
53 Self: Sized;
54
55 fn find_one<Exec: Executor, Expr: Expression>(
56 executor: &mut Exec,
57 condition: &Expr,
58 ) -> impl Future<Output = Result<Option<Self>>> + Send
59 where
60 Self: Sized,
61 {
62 let stream = Self::find_many(executor, condition, Some(1));
63 async move { pin!(stream).into_future().map(|(v, _)| v).await.transpose() }
64 }
65
66 fn find_many<Exec: Executor, Expr: Expression>(
67 executor: &mut Exec,
68 condition: &Expr,
69 limit: Option<u32>,
70 ) -> impl Stream<Item = Result<Self>> + Send
71 where
72 Self: Sized;
73
74 fn delete_one<Exec: Executor>(
75 executor: &mut Exec,
76 primary_key: Self::PrimaryKey<'_>,
77 ) -> impl Future<Output = Result<RowsAffected>> + Send
78 where
79 Self: Sized;
80
81 fn delete_many<Exec: Executor, Expr: Expression>(
82 executor: &mut Exec,
83 condition: &Expr,
84 ) -> impl Future<Output = Result<RowsAffected>> + Send
85 where
86 Self: Sized;
87
88 fn row_filtered(&self) -> Box<[(&'static str, Value)]>;
89 fn row_full(&self) -> Row;
90 fn primary_key(&self) -> Self::PrimaryKey<'_>;
91 fn save<Exec: Executor>(&self, executor: &mut Exec) -> impl Future<Output = Result<()>> + Send
92 where
93 Self: Sized,
94 {
95 let mut query = String::with_capacity(512);
96 executor
97 .driver()
98 .sql_writer()
99 .write_insert(&mut query, [self], true);
100 executor.execute(query.into()).map_ok(|_| ())
101 }
102 fn delete<Exec: Executor>(&self, executor: &mut Exec) -> impl Future<Output = Result<()>> + Send
103 where
104 Self: Sized,
105 {
106 Self::delete_one(executor, self.primary_key()).map(|v| {
107 v.and_then(|v| {
108 if v.rows_affected == 1 {
109 Ok(())
110 } else {
111 let error = Error::msg(format!(
112 "The query deleted {} rows instead of the expected 1",
113 v.rows_affected
114 ));
115 log::log!(
116 if v.rows_affected == 0 {
117 Level::Info
118 } else {
119 Level::Error
120 },
121 "{}",
122 error
123 );
124 Err(error)
125 }
126 })
127 })
128 }
129}
130
131impl<E: Entity> DataSet for E {
132 fn qualified_columns() -> bool
133 where
134 Self: Sized,
135 {
136 false
137 }
138 fn write_query(&self, writer: &dyn SqlWriter, context: &mut Context, buff: &mut String) {
139 Self::table_ref().write_query(writer, context, buff);
140 }
141}