pass base types into clause creation functions, rather than enum types

This commit is contained in:
Emily Toop 2018-03-23 15:35:22 +00:00
parent 1749bc31a2
commit 06c2d3c179

View file

@ -11,12 +11,20 @@
#![macro_use] #![macro_use]
use mentat_core::{ use mentat_core::{
Entid, Entid,
NamespacedKeyword,
TypedValue,
}; };
use mentat_query::{ use mentat_query::{
Variable, Variable,
}; };
use edn::{
DateTime,
Utc,
Uuid,
};
use errors::{ use errors::{
Result, Result,
}; };
@ -24,25 +32,83 @@ use errors::{
pub enum EntityType { pub enum EntityType {
Predicate(String), Predicate(String),
Ref(Entid), Ref(Entid),
Var(String), Var(Variable),
}
impl From<String> for EntityType {
fn from(v: String) -> EntityType {
EntityType::Predicate(v)
}
}
impl<'a> From<&'a str> for EntityType {
fn from(v: &'a str) -> EntityType {
EntityType::Predicate(v.to_string())
}
}
impl From<Entid> for EntityType {
fn from(v: Entid) -> EntityType {
EntityType::Ref(v)
}
}
impl From<Variable> for EntityType {
fn from(v: Variable) -> EntityType {
EntityType::Var(v)
}
} }
pub enum AttributeType { pub enum AttributeType {
Keyword(String), Keyword(NamespacedKeyword),
Ref(Entid), Ref(Entid),
Var(String), Var(Variable),
}
impl From<NamespacedKeyword> for AttributeType {
fn from(v: NamespacedKeyword) -> AttributeType {
AttributeType::Keyword(v)
}
}
impl From<Entid> for AttributeType {
fn from(v: Entid) -> AttributeType {
AttributeType::Ref(v)
}
}
impl From<Variable> for AttributeType {
fn from(v: Variable) -> AttributeType {
AttributeType::Var(v)
}
} }
pub enum QueryValueType { pub enum QueryValueType {
Boolean(bool), Var(Variable),
Double(f64), Value(TypedValue),
Instant(i64), }
Keyword(String),
Long(i64), impl QueryValueType {
Ref(Entid), pub fn value<T>(value: T) -> Self where T: Into<TypedValue> {
String(String), let typed_value: TypedValue = value.into();
Uuid(String), typed_value.into()
Var(String), }
pub fn variable(value: Variable) -> Self {
value.into()
}
}
impl From<Variable> for QueryValueType {
fn from(v: Variable) -> QueryValueType {
QueryValueType::Var(v)
}
}
impl From<TypedValue> for QueryValueType {
fn from(v: TypedValue) -> QueryValueType {
QueryValueType::Value(v)
}
} }
pub enum FindType { pub enum FindType {
@ -174,15 +240,8 @@ impl WhereBuilder {
self self
} }
pub fn add_clause<E, A, V>(mut self, entity: E, attribute: A, value: V) -> Self pub fn add_clause<F>(mut self, clause_fn: F) -> Self where F: 'static + FnOnce(WhereClauseBuilder) -> WhereClauseBuilder {
where E: Into<Option<EntityType>>, self.clauses.push(Box::new(clause_fn(WhereClauseBuilder::default())));
A: Into<Option<AttributeType>>,
V: Into<Option<QueryValueType>> {
self.clauses.push(Box::new( WhereClauseBuilder{
entity: entity.into(),
attribute: attribute.into(),
value: value.into(),
}));
self self
} }
@ -198,18 +257,18 @@ impl WhereBuilder {
} }
impl WhereClauseBuilder { impl WhereClauseBuilder {
pub fn add_entity(mut self, entity: EntityType) -> Self { pub fn entity<E>(mut self, entity: E) -> Self where E: Into<EntityType> {
self.entity = Some(entity); self.entity = Some(entity.into());
self self
} }
pub fn add_attribute(mut self, attribute: AttributeType) -> Self { pub fn attribute<A>(mut self, attribute: A) -> Self where A: Into<AttributeType> {
self.attribute = Some(attribute); self.attribute = Some(attribute.into());
self self
} }
pub fn add_value(mut self, value: QueryValueType) -> Self { pub fn value<V>(mut self, value: V) -> Self where V: Into<QueryValueType> {
self.value = Some(value); self.value = Some(value.into());
self self
} }
} }
@ -225,15 +284,8 @@ impl NotClauseBuilder {
self self
} }
pub fn add_clause<E, A, V>(mut self, entity: E, attribute: A, value: V) -> Self pub fn add_clause<F>(mut self, clause_fn: F) -> Self where F: 'static + FnOnce(WhereClauseBuilder) -> WhereClauseBuilder {
where E: Into<Option<EntityType>>, self.clauses.push(Box::new(clause_fn(WhereClauseBuilder::default())));
A: Into<Option<AttributeType>>,
V: Into<Option<QueryValueType>> {
self.clauses.push(Box::new( WhereClauseBuilder{
entity: entity.into(),
attribute: attribute.into(),
value: value.into(),
}));
self self
} }
@ -264,15 +316,8 @@ impl OrClauseBuilder {
self self
} }
pub fn add_clause<E, A, V>(mut self, entity: E, attribute: A, value: V) -> Self pub fn add_clause<F>(mut self, clause_fn: F) -> Self where F: 'static + FnOnce(WhereClauseBuilder) -> WhereClauseBuilder {
where E: Into<Option<EntityType>>, self.clauses.push(Box::new(clause_fn(WhereClauseBuilder::default())));
A: Into<Option<AttributeType>>,
V: Into<Option<QueryValueType>> {
self.clauses.push(Box::new( WhereClauseBuilder{
entity: entity.into(),
attribute: attribute.into(),
value: value.into(),
}));
self self
} }
@ -298,15 +343,8 @@ impl AndClauseBuilder {
self self
} }
pub fn add_clause<E, A, V>(mut self, entity: E, attribute: A, value: V) -> Self pub fn add_clause<F>(mut self, clause_fn: F) -> Self where F: 'static + FnOnce(WhereClauseBuilder) -> WhereClauseBuilder {
where E: Into<Option<EntityType>>, self.clauses.push(Box::new(clause_fn(WhereClauseBuilder::default())));
A: Into<Option<AttributeType>>,
V: Into<Option<QueryValueType>> {
self.clauses.push(Box::new( WhereClauseBuilder{
entity: entity.into(),
attribute: attribute.into(),
value: value.into(),
}));
self self
} }
@ -358,7 +396,9 @@ mod test {
fn test_find_rel() { fn test_find_rel() {
let _ = query().add_find(|find| find.add("?x")) let _ = query().add_find(|find| find.add("?x"))
.add_where(|w| { .add_where(|w| {
w.add_clause(EntityType::Var("?x".to_string()), AttributeType::Keyword(":foo/bar".to_string()), QueryValueType::String("yyy".to_string())) w.add_clause(|c| c.entity(var!(?x))
.attribute(kw!(:foo/bar))
.value(QueryValueType::value("yyy")))
}).execute(); }).execute();
panic!("not complete"); panic!("not complete");
} }
@ -368,7 +408,8 @@ mod test {
fn test_find_no_attribute() { fn test_find_no_attribute() {
let _ = query().add_find(|find| find.add("?x")) let _ = query().add_find(|find| find.add("?x"))
.add_where(|w| { .add_where(|w| {
w.add_clause(EntityType::Var("?x".to_string()), None, QueryValueType::String("yyy".to_string())) w.add_clause(|c| c.entity(var!(?x))
.value(QueryValueType::value("yyy")))
}).execute(); }).execute();
panic!("not complete"); panic!("not complete");
} }
@ -378,7 +419,9 @@ mod test {
fn test_find_scalar() { fn test_find_scalar() {
let _ = query().add_find(|find| find.set_type(FindType::Scalar).add("?x")) let _ = query().add_find(|find| find.set_type(FindType::Scalar).add("?x"))
.add_where(|w| { .add_where(|w| {
w.add_clause(EntityType::Var("?x".to_string()), AttributeType::Keyword(":foo/bar".to_string()), QueryValueType::String("yyy".to_string())) w.add_clause(|c| c.entity(var!(?x))
.attribute(kw!(:foo/bar))
.value(QueryValueType::value("yyy")))
}).execute(); }).execute();
panic!("not complete"); panic!("not complete");
} }
@ -397,11 +440,19 @@ mod test {
.add_where(|w| { .add_where(|w| {
w.add_or(|or| { w.add_or(|or| {
or.join("?page") or.join("?page")
.add_clause(EntityType::Var("?page".to_string()), AttributeType::Keyword(":page/url".to_string()), QueryValueType::String("http://foo.com/".to_string())) .add_clause(|c| c.entity(var!(?page))
.add_clause(EntityType::Var("?page".to_string()), AttributeType::Keyword(":page/title".to_string()), QueryValueType::String("Foo".to_string())) .attribute(kw!(:page/url))
.value(QueryValueType::value("http://foo.com/")))
.add_clause(|c| c.entity(var!(?page))
.attribute(kw!(:page/title))
.value(QueryValueType::value("Foo")))
}) })
.add_clause(EntityType::Var("?page".to_string()), AttributeType::Keyword(":page/url".to_string()), QueryValueType::Var("?url".to_string())) .add_clause(|c| c.entity(var!(?page))
.add_clause(EntityType::Var("?page".to_string()), AttributeType::Keyword(":page/description".to_string()), QueryValueType::Var("?description".to_string())) .attribute(kw!(:page/url))
.value(var!(?url)))
.add_clause(|c| c.entity(var!(?page))
.attribute(kw!(:page/description))
.value(var!(?description)))
}) })
.execute(); .execute();
panic!("not complete"); panic!("not complete");
@ -413,7 +464,9 @@ mod test {
fn test_find_with_limit() { fn test_find_with_limit() {
let _ = query().add_find(|find| find.add("?x")) let _ = query().add_find(|find| find.add("?x"))
.add_where(|w| { .add_where(|w| {
w.add_clause(EntityType::Var("?x".to_string()), AttributeType::Keyword(":foo/baz".to_string()), QueryValueType::Var("?y".to_string())) w.add_clause(|c| c.entity(var!(?x))
.attribute(kw!(:foo/baz))
.value(var!(?y)))
}) })
.add_limit(1000) .add_limit(1000)
.execute(); .execute();
@ -425,7 +478,9 @@ mod test {
fn test_find_with_default_order() { fn test_find_with_default_order() {
let _ = query().add_find(|find| find.add("?x")) let _ = query().add_find(|find| find.add("?x"))
.add_where(|w| { .add_where(|w| {
w.add_clause(EntityType::Var("?x".to_string()), AttributeType::Keyword(":foo/baz".to_string()), QueryValueType::Var("?y".to_string())) w.add_clause(|c| c.entity(var!(?x))
.attribute(kw!(:foo/baz))
.value(var!(?y)))
}) })
.add_order(|order| order.add("?y")) .add_order(|order| order.add("?y"))
.execute(); .execute();
@ -437,7 +492,9 @@ mod test {
fn test_find_with_desc_order() { fn test_find_with_desc_order() {
let _ = query().add_find(|find| find.add("?x")) let _ = query().add_find(|find| find.add("?x"))
.add_where(|w| { .add_where(|w| {
w.add_clause(EntityType::Var("?x".to_string()), AttributeType::Keyword(":foo/bar".to_string()), QueryValueType::Var("?y".to_string())) w.add_clause(|c| c.entity(var!(?x))
.attribute(kw!(:foo/bar))
.value(var!(?y)))
}) })
.add_order(|order| order.add_descending("?y")) .add_order(|order| order.add_descending("?y"))
.execute(); .execute();
@ -449,7 +506,9 @@ mod test {
fn test_find_with_multiple_orders() { fn test_find_with_multiple_orders() {
let _ = query().add_find(|find| find.add("?x")) let _ = query().add_find(|find| find.add("?x"))
.add_where(|w| { .add_where(|w| {
w.add_clause(EntityType::Var("?x".to_string()), AttributeType::Keyword(":foo/baz".to_string()), QueryValueType::Var("?y".to_string())) w.add_clause(|c| c.entity(var!(?x))
.attribute(kw!(:foo/baz))
.value(var!(?y)))
}) })
.add_order(|order| order.add_descending("?y").add_ascending("?x")) .add_order(|order| order.add_descending("?y").add_ascending("?x"))
.execute(); .execute();
@ -461,8 +520,12 @@ mod test {
fn test_find_with_predicate() { fn test_find_with_predicate() {
let _ = query().add_find(|find| find.set_type(FindType::Scalar).add("?x")) let _ = query().add_find(|find| find.set_type(FindType::Scalar).add("?x"))
.add_where(|w| { .add_where(|w| {
w.add_clause(EntityType::Var("?x".to_string()), AttributeType::Keyword(":foo/bar".to_string()), QueryValueType::Var("?y".to_string())) w.add_clause(|c| c.entity(var!(?x))
.add_clause(EntityType::Predicate("!=".to_string()), AttributeType::Var("?y".to_string()), QueryValueType::Long(12)) .attribute(kw!(:foo/bar))
.value(var!(?y)))
.add_clause(|c| c.entity("!=")
.attribute(var!(?y))
.value(QueryValueType::value(12)))
}) })
.execute(); .execute();
panic!("not complete"); panic!("not complete");