diff --git a/Cargo.toml b/Cargo.toml index 6acf5404..4c8b55a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,9 @@ path = "edn" [dependencies.mentat_parser_utils] path = "parser-utils" +[dependencies.mentat_core] +path = "core" + [dependencies.mentat_db] path = "db" diff --git a/core/Cargo.toml b/core/Cargo.toml new file mode 100644 index 00000000..0bc3493f --- /dev/null +++ b/core/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "mentat_core" +version = "0.0.1" + +[dependencies] +num = "0.1.35" +ordered-float = "0.4.0" + +[dependencies.rusqlite] + diff --git a/core/src/lib.rs b/core/src/lib.rs new file mode 100644 index 00000000..aea97538 --- /dev/null +++ b/core/src/lib.rs @@ -0,0 +1,92 @@ +// 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. + +/// Core types defining a Mentat knowledge base. + +/// 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; + +/// 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,Debug,Eq,Hash,Ord,PartialOrd,PartialEq)] +pub enum ValueType { + Ref, + Boolean, + Instant, + Long, + Double, + String, + Keyword, +} + +/// 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, + + /// `true` 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. + pub unique_value: bool, + + /// `true` 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_identity: bool, + + /// `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, +} + +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_value: false, + unique_identity: false, + component: false, + } + } +} + diff --git a/db/Cargo.toml b/db/Cargo.toml index 96b977eb..d4aba934 100644 --- a/db/Cargo.toml +++ b/db/Cargo.toml @@ -17,6 +17,9 @@ features = ["bundled"] [dependencies.edn] path = "../edn" +[dependencies.mentat_core] +path = "../core" + [dependencies.mentat_tx] path = "../tx" diff --git a/db/src/types.rs b/db/src/types.rs index ea8f66e7..8fda08d3 100644 --- a/db/src/types.rs +++ b/db/src/types.rs @@ -14,30 +14,17 @@ use std::collections::{BTreeMap}; use ordered_float::{OrderedFloat}; -/// Core types defining a Mentat knowledge base. +extern crate mentat_core; -/// 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; - -/// 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,Debug,Eq,Hash,Ord,PartialOrd,PartialEq)] -pub enum ValueType { - Ref, - Boolean, - Instant, - Long, - Double, - String, - Keyword, -} +pub use self::mentat_core::{ + Entid, + ValueType, + Attribute, +}; /// Represents a Mentat value in a particular value set. // TODO: expand to include :db.type/{instant,url,uuid}. +// TODO: BigInt? #[derive(Clone,Debug,Eq,Hash,Ord,PartialOrd,PartialEq)] pub enum TypedValue { Ref(Entid), @@ -80,67 +67,6 @@ impl Partition { /// Map partition names to `Partition` instances. pub type PartitionMap = BTreeMap; - -/// 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, - - /// `true` 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. - pub unique_value: bool, - - /// `true` 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_identity: bool, - - /// `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, -} - -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_value: false, - unique_identity: false, - component: false, - } - } -} - /// Map `String` idents (`:db/ident`) to positive integer entids (`1`). pub type IdentMap = BTreeMap;