parsql_postgres/
crud_ops.rs1use parsql_core::{Deleteable, Insertable, Queryable, Updateable};
2use postgres::{types::ToSql, Client, Error, Row};
3
4pub trait SqlParams {
5 fn params(&self) -> Vec<&(dyn ToSql + Sync)>;
6}
7
8pub trait UpdateParams {
9 fn params(&self) -> Vec<&(dyn ToSql + Sync)>;
10}
11
12pub trait FromRow {
13 fn from_row(row: &Row) -> Self;
14}
15
16pub fn insert<T: Insertable + SqlParams>(client: &mut Client, entity: T) -> Result<u64, Error> {
17 let table = T::table_name();
18 let columns = T::columns().join(", ");
19 let placeholders = (1..=T::columns().len())
20 .map(|i| format!("${}", i))
21 .collect::<Vec<_>>()
22 .join(", ");
23
24 let sql = format!(
25 "INSERT INTO {} ({}) VALUES ({})",
26 table, columns, placeholders
27 );
28
29 let params = entity.params();
30
31 client.execute(&sql, ¶ms)
32}
33
34pub fn update<T: Updateable + UpdateParams>(
35 client: &mut postgres::Client,
36 entity: T,
37) -> Result<u64, Error> {
38 let table_name = T::table_name();
39 let update_clause = T::update_clause();
40 let where_clause = T::where_clause();
41
42 let update_clause = update_clause
44 .iter()
45 .enumerate()
46 .map(|(i, col)| format!("{} = ${}", col, i + 1))
47 .collect::<Vec<_>>()
48 .join(", ");
49
50 let sql = format!(
51 "UPDATE {} SET {} WHERE {}",
52 table_name, update_clause, where_clause
53 );
54
55 let params = entity.params();
56
57 match client.execute(&sql, ¶ms) {
58 Ok(rows_affected) => Ok(rows_affected),
59 Err(e) => Err(e),
60 }
61}
62
63pub fn delete<T: Deleteable + SqlParams>(
64 client: &mut postgres::Client,
65 entity: T,
66) -> Result<u64, Error> {
67 let table_name = T::table_name();
68 let where_clause = T::where_clause();
69
70 let sql = format!("DELETE FROM {} WHERE {}", table_name, where_clause);
71
72 let params = entity.params();
73
74 match client.execute(&sql, ¶ms) {
75 Ok(rows_affected) => Ok(rows_affected),
76 Err(e) => Err(e),
77 }
78}
79
80pub fn get<T: Queryable + FromRow + SqlParams>(
81 client: &mut postgres::Client,
82 entity: T,
83) -> Result<T, Error>
84{
85 let table_name = T::table_name();
86 let select_clause = T::select_clause().join(", ");
87 let where_clause = T::where_clause();
88
89 let sql = format!(
90 "SELECT {} FROM {} WHERE {}",
91 select_clause, table_name, where_clause
92 );
93
94 let params = entity.params();
95
96 let query = client.prepare(&sql).unwrap();
97
98 match client.query_one(&query, ¶ms) {
99 Ok(row) => Ok(T::from_row(&row)),
100 Err(e) => Err(e),
101 }
102}
103
104pub fn select<T: Queryable + SqlParams, F>(
105 client: &mut postgres::Client,
106 entity: T,
107 to_model: F,
108) -> Result<T, Error>
109where
110 F: Fn(&Row) -> Result<T, Error>,
111{
112 let table_name = T::table_name();
113 let select_clause = T::select_clause().join(", ");
114 let where_clause = T::where_clause();
115
116 let sql = format!(
117 "SELECT {} FROM {} WHERE {}",
118 select_clause, table_name, where_clause
119 );
120
121 let params = entity.params();
122
123 let query = client.prepare(&sql).unwrap();
124
125 match client.query_one(&query, ¶ms) {
126 Ok(row) => Ok(to_model(&row)?),
127 Err(e) => Err(e),
128 }
129}