Compare commits

...

20 commits

Author SHA1 Message Date
Grisha Kruglov a7bb805982 Bump version to 0.11.1 2018-08-09 13:13:37 -07:00
Grisha Kruglov e188397981 Post: Make tests pass on Rust 1.25.0
For some reason, the converted doc test fails on Rust 1.25.0, while
working with other Rust versions. For simplicity, just convert it into
a regular test.
2018-08-09 13:13:36 -07:00
Grisha Kruglov 994a93004b Post: Remove bunch of dependencies from query-pull 2018-08-09 13:13:36 -07:00
Grisha Kruglov cfedfea190 Post: Remove mentat_sql dependency from query-projector 2018-08-09 13:13:35 -07:00
Grisha Kruglov 40ff6a1ed0 Post: Use a single implementation of bail macro 2018-08-09 13:13:35 -07:00
Grisha Kruglov b6f3e716e4 Part 1: Move public errors into public-traits 2018-08-09 13:13:34 -07:00
Grisha Kruglov 722921760e Pre: Remove :: dependency from src/errors.rs 2018-08-09 13:13:33 -07:00
Grisha Kruglov 99301398a3 Pre: Move tolstoy/errors into tolstoy-traits 2018-08-08 16:05:26 -07:00
Grisha Kruglov 2c8f197a3f Pre: Move core/Attribute* to core-traits 2018-08-08 16:05:22 -07:00
Grisha Kruglov 474d17d3da Pre: Move sql/errors into sql_traits 2018-08-08 16:05:17 -07:00
Grisha Kruglov cd0bd46232 Pre: Fold query-translator into query-projector 2018-08-08 16:05:13 -07:00
Grisha Kruglov 9444559f6c Pre: Move query-projectors/errors and aggregates into query-projector-traits 2018-08-08 16:05:09 -07:00
Grisha Kruglov f7111c799d Pre: Move query-algebrizer/error.rs into query-algebrizer-traits 2018-08-08 16:05:04 -07:00
Grisha Kruglov 5b875a26b9 Pre: Move ValueTypeSet into core-traits 2018-08-08 16:04:59 -07:00
Grisha Kruglov aea988ff55 Pre: Do not re-export EdnParseError from core 2018-08-08 16:04:54 -07:00
Grisha Kruglov 30f1304c3a Pre: Remove query/ crate 2018-08-08 16:04:49 -07:00
Grisha Kruglov 32e57bee7a Pre: Move query-pull/errors into query-pull-traits 2018-08-08 16:04:43 -07:00
Grisha Kruglov 055b42af0a Pre: Move db/errors.rs into db_traits 2018-08-08 16:04:38 -07:00
Grisha Kruglov 1f89968403 Pre: Move core/types.rs into core_traits 2018-08-08 16:04:33 -07:00
Grisha Kruglov 163635a4a7 Pre: Move Entid and KnownEntid into core_traits 2018-08-08 16:04:27 -07:00
119 changed files with 2227 additions and 1689 deletions

View file

@ -1,3 +1,12 @@
# 0.11.1 (2018-08-09)
* sdks/android compiled against:
* Kotlin standard library 1.2.41
* **API changes**: Changed wording of MentatError::ConflictingAttributeDefinitions, MentatError::ExistingVocabularyTooNew, MentatError::UnexpectedCoreSchema.
* [Commits](https://github.com/mozilla/mentat/compare/v0.11.0...v0.11.1)
# 0.11 (2018-07-31)
* sdks/android compiled against:

View file

@ -12,14 +12,14 @@ authors = [
"Thom Chiovoloni <tchiovoloni@mozilla.com>",
]
name = "mentat"
version = "0.11.0"
version = "0.11.1"
build = "build/version.rs"
[features]
default = ["bundled_sqlite3", "syncable"]
bundled_sqlite3 = ["rusqlite/bundled"]
sqlcipher = ["rusqlite/sqlcipher", "mentat_db/sqlcipher"]
syncable = ["mentat_tolstoy", "mentat_db/syncable"]
syncable = ["mentat_tolstoy", "tolstoy_traits", "mentat_db/syncable"]
[workspace]
members = ["tools/cli", "ffi"]
@ -30,7 +30,6 @@ rustc_version = "0.2"
[dependencies]
chrono = "0.4"
failure = "0.1.1"
failure_derive = "0.1.1"
lazy_static = "0.2"
time = "0.1"
uuid = { version = "0.5", features = ["v4", "serde"] }
@ -43,6 +42,9 @@ features = ["limits"]
[dependencies.edn]
path = "edn"
[dependencies.core_traits]
path = "core-traits"
[dependencies.mentat_core]
path = "core"
@ -52,28 +54,44 @@ path = "sql"
[dependencies.mentat_db]
path = "db"
[dependencies.mentat_query]
path = "query"
[dependencies.db_traits]
path = "db-traits"
[dependencies.mentat_query_algebrizer]
path = "query-algebrizer"
[dependencies.query_algebrizer_traits]
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"
[dependencies.query_pull_traits]
path = "query-pull-traits"
[dependencies.mentat_query_sql]
path = "query-sql"
[dependencies.mentat_query_translator]
path = "query-translator"
[dependencies.sql_traits]
path = "sql-traits"
[dependencies.public_traits]
path = "public-traits"
[dependencies.mentat_tolstoy]
path = "tolstoy"
optional = true
[dependencies.tolstoy_traits]
path = "tolstoy-traits"
optional = true
[profile.release]
opt-level = 3
debug = false

22
core-traits/Cargo.toml Normal file
View file

@ -0,0 +1,22 @@
[package]
name = "core_traits"
version = "0.0.1"
workspace = ".."
[lib]
name = "core_traits"
path = "lib.rs"
[dependencies]
chrono = { version = "0.4", features = ["serde"] }
enum-set = "0.0.7"
lazy_static = "0.2"
indexmap = "1"
ordered-float = { version = "0.5", features = ["serde"] }
uuid = { version = "0.5", features = ["v4", "serde"] }
serde = { version = "1.0", features = ["rc"] }
serde_derive = "1.0"
[dependencies.edn]
path = "../edn"
features = ["serde_support"]

1082
core-traits/lib.rs Normal file

File diff suppressed because it is too large Load diff

View file

@ -8,11 +8,11 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use ::enum_set::{
use enum_set::{
EnumSet,
};
use ::types::{
use ::{
ValueType,
};

View file

@ -8,11 +8,11 @@ chrono = { version = "0.4", features = ["serde"] }
enum-set = "0.0.7"
failure = "0.1.1"
indexmap = "1"
lazy_static = "0.2"
ordered-float = { version = "0.5", features = ["serde"] }
uuid = { version = "0.5", features = ["v4", "serde"] }
serde = { version = "1.0", features = ["rc"] }
serde_derive = "1.0"
[dependencies.core_traits]
path = "../core-traits"
[dependencies.edn]
path = "../edn"

View file

@ -14,12 +14,15 @@ use std::collections::{
BTreeSet,
};
use ::{
use core_traits::{
Entid,
Schema,
TypedValue,
};
use ::{
Schema,
};
pub trait CachedAttributes {
fn is_attribute_cached_reverse(&self, entid: Entid) -> bool;
fn is_attribute_cached_forward(&self, entid: Entid) -> bool;

View file

@ -14,17 +14,18 @@ extern crate failure;
extern crate indexmap;
extern crate ordered_float;
extern crate uuid;
extern crate serde;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate serde_derive;
extern crate core_traits;
extern crate edn;
pub mod values;
use core_traits::{
Attribute,
Entid,
KnownEntid,
ValueType,
};
mod cache;
use std::collections::{
@ -50,7 +51,6 @@ pub use edn::{
pub use edn::parse::{
parse_query,
ParseError as EdnParseError,
};
pub use cache::{
@ -61,7 +61,6 @@ pub use cache::{
/// Core types defining a Mentat knowledge base.
mod types;
mod tx_report;
mod value_type_set;
mod sql_types;
pub use tx_report::{
@ -69,18 +68,7 @@ pub use tx_report::{
};
pub use types::{
Binding,
Entid,
KnownEntid,
StructuredMap,
TypedValue,
ValueType,
ValueTypeTag,
now,
};
pub use value_type_set::{
ValueTypeSet,
};
pub use sql_types::{
@ -89,159 +77,6 @@ pub use sql_types::{
SQLValueTypeSet,
};
/// Bit flags used in `flags0` column in temporary tables created during search,
/// such as the `search_results`, `inexact_searches` and `exact_searches` tables.
/// When moving to a more concrete table, such as `datoms`, they are expanded out
/// via these flags and put into their own column rather than a bit field.
pub enum AttributeBitFlags {
IndexAVET = 1 << 0,
IndexVAET = 1 << 1,
IndexFulltext = 1 << 2,
UniqueValue = 1 << 3,
}
pub mod attribute {
use TypedValue;
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)]
pub enum Unique {
Value,
Identity,
}
impl Unique {
// This is easier than rejigging DB_UNIQUE_VALUE to not be EDN.
pub fn into_typed_value(self) -> TypedValue {
match self {
Unique::Value => TypedValue::typed_ns_keyword("db.unique", "value"),
Unique::Identity => TypedValue::typed_ns_keyword("db.unique", "identity"),
}
}
}
}
/// A Mentat schema attribute has a value type and several other flags determining how assertions
/// with the attribute are interpreted.
///
/// TODO: consider packing this into a bitfield or similar.
#[derive(Clone,Debug,Eq,Hash,Ord,PartialOrd,PartialEq)]
pub struct Attribute {
/// The associated value type, i.e., `:db/valueType`?
pub value_type: ValueType,
/// `true` if this attribute is multi-valued, i.e., it is `:db/cardinality
/// :db.cardinality/many`. `false` if this attribute is single-valued (the default), i.e., it
/// is `:db/cardinality :db.cardinality/one`.
pub multival: bool,
/// `None` if this attribute is neither unique-value nor unique-identity.
///
/// `Some(attribute::Unique::Value)` if this attribute is unique-value, i.e., it is `:db/unique
/// :db.unique/value`.
///
/// *Unique-value* means that there is at most one assertion with the attribute and a
/// particular value in the datom store. Unique-value attributes can be used in lookup-refs.
///
/// `Some(attribute::Unique::Identity)` if this attribute is unique-identity, i.e., it is `:db/unique
/// :db.unique/identity`.
///
/// Unique-identity attributes always have value type `Ref`.
///
/// *Unique-identity* means that the attribute is *unique-value* and that they can be used in
/// lookup-refs and will automatically upsert where appropriate.
pub unique: Option<attribute::Unique>,
/// `true` if this attribute is automatically indexed, i.e., it is `:db/indexing true`.
pub index: bool,
/// `true` if this attribute is automatically fulltext indexed, i.e., it is `:db/fulltext true`.
///
/// Fulltext attributes always have string values.
pub fulltext: bool,
/// `true` if this attribute is a component, i.e., it is `:db/isComponent true`.
///
/// Component attributes always have value type `Ref`.
///
/// They are used to compose entities from component sub-entities: they are fetched recursively
/// by pull expressions, and they are automatically recursively deleted where appropriate.
pub component: bool,
/// `true` if this attribute doesn't require history to be kept, i.e., it is `:db/noHistory true`.
pub no_history: bool,
}
impl Attribute {
/// Combine several attribute flags into a bitfield used in temporary search tables.
pub fn flags(&self) -> u8 {
let mut flags: u8 = 0;
if self.index {
flags |= AttributeBitFlags::IndexAVET as u8;
}
if self.value_type == ValueType::Ref {
flags |= AttributeBitFlags::IndexVAET as u8;
}
if self.fulltext {
flags |= AttributeBitFlags::IndexFulltext as u8;
}
if self.unique.is_some() {
flags |= AttributeBitFlags::UniqueValue as u8;
}
flags
}
pub fn to_edn_value(&self, ident: Option<Keyword>) -> edn::Value {
let mut attribute_map: BTreeMap<edn::Value, edn::Value> = BTreeMap::default();
if let Some(ident) = ident {
attribute_map.insert(values::DB_IDENT.clone(), edn::Value::Keyword(ident));
}
attribute_map.insert(values::DB_VALUE_TYPE.clone(), self.value_type.into_edn_value());
attribute_map.insert(values::DB_CARDINALITY.clone(), if self.multival { values::DB_CARDINALITY_MANY.clone() } else { values::DB_CARDINALITY_ONE.clone() });
match self.unique {
Some(attribute::Unique::Value) => { attribute_map.insert(values::DB_UNIQUE.clone(), values::DB_UNIQUE_VALUE.clone()); },
Some(attribute::Unique::Identity) => { attribute_map.insert(values::DB_UNIQUE.clone(), values::DB_UNIQUE_IDENTITY.clone()); },
None => (),
}
if self.index {
attribute_map.insert(values::DB_INDEX.clone(), edn::Value::Boolean(true));
}
if self.fulltext {
attribute_map.insert(values::DB_FULLTEXT.clone(), edn::Value::Boolean(true));
}
if self.component {
attribute_map.insert(values::DB_IS_COMPONENT.clone(), edn::Value::Boolean(true));
}
if self.no_history {
attribute_map.insert(values::DB_NO_HISTORY.clone(), edn::Value::Boolean(true));
}
edn::Value::Map(attribute_map)
}
}
impl Default for Attribute {
fn default() -> Attribute {
Attribute {
// There's no particular reason to favour one value type, so Ref it is.
value_type: ValueType::Ref,
fulltext: false,
index: false,
multival: false,
unique: None,
component: false,
no_history: false,
}
}
}
/// Map `Keyword` idents (`:db/ident`) to positive integer entids (`1`).
pub type IdentMap = BTreeMap<Keyword, Entid>;
@ -418,6 +253,11 @@ mod test {
use std::str::FromStr;
use core_traits::{
attribute,
TypedValue,
};
fn associate_ident(schema: &mut Schema, i: Keyword, e: Entid) {
schema.entid_map.insert(e, i.clone());
schema.ident_map.insert(i, e);
@ -427,54 +267,6 @@ mod test {
schema.attribute_map.insert(e, a);
}
#[test]
fn test_attribute_flags() {
let attr1 = Attribute {
index: true,
value_type: ValueType::Ref,
fulltext: false,
unique: None,
multival: false,
component: false,
no_history: false,
};
assert!(attr1.flags() & AttributeBitFlags::IndexAVET as u8 != 0);
assert!(attr1.flags() & AttributeBitFlags::IndexVAET as u8 != 0);
assert!(attr1.flags() & AttributeBitFlags::IndexFulltext as u8 == 0);
assert!(attr1.flags() & AttributeBitFlags::UniqueValue as u8 == 0);
let attr2 = Attribute {
index: false,
value_type: ValueType::Boolean,
fulltext: true,
unique: Some(attribute::Unique::Value),
multival: false,
component: false,
no_history: false,
};
assert!(attr2.flags() & AttributeBitFlags::IndexAVET as u8 == 0);
assert!(attr2.flags() & AttributeBitFlags::IndexVAET as u8 == 0);
assert!(attr2.flags() & AttributeBitFlags::IndexFulltext as u8 != 0);
assert!(attr2.flags() & AttributeBitFlags::UniqueValue as u8 != 0);
let attr3 = Attribute {
index: false,
value_type: ValueType::Boolean,
fulltext: true,
unique: Some(attribute::Unique::Identity),
multival: false,
component: false,
no_history: false,
};
assert!(attr3.flags() & AttributeBitFlags::IndexAVET as u8 == 0);
assert!(attr3.flags() & AttributeBitFlags::IndexVAET as u8 == 0);
assert!(attr3.flags() & AttributeBitFlags::IndexFulltext as u8 != 0);
assert!(attr3.flags() & AttributeBitFlags::UniqueValue as u8 != 0);
}
#[test]
fn test_datetime_truncation() {
let dt: DateTime<Utc> = DateTime::from_str("2018-01-11T00:34:09.273457004Z").expect("parsed");

View file

@ -12,13 +12,13 @@ use std::collections::{
BTreeSet,
};
use types::{
use core_traits::{
ValueType,
ValueTypeTag,
ValueTypeSet,
};
use value_type_set::{
ValueTypeSet,
use types::{
ValueTypeTag,
};
/// Type safe representation of the possible return values from SQLite's `typeof`
@ -68,16 +68,6 @@ impl SQLValueType for ValueType {
/// Returns true if the provided integer is in the SQLite value space of this type. For
/// example, `1` is how we encode `true`.
///
/// ```
/// use mentat_core::{ValueType, SQLValueType};
/// assert!(!ValueType::Instant.accommodates_integer(1493399581314));
/// assert!(!ValueType::Instant.accommodates_integer(1493399581314000));
/// assert!(ValueType::Boolean.accommodates_integer(1));
/// assert!(!ValueType::Boolean.accommodates_integer(-1));
/// assert!(!ValueType::Boolean.accommodates_integer(10));
/// assert!(!ValueType::String.accommodates_integer(10));
/// ```
fn accommodates_integer(&self, int: i64) -> bool {
use ValueType::*;
match *self {
@ -137,3 +127,23 @@ impl SQLValueTypeSet for ValueTypeSet {
!acc.is_empty()
}
}
#[cfg(test)]
mod tests {
use core_traits::{
ValueType,
};
use sql_types::{
SQLValueType,
};
#[test]
fn test_accommodates_integer() {
assert!(!ValueType::Instant.accommodates_integer(1493399581314));
assert!(!ValueType::Instant.accommodates_integer(1493399581314000));
assert!(ValueType::Boolean.accommodates_integer(1));
assert!(!ValueType::Boolean.accommodates_integer(-1));
assert!(!ValueType::Boolean.accommodates_integer(10));
assert!(!ValueType::String.accommodates_integer(10));
}
}

View file

@ -14,9 +14,12 @@ use std::collections::{
BTreeMap,
};
use core_traits::{
Entid,
};
use ::{
DateTime,
Entid,
Utc,
};

View file

@ -8,849 +8,4 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use ::std::convert::{
AsRef,
};
use ::std::ffi::{
CString,
};
use ::std::ops::{
Deref,
};
use ::std::os::raw::c_char;
use ::std::rc::{
Rc,
};
use ::std::sync::{
Arc,
};
use std::fmt;
use ::enum_set::EnumSet;
use ::ordered_float::OrderedFloat;
use ::uuid::Uuid;
use ::chrono::{
DateTime,
Timelike, // For truncation.
};
use ::indexmap::{
IndexMap,
};
use ::edn::{
self,
Cloned,
FromMicros,
FromRc,
Keyword,
Utc,
ValueRc,
};
use ::edn::entities::{
AttributePlace,
EntidOrIdent,
EntityPlace,
ValuePlace,
TransactableValueMarker,
};
use values;
/// Represents one entid in the entid space.
///
/// Per https://www.sqlite.org/datatype3.html (see also http://stackoverflow.com/a/8499544), SQLite
/// stores signed integers up to 64 bits in size. Since u32 is not appropriate for our use case, we
/// use i64 rather than manually truncating u64 to u63 and casting to i64 throughout the codebase.
pub type Entid = i64;
/// An entid that's either already in the store, or newly allocated to a tempid.
/// TODO: we'd like to link this in some way to the lifetime of a particular PartitionMap.
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
pub struct KnownEntid(pub Entid);
impl From<KnownEntid> for Entid {
fn from(k: KnownEntid) -> Entid {
k.0
}
}
impl From<KnownEntid> for TypedValue {
fn from(k: KnownEntid) -> TypedValue {
TypedValue::Ref(k.0)
}
}
impl<V: TransactableValueMarker> Into<EntityPlace<V>> for KnownEntid {
fn into(self) -> EntityPlace<V> {
EntityPlace::Entid(EntidOrIdent::Entid(self.0))
}
}
impl Into<AttributePlace> for KnownEntid {
fn into(self) -> AttributePlace {
AttributePlace::Entid(EntidOrIdent::Entid(self.0))
}
}
impl<V: TransactableValueMarker> Into<ValuePlace<V>> for KnownEntid {
fn into(self) -> ValuePlace<V> {
ValuePlace::Entid(EntidOrIdent::Entid(self.0))
}
}
/// The attribute of each Mentat assertion has a :db/valueType constraining the value to a
/// particular set. Mentat recognizes the following :db/valueType values.
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)]
#[repr(u32)]
pub enum ValueType {
Ref,
Boolean,
Instant,
Long,
Double,
String,
Keyword,
Uuid,
}
pub type ValueTypeTag = i32;
impl ValueType {
pub fn all_enums() -> EnumSet<ValueType> {
// TODO: lazy_static.
let mut s = EnumSet::new();
s.insert(ValueType::Ref);
s.insert(ValueType::Boolean);
s.insert(ValueType::Instant);
s.insert(ValueType::Long);
s.insert(ValueType::Double);
s.insert(ValueType::String);
s.insert(ValueType::Keyword);
s.insert(ValueType::Uuid);
s
}
}
impl ::enum_set::CLike for ValueType {
fn to_u32(&self) -> u32 {
*self as u32
}
unsafe fn from_u32(v: u32) -> ValueType {
::std::mem::transmute(v)
}
}
impl ValueType {
pub fn into_keyword(self) -> Keyword {
Keyword::namespaced("db.type", match self {
ValueType::Ref => "ref",
ValueType::Boolean => "boolean",
ValueType::Instant => "instant",
ValueType::Long => "long",
ValueType::Double => "double",
ValueType::String => "string",
ValueType::Keyword => "keyword",
ValueType::Uuid => "uuid",
})
}
pub fn from_keyword(keyword: &Keyword) -> Option<Self> {
if keyword.namespace() != Some("db.type") {
return None;
}
return match keyword.name() {
"ref" => Some(ValueType::Ref),
"boolean" => Some(ValueType::Boolean),
"instant" => Some(ValueType::Instant),
"long" => Some(ValueType::Long),
"double" => Some(ValueType::Double),
"string" => Some(ValueType::String),
"keyword" => Some(ValueType::Keyword),
"uuid" => Some(ValueType::Uuid),
_ => None,
}
}
pub fn into_typed_value(self) -> TypedValue {
TypedValue::typed_ns_keyword("db.type", match self {
ValueType::Ref => "ref",
ValueType::Boolean => "boolean",
ValueType::Instant => "instant",
ValueType::Long => "long",
ValueType::Double => "double",
ValueType::String => "string",
ValueType::Keyword => "keyword",
ValueType::Uuid => "uuid",
})
}
pub fn into_edn_value(self) -> edn::Value {
match self {
ValueType::Ref => values::DB_TYPE_REF.clone(),
ValueType::Boolean => values::DB_TYPE_BOOLEAN.clone(),
ValueType::Instant => values::DB_TYPE_INSTANT.clone(),
ValueType::Long => values::DB_TYPE_LONG.clone(),
ValueType::Double => values::DB_TYPE_DOUBLE.clone(),
ValueType::String => values::DB_TYPE_STRING.clone(),
ValueType::Keyword => values::DB_TYPE_KEYWORD.clone(),
ValueType::Uuid => values::DB_TYPE_UUID.clone(),
}
}
pub fn is_numeric(&self) -> bool {
match self {
&ValueType::Long | &ValueType::Double => true,
_ => false
}
}
}
impl fmt::Display for ValueType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", match *self {
ValueType::Ref => ":db.type/ref",
ValueType::Boolean => ":db.type/boolean",
ValueType::Instant => ":db.type/instant",
ValueType::Long => ":db.type/long",
ValueType::Double => ":db.type/double",
ValueType::String => ":db.type/string",
ValueType::Keyword => ":db.type/keyword",
ValueType::Uuid => ":db.type/uuid",
})
}
}
/// Represents a value that can be stored in a Mentat store.
// TODO: expand to include :db.type/uri. https://github.com/mozilla/mentat/issues/201
// TODO: JSON data type? https://github.com/mozilla/mentat/issues/31
// TODO: BigInt? Bytes?
#[derive(Clone, Debug, Eq, Hash, Ord, PartialOrd, PartialEq, Serialize, Deserialize)]
pub enum TypedValue {
Ref(Entid),
Boolean(bool),
Long(i64),
Double(OrderedFloat<f64>),
Instant(DateTime<Utc>), // Use `into()` to ensure truncation.
// TODO: &str throughout?
String(ValueRc<String>),
Keyword(ValueRc<Keyword>),
Uuid(Uuid), // It's only 128 bits, so this should be acceptable to clone.
}
/// `TypedValue` is the value type for programmatic use in transaction builders.
impl TransactableValueMarker for TypedValue {}
/// The values bound in a query specification can be:
///
/// * Vecs of structured values, for multi-valued component attributes or nested expressions.
/// * Single structured values, for single-valued component attributes or nested expressions.
/// * Single typed values, for simple attributes.
///
/// The `Binding` enum defines these three options.
///
/// Datomic also supports structured inputs; at present Mentat does not, but this type
/// would also serve that purpose.
///
/// Note that maps are not ordered, and so `Binding` is neither `Ord` nor `PartialOrd`.
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Binding {
Scalar(TypedValue),
Vec(ValueRc<Vec<Binding>>),
Map(ValueRc<StructuredMap>),
}
impl<T> From<T> for Binding where T: Into<TypedValue> {
fn from(value: T) -> Self {
Binding::Scalar(value.into())
}
}
impl From<StructuredMap> for Binding {
fn from(value: StructuredMap) -> Self {
Binding::Map(ValueRc::new(value))
}
}
impl From<Vec<Binding>> for Binding {
fn from(value: Vec<Binding>) -> Self {
Binding::Vec(ValueRc::new(value))
}
}
impl Binding {
pub fn into_scalar(self) -> Option<TypedValue> {
match self {
Binding::Scalar(v) => Some(v),
_ => None,
}
}
pub fn into_vec(self) -> Option<ValueRc<Vec<Binding>>> {
match self {
Binding::Vec(v) => Some(v),
_ => None,
}
}
pub fn into_map(self) -> Option<ValueRc<StructuredMap>> {
match self {
Binding::Map(v) => Some(v),
_ => None,
}
}
pub fn as_scalar(&self) -> Option<&TypedValue> {
match self {
&Binding::Scalar(ref v) => Some(v),
_ => None,
}
}
pub fn as_vec(&self) -> Option<&Vec<Binding>> {
match self {
&Binding::Vec(ref v) => Some(v),
_ => None,
}
}
pub fn as_map(&self) -> Option<&StructuredMap> {
match self {
&Binding::Map(ref v) => Some(v),
_ => None,
}
}
}
/// A pull expression expands a binding into a structure. The returned structure
/// associates attributes named in the input or retrieved from the store with values.
/// This association is a `StructuredMap`.
///
/// Note that 'attributes' in Datomic's case can mean:
/// - Reversed attribute keywords (:artist/_country).
/// - An alias using `:as` (:artist/name :as "Band name").
///
/// We entirely support the former, and partially support the latter -- you can alias
/// using a different keyword only.
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct StructuredMap(pub IndexMap<ValueRc<Keyword>, Binding>);
impl Deref for StructuredMap {
type Target = IndexMap<ValueRc<Keyword>, Binding>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl StructuredMap {
pub fn insert<N, B>(&mut self, name: N, value: B) where N: Into<ValueRc<Keyword>>, B: Into<Binding> {
self.0.insert(name.into(), value.into());
}
}
impl From<IndexMap<ValueRc<Keyword>, Binding>> for StructuredMap {
fn from(src: IndexMap<ValueRc<Keyword>, Binding>) -> Self {
StructuredMap(src)
}
}
// Mostly for testing.
impl<T> From<Vec<(Keyword, T)>> for StructuredMap where T: Into<Binding> {
fn from(value: Vec<(Keyword, T)>) -> Self {
let mut sm = StructuredMap::default();
for (k, v) in value.into_iter() {
sm.insert(k, v);
}
sm
}
}
impl Binding {
/// Returns true if the provided type is `Some` and matches this value's type, or if the
/// provided type is `None`.
#[inline]
pub fn is_congruent_with<T: Into<Option<ValueType>>>(&self, t: T) -> bool {
t.into().map_or(true, |x| self.matches_type(x))
}
#[inline]
pub fn matches_type(&self, t: ValueType) -> bool {
self.value_type() == Some(t)
}
pub fn value_type(&self) -> Option<ValueType> {
match self {
&Binding::Scalar(ref v) => Some(v.value_type()),
&Binding::Map(_) => None,
&Binding::Vec(_) => None,
}
}
}
impl TypedValue {
/// Returns true if the provided type is `Some` and matches this value's type, or if the
/// provided type is `None`.
#[inline]
pub fn is_congruent_with<T: Into<Option<ValueType>>>(&self, t: T) -> bool {
t.into().map_or(true, |x| self.matches_type(x))
}
#[inline]
pub fn matches_type(&self, t: ValueType) -> bool {
self.value_type() == t
}
pub fn value_type(&self) -> ValueType {
match self {
&TypedValue::Ref(_) => ValueType::Ref,
&TypedValue::Boolean(_) => ValueType::Boolean,
&TypedValue::Long(_) => ValueType::Long,
&TypedValue::Instant(_) => ValueType::Instant,
&TypedValue::Double(_) => ValueType::Double,
&TypedValue::String(_) => ValueType::String,
&TypedValue::Keyword(_) => ValueType::Keyword,
&TypedValue::Uuid(_) => ValueType::Uuid,
}
}
/// Construct a new `TypedValue::Keyword` instance by cloning the provided
/// values and wrapping them in a new `ValueRc`. This is expensive, so this might
/// be best limited to tests.
pub fn typed_ns_keyword<S: AsRef<str>, T: AsRef<str>>(ns: S, name: T) -> TypedValue {
Keyword::namespaced(ns.as_ref(), name.as_ref()).into()
}
/// Construct a new `TypedValue::String` instance by cloning the provided
/// value and wrapping it in a new `ValueRc`. This is expensive, so this might
/// be best limited to tests.
pub fn typed_string<S: AsRef<str>>(s: S) -> TypedValue {
s.as_ref().into()
}
pub fn current_instant() -> TypedValue {
Utc::now().into()
}
/// Construct a new `TypedValue::Instant` instance from the provided
/// microsecond timestamp.
pub fn instant(micros: i64) -> TypedValue {
DateTime::<Utc>::from_micros(micros).into()
}
}
trait MicrosecondPrecision {
/// Truncate the provided `DateTime` to microsecond precision.
fn microsecond_precision(self) -> Self;
}
impl MicrosecondPrecision for DateTime<Utc> {
fn microsecond_precision(self) -> DateTime<Utc> {
let nanoseconds = self.nanosecond();
if nanoseconds % 1000 == 0 {
return self;
}
let microseconds = nanoseconds / 1000;
let truncated = microseconds * 1000;
self.with_nanosecond(truncated).expect("valid timestamp")
}
}
/// Return the current time as a UTC `DateTime` instance with microsecond precision.
pub fn now() -> DateTime<Utc> {
Utc::now().microsecond_precision()
}
// We don't do From<i64> or From<Entid> 'cos it's ambiguous.
impl From<bool> for TypedValue {
fn from(value: bool) -> TypedValue {
TypedValue::Boolean(value)
}
}
/// Truncate the provided `DateTime` to microsecond precision, and return the corresponding
/// `TypedValue::Instant`.
impl From<DateTime<Utc>> for TypedValue {
fn from(value: DateTime<Utc>) -> TypedValue {
TypedValue::Instant(value.microsecond_precision())
}
}
impl From<Uuid> for TypedValue {
fn from(value: Uuid) -> TypedValue {
TypedValue::Uuid(value)
}
}
impl<'a> From<&'a str> for TypedValue {
fn from(value: &'a str) -> TypedValue {
TypedValue::String(ValueRc::new(value.to_string()))
}
}
impl From<Arc<String>> for TypedValue {
fn from(value: Arc<String>) -> TypedValue {
TypedValue::String(ValueRc::from_arc(value))
}
}
impl From<Rc<String>> for TypedValue {
fn from(value: Rc<String>) -> TypedValue {
TypedValue::String(ValueRc::from_rc(value))
}
}
impl From<Box<String>> for TypedValue {
fn from(value: Box<String>) -> TypedValue {
TypedValue::String(ValueRc::new(*value))
}
}
impl From<String> for TypedValue {
fn from(value: String) -> TypedValue {
TypedValue::String(ValueRc::new(value))
}
}
impl From<Arc<Keyword>> for TypedValue {
fn from(value: Arc<Keyword>) -> TypedValue {
TypedValue::Keyword(ValueRc::from_arc(value))
}
}
impl From<Rc<Keyword>> for TypedValue {
fn from(value: Rc<Keyword>) -> TypedValue {
TypedValue::Keyword(ValueRc::from_rc(value))
}
}
impl From<Keyword> for TypedValue {
fn from(value: Keyword) -> TypedValue {
TypedValue::Keyword(ValueRc::new(value))
}
}
impl From<u32> for TypedValue {
fn from(value: u32) -> TypedValue {
TypedValue::Long(value as i64)
}
}
impl From<i32> for TypedValue {
fn from(value: i32) -> TypedValue {
TypedValue::Long(value as i64)
}
}
impl From<f64> for TypedValue {
fn from(value: f64) -> TypedValue {
TypedValue::Double(OrderedFloat(value))
}
}
impl TypedValue {
pub fn into_known_entid(self) -> Option<KnownEntid> {
match self {
TypedValue::Ref(v) => Some(KnownEntid(v)),
_ => None,
}
}
pub fn into_entid(self) -> Option<Entid> {
match self {
TypedValue::Ref(v) => Some(v),
_ => None,
}
}
pub fn into_kw(self) -> Option<ValueRc<Keyword>> {
match self {
TypedValue::Keyword(v) => Some(v),
_ => None,
}
}
pub fn into_boolean(self) -> Option<bool> {
match self {
TypedValue::Boolean(v) => Some(v),
_ => None,
}
}
pub fn into_long(self) -> Option<i64> {
match self {
TypedValue::Long(v) => Some(v),
_ => None,
}
}
pub fn into_double(self) -> Option<f64> {
match self {
TypedValue::Double(v) => Some(v.into_inner()),
_ => None,
}
}
pub fn into_instant(self) -> Option<DateTime<Utc>> {
match self {
TypedValue::Instant(v) => Some(v),
_ => None,
}
}
pub fn into_timestamp(self) -> Option<i64> {
match self {
TypedValue::Instant(v) => Some(v.timestamp()),
_ => None,
}
}
pub fn into_string(self) -> Option<ValueRc<String>> {
match self {
TypedValue::String(v) => Some(v),
_ => None,
}
}
pub fn into_c_string(self) -> Option<*mut c_char> {
match self {
TypedValue::String(v) => {
// Get an independent copy of the string.
let s: String = v.cloned();
// Make a CString out of the new bytes.
let c: CString = CString::new(s).expect("String conversion failed!");
// Return a C-owned pointer.
Some(c.into_raw())
},
_ => None,
}
}
pub fn into_kw_c_string(self) -> Option<*mut c_char> {
match self {
TypedValue::Keyword(v) => {
// Get an independent copy of the string.
let s: String = v.to_string();
// Make a CString out of the new bytes.
let c: CString = CString::new(s).expect("String conversion failed!");
// Return a C-owned pointer.
Some(c.into_raw())
},
_ => None,
}
}
pub fn into_uuid_c_string(self) -> Option<*mut c_char> {
match self {
TypedValue::Uuid(v) => {
// Get an independent copy of the string.
let s: String = v.hyphenated().to_string();
// Make a CString out of the new bytes.
let c: CString = CString::new(s).expect("String conversion failed!");
// Return a C-owned pointer.
Some(c.into_raw())
},
_ => None,
}
}
pub fn into_uuid(self) -> Option<Uuid> {
match self {
TypedValue::Uuid(v) => Some(v),
_ => None,
}
}
pub fn into_uuid_string(self) -> Option<String> {
match self {
TypedValue::Uuid(v) => Some(v.hyphenated().to_string()),
_ => None,
}
}
}
impl Binding {
pub fn into_known_entid(self) -> Option<KnownEntid> {
match self {
Binding::Scalar(TypedValue::Ref(v)) => Some(KnownEntid(v)),
_ => None,
}
}
pub fn into_entid(self) -> Option<Entid> {
match self {
Binding::Scalar(TypedValue::Ref(v)) => Some(v),
_ => None,
}
}
pub fn into_kw(self) -> Option<ValueRc<Keyword>> {
match self {
Binding::Scalar(TypedValue::Keyword(v)) => Some(v),
_ => None,
}
}
pub fn into_boolean(self) -> Option<bool> {
match self {
Binding::Scalar(TypedValue::Boolean(v)) => Some(v),
_ => None,
}
}
pub fn into_long(self) -> Option<i64> {
match self {
Binding::Scalar(TypedValue::Long(v)) => Some(v),
_ => None,
}
}
pub fn into_double(self) -> Option<f64> {
match self {
Binding::Scalar(TypedValue::Double(v)) => Some(v.into_inner()),
_ => None,
}
}
pub fn into_instant(self) -> Option<DateTime<Utc>> {
match self {
Binding::Scalar(TypedValue::Instant(v)) => Some(v),
_ => None,
}
}
pub fn into_timestamp(self) -> Option<i64> {
match self {
Binding::Scalar(TypedValue::Instant(v)) => Some(v.timestamp()),
_ => None,
}
}
pub fn into_string(self) -> Option<ValueRc<String>> {
match self {
Binding::Scalar(TypedValue::String(v)) => Some(v),
_ => None,
}
}
pub fn into_uuid(self) -> Option<Uuid> {
match self {
Binding::Scalar(TypedValue::Uuid(v)) => Some(v),
_ => None,
}
}
pub fn into_uuid_string(self) -> Option<String> {
match self {
Binding::Scalar(TypedValue::Uuid(v)) => Some(v.hyphenated().to_string()),
_ => None,
}
}
pub fn into_c_string(self) -> Option<*mut c_char> {
match self {
Binding::Scalar(v) => v.into_c_string(),
_ => None,
}
}
pub fn into_kw_c_string(self) -> Option<*mut c_char> {
match self {
Binding::Scalar(v) => v.into_kw_c_string(),
_ => None,
}
}
pub fn into_uuid_c_string(self) -> Option<*mut c_char> {
match self {
Binding::Scalar(v) => v.into_uuid_c_string(),
_ => None,
}
}
pub fn as_entid(&self) -> Option<&Entid> {
match self {
&Binding::Scalar(TypedValue::Ref(ref v)) => Some(v),
_ => None,
}
}
pub fn as_kw(&self) -> Option<&ValueRc<Keyword>> {
match self {
&Binding::Scalar(TypedValue::Keyword(ref v)) => Some(v),
_ => None,
}
}
pub fn as_boolean(&self) -> Option<&bool> {
match self {
&Binding::Scalar(TypedValue::Boolean(ref v)) => Some(v),
_ => None,
}
}
pub fn as_long(&self) -> Option<&i64> {
match self {
&Binding::Scalar(TypedValue::Long(ref v)) => Some(v),
_ => None,
}
}
pub fn as_double(&self) -> Option<&f64> {
match self {
&Binding::Scalar(TypedValue::Double(ref v)) => Some(&v.0),
_ => None,
}
}
pub fn as_instant(&self) -> Option<&DateTime<Utc>> {
match self {
&Binding::Scalar(TypedValue::Instant(ref v)) => Some(v),
_ => None,
}
}
pub fn as_string(&self) -> Option<&ValueRc<String>> {
match self {
&Binding::Scalar(TypedValue::String(ref v)) => Some(v),
_ => None,
}
}
pub fn as_uuid(&self) -> Option<&Uuid> {
match self {
&Binding::Scalar(TypedValue::Uuid(ref v)) => Some(v),
_ => None,
}
}
}
#[test]
fn test_typed_value() {
assert!(TypedValue::Boolean(false).is_congruent_with(None));
assert!(TypedValue::Boolean(false).is_congruent_with(ValueType::Boolean));
assert!(!TypedValue::typed_string("foo").is_congruent_with(ValueType::Boolean));
assert!(TypedValue::typed_string("foo").is_congruent_with(ValueType::String));
assert!(TypedValue::typed_string("foo").is_congruent_with(None));
}

22
db-traits/Cargo.toml Normal file
View file

@ -0,0 +1,22 @@
[package]
name = "db_traits"
version = "0.0.1"
workspace = ".."
[lib]
name = "db_traits"
path = "lib.rs"
[dependencies]
failure = "0.1.1"
failure_derive = "0.1.1"
[dependencies.edn]
path = "../edn"
[dependencies.core_traits]
path = "../core-traits"
[dependencies.rusqlite]
version = "0.13"
features = ["limits"]

View file

@ -26,22 +26,14 @@ use rusqlite;
use edn::entities::{
TempId,
};
use mentat_core::{
KnownEntid,
};
use types::{
use core_traits::{
Entid,
KnownEntid,
TypedValue,
ValueType,
};
#[macro_export]
macro_rules! bail {
($e:expr) => (
return Err($e.into());
)
}
pub type Result<T> = ::std::result::Result<T, DbError>;
// TODO Error/ErrorKind pair

20
db-traits/lib.rs Normal file
View file

@ -0,0 +1,20 @@
// 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 edn;
extern crate core_traits;
pub mod errors;

View file

@ -10,7 +10,6 @@ syncable = ["serde", "serde_json", "serde_derive"]
[dependencies]
failure = "0.1.1"
failure_derive = "0.1.1"
indexmap = "1"
itertools = "0.7"
lazy_static = "0.2"
@ -32,6 +31,12 @@ path = "../edn"
[dependencies.mentat_core]
path = "../core"
[dependencies.core_traits]
path = "../core-traits"
[dependencies.db_traits]
path = "../db-traits"
[dependencies.mentat_sql]
path = "../sql"

View file

@ -11,7 +11,7 @@
#![allow(dead_code)]
use edn;
use errors::{
use db_traits::errors::{
DbErrorKind,
Result,
};
@ -20,11 +20,15 @@ use edn::symbols;
use entids;
use db::TypedSQLValue;
use edn::entities::Entity;
use core_traits::{
TypedValue,
values,
};
use mentat_core::{
IdentMap,
Schema,
TypedValue,
values,
};
use schema::SchemaBuilding;
use types::{Partition, PartitionMap};

View file

@ -78,13 +78,16 @@ use failure::{
use rusqlite;
use mentat_core::{
use core_traits::{
Binding,
CachedAttributes,
Entid,
TypedValue,
};
use mentat_core::{
CachedAttributes,
HasSchema,
Schema,
TypedValue,
UpdateableCache,
ValueRc,
};
@ -107,7 +110,7 @@ use db::{
TypedSQLValue,
};
use errors::{
use db_traits::errors::{
DbError,
DbErrorKind,
Result,

View file

@ -40,25 +40,30 @@ use edn::{
};
use entids;
use mentat_core::{
use core_traits::{
attribute,
Attribute,
AttributeBitFlags,
Entid,
TypedValue,
ValueType,
};
use mentat_core::{
FromMicros,
IdentMap,
Schema,
AttributeMap,
TypedValue,
ToMicros,
ValueType,
ValueRc,
};
use errors::{
use db_traits::errors::{
DbErrorKind,
Result,
};
use metadata;
use schema::{
SchemaBuilding,
@ -1221,17 +1226,19 @@ mod tests {
use edn::entities::{
OpType,
};
use core_traits::{
attribute,
KnownEntid,
};
use mentat_core::{
HasSchema,
Keyword,
KnownEntid,
attribute,
};
use mentat_core::util::Either::*;
use std::collections::{
BTreeMap,
};
use errors;
use db_traits::errors as errors;
use internal_types::{
Term,
};

View file

@ -65,13 +65,18 @@ use db::*;
use db::{read_attribute_map,read_ident_map};
use edn;
use entids;
use errors::Result;
use db_traits::errors::Result;
use core_traits::{
Entid,
TypedValue,
ValueType,
};
use mentat_core::{
HasSchema,
SQLValueType,
TxReport,
TypedValue,
ValueType,
};
use edn::{
InternSet,

View file

@ -14,7 +14,9 @@
///
/// Used through-out the transactor to match core DB constructs.
use types::{Entid};
use core_traits::{
Entid,
};
// Added in SQL schema v1.
pub const DB_IDENT: Entid = 1;

View file

@ -18,7 +18,13 @@ use std::collections::{
HashMap,
};
use mentat_core::KnownEntid;
use core_traits::{
Attribute,
Entid,
KnownEntid,
TypedValue,
ValueType,
};
use mentat_core::util::Either;
@ -36,8 +42,8 @@ use edn::entities::{
TxFunction,
};
use errors;
use errors::{
use db_traits::errors as errors;
use db_traits::errors::{
DbErrorKind,
Result,
};
@ -45,14 +51,10 @@ use schema::{
SchemaTypeChecking,
};
use types::{
Attribute,
AVMap,
AVPair,
Entid,
Schema,
TransactableValue,
TypedValue,
ValueType,
};
impl TransactableValue for ValueAndSpan {

View file

@ -9,7 +9,6 @@
// specific language governing permissions and limitations under the License.
extern crate failure;
#[macro_use] extern crate failure_derive;
extern crate indexmap;
extern crate itertools;
#[macro_use] extern crate lazy_static;
@ -25,19 +24,18 @@ extern crate time;
#[macro_use] extern crate edn;
#[macro_use] extern crate mentat_core;
extern crate db_traits;
#[macro_use] extern crate core_traits;
extern crate mentat_sql;
use std::iter::repeat;
use itertools::Itertools;
pub use errors::{
DbError,
use db_traits::errors::{
DbErrorKind,
Result,
SchemaConstraintViolation,
};
#[macro_use] pub mod errors;
#[macro_use] pub mod debug;

View file

@ -34,19 +34,23 @@ use add_retract_alter_set::{
};
use edn::symbols;
use entids;
use errors::{
use db_traits::errors::{
DbErrorKind,
Result,
};
use mentat_core::{
use core_traits::{
attribute,
Entid,
Schema,
AttributeMap,
TypedValue,
ValueType,
};
use mentat_core::{
Schema,
AttributeMap,
};
use schema::{
AttributeBuilder,
AttributeValidation,

View file

@ -12,23 +12,27 @@
use db::TypedSQLValue;
use edn;
use errors::{
use db_traits::errors::{
DbErrorKind,
Result,
};
use edn::symbols;
use mentat_core::{
use core_traits::{
attribute,
Attribute,
Entid,
KnownEntid,
TypedValue,
ValueType,
};
use mentat_core::{
EntidMap,
HasSchema,
IdentMap,
KnownEntid,
Schema,
AttributeMap,
TypedValue,
ValueType,
};
use metadata;
use metadata::{

View file

@ -12,16 +12,19 @@ use std::ops::RangeFrom;
use rusqlite;
use errors::{
use db_traits::errors::{
DbErrorKind,
Result,
};
use mentat_core::{
use core_traits::{
Entid,
Schema,
TypedValue,
KnownEntid,
TypedValue,
};
use mentat_core::{
Schema,
};
use edn::{

View file

@ -66,8 +66,8 @@ use edn::{
Keyword,
};
use entids;
use errors;
use errors::{
use db_traits::errors as errors;
use db_traits::errors::{
DbErrorKind,
Result,
};
@ -89,14 +89,21 @@ use internal_types::{
use mentat_core::util::Either;
use core_traits::{
attribute,
Attribute,
Entid,
KnownEntid,
TypedValue,
ValueType,
now,
};
use mentat_core::{
DateTime,
KnownEntid,
Schema,
TxReport,
Utc,
attribute,
now,
};
use edn::entities as entmod;
@ -115,12 +122,8 @@ use tx_checking;
use types::{
AVMap,
AVPair,
Attribute,
Entid,
PartitionMap,
TransactableValue,
TypedValue,
ValueType,
};
use upsert_resolution::{
FinalPopulations,

View file

@ -13,13 +13,13 @@ use std::collections::{
BTreeMap,
};
use mentat_core::{
use core_traits::{
Entid,
TypedValue,
ValueType,
};
use errors::{
use db_traits::errors::{
CardinalityConflict,
};

View file

@ -26,17 +26,20 @@ use indexmap::{
IndexMap,
};
use mentat_core::{
use core_traits::{
Entid,
Schema,
TypedValue,
};
use mentat_core::{
Schema,
};
use edn::entities::{
OpType,
};
use errors::{
use db_traits::errors::{
Result,
};

View file

@ -26,23 +26,24 @@ use std::ops::{
extern crate mentat_core;
pub use self::mentat_core::{
Attribute,
AttributeBitFlags,
DateTime,
use core_traits::{
Entid,
Schema,
TypedValue,
Utc,
ValueType,
};
pub use self::mentat_core::{
DateTime,
Schema,
Utc,
};
use edn::entities::{
EntityPlace,
TempId,
};
use errors;
use db_traits::errors as errors;
/// Represents one partition of the entid space.
#[derive(Clone, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)]

View file

@ -21,7 +21,7 @@ use std::collections::{
use indexmap;
use petgraph::unionfind;
use errors::{
use db_traits::errors::{
DbErrorKind,
Result,
};
@ -40,13 +40,16 @@ use internal_types::{
use mentat_core::util::Either::*;
use mentat_core::{
use core_traits::{
attribute,
Attribute,
Entid,
Schema,
TypedValue,
};
use mentat_core::{
Schema,
};
use edn::entities::OpType;
use schema::SchemaBuilding;

View file

@ -17,17 +17,20 @@
// - When observers are registered we want to flip some flags as writes occur so that we can
// notifying them outside the transaction.
use mentat_core::{
use core_traits::{
Entid,
Schema,
TypedValue,
};
use mentat_core::{
Schema,
};
use edn::entities::{
OpType,
};
use errors::{
use db_traits::errors::{
Result,
};

View file

@ -9,7 +9,7 @@
// specific language governing permissions and limitations under the License.
extern crate edn;
extern crate mentat_core;
extern crate core_traits;
extern crate mentat_db;
extern crate ordered_float;
extern crate rusqlite;
@ -18,7 +18,10 @@ use ordered_float::OrderedFloat;
use edn::symbols;
use mentat_core::{TypedValue, ValueType};
use core_traits::{
TypedValue,
ValueType,
};
use mentat_db::db::TypedSQLValue;
// It's not possible to test to_sql_value_pair since rusqlite::ToSqlOutput doesn't implement

45
public-traits/Cargo.toml Normal file
View file

@ -0,0 +1,45 @@
[package]
name = "public_traits"
version = "0.0.1"
workspace = ".."
[lib]
name = "public_traits"
path = "lib.rs"
[features]
default = ["syncable"]
syncable = ["tolstoy_traits"]
[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_algebrizer_traits]
path = "../query-algebrizer-traits"
[dependencies.query_projector_traits]
path = "../query-projector-traits"
[dependencies.query_pull_traits]
path = "../query-pull-traits"
[dependencies.sql_traits]
path = "../sql-traits"
[dependencies.tolstoy_traits]
path = "../tolstoy-traits"
optional = true

View file

@ -18,30 +18,32 @@ use rusqlite;
use edn;
use mentat_core::{
use core_traits::{
Attribute,
ValueType,
};
use mentat_db;
use mentat_query;
use mentat_query_algebrizer;
use mentat_query_projector;
use mentat_query_pull;
use mentat_sql;
use db_traits::errors::DbError;
use query_algebrizer_traits::errors::{
AlgebrizerError,
};
use query_projector_traits::errors::{
ProjectorError,
};
use query_pull_traits::errors::{
PullError,
};
use sql_traits::errors::{
SQLError,
};
#[cfg(feature = "syncable")]
use mentat_tolstoy;
use tolstoy_traits::errors::{
TolstoyError,
};
pub type Result<T> = std::result::Result<T, MentatError>;
#[macro_export]
macro_rules! bail {
($e:expr) => (
return Err($e.into());
)
}
#[derive(Debug, Fail)]
pub enum MentatError {
#[fail(display = "bad uuid {}", _0)]
@ -62,20 +64,20 @@ pub enum MentatError {
#[fail(display = "invalid vocabulary version")]
InvalidVocabularyVersion,
#[fail(display = "vocabulary {}/{} already has attribute {}, and the requested definition differs", _0, _1, _2)]
ConflictingAttributeDefinitions(String, ::vocabulary::Version, String, Attribute, Attribute),
#[fail(display = "vocabulary {}/version {} already has attribute {}, and the requested definition differs", _0, _1, _2)]
ConflictingAttributeDefinitions(String, u32, String, Attribute, Attribute),
#[fail(display = "existing vocabulary {} too new: wanted {}, got {}", _0, _1, _2)]
ExistingVocabularyTooNew(String, ::vocabulary::Version, ::vocabulary::Version),
#[fail(display = "existing vocabulary {} too new: wanted version {}, got version {}", _0, _1, _2)]
ExistingVocabularyTooNew(String, u32, u32),
#[fail(display = "core schema: wanted {}, got {:?}", _0, _1)]
UnexpectedCoreSchema(::vocabulary::Version, Option<::vocabulary::Version>),
#[fail(display = "core schema: wanted version {}, got version {:?}", _0, _1)]
UnexpectedCoreSchema(u32, Option<u32>),
#[fail(display = "Lost the transact() race!")]
UnexpectedLostTransactRace,
#[fail(display = "missing core attribute {}", _0)]
MissingCoreVocabulary(mentat_query::Keyword),
MissingCoreVocabulary(edn::query::Keyword),
#[fail(display = "schema changed since query was prepared")]
PreparedQuerySchemaMismatch,
@ -95,23 +97,23 @@ pub enum MentatError {
EdnParseError(#[cause] edn::ParseError),
#[fail(display = "{}", _0)]
DbError(#[cause] mentat_db::DbError),
DbError(#[cause] DbError),
#[fail(display = "{}", _0)]
AlgebrizerError(#[cause] mentat_query_algebrizer::AlgebrizerError),
AlgebrizerError(#[cause] AlgebrizerError),
#[fail(display = "{}", _0)]
ProjectorError(#[cause] mentat_query_projector::ProjectorError),
ProjectorError(#[cause] ProjectorError),
#[fail(display = "{}", _0)]
PullError(#[cause] mentat_query_pull::PullError),
PullError(#[cause] PullError),
#[fail(display = "{}", _0)]
SQLError(#[cause] mentat_sql::SQLError),
SQLError(#[cause] SQLError),
#[cfg(feature = "syncable")]
#[fail(display = "{}", _0)]
TolstoyError(#[cause] mentat_tolstoy::TolstoyError),
TolstoyError(#[cause] TolstoyError),
}
impl From<std::io::Error> for MentatError {
@ -132,39 +134,39 @@ impl From<edn::ParseError> for MentatError {
}
}
impl From<mentat_db::DbError> for MentatError {
fn from(error: mentat_db::DbError) -> MentatError {
impl From<DbError> for MentatError {
fn from(error: DbError) -> MentatError {
MentatError::DbError(error)
}
}
impl From<mentat_query_algebrizer::AlgebrizerError> for MentatError {
fn from(error: mentat_query_algebrizer::AlgebrizerError) -> MentatError {
impl From<AlgebrizerError> for MentatError {
fn from(error: AlgebrizerError) -> MentatError {
MentatError::AlgebrizerError(error)
}
}
impl From<mentat_query_projector::ProjectorError> for MentatError {
fn from(error: mentat_query_projector::ProjectorError) -> MentatError {
impl From<ProjectorError> for MentatError {
fn from(error: ProjectorError) -> MentatError {
MentatError::ProjectorError(error)
}
}
impl From<mentat_query_pull::PullError> for MentatError {
fn from(error: mentat_query_pull::PullError) -> MentatError {
impl From<PullError> for MentatError {
fn from(error: PullError) -> MentatError {
MentatError::PullError(error)
}
}
impl From<mentat_sql::SQLError> for MentatError {
fn from(error: mentat_sql::SQLError) -> MentatError {
impl From<SQLError> for MentatError {
fn from(error: SQLError) -> MentatError {
MentatError::SQLError(error)
}
}
#[cfg(feature = "syncable")]
impl From<mentat_tolstoy::TolstoyError> for MentatError {
fn from(error: mentat_tolstoy::TolstoyError) -> MentatError {
impl From<TolstoyError> for MentatError {
fn from(error: TolstoyError) -> MentatError {
MentatError::TolstoyError(error)
}
}

26
public-traits/lib.rs Normal file
View file

@ -0,0 +1,26 @@
// 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 edn;
extern crate core_traits;
extern crate db_traits;
extern crate query_pull_traits;
extern crate query_projector_traits;
extern crate query_algebrizer_traits;
extern crate tolstoy_traits;
extern crate sql_traits;
pub mod errors;

View file

@ -0,0 +1,18 @@
[package]
name = "query_algebrizer_traits"
version = "0.0.1"
workspace = ".."
[lib]
name = "query_algebrizer_traits"
path = "lib.rs"
[dependencies]
failure = "0.1.1"
failure_derive = "0.1.1"
[dependencies.edn]
path = "../edn"
[dependencies.core_traits]
path = "../core-traits"

View file

@ -8,29 +8,23 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
extern crate mentat_query;
use std; // To refer to std::result::Result.
use mentat_core::{
EdnParseError,
use core_traits::{
ValueType,
ValueTypeSet,
};
use self::mentat_query::{
use edn::parse::{
ParseError,
};
use edn::query::{
PlainSymbol,
};
pub type Result<T> = std::result::Result<T, AlgebrizerError>;
#[macro_export]
macro_rules! bail {
($e:expr) => (
return Err($e.into());
)
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum BindingError {
NoBoundVariable,
@ -104,11 +98,11 @@ pub enum AlgebrizerError {
InvalidBinding(PlainSymbol, BindingError),
#[fail(display = "{}", _0)]
EdnParseError(#[cause] EdnParseError),
EdnParseError(#[cause] ParseError),
}
impl From<EdnParseError> for AlgebrizerError {
fn from(error: EdnParseError) -> AlgebrizerError {
impl From<ParseError> for AlgebrizerError {
fn from(error: ParseError) -> AlgebrizerError {
AlgebrizerError::EdnParseError(error)
}
}

View file

@ -0,0 +1,18 @@
// 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 core_traits;
extern crate edn;
pub mod errors;

View file

@ -5,13 +5,18 @@ workspace = ".."
[dependencies]
failure = "0.1.1"
failure_derive = "0.1.1"
[dependencies.edn]
path = "../edn"
[dependencies.mentat_core]
path = "../core"
[dependencies.mentat_query]
path = "../query"
[dependencies.core_traits]
path = "../core-traits"
[dependencies.query_algebrizer_traits]
path = "../query-algebrizer-traits"
[dev-dependencies]
itertools = "0.7"

View file

@ -8,16 +8,19 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use core_traits::{
ValueType,
ValueTypeSet,
TypedValue,
};
use mentat_core::{
HasSchema,
Schema,
SQLValueType,
TypedValue,
ValueType,
ValueTypeSet,
};
use mentat_query::{
use edn::query::{
FnArg,
NonIntegerConstant,
Variable,
@ -27,7 +30,7 @@ use clauses::{
ConjoiningClauses,
};
use errors::{
use query_algebrizer_traits::errors::{
AlgebrizerError,
Result,
};

View file

@ -8,15 +8,18 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use core_traits::{
ValueType,
TypedValue,
};
use mentat_core::{
HasSchema,
TypedValue,
ValueType,
};
use mentat_core::util::Either;
use mentat_query::{
use edn::query::{
Binding,
FnArg,
NonIntegerConstant,
@ -29,7 +32,7 @@ use clauses::{
ConjoiningClauses,
};
use errors::{
use query_algebrizer_traits::errors::{
AlgebrizerError,
BindingError,
Result,
@ -261,13 +264,16 @@ impl ConjoiningClauses {
mod testing {
use super::*;
use mentat_core::{
use core_traits::{
Attribute,
Schema,
ValueType,
};
use mentat_query::{
use mentat_core::{
Schema,
};
use edn::query::{
Binding,
FnArg,
Keyword,

View file

@ -8,14 +8,17 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use mentat_core::{
Schema,
TypedValue,
use core_traits::{
ValueType,
ValueTypeSet,
TypedValue,
};
use mentat_query::{
use mentat_core::{
Schema,
};
use edn::query::{
Binding,
FnArg,
Variable,
@ -30,7 +33,7 @@ use clauses::{
use clauses::convert::ValueConversion;
use errors::{
use query_algebrizer_traits::errors::{
AlgebrizerError,
BindingError,
Result,
@ -321,12 +324,12 @@ impl ConjoiningClauses {
mod testing {
use super::*;
use mentat_core::{
use core_traits::{
Attribute,
ValueType,
};
use mentat_query::{
use edn::query::{
Binding,
FnArg,
Keyword,

View file

@ -10,16 +10,16 @@
use std::collections::BTreeMap;
use mentat_core::{
TypedValue,
use core_traits::{
ValueType,
TypedValue,
};
use mentat_query::{
use edn::query::{
Variable,
};
use errors::{
use query_algebrizer_traits::errors::{
AlgebrizerError,
Result,
};

View file

@ -25,34 +25,34 @@ use std::fmt::{
Formatter,
};
use mentat_core::{
use core_traits::{
Attribute,
Cloned,
Entid,
HasSchema,
KnownEntid,
Schema,
TypedValue,
ValueType,
ValueTypeSet,
TypedValue,
};
use mentat_core::{
Cloned,
HasSchema,
Schema,
};
use mentat_core::counter::RcCounter;
use mentat_query::{
use edn::query::{
Element,
FindSpec,
Keyword,
Pull,
Variable,
WhereClause,
};
use mentat_query::{
PatternNonValuePlace,
};
use errors::{
use query_algebrizer_traits::errors::{
AlgebrizerError,
Result,
};

View file

@ -8,7 +8,7 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use mentat_query::{
use edn::query::{
ContainsVariables,
NotJoin,
UnifyVars,
@ -16,7 +16,7 @@ use mentat_query::{
use clauses::ConjoiningClauses;
use errors::{
use query_algebrizer_traits::errors::{
AlgebrizerError,
Result,
};
@ -90,15 +90,18 @@ mod testing {
use super::*;
use mentat_core::{
use core_traits::{
Attribute,
Schema,
TypedValue,
ValueType,
ValueTypeSet,
};
use mentat_query::{
use mentat_core::{
Schema,
};
use edn::query::{
Keyword,
PlainSymbol,
Variable
@ -110,7 +113,7 @@ mod testing {
associate_ident,
};
use errors::{
use query_algebrizer_traits::errors::{
AlgebrizerError,
};

View file

@ -14,11 +14,11 @@ use std::collections::{
BTreeSet,
};
use mentat_core::{
use core_traits::{
ValueTypeSet,
};
use mentat_query::{
use edn::query::{
OrJoin,
OrWhereClause,
Pattern,
@ -34,7 +34,7 @@ use clauses::{
PushComputed,
};
use errors::{
use query_algebrizer_traits::errors::{
Result,
};
@ -753,14 +753,17 @@ fn union_types(into: &mut BTreeMap<Variable, ValueTypeSet>,
mod testing {
use super::*;
use mentat_core::{
use core_traits::{
Attribute,
Schema,
TypedValue,
ValueType,
TypedValue,
};
use mentat_query::{
use mentat_core::{
Schema,
};
use edn::query::{
Keyword,
Variable,
};

View file

@ -8,16 +8,19 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use mentat_core::{
Cloned,
use core_traits::{
Entid,
HasSchema,
TypedValue,
ValueType,
TypedValue,
ValueTypeSet,
};
use mentat_query::{
use mentat_core::{
Cloned,
HasSchema,
};
use edn::query::{
NonIntegerConstant,
Pattern,
PatternValuePlace,
@ -656,14 +659,18 @@ mod testing {
use std::collections::BTreeMap;
use std::collections::BTreeSet;
use mentat_core::attribute::Unique;
use mentat_core::{
use core_traits::attribute::{
Unique,
};
use core_traits::{
Attribute,
Schema,
ValueTypeSet,
};
use mentat_core::{
Schema,
};
use mentat_query::{
use edn::query::{
Keyword,
Variable,
};

View file

@ -8,13 +8,16 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use mentat_core::{
Schema,
use core_traits::{
ValueType,
ValueTypeSet,
};
use mentat_query::{
use mentat_core::{
Schema,
};
use edn::query::{
FnArg,
PlainSymbol,
Predicate,
@ -25,7 +28,7 @@ use clauses::ConjoiningClauses;
use clauses::convert::ValueTypes;
use errors::{
use query_algebrizer_traits::errors::{
AlgebrizerError,
Result,
};
@ -187,14 +190,16 @@ impl Inequality {
mod testing {
use super::*;
use mentat_core::attribute::Unique;
use mentat_core::{
use core_traits::attribute::{
Unique,
};
use core_traits::{
Attribute,
TypedValue,
ValueType,
};
use mentat_query::{
use edn::query::{
FnArg,
Keyword,
Pattern,

View file

@ -8,14 +8,17 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use core_traits::{
ValueType,
TypedValue,
};
use mentat_core::{
HasSchema,
Schema,
TypedValue,
ValueType,
};
use mentat_query::{
use edn::query::{
FnArg,
NonIntegerConstant,
PlainSymbol,
@ -23,7 +26,7 @@ use mentat_query::{
use clauses::ConjoiningClauses;
use errors::{
use query_algebrizer_traits::errors::{
AlgebrizerError,
Result,
};

View file

@ -8,11 +8,11 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use mentat_core::{
use core_traits::{
ValueType,
};
use mentat_query::{
use edn::query::{
Binding,
FnArg,
SrcVar,
@ -24,7 +24,7 @@ use clauses::{
ConjoiningClauses,
};
use errors::{
use query_algebrizer_traits::errors::{
AlgebrizerError,
BindingError,
Result,
@ -248,13 +248,16 @@ impl ConjoiningClauses {
mod testing {
use super::*;
use mentat_core::{
Schema,
use core_traits::{
TypedValue,
ValueType,
};
use mentat_query::{
use mentat_core::{
Schema,
};
use edn::query::{
Binding,
FnArg,
PlainSymbol,

View file

@ -8,7 +8,7 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use mentat_query::{
use edn::query::{
WhereFn,
};
@ -16,7 +16,7 @@ use clauses::{
ConjoiningClauses,
};
use errors::{
use query_algebrizer_traits::errors::{
AlgebrizerError,
Result,
};

View file

@ -10,33 +10,35 @@
extern crate failure;
#[macro_use] extern crate failure_derive;
extern crate edn;
extern crate mentat_core;
extern crate mentat_query;
#[macro_use]
extern crate core_traits;
extern crate query_algebrizer_traits;
use std::collections::BTreeSet;
use std::ops::Sub;
use std::rc::Rc;
#[macro_use]
mod errors;
mod types;
mod validate;
mod clauses;
use mentat_core::{
CachedAttributes,
use core_traits::{
Entid,
Schema,
TypedValue,
ValueType,
};
use mentat_core::{
CachedAttributes,
Schema,
parse_query,
};
use mentat_core::counter::RcCounter;
use mentat_query::{
use edn::query::{
Element,
FindSpec,
Limit,
@ -47,9 +49,8 @@ use mentat_query::{
WhereClause,
};
pub use errors::{
use query_algebrizer_traits::errors::{
AlgebrizerError,
BindingError,
Result,
};

View file

@ -14,15 +14,18 @@ use std::fmt::{
Formatter,
};
use mentat_core::{
use core_traits::{
Entid,
TypedValue,
ValueRc,
ValueType,
ValueTypeSet,
};
use mentat_query::{
use mentat_core::{
ValueRc,
};
use edn::query::{
Direction,
FindSpec,
Keyword,

View file

@ -10,7 +10,7 @@
use std::collections::BTreeSet;
use mentat_query::{
use edn::query::{
ContainsVariables,
OrJoin,
NotJoin,
@ -18,7 +18,7 @@ use mentat_query::{
UnifyVars,
};
use errors::{
use query_algebrizer_traits::errors::{
AlgebrizerError,
Result,
};
@ -95,9 +95,9 @@ pub(crate) fn validate_not_join(not_join: &NotJoin) -> Result<()> {
#[cfg(test)]
mod tests {
extern crate mentat_core;
extern crate mentat_query;
extern crate edn;
use self::mentat_query::{
use edn::query::{
Keyword,
OrWhereClause,
Pattern,

View file

@ -8,19 +8,24 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
extern crate edn;
extern crate mentat_core;
extern crate mentat_query;
extern crate core_traits;
extern crate mentat_query_algebrizer;
extern crate query_algebrizer_traits;
mod utils;
use mentat_core::{
use core_traits::{
Attribute,
Schema,
ValueType,
};
use mentat_query::{
use mentat_core::{
Schema,
};
use edn::query::{
Keyword,
};

View file

@ -8,30 +8,38 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
extern crate edn;
extern crate mentat_core;
extern crate mentat_query;
extern crate core_traits;
extern crate mentat_query_algebrizer;
extern crate query_algebrizer_traits;
mod utils;
use std::collections::BTreeMap;
use mentat_core::{
use core_traits::{
Attribute,
Schema,
ValueType,
TypedValue,
};
use mentat_query::{
use mentat_core::{
Schema,
};
use edn::query::{
Keyword,
PlainSymbol,
Variable,
};
use mentat_query_algebrizer::{
use query_algebrizer_traits::errors::{
AlgebrizerError,
BindingError,
};
use mentat_query_algebrizer::{
ComputedTable,
Known,
QueryInputs,

View file

@ -8,30 +8,38 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
extern crate edn;
extern crate mentat_core;
extern crate mentat_query;
extern crate core_traits;
extern crate mentat_query_algebrizer;
extern crate query_algebrizer_traits;
mod utils;
use mentat_core::{
use core_traits::{
Attribute,
DateTime,
Schema,
TypedValue,
Utc,
ValueType,
TypedValue,
ValueTypeSet,
};
use mentat_query::{
use mentat_core::{
DateTime,
Schema,
Utc,
};
use edn::query::{
Keyword,
PlainSymbol,
Variable,
};
use mentat_query_algebrizer::{
use query_algebrizer_traits::errors::{
AlgebrizerError,
};
use mentat_query_algebrizer::{
EmptyBecause,
Known,
QueryInputs,

View file

@ -8,9 +8,11 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
extern crate edn;
extern crate core_traits;
extern crate mentat_core;
extern crate mentat_query;
extern crate mentat_query_algebrizer;
extern crate query_algebrizer_traits;
mod utils;
@ -20,9 +22,12 @@ use utils::{
bails,
};
use core_traits::{
ValueType,
};
use mentat_core::{
Schema,
ValueType,
};
use mentat_query_algebrizer::Known;

View file

@ -13,19 +13,25 @@
// this module will get warnings otherwise).
#![allow(dead_code)]
use mentat_core::{
use core_traits::{
Attribute,
Entid,
Schema,
ValueType,
};
use mentat_query::{
use mentat_core::{
Schema,
};
use edn::query::{
Keyword,
};
use mentat_query_algebrizer::{
use query_algebrizer_traits::errors::{
AlgebrizerError,
};
use mentat_query_algebrizer::{
ConjoiningClauses,
Known,
QueryInputs,

View file

@ -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"

View file

@ -8,12 +8,12 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use mentat_core::{
use core_traits::{
ValueType,
ValueTypeSet,
};
use mentat_query::{
use edn::query::{
Aggregate,
QueryFunction,
Variable,
@ -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<ValueType> {
pub fn is_applicable_to_types(&self, possibilities: ValueTypeSet) -> Result<ValueType> {
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<SimpleAggregate>;
}
@ -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 =

View file

@ -12,26 +12,21 @@ use std; // To refer to std::result::Result.
use rusqlite;
use mentat_core::{
use core_traits::{
ValueTypeSet,
};
use mentat_db;
use mentat_query::{
use db_traits::errors::DbError;
use edn::query::{
PlainSymbol,
};
use mentat_query_pull;
use query_pull_traits::errors::{
PullError,
};
use aggregates::{
SimpleAggregationOp,
};
#[macro_export]
macro_rules! bail {
($e:expr) => (
return Err($e.into());
)
}
pub type Result<T> = std::result::Result<T, ProjectorError>;
#[derive(Debug, Fail)]
@ -71,10 +66,10 @@ pub enum ProjectorError {
RusqliteError(String),
#[fail(display = "{}", _0)]
DbError(#[cause] mentat_db::DbError),
DbError(#[cause] DbError),
#[fail(display = "{}", _0)]
PullError(#[cause] mentat_query_pull::PullError),
PullError(#[cause] PullError),
}
impl From<rusqlite::Error> for ProjectorError {
@ -83,14 +78,14 @@ impl From<rusqlite::Error> for ProjectorError {
}
}
impl From<mentat_db::DbError> for ProjectorError {
fn from(error: mentat_db::DbError) -> ProjectorError {
impl From<DbError> for ProjectorError {
fn from(error: DbError) -> ProjectorError {
ProjectorError::DbError(error)
}
}
impl From<mentat_query_pull::PullError> for ProjectorError {
fn from(error: mentat_query_pull::PullError) -> ProjectorError {
impl From<PullError> for ProjectorError {
fn from(error: PullError) -> ProjectorError {
ProjectorError::PullError(error)
}
}

View file

@ -1,4 +1,4 @@
// Copyright 2016 Mozilla
// 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
@ -9,26 +9,20 @@
// specific language governing permissions and limitations under the License.
extern crate failure;
#[macro_use]
extern crate failure_derive;
extern crate rusqlite;
extern crate mentat_core;
extern crate mentat_query;
#[macro_use]
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_projector;
extern crate mentat_query_sql;
extern crate mentat_sql;
mod translate;
pub mod errors;
pub mod aggregates;
pub use mentat_query_sql::{
Projection,
};
pub use translate::{
ProjectedSelect,
cc_to_exists,
query_to_select,
};
// query-translator could be folded into query-projector; for now, just type alias the errors.
pub type TranslatorError = mentat_query_projector::ProjectorError;
pub type Result<T> = std::result::Result<T, TranslatorError>;

View file

@ -8,19 +8,24 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
extern crate edn;
extern crate mentat_core;
extern crate mentat_query;
extern crate core_traits;
extern crate mentat_query_algebrizer;
extern crate mentat_query_projector;
extern crate query_projector_traits;
use mentat_core::{
use core_traits::{
Attribute,
Entid,
Schema,
ValueType,
};
use mentat_query::{
use mentat_core::{
Schema,
};
use edn::query::{
Keyword,
};
@ -98,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") {

View file

@ -5,24 +5,26 @@ workspace = ".."
[dependencies]
failure = "0.1.1"
failure_derive = "0.1.1"
indexmap = "1"
[dependencies.rusqlite]
version = "0.13"
features = ["limits"]
[dependencies.core_traits]
path = "../core-traits"
[dependencies.edn]
path = "../edn"
[dependencies.mentat_core]
path = "../core"
[dependencies.mentat_db]
path = "../db"
[dependencies.mentat_sql]
path = "../sql"
[dependencies.mentat_query]
path = "../query"
[dependencies.db_traits]
path = "../db-traits"
[dependencies.mentat_query_algebrizer]
path = "../query-algebrizer"
@ -30,6 +32,14 @@ path = "../query-algebrizer"
[dependencies.mentat_query_pull]
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"
[dev-dependencies.mentat_sql]
path = "../sql"

View file

@ -8,11 +8,11 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use mentat_core::{
use core_traits::{
Binding,
};
use errors::{
use query_projector_traits::errors::{
ProjectorError,
Result,
};

View file

@ -10,18 +10,20 @@
extern crate failure;
#[macro_use]
extern crate failure_derive;
extern crate indexmap;
extern crate rusqlite;
extern crate edn;
extern crate mentat_core;
extern crate db_traits;
#[macro_use]
extern crate core_traits;
extern crate mentat_db; // For value conversion.
extern crate mentat_query;
extern crate mentat_query_algebrizer;
extern crate mentat_query_pull;
extern crate query_pull_traits;
extern crate query_projector_traits;
extern crate mentat_query_sql;
extern crate mentat_sql;
use std::collections::{
BTreeSet,
@ -36,11 +38,13 @@ use rusqlite::{
Rows,
};
use mentat_core::{
use core_traits::{
Binding,
Schema,
TypedValue,
ValueType,
};
use mentat_core::{
Schema,
ValueTypeTag,
};
@ -52,7 +56,7 @@ use mentat_db::{
TypedSQLValue,
};
use mentat_query::{
use edn::query::{
Element,
FindSpec,
Limit,
@ -69,10 +73,8 @@ use mentat_query_sql::{
Projection,
};
#[macro_use]
pub mod errors;
pub mod translate;
mod aggregates;
mod binding_tuple;
pub use binding_tuple::{
BindingTuple,
@ -82,10 +84,6 @@ mod projectors;
mod pull;
mod relresult;
pub use aggregates::{
SimpleAggregationOp,
};
use project::{
ProjectedElements,
project_elements,
@ -116,7 +114,7 @@ pub use relresult::{
StructuredRelResult,
};
pub use errors::{
use query_projector_traits::errors::{
ProjectorError,
Result,
};

View file

@ -16,17 +16,20 @@ use indexmap::{
IndexSet,
};
use core_traits::{
ValueTypeSet,
};
use mentat_core::{
SQLValueType,
SQLValueTypeSet,
ValueTypeSet,
};
use mentat_core::util::{
Either,
};
use mentat_query::{
use edn::query::{
Element,
Pull,
Variable,
@ -49,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,
};
@ -310,7 +313,7 @@ pub(crate) fn project_elements<'a, I: IntoIterator<Item = &'a Element>>(
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;

View file

@ -20,7 +20,7 @@ use ::{
rusqlite,
};
use ::errors::{
use query_projector_traits::errors::{
Result,
};

View file

@ -16,7 +16,7 @@ use super::{
rusqlite,
};
use super::errors::{
use query_projector_traits::errors::{
Result,
};

View file

@ -18,7 +18,7 @@ use mentat_query_pull::{
Puller,
};
use mentat_core::{
use core_traits::{
Entid,
};
@ -44,7 +44,7 @@ use ::pull::{
PullTemplate,
};
use ::errors::{
use query_projector_traits::errors::{
Result,
};

View file

@ -26,7 +26,7 @@ use ::{
rusqlite,
};
use ::errors::{
use query_projector_traits::errors::{
Result,
};

View file

@ -13,16 +13,19 @@ use std::collections::{
BTreeSet,
};
use mentat_core::{
use core_traits::{
Binding,
Entid,
Schema,
StructuredMap,
TypedValue,
};
use mentat_core::{
Schema,
ValueRc,
};
use mentat_query::{
use edn::query::{
PullAttributeSpec,
};
@ -30,7 +33,7 @@ use mentat_query_pull::{
Puller,
};
use errors::Result;
use query_projector_traits::errors::Result;
use super::{
Index,

View file

@ -8,7 +8,7 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use mentat_core::{
use core_traits::{
Binding,
TypedValue,
};

View file

@ -8,22 +8,25 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
use core_traits::{
TypedValue,
ValueType,
ValueTypeSet,
};
use mentat_core::{
Schema,
SQLTypeAffinity,
SQLValueType,
SQLValueTypeSet,
TypedValue,
ValueType,
ValueTypeTag,
ValueTypeSet,
};
use mentat_core::util::{
Either,
};
use mentat_query::{
use edn::query::{
Limit,
};
@ -46,7 +49,7 @@ use mentat_query_algebrizer::{
VariableColumn,
};
use mentat_query_projector::{
use ::{
CombinedProjection,
ConstantProjector,
Projector,

View file

@ -8,31 +8,34 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
extern crate edn;
extern crate mentat_core;
extern crate mentat_query;
extern crate core_traits;
extern crate mentat_query_algebrizer;
extern crate mentat_query_projector;
extern crate mentat_query_translator;
extern crate mentat_sql;
use std::collections::BTreeMap;
use std::rc::Rc;
use mentat_query::{
use edn::query::{
FindSpec,
Keyword,
Variable,
};
use mentat_core::{
use core_traits::{
Attribute,
Entid,
Schema,
TypedValue,
ValueType,
};
use mentat_core::{
Schema,
};
use mentat_query_algebrizer::{
Known,
QueryInputs,
@ -45,7 +48,7 @@ use mentat_query_projector::{
ConstantProjector,
};
use mentat_query_translator::{
use mentat_query_projector::translate::{
ProjectedSelect,
query_to_select,
};

View file

@ -0,0 +1,18 @@
[package]
name = "query_pull_traits"
version = "0.0.1"
workspace = ".."
[lib]
name = "query_pull_traits"
path = "lib.rs"
[dependencies]
failure = "0.1.1"
failure_derive = "0.1.1"
[dependencies.core_traits]
path = "../core-traits"
[dependencies.db_traits]
path = "../db-traits"

View file

@ -10,11 +10,11 @@
use std; // To refer to std::result::Result.
use mentat_db::{
use db_traits::errors::{
DbError,
};
use mentat_core::{
use core_traits::{
Entid,
};

18
query-pull-traits/lib.rs Normal file
View file

@ -0,0 +1,18 @@
// 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 core_traits;
extern crate db_traits;
pub mod errors;

View file

@ -5,26 +5,22 @@ workspace = ".."
[dependencies]
failure = "0.1.1"
failure_derive = "0.1.1"
[dependencies.query_pull_traits]
path = "../query-pull-traits"
[dependencies.rusqlite]
version = "0.13"
features = ["limits"]
[dependencies.edn]
path = "../edn"
[dependencies.mentat_core]
path = "../core"
[dependencies.core_traits]
path = "../core-traits"
[dependencies.mentat_db]
path = "../db"
[dependencies.mentat_query]
path = "../query"
[dependencies.mentat_query_algebrizer]
path = "../query-algebrizer"
[dependencies.mentat_query_sql]
path = "../query-sql"
[dependencies.mentat_sql]
path = "../sql"

View file

@ -58,18 +58,13 @@
///! ```
extern crate failure;
#[macro_use]
extern crate failure_derive;
extern crate rusqlite;
extern crate edn;
extern crate mentat_core;
extern crate core_traits;
extern crate mentat_db;
extern crate mentat_query;
extern crate mentat_query_algebrizer;
extern crate mentat_query_sql;
extern crate mentat_sql;
extern crate query_pull_traits;
use std::collections::{
BTreeMap,
@ -80,29 +75,30 @@ use std::iter::{
once,
};
use mentat_core::{
use core_traits::{
Binding,
Cloned,
Entid,
TypedValue,
StructuredMap,
};
use mentat_core::{
Cloned,
HasSchema,
Keyword,
Schema,
StructuredMap,
TypedValue,
ValueRc,
};
use mentat_db::cache;
use mentat_query::{
use edn::query::{
NamedPullAttribute,
PullAttributeSpec,
PullConcreteAttribute,
};
pub mod errors;
pub use errors::{
use query_pull_traits::errors::{
PullError,
Result,
};

View file

@ -5,14 +5,20 @@ workspace = ".."
[dependencies]
[dependencies.edn]
path = "../edn"
[dependencies.core_traits]
path = "../core-traits"
[dependencies.mentat_core]
path = "../core"
[dependencies.mentat_sql]
path = "../sql"
[dependencies.mentat_query]
path = "../query"
[dependencies.sql_traits]
path = "../sql-traits"
[dependencies.mentat_query_algebrizer]
path = "../query-algebrizer"

View file

@ -9,19 +9,25 @@
// specific language governing permissions and limitations under the License.
#[macro_use] extern crate mentat_core;
extern crate mentat_query;
extern crate core_traits;
extern crate sql_traits;
extern crate edn;
extern crate mentat_query_algebrizer;
extern crate mentat_sql;
use std::boxed::Box;
use mentat_core::{
use core_traits::{
Entid,
SQLTypeAffinity,
TypedValue,
ValueType,
};
use mentat_query::{
use mentat_core::{
SQLTypeAffinity,
};
use edn::query::{
Direction,
Limit,
Variable,
@ -37,11 +43,14 @@ use mentat_query_algebrizer::{
VariableColumn,
};
use mentat_sql::{
use sql_traits::errors::{
BuildQueryResult,
SQLError,
};
use mentat_sql::{
QueryBuilder,
QueryFragment,
SQLError,
SQLiteQueryBuilder,
SQLQuery,
};

View file

@ -1,26 +0,0 @@
[package]
name = "mentat_query_translator"
version = "0.0.1"
workspace = ".."
[dependencies]
failure = "0.1.1"
failure_derive = "0.1.1"
[dependencies.mentat_core]
path = "../core"
[dependencies.mentat_sql]
path = "../sql"
[dependencies.mentat_query]
path = "../query"
[dependencies.mentat_query_algebrizer]
path = "../query-algebrizer"
[dependencies.mentat_query_projector]
path = "../query-projector"
[dependencies.mentat_query_sql]
path = "../query-sql"

View file

@ -1,3 +0,0 @@
This crate turns an algebrized Datalog query into a domain-specific representation of a SQL query, and then uses `mentat_sql` to turn that into a SQL string to be executed.
This subsumes both planning and query construction, because in Mentat the SQL query is effectively a query plan.

View file

@ -1,12 +0,0 @@
[package]
name = "mentat_query"
version = "0.0.1"
workspace = ".."
[dependencies]
[dependencies.edn]
path = "../edn"
[dependencies.mentat_core]
path = "../core"

View file

@ -1,4 +0,0 @@
This sub-crate implements the core types used by the query parser,
translator, and executor — variables, find specifications, etc.
The `edn` sub-crate implements some even lower-level types, such as `Keyword`.

View file

@ -4,7 +4,7 @@ buildscript {
ext.kotlin_version = '1.2.41'
ext.library = [
version: '0.11.0'
version: '0.11.1'
]
ext.build = [

12
sql-traits/Cargo.toml Normal file
View file

@ -0,0 +1,12 @@
[package]
name = "sql_traits"
version = "0.0.1"
workspace = ".."
[lib]
name = "sql_traits"
path = "lib.rs"
[dependencies]
failure = "0.1.1"
failure_derive = "0.1.1"

20
sql-traits/errors.rs Normal file
View file

@ -0,0 +1,20 @@
// 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.
#[derive(Debug, Fail)]
pub enum SQLError {
#[fail(display = "invalid parameter name: {}", _0)]
InvalidParameterName(String),
#[fail(display = "parameter name could be generated: '{}'", _0)]
BindParamCouldBeGenerated(String)
}
pub type BuildQueryResult = Result<(), SQLError>;

View file

@ -8,5 +8,8 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
extern crate edn;
pub use edn::query::*;
extern crate failure;
#[macro_use]
extern crate failure_derive;
pub mod errors;

View file

@ -5,12 +5,17 @@ workspace = ".."
[dependencies]
failure = "0.1.1"
failure_derive = "0.1.1"
ordered-float = "0.5"
[dependencies.rusqlite]
version = "0.13"
features = ["limits"]
[dependencies.core_traits]
path = "../core-traits"
[dependencies.mentat_core]
path = "../core"
[dependencies.sql_traits]
path = "../sql-traits"

View file

@ -7,12 +7,14 @@
// 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 ordered_float;
extern crate rusqlite;
extern crate core_traits;
extern crate sql_traits;
extern crate mentat_core;
use std::rc::Rc;
@ -21,25 +23,22 @@ use std::collections::HashMap;
use ordered_float::OrderedFloat;
use core_traits::{
TypedValue,
};
use sql_traits::errors::{
BuildQueryResult,
SQLError,
};
use mentat_core::{
ToMicros,
TypedValue,
ValueRc,
};
pub use rusqlite::types::Value;
#[derive(Debug, Fail)]
pub enum SQLError {
#[fail(display = "invalid parameter name: {}", _0)]
InvalidParameterName(String),
#[fail(display = "parameter name could be generated: '{}'", _0)]
BindParamCouldBeGenerated(String)
}
pub type BuildQueryResult = Result<(), SQLError>;
/// 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.
/// Additional user-supplied argument bindings, with their placeholders accumulated via

View file

@ -45,18 +45,21 @@ use edn::{
InternSet,
};
use mentat_core::{
pub use core_traits::{
Attribute,
Entid,
HasSchema,
KnownEntid,
StructuredMap,
TypedValue,
ValueType,
};
use mentat_core::{
HasSchema,
Keyword,
Schema,
StructuredMap,
TxReport,
TypedValue,
ValueRc,
ValueType,
};
use mentat_db::cache::{
@ -94,7 +97,7 @@ use entity_builder::{
TermBuilder,
};
use errors::{
use public_traits::errors::{
Result,
MentatError,
};
@ -559,7 +562,7 @@ impl<'a, 'o> TransactWatcher for InProgressTransactWatcher<'a, 'o> {
self.observer_watcher.datom(op.clone(), e.clone(), a.clone(), v);
}
fn done(&mut self, t: &Entid, schema: &Schema) -> ::mentat_db::errors::Result<()> {
fn done(&mut self, t: &Entid, schema: &Schema) -> ::db_traits::errors::Result<()> {
self.cache_watcher.done(t, schema)?;
self.observer_watcher.done(t, schema)?;
self.tx_id = Some(t.clone());
@ -858,12 +861,15 @@ mod tests {
Instant,
};
use mentat_core::{
CachedAttributes,
use core_traits::{
Binding,
TypedValue,
};
use mentat_core::{
CachedAttributes,
};
use ::query::{
Variable,
};
@ -889,7 +895,7 @@ mod tests {
match conn.transact(&mut sqlite, t.as_str()) {
Err(MentatError::DbError(e)) => {
assert_eq!(e.kind(), ::mentat_db::DbErrorKind::UnrecognizedEntid(next + 1));
assert_eq!(e.kind(), ::db_traits::errors::DbErrorKind::UnrecognizedEntid(next + 1));
},
x => panic!("expected db error, got {:?}", x),
}
@ -917,7 +923,7 @@ mod tests {
match conn.transact(&mut sqlite, t.as_str()) {
Err(MentatError::DbError(e)) => {
// All this, despite this being the ID we were about to allocate!
assert_eq!(e.kind(), ::mentat_db::DbErrorKind::UnrecognizedEntid(next));
assert_eq!(e.kind(), ::db_traits::errors::DbErrorKind::UnrecognizedEntid(next));
},
x => panic!("expected db error, got {:?}", x),
}
@ -1101,7 +1107,7 @@ mod tests {
match report.expect_err("expected transact error") {
MentatError::DbError(e) => {
match e.kind() {
::mentat_db::DbErrorKind::SchemaConstraintViolation(_) => {},
::db_traits::errors::DbErrorKind::SchemaConstraintViolation(_) => {},
_ => panic!("expected SchemaConstraintViolation"),
}
},

View file

@ -68,16 +68,19 @@ use edn::entities::{
ValuePlace,
};
use core_traits::{
TypedValue,
};
use mentat_core::{
TxReport,
TypedValue,
};
use conn::{
InProgress,
};
use errors::{
use public_traits::errors::{
Result,
};
@ -279,6 +282,7 @@ impl<'a, 'c> EntityBuilder<InProgressBuilder<'a, 'c>> {
#[cfg(test)]
mod testing {
extern crate mentat_db;
extern crate db_traits;
use ::{
Conn,
@ -323,7 +327,7 @@ mod testing {
// This should fail: unrecognized entid.
match in_progress.transact_entities(terms).expect_err("expected transact to fail") {
MentatError::DbError(e) => {
assert_eq!(e.kind(), mentat_db::DbErrorKind::UnrecognizedEntid(999));
assert_eq!(e.kind(), db_traits::errors::DbErrorKind::UnrecognizedEntid(999));
},
_ => panic!("Should have rejected the entid."),
}

View file

@ -10,8 +10,6 @@
#![recursion_limit="128"]
#[macro_use]
extern crate failure_derive;
extern crate failure;
#[macro_use]
@ -23,36 +21,48 @@ extern crate uuid;
pub extern crate edn;
extern crate mentat_core;
#[macro_use]
extern crate core_traits;
extern crate mentat_db;
extern crate mentat_query;
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 mentat_query_translator;
extern crate query_pull_traits;
extern crate sql_traits;
extern crate mentat_sql;
extern crate public_traits;
#[cfg(feature = "syncable")]
extern crate mentat_tolstoy;
pub use mentat_core::{
#[cfg(feature = "syncable")]
extern crate tolstoy_traits;
pub use core_traits::{
Attribute,
Binding,
DateTime,
Entid,
HasSchema,
Keyword,
KnownEntid,
Schema,
StructuredMap,
TxReport,
TypedValue,
Utc,
Uuid,
ValueType,
now,
};
pub use mentat_query::{
pub use mentat_core::{
DateTime,
HasSchema,
Keyword,
Schema,
TxReport,
Utc,
Uuid,
};
pub use edn::query::{
FindSpec,
};
@ -120,9 +130,8 @@ macro_rules! kw {
};
}
#[macro_use]
pub mod errors;
pub use errors::{
pub use public_traits::errors;
pub use public_traits::errors::{
MentatError,
Result,
};
@ -134,14 +143,15 @@ pub use edn::{
ToMicros,
ToMillis,
};
pub use mentat_db::DbError;
pub use mentat_query_algebrizer::AlgebrizerError;
pub use mentat_query_projector::{
BindingTuple,
pub use query_algebrizer_traits::errors::AlgebrizerError;
pub use query_projector_traits::errors::{
ProjectorError,
};
pub use mentat_query_pull::PullError;
pub use mentat_sql::SQLError;
pub use mentat_query_projector::{
BindingTuple,
};
pub use query_pull_traits::errors::PullError;
pub use sql_traits::errors::SQLError;
pub mod conn;
pub mod entity_builder;

View file

@ -13,15 +13,18 @@ use rusqlite::types::ToSql;
use std::rc::Rc;
use mentat_core::{
use core_traits::{
Binding,
Entid,
HasSchema,
KnownEntid,
Schema,
TypedValue,
};
use mentat_core::{
HasSchema,
Schema,
};
use mentat_query_algebrizer::{
AlgebraicQuery,
EmptyBecause,
@ -34,13 +37,13 @@ pub use mentat_query_algebrizer::{
QueryInputs,
};
pub use mentat_query::{
pub use edn::query::{
Keyword,
PlainSymbol,
Variable,
};
use mentat_query::{
use edn::query::{
Element,
FindSpec,
Pattern,
@ -54,15 +57,15 @@ use mentat_query_projector::{
Projector,
};
use mentat_sql::{
SQLQuery,
};
use mentat_query_translator::{
use mentat_query_projector::translate::{
ProjectedSelect,
query_to_select,
};
use mentat_sql::{
SQLQuery,
};
pub use mentat_query_algebrizer::{
Known,
};
@ -73,7 +76,7 @@ pub use mentat_query_projector::{
RelResult,
};
use errors::{
use public_traits::errors::{
MentatError,
Result,
};

View file

@ -13,16 +13,19 @@ use std::collections::{
BTreeMap,
};
use mentat_core::{
DateTime,
pub use core_traits::{
Entid,
Keyword,
Binding,
TypedValue,
Utc,
ValueType,
};
use mentat_core::{
DateTime,
Keyword,
Utc,
};
use ::{
HasSchema,
Queryable,
@ -33,7 +36,7 @@ use ::{
Variable,
};
use errors::{
use public_traits::errors::{
MentatError,
Result,
};

View file

@ -26,12 +26,15 @@ use rusqlite;
use edn;
use mentat_core::{
use core_traits::{
Entid,
Keyword,
StructuredMap,
TxReport,
TypedValue,
};
use mentat_core::{
Keyword,
TxReport,
ValueRc,
};
use mentat_db::{
@ -56,7 +59,10 @@ use conn::{
Syncable,
};
use errors::*;
use public_traits::errors::{
MentatError,
Result,
};
use query::{
PreparedResult,
@ -277,11 +283,14 @@ mod tests {
SQLiteAttributeCache,
};
use core_traits::{
TypedValue,
ValueType,
};
use mentat_core::{
CachedAttributes,
HasSchema,
TypedValue,
ValueType,
};
use ::entity_builder::{
@ -302,7 +311,7 @@ mod tests {
VersionedStore,
};
use ::vocabulary::attribute::{
use core_traits::attribute::{
Unique,
};

Some files were not shown because too many files have changed in this diff Show more