good_ormning/runtime/
pg.rs1use {
2 async_trait::async_trait,
3 std::borrow::Cow,
4};
5#[cfg(feature = "chrono")]
6use chrono::{
7 DateTime,
8 FixedOffset,
9 Utc,
10};
11#[cfg(feature = "jiff")]
12use jiff::{
13 Timestamp,
14 Zoned,
15};
16
17pub trait GoodErrorQuery<T> {
18 fn to_good_error_query(self, query: &str) -> Result<T, loga::Error>;
19}
20
21impl<T> GoodErrorQuery<T> for Result<T, tokio_postgres::Error> {
22 fn to_good_error_query(self, query: &str) -> Result<T, loga::Error> {
23 match self {
24 Ok(v) => Ok(v),
25 Err(e) => Err(loga::err(e).context(format!("Error executing query: {}", query))),
26 }
27 }
28}
29
30#[async_trait]
31pub trait PgConnection: Send {
32 async fn execute(
33 &mut self,
34 query: &str,
35 params: &[&(dyn tokio_postgres::types::ToSql + Sync)],
36 ) -> Result<u64, tokio_postgres::Error>;
37 async fn query(
38 &mut self,
39 query: &str,
40 params: &[&(dyn tokio_postgres::types::ToSql + Sync)],
41 ) -> Result<Vec<tokio_postgres::Row>, tokio_postgres::Error>;
42}
43
44#[async_trait]
45impl PgConnection for tokio_postgres::Client {
46 async fn execute(
47 &mut self,
48 query: &str,
49 params: &[&(dyn tokio_postgres::types::ToSql + Sync)],
50 ) -> Result<u64, tokio_postgres::Error> {
51 tokio_postgres::Client::execute(self, query, params).await
52 }
53
54 async fn query(
55 &mut self,
56 query: &str,
57 params: &[&(dyn tokio_postgres::types::ToSql + Sync)],
58 ) -> Result<Vec<tokio_postgres::Row>, tokio_postgres::Error> {
59 tokio_postgres::Client::query(self, query, params).await
60 }
61}
62
63#[async_trait]
64impl PgConnection for tokio_postgres::Transaction<'_> {
65 async fn execute(
66 &mut self,
67 query: &str,
68 params: &[&(dyn tokio_postgres::types::ToSql + Sync)],
69 ) -> Result<u64, tokio_postgres::Error> {
70 tokio_postgres::Transaction::execute(self, query, params).await
71 }
72
73 async fn query(
74 &mut self,
75 query: &str,
76 params: &[&(dyn tokio_postgres::types::ToSql + Sync)],
77 ) -> Result<Vec<tokio_postgres::Row>, tokio_postgres::Error> {
78 tokio_postgres::Transaction::query(self, query, params).await
79 }
80}
81
82pub trait GoodOrmningCustomAuto<T> {
83 fn to_sql(value: &T) -> i64;
84 fn from_sql(value: i64) -> Result<T, String>;
85}
86
87pub trait GoodOrmningCustomBool<T> {
88 fn to_sql(value: &T) -> bool;
89 fn from_sql(value: bool) -> Result<T, String>;
90}
91
92pub trait GoodOrmningCustomI16<T> {
93 fn to_sql(value: &T) -> i16;
94 fn from_sql(value: i16) -> Result<T, String>;
95}
96
97pub trait GoodOrmningCustomI32<T> {
98 fn to_sql(value: &T) -> i32;
99 fn from_sql(value: i32) -> Result<T, String>;
100}
101
102pub trait GoodOrmningCustomI64<T> {
103 fn to_sql(value: &T) -> i64;
104 fn from_sql(value: i64) -> Result<T, String>;
105}
106
107pub trait GoodOrmningCustomU32<T> {
108 fn to_sql(value: &T) -> i64;
109 fn from_sql(value: i64) -> Result<T, String>;
110}
111
112pub trait GoodOrmningCustomF32<T> {
113 fn to_sql(value: &T) -> f32;
114 fn from_sql(value: f32) -> Result<T, String>;
115}
116
117pub trait GoodOrmningCustomF64<T> {
118 fn to_sql(value: &T) -> f64;
119 fn from_sql(value: f64) -> Result<T, String>;
120}
121
122pub trait GoodOrmningCustomString<T> {
123 fn to_sql(value: &T) -> &str;
124 fn from_sql(value: String) -> Result<T, String>;
125}
126
127pub trait GoodOrmningCustomBytes<T> {
128 fn to_sql<'a>(value: &'a T) -> Cow<'a, [u8]>;
129 fn from_sql(value: Vec<u8>) -> Result<T, String>;
130}
131
132#[cfg(feature = "chrono")]
133pub trait GoodOrmningCustomUtcTimeChrono<T> {
134 fn to_sql(value: &T) -> DateTime<Utc>;
135 fn from_sql(value: DateTime<Utc>) -> Result<T, String>;
136}
137
138#[cfg(feature = "chrono")]
139pub trait GoodOrmningCustomFixedOffsetTimeChrono<T> {
140 fn to_sql(value: &T) -> DateTime<FixedOffset>;
141 fn from_sql(value: DateTime<FixedOffset>) -> Result<T, String>;
142}
143
144#[cfg(feature = "jiff")]
145pub trait GoodOrmningCustomUtcTimeJiff<T> {
146 fn to_sql(value: &T) -> Timestamp;
147 fn from_sql(value: Timestamp) -> Result<T, String>;
148}
149
150#[cfg(feature = "jiff")]
151pub trait GoodOrmningCustomFixedOffsetTimeJiff<T> {
152 fn to_sql(value: &T) -> Zoned;
153 fn from_sql(value: Zoned) -> Result<T, String>;
154}