Convert mentat_sql to use error-chain. r=nalexander
This commit is contained in:
parent
dcd9bcb1ce
commit
b2f22952c1
3 changed files with 27 additions and 13 deletions
|
@ -24,8 +24,9 @@ use mentat_query_algebrizer::{
|
||||||
SourceAlias,
|
SourceAlias,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use mentat_sql;
|
||||||
|
|
||||||
use mentat_sql::{
|
use mentat_sql::{
|
||||||
BuildQueryError,
|
|
||||||
BuildQueryResult,
|
BuildQueryResult,
|
||||||
QueryBuilder,
|
QueryBuilder,
|
||||||
QueryFragment,
|
QueryFragment,
|
||||||
|
@ -268,7 +269,7 @@ impl QueryFragment for SelectQuery {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SelectQuery {
|
impl SelectQuery {
|
||||||
pub fn to_sql_query(&self) -> Result<SQLQuery, BuildQueryError> {
|
pub fn to_sql_query(&self) -> mentat_sql::Result<SQLQuery> {
|
||||||
let mut builder = SQLiteQueryBuilder::new();
|
let mut builder = SQLiteQueryBuilder::new();
|
||||||
self.push_sql(&mut builder).map(|_| builder.finish())
|
self.push_sql(&mut builder).map(|_| builder.finish())
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ version = "0.0.1"
|
||||||
workspace = ".."
|
workspace = ".."
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
error-chain = "0.9.0"
|
||||||
ordered-float = "0.4.0"
|
ordered-float = "0.4.0"
|
||||||
|
|
||||||
[dependencies.mentat_core]
|
[dependencies.mentat_core]
|
||||||
|
|
|
@ -8,23 +8,35 @@
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate error_chain;
|
||||||
extern crate ordered_float;
|
extern crate ordered_float;
|
||||||
extern crate mentat_core;
|
extern crate mentat_core;
|
||||||
|
|
||||||
use std::error::Error;
|
|
||||||
|
|
||||||
use ordered_float::OrderedFloat;
|
use ordered_float::OrderedFloat;
|
||||||
|
|
||||||
use mentat_core::TypedValue;
|
use mentat_core::TypedValue;
|
||||||
|
|
||||||
pub type BuildQueryError = Box<Error + Send + Sync>;
|
error_chain! {
|
||||||
pub type BuildQueryResult = Result<(), BuildQueryError>;
|
types {
|
||||||
|
Error, ErrorKind, ResultExt, Result;
|
||||||
pub enum BindParamError {
|
|
||||||
InvalidParameterName(String),
|
|
||||||
BindParamCouldBeGenerated(String),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
errors {
|
||||||
|
InvalidParameterName(name: String) {
|
||||||
|
description("invalid parameter name")
|
||||||
|
display("invalid parameter name: '{}'", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
BindParamCouldBeGenerated(name: String) {
|
||||||
|
description("parameter name could be generated")
|
||||||
|
display("parameter name could be generated: '{}'", name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type BuildQueryResult = Result<()>;
|
||||||
|
|
||||||
/// We want to accumulate values that will later be substituted into a SQL statement execution.
|
/// We want to accumulate values that will later be substituted into a SQL statement execution.
|
||||||
/// This struct encapsulates the generated string and the _initial_ argument list.
|
/// This struct encapsulates the generated string and the _initial_ argument list.
|
||||||
/// Additional user-supplied argument bindings, with their placeholders accumulated via
|
/// Additional user-supplied argument bindings, with their placeholders accumulated via
|
||||||
|
@ -42,7 +54,7 @@ pub trait QueryBuilder {
|
||||||
fn push_sql(&mut self, sql: &str);
|
fn push_sql(&mut self, sql: &str);
|
||||||
fn push_identifier(&mut self, identifier: &str) -> BuildQueryResult;
|
fn push_identifier(&mut self, identifier: &str) -> BuildQueryResult;
|
||||||
fn push_typed_value(&mut self, value: &TypedValue) -> BuildQueryResult;
|
fn push_typed_value(&mut self, value: &TypedValue) -> BuildQueryResult;
|
||||||
fn push_bind_param(&mut self, name: &str) -> Result<(), BindParamError>;
|
fn push_bind_param(&mut self, name: &str) -> BuildQueryResult;
|
||||||
fn finish(self) -> SQLQuery;
|
fn finish(self) -> SQLQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,16 +146,16 @@ impl QueryBuilder for SQLiteQueryBuilder {
|
||||||
/// returns an `InvalidParameterName` error result.
|
/// returns an `InvalidParameterName` error result.
|
||||||
/// Callers should make sure that the name doesn't overlap with generated parameter names. If
|
/// Callers should make sure that the name doesn't overlap with generated parameter names. If
|
||||||
/// it does, `BindParamCouldBeGenerated` is the error.
|
/// it does, `BindParamCouldBeGenerated` is the error.
|
||||||
fn push_bind_param(&mut self, name: &str) -> Result<(), BindParamError> {
|
fn push_bind_param(&mut self, name: &str) -> BuildQueryResult {
|
||||||
// Do some validation first.
|
// Do some validation first.
|
||||||
// This is not free, but it's probably worth it for now.
|
// This is not free, but it's probably worth it for now.
|
||||||
if !name.chars().all(char::is_alphanumeric) {
|
if !name.chars().all(char::is_alphanumeric) {
|
||||||
return Err(BindParamError::InvalidParameterName(name.to_string()));
|
bail!(ErrorKind::InvalidParameterName(name.to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if name.starts_with(self.arg_prefix.as_str()) &&
|
if name.starts_with(self.arg_prefix.as_str()) &&
|
||||||
name.chars().skip(self.arg_prefix.len()).all(char::is_numeric) {
|
name.chars().skip(self.arg_prefix.len()).all(char::is_numeric) {
|
||||||
return Err(BindParamError::BindParamCouldBeGenerated(name.to_string()));
|
bail!(ErrorKind::BindParamCouldBeGenerated(name.to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.push_sql("$");
|
self.push_sql("$");
|
||||||
|
|
Loading…
Reference in a new issue