Preliminary work for vocabulary management. r=emily,nalexander

Pre: export AttributeBuilder from mentat_db.
Pre: fix module-level comment for tx/src/entities.rs.
Pre: rename some `to_` conversions to `into_`.
Pre: make AttributeBuilder::unique less verbose.
Pre: split out a HasSchema trait to abstract over Schema.
Pre: rename SchemaMap/schema_map to AttributeMap/attribute_map.
Pre: TypedValue/NamespacedKeyword conversions.
Pre: turn Unique and ValueType into TypedValue::Keyword.
Pre: export IntoResult.
Pre: export NamespacedKeyword from mentat_core.
Pre: use intern_set in tx.
Pre: add InternSet::len.
Pre: comment gardening.
Pre: remove inaccurate TODO from TxReport comment.
This commit is contained in:
Richard Newman 2018-01-23 08:23:37 -08:00
parent 224570fb45
commit 6797a606b5
22 changed files with 150 additions and 80 deletions

View file

@ -33,6 +33,10 @@ impl<T> InternSet<T> where T: Eq + Hash {
}
}
pub fn len(&self) -> usize {
self.inner.len()
}
/// Intern a value, providing a ref-counted handle to the interned value.
///
/// ```

View file

@ -31,9 +31,6 @@ use std::rc::Rc;
use enum_set::EnumSet;
use self::ordered_float::OrderedFloat;
use self::edn::{
NamespacedKeyword,
};
pub use uuid::Uuid;
@ -44,6 +41,7 @@ pub use chrono::{
pub use edn::{
FromMicros,
NamespacedKeyword,
ToMicros,
Utc,
};
@ -102,7 +100,33 @@ impl enum_set::CLike for ValueType {
}
impl ValueType {
pub fn to_edn_value(self) -> edn::Value {
pub fn into_keyword(self) -> NamespacedKeyword {
NamespacedKeyword::new("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_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(),
@ -480,11 +504,23 @@ pub enum AttributeBitFlags {
}
pub mod attribute {
#[derive(Clone,Debug,Eq,Hash,Ord,PartialOrd,PartialEq)]
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
@ -561,7 +597,7 @@ impl Attribute {
attribute_map.insert(values::DB_IDENT.clone(), edn::Value::NamespacedKeyword(ident));
}
attribute_map.insert(values::DB_VALUE_TYPE.clone(), self.value_type.to_edn_value());
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() });
@ -608,7 +644,7 @@ pub type IdentMap = BTreeMap<NamespacedKeyword, Entid>;
pub type EntidMap = BTreeMap<Entid, NamespacedKeyword>;
/// Map attribute entids to `Attribute` instances.
pub type SchemaMap = BTreeMap<Entid, Attribute>;
pub type AttributeMap = BTreeMap<Entid, Attribute>;
/// Represents a Mentat schema.
///
@ -633,44 +669,59 @@ pub struct Schema {
///
/// Invariant: key-set is the same as the key-set of `entid_map` (equivalently, the value-set of
/// `ident_map`).
pub schema_map: SchemaMap,
pub attribute_map: AttributeMap,
}
pub trait HasSchema {
fn get_ident(&self, x: Entid) -> Option<&NamespacedKeyword>;
fn get_entid(&self, x: &NamespacedKeyword) -> Option<Entid>;
fn attribute_for_entid(&self, x: Entid) -> Option<&Attribute>;
fn attribute_for_ident(&self, ident: &NamespacedKeyword) -> Option<&Attribute>;
/// Return true if the provided entid identifies an attribute in this schema.
fn is_attribute(&self, x: Entid) -> bool;
/// Return true if the provided ident identifies an attribute in this schema.
fn identifies_attribute(&self, x: &NamespacedKeyword) -> bool;
}
impl Schema {
pub fn get_ident(&self, x: Entid) -> Option<&NamespacedKeyword> {
/// Returns an symbolic representation of the schema suitable for applying across Mentat stores.
pub fn to_edn_value(&self) -> edn::Value {
edn::Value::Vector((&self.attribute_map).iter()
.map(|(entid, attribute)|
attribute.to_edn_value(self.get_ident(*entid).cloned()))
.collect())
}
}
impl HasSchema for Schema {
fn get_ident(&self, x: Entid) -> Option<&NamespacedKeyword> {
self.entid_map.get(&x)
}
pub fn get_entid(&self, x: &NamespacedKeyword) -> Option<Entid> {
fn get_entid(&self, x: &NamespacedKeyword) -> Option<Entid> {
self.ident_map.get(x).map(|x| *x)
}
pub fn attribute_for_entid(&self, x: Entid) -> Option<&Attribute> {
self.schema_map.get(&x)
fn attribute_for_entid(&self, x: Entid) -> Option<&Attribute> {
self.attribute_map.get(&x)
}
pub fn attribute_for_ident(&self, ident: &NamespacedKeyword) -> Option<&Attribute> {
fn attribute_for_ident(&self, ident: &NamespacedKeyword) -> Option<&Attribute> {
self.get_entid(&ident)
.and_then(|x| self.attribute_for_entid(x))
}
/// Return true if the provided entid identifies an attribute in this schema.
pub fn is_attribute(&self, x: Entid) -> bool {
self.schema_map.contains_key(&x)
fn is_attribute(&self, x: Entid) -> bool {
self.attribute_map.contains_key(&x)
}
/// Return true if the provided ident identifies an attribute in this schema.
pub fn identifies_attribute(&self, x: &NamespacedKeyword) -> bool {
fn identifies_attribute(&self, x: &NamespacedKeyword) -> bool {
self.get_entid(x).map(|e| self.is_attribute(e)).unwrap_or(false)
}
/// Returns an symbolic representation of the schema suitable for applying across Mentat stores.
pub fn to_edn_value(&self) -> edn::Value {
edn::Value::Vector((&self.schema_map).iter()
.map(|(entid, attribute)|
attribute.to_edn_value(self.get_ident(*entid).cloned()))
.collect())
}
}
#[cfg(test)]
@ -685,7 +736,7 @@ mod test {
}
fn add_attribute(schema: &mut Schema, e: Entid, a: Attribute) {
schema.schema_map.insert(e, a);
schema.attribute_map.insert(e, a);
}
#[test]

View file

@ -44,7 +44,7 @@ use mentat_core::{
FromMicros,
IdentMap,
Schema,
SchemaMap,
AttributeMap,
TypedValue,
ToMicros,
ValueType,
@ -479,11 +479,11 @@ fn read_ident_map(conn: &rusqlite::Connection) -> Result<IdentMap> {
}
/// Read the schema materialized view from the given SQL store.
fn read_schema_map(conn: &rusqlite::Connection) -> Result<SchemaMap> {
fn read_attribute_map(conn: &rusqlite::Connection) -> Result<AttributeMap> {
let entid_triples = read_materialized_view(conn, "schema")?;
let mut schema_map = SchemaMap::default();
metadata::update_schema_map_from_entid_triples(&mut schema_map, entid_triples)?;
Ok(schema_map)
let mut attribute_map = AttributeMap::default();
metadata::update_attribute_map_from_entid_triples(&mut attribute_map, entid_triples)?;
Ok(attribute_map)
}
/// Read the materialized views from the given SQL store and return a Mentat `DB` for querying and
@ -491,8 +491,8 @@ fn read_schema_map(conn: &rusqlite::Connection) -> Result<SchemaMap> {
pub fn read_db(conn: &rusqlite::Connection) -> Result<DB> {
let partition_map = read_partition_map(conn)?;
let ident_map = read_ident_map(conn)?;
let schema_map = read_schema_map(conn)?;
let schema = Schema::from_ident_map_and_schema_map(ident_map, schema_map)?;
let attribute_map = read_attribute_map(conn)?;
let schema = Schema::from_ident_map_and_attribute_map(ident_map, attribute_map)?;
Ok(DB::new(partition_map, schema))
}
@ -1106,6 +1106,8 @@ mod tests {
use debug;
use edn;
use mentat_core::{
HasSchema,
Schema,
attribute,
};
use mentat_tx_parser;
@ -1158,9 +1160,9 @@ mod tests {
impl TestConn {
fn assert_materialized_views(&self) {
let materialized_ident_map = read_ident_map(&self.sqlite).expect("ident map");
let materialized_schema_map = read_schema_map(&self.sqlite).expect("schema map");
let materialized_attribute_map = read_attribute_map(&self.sqlite).expect("schema map");
let materialized_schema = Schema::from_ident_map_and_schema_map(materialized_ident_map, materialized_schema_map).expect("schema");
let materialized_schema = Schema::from_ident_map_and_attribute_map(materialized_ident_map, materialized_attribute_map).expect("schema");
assert_eq!(materialized_schema, self.schema);
}

View file

@ -27,6 +27,7 @@ use edn;
use entids;
use errors::Result;
use mentat_core::{
HasSchema,
SQLValueType,
TypedValue,
ValueType,

View file

@ -55,6 +55,8 @@ pub use bootstrap::{
USER0,
};
pub use schema::AttributeBuilder;
pub use db::{
TypedSQLValue,
new_connection,

View file

@ -43,7 +43,7 @@ use mentat_core::{
attribute,
Entid,
Schema,
SchemaMap,
AttributeMap,
TypedValue,
ValueType,
};
@ -78,24 +78,24 @@ pub enum IdentAlteration {
/// Summarizes changes to metadata such as a a `Schema` and (in the future) a `PartitionMap`.
#[derive(Clone, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)]
pub struct MetadataReport {
// Entids that were not present in the original `SchemaMap` that was mutated.
// Entids that were not present in the original `AttributeMap` that was mutated.
pub attributes_installed: BTreeSet<Entid>,
// Entids that were present in the original `SchemaMap` that was mutated, together with a
// Entids that were present in the original `AttributeMap` that was mutated, together with a
// representation of the mutations that were applied.
pub attributes_altered: BTreeMap<Entid, Vec<AttributeAlteration>>,
// Idents that were installed into the `SchemaMap`.
// Idents that were installed into the `AttributeMap`.
pub idents_altered: BTreeMap<Entid, IdentAlteration>,
}
/// Update a `SchemaMap` in place from the given `[e a typed_value]` triples.
/// Update a `AttributeMap` in place from the given `[e a typed_value]` triples.
///
/// This is suitable for producing a `SchemaMap` from the `schema` materialized view, which does not
/// This is suitable for producing a `AttributeMap` from the `schema` materialized view, which does not
/// contain install and alter markers.
///
/// Returns a report summarizing the mutations that were applied.
pub fn update_schema_map_from_entid_triples<U>(schema_map: &mut SchemaMap, assertions: U) -> Result<MetadataReport>
pub fn update_attribute_map_from_entid_triples<U>(attribute_map: &mut AttributeMap, assertions: U) -> Result<MetadataReport>
where U: IntoIterator<Item=(Entid, Entid, TypedValue)> {
// Group mutations by impacted entid.
@ -142,8 +142,8 @@ pub fn update_schema_map_from_entid_triples<U>(schema_map: &mut SchemaMap, asser
// builder.unique_value(false);
// builder.unique_identity(false);
// },
TypedValue::Ref(entids::DB_UNIQUE_VALUE) => { builder.unique(Some(attribute::Unique::Value)); },
TypedValue::Ref(entids::DB_UNIQUE_IDENTITY) => { builder.unique(Some(attribute::Unique::Identity)); },
TypedValue::Ref(entids::DB_UNIQUE_VALUE) => { builder.unique(attribute::Unique::Value); },
TypedValue::Ref(entids::DB_UNIQUE_IDENTITY) => { builder.unique(attribute::Unique::Identity); },
_ => bail!(ErrorKind::BadSchemaAssertion(format!("Expected [... :db/unique :db.unique/value|:db.unique/identity] but got [... :db/unique {:?}]", value)))
}
},
@ -179,7 +179,7 @@ pub fn update_schema_map_from_entid_triples<U>(schema_map: &mut SchemaMap, asser
let mut attributes_altered: BTreeMap<Entid, Vec<AttributeAlteration>> = BTreeMap::default();
for (entid, builder) in builders.into_iter() {
match schema_map.entry(entid) {
match attribute_map.entry(entid) {
Entry::Vacant(entry) => {
builder.validate_install_attribute()
.chain_err(|| ErrorKind::BadSchemaAssertion(format!("Schema alteration for new attribute with entid {} is not valid", entid)))?;
@ -245,7 +245,7 @@ pub fn update_schema_from_entid_quadruples<U>(schema: &mut Schema, assertions: U
let asserted_triples = attribute_set.asserted.into_iter().map(|((e, a), typed_value)| (e, a, typed_value));
let altered_triples = attribute_set.altered.into_iter().map(|((e, a), (_old_value, new_value))| (e, a, new_value));
let report = update_schema_map_from_entid_triples(&mut schema.schema_map, asserted_triples.chain(altered_triples))?;
let report = update_attribute_map_from_entid_triples(&mut schema.attribute_map, asserted_triples.chain(altered_triples))?;
let mut idents_altered: BTreeMap<Entid, IdentAlteration> = BTreeMap::new();

View file

@ -19,9 +19,10 @@ use mentat_core::{
Attribute,
Entid,
EntidMap,
HasSchema,
IdentMap,
Schema,
SchemaMap,
AttributeMap,
TypedValue,
ValueType,
};
@ -30,9 +31,9 @@ use metadata::{
AttributeAlteration,
};
/// Return `Ok(())` if `schema_map` defines a valid Mentat schema.
fn validate_schema_map(entid_map: &EntidMap, schema_map: &SchemaMap) -> Result<()> {
for (entid, attribute) in schema_map {
/// Return `Ok(())` if `attribute_map` defines a valid Mentat schema.
fn validate_attribute_map(entid_map: &EntidMap, attribute_map: &AttributeMap) -> Result<()> {
for (entid, attribute) in attribute_map {
let ident = || entid_map.get(entid).map(|ident| ident.to_string()).unwrap_or(entid.to_string());
if attribute.unique == Some(attribute::Unique::Value) && !attribute.index {
bail!(ErrorKind::BadSchemaAssertion(format!(":db/unique :db/unique_value without :db/index true for entid: {}", ident())))
@ -78,8 +79,8 @@ impl AttributeBuilder {
self
}
pub fn unique<'a>(&'a mut self, unique: Option<attribute::Unique>) -> &'a mut Self {
self.unique = Some(unique);
pub fn unique<'a>(&'a mut self, unique: attribute::Unique) -> &'a mut Self {
self.unique = Some(Some(unique));
self
}
@ -174,7 +175,7 @@ pub trait SchemaBuilding {
fn require_ident(&self, entid: Entid) -> Result<&symbols::NamespacedKeyword>;
fn require_entid(&self, ident: &symbols::NamespacedKeyword) -> Result<Entid>;
fn require_attribute_for_entid(&self, entid: Entid) -> Result<&Attribute>;
fn from_ident_map_and_schema_map(ident_map: IdentMap, schema_map: SchemaMap) -> Result<Schema>;
fn from_ident_map_and_attribute_map(ident_map: IdentMap, attribute_map: AttributeMap) -> Result<Schema>;
fn from_ident_map_and_triples<U>(ident_map: IdentMap, assertions: U) -> Result<Schema>
where U: IntoIterator<Item=(symbols::NamespacedKeyword, symbols::NamespacedKeyword, TypedValue)>;
}
@ -193,15 +194,15 @@ impl SchemaBuilding for Schema {
}
/// Create a valid `Schema` from the constituent maps.
fn from_ident_map_and_schema_map(ident_map: IdentMap, schema_map: SchemaMap) -> Result<Schema> {
fn from_ident_map_and_attribute_map(ident_map: IdentMap, attribute_map: AttributeMap) -> Result<Schema> {
let entid_map: EntidMap = ident_map.iter().map(|(k, v)| (v.clone(), k.clone())).collect();
validate_schema_map(&entid_map, &schema_map)?;
validate_attribute_map(&entid_map, &attribute_map)?;
Ok(Schema {
ident_map: ident_map,
entid_map: entid_map,
schema_map: schema_map,
attribute_map: attribute_map,
})
}
@ -214,8 +215,8 @@ impl SchemaBuilding for Schema {
let attr: i64 = *ident_map.get(&symbolic_attr).ok_or(ErrorKind::UnrecognizedIdent(symbolic_attr.to_string()))?;
Ok((ident, attr, value))
}).collect();
let mut schema = Schema::from_ident_map_and_schema_map(ident_map, SchemaMap::default())?;
metadata::update_schema_map_from_entid_triples(&mut schema.schema_map, entid_assertions?)?;
let mut schema = Schema::from_ident_map_and_attribute_map(ident_map, AttributeMap::default())?;
metadata::update_attribute_map_from_entid_triples(&mut schema.attribute_map, entid_assertions?)?;
Ok(schema)
}
}
@ -283,11 +284,11 @@ mod test {
schema.entid_map.insert(entid, ident.clone());
schema.ident_map.insert(ident.clone(), entid);
schema.schema_map.insert(entid, attribute);
schema.attribute_map.insert(entid, attribute);
}
#[test]
fn validate_schema_map_success() {
fn validate_attribute_map_success() {
let mut schema = Schema::default();
// attribute that is not an index has no uniqueness
add_attribute(&mut schema, NamespacedKeyword::new("foo", "bar"), 97, Attribute {
@ -335,7 +336,7 @@ mod test {
component: false,
});
assert!(validate_schema_map(&schema.entid_map, &schema.schema_map).is_ok());
assert!(validate_attribute_map(&schema.entid_map, &schema.attribute_map).is_ok());
}
#[test]
@ -352,7 +353,7 @@ mod test {
component: false,
});
let err = validate_schema_map(&schema.entid_map, &schema.schema_map).err();
let err = validate_attribute_map(&schema.entid_map, &schema.attribute_map).err();
assert!(err.is_some());
match err.unwrap() {
@ -374,7 +375,7 @@ mod test {
component: false,
});
let err = validate_schema_map(&schema.entid_map, &schema.schema_map).err();
let err = validate_attribute_map(&schema.entid_map, &schema.attribute_map).err();
assert!(err.is_some());
match err.unwrap() {
@ -396,7 +397,7 @@ mod test {
component: true,
});
let err = validate_schema_map(&schema.entid_map, &schema.schema_map).err();
let err = validate_attribute_map(&schema.entid_map, &schema.attribute_map).err();
assert!(err.is_some());
match err.unwrap() {
@ -418,7 +419,7 @@ mod test {
component: false,
});
let err = validate_schema_map(&schema.entid_map, &schema.schema_map).err();
let err = validate_attribute_map(&schema.entid_map, &schema.attribute_map).err();
assert!(err.is_some());
match err.unwrap() {
@ -439,7 +440,7 @@ mod test {
component: false,
});
let err = validate_schema_map(&schema.entid_map, &schema.schema_map).err();
let err = validate_attribute_map(&schema.entid_map, &schema.attribute_map).err();
assert!(err.is_some());
match err.unwrap() {

View file

@ -85,8 +85,10 @@ use mentat_core::{
Schema,
Utc,
attribute,
intern_set,
};
use mentat_core::intern_set::InternSet;
use mentat_tx::entities as entmod;
use mentat_tx::entities::{
Entity,
@ -199,13 +201,13 @@ impl<'conn, 'a> Tx<'conn, 'a> {
///
/// The `Term` instances produce share interned TempId and LookupRef handles, and we return the
/// interned handle sets so that consumers can ensure all handles are used appropriately.
fn entities_into_terms_with_temp_ids_and_lookup_refs<I>(&self, entities: I) -> Result<(Vec<TermWithTempIdsAndLookupRefs>, intern_set::InternSet<TempId>, intern_set::InternSet<AVPair>)> where I: IntoIterator<Item=Entity> {
fn entities_into_terms_with_temp_ids_and_lookup_refs<I>(&self, entities: I) -> Result<(Vec<TermWithTempIdsAndLookupRefs>, InternSet<TempId>, InternSet<AVPair>)> where I: IntoIterator<Item=Entity> {
struct InProcess<'a> {
partition_map: &'a PartitionMap,
schema: &'a Schema,
mentat_id_count: i64,
temp_ids: intern_set::InternSet<TempId>,
lookup_refs: intern_set::InternSet<AVPair>,
temp_ids: InternSet<TempId>,
lookup_refs: InternSet<AVPair>,
}
impl<'a> InProcess<'a> {
@ -214,8 +216,8 @@ impl<'conn, 'a> Tx<'conn, 'a> {
partition_map,
schema,
mentat_id_count: 0,
temp_ids: intern_set::InternSet::new(),
lookup_refs: intern_set::InternSet::new(),
temp_ids: InternSet::new(),
lookup_refs: InternSet::new(),
}
}
@ -685,6 +687,8 @@ impl<'conn, 'a> Tx<'conn, 'a> {
}
/// Transact the given `entities` against the given SQLite `conn`, using the given metadata.
/// If you want this work to occur inside a SQLite transaction, establish one on the connection
/// prior to calling this function.
///
/// This approach is explained in https://github.com/mozilla/mentat/wiki/Transacting.
// TODO: move this to the transactor layer.
@ -694,8 +698,6 @@ pub fn transact<'conn, 'a, I>(
schema_for_mutation: &'a Schema,
schema: &'a Schema,
entities: I) -> Result<(TxReport, PartitionMap, Option<Schema>)> where I: IntoIterator<Item=Entity> {
// Eventually, this function will be responsible for managing a SQLite transaction. For
// now, it's just about the tx details.
let tx_instant = ::now(); // Label the transaction with the timestamp when we first see it: leading edge.
let tx_id = partition_map.allocate_entid(":db.part/tx");

View file

@ -83,7 +83,6 @@ pub type AVPair = (Entid, TypedValue);
pub type AVMap<'a> = HashMap<&'a AVPair, Entid>;
/// A transaction report summarizes an applied transaction.
// TODO: include map of resolved tempids.
#[derive(Clone, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)]
pub struct TxReport {
/// The transaction ID of the transaction.

View file

@ -11,6 +11,7 @@
use std::rc::Rc;
use mentat_core::{
HasSchema,
Schema,
SQLValueType,
TypedValue,

View file

@ -9,6 +9,7 @@
// specific language governing permissions and limitations under the License.
use mentat_core::{
HasSchema,
Schema,
TypedValue,
ValueType,

View file

@ -25,6 +25,7 @@ use std::fmt::{
use mentat_core::{
Attribute,
Entid,
HasSchema,
Schema,
TypedValue,
ValueType,
@ -917,7 +918,7 @@ fn associate_ident(schema: &mut Schema, i: NamespacedKeyword, e: Entid) {
#[cfg(test)]
fn add_attribute(schema: &mut Schema, e: Entid, a: Attribute) {
schema.schema_map.insert(e, a);
schema.attribute_map.insert(e, a);
}
#[cfg(test)]

View file

@ -79,6 +79,7 @@ mod testing {
use mentat_core::{
Attribute,
Schema,
TypedValue,
ValueType,
ValueTypeSet,

View file

@ -9,6 +9,7 @@
// specific language governing permissions and limitations under the License.
use mentat_core::{
HasSchema,
Schema,
TypedValue,
ValueType,

View file

@ -41,7 +41,7 @@ fn associate_ident(schema: &mut Schema, i: NamespacedKeyword, e: Entid) {
}
fn add_attribute(schema: &mut Schema, e: Entid, a: Attribute) {
schema.schema_map.insert(e, a);
schema.attribute_map.insert(e, a);
}
fn prepopulated_schema() -> Schema {

View file

@ -53,7 +53,7 @@ fn associate_ident(schema: &mut Schema, i: NamespacedKeyword, e: Entid) {
#[cfg(test)]
fn add_attribute(schema: &mut Schema, e: Entid, a: Attribute) {
schema.schema_map.insert(e, a);
schema.attribute_map.insert(e, a);
}
fn prepopulated_schema() -> Schema {

View file

@ -48,7 +48,7 @@ fn associate_ident(schema: &mut Schema, i: NamespacedKeyword, e: Entid) {
#[cfg(test)]
fn add_attribute(schema: &mut Schema, e: Entid, a: Attribute) {
schema.schema_map.insert(e, a);
schema.attribute_map.insert(e, a);
}
fn prepopulated_schema() -> Schema {

View file

@ -50,7 +50,7 @@ fn associate_ident(schema: &mut Schema, i: NamespacedKeyword, e: Entid) {
}
fn add_attribute(schema: &mut Schema, e: Entid, a: Attribute) {
schema.schema_map.insert(e, a);
schema.attribute_map.insert(e, a);
}
fn translate_with_inputs(schema: &Schema, query: &'static str, inputs: QueryInputs) -> SQLQuery {

View file

@ -54,6 +54,7 @@ pub use mentat_db::{
};
pub use query::{
IntoResult,
NamespacedKeyword,
PlainSymbol,
QueryExplanation,

View file

@ -15,6 +15,7 @@ use std::rc::Rc;
use mentat_core::{
Entid,
HasSchema,
Schema,
TypedValue,
};

View file

@ -22,6 +22,7 @@ use chrono::FixedOffset;
use mentat_core::{
DateTime,
HasSchema,
TypedValue,
ValueType,
Utc,

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.
///! This module defines core types that support the transaction processor.
//! This module defines core types that support the transaction processor.
extern crate edn;