diff --git a/src/dbs/executor.rs b/src/dbs/executor.rs index f9e60504..e7221e59 100644 --- a/src/dbs/executor.rs +++ b/src/dbs/executor.rs @@ -1,5 +1,5 @@ use crate::ctx::Context; -use crate::dbs::response::{Response, Responses}; +use crate::dbs::response::{Response, Responses, Status}; use crate::dbs::Auth; use crate::dbs::Level; use crate::dbs::Options; @@ -107,7 +107,33 @@ impl<'a> Executor<'a> { } } + pub fn buf_cancel(&self, v: Response) -> Response { + Response { + time: v.time, + status: Status::Err, + detail: Some(format!("Transaction cancelled")), + result: None, + } + } + + pub fn buf_commit(&self, v: Response) -> Response { + match &self.err { + Some(_) => Response { + time: v.time, + status: Status::Err, + detail: match v.status { + Status::Ok => Some(format!("{}", Error::QueryExecutionError)), + Status::Err => v.detail, + }, + result: None, + }, + _ => v, + } + } + pub async fn execute(&mut self, mut ctx: Runtime, qry: Query) -> Result { + // Initialise buffer of responses + let mut buf: Vec = vec![]; // Initialise array of responses let mut out: Vec = vec![]; // Create a new options @@ -138,20 +164,30 @@ impl<'a> Executor<'a> { // Begin a new transaction Statement::Begin(stm) => { let res = stm.compute(&ctx, &opt, self, None).await; - self.err = res.err(); + if res.is_err() { + self.err = res.err() + }; continue; } // Cancel a running transaction Statement::Cancel(stm) => { let res = stm.compute(&ctx, &opt, self, None).await; - self.err = res.err(); + if res.is_err() { + self.err = res.err() + }; + buf = buf.into_iter().map(|v| self.buf_cancel(v)).collect(); + out.append(&mut buf); self.txn = None; continue; } // Commit a running transaction Statement::Commit(stm) => { let res = stm.compute(&ctx, &opt, self, None).await; - self.err = res.err(); + if res.is_err() { + self.err = res.err() + }; + buf = buf.into_iter().map(|v| self.buf_commit(v)).collect(); + out.append(&mut buf); self.txn = None; continue; } @@ -210,25 +246,38 @@ impl<'a> Executor<'a> { }; // Get the statement end time let dur = now.elapsed(); - // Buffer the returned result - match res { - Ok(v) => out.push(Response { + // Produce the response + let res = match res { + Ok(v) => Response { time: format!("{:?}", dur), - status: String::from("OK"), + status: Status::Ok, detail: None, result: v.output(), - }), + }, Err(e) => { - // Output the error - out.push(Response { + // Produce the response + let res = Response { time: format!("{:?}", dur), - status: String::from("ERR"), + status: Status::Err, detail: Some(format!("{}", e)), result: None, - }); + }; // Keep the error self.err = Some(e); + // Return + res } + }; + // Output the response + match self.txn { + Some(_) => match stm { + Statement::Output(_) => { + buf.clear(); + buf.push(res); + } + _ => buf.push(res), + }, + None => out.push(res), } } // Return responses diff --git a/src/dbs/response.rs b/src/dbs/response.rs index 26279707..b198f877 100644 --- a/src/dbs/response.rs +++ b/src/dbs/response.rs @@ -1,13 +1,20 @@ use crate::sql::value::Value; use serde::{Deserialize, Serialize}; +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "UPPERCASE")] +pub enum Status { + Ok, + Err, +} + #[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] pub struct Responses(pub Vec); #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] pub struct Response { pub time: String, - pub status: String, + pub status: Status, #[serde(skip_serializing_if = "Option::is_none")] pub detail: Option, #[serde(skip_serializing_if = "Option::is_none")]