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