Skip to main content

good_ormning/runtime/
pg.rs

1use {
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}