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 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 => {
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 _ => {
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}