use std::str::FromStr; use edgedb_errors::NoDataError; use edgedb_protocol::model::Uuid; use edgedb_protocol::named_args; use edgedb_protocol::value::{EnumValue, Value}; use edgedb_tokio::{Client, Queryable}; use futures_util::stream::{self, StreamExt}; use serde::{Deserialize, Serialize}; use crate::server::SERVER; #[tokio::test] async fn simple() -> anyhow::Result<()> { let client = Client::new(&SERVER.config); client.ensure_connected().await?; let value = client.query::("SELECT 7*93", &()).await?; assert_eq!(value, vec![651]); let value = client.query_single::("SELECT 5*11", &()).await?; assert_eq!(value, Some(55)); let value = client .query_single::("SELECT {}", &()) .await?; assert_eq!(value, None); let value = client .query_required_single::("SELECT 5*11", &()) .await?; assert_eq!(value, 55); let err = client .query_required_single::("SELECT {}", &()) .await .unwrap_err(); assert!(err.is::()); let value = client.query_json("SELECT 'x' ++ 'y'", &()).await?; assert_eq!(value.as_ref(), r#"["xy"]"#); let value = client.query_single_json("SELECT 'x' ++ 'y'", &()).await?; assert_eq!(value.as_deref(), Some(r#""xy""#)); let value = client.query_single_json("SELECT {}", &()).await?; assert_eq!(value.as_deref(), None); let err = client .query_required_single_json("SELECT {}", &()) .await .unwrap_err(); assert!(err.is::()); client.execute("SELECT 1+1", &()).await?; client .execute("START MIGRATION TO {}; ABORT MIGRATION", &()) .await?; // basic enum param let enum_query = "SELECT ($0) = 'waiting'"; assert!(client .query_required_single::(enum_query, &(Value::Enum(EnumValue::from("waiting")),)) .await .unwrap()); // unsupported: enum param as Value::Str client .query_required_single::(enum_query, &(Value::Str("waiting".to_string()),)) .await .unwrap_err(); // unsupported: enum param as String client .query_required_single::(enum_query, &("waiting".to_string(),)) .await .unwrap_err(); // enum param as &str assert!(client .query_required_single::(enum_query, &("waiting",),) .await .unwrap()); // named args let value = client .query_required_single::( "select ( std::array_join(>$msg1, ' ') ++ ($question ?? ' the ultimate question of life') ++ ': ' ++ $answer );", &named_args! { "msg1" => vec!["the".to_string(), "answer".to_string(), "to".to_string()], "question" => None::, "answer" => 42_i64, }, ) .await .unwrap(); assert_eq!( value.as_str(), "the answer to the ultimate question of life: 42" ); // args for values let uuid = "43299d0a-f993-4dcb-a8a2-50041bf5af79"; let value = client .query_required_single::( "select $my_uuid;", &named_args! { "my_uuid" => Uuid::from_str("43299d0a-f993-4dcb-a8a2-50041bf5af79").unwrap(), }, ) .await .unwrap(); assert_eq!(value, Uuid::from_str(uuid).unwrap()); Ok(()) } #[tokio::test] async fn parallel_queries() -> anyhow::Result<()> { let client = Client::new(&SERVER.config); client.ensure_connected().await?; let result = stream::iter(0..10i64) .map(|idx| { let cli = client.clone(); async move { cli.query_required_single::("SELECT $0*10", &(idx,)) .await } }) .buffer_unordered(7) .collect::>() .await; let mut result: Vec<_> = result.into_iter().collect::>()?; result.sort(); assert_eq!(result, (0..100).step_by(10).collect::>()); Ok(()) } #[tokio::test] async fn json() -> anyhow::Result<()> { let client = Client::new(&SERVER.config); client.ensure_connected().await?; client .execute::<_>( "insert test::OtpPhoneRequest { phone := '0123456789', sent_at := datetime_of_statement(), otp := 98271 }", &(), ) .await .unwrap(); #[derive(Clone, Debug, Serialize, Deserialize, Queryable)] #[edgedb(json)] pub struct OtpPhoneRequest { pub phone: String, pub otp: i32, } let res = client.query::( "select (select test::OtpPhoneRequest { phone, otp } filter .phone = '0123456789')", &() ) .await?; let res = res.into_iter().next().unwrap(); assert_eq!(res.phone, "0123456789"); assert_eq!(res.otp, 98271); Ok(()) } #[tokio::test] async fn big_num() -> anyhow::Result<()> { let client = Client::new(&SERVER.config); client.ensure_connected().await?; let res = client .query_required_single::("select 1234567890123456789012345678900000n", &()) .await .unwrap(); if let Value::BigInt(res) = res { assert_eq!(res.to_string(), "1234567890123456789012345678900000"); } else { panic!(); } let res = client .query_required_single::("select 1234567891234567890.12345678900000n", &()) .await .unwrap(); if let Value::Decimal(res) = res { assert_eq!(res.to_string(), "1234567891234567890.12345678900000"); } else { panic!(); } let res = client .query_required_single::("select 0.00012n", &()) .await .unwrap(); if let Value::Decimal(res) = res { assert_eq!(res.to_string(), "0.00012"); } else { panic!(); } Ok(()) }