// Copyright 2016 Mozilla // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use // this file except in compliance with the License. You may obtain a copy of the // License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. use std::collections::BTreeMap; use mentat_core::{ TypedValue, ValueType, }; use mentat_query::{ Variable, }; use errors::{ ErrorKind, Result, }; /// Define the inputs to a query. This is in two parts: a set of values known now, and a set of /// types known now. /// The separate map of types is to allow queries to be algebrized without full knowledge of /// the bindings that will be used at execution time. /// When built correctly, `types` is guaranteed to contain the types of `values` -- use /// `QueryInputs::new` or `QueryInputs::with_values` to construct an instance. pub struct QueryInputs { // These should be crate-private. pub types: BTreeMap, pub values: BTreeMap, } impl Default for QueryInputs { fn default() -> Self { QueryInputs { types: BTreeMap::default(), values: BTreeMap::default(), } } } impl QueryInputs { pub fn with_value_sequence(vals: Vec<(Variable, TypedValue)>) -> QueryInputs { let values: BTreeMap = vals.into_iter().collect(); QueryInputs::with_values(values) } pub fn with_values(values: BTreeMap) -> QueryInputs { QueryInputs { types: values.iter().map(|(var, val)| (var.clone(), val.value_type())).collect(), values: values, } } pub fn new(mut types: BTreeMap, values: BTreeMap) -> Result { // Make sure that the types of the values agree with those in types, and collect. for (var, v) in values.iter() { let t = v.value_type(); let old = types.insert(var.clone(), t); if let Some(old) = old { if old != t { bail!(ErrorKind::InputTypeDisagreement(var.name(), old, t)); } } } Ok(QueryInputs { types: types, values: values }) } }