xdl_dataframe/
database.rs

1//! Database integration - convert between DataFrame and database Recordset
2
3#[cfg(feature = "database-integration")]
4use crate::dataframe::DataFrame;
5#[cfg(feature = "database-integration")]
6use crate::error::DataFrameResult;
7#[cfg(feature = "database-integration")]
8use crate::series::Series;
9#[cfg(feature = "database-integration")]
10use indexmap::IndexMap;
11#[cfg(feature = "database-integration")]
12use serde_json::Value as JsonValue;
13#[cfg(feature = "database-integration")]
14use xdl_core::XdlValue;
15#[cfg(feature = "database-integration")]
16use xdl_database::Recordset;
17
18/// Convert a database Recordset to a DataFrame
19#[cfg(feature = "database-integration")]
20pub fn from_recordset(recordset: &Recordset) -> DataFrameResult<DataFrame> {
21    let column_names = recordset.column_names();
22    let mut columns = IndexMap::new();
23
24    // Extract each column
25    for col_name in &column_names {
26        let col_data = recordset.get_column(col_name)?;
27        columns.insert(col_name.clone(), Series::from_vec(col_data)?);
28    }
29
30    DataFrame::from_columns(columns)
31}
32
33/// Convert DataFrame to JSON values (compatible with Recordset format)
34#[cfg(feature = "database-integration")]
35pub fn to_json_rows(dataframe: &DataFrame) -> Vec<Vec<JsonValue>> {
36    let mut rows = Vec::new();
37
38    for row_idx in 0..dataframe.nrows() {
39        let mut row = Vec::new();
40        for col_name in dataframe.column_names() {
41            if let Ok(series) = dataframe.column(&col_name) {
42                if let Ok(value) = series.get(row_idx) {
43                    row.push(xdl_value_to_json(value));
44                }
45            }
46        }
47        rows.push(row);
48    }
49
50    rows
51}
52
53#[cfg(feature = "database-integration")]
54fn xdl_value_to_json(value: &XdlValue) -> JsonValue {
55    match value {
56        XdlValue::Undefined => JsonValue::Null,
57        XdlValue::Int(i) => JsonValue::from(*i),
58        XdlValue::Long(l) => JsonValue::from(*l),
59        XdlValue::Long64(l) => JsonValue::from(*l),
60        XdlValue::Float(f) => JsonValue::from(*f),
61        XdlValue::Double(d) => JsonValue::from(*d),
62        XdlValue::String(s) => JsonValue::from(s.clone()),
63        XdlValue::NestedArray(arr) => JsonValue::Array(arr.iter().map(xdl_value_to_json).collect()),
64        _ => JsonValue::String(value.to_string_repr()),
65    }
66}
67
68#[cfg(not(feature = "database-integration"))]
69use crate::dataframe::DataFrame;
70#[cfg(not(feature = "database-integration"))]
71use crate::error::{DataFrameError, DataFrameResult};
72
73#[cfg(not(feature = "database-integration"))]
74pub fn from_recordset(_recordset: &()) -> DataFrameResult<DataFrame> {
75    Err(DataFrameError::InvalidOperation(
76        "Database integration not enabled. Enable the 'database-integration' feature".to_string(),
77    ))
78}