Skip to main content

wae_database/connection/
row.rs

1//! 数据库行和结果集模块
2
3use crate::connection::{config::DatabaseResult, value_impl::FromDatabaseValue};
4#[cfg(feature = "mysql")]
5use mysql_async::Row as MySqlRow;
6#[cfg(feature = "postgres")]
7use tokio_postgres::Row as PostgresRow;
8#[cfg(feature = "turso")]
9use turso::Row;
10use wae_types::{WaeError, WaeErrorKind};
11
12/// 查询结果行
13pub enum DatabaseRow {
14    /// Turso 数据库行
15    #[cfg(feature = "turso")]
16    Turso(Row),
17    /// PostgreSQL 数据库行
18    #[cfg(feature = "postgres")]
19    Postgres(PostgresRow),
20    /// MySQL 数据库行
21    #[cfg(feature = "mysql")]
22    MySql(MySqlRow),
23}
24
25impl DatabaseRow {
26    #[cfg(feature = "turso")]
27    pub(crate) fn new_turso(row: Row) -> Self {
28        Self::Turso(row)
29    }
30
31    #[cfg(feature = "postgres")]
32    pub(crate) fn new_postgres(row: PostgresRow) -> Self {
33        Self::Postgres(row)
34    }
35
36    #[cfg(feature = "mysql")]
37    pub(crate) fn new_mysql(row: MySqlRow) -> Self {
38        Self::MySql(row)
39    }
40
41    /// 获取列值
42    pub fn get<T: FromDatabaseValue>(&self, index: usize) -> DatabaseResult<T> {
43        match self {
44            #[cfg(feature = "turso")]
45            Self::Turso(row) => {
46                let value = row.get_value(index).map_err(|e| {
47                    WaeError::database(WaeErrorKind::QueryFailed {
48                        query: None,
49                        reason: format!("Failed to get column {}: {}", index, e),
50                    })
51                })?;
52                T::from_turso_value(value)
53            }
54            #[cfg(feature = "postgres")]
55            Self::Postgres(row) => T::from_postgres_row(row, index),
56            #[cfg(feature = "mysql")]
57            Self::MySql(row) => T::from_mysql_row(row, index),
58        }
59    }
60
61    /// 获取列数量
62    pub fn column_count(&self) -> usize {
63        match self {
64            #[cfg(feature = "turso")]
65            Self::Turso(row) => row.column_count(),
66            #[cfg(feature = "postgres")]
67            Self::Postgres(row) => row.len(),
68            #[cfg(feature = "mysql")]
69            Self::MySql(row) => row.len(),
70        }
71    }
72}
73
74/// 查询结果集迭代器
75pub enum DatabaseRows {
76    /// Turso 数据库结果集
77    #[cfg(feature = "turso")]
78    Turso(turso::Rows),
79    /// PostgreSQL 数据库结果集
80    #[cfg(feature = "postgres")]
81    Postgres(Vec<PostgresRow>, usize),
82    /// MySQL 数据库结果集
83    #[cfg(feature = "mysql")]
84    MySql(Vec<MySqlRow>, usize),
85}
86
87impl DatabaseRows {
88    #[cfg(feature = "turso")]
89    pub(crate) fn new_turso(rows: turso::Rows) -> Self {
90        Self::Turso(rows)
91    }
92
93    #[cfg(feature = "postgres")]
94    pub(crate) fn new_postgres(rows: Vec<PostgresRow>) -> Self {
95        Self::Postgres(rows, 0)
96    }
97
98    #[cfg(feature = "mysql")]
99    pub(crate) fn new_mysql(rows: Vec<MySqlRow>) -> Self {
100        Self::MySql(rows, 0)
101    }
102
103    /// 获取下一行
104    pub async fn next(&mut self) -> DatabaseResult<Option<DatabaseRow>> {
105        match self {
106            #[cfg(feature = "turso")]
107            Self::Turso(rows) => rows
108                .next()
109                .await
110                .map_err(|e| {
111                    WaeError::database(WaeErrorKind::QueryFailed { query: None, reason: format!("Failed to fetch row: {}", e) })
112                })
113                .map(|opt| opt.map(DatabaseRow::new_turso)),
114            #[cfg(feature = "postgres")]
115            Self::Postgres(rows, index) => {
116                if *index < rows.len() {
117                    let row = DatabaseRow::new_postgres(rows[*index].clone());
118                    *index += 1;
119                    Ok(Some(row))
120                }
121                else {
122                    Ok(None)
123                }
124            }
125            #[cfg(feature = "mysql")]
126            Self::MySql(rows, index) => {
127                if *index < rows.len() {
128                    let row = DatabaseRow::new_mysql(rows[*index].clone());
129                    *index += 1;
130                    Ok(Some(row))
131                }
132                else {
133                    Ok(None)
134                }
135            }
136        }
137    }
138
139    /// 收集所有行
140    pub async fn collect(mut self) -> DatabaseResult<Vec<DatabaseRow>> {
141        let mut rows = Vec::new();
142        while let Some(row) = self.next().await? {
143            rows.push(row);
144        }
145        Ok(rows)
146    }
147}