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;
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 =
47                    row.get_value(index).map_err(|e| WaeError::internal(format!("Failed to get column {}: {}", index, e)))?;
48                T::from_turso_value(value)
49            }
50            #[cfg(feature = "postgres")]
51            Self::Postgres(row) => T::from_postgres_row(row, index),
52            #[cfg(feature = "mysql")]
53            Self::MySql(row) => T::from_mysql_row(row, index),
54        }
55    }
56
57    /// 获取列数量
58    pub fn column_count(&self) -> usize {
59        match self {
60            #[cfg(feature = "turso")]
61            Self::Turso(row) => row.column_count(),
62            #[cfg(feature = "postgres")]
63            Self::Postgres(row) => row.len(),
64            #[cfg(feature = "mysql")]
65            Self::MySql(row) => row.len(),
66        }
67    }
68}
69
70/// 查询结果集迭代器
71pub enum DatabaseRows {
72    /// Turso 数据库结果集
73    #[cfg(feature = "turso")]
74    Turso(turso::Rows),
75    /// PostgreSQL 数据库结果集
76    #[cfg(feature = "postgres")]
77    Postgres(Vec<PostgresRow>, usize),
78    /// MySQL 数据库结果集
79    #[cfg(feature = "mysql")]
80    MySql(Vec<MySqlRow>, usize),
81}
82
83impl DatabaseRows {
84    #[cfg(feature = "turso")]
85    pub(crate) fn new_turso(rows: turso::Rows) -> Self {
86        Self::Turso(rows)
87    }
88
89    #[cfg(feature = "postgres")]
90    pub(crate) fn new_postgres(rows: Vec<PostgresRow>) -> Self {
91        Self::Postgres(rows, 0)
92    }
93
94    #[cfg(feature = "mysql")]
95    pub(crate) fn new_mysql(rows: Vec<MySqlRow>) -> Self {
96        Self::MySql(rows, 0)
97    }
98
99    /// 获取下一行
100    pub async fn next(&mut self) -> DatabaseResult<Option<DatabaseRow>> {
101        match self {
102            #[cfg(feature = "turso")]
103            Self::Turso(rows) => rows
104                .next()
105                .await
106                .map_err(|e| WaeError::internal(format!("Failed to fetch row: {}", e)))
107                .map(|opt| opt.map(DatabaseRow::new_turso)),
108            #[cfg(feature = "postgres")]
109            Self::Postgres(rows, index) => {
110                if *index < rows.len() {
111                    let row = DatabaseRow::new_postgres(rows[*index].clone());
112                    *index += 1;
113                    Ok(Some(row))
114                }
115                else {
116                    Ok(None)
117                }
118            }
119            #[cfg(feature = "mysql")]
120            Self::MySql(rows, index) => {
121                if *index < rows.len() {
122                    let row = DatabaseRow::new_mysql(rows[*index].clone());
123                    *index += 1;
124                    Ok(Some(row))
125                }
126                else {
127                    Ok(None)
128                }
129            }
130        }
131    }
132
133    /// 收集所有行
134    pub async fn collect(mut self) -> DatabaseResult<Vec<DatabaseRow>> {
135        let mut rows = Vec::new();
136        while let Some(row) = self.next().await? {
137            rows.push(row);
138        }
139        Ok(rows)
140    }
141}