chuchi_postgres/table/
table_owned.rs

1//! This module exists to help backwards compatibility
2//!
3//! Might remove it in the future, let's see
4
5use 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	// Create
66	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	/// ## Panics
77	/// if the table could not be created
78	pub async fn create(self) -> Self {
79		self.try_create().await.expect("could not create table");
80		self
81	}
82
83	// find
84	// maybe rename to insert
85	// and store statement in table
86	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	/*
111	SELECT id, name, FROM {}
112	*/
113	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	// update one
156	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	// delete one
184	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}