sqlite_util.rs (2205B)
1 #![forbid(unsafe_code)] 2 3 use crate::error::SqlError; 4 use rusqlite::{Row, types::Value as SqlValue}; 5 use serde_json::{Map, Value}; 6 7 pub fn parse_params(params_json: &str) -> Result<Vec<SqlValue>, SqlError> { 8 let vals: Vec<Value> = serde_json::from_str(params_json) 9 .map_err(|e| SqlError::SerializationError(e.to_string()))?; 10 vals.into_iter() 11 .map(|v| match v { 12 Value::Null => Ok(SqlValue::Null), 13 Value::Bool(b) => Ok(SqlValue::from(if b { 1 } else { 0 })), 14 Value::Number(n) => { 15 if let Some(i) = n.as_i64() { 16 Ok(SqlValue::from(i)) 17 } else if let Some(u) = n.as_u64() { 18 Ok(SqlValue::from(u as i64)) 19 } else if let Some(f) = n.as_f64() { 20 Ok(SqlValue::from(f)) 21 } else { 22 Err(SqlError::InvalidArgument("unsupported number".to_string())) 23 } 24 } 25 Value::String(s) => Ok(SqlValue::from(s)), 26 other => Err(SqlError::InvalidArgument(format!( 27 "unsupported bind value: {}", 28 other 29 ))), 30 }) 31 .collect() 32 } 33 34 pub fn row_to_json(row: &Row) -> rusqlite::Result<Value> { 35 let stmt = row.as_ref(); 36 let mut obj = Map::new(); 37 for i in 0..stmt.column_count() { 38 let name = stmt.column_name(i).unwrap_or("").to_string(); 39 let v = row.get_ref(i)?; 40 let j = match v { 41 rusqlite::types::ValueRef::Null => Value::Null, 42 rusqlite::types::ValueRef::Integer(i) => Value::from(i), 43 rusqlite::types::ValueRef::Real(f) => Value::from(f), 44 rusqlite::types::ValueRef::Text(s) => { 45 let s = std::str::from_utf8(s).map_err(|e| { 46 rusqlite::Error::FromSqlConversionFailure( 47 i, 48 rusqlite::types::Type::Text, 49 Box::new(e), 50 ) 51 })?; 52 Value::from(s.to_string()) 53 } 54 rusqlite::types::ValueRef::Blob(_) => Value::Null, 55 }; 56 obj.insert(name, j); 57 } 58 Ok(Value::Object(obj)) 59 }