1use apiplant_core::FieldType;
4use sea_orm::sea_query::Value as SqlValue;
5
6pub fn json_to_sql(ty: FieldType, v: &serde_json::Value) -> Result<SqlValue, String> {
9 if v.is_null() {
10 return Ok(null_for(ty));
11 }
12 Ok(match ty {
13 FieldType::String | FieldType::Text => {
14 SqlValue::from(v.as_str().ok_or("expected a string")?.to_string())
15 }
16 FieldType::Integer => SqlValue::from(
17 i32::try_from(v.as_i64().ok_or("expected an integer")?)
18 .map_err(|_| "integer out of range")?,
19 ),
20 FieldType::BigInt => SqlValue::from(v.as_i64().ok_or("expected an integer")?),
21 FieldType::Float => SqlValue::from(v.as_f64().ok_or("expected a number")?),
22 FieldType::Boolean => SqlValue::from(v.as_bool().ok_or("expected a boolean")?),
23 FieldType::Uuid | FieldType::Reference => {
24 let s = v.as_str().ok_or("expected a UUID string")?;
25 SqlValue::from(uuid::Uuid::parse_str(s).map_err(|e| e.to_string())?)
26 }
27 FieldType::Timestamp => {
28 let s = v.as_str().ok_or("expected an RFC3339 timestamp")?;
29 SqlValue::from(chrono::DateTime::parse_from_rfc3339(s).map_err(|e| e.to_string())?)
30 }
31 FieldType::Json => SqlValue::from(v.clone()),
32 })
33}
34
35pub fn null_for(ty: FieldType) -> SqlValue {
38 match ty {
39 FieldType::String | FieldType::Text => SqlValue::String(None),
40 FieldType::Integer => SqlValue::Int(None),
41 FieldType::BigInt => SqlValue::BigInt(None),
42 FieldType::Float => SqlValue::Double(None),
43 FieldType::Boolean => SqlValue::Bool(None),
44 FieldType::Uuid | FieldType::Reference => SqlValue::Uuid(None),
45 FieldType::Timestamp => SqlValue::ChronoDateTimeWithTimeZone(None),
46 FieldType::Json => SqlValue::Json(None),
47 }
48}
49
50pub fn string_to_sql(ty: FieldType, s: &str) -> Result<SqlValue, String> {
53 Ok(match ty {
54 FieldType::String | FieldType::Text => SqlValue::from(s.to_string()),
55 FieldType::Integer => SqlValue::from(s.parse::<i32>().map_err(|_| "expected an integer")?),
56 FieldType::BigInt => SqlValue::from(s.parse::<i64>().map_err(|_| "expected an integer")?),
57 FieldType::Float => SqlValue::from(s.parse::<f64>().map_err(|_| "expected a number")?),
58 FieldType::Boolean => SqlValue::from(s.parse::<bool>().map_err(|_| "expected a boolean")?),
59 FieldType::Uuid | FieldType::Reference => {
60 SqlValue::from(uuid::Uuid::parse_str(s).map_err(|e| e.to_string())?)
61 }
62 FieldType::Timestamp => {
63 SqlValue::from(chrono::DateTime::parse_from_rfc3339(s).map_err(|e| e.to_string())?)
64 }
65 FieldType::Json => SqlValue::from(serde_json::Value::String(s.to_string())),
66 })
67}
68
69pub fn json_param(v: &serde_json::Value) -> SqlValue {
72 use serde_json::Value as J;
73 match v {
74 J::Null => SqlValue::String(None),
75 J::Bool(b) => SqlValue::from(*b),
76 J::Number(n) if n.is_i64() => SqlValue::from(n.as_i64().unwrap()),
77 J::Number(n) if n.is_u64() => SqlValue::from(n.as_u64().unwrap() as i64),
78 J::Number(n) => SqlValue::from(n.as_f64().unwrap()),
79 J::String(s) => SqlValue::from(s.clone()),
80 other => SqlValue::from(other.clone()),
81 }
82}