chuchi_postgres/table/
table_owned.rs1use super::util::info_data_to_sql;
6use super::{Info, TableTemplate};
7
8use crate::connection::ConnectionOwned;
9use crate::database::DatabaseError;
10use crate::filter::{Filter, WhereFilter};
11use crate::row::ToRow;
12use crate::{Database, Error, Result, filter};
13
14use std::borrow::Borrow;
15use std::marker::PhantomData;
16use std::sync::Arc;
17
18#[derive(Debug)]
19struct TableMeta {
20 info: Info,
21}
22
23#[derive(Debug)]
24pub struct TableOwned<T>
25where
26 T: TableTemplate,
27{
28 db: Database,
29 name: &'static str,
30 meta: Arc<TableMeta>,
31 phantom: PhantomData<T>,
32}
33
34impl<T> TableOwned<T>
35where
36 T: TableTemplate,
37{
38 pub(crate) fn new(db: Database, name: &'static str) -> Self {
39 let info = T::table_info();
40 let meta = TableMeta { info };
41
42 Self {
43 db,
44 name,
45 meta: Arc::new(meta),
46 phantom: PhantomData,
47 }
48 }
49
50 pub fn name(&self) -> &'static str {
51 self.name
52 }
53
54 pub fn info(&self) -> &Info {
55 &self.meta.info
56 }
57
58 pub async fn get_connection(&self) -> Result<ConnectionOwned> {
59 self.db.get().await.map_err(|e| match e {
60 DatabaseError::Other(e) => e.into(),
61 e => Error::Unknown(e.into()),
62 })
63 }
64
65 pub async fn try_create(&self) -> Result<()> {
67 let sql = info_data_to_sql(self.name, self.meta.info.data());
68
69 self.get_connection()
70 .await?
71 .connection()
72 .batch_execute(sql.as_str())
73 .await
74 }
75
76 pub async fn create(self) -> Self {
79 self.try_create().await.expect("could not create table");
80 self
81 }
82
83 pub async fn insert_one(&self, input: &T) -> Result<()> {
87 self.get_connection()
88 .await?
89 .connection()
90 .insert(self.name, input)
91 .await
92 }
93
94 pub async fn insert_many<I>(&self, input: I) -> Result<()>
95 where
96 I: IntoIterator,
97 I::Item: Borrow<T>,
98 {
99 let mut conn = self.get_connection().await?;
100 let trans = conn.transaction().await?;
101 let conn = trans.connection();
102
103 conn.insert_many(self.name, input).await?;
104
105 trans.commit().await?;
106
107 Ok(())
108 }
109
110 pub async fn find_all(&self) -> Result<Vec<T>> {
114 self.get_connection()
115 .await?
116 .connection()
117 .select(self.name, filter!())
118 .await
119 }
120
121 pub async fn find_many(
122 &self,
123 filter: impl Borrow<Filter<'_>>,
124 ) -> Result<Vec<T>> {
125 self.get_connection()
126 .await?
127 .connection()
128 .select(self.name, filter)
129 .await
130 }
131
132 pub async fn find_one(
133 &self,
134 filter: impl Borrow<Filter<'_>>,
135 ) -> Result<Option<T>> {
136 self.get_connection()
137 .await?
138 .connection()
139 .select_opt(self.name, filter)
140 .await
141 }
142
143 pub async fn count<'a>(
144 &self,
145 column: &str,
146 filter: impl Borrow<Filter<'_>>,
147 ) -> Result<u64> {
148 self.get_connection()
149 .await?
150 .connection()
151 .count(self.name, column, filter)
152 .await
153 }
154
155 pub async fn update<'a, U>(
157 &self,
158 item: &U,
159 filter: impl Borrow<WhereFilter<'a>>,
160 ) -> Result<()>
161 where
162 U: ToRow,
163 {
164 self.get_connection()
165 .await?
166 .connection()
167 .update(self.name, item, filter)
168 .await
169 }
170
171 pub async fn update_full<'a>(
172 &self,
173 input: &'a T,
174 filter: impl Borrow<WhereFilter<'a>>,
175 ) -> Result<()> {
176 self.get_connection()
177 .await?
178 .connection()
179 .update(self.name, input, filter)
180 .await
181 }
182
183 pub async fn delete(
185 &self,
186 filter: impl Borrow<WhereFilter<'_>>,
187 ) -> Result<()> {
188 self.get_connection()
189 .await?
190 .connection()
191 .delete(self.name, filter)
192 .await
193 }
194}
195
196impl<T> Clone for TableOwned<T>
197where
198 T: TableTemplate,
199{
200 fn clone(&self) -> Self {
201 Self {
202 db: self.db.clone(),
203 name: self.name,
204 meta: self.meta.clone(),
205 phantom: PhantomData,
206 }
207 }
208}