1use sqlx::{PgPool, postgres::PgPoolOptions};
4use super::models::*;
5
6pub struct PostgresClient {
8 pool: PgPool,
9}
10
11impl PostgresClient {
12 pub async fn connect(database_url: &str) -> Result<Self, sqlx::Error> {
14 let pool = PgPoolOptions::new()
15 .max_connections(5)
16 .connect(database_url)
17 .await?;
18
19 Ok(Self { pool })
20 }
21
22 pub async fn create_table(&self) -> Result<(), sqlx::Error> {
24 sqlx::query(POSTGRES_CREATE_TABLE)
25 .execute(&self.pool)
26 .await?;
27 Ok(())
28 }
29
30 pub async fn insert(&self, record: &NfeRecord) -> Result<(), sqlx::Error> {
32 sqlx::query(POSTGRES_INSERT)
33 .bind(&record.id)
34 .bind(&record.chave_acesso)
35 .bind(record.numero)
36 .bind(record.serie)
37 .bind(record.data_emissao)
38 .bind(&record.emit_cnpj)
39 .bind(&record.emit_razao_social)
40 .bind(&record.dest_cnpj)
41 .bind(&record.dest_razao_social)
42 .bind(record.valor_total)
43 .bind(&record.xml)
44 .bind(&record.json_data)
45 .execute(&self.pool)
46 .await?;
47 Ok(())
48 }
49
50 pub async fn find_by_chave(&self, chave: &str) -> Result<Option<NfeRecord>, sqlx::Error> {
52 let row = sqlx::query_as::<_, (String, String, i32, i16, chrono::DateTime<chrono::Utc>, String, String, Option<String>, Option<String>, f64, String, String, chrono::DateTime<chrono::Utc>)>(
53 "SELECT id, chave_acesso, numero, serie, data_emissao, emit_cnpj, emit_razao_social, dest_cnpj, dest_razao_social, valor_total::float8, xml, json_data::text, created_at FROM nfe WHERE chave_acesso = $1"
54 )
55 .bind(chave)
56 .fetch_optional(&self.pool)
57 .await?;
58
59 Ok(row.map(|r| NfeRecord {
60 id: r.0,
61 chave_acesso: r.1,
62 numero: r.2,
63 serie: r.3,
64 data_emissao: r.4,
65 emit_cnpj: r.5,
66 emit_razao_social: r.6,
67 dest_cnpj: r.7,
68 dest_razao_social: r.8,
69 valor_total: r.9,
70 xml: r.10,
71 json_data: r.11,
72 created_at: r.12,
73 }))
74 }
75
76 pub async fn list(&self, limit: i64, offset: i64) -> Result<Vec<NfeRecord>, sqlx::Error> {
78 let rows = sqlx::query_as::<_, (String, String, i32, i16, chrono::DateTime<chrono::Utc>, String, String, Option<String>, Option<String>, f64, String, String, chrono::DateTime<chrono::Utc>)>(
79 "SELECT id, chave_acesso, numero, serie, data_emissao, emit_cnpj, emit_razao_social, dest_cnpj, dest_razao_social, valor_total::float8, xml, json_data::text, created_at FROM nfe ORDER BY created_at DESC LIMIT $1 OFFSET $2"
80 )
81 .bind(limit)
82 .bind(offset)
83 .fetch_all(&self.pool)
84 .await?;
85
86 Ok(rows.into_iter().map(|r| NfeRecord {
87 id: r.0,
88 chave_acesso: r.1,
89 numero: r.2,
90 serie: r.3,
91 data_emissao: r.4,
92 emit_cnpj: r.5,
93 emit_razao_social: r.6,
94 dest_cnpj: r.7,
95 dest_razao_social: r.8,
96 valor_total: r.9,
97 xml: r.10,
98 json_data: r.11,
99 created_at: r.12,
100 }).collect())
101 }
102}