diff --git a/lib/src/err/mod.rs b/lib/src/err/mod.rs index 27f8ef78..cea67689 100644 --- a/lib/src/err/mod.rs +++ b/lib/src/err/mod.rs @@ -43,7 +43,7 @@ pub enum Error { Deprecated(String), /// A custom error has been thrown - #[error("{0}")] + #[error("An error occurred: {0}")] Thrown(String), /// There was a problem with the underlying datastore diff --git a/lib/tests/throw.rs b/lib/tests/throw.rs new file mode 100644 index 00000000..a5bca6de --- /dev/null +++ b/lib/tests/throw.rs @@ -0,0 +1,23 @@ +mod parse; +use surrealdb::dbs::Session; +use surrealdb::err::Error; +use surrealdb::kvs::Datastore; + +#[tokio::test] +async fn throw_basic() -> Result<(), Error> { + let sql = " + THROW 'there was an error'; + "; + let dbs = Datastore::new("memory").await?; + let ses = Session::owner().with_ns("test").with_db("test"); + let res = &mut dbs.execute(sql, &ses, None).await?; + assert_eq!(res.len(), 1); + // + let tmp = res.remove(0).result; + assert!(matches!( + tmp.err(), + Some(e) if e.to_string() == r#"An error occurred: there was an error"# + )); + // + Ok(()) +} diff --git a/lib/tests/transaction.rs b/lib/tests/transaction.rs new file mode 100644 index 00000000..807c0968 --- /dev/null +++ b/lib/tests/transaction.rs @@ -0,0 +1,186 @@ +mod parse; +use parse::Parse; +use surrealdb::dbs::Session; +use surrealdb::err::Error; +use surrealdb::kvs::Datastore; +use surrealdb::sql::Value; + +#[tokio::test] +async fn transaction_basic() -> Result<(), Error> { + let sql = " + BEGIN; + CREATE person:tobie; + CREATE person:jaime; + COMMIT; + "; + let dbs = Datastore::new("memory").await?; + let ses = Session::owner().with_ns("test").with_db("test"); + let res = &mut dbs.execute(sql, &ses, None).await?; + assert_eq!(res.len(), 2); + // + let tmp = res.remove(0).result?; + let val = Value::parse( + "[ + { + id: person:tobie, + } + ]", + ); + assert_eq!(tmp, val); + // + let tmp = res.remove(0).result?; + let val = Value::parse( + "[ + { + id: person:jaime, + } + ]", + ); + assert_eq!(tmp, val); + // + Ok(()) +} + +#[tokio::test] +async fn transaction_with_return() -> Result<(), Error> { + let sql = " + BEGIN; + CREATE person:tobie; + CREATE person:jaime; + RETURN { tobie: person:tobie, jaime: person:jaime }; + COMMIT; + "; + let dbs = Datastore::new("memory").await?; + let ses = Session::owner().with_ns("test").with_db("test"); + let res = &mut dbs.execute(sql, &ses, None).await?; + assert_eq!(res.len(), 1); + // + let tmp = res.remove(0).result?; + let val = Value::parse( + "{ + tobie: person:tobie, + jaime: person:jaime, + }", + ); + assert_eq!(tmp, val); + // + Ok(()) +} + +#[tokio::test] +async fn transaction_with_failure() -> Result<(), Error> { + let sql = " + BEGIN; + CREATE person:tobie; + CREATE person:jaime; + CREATE person:tobie; + COMMIT; + "; + let dbs = Datastore::new("memory").await?; + let ses = Session::owner().with_ns("test").with_db("test"); + let res = &mut dbs.execute(sql, &ses, None).await?; + assert_eq!(res.len(), 3); + // + let tmp = res.remove(0).result; + assert!(matches!( + tmp.err(), + Some(e) if e.to_string() == r#"The query was not executed due to a failed transaction"# + )); + // + let tmp = res.remove(0).result; + assert!(matches!( + tmp.err(), + Some(e) if e.to_string() == r#"The query was not executed due to a failed transaction"# + )); + // + let tmp = res.remove(0).result; + assert!(matches!( + tmp.err(), + Some(e) if e.to_string() == r#"Database record `person:tobie` already exists"# + )); + // + Ok(()) +} + +#[tokio::test] +async fn transaction_with_failure_and_return() -> Result<(), Error> { + let sql = " + BEGIN; + CREATE person:tobie; + CREATE person:jaime; + CREATE person:tobie; + RETURN { tobie: person:tobie, jaime: person:jaime }; + COMMIT; + "; + let dbs = Datastore::new("memory").await?; + let ses = Session::owner().with_ns("test").with_db("test"); + let res = &mut dbs.execute(sql, &ses, None).await?; + assert_eq!(res.len(), 1); + // + let tmp = res.remove(0).result; + assert!(matches!( + tmp.err(), + Some(e) if e.to_string() == r#"The query was not executed due to a failed transaction"# + )); + // + Ok(()) +} + +#[tokio::test] +async fn transaction_with_throw() -> Result<(), Error> { + let sql = " + BEGIN; + CREATE person:tobie; + CREATE person:jaime; + THROW 'there was an error'; + COMMIT; + "; + let dbs = Datastore::new("memory").await?; + let ses = Session::owner().with_ns("test").with_db("test"); + let res = &mut dbs.execute(sql, &ses, None).await?; + assert_eq!(res.len(), 3); + // + let tmp = res.remove(0).result; + assert!(matches!( + tmp.err(), + Some(e) if e.to_string() == r#"The query was not executed due to a failed transaction"# + )); + // + let tmp = res.remove(0).result; + assert!(matches!( + tmp.err(), + Some(e) if e.to_string() == r#"The query was not executed due to a failed transaction"# + )); + // + let tmp = res.remove(0).result; + assert!(matches!( + tmp.err(), + Some(e) if e.to_string() == r#"An error occurred: there was an error"# + )); + // + Ok(()) +} + +#[tokio::test] +async fn transaction_with_throw_and_return() -> Result<(), Error> { + let sql = " + BEGIN; + CREATE person:tobie; + CREATE person:jaime; + THROW 'there was an error'; + RETURN { tobie: person:tobie, jaime: person:jaime }; + COMMIT; + "; + let dbs = Datastore::new("memory").await?; + let ses = Session::owner().with_ns("test").with_db("test"); + let res = &mut dbs.execute(sql, &ses, None).await?; + assert_eq!(res.len(), 1); + // + let tmp = res.remove(0).result; + assert!(matches!( + tmp.err(), + Some(e) if e.to_string() == r#"The query was not executed due to a failed transaction"# + )); + // + Ok(()) +}