1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use bigdecimal::BigDecimal;
use oracle::sql_type::OracleType;
use rbdc::{datetime::FastDateTime, Error};
use rbs::Value;
use std::str::FromStr;

use crate::OracleData;

pub trait Decode {
    fn decode(row: &OracleData) -> Result<Value, Error>;
}

impl Decode for Value {
    fn decode(row: &OracleData) -> Result<Value, Error> {
        let s = row.str.as_ref();
        if s.is_none() {
            return Ok(Value::Null);
        }
        let value = s.unwrap().clone();
        match row.column_type {
            OracleType::Number(p, s) => {
                if p ==0 && s == -127{
                    // it means number(*)
                    let dec =
                        BigDecimal::from_str(&value).map_err(|e| Error::from(e.to_string()))?;
                    if dec.is_integer() {
                        let d = dec.digits();
                        if 1 <= d && d <= 9 {
                            let a = value.parse::<i32>()?;
                            return Ok(Value::I32(a));
                        } else if 10 <= d && d <= 18 {
                            let a = value.parse::<i64>()?;
                            return Ok(Value::I64(a));
                        }
                        return Ok(Value::String(dec.to_string()).into_ext("Decimal"));
                    }
                    return Ok(Value::String(dec.to_string()).into_ext("Decimal"));
                }
                if s > 0 {
                    let dec =
                        BigDecimal::from_str(&value).map_err(|e| Error::from(e.to_string()))?;
                    return Ok(Value::String(dec.to_string()).into_ext("Decimal"));
                } else if 1 <= p && p <= 9 {
                    let a = value.parse::<i32>()?;
                    return Ok(Value::I32(a));
                } else if 10 <= p && p <= 18 {
                    let a = value.parse::<i64>()?;
                    return Ok(Value::I64(a));
                }
                let dec = BigDecimal::from_str(&value).map_err(|e| Error::from(e.to_string()))?;
                return Ok(Value::String(dec.to_string()).into_ext("Decimal"));
            }
            //OracleType::Int64 is integer
            OracleType::Int64 => {
                let a = value.parse::<i32>()?;
                return Ok(Value::I32(a));
            }
            OracleType::Long => {
                let a = value.parse::<i64>()?;
                return Ok(Value::I64(a));
            }
            OracleType::Date => {
                let a = FastDateTime::from_str(&value)?;
                return Ok(Value::from(a));
            }
            //TODO: more types!
            _ => return Ok(Value::String(value)),
        };
    }
}