Add results type unwrapping helpers.

This commit is contained in:
Richard Newman 2017-12-06 14:34:48 -08:00
parent 75bcb76dd5
commit a3b8fd3022
2 changed files with 69 additions and 0 deletions

View file

@ -69,6 +69,13 @@ error_chain! {
links {
DbError(mentat_db::Error, mentat_db::ErrorKind);
}
errors {
UnexpectedResultsType(actual: &'static str, expected: &'static str) {
description("unexpected query results type")
display("expected {}, got {}", expected, actual)
}
}
}
#[derive(Debug, PartialEq, Eq)]
@ -119,6 +126,42 @@ impl QueryResults {
&FindRel(_) => Box::new(|| QueryResults::Rel(vec![])),
}
}
pub fn into_scalar(self) -> Result<Option<TypedValue>> {
match self {
QueryResults::Scalar(o) => Ok(o),
QueryResults::Coll(_) => bail!(ErrorKind::UnexpectedResultsType("coll", "scalar")),
QueryResults::Tuple(_) => bail!(ErrorKind::UnexpectedResultsType("tuple", "scalar")),
QueryResults::Rel(_) => bail!(ErrorKind::UnexpectedResultsType("rel", "scalar")),
}
}
pub fn into_coll(self) -> Result<Vec<TypedValue>> {
match self {
QueryResults::Scalar(_) => bail!(ErrorKind::UnexpectedResultsType("scalar", "coll")),
QueryResults::Coll(c) => Ok(c),
QueryResults::Tuple(_) => bail!(ErrorKind::UnexpectedResultsType("tuple", "coll")),
QueryResults::Rel(_) => bail!(ErrorKind::UnexpectedResultsType("rel", "coll")),
}
}
pub fn into_tuple(self) -> Result<Option<Vec<TypedValue>>> {
match self {
QueryResults::Scalar(_) => bail!(ErrorKind::UnexpectedResultsType("scalar", "tuple")),
QueryResults::Coll(_) => bail!(ErrorKind::UnexpectedResultsType("coll", "tuple")),
QueryResults::Tuple(t) => Ok(t),
QueryResults::Rel(_) => bail!(ErrorKind::UnexpectedResultsType("rel", "tuple")),
}
}
pub fn into_rel(self) -> Result<Vec<Vec<TypedValue>>> {
match self {
QueryResults::Scalar(_) => bail!(ErrorKind::UnexpectedResultsType("scalar", "rel")),
QueryResults::Coll(_) => bail!(ErrorKind::UnexpectedResultsType("coll", "rel")),
QueryResults::Tuple(_) => bail!(ErrorKind::UnexpectedResultsType("tuple", "rel")),
QueryResults::Rel(r) => Ok(r),
}
}
}
type Index = i32; // See rusqlite::RowIndex.

View file

@ -13,6 +13,7 @@ use rusqlite::types::ToSql;
use mentat_core::{
Schema,
TypedValue,
};
use mentat_query_algebrizer::{
@ -52,6 +53,31 @@ use errors::{
pub type QueryExecutionResult = Result<QueryResults>;
pub trait IntoResult {
fn into_scalar_result(self) -> Result<Option<TypedValue>>;
fn into_coll_result(self) -> Result<Vec<TypedValue>>;
fn into_tuple_result(self) -> Result<Option<Vec<TypedValue>>>;
fn into_rel_result(self) -> Result<Vec<Vec<TypedValue>>>;
}
impl IntoResult for QueryExecutionResult {
fn into_scalar_result(self) -> Result<Option<TypedValue>> {
self?.into_scalar().map_err(|e| e.into())
}
fn into_coll_result(self) -> Result<Vec<TypedValue>> {
self?.into_coll().map_err(|e| e.into())
}
fn into_tuple_result(self) -> Result<Option<Vec<TypedValue>>> {
self?.into_tuple().map_err(|e| e.into())
}
fn into_rel_result(self) -> Result<Vec<Vec<TypedValue>>> {
self?.into_rel().map_err(|e| e.into())
}
}
/// Take an EDN query string, a reference to an open SQLite connection, a Mentat schema, and an
/// optional collection of input bindings (which should be keyed by `"?varname"`), and execute the
/// query immediately, blocking the current thread.