parsql_postgres/
crud_ops.rs

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
use parsql_core::{Deleteable, Insertable, Queryable, Updateable};
use postgres::{types::ToSql, Client, Error, Row};

pub trait SqlParams {
    fn params(&self) -> Vec<&(dyn ToSql + Sync)>;
}

pub fn insert<T: Insertable + SqlParams>(client: &mut Client, entity: T) -> Result<u64, Error> {
    let table = T::table_name();
    let columns = T::columns().join(", ");
    let placeholders = (1..=T::columns().len())
        .map(|i| format!("${}", i))
        .collect::<Vec<_>>()
        .join(", ");

    let sql = format!(
        "INSERT INTO {} ({}) VALUES ({})",
        table, columns, placeholders
    );

    let params = entity.params();

    client.execute(&sql, &params)
}

pub fn update<T: Updateable + SqlParams>(
    mut client: postgres::Client,
    entity: T,
) -> Result<u64, Error> {
    let table_name = T::table_name();
    let update_clause = T::update_clause();
    let where_clause = T::where_clause();

    // Sütunları "name = $1, age = $2" formatında birleştir
    let update_clause = update_clause
        .iter()
        .enumerate()
        .map(|(i, col)| format!("{} = ${}", col, i + 1))
        .collect::<Vec<_>>()
        .join(", ");

    let sql = format!(
        "UPDATE {} SET {} WHERE {}",
        table_name, update_clause, where_clause
    );

    let params = entity.params();

    match client.execute(&sql, &params) {
        Ok(rows_affected) => Ok(rows_affected),
        Err(e) => Err(e),
    }
}

pub fn delete<T: Deleteable + SqlParams>(
    mut client: postgres::Client,
    entity: T,
) -> Result<u64, Error> {
    let table_name = T::table_name();
    let where_clause = T::where_clause();

    let sql = format!("DELETE FROM {} WHERE {}", table_name, where_clause);

    let params = entity.params();

    match client.execute(&sql, &params) {
        Ok(rows_affected) => Ok(rows_affected),
        Err(e) => Err(e),
    }
}

pub fn get<T: Queryable + SqlParams, F, R>(
    mut client: postgres::Client,
    entity: T,
    to_model: F,
) -> Result<R, Error>
where
    F: Fn(&Row) -> Result<R, Error>,
{
    let table_name = T::table_name();
    let select_clause = T::select_clause().join(", ");
    let where_clause = T::where_clause();

    let sql = format!(
        "SELECT {} FROM {} WHERE {}",
        select_clause, table_name, where_clause
    );

    let params = entity.params();

    let query = client.prepare(&sql).unwrap();

    match client.query_one(&query, &params) {
        Ok(row) => Ok(to_model(&row)?),
        Err(e) => Err(e),
    }
}