1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
use std::borrow::{Borrow, Cow};

use crate::{
	filter::{Filter, WhereFilter},
	row::{FromRowOwned, NamedColumns, ToRow, ToRowStatic},
	Connection, Error,
};

#[derive(Debug, Clone)]
pub struct Table {
	name: Cow<'static, str>,
}

impl Table {
	pub fn new(name: impl Into<Cow<'static, str>>) -> Self {
		Self { name: name.into() }
	}

	pub fn name(&self) -> &str {
		self.name.as_ref()
	}

	pub fn with_conn<'a>(&'a self, conn: Connection<'a>) -> TableWithConn<'a> {
		TableWithConn { table: &self, conn }
	}
}

#[derive(Debug, Clone)]
pub struct TableWithConn<'a> {
	table: &'a Table,
	conn: Connection<'a>,
}

impl TableWithConn<'_> {
	/// Get the name of the table
	pub fn name(&self) -> &str {
		self.table.name.as_ref()
	}

	pub async fn select<R>(
		&self,
		filter: impl Borrow<Filter<'_>>,
	) -> Result<Vec<R>, Error>
	where
		R: FromRowOwned + NamedColumns,
	{
		self.conn.select(self.name(), filter).await
	}

	pub async fn select_one<R>(
		&self,
		filter: impl Borrow<Filter<'_>>,
	) -> Result<R, Error>
	where
		R: FromRowOwned + NamedColumns,
	{
		self.conn.select_one(self.name(), filter).await
	}

	pub async fn select_opt<R>(
		&self,
		filter: impl Borrow<Filter<'_>>,
	) -> Result<Option<R>, Error>
	where
		R: FromRowOwned + NamedColumns,
	{
		self.conn.select_opt(self.name(), filter).await
	}

	pub async fn count(
		&self,
		column: &str,
		filter: impl Borrow<Filter<'_>>,
	) -> Result<u32, Error> {
		self.conn.count(self.name(), column, filter).await
	}

	pub async fn insert<U>(&self, item: &U) -> Result<(), Error>
	where
		U: ToRow,
	{
		self.conn.insert(self.name(), item).await
	}

	pub async fn insert_many<U, I>(&self, items: I) -> Result<(), Error>
	where
		U: ToRowStatic,
		I: IntoIterator,
		I::Item: Borrow<U>,
	{
		self.conn.insert_many(self.name(), items).await
	}

	pub async fn update<U>(
		&self,
		item: &U,
		filter: impl Borrow<WhereFilter<'_>>,
	) -> Result<(), Error>
	where
		U: ToRow,
	{
		self.conn.update(self.name(), item, filter).await
	}

	pub async fn delete(
		&self,
		filter: impl Borrow<WhereFilter<'_>>,
	) -> Result<(), Error> {
		self.conn.delete(self.name(), filter).await
	}

	pub fn conn(&self) -> &Connection<'_> {
		&self.conn
	}
}