rbdc_oracle/
decode.rs

1use bigdecimal::BigDecimal;
2use oracle::sql_type::OracleType;
3use rbdc::{datetime::DateTime, Error};
4use rbs::Value;
5use std::str::FromStr;
6
7use crate::OracleData;
8
9pub trait Decode {
10    fn decode(row: &OracleData) -> Result<Value, Error>;
11}
12
13impl Decode for Value {
14    fn decode(row: &OracleData) -> Result<Value, Error> {
15        if row.is_sql_null {
16            return Ok(Value::Null);
17        }
18        match row.column_type {
19            OracleType::Number(p, s) => {
20                let value = row.str.as_ref().unwrap().clone();
21                if p == 0 && s == -127 {
22                    // it means number(*)
23                    let dec =
24                        BigDecimal::from_str(&value).map_err(|e| Error::from(e.to_string()))?;
25                    if dec.is_integer() {
26                        let d = dec.digits();
27                        if 1 <= d && d <= 9 {
28                            let a = value.parse::<i32>()?;
29                            return Ok(Value::I32(a));
30                        } else if 10 <= d && d <= 18 {
31                            let a = value.parse::<i64>()?;
32                            return Ok(Value::I64(a));
33                        }
34                        return Ok(Value::String(dec.to_string()).into_ext("Decimal"));
35                    }
36                    return Ok(Value::String(dec.to_string()).into_ext("Decimal"));
37                }
38                if s > 0 {
39                    let dec =
40                        BigDecimal::from_str(&value).map_err(|e| Error::from(e.to_string()))?;
41                    return Ok(Value::String(dec.to_string()).into_ext("Decimal"));
42                } else if 1 <= p && p <= 9 {
43                    let a = value.parse::<i32>()?;
44                    return Ok(Value::I32(a));
45                } else if 10 <= p && p <= 18 {
46                    let a = value.parse::<i64>()?;
47                    return Ok(Value::I64(a));
48                }
49                let dec = BigDecimal::from_str(&value).map_err(|e| Error::from(e.to_string()))?;
50                return Ok(Value::String(dec.to_string()).into_ext("Decimal"));
51            }
52            //OracleType::Int64 is integer
53            OracleType::Int64 => {
54                let a = row.str.as_ref().unwrap().clone().parse::<i32>()?;
55                return Ok(Value::I32(a));
56            }
57            OracleType::Float(p) => {
58                return if p >= 24 {
59                    let a = row.str.as_ref().unwrap().clone().parse::<f64>()?;
60                    Ok(Value::F64(a))
61                } else {
62                    let a = row.str.as_ref().unwrap().clone().parse::<f32>()?;
63                    Ok(Value::F32(a))
64                }
65            }
66            OracleType::Date => {
67                let a = DateTime::from_str(&row.str.as_ref().unwrap().clone())?;
68                return Ok(Value::from(a));
69            }
70            OracleType::BLOB => {
71                if let Some(a) = &row.bin{
72                    return Ok(Value::Binary(a.clone()));
73                }
74                return Ok(Value::Null);
75            }
76            OracleType::Long => {
77                return Ok(Value::String(row.str.as_ref().unwrap().clone()))
78            }
79            OracleType::CLOB => {
80                return Ok(Value::String(row.str.as_ref().unwrap().clone()))
81            }
82            OracleType::NCLOB => {
83                return Ok(Value::String(row.str.as_ref().unwrap().clone()))
84            }
85            //TODO: more types!
86            _ => {
87                if row.str.as_ref().is_some() {
88                    return Ok(Value::String(row.str.as_ref().unwrap().clone()))
89                }
90                return Err( Error::from("unimpl"));
91            },
92        };
93    }
94}