mod parse; use parse::Parse; mod helpers; use crate::helpers::skip_ok; use helpers::new_ds; use surrealdb::dbs::Session; use surrealdb::err::Error; use surrealdb::sql::Value; use surrealdb_core::sql::Number; #[tokio::test] async fn create_relate_select() -> Result<(), Error> { let sql = " CREATE user:tobie SET name = 'Tobie'; CREATE user:jaime SET name = 'Jaime'; CREATE product:phone SET price = 1000; CREATE product:laptop SET price = 3000; RELATE user:tobie->bought->product:phone SET id = bought:1, payment_method = 'VISA'; RELATE user:tobie->bought->product:laptop SET id = bought:2, payment_method = 'VISA'; RELATE user:jaime->bought->product:laptop SET id = bought:3, payment_method = 'VISA'; SELECT *, ->bought AS purchases FROM user; SELECT *, ->bought.out.* AS products FROM user; SELECT *, ->bought->product.* AS products FROM user; SELECT *, ->bought AS products FROM user FETCH products; SELECT *, ->(bought AS purchases) FROM user FETCH purchases, purchases.out; LET $param1 = 'purchases'; SELECT *, ->(bought AS purchases) FROM user FETCH $param1, purchases.out; SELECT *, ->(bought AS purchases) FROM user FETCH type::field('purchases'), purchases.out; SELECT *, ->(bought AS purchases) FROM user FETCH type::fields([$param1, 'purchases.out']); LET $faultyparam = 1.0f; SELECT *, ->(bought AS purchases) FROM user FETCH $faultyparam, purchases.out; "; let dbs = new_ds().await?; let ses = Session::owner().with_ns("test").with_db("test"); let res = &mut dbs.execute(sql, &ses, None).await?; assert_eq!(res.len(), 18); // let tmp = res.remove(0).result?; let val = Value::parse( "[ { id: user:tobie, name: 'Tobie' } ]", ); assert_eq!(tmp, val); // let tmp = res.remove(0).result?; let val = Value::parse( "[ { id: user:jaime, name: 'Jaime' } ]", ); assert_eq!(tmp, val); // let tmp = res.remove(0).result?; let val = Value::parse( "[ { id: product:phone, price: 1000 } ]", ); assert_eq!(tmp, val); // let tmp = res.remove(0).result?; let val = Value::parse( "[ { id: product:laptop, price: 3000 } ]", ); assert_eq!(tmp, val); // let tmp = res.remove(0).result?; let val = Value::parse( "[ { 'id': bought:1, 'in': user:tobie, 'out': product:phone, 'payment_method': 'VISA' } ]", ); assert_eq!(tmp, val); // let tmp = res.remove(0).result?; let val = Value::parse( "[ { 'id': bought:2, 'in': user:tobie, 'out': product:laptop, 'payment_method': 'VISA' } ]", ); assert_eq!(tmp, val); // let tmp = res.remove(0).result?; let val = Value::parse( "[ { 'id': bought:3, 'in': user:jaime, 'out': product:laptop, 'payment_method': 'VISA' } ]", ); assert_eq!(tmp, val); // let tmp = res.remove(0).result?; let val = Value::parse( "[ { id: user:jaime, name: 'Jaime', purchases: [ bought:3 ] }, { id: user:tobie, name: 'Tobie', purchases: [ bought:1, bought:2 ] } ]", ); assert_eq!(tmp, val); // let tmp = res.remove(0).result?; let val = Value::parse( "[ { id: user:jaime, name: 'Jaime', products: [ { id: product:laptop, price: 3000 } ] }, { id: user:tobie, name: 'Tobie', products: [ { id: product:phone, price: 1000 }, { id: product:laptop, price: 3000 } ] } ]", ); assert_eq!(tmp, val); // let tmp = res.remove(0).result?; let val = Value::parse( "[ { id: user:jaime, name: 'Jaime', products: [ { id: product:laptop, price: 3000 } ] }, { id: user:tobie, name: 'Tobie', products: [ { id: product:phone, price: 1000 }, { id: product:laptop, price: 3000 } ] } ]", ); assert_eq!(tmp, val); // let tmp = res.remove(0).result?; let val = Value::parse( "[ { id: user:jaime, name: 'Jaime', products: [ { id: bought:3, in: user:jaime, out: product:laptop, payment_method: 'VISA' } ] }, { id: user:tobie, name: 'Tobie', products: [ { id: bought:1, in: user:tobie, out: product:phone, payment_method: 'VISA' }, { id: bought:2, in: user:tobie, out: product:laptop, payment_method: 'VISA' } ] } ]", ); assert_eq!(tmp, val); // let tmp = res.remove(0).result?; let val = Value::parse( "[ { id: user:jaime, name: 'Jaime', purchases: [ { id: bought:3, in: user:jaime, out: { id: product:laptop, price: 3000 }, payment_method: 'VISA' } ] }, { id: user:tobie, name: 'Tobie', purchases: [ { id: bought:1, in: user:tobie, out: { id: product:phone, price: 1000 }, payment_method: 'VISA' }, { id: bought:2, in: user:tobie, out: { id: product:laptop, price: 3000 }, payment_method: 'VISA' } ] } ]", ); assert_eq!(tmp, val); // Skip the LET $param statements skip_ok(res, 1)?; // for i in 0..3 { let tmp = res.remove(0).result.unwrap_or_else(|e| panic!("{i} {e}")); let val = Value::parse( "[ { id: user:jaime, name: 'Jaime', purchases: [ { id: bought:3, in: user:jaime, out: { id: product:laptop, price: 3000 }, payment_method: 'VISA' } ] }, { id: user:tobie, name: 'Tobie', purchases: [ { id: bought:1, in: user:tobie, out: { id: product:phone, price: 1000 }, payment_method: 'VISA' }, { id: bought:2, in: user:tobie, out: { id: product:laptop, price: 3000 }, payment_method: 'VISA' } ] } ]", ); assert_eq!(tmp, val, "{i}"); } // Ignore LET statement result res.remove(0); match res.remove(0).result { Err(Error::InvalidFetch { value, }) if value == Value::Number(Number::Float(1.0)) => {} found => panic!("Expected Err(Error::InvalidFetch), found '{found:?}'"), }; assert_eq!(tmp, val); // Ok(()) }