diff --git a/Cargo.toml b/Cargo.toml index dca49e64..c1e2afb5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -67,6 +67,9 @@ path = "query-algebrizer-traits" [dependencies.mentat_query_projector] path = "query-projector" +[dependencies.query_projector_traits] +path = "query-projector-traits" + [dependencies.mentat_query_pull] path = "query-pull" diff --git a/query-projector-traits/Cargo.toml b/query-projector-traits/Cargo.toml new file mode 100644 index 00000000..2cf166d0 --- /dev/null +++ b/query-projector-traits/Cargo.toml @@ -0,0 +1,40 @@ +[package] +name = "query_projector_traits" +version = "0.0.1" +workspace = ".." + +[lib] +name = "query_projector_traits" +path = "lib.rs" + +[dependencies] +failure = "0.1.1" +failure_derive = "0.1.1" + +[dependencies.rusqlite] +version = "0.13" +features = ["limits"] + +[dependencies.edn] +path = "../edn" + +[dependencies.core_traits] +path = "../core-traits" + +[dependencies.db_traits] +path = "../db-traits" + +[dependencies.query_pull_traits] +path = "../query-pull-traits" + +[dependencies.mentat_query_algebrizer] +path = "../query-algebrizer" + +[dependencies.mentat_query_sql] +path = "../query-sql" + +[dev-dependencies.mentat_core] +path = "../core" + +[dev-dependencies.mentat_query_projector] +path = "../query-projector" diff --git a/query-projector/src/aggregates.rs b/query-projector-traits/aggregates.rs similarity index 93% rename from query-projector/src/aggregates.rs rename to query-projector-traits/aggregates.rs index 230dd150..a99a003c 100644 --- a/query-projector/src/aggregates.rs +++ b/query-projector-traits/aggregates.rs @@ -47,7 +47,7 @@ pub enum SimpleAggregationOp { } impl SimpleAggregationOp { - pub(crate) fn to_sql(&self) -> &'static str { + pub fn to_sql(&self) -> &'static str { use self::SimpleAggregationOp::*; match self { &Avg => "avg", @@ -76,7 +76,7 @@ impl SimpleAggregationOp { /// but invalid to take `Max` of `{Uuid, String}`. /// /// The returned type is the type of the result of the aggregation. - pub(crate) fn is_applicable_to_types(&self, possibilities: ValueTypeSet) -> Result { + pub fn is_applicable_to_types(&self, possibilities: ValueTypeSet) -> Result { use self::SimpleAggregationOp::*; if possibilities.is_empty() { bail!(ProjectorError::CannotProjectImpossibleBinding(*self)) @@ -110,7 +110,7 @@ impl SimpleAggregationOp { &Max | &Min => { if possibilities.is_unit() { - use ValueType::*; + use self::ValueType::*; let the_type = possibilities.exemplar().expect("a type"); match the_type { // These types are numerically ordered. @@ -147,17 +147,17 @@ impl SimpleAggregationOp { } } -pub(crate) struct SimpleAggregate { +pub struct SimpleAggregate { pub op: SimpleAggregationOp, pub var: Variable, } impl SimpleAggregate { - pub(crate) fn column_name(&self) -> Name { + pub fn column_name(&self) -> Name { format!("({} {})", self.op.to_sql(), self.var.name()) } - pub(crate) fn use_static_value(&self) -> bool { + pub fn use_static_value(&self) -> bool { use self::SimpleAggregationOp::*; match self.op { Avg | Max | Min => true, @@ -166,7 +166,7 @@ impl SimpleAggregate { } /// Return `true` if this aggregate can be `NULL` over 0 rows. - pub(crate) fn is_nullable(&self) -> bool { + pub fn is_nullable(&self) -> bool { use self::SimpleAggregationOp::*; match self.op { Avg | Max | Min => true, @@ -175,7 +175,7 @@ impl SimpleAggregate { } } -pub(crate) trait SimpleAggregation { +pub trait SimpleAggregation { fn to_simple(&self) -> Option; } @@ -195,7 +195,7 @@ impl SimpleAggregation for Aggregate { /// - The `ColumnOrExpression` to use in the query. This will always refer to other /// variables by name; never to a datoms column. /// - The known type of that value. -pub(crate) fn projected_column_for_simple_aggregate(simple: &SimpleAggregate, cc: &ConjoiningClauses) -> Result<(ProjectedColumn, ValueType)> { +pub fn projected_column_for_simple_aggregate(simple: &SimpleAggregate, cc: &ConjoiningClauses) -> Result<(ProjectedColumn, ValueType)> { let known_types = cc.known_type_set(&simple.var); let return_type = simple.op.is_applicable_to_types(known_types)?; let projected_column_or_expression = diff --git a/query-projector/src/errors.rs b/query-projector-traits/errors.rs similarity index 100% rename from query-projector/src/errors.rs rename to query-projector-traits/errors.rs diff --git a/query-projector-traits/lib.rs b/query-projector-traits/lib.rs new file mode 100644 index 00000000..01f315a6 --- /dev/null +++ b/query-projector-traits/lib.rs @@ -0,0 +1,28 @@ +// Copyright 2018 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. + +extern crate failure; +#[macro_use] +extern crate failure_derive; +extern crate rusqlite; + +extern crate core_traits; +extern crate db_traits; +extern crate edn; +extern crate query_pull_traits; + +// TODO we only want to import a *_traits here, this is a smell. +extern crate mentat_query_algebrizer; +extern crate mentat_query_sql; + +#[macro_use] +pub mod errors; +pub mod aggregates; + diff --git a/query-projector/tests/aggregates.rs b/query-projector-traits/tests/aggregates.rs similarity index 97% rename from query-projector/tests/aggregates.rs rename to query-projector-traits/tests/aggregates.rs index 84c13743..092d6121 100644 --- a/query-projector/tests/aggregates.rs +++ b/query-projector-traits/tests/aggregates.rs @@ -13,6 +13,7 @@ extern crate mentat_core; extern crate core_traits; extern crate mentat_query_algebrizer; extern crate mentat_query_projector; +extern crate query_projector_traits; use core_traits::{ Entid, @@ -102,7 +103,7 @@ fn test_the_without_max_or_min() { // … when we look at the projection list, we cannot reconcile the types. let projection = query_projection(&schema, &algebrized); assert!(projection.is_err()); - use ::mentat_query_projector::errors::{ + use query_projector_traits::errors::{ ProjectorError, }; match projection.err().expect("expected failure") { diff --git a/query-projector/Cargo.toml b/query-projector/Cargo.toml index b993d3e9..077700a4 100644 --- a/query-projector/Cargo.toml +++ b/query-projector/Cargo.toml @@ -5,7 +5,6 @@ workspace = ".." [dependencies] failure = "0.1.1" -failure_derive = "0.1.1" indexmap = "1" [dependencies.rusqlite] @@ -39,6 +38,9 @@ path = "../query-pull" [dependencies.query_pull_traits] path = "../query-pull-traits" +[dependencies.query_projector_traits] +path = "../query-projector-traits" + [dependencies.mentat_query_sql] path = "../query-sql" diff --git a/query-projector/src/binding_tuple.rs b/query-projector/src/binding_tuple.rs index 02fc94c9..140e2d51 100644 --- a/query-projector/src/binding_tuple.rs +++ b/query-projector/src/binding_tuple.rs @@ -12,7 +12,7 @@ use core_traits::{ Binding, }; -use errors::{ +use query_projector_traits::errors::{ ProjectorError, Result, }; diff --git a/query-projector/src/lib.rs b/query-projector/src/lib.rs index 1de16b86..6365ecd2 100644 --- a/query-projector/src/lib.rs +++ b/query-projector/src/lib.rs @@ -10,8 +10,6 @@ extern crate failure; -#[macro_use] -extern crate failure_derive; extern crate indexmap; extern crate rusqlite; @@ -23,6 +21,8 @@ extern crate mentat_db; // For value conversion. extern crate mentat_query_algebrizer; extern crate mentat_query_pull; extern crate query_pull_traits; +#[macro_use] +extern crate query_projector_traits; extern crate mentat_query_sql; extern crate mentat_sql; @@ -42,7 +42,6 @@ use rusqlite::{ use core_traits::{ Binding, TypedValue, - ValueType, }; use mentat_core::{ @@ -75,10 +74,6 @@ use mentat_query_sql::{ Projection, }; -#[macro_use] -pub mod errors; - -mod aggregates; mod binding_tuple; pub use binding_tuple::{ BindingTuple, @@ -88,10 +83,6 @@ mod projectors; mod pull; mod relresult; -pub use aggregates::{ - SimpleAggregationOp, -}; - use project::{ ProjectedElements, project_elements, @@ -122,7 +113,7 @@ pub use relresult::{ StructuredRelResult, }; -pub use errors::{ +use query_projector_traits::errors::{ ProjectorError, Result, }; diff --git a/query-projector/src/project.rs b/query-projector/src/project.rs index 16bb8da4..d7f0ca20 100644 --- a/query-projector/src/project.rs +++ b/query-projector/src/project.rs @@ -52,12 +52,12 @@ use mentat_query_sql::{ ProjectedColumn, }; -use aggregates::{ +use query_projector_traits::aggregates::{ SimpleAggregation, projected_column_for_simple_aggregate, }; -use errors::{ +use query_projector_traits::errors::{ ProjectorError, Result, }; @@ -313,7 +313,7 @@ pub(crate) fn project_elements<'a, I: IntoIterator>( if let Some(simple) = a.to_simple() { aggregates = true; - use aggregates::SimpleAggregationOp::*; + use query_projector_traits::aggregates::SimpleAggregationOp::*; match simple.op { Max | Min => { min_max_count += 1; diff --git a/query-projector/src/projectors/constant.rs b/query-projector/src/projectors/constant.rs index f56bac0a..5e35be28 100644 --- a/query-projector/src/projectors/constant.rs +++ b/query-projector/src/projectors/constant.rs @@ -20,7 +20,7 @@ use ::{ rusqlite, }; -use ::errors::{ +use query_projector_traits::errors::{ Result, }; diff --git a/query-projector/src/projectors/mod.rs b/query-projector/src/projectors/mod.rs index b4e7c363..d3b47092 100644 --- a/query-projector/src/projectors/mod.rs +++ b/query-projector/src/projectors/mod.rs @@ -16,7 +16,7 @@ use super::{ rusqlite, }; -use super::errors::{ +use query_projector_traits::errors::{ Result, }; diff --git a/query-projector/src/projectors/pull_two_stage.rs b/query-projector/src/projectors/pull_two_stage.rs index 63de6401..01a639b7 100644 --- a/query-projector/src/projectors/pull_two_stage.rs +++ b/query-projector/src/projectors/pull_two_stage.rs @@ -44,7 +44,7 @@ use ::pull::{ PullTemplate, }; -use ::errors::{ +use query_projector_traits::errors::{ Result, }; diff --git a/query-projector/src/projectors/simple.rs b/query-projector/src/projectors/simple.rs index 337fc214..b6b61b7d 100644 --- a/query-projector/src/projectors/simple.rs +++ b/query-projector/src/projectors/simple.rs @@ -26,7 +26,7 @@ use ::{ rusqlite, }; -use ::errors::{ +use query_projector_traits::errors::{ Result, }; diff --git a/query-projector/src/pull.rs b/query-projector/src/pull.rs index dc66028e..33cf0b81 100644 --- a/query-projector/src/pull.rs +++ b/query-projector/src/pull.rs @@ -33,7 +33,7 @@ use mentat_query_pull::{ Puller, }; -use errors::Result; +use query_projector_traits::errors::Result; use super::{ Index, diff --git a/query-translator/Cargo.toml b/query-translator/Cargo.toml index 7eb9692c..8916f775 100644 --- a/query-translator/Cargo.toml +++ b/query-translator/Cargo.toml @@ -25,5 +25,8 @@ path = "../query-algebrizer" [dependencies.mentat_query_projector] path = "../query-projector" +[dependencies.query_projector_traits] +path = "../query-projector-traits" + [dependencies.mentat_query_sql] path = "../query-sql" diff --git a/query-translator/src/lib.rs b/query-translator/src/lib.rs index 59a46c36..0e98a808 100644 --- a/query-translator/src/lib.rs +++ b/query-translator/src/lib.rs @@ -15,6 +15,7 @@ extern crate core_traits; extern crate mentat_core; extern crate mentat_query_algebrizer; extern crate mentat_query_projector; +extern crate query_projector_traits; extern crate mentat_query_sql; extern crate mentat_sql; @@ -31,5 +32,5 @@ pub use translate::{ }; // query-translator could be folded into query-projector; for now, just type alias the errors. -pub type TranslatorError = mentat_query_projector::ProjectorError; +pub type TranslatorError = query_projector_traits::errors::ProjectorError; pub type Result = std::result::Result; diff --git a/src/errors.rs b/src/errors.rs index c6c98187..eb990d11 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -30,7 +30,9 @@ use db_traits::errors::DbError; use query_algebrizer_traits::errors::{ AlgebrizerError, }; -use mentat_query_projector; +use query_projector_traits::errors::{ + ProjectorError, +}; use query_pull_traits::errors::{ PullError, }; @@ -107,7 +109,7 @@ pub enum MentatError { AlgebrizerError(#[cause] AlgebrizerError), #[fail(display = "{}", _0)] - ProjectorError(#[cause] mentat_query_projector::ProjectorError), + ProjectorError(#[cause] ProjectorError), #[fail(display = "{}", _0)] PullError(#[cause] PullError), @@ -150,8 +152,8 @@ impl From for MentatError { } } -impl From for MentatError { - fn from(error: mentat_query_projector::ProjectorError) -> MentatError { +impl From for MentatError { + fn from(error: ProjectorError) -> MentatError { MentatError::ProjectorError(error) } } diff --git a/src/lib.rs b/src/lib.rs index c8437f06..f5d12a6d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,6 +29,7 @@ extern crate db_traits; extern crate mentat_query_algebrizer; extern crate query_algebrizer_traits; extern crate mentat_query_projector; +extern crate query_projector_traits; extern crate mentat_query_pull; extern crate query_pull_traits; extern crate mentat_query_translator; @@ -141,9 +142,11 @@ pub use edn::{ ToMillis, }; pub use query_algebrizer_traits::errors::AlgebrizerError; +pub use query_projector_traits::errors::{ + ProjectorError, +}; pub use mentat_query_projector::{ BindingTuple, - ProjectorError, }; pub use query_pull_traits::errors::PullError; pub use mentat_sql::SQLError; diff --git a/tests/query.rs b/tests/query.rs index fe8f70dd..dbf6a0d4 100644 --- a/tests/query.rs +++ b/tests/query.rs @@ -19,7 +19,7 @@ extern crate mentat_db; // TODO: when we switch to `failure`, make this more humane. extern crate query_algebrizer_traits; // For errors; -extern crate mentat_query_projector; // For errors. +extern crate query_projector_traits; // For errors. extern crate mentat_query_translator; // For errors. use std::str::FromStr; @@ -40,7 +40,7 @@ use mentat_core::{ Uuid, }; -use mentat_query_projector::{ +use query_projector_traits::aggregates::{ SimpleAggregationOp, }; @@ -587,7 +587,7 @@ fn test_aggregates_type_handling() { let r = store.q_once(r#"[:find (sum ?v) . :where [_ _ ?v]]"#, None); let all_types = ValueTypeSet::any(); match r.expect_err("expected query to fail") { - MentatError::ProjectorError(::mentat_query_projector::errors::ProjectorError::CannotApplyAggregateOperationToTypes( + MentatError::ProjectorError(::query_projector_traits::errors::ProjectorError::CannotApplyAggregateOperationToTypes( SimpleAggregationOp::Sum, types)) => { assert_eq!(types, all_types); }, @@ -599,7 +599,7 @@ fn test_aggregates_type_handling() { :where [_ _ ?v] [(type ?v :db.type/instant)]]"#, None); match r.expect_err("expected query to fail") { - MentatError::ProjectorError(::mentat_query_projector::errors::ProjectorError::CannotApplyAggregateOperationToTypes( + MentatError::ProjectorError(::query_projector_traits::errors::ProjectorError::CannotApplyAggregateOperationToTypes( SimpleAggregationOp::Sum, types)) => { assert_eq!(types, ValueTypeSet::of_one(ValueType::Instant)); @@ -1341,7 +1341,7 @@ fn test_aggregation_implicit_grouping() { [?person :foo/is-vegetarian true] [?person :foo/name ?name]]"#, None); match res.expect_err("expected query to fail") { - MentatError::ProjectorError(::mentat_query_projector::errors::ProjectorError::AmbiguousAggregates(mmc, cc)) => { + MentatError::ProjectorError(::query_projector_traits::errors::ProjectorError::AmbiguousAggregates(mmc, cc)) => { assert_eq!(mmc, 2); assert_eq!(cc, 1); },