From 7826538ee2e6d7f65f36886aa235b6c63fb7c0b2 Mon Sep 17 00:00:00 2001 From: Brendan Allan Date: Sun, 20 Aug 2023 18:11:29 +0800 Subject: [PATCH] add prisma value conversions --- crates/lib/src/client.rs | 4 +-- crates/lib/src/prisma_value.rs | 49 +++++++++++++++++++++++++++++----- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/crates/lib/src/client.rs b/crates/lib/src/client.rs index e9cb21eb..7437bc35 100644 --- a/crates/lib/src/client.rs +++ b/crates/lib/src/client.rs @@ -46,7 +46,7 @@ impl ExecutionEngine { op, connector.query_schema.clone(), None, - EngineProtocol::Graphql, + EngineProtocol::Json, ) .await .map_err(|e| QueryError::Execute(e.into()))?; @@ -78,7 +78,7 @@ impl ExecutionEngine { Some(BatchDocumentTransaction::new(None)), connector.query_schema.clone(), None, - EngineProtocol::Graphql, + EngineProtocol::Json, ) .await .map_err(|e| QueryError::Execute(e.into()))?; diff --git a/crates/lib/src/prisma_value.rs b/crates/lib/src/prisma_value.rs index ab017a07..da4eff2c 100644 --- a/crates/lib/src/prisma_value.rs +++ b/crates/lib/src/prisma_value.rs @@ -1,9 +1,12 @@ -use std::sync::Arc; +use std::{str::FromStr, sync::Arc}; use bigdecimal::{BigDecimal, FromPrimitive, ToPrimitive}; use chrono::{DateTime, FixedOffset}; use indexmap::IndexMap; -use query_core::response_ir::Item as PrismaItem; +use query_core::{ + constants::custom_types::{self}, + response_ir::Item as PrismaItem, +}; use serde::{Serialize, Serializer}; use uuid::Uuid; @@ -14,7 +17,7 @@ use uuid::Uuid; /// (eg. float values are encoded as strings). /// /// This implementation only has an override for `PrismaValue::Null`, which is serialized as `None` -#[derive(Clone, Serialize)] +#[derive(Debug, Clone, Serialize)] #[serde(untagged)] pub enum PrismaValue { String(String), @@ -29,13 +32,14 @@ pub enum PrismaValue { Null, DateTime(DateTime), Float(f64), + Decimal(BigDecimal), BigInt(i64), Bytes(Vec), } /// A Rust-friendly version of Prisma's own Item. /// Exists solely for nicer conversion of query results to our PrismaValue. -#[derive(Clone, Serialize)] +#[derive(Debug, Clone, Serialize)] #[serde(untagged)] pub enum Item { Map(IndexMap), @@ -81,8 +85,40 @@ impl From for PrismaValue { prisma_models::PrismaValue::Json(value) => { Self::Json(serde_json::from_str(&value).unwrap()) } - prisma_models::PrismaValue::Object(value) => { - Self::Object(value.into_iter().map(|(k, v)| (k, v.into())).collect()) + prisma_models::PrismaValue::Object(mut value) => { + let type_position = value.iter().position(|(k, _)| k == custom_types::TYPE); + + if let Some((_, prisma_models::PrismaValue::String(typ))) = + type_position.map(|pos| value.swap_remove(pos)) + { + let (_, value) = value.swap_remove( + value + .iter() + .position(|(k, _)| k == custom_types::VALUE) + .unwrap(), + ); + + match (typ.as_str(), value) { + (custom_types::DATETIME, prisma_models::PrismaValue::DateTime(dt)) => { + PrismaValue::DateTime(dt) + } + (custom_types::BIGINT, prisma_models::PrismaValue::BigInt(i)) => { + PrismaValue::BigInt(i) + } + (custom_types::DECIMAL, prisma_models::PrismaValue::String(s)) => { + PrismaValue::Decimal(BigDecimal::from_str(&s).unwrap()) + } + (custom_types::BYTES, prisma_models::PrismaValue::Bytes(b)) => { + PrismaValue::Bytes(b) + } + (custom_types::JSON, prisma_models::PrismaValue::Json(j)) => { + PrismaValue::Json(serde_json::from_str(&j).unwrap()) + } + _ => unreachable!("Incorrect PrismaValue for {typ}"), + } + } else { + Self::Object(value.into_iter().map(|(k, v)| (k, v.into())).collect()) + } } prisma_models::PrismaValue::Null => Self::Null, prisma_models::PrismaValue::DateTime(value) => Self::DateTime(value), @@ -108,6 +144,7 @@ impl From for prisma_models::PrismaValue { } PrismaValue::Null => Self::Null, PrismaValue::DateTime(value) => Self::DateTime(value), + PrismaValue::Decimal(value) => Self::Float(value), PrismaValue::Float(value) => Self::Float(BigDecimal::from_f64(value).unwrap()), PrismaValue::BigInt(value) => Self::BigInt(value), PrismaValue::Bytes(value) => Self::Bytes(value),