Update dependencies. Lint.

This commit is contained in:
Gregory Burd 2020-08-05 23:03:58 -04:00
parent 0e63167aab
commit 125306e108
104 changed files with 950 additions and 1027 deletions

View file

@ -14,7 +14,7 @@ authors = [
"Gregory Burd <greg@burd.me>", "Gregory Burd <greg@burd.me>",
] ]
name = "mentat" name = "mentat"
version = "0.12.0" version = "0.13.0"
build = "build/version.rs" build = "build/version.rs"
[features] [features]

View file

@ -11,8 +11,8 @@ path = "lib.rs"
chrono = { version = "~0.4", features = ["serde"] } chrono = { version = "~0.4", features = ["serde"] }
enum-set = "~0.0.8" enum-set = "~0.0.8"
lazy_static = "~1.4" lazy_static = "~1.4"
indexmap = "~1.3" indexmap = "~1.5"
ordered-float = { version = "~1.0.2", features = ["serde"] } ordered-float = { version = "~2.0", features = ["serde"] }
uuid = { version = "~0.8", features = ["v4", "serde"] } uuid = { version = "~0.8", features = ["v4", "serde"] }
serde = { version = "~1.0", features = ["rc"] } serde = { version = "~1.0", features = ["rc"] }
serde_derive = "~1.0" serde_derive = "~1.0"

View file

@ -52,7 +52,7 @@ use edn::entities::{
mod value_type_set; mod value_type_set;
pub mod values; pub mod values;
pub use value_type_set::ValueTypeSet; pub use crate::value_type_set::ValueTypeSet;
#[macro_export] #[macro_export]
macro_rules! bail { macro_rules! bail {
@ -109,7 +109,7 @@ pub enum AttributeBitFlags {
} }
pub mod attribute { pub mod attribute {
use TypedValue; use crate::TypedValue;
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)] #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)]
pub enum Unique { pub enum Unique {
@ -373,10 +373,7 @@ impl ValueType {
} }
pub fn is_numeric(self) -> bool { pub fn is_numeric(self) -> bool {
match self { matches!(self, ValueType::Long | ValueType::Double)
ValueType::Long | ValueType::Double => true,
_ => false,
}
} }
} }

View file

@ -10,7 +10,7 @@
use enum_set::EnumSet; use enum_set::EnumSet;
use ValueType; use crate::ValueType;
trait EnumSetExtensions<T: ::enum_set::CLike + Clone> { trait EnumSetExtensions<T: ::enum_set::CLike + Clone> {
/// Return a set containing both `x` and `y`. /// Return a set containing both `x` and `y`.

View file

@ -7,8 +7,8 @@ workspace = ".."
chrono = { version = "~0.4", features = ["serde"] } chrono = { version = "~0.4", features = ["serde"] }
enum-set = "~0.0" enum-set = "~0.0"
failure = "~0.1" failure = "~0.1"
indexmap = "~1.3" indexmap = "~1.5"
ordered-float = { version = "~1.0", features = ["serde"] } ordered-float = { version = "~2.0", features = ["serde"] }
uuid = { version = "~0.8", features = ["v4", "serde"] } uuid = { version = "~0.8", features = ["v4", "serde"] }
[dependencies.core_traits] [dependencies.core_traits]

View file

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

View file

@ -35,18 +35,18 @@ pub use chrono::{
pub use edn::parse::parse_query; pub use edn::parse::parse_query;
pub use edn::{Cloned, FromMicros, FromRc, Keyword, ToMicros, Utc, ValueRc}; pub use edn::{Cloned, FromMicros, FromRc, Keyword, ToMicros, Utc, ValueRc};
pub use cache::{CachedAttributes, UpdateableCache}; pub use crate::cache::{CachedAttributes, UpdateableCache};
mod sql_types; mod sql_types;
mod tx_report; mod tx_report;
/// Core types defining a Mentat knowledge base. /// Core types defining a Mentat knowledge base.
mod types; mod types;
pub use tx_report::TxReport; pub use crate::tx_report::TxReport;
pub use types::ValueTypeTag; pub use crate::types::ValueTypeTag;
pub use sql_types::{SQLTypeAffinity, SQLValueType, SQLValueTypeSet}; pub use crate::sql_types::{SQLTypeAffinity, SQLValueType, SQLValueTypeSet};
/// Map `Keyword` idents (`:db/ident`) to positive integer entids (`1`). /// Map `Keyword` idents (`:db/ident`) to positive integer entids (`1`).
pub type IdentMap = BTreeMap<Keyword, Entid>; pub type IdentMap = BTreeMap<Keyword, Entid>;

View file

@ -12,7 +12,7 @@ use std::collections::BTreeSet;
use core_traits::{ValueType, ValueTypeSet}; use core_traits::{ValueType, ValueTypeSet};
use types::ValueTypeTag; use crate::types::ValueTypeTag;
/// Type safe representation of the possible return values from SQLite's `typeof` /// Type safe representation of the possible return values from SQLite's `typeof`
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)] #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)]
@ -62,7 +62,7 @@ impl SQLValueType for ValueType {
/// Returns true if the provided integer is in the SQLite value space of this type. For /// Returns true if the provided integer is in the SQLite value space of this type. For
/// example, `1` is how we encode `true`. /// example, `1` is how we encode `true`.
fn accommodates_integer(&self, int: i64) -> bool { fn accommodates_integer(&self, int: i64) -> bool {
use ValueType::*; use crate::ValueType::*;
match *self { match *self {
Instant => false, // Always use #inst. Instant => false, // Always use #inst.
Long | Double => true, Long | Double => true,
@ -123,8 +123,8 @@ impl SQLValueTypeSet for ValueTypeSet {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::sql_types::SQLValueType;
use core_traits::ValueType; use core_traits::ValueType;
use sql_types::SQLValueType;
#[test] #[test]
fn test_accommodates_integer() { fn test_accommodates_integer() {

View file

@ -14,7 +14,7 @@ use std::collections::BTreeMap;
use core_traits::Entid; use core_traits::Entid;
use {DateTime, Utc}; use crate::{DateTime, Utc};
/// A transaction report summarizes an applied transaction. /// A transaction report summarizes an applied transaction.
#[derive(Clone, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)] #[derive(Clone, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)]

View file

@ -10,11 +10,11 @@ syncable = ["serde", "serde_json", "serde_derive"]
[dependencies] [dependencies]
failure = "~0.1" failure = "~0.1"
indexmap = "~1.3" indexmap = "~1.5"
itertools = "~0.9" itertools = "~0.9"
lazy_static = "~1.4" lazy_static = "~1.4"
log = "~0.4" log = "~0.4"
ordered-float = "~1.0" ordered-float = "~2.0"
time = "~0.2" time = "~0.2"
petgraph = "~0.5" petgraph = "~0.5"
serde = { version = "~1.0", optional = true } serde = { version = "~1.0", optional = true }

View file

@ -10,19 +10,19 @@
#![allow(dead_code)] #![allow(dead_code)]
use db::TypedSQLValue; use crate::db::TypedSQLValue;
use crate::entids;
use db_traits::errors::{DbErrorKind, Result}; use db_traits::errors::{DbErrorKind, Result};
use edn; use edn;
use edn::entities::Entity; use edn::entities::Entity;
use edn::symbols; use edn::symbols;
use edn::types::Value; use edn::types::Value;
use entids;
use core_traits::{values, TypedValue}; use core_traits::{values, TypedValue};
use crate::schema::SchemaBuilding;
use crate::types::{Partition, PartitionMap};
use mentat_core::{IdentMap, Schema}; use mentat_core::{IdentMap, Schema};
use schema::SchemaBuilding;
use types::{Partition, PartitionMap};
/// The first transaction ID applied to the knowledge base. /// The first transaction ID applied to the knowledge base.
/// ///

View file

@ -72,11 +72,11 @@ use mentat_sql::{QueryBuilder, SQLQuery, SQLiteQueryBuilder};
use edn::entities::OpType; use edn::entities::OpType;
use db::TypedSQLValue; use crate::db::TypedSQLValue;
use db_traits::errors::{DbError, DbErrorKind, Result}; use db_traits::errors::{DbError, DbErrorKind, Result};
use watcher::TransactWatcher; use crate::watcher::TransactWatcher;
// Right now we use BTreeMap, because we expect few cached attributes. // Right now we use BTreeMap, because we expect few cached attributes.
pub type CacheMap<K, V> = BTreeMap<K, V>; pub type CacheMap<K, V> = BTreeMap<K, V>;
@ -198,9 +198,7 @@ impl AevFactory {
let a: Entid = row.get_unwrap(0); let a: Entid = row.get_unwrap(0);
let e: Entid = row.get_unwrap(1); let e: Entid = row.get_unwrap(1);
let value_type_tag: i32 = row.get_unwrap(3); let value_type_tag: i32 = row.get_unwrap(3);
let v = TypedValue::from_sql_value_pair(row.get_unwrap(2), value_type_tag) let v = TypedValue::from_sql_value_pair(row.get_unwrap(2), value_type_tag).unwrap();
.map(|x| x)
.unwrap();
(a, e, self.intern(v)) (a, e, self.intern(v))
} }
} }

View file

@ -25,12 +25,12 @@ use rusqlite::limits::Limit;
use rusqlite::types::{ToSql, ToSqlOutput}; use rusqlite::types::{ToSql, ToSqlOutput};
use rusqlite::TransactionBehavior; use rusqlite::TransactionBehavior;
use bootstrap; use crate::bootstrap;
use {repeat_values, to_namespaced_keyword}; use crate::{repeat_values, to_namespaced_keyword};
use edn::{DateTime, Utc, Uuid, Value}; use edn::{DateTime, Utc, Uuid, Value};
use entids; use crate::entids;
use core_traits::{attribute, Attribute, AttributeBitFlags, Entid, TypedValue, ValueType}; use core_traits::{attribute, Attribute, AttributeBitFlags, Entid, TypedValue, ValueType};
@ -38,13 +38,13 @@ use mentat_core::{AttributeMap, FromMicros, IdentMap, Schema, ToMicros, ValueRc}
use db_traits::errors::{DbErrorKind, Result}; use db_traits::errors::{DbErrorKind, Result};
use metadata; use crate::metadata;
use schema::SchemaBuilding; use crate::schema::SchemaBuilding;
use tx::transact; use crate::tx::transact;
use types::{AVMap, AVPair, Partition, PartitionMap, DB}; use crate::types::{AVMap, AVPair, Partition, PartitionMap, DB};
use crate::watcher::NullWatcher;
use std::convert::TryInto; use std::convert::TryInto;
use watcher::NullWatcher;
// In PRAGMA foo='bar', `'bar'` must be a constant string (it cannot be a // In PRAGMA foo='bar', `'bar'` must be a constant string (it cannot be a
// bound parameter), so we need to escape manually. According to // bound parameter), so we need to escape manually. According to
@ -314,7 +314,7 @@ fn create_current_partition_view(conn: &rusqlite::Connection) -> Result<()> {
max(e) + 1 AS idx max(e) + 1 AS idx
FROM timelined_transactions WHERE timeline = {} GROUP BY part", FROM timelined_transactions WHERE timeline = {} GROUP BY part",
case.join(" "), case.join(" "),
::TIMELINE_MAIN crate::TIMELINE_MAIN
); );
conn.execute(&view_stmt, rusqlite::params![])?; conn.execute(&view_stmt, rusqlite::params![])?;
@ -908,6 +908,7 @@ impl MentatStoring for rusqlite::Connection {
// We must keep these computed values somewhere to reference them later, so we can't // We must keep these computed values somewhere to reference them later, so we can't
// combine this map and the subsequent flat_map. // combine this map and the subsequent flat_map.
// (e0, a0, v0, value_type_tag0, added0, flags0) // (e0, a0, v0, value_type_tag0, added0, flags0)
#[allow(clippy::type_complexity)]
let block: Result<Vec<(i64 /* e */, let block: Result<Vec<(i64 /* e */,
i64 /* a */, i64 /* a */,
ToSqlOutput<'a> /* value */, ToSqlOutput<'a> /* value */,
@ -984,6 +985,7 @@ impl MentatStoring for rusqlite::Connection {
// We must keep these computed values somewhere to reference them later, so we can't // We must keep these computed values somewhere to reference them later, so we can't
// combine this map and the subsequent flat_map. // combine this map and the subsequent flat_map.
// (e0, a0, v0, value_type_tag0, added0, flags0) // (e0, a0, v0, value_type_tag0, added0, flags0)
#[allow(clippy::type_complexity)]
let block: Result<Vec<(i64 /* e */, let block: Result<Vec<(i64 /* e */,
i64 /* a */, i64 /* a */,
Option<ToSqlOutput<'a>> /* value */, Option<ToSqlOutput<'a>> /* value */,
@ -1174,7 +1176,7 @@ pub fn update_metadata(
new_schema: &Schema, new_schema: &Schema,
metadata_report: &metadata::MetadataReport, metadata_report: &metadata::MetadataReport,
) -> Result<()> { ) -> Result<()> {
use metadata::AttributeAlteration::*; use crate::metadata::AttributeAlteration::*;
// Populate the materialized view directly from datoms (and, potentially in the future, // Populate the materialized view directly from datoms (and, potentially in the future,
// transactions). This might generalize nicely as we expand the set of materialized views. // transactions). This might generalize nicely as we expand the set of materialized views.
@ -1331,12 +1333,12 @@ mod tests {
use std::borrow::Borrow; use std::borrow::Borrow;
use super::*; use super::*;
use crate::debug::{tempids, TestConn};
use crate::internal_types::Term;
use core_traits::{attribute, KnownEntid}; use core_traits::{attribute, KnownEntid};
use db_traits::errors; use db_traits::errors;
use debug::{tempids, TestConn};
use edn::entities::OpType; use edn::entities::OpType;
use edn::{self, InternSet}; use edn::{self, InternSet};
use internal_types::Term;
use mentat_core::util::Either::*; use mentat_core::util::Either::*;
use mentat_core::{HasSchema, Keyword}; use mentat_core::{HasSchema, Keyword};
use std::collections::BTreeMap; use std::collections::BTreeMap;

View file

@ -66,23 +66,23 @@ use rusqlite::types::ToSql;
use rusqlite::TransactionBehavior; use rusqlite::TransactionBehavior;
use tabwriter::TabWriter; use tabwriter::TabWriter;
use bootstrap; use crate::bootstrap;
use db::*; use crate::db::*;
use db::{read_attribute_map, read_ident_map}; use crate::db::{read_attribute_map, read_ident_map};
use crate::entids;
use db_traits::errors::Result; use db_traits::errors::Result;
use edn; use edn;
use entids;
use core_traits::{Entid, TypedValue, ValueType}; use core_traits::{Entid, TypedValue, ValueType};
use crate::internal_types::TermWithTempIds;
use crate::schema::SchemaBuilding;
use crate::tx::{transact, transact_terms};
use crate::types::*;
use crate::watcher::NullWatcher;
use edn::entities::{EntidOrIdent, TempId}; use edn::entities::{EntidOrIdent, TempId};
use edn::InternSet; use edn::InternSet;
use internal_types::TermWithTempIds;
use mentat_core::{HasSchema, SQLValueType, TxReport}; use mentat_core::{HasSchema, SQLValueType, TxReport};
use schema::SchemaBuilding;
use tx::{transact, transact_terms};
use types::*;
use watcher::NullWatcher;
/// Represents a *datom* (assertion) in the store. /// Represents a *datom* (assertion) in the store.
#[derive(Clone, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)] #[derive(Clone, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)]

View file

@ -63,7 +63,8 @@ pub fn might_update_metadata(attribute: Entid) -> bool {
if attribute >= DB_DOC { if attribute >= DB_DOC {
return false; return false;
} }
match attribute { matches!(
attribute,
// Idents. // Idents.
DB_IDENT | DB_IDENT |
// Schema. // Schema.
@ -72,19 +73,22 @@ pub fn might_update_metadata(attribute: Entid) -> bool {
DB_INDEX | DB_INDEX |
DB_IS_COMPONENT | DB_IS_COMPONENT |
DB_UNIQUE | DB_UNIQUE |
DB_VALUE_TYPE => DB_VALUE_TYPE
true, )
_ => false,
}
} }
/// Return 'false' if the given attribute might be used to describe a schema attribute. /// Return 'false' if the given attribute might be used to describe a schema attribute.
pub fn is_a_schema_attribute(attribute: Entid) -> bool { pub fn is_a_schema_attribute(attribute: Entid) -> bool {
match attribute { matches!(
DB_IDENT | DB_CARDINALITY | DB_FULLTEXT | DB_INDEX | DB_IS_COMPONENT | DB_UNIQUE attribute,
| DB_VALUE_TYPE => true, DB_IDENT
_ => false, | DB_CARDINALITY
} | DB_FULLTEXT
| DB_INDEX
| DB_IS_COMPONENT
| DB_UNIQUE
| DB_VALUE_TYPE
)
} }
lazy_static! { lazy_static! {

View file

@ -23,10 +23,10 @@ use edn::entities;
use edn::entities::{EntityPlace, OpType, TempId, TxFunction}; use edn::entities::{EntityPlace, OpType, TempId, TxFunction};
use edn::{SpannedValue, ValueAndSpan, ValueRc}; use edn::{SpannedValue, ValueAndSpan, ValueRc};
use crate::schema::SchemaTypeChecking;
use crate::types::{AVMap, AVPair, Schema, TransactableValue};
use db_traits::errors; use db_traits::errors;
use db_traits::errors::{DbErrorKind, Result}; use db_traits::errors::{DbErrorKind, Result};
use schema::SchemaTypeChecking;
use types::{AVMap, AVPair, Schema, TransactableValue};
impl TransactableValue for ValueAndSpan { impl TransactableValue for ValueAndSpan {
fn into_typed_value(self, schema: &Schema, value_type: ValueType) -> Result<TypedValue> { fn into_typed_value(self, schema: &Schema, value_type: ValueType) -> Result<TypedValue> {
@ -82,11 +82,7 @@ impl TransactableValue for ValueAndSpan {
} }
fn as_tempid(&self) -> Option<TempId> { fn as_tempid(&self) -> Option<TempId> {
self.inner self.inner.as_text().cloned().map(TempId::External)
.as_text()
.cloned()
.map(TempId::External)
.map(|v| v)
} }
} }

View file

@ -60,30 +60,30 @@ mod upsert_resolution;
mod watcher; mod watcher;
// Export these for reference from sync code and tests. // Export these for reference from sync code and tests.
pub use bootstrap::{TX0, USER0, V1_PARTS}; pub use crate::bootstrap::{TX0, USER0, V1_PARTS};
pub static TIMELINE_MAIN: i64 = 0; pub static TIMELINE_MAIN: i64 = 0;
pub use schema::{AttributeBuilder, AttributeValidation}; pub use crate::schema::{AttributeBuilder, AttributeValidation};
pub use bootstrap::CORE_SCHEMA_VERSION; pub use crate::bootstrap::CORE_SCHEMA_VERSION;
use edn::symbols; use edn::symbols;
pub use entids::DB_SCHEMA_CORE; pub use crate::entids::DB_SCHEMA_CORE;
pub use db::{new_connection, TypedSQLValue}; pub use crate::db::{new_connection, TypedSQLValue};
#[cfg(feature = "sqlcipher")] #[cfg(feature = "sqlcipher")]
pub use db::{change_encryption_key, new_connection_with_key}; pub use db::{change_encryption_key, new_connection_with_key};
pub use watcher::TransactWatcher; pub use crate::watcher::TransactWatcher;
pub use tx::{transact, transact_terms}; pub use crate::tx::{transact, transact_terms};
pub use tx_observer::{InProgressObserverTransactWatcher, TxObservationService, TxObserver}; pub use crate::tx_observer::{InProgressObserverTransactWatcher, TxObservationService, TxObserver};
pub use types::{AttributeSet, Partition, PartitionMap, TransactableValue, DB}; pub use crate::types::{AttributeSet, Partition, PartitionMap, TransactableValue, DB};
pub fn to_namespaced_keyword(s: &str) -> Result<symbols::Keyword> { pub fn to_namespaced_keyword(s: &str) -> Result<symbols::Keyword> {
let splits = [':', '/']; let splits = [':', '/'];

View file

@ -29,18 +29,18 @@ use failure::ResultExt;
use std::collections::btree_map::Entry; use std::collections::btree_map::Entry;
use std::collections::{BTreeMap, BTreeSet}; use std::collections::{BTreeMap, BTreeSet};
use add_retract_alter_set::AddRetractAlterSet; use crate::add_retract_alter_set::AddRetractAlterSet;
use crate::entids;
use db_traits::errors::{DbErrorKind, Result}; use db_traits::errors::{DbErrorKind, Result};
use edn::symbols; use edn::symbols;
use entids;
use core_traits::{attribute, Entid, TypedValue, ValueType}; use core_traits::{attribute, Entid, TypedValue, ValueType};
use mentat_core::{AttributeMap, Schema}; use mentat_core::{AttributeMap, Schema};
use schema::{AttributeBuilder, AttributeValidation}; use crate::schema::{AttributeBuilder, AttributeValidation};
use types::EAV; use crate::types::EAV;
/// An alteration to an attribute. /// An alteration to an attribute.
#[derive(Clone, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)] #[derive(Clone, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)]

View file

@ -10,16 +10,16 @@
#![allow(dead_code)] #![allow(dead_code)]
use db::TypedSQLValue; use crate::db::TypedSQLValue;
use db_traits::errors::{DbErrorKind, Result}; use db_traits::errors::{DbErrorKind, Result};
use edn; use edn;
use edn::symbols; use edn::symbols;
use core_traits::{attribute, Attribute, Entid, KnownEntid, TypedValue, ValueType}; use core_traits::{attribute, Attribute, Entid, KnownEntid, TypedValue, ValueType};
use crate::metadata;
use crate::metadata::AttributeAlteration;
use mentat_core::{AttributeMap, EntidMap, HasSchema, IdentMap, Schema}; use mentat_core::{AttributeMap, EntidMap, HasSchema, IdentMap, Schema};
use metadata;
use metadata::AttributeAlteration;
pub trait AttributeValidation { pub trait AttributeValidation {
fn validate<F>(&self, ident: F) -> Result<()> fn validate<F>(&self, ident: F) -> Result<()>
@ -394,7 +394,7 @@ mod test {
fn add_attribute(schema: &mut Schema, ident: Keyword, entid: Entid, attribute: Attribute) { fn add_attribute(schema: &mut Schema, ident: Keyword, entid: Entid, attribute: Attribute) {
schema.entid_map.insert(entid, ident.clone()); schema.entid_map.insert(entid, ident.clone());
schema.ident_map.insert(ident.clone(), entid); schema.ident_map.insert(ident, entid);
if attribute.component { if attribute.component {
schema.component_attributes.push(entid); schema.component_attributes.push(entid);

View file

@ -22,16 +22,16 @@ use edn::InternSet;
use edn::entities::OpType; use edn::entities::OpType;
use db; use crate::db;
use db::TypedSQLValue; use crate::db::TypedSQLValue;
use tx::{transact_terms_with_action, TransactorAction}; use crate::tx::{transact_terms_with_action, TransactorAction};
use types::PartitionMap; use crate::types::PartitionMap;
use internal_types::{Term, TermWithoutTempIds}; use crate::internal_types::{Term, TermWithoutTempIds};
use watcher::NullWatcher; use crate::watcher::NullWatcher;
/// Collects a supplied tx range into an DESC ordered Vec of valid txs, /// Collects a supplied tx range into an DESC ordered Vec of valid txs,
/// ensuring they all belong to the same timeline. /// ensuring they all belong to the same timeline.
@ -79,7 +79,7 @@ fn move_transactions_to(
&format!( &format!(
"UPDATE timelined_transactions SET timeline = {} WHERE tx IN {}", "UPDATE timelined_transactions SET timeline = {} WHERE tx IN {}",
new_timeline, new_timeline,
::repeat_values(tx_ids.len(), 1) crate::repeat_values(tx_ids.len(), 1)
), ),
&(tx_ids &(tx_ids
.iter() .iter()
@ -109,7 +109,7 @@ fn reversed_terms_for(
) -> Result<Vec<TermWithoutTempIds>> { ) -> Result<Vec<TermWithoutTempIds>> {
let mut stmt = conn.prepare("SELECT e, a, v, value_type_tag, tx, added FROM timelined_transactions WHERE tx = ? AND timeline = ? ORDER BY tx DESC")?; let mut stmt = conn.prepare("SELECT e, a, v, value_type_tag, tx, added FROM timelined_transactions WHERE tx = ? AND timeline = ? ORDER BY tx DESC")?;
let rows = stmt.query_and_then( let rows = stmt.query_and_then(
&[&tx_id, &::TIMELINE_MAIN], &[&tx_id, &crate::TIMELINE_MAIN],
|row| -> Result<TermWithoutTempIds> { |row| -> Result<TermWithoutTempIds> {
let op = if row.get(5)? { let op = if row.get(5)? {
OpType::Retract OpType::Retract
@ -141,7 +141,7 @@ pub fn move_from_main_timeline(
txs_from: RangeFrom<Entid>, txs_from: RangeFrom<Entid>,
new_timeline: Entid, new_timeline: Entid,
) -> Result<(Option<Schema>, PartitionMap)> { ) -> Result<(Option<Schema>, PartitionMap)> {
if new_timeline == ::TIMELINE_MAIN { if new_timeline == crate::TIMELINE_MAIN {
bail!(DbErrorKind::NotYetImplemented( bail!(DbErrorKind::NotYetImplemented(
"Can't move transactions to main timeline".to_string() "Can't move transactions to main timeline".to_string()
)); ));
@ -154,7 +154,7 @@ pub fn move_from_main_timeline(
bail!(DbErrorKind::TimelinesMoveToNonEmpty); bail!(DbErrorKind::TimelinesMoveToNonEmpty);
} }
let txs_to_move = collect_ordered_txs_to_move(conn, txs_from, ::TIMELINE_MAIN)?; let txs_to_move = collect_ordered_txs_to_move(conn, txs_from, crate::TIMELINE_MAIN)?;
let mut last_schema = None; let mut last_schema = None;
for tx_id in &txs_to_move { for tx_id in &txs_to_move {
@ -199,16 +199,16 @@ mod tests {
use std::borrow::Borrow; use std::borrow::Borrow;
use debug::TestConn; use crate::debug::TestConn;
use bootstrap; use crate::bootstrap;
// For convenience during testing. // For convenience during testing.
// Real consumers will perform similar operations when appropriate. // Real consumers will perform similar operations when appropriate.
fn update_conn(conn: &mut TestConn, schema: &Option<Schema>, pmap: &PartitionMap) { fn update_conn(conn: &mut TestConn, schema: &Option<Schema>, pmap: &PartitionMap) {
match schema { match schema {
&Some(ref s) => conn.schema = s.clone(), Some(ref s) => conn.schema = s.clone(),
&None => (), None => (),
}; };
conn.partition_map = pmap.clone(); conn.partition_map = pmap.clone();
} }
@ -241,7 +241,7 @@ mod tests {
assert_matches!(conn.transactions(), "[]"); assert_matches!(conn.transactions(), "[]");
assert_eq!(new_partition_map, partition_map0); assert_eq!(new_partition_map, partition_map0);
conn.partition_map = partition_map0.clone(); conn.partition_map = partition_map0;
let report2 = assert_transact!(conn, t); let report2 = assert_transact!(conn, t);
let partition_map2 = conn.partition_map.clone(); let partition_map2 = conn.partition_map.clone();

View file

@ -49,17 +49,17 @@ use std::borrow::Cow;
use std::collections::{BTreeMap, BTreeSet, VecDeque}; use std::collections::{BTreeMap, BTreeSet, VecDeque};
use std::iter::once; use std::iter::once;
use db; use crate::db;
use db::MentatStoring; use crate::db::MentatStoring;
use db_traits::errors; use crate::entids;
use db_traits::errors::{DbErrorKind, Result}; use crate::internal_types::{
use edn::{InternSet, Keyword};
use entids;
use internal_types::{
replace_lookup_ref, AEVTrie, AddAndRetract, KnownEntidOr, LookupRef, LookupRefOrTempId, replace_lookup_ref, AEVTrie, AddAndRetract, KnownEntidOr, LookupRef, LookupRefOrTempId,
TempIdHandle, TempIdMap, Term, TermWithTempIds, TermWithTempIdsAndLookupRefs, TempIdHandle, TempIdMap, Term, TermWithTempIds, TermWithTempIdsAndLookupRefs,
TermWithoutTempIds, TypedValueOr, TermWithoutTempIds, TypedValueOr,
}; };
use db_traits::errors;
use db_traits::errors::{DbErrorKind, Result};
use edn::{InternSet, Keyword};
use mentat_core::util::Either; use mentat_core::util::Either;
@ -67,15 +67,15 @@ use core_traits::{attribute, now, Attribute, Entid, KnownEntid, TypedValue, Valu
use mentat_core::{DateTime, Schema, TxReport, Utc}; use mentat_core::{DateTime, Schema, TxReport, Utc};
use crate::metadata;
use crate::schema::SchemaBuilding;
use crate::tx_checking;
use crate::types::{AVMap, AVPair, PartitionMap, TransactableValue};
use crate::upsert_resolution::{FinalPopulations, Generation};
use crate::watcher::TransactWatcher;
use edn::entities as entmod; use edn::entities as entmod;
use edn::entities::{AttributePlace, Entity, OpType, TempId}; use edn::entities::{AttributePlace, Entity, OpType, TempId};
use metadata;
use rusqlite; use rusqlite;
use schema::SchemaBuilding;
use tx_checking;
use types::{AVMap, AVPair, PartitionMap, TransactableValue};
use upsert_resolution::{FinalPopulations, Generation};
use watcher::TransactWatcher;
/// Defines transactor's high level behaviour. /// Defines transactor's high level behaviour.
pub(crate) enum TransactorAction { pub(crate) enum TransactorAction {
@ -1058,6 +1058,7 @@ where
) )
} }
#[allow(clippy::too_many_arguments)]
pub(crate) fn transact_terms_with_action<'conn, 'a, I, W>( pub(crate) fn transact_terms_with_action<'conn, 'a, I, W>(
conn: &'conn rusqlite::Connection, conn: &'conn rusqlite::Connection,
partition_map: PartitionMap, partition_map: PartitionMap,

View file

@ -14,7 +14,7 @@ use core_traits::{Entid, TypedValue, ValueType};
use db_traits::errors::CardinalityConflict; use db_traits::errors::CardinalityConflict;
use internal_types::AEVTrie; use crate::internal_types::AEVTrie;
/// Map from found [e a v] to expected type. /// Map from found [e a v] to expected type.
pub(crate) type TypeDisagreements = BTreeMap<(Entid, Entid, TypedValue), ValueType>; pub(crate) type TypeDisagreements = BTreeMap<(Entid, Entid, TypedValue), ValueType>;

View file

@ -24,11 +24,12 @@ use edn::entities::OpType;
use db_traits::errors::Result; use db_traits::errors::Result;
use types::AttributeSet; use crate::types::AttributeSet;
use watcher::TransactWatcher; use crate::watcher::TransactWatcher;
pub struct TxObserver { pub struct TxObserver {
#[allow(clippy::type_complexity)]
notify_fn: Arc<Box<dyn Fn(&str, IndexMap<&Entid, &AttributeSet>) + Send + Sync>>, notify_fn: Arc<Box<dyn Fn(&str, IndexMap<&Entid, &AttributeSet>) + Send + Sync>>,
attributes: AttributeSet, attributes: AttributeSet,
} }
@ -131,6 +132,7 @@ impl TxObservationService {
} }
let executor = self.executor.get_or_insert_with(|| { let executor = self.executor.get_or_insert_with(|| {
#[allow(clippy::type_complexity)]
let (tx, rx): ( let (tx, rx): (
Sender<Box<dyn Command + Send>>, Sender<Box<dyn Command + Send>>,
Receiver<Box<dyn Command + Send>>, Receiver<Box<dyn Command + Send>>,

View file

@ -18,19 +18,19 @@ use std::collections::{BTreeMap, BTreeSet};
use indexmap; use indexmap;
use petgraph::unionfind; use petgraph::unionfind;
use db_traits::errors::{DbErrorKind, Result}; use crate::internal_types::{
use internal_types::{
Population, TempIdHandle, TempIdMap, Term, TermWithTempIds, TermWithoutTempIds, TypedValueOr, Population, TempIdHandle, TempIdMap, Term, TermWithTempIds, TermWithoutTempIds, TypedValueOr,
}; };
use types::AVPair; use crate::types::AVPair;
use db_traits::errors::{DbErrorKind, Result};
use mentat_core::util::Either::*; use mentat_core::util::Either::*;
use core_traits::{attribute, Attribute, Entid, TypedValue}; use core_traits::{attribute, Attribute, Entid, TypedValue};
use crate::schema::SchemaBuilding;
use edn::entities::OpType; use edn::entities::OpType;
use mentat_core::Schema; use mentat_core::Schema;
use schema::SchemaBuilding;
/// A "Simple upsert" that looks like [:db/add TEMPID a v], where a is :db.unique/identity. /// A "Simple upsert" that looks like [:db/add TEMPID a v], where a is :db.unique/identity.
#[derive(Clone, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)] #[derive(Clone, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)]

View file

@ -12,8 +12,8 @@ readme = "./README.md"
[dependencies] [dependencies]
chrono = "~0.4" chrono = "~0.4"
itertools = "~0.9" itertools = "~0.9"
num = "~0.2" num = "~0.3"
ordered-float = "~1.0" ordered-float = "~2.0"
pretty = "~0.10" pretty = "~0.10"
uuid = { version = "~0.8", features = ["v4", "serde"] } uuid = { version = "~0.8", features = ["v4", "serde"] }
serde = { version = "~1.0", optional = true } serde = { version = "~1.0", optional = true }

View file

@ -13,11 +13,11 @@
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::fmt; use std::fmt;
use value_rc::ValueRc; use crate::value_rc::ValueRc;
use symbols::{Keyword, PlainSymbol}; use crate::symbols::{Keyword, PlainSymbol};
use types::ValueAndSpan; use crate::types::ValueAndSpan;
/// `EntityPlace` and `ValuePlace` embed values, either directly (i.e., `ValuePlace::Atom`) or /// `EntityPlace` and `ValuePlace` embed values, either directly (i.e., `ValuePlace::Atom`) or
/// indirectly (i.e., `EntityPlace::LookupRef`). In order to maintain the graph of `Into` and /// indirectly (i.e., `EntityPlace::LookupRef`). In order to maintain the graph of `Into` and

View file

@ -14,7 +14,7 @@ use std::collections::HashSet;
use std::hash::Hash; use std::hash::Hash;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use ValueRc; use crate::ValueRc;
/// An `InternSet` allows to "intern" some potentially large values, maintaining a single value /// An `InternSet` allows to "intern" some potentially large values, maintaining a single value
/// instance owned by the `InternSet` and leaving consumers with lightweight ref-counted handles to /// instance owned by the `InternSet` and leaving consumers with lightweight ref-counted handles to

View file

@ -25,7 +25,7 @@ extern crate serde_derive;
pub mod entities; pub mod entities;
pub mod intern_set; pub mod intern_set;
pub use intern_set::InternSet; pub use crate::intern_set::InternSet;
// Intentionally not pub. // Intentionally not pub.
pub mod matcher; pub mod matcher;
mod namespaceable_name; mod namespaceable_name;
@ -35,7 +35,7 @@ pub mod symbols;
pub mod types; pub mod types;
pub mod utils; pub mod utils;
pub mod value_rc; pub mod value_rc;
pub use value_rc::{Cloned, FromRc, ValueRc}; pub use crate::value_rc::{Cloned, FromRc, ValueRc};
// Re-export the types we use. // Re-export the types we use.
pub use chrono::{DateTime, Utc}; pub use chrono::{DateTime, Utc};
@ -44,11 +44,11 @@ pub use ordered_float::OrderedFloat;
pub use uuid::Uuid; pub use uuid::Uuid;
// Export from our modules. // Export from our modules.
pub use types::{ pub use crate::types::{
FromMicros, FromMillis, Span, SpannedValue, ToMicros, ToMillis, Value, ValueAndSpan, FromMicros, FromMillis, Span, SpannedValue, ToMicros, ToMillis, Value, ValueAndSpan,
}; };
pub use symbols::{Keyword, NamespacedSymbol, PlainSymbol}; pub use crate::symbols::{Keyword, NamespacedSymbol, PlainSymbol};
use std::collections::{BTreeMap, BTreeSet, LinkedList}; use std::collections::{BTreeMap, BTreeSet, LinkedList};
use std::f64::{INFINITY, NAN, NEG_INFINITY}; use std::f64::{INFINITY, NAN, NEG_INFINITY};
@ -56,8 +56,8 @@ use std::iter::FromIterator;
use chrono::TimeZone; use chrono::TimeZone;
use entities::*; use crate::entities::*;
use query::FromValue; use crate::query::FromValue;
// Goal: Be able to parse https://github.com/edn-format/edn // Goal: Be able to parse https://github.com/edn-format/edn
// Also extensible to help parse http://docs.datomic.com/query.html // Also extensible to help parse http://docs.datomic.com/query.html
@ -311,7 +311,7 @@ peg::parser!(pub grammar parse() for str {
/ __ v:atom() __ { ValuePlace::Atom(v) } / __ v:atom() __ { ValuePlace::Atom(v) }
pub rule entity() -> Entity<ValueAndSpan> pub rule entity() -> Entity<ValueAndSpan>
= __ "[" __ op:(op()) __ e:(entity_place()) __ a:(forward_entid()) __ v:(value_place()) __ "]" __ { Entity::AddOrRetract { op, e: e, a: AttributePlace::Entid(a), v: v } } = __ "[" __ op:(op()) __ e:(entity_place()) __ a:(forward_entid()) __ v:(value_place()) __ "]" __ { Entity::AddOrRetract { op, e, a: AttributePlace::Entid(a), v } }
/ __ "[" __ op:(op()) __ e:(value_place()) __ a:(backward_entid()) __ v:(entity_place()) __ "]" __ { Entity::AddOrRetract { op, e: v, a: AttributePlace::Entid(a), v: e } } / __ "[" __ op:(op()) __ e:(value_place()) __ a:(backward_entid()) __ v:(entity_place()) __ "]" __ { Entity::AddOrRetract { op, e: v, a: AttributePlace::Entid(a), v: e } }
/ __ map:map_notation() __ { Entity::MapNotation(map) } / __ map:map_notation() __ { Entity::MapNotation(map) }
/ expected!("entity") / expected!("entity")
@ -353,7 +353,7 @@ peg::parser!(pub grammar parse() for str {
query::PullAttributeSpec::Attribute( query::PullAttributeSpec::Attribute(
query::NamedPullAttribute { query::NamedPullAttribute {
attribute, attribute,
alias: alias, alias,
}) })
} }
@ -470,7 +470,7 @@ peg::parser!(pub grammar parse() for str {
query::WhereClause::Pred( query::WhereClause::Pred(
query::Predicate { query::Predicate {
operator: func.0, operator: func.0,
args: args, args,
}) })
} }
@ -479,7 +479,7 @@ peg::parser!(pub grammar parse() for str {
query::WhereClause::WhereFn( query::WhereClause::WhereFn(
query::WhereFn { query::WhereFn {
operator: func.0, operator: func.0,
args: args, args,
binding, binding,
}) })
} }

View file

@ -12,8 +12,8 @@ use itertools::diff_with;
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::HashMap; use std::collections::HashMap;
use symbols; use crate::symbols;
use types::Value; use crate::types::Value;
/// A trait defining pattern matching rules for any given pattern of type `T`. /// A trait defining pattern matching rules for any given pattern of type `T`.
trait PatternMatchingRules<'a, T> { trait PatternMatchingRules<'a, T> {
@ -87,7 +87,7 @@ impl<'a> Matcher<'a> {
where where
T: PatternMatchingRules<'a, Value>, T: PatternMatchingRules<'a, Value>,
{ {
use Value::*; use crate::Value::*;
if T::matches_any(pattern) { if T::matches_any(pattern) {
true true
@ -140,7 +140,7 @@ impl Value {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use parse; use crate::parse;
macro_rules! assert_match { macro_rules! assert_match {
( $pattern:tt, $value:tt, $expected:expr ) => { ( $pattern:tt, $value:tt, $expected:expr ) => {

View file

@ -309,17 +309,6 @@ mod test {
arr.sort(); arr.sort();
assert_eq!( assert_eq!(arr, [n0, n2, n1, n3, n4, n5, n6,]);
arr,
[
n0.clone(),
n2.clone(),
n1.clone(),
n3.clone(),
n4.clone(),
n5.clone(),
n6.clone(),
]
);
} }
} }

View file

@ -16,7 +16,7 @@ use pretty;
use std::borrow::Cow; use std::borrow::Cow;
use std::io; use std::io;
use types::Value; use crate::types::Value;
impl Value { impl Value {
/// Return a pretty string representation of this `Value`. /// Return a pretty string representation of this `Value`.
@ -110,7 +110,7 @@ impl Value {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use parse; use crate::parse;
#[test] #[test]
fn test_pp_io() { fn test_pp_io() {

View file

@ -35,11 +35,11 @@ use std;
use std::fmt; use std::fmt;
use std::rc::Rc; use std::rc::Rc;
use {BigInt, DateTime, OrderedFloat, Utc, Uuid}; use crate::{BigInt, DateTime, OrderedFloat, Utc, Uuid};
use value_rc::{FromRc, ValueRc}; use crate::value_rc::{FromRc, ValueRc};
pub use {Keyword, PlainSymbol}; pub use crate::{Keyword, PlainSymbol};
pub type SrcVarName = String; // Do not include the required syntactic '$'. pub type SrcVarName = String; // Do not include the required syntactic '$'.
@ -64,15 +64,15 @@ impl Variable {
} }
pub trait FromValue<T> { pub trait FromValue<T> {
fn from_value(v: &::ValueAndSpan) -> Option<T>; fn from_value(v: &crate::ValueAndSpan) -> Option<T>;
} }
/// If the provided EDN value is a PlainSymbol beginning with '?', return /// If the provided EDN value is a PlainSymbol beginning with '?', return
/// it wrapped in a Variable. If not, return None. /// it wrapped in a Variable. If not, return None.
/// TODO: intern strings. #398. /// TODO: intern strings. #398.
impl FromValue<Variable> for Variable { impl FromValue<Variable> for Variable {
fn from_value(v: &::ValueAndSpan) -> Option<Variable> { fn from_value(v: &crate::ValueAndSpan) -> Option<Variable> {
if let ::SpannedValue::PlainSymbol(ref s) = v.inner { if let crate::SpannedValue::PlainSymbol(ref s) = v.inner {
Variable::from_symbol(s) Variable::from_symbol(s)
} else { } else {
None None
@ -115,8 +115,8 @@ impl std::fmt::Display for Variable {
pub struct QueryFunction(pub PlainSymbol); pub struct QueryFunction(pub PlainSymbol);
impl FromValue<QueryFunction> for QueryFunction { impl FromValue<QueryFunction> for QueryFunction {
fn from_value(v: &::ValueAndSpan) -> Option<QueryFunction> { fn from_value(v: &crate::ValueAndSpan) -> Option<QueryFunction> {
if let ::SpannedValue::PlainSymbol(ref s) = v.inner { if let crate::SpannedValue::PlainSymbol(ref s) = v.inner {
QueryFunction::from_symbol(s) QueryFunction::from_symbol(s)
} else { } else {
None None
@ -154,8 +154,8 @@ pub enum SrcVar {
} }
impl FromValue<SrcVar> for SrcVar { impl FromValue<SrcVar> for SrcVar {
fn from_value(v: &::ValueAndSpan) -> Option<SrcVar> { fn from_value(v: &crate::ValueAndSpan) -> Option<SrcVar> {
if let ::SpannedValue::PlainSymbol(ref s) = v.inner { if let crate::SpannedValue::PlainSymbol(ref s) = v.inner {
SrcVar::from_symbol(s) SrcVar::from_symbol(s)
} else { } else {
None None
@ -213,8 +213,8 @@ pub enum FnArg {
} }
impl FromValue<FnArg> for FnArg { impl FromValue<FnArg> for FnArg {
fn from_value(v: &::ValueAndSpan) -> Option<FnArg> { fn from_value(v: &crate::ValueAndSpan) -> Option<FnArg> {
use SpannedValue::*; use crate::SpannedValue::*;
match v.inner { match v.inner {
Integer(x) => Some(FnArg::EntidOrInteger(x)), Integer(x) => Some(FnArg::EntidOrInteger(x)),
PlainSymbol(ref x) if x.is_src_symbol() => SrcVar::from_symbol(x).map(FnArg::SrcVar), PlainSymbol(ref x) if x.is_src_symbol() => SrcVar::from_symbol(x).map(FnArg::SrcVar),
@ -316,16 +316,16 @@ impl PatternNonValuePlace {
} }
impl FromValue<PatternNonValuePlace> for PatternNonValuePlace { impl FromValue<PatternNonValuePlace> for PatternNonValuePlace {
fn from_value(v: &::ValueAndSpan) -> Option<PatternNonValuePlace> { fn from_value(v: &crate::ValueAndSpan) -> Option<PatternNonValuePlace> {
match v.inner { match v.inner {
::SpannedValue::Integer(x) => { crate::SpannedValue::Integer(x) => {
if x >= 0 { if x >= 0 {
Some(PatternNonValuePlace::Entid(x)) Some(PatternNonValuePlace::Entid(x))
} else { } else {
None None
} }
} }
::SpannedValue::PlainSymbol(ref x) => { crate::SpannedValue::PlainSymbol(ref x) => {
if x.0.as_str() == "_" { if x.0.as_str() == "_" {
Some(PatternNonValuePlace::Placeholder) Some(PatternNonValuePlace::Placeholder)
} else if let Some(v) = Variable::from_symbol(x) { } else if let Some(v) = Variable::from_symbol(x) {
@ -334,7 +334,7 @@ impl FromValue<PatternNonValuePlace> for PatternNonValuePlace {
None None
} }
} }
::SpannedValue::Keyword(ref x) => Some(x.clone().into()), crate::SpannedValue::Keyword(ref x) => Some(x.clone().into()),
_ => None, _ => None,
} }
} }
@ -371,45 +371,45 @@ impl From<Keyword> for PatternValuePlace {
} }
impl FromValue<PatternValuePlace> for PatternValuePlace { impl FromValue<PatternValuePlace> for PatternValuePlace {
fn from_value(v: &::ValueAndSpan) -> Option<PatternValuePlace> { fn from_value(v: &crate::ValueAndSpan) -> Option<PatternValuePlace> {
match v.inner { match v.inner {
::SpannedValue::Integer(x) => Some(PatternValuePlace::EntidOrInteger(x)), crate::SpannedValue::Integer(x) => Some(PatternValuePlace::EntidOrInteger(x)),
::SpannedValue::PlainSymbol(ref x) if x.0.as_str() == "_" => { crate::SpannedValue::PlainSymbol(ref x) if x.0.as_str() == "_" => {
Some(PatternValuePlace::Placeholder) Some(PatternValuePlace::Placeholder)
} }
::SpannedValue::PlainSymbol(ref x) => { crate::SpannedValue::PlainSymbol(ref x) => {
Variable::from_symbol(x).map(PatternValuePlace::Variable) Variable::from_symbol(x).map(PatternValuePlace::Variable)
} }
::SpannedValue::Keyword(ref x) if x.is_namespaced() => Some(x.clone().into()), crate::SpannedValue::Keyword(ref x) if x.is_namespaced() => Some(x.clone().into()),
::SpannedValue::Boolean(x) => { crate::SpannedValue::Boolean(x) => {
Some(PatternValuePlace::Constant(NonIntegerConstant::Boolean(x))) Some(PatternValuePlace::Constant(NonIntegerConstant::Boolean(x)))
} }
::SpannedValue::Float(x) => { crate::SpannedValue::Float(x) => {
Some(PatternValuePlace::Constant(NonIntegerConstant::Float(x))) Some(PatternValuePlace::Constant(NonIntegerConstant::Float(x)))
} }
::SpannedValue::BigInteger(ref x) => Some(PatternValuePlace::Constant( crate::SpannedValue::BigInteger(ref x) => Some(PatternValuePlace::Constant(
NonIntegerConstant::BigInteger(x.clone()), NonIntegerConstant::BigInteger(x.clone()),
)), )),
::SpannedValue::Instant(x) => { crate::SpannedValue::Instant(x) => {
Some(PatternValuePlace::Constant(NonIntegerConstant::Instant(x))) Some(PatternValuePlace::Constant(NonIntegerConstant::Instant(x)))
} }
::SpannedValue::Text(ref x) => crate::SpannedValue::Text(ref x) =>
// TODO: intern strings. #398. // TODO: intern strings. #398.
{ {
Some(PatternValuePlace::Constant(x.clone().into())) Some(PatternValuePlace::Constant(x.clone().into()))
} }
::SpannedValue::Uuid(ref u) => { crate::SpannedValue::Uuid(ref u) => {
Some(PatternValuePlace::Constant(NonIntegerConstant::Uuid(*u))) Some(PatternValuePlace::Constant(NonIntegerConstant::Uuid(*u)))
} }
// These don't appear in queries. // These don't appear in queries.
::SpannedValue::Nil => None, crate::SpannedValue::Nil => None,
::SpannedValue::NamespacedSymbol(_) => None, crate::SpannedValue::NamespacedSymbol(_) => None,
::SpannedValue::Keyword(_) => None, // … yet. crate::SpannedValue::Keyword(_) => None, // … yet.
::SpannedValue::Map(_) => None, crate::SpannedValue::Map(_) => None,
::SpannedValue::List(_) => None, crate::SpannedValue::List(_) => None,
::SpannedValue::Set(_) => None, crate::SpannedValue::Set(_) => None,
::SpannedValue::Vector(_) => None, crate::SpannedValue::Vector(_) => None,
} }
} }
} }
@ -882,10 +882,7 @@ pub enum UnifyVars {
impl WhereClause { impl WhereClause {
pub fn is_pattern(&self) -> bool { pub fn is_pattern(&self) -> bool {
match self { matches!(self, WhereClause::Pattern(_))
WhereClause::Pattern(_) => true,
_ => false,
}
} }
} }

View file

@ -10,7 +10,7 @@
use std::fmt::{Display, Formatter, Write}; use std::fmt::{Display, Formatter, Write};
use namespaceable_name::NamespaceableName; use crate::namespaceable_name::NamespaceableName;
#[macro_export] #[macro_export]
macro_rules! ns_keyword { macro_rules! ns_keyword {

View file

@ -25,7 +25,7 @@ use num::BigInt;
use ordered_float::OrderedFloat; use ordered_float::OrderedFloat;
use uuid::Uuid; use uuid::Uuid;
use symbols; use crate::symbols;
/// Value represents one of the allowed values in an EDN string. /// Value represents one of the allowed values in an EDN string.
#[derive(PartialEq, Eq, Hash, Clone, Debug)] #[derive(PartialEq, Eq, Hash, Clone, Debug)]
@ -139,7 +139,7 @@ impl Value {
/// But right now, it's used in the bootstrapper. We'll fix that soon. /// But right now, it's used in the bootstrapper. We'll fix that soon.
pub fn with_spans(self) -> ValueAndSpan { pub fn with_spans(self) -> ValueAndSpan {
let s = self.to_pretty(120).unwrap(); let s = self.to_pretty(120).unwrap();
use parse; use crate::parse;
let with_spans = parse::value(&s).unwrap(); let with_spans = parse::value(&s).unwrap();
assert_eq!(self, with_spans.clone().without_spans()); assert_eq!(self, with_spans.clone().without_spans());
with_spans with_spans
@ -209,10 +209,7 @@ macro_rules! def_from_option {
macro_rules! def_is { macro_rules! def_is {
($name: ident, $pat: pat) => { ($name: ident, $pat: pat) => {
pub fn $name(&self) -> bool { pub fn $name(&self) -> bool {
match *self { matches!(*self, $pat)
$pat => true,
_ => false,
}
} }
}; };
} }
@ -707,7 +704,7 @@ mod test {
use std::f64; use std::f64;
use std::iter::FromIterator; use std::iter::FromIterator;
use parse; use crate::parse;
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use num::BigInt; use num::BigInt;
@ -740,12 +737,12 @@ mod test {
fn test_print_edn() { fn test_print_edn() {
assert_eq!("1234N", Value::from_bigint("1234").unwrap().to_string()); assert_eq!("1234N", Value::from_bigint("1234").unwrap().to_string());
let string = "[ 1 2 ( 3.14 ) #{ 4N } { foo/bar 42 :baz/boz 43 } [ ] :five :six/seven eight nine/ten true false nil #f NaN #f -Infinity #f +Infinity ]"; let string = "[ 1 2 ( 7.14 ) #{ 4N } { foo/bar 42 :baz/boz 43 } [ ] :five :six/seven eight nine/ten true false nil #f NaN #f -Infinity #f +Infinity ]";
let data = Value::Vector(vec![ let data = Value::Vector(vec![
Value::Integer(1), Value::Integer(1),
Value::Integer(2), Value::Integer(2),
Value::List(LinkedList::from_iter(vec![Value::from_float(3.14)])), Value::List(LinkedList::from_iter(vec![Value::from_float(7.14)])),
Value::Set(BTreeSet::from_iter(vec![Value::from_bigint("4").unwrap()])), Value::Set(BTreeSet::from_iter(vec![Value::from_bigint("4").unwrap()])),
Value::Map(BTreeMap::from_iter(vec![ Value::Map(BTreeMap::from_iter(vec![
(Value::from_symbol("foo", "bar"), Value::Integer(42)), (Value::from_symbol("foo", "bar"), Value::Integer(42)),
@ -847,10 +844,10 @@ mod test {
assert!(n_v.clone().into_keyword().is_some()); assert!(n_v.clone().into_keyword().is_some());
assert!(n_v.clone().into_plain_keyword().is_none()); assert!(n_v.clone().into_plain_keyword().is_none());
assert!(n_v.clone().into_namespaced_keyword().is_some()); assert!(n_v.into_namespaced_keyword().is_some());
assert!(p_v.clone().into_keyword().is_some()); assert!(p_v.clone().into_keyword().is_some());
assert!(p_v.clone().into_plain_keyword().is_some()); assert!(p_v.clone().into_plain_keyword().is_some());
assert!(p_v.clone().into_namespaced_keyword().is_none()); assert!(p_v.into_namespaced_keyword().is_none());
} }
} }

View file

@ -10,7 +10,7 @@
#![allow(dead_code)] #![allow(dead_code)]
use types::Value; use crate::types::Value;
/// Merge the EDN `Value::Map` instance `right` into `left`. Returns `None` if either `left` or /// Merge the EDN `Value::Map` instance `right` into `left`. Returns `None` if either `left` or
/// `right` is not a `Value::Map`. /// `right` is not a `Value::Map`.

View file

@ -1497,7 +1497,7 @@ macro_rules! def_test_into_type {
} }
#[test] #[test]
#[cfg_attr(feature = "cargo-clippy", allow(float_cmp))] #[cfg_attr(feature = "cargo-clippy", allow(clippy::float_cmp, clippy::unit_cmp))]
fn test_is_and_as_type_helper_functions() { fn test_is_and_as_type_helper_functions() {
let max_i64 = i64::max_value().to_bigint().unwrap(); let max_i64 = i64::max_value().to_bigint().unwrap();
let bigger = &max_i64 * &max_i64; let bigger = &max_i64 * &max_i64;

View file

@ -176,6 +176,8 @@ pub unsafe extern "C" fn store_open(uri: *const c_char, error: *mut ExternError)
} }
/// Variant of store_open that opens an encrypted database. /// Variant of store_open that opens an encrypted database.
/// # Safety
/// Be afraid... TODO
#[cfg(feature = "sqlcipher")] #[cfg(feature = "sqlcipher")]
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn store_open_encrypted( pub unsafe extern "C" fn store_open_encrypted(
@ -246,6 +248,7 @@ pub unsafe extern "C" fn in_progress_transact<'m>(
/// Commit all the transacts that have been performed using this /// Commit all the transacts that have been performed using this
/// in progress transaction. /// in progress transaction.
/// ///
/// # Safety
/// TODO: Document the errors that can result from transact /// TODO: Document the errors that can result from transact
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn in_progress_commit<'m>( pub unsafe extern "C" fn in_progress_commit<'m>(
@ -260,6 +263,7 @@ pub unsafe extern "C" fn in_progress_commit<'m>(
/// Rolls back all the transacts that have been performed using this /// Rolls back all the transacts that have been performed using this
/// in progress transaction. /// in progress transaction.
/// ///
/// # Safety
/// TODO: Document the errors that can result from rollback /// TODO: Document the errors that can result from rollback
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn in_progress_rollback<'m>( pub unsafe extern "C" fn in_progress_rollback<'m>(
@ -342,7 +346,7 @@ pub unsafe extern "C" fn store_in_progress_builder<'a, 'c>(
let store = &mut *store; let store = &mut *store;
let result = store let result = store
.begin_transaction() .begin_transaction()
.and_then(|in_progress| Ok(in_progress.builder())); .map(|in_progress| in_progress.builder());
translate_result(result, error) translate_result(result, error)
} }
@ -365,7 +369,7 @@ pub unsafe extern "C" fn store_entity_builder_from_temp_id<'a, 'c>(
let temp_id = c_char_to_string(temp_id); let temp_id = c_char_to_string(temp_id);
let result = store let result = store
.begin_transaction() .begin_transaction()
.and_then(|in_progress| Ok(in_progress.builder().describe_tempid(&temp_id))); .map(|in_progress| in_progress.builder().describe_tempid(&temp_id));
translate_result(result, error) translate_result(result, error)
} }
@ -387,7 +391,7 @@ pub unsafe extern "C" fn store_entity_builder_from_entid<'a, 'c>(
let store = &mut *store; let store = &mut *store;
let result = store let result = store
.begin_transaction() .begin_transaction()
.and_then(|in_progress| Ok(in_progress.builder().describe(KnownEntid(entid)))); .map(|in_progress| in_progress.builder().describe(KnownEntid(entid)));
translate_result(result, error) translate_result(result, error)
} }
@ -399,10 +403,12 @@ pub unsafe extern "C" fn store_entity_builder_from_entid<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/string`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/string`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn in_progress_builder_add_string<'a, 'c>( pub unsafe extern "C" fn in_progress_builder_add_string(
builder: *mut InProgressBuilder<'a, 'c>, builder: *mut InProgressBuilder,
entid: c_longlong, entid: c_longlong,
kw: *const c_char, kw: *const c_char,
value: *const c_char, value: *const c_char,
@ -422,10 +428,13 @@ pub unsafe extern "C" fn in_progress_builder_add_string<'a, 'c>(
/// If `entid` is not present in the store. /// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/long`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/long`.
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 ///
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn in_progress_builder_add_long<'a, 'c>( pub unsafe extern "C" fn in_progress_builder_add_long(
builder: *mut InProgressBuilder<'a, 'c>, builder: *mut InProgressBuilder,
entid: c_longlong, entid: c_longlong,
kw: *const c_char, kw: *const c_char,
value: c_longlong, value: c_longlong,
@ -446,10 +455,13 @@ pub unsafe extern "C" fn in_progress_builder_add_long<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If `value` is not present as an Entid in the store. /// If `value` is not present as an Entid in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/ref`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/ref`.
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 ///
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn in_progress_builder_add_ref<'a, 'c>( pub unsafe extern "C" fn in_progress_builder_add_ref(
builder: *mut InProgressBuilder<'a, 'c>, builder: *mut InProgressBuilder,
entid: c_longlong, entid: c_longlong,
kw: *const c_char, kw: *const c_char,
value: c_longlong, value: c_longlong,
@ -471,10 +483,12 @@ pub unsafe extern "C" fn in_progress_builder_add_ref<'a, 'c>(
/// If `value` is not present as an attribute in the store. /// If `value` is not present as an attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/keyword`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/keyword`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn in_progress_builder_add_keyword<'a, 'c>( pub unsafe extern "C" fn in_progress_builder_add_keyword(
builder: *mut InProgressBuilder<'a, 'c>, builder: *mut InProgressBuilder,
entid: c_longlong, entid: c_longlong,
kw: *const c_char, kw: *const c_char,
value: *const c_char, value: *const c_char,
@ -495,10 +509,12 @@ pub unsafe extern "C" fn in_progress_builder_add_keyword<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/boolean`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/boolean`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn in_progress_builder_add_boolean<'a, 'c>( pub unsafe extern "C" fn in_progress_builder_add_boolean(
builder: *mut InProgressBuilder<'a, 'c>, builder: *mut InProgressBuilder,
entid: c_longlong, entid: c_longlong,
kw: *const c_char, kw: *const c_char,
value: bool, value: bool,
@ -519,10 +535,12 @@ pub unsafe extern "C" fn in_progress_builder_add_boolean<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/double`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/double`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn in_progress_builder_add_double<'a, 'c>( pub unsafe extern "C" fn in_progress_builder_add_double(
builder: *mut InProgressBuilder<'a, 'c>, builder: *mut InProgressBuilder,
entid: c_longlong, entid: c_longlong,
kw: *const c_char, kw: *const c_char,
value: f64, value: f64,
@ -543,10 +561,12 @@ pub unsafe extern "C" fn in_progress_builder_add_double<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/instant`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/instant`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn in_progress_builder_add_timestamp<'a, 'c>( pub unsafe extern "C" fn in_progress_builder_add_timestamp(
builder: *mut InProgressBuilder<'a, 'c>, builder: *mut InProgressBuilder,
entid: c_longlong, entid: c_longlong,
kw: *const c_char, kw: *const c_char,
value: c_longlong, value: c_longlong,
@ -567,10 +587,12 @@ pub unsafe extern "C" fn in_progress_builder_add_timestamp<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/uuid`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/uuid`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn in_progress_builder_add_uuid<'a, 'c>( pub unsafe extern "C" fn in_progress_builder_add_uuid(
builder: *mut InProgressBuilder<'a, 'c>, builder: *mut InProgressBuilder,
entid: c_longlong, entid: c_longlong,
kw: *const c_char, kw: *const c_char,
value: *const [u8; 16], value: *const [u8; 16],
@ -593,10 +615,12 @@ pub unsafe extern "C" fn in_progress_builder_add_uuid<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/string`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/string`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn in_progress_builder_retract_string<'a, 'c>( pub unsafe extern "C" fn in_progress_builder_retract_string(
builder: *mut InProgressBuilder<'a, 'c>, builder: *mut InProgressBuilder,
entid: c_longlong, entid: c_longlong,
kw: *const c_char, kw: *const c_char,
value: *const c_char, value: *const c_char,
@ -617,10 +641,12 @@ pub unsafe extern "C" fn in_progress_builder_retract_string<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/long`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/long`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn in_progress_builder_retract_long<'a, 'c>( pub unsafe extern "C" fn in_progress_builder_retract_long(
builder: *mut InProgressBuilder<'a, 'c>, builder: *mut InProgressBuilder,
entid: c_longlong, entid: c_longlong,
kw: *const c_char, kw: *const c_char,
value: c_longlong, value: c_longlong,
@ -641,10 +667,12 @@ pub unsafe extern "C" fn in_progress_builder_retract_long<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/ref`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/ref`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn in_progress_builder_retract_ref<'a, 'c>( pub unsafe extern "C" fn in_progress_builder_retract_ref(
builder: *mut InProgressBuilder<'a, 'c>, builder: *mut InProgressBuilder,
entid: c_longlong, entid: c_longlong,
kw: *const c_char, kw: *const c_char,
value: c_longlong, value: c_longlong,
@ -665,10 +693,12 @@ pub unsafe extern "C" fn in_progress_builder_retract_ref<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/keyword`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/keyword`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn in_progress_builder_retract_keyword<'a, 'c>( pub unsafe extern "C" fn in_progress_builder_retract_keyword(
builder: *mut InProgressBuilder<'a, 'c>, builder: *mut InProgressBuilder,
entid: c_longlong, entid: c_longlong,
kw: *const c_char, kw: *const c_char,
value: *const c_char, value: *const c_char,
@ -689,10 +719,12 @@ pub unsafe extern "C" fn in_progress_builder_retract_keyword<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/boolean`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/boolean`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn in_progress_builder_retract_boolean<'a, 'c>( pub unsafe extern "C" fn in_progress_builder_retract_boolean(
builder: *mut InProgressBuilder<'a, 'c>, builder: *mut InProgressBuilder,
entid: c_longlong, entid: c_longlong,
kw: *const c_char, kw: *const c_char,
value: bool, value: bool,
@ -713,10 +745,12 @@ pub unsafe extern "C" fn in_progress_builder_retract_boolean<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/double`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/double`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn in_progress_builder_retract_double<'a, 'c>( pub unsafe extern "C" fn in_progress_builder_retract_double(
builder: *mut InProgressBuilder<'a, 'c>, builder: *mut InProgressBuilder,
entid: c_longlong, entid: c_longlong,
kw: *const c_char, kw: *const c_char,
value: f64, value: f64,
@ -737,10 +771,12 @@ pub unsafe extern "C" fn in_progress_builder_retract_double<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/instant`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/instant`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn in_progress_builder_retract_timestamp<'a, 'c>( pub unsafe extern "C" fn in_progress_builder_retract_timestamp(
builder: *mut InProgressBuilder<'a, 'c>, builder: *mut InProgressBuilder,
entid: c_longlong, entid: c_longlong,
kw: *const c_char, kw: *const c_char,
value: c_longlong, value: c_longlong,
@ -761,12 +797,13 @@ pub unsafe extern "C" fn in_progress_builder_retract_timestamp<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/uuid`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/uuid`.
/// ///
/// # Safety
/// TODO:
// TODO don't panic if the UUID is not valid - return result instead. // TODO don't panic if the UUID is not valid - return result instead.
//
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 // TODO Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn in_progress_builder_retract_uuid<'a, 'c>( pub unsafe extern "C" fn in_progress_builder_retract_uuid(
builder: *mut InProgressBuilder<'a, 'c>, builder: *mut InProgressBuilder,
entid: c_longlong, entid: c_longlong,
kw: *const c_char, kw: *const c_char,
value: *const [u8; 16], value: *const [u8; 16],
@ -786,10 +823,12 @@ pub unsafe extern "C" fn in_progress_builder_retract_uuid<'a, 'c>(
/// ///
/// This consumes the builder and the enclosed [InProgress](mentat::InProgress) transaction. /// This consumes the builder and the enclosed [InProgress](mentat::InProgress) transaction.
/// ///
/// # Safety
/// TODO:
// TODO: Document the errors that can result from transact // TODO: Document the errors that can result from transact
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn in_progress_builder_commit<'a, 'c>( pub unsafe extern "C" fn in_progress_builder_commit(
builder: *mut InProgressBuilder<'a, 'c>, builder: *mut InProgressBuilder,
error: *mut ExternError, error: *mut ExternError,
) -> *mut TxReport { ) -> *mut TxReport {
assert_not_null!(builder); assert_not_null!(builder);
@ -828,10 +867,12 @@ pub unsafe extern "C" fn in_progress_builder_transact<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/string`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/string`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn entity_builder_add_string<'a, 'c>( pub unsafe extern "C" fn entity_builder_add_string(
builder: *mut EntityBuilder<InProgressBuilder<'a, 'c>>, builder: *mut EntityBuilder<InProgressBuilder>,
kw: *const c_char, kw: *const c_char,
value: *const c_char, value: *const c_char,
error: *mut ExternError, error: *mut ExternError,
@ -851,10 +892,12 @@ pub unsafe extern "C" fn entity_builder_add_string<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/long`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/long`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn entity_builder_add_long<'a, 'c>( pub unsafe extern "C" fn entity_builder_add_long(
builder: *mut EntityBuilder<InProgressBuilder<'a, 'c>>, builder: *mut EntityBuilder<InProgressBuilder>,
kw: *const c_char, kw: *const c_char,
value: c_longlong, value: c_longlong,
error: *mut ExternError, error: *mut ExternError,
@ -874,10 +917,12 @@ pub unsafe extern "C" fn entity_builder_add_long<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/ref`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/ref`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn entity_builder_add_ref<'a, 'c>( pub unsafe extern "C" fn entity_builder_add_ref(
builder: *mut EntityBuilder<InProgressBuilder<'a, 'c>>, builder: *mut EntityBuilder<InProgressBuilder>,
kw: *const c_char, kw: *const c_char,
value: c_longlong, value: c_longlong,
error: *mut ExternError, error: *mut ExternError,
@ -897,10 +942,12 @@ pub unsafe extern "C" fn entity_builder_add_ref<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/keyword`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/keyword`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn entity_builder_add_keyword<'a, 'c>( pub unsafe extern "C" fn entity_builder_add_keyword(
builder: *mut EntityBuilder<InProgressBuilder<'a, 'c>>, builder: *mut EntityBuilder<InProgressBuilder>,
kw: *const c_char, kw: *const c_char,
value: *const c_char, value: *const c_char,
error: *mut ExternError, error: *mut ExternError,
@ -920,10 +967,12 @@ pub unsafe extern "C" fn entity_builder_add_keyword<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/boolean`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/boolean`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn entity_builder_add_boolean<'a, 'c>( pub unsafe extern "C" fn entity_builder_add_boolean(
builder: *mut EntityBuilder<InProgressBuilder<'a, 'c>>, builder: *mut EntityBuilder<InProgressBuilder>,
kw: *const c_char, kw: *const c_char,
value: bool, value: bool,
error: *mut ExternError, error: *mut ExternError,
@ -943,10 +992,12 @@ pub unsafe extern "C" fn entity_builder_add_boolean<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/double`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/double`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn entity_builder_add_double<'a, 'c>( pub unsafe extern "C" fn entity_builder_add_double(
builder: *mut EntityBuilder<InProgressBuilder<'a, 'c>>, builder: *mut EntityBuilder<InProgressBuilder>,
kw: *const c_char, kw: *const c_char,
value: f64, value: f64,
error: *mut ExternError, error: *mut ExternError,
@ -966,10 +1017,12 @@ pub unsafe extern "C" fn entity_builder_add_double<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/instant`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/instant`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn entity_builder_add_timestamp<'a, 'c>( pub unsafe extern "C" fn entity_builder_add_timestamp(
builder: *mut EntityBuilder<InProgressBuilder<'a, 'c>>, builder: *mut EntityBuilder<InProgressBuilder>,
kw: *const c_char, kw: *const c_char,
value: c_longlong, value: c_longlong,
error: *mut ExternError, error: *mut ExternError,
@ -989,10 +1042,12 @@ pub unsafe extern "C" fn entity_builder_add_timestamp<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/uuid`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/uuid`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn entity_builder_add_uuid<'a, 'c>( pub unsafe extern "C" fn entity_builder_add_uuid(
builder: *mut EntityBuilder<InProgressBuilder<'a, 'c>>, builder: *mut EntityBuilder<InProgressBuilder>,
kw: *const c_char, kw: *const c_char,
value: *const [u8; 16], value: *const [u8; 16],
error: *mut ExternError, error: *mut ExternError,
@ -1014,10 +1069,12 @@ pub unsafe extern "C" fn entity_builder_add_uuid<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/string`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/string`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn entity_builder_retract_string<'a, 'c>( pub unsafe extern "C" fn entity_builder_retract_string(
builder: *mut EntityBuilder<InProgressBuilder<'a, 'c>>, builder: *mut EntityBuilder<InProgressBuilder>,
kw: *const c_char, kw: *const c_char,
value: *const c_char, value: *const c_char,
error: *mut ExternError, error: *mut ExternError,
@ -1037,10 +1094,12 @@ pub unsafe extern "C" fn entity_builder_retract_string<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/long`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/long`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn entity_builder_retract_long<'a, 'c>( pub unsafe extern "C" fn entity_builder_retract_long(
builder: *mut EntityBuilder<InProgressBuilder<'a, 'c>>, builder: *mut EntityBuilder<InProgressBuilder>,
kw: *const c_char, kw: *const c_char,
value: c_longlong, value: c_longlong,
error: *mut ExternError, error: *mut ExternError,
@ -1060,10 +1119,12 @@ pub unsafe extern "C" fn entity_builder_retract_long<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/ref`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/ref`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn entity_builder_retract_ref<'a, 'c>( pub unsafe extern "C" fn entity_builder_retract_ref(
builder: *mut EntityBuilder<InProgressBuilder<'a, 'c>>, builder: *mut EntityBuilder<InProgressBuilder>,
kw: *const c_char, kw: *const c_char,
value: c_longlong, value: c_longlong,
error: *mut ExternError, error: *mut ExternError,
@ -1083,10 +1144,12 @@ pub unsafe extern "C" fn entity_builder_retract_ref<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/keyword`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/keyword`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn entity_builder_retract_keyword<'a, 'c>( pub unsafe extern "C" fn entity_builder_retract_keyword(
builder: *mut EntityBuilder<InProgressBuilder<'a, 'c>>, builder: *mut EntityBuilder<InProgressBuilder>,
kw: *const c_char, kw: *const c_char,
value: *const c_char, value: *const c_char,
error: *mut ExternError, error: *mut ExternError,
@ -1106,10 +1169,12 @@ pub unsafe extern "C" fn entity_builder_retract_keyword<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/boolean`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/boolean`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn entity_builder_retract_boolean<'a, 'c>( pub unsafe extern "C" fn entity_builder_retract_boolean(
builder: *mut EntityBuilder<InProgressBuilder<'a, 'c>>, builder: *mut EntityBuilder<InProgressBuilder>,
kw: *const c_char, kw: *const c_char,
value: bool, value: bool,
error: *mut ExternError, error: *mut ExternError,
@ -1129,10 +1194,12 @@ pub unsafe extern "C" fn entity_builder_retract_boolean<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/double`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/double`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn entity_builder_retract_double<'a, 'c>( pub unsafe extern "C" fn entity_builder_retract_double(
builder: *mut EntityBuilder<InProgressBuilder<'a, 'c>>, builder: *mut EntityBuilder<InProgressBuilder>,
kw: *const c_char, kw: *const c_char,
value: f64, value: f64,
error: *mut ExternError, error: *mut ExternError,
@ -1152,10 +1219,12 @@ pub unsafe extern "C" fn entity_builder_retract_double<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/instant`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/instant`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn entity_builder_retract_timestamp<'a, 'c>( pub unsafe extern "C" fn entity_builder_retract_timestamp(
builder: *mut EntityBuilder<InProgressBuilder<'a, 'c>>, builder: *mut EntityBuilder<InProgressBuilder>,
kw: *const c_char, kw: *const c_char,
value: c_longlong, value: c_longlong,
error: *mut ExternError, error: *mut ExternError,
@ -1175,11 +1244,13 @@ pub unsafe extern "C" fn entity_builder_retract_timestamp<'a, 'c>(
/// If `kw` is not a valid attribute in the store. /// If `kw` is not a valid attribute in the store.
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/uuid`. /// If the `:db/type` of the attribute described by `kw` is not `:db.type/uuid`.
/// ///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703 /// # Safety
// TODO don't panic if the UUID is not valid - return result instead. /// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
// TODO: don't panic if the UUID is not valid - return result instead.
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn entity_builder_retract_uuid<'a, 'c>( pub unsafe extern "C" fn entity_builder_retract_uuid(
builder: *mut EntityBuilder<InProgressBuilder<'a, 'c>>, builder: *mut EntityBuilder<InProgressBuilder>,
kw: *const c_char, kw: *const c_char,
value: *const [u8; 16], value: *const [u8; 16],
error: *mut ExternError, error: *mut ExternError,
@ -1221,10 +1292,12 @@ pub unsafe extern "C" fn entity_builder_transact<'a, 'c>(
/// ///
/// This consumes the builder and the enclosed [InProgress](mentat::InProgress) transaction. /// This consumes the builder and the enclosed [InProgress](mentat::InProgress) transaction.
/// ///
/// # Safety
/// TODO:
/// TODO: Document the errors that can result from transact /// TODO: Document the errors that can result from transact
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn entity_builder_commit<'a, 'c>( pub unsafe extern "C" fn entity_builder_commit(
builder: *mut EntityBuilder<InProgressBuilder<'a, 'c>>, builder: *mut EntityBuilder<InProgressBuilder>,
error: *mut ExternError, error: *mut ExternError,
) -> *mut TxReport { ) -> *mut TxReport {
assert_not_null!(builder); assert_not_null!(builder);
@ -1234,6 +1307,8 @@ pub unsafe extern "C" fn entity_builder_commit<'a, 'c>(
/// Performs a single transaction against the store. /// Performs a single transaction against the store.
/// ///
/// # Safety
/// TODO:
/// TODO: Document the errors that can result from transact /// TODO: Document the errors that can result from transact
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn store_transact( pub unsafe extern "C" fn store_transact(
@ -1253,6 +1328,7 @@ pub unsafe extern "C" fn store_transact(
} }
/// Fetches the `tx_id` for the given [TxReport](mentat::TxReport)`. /// Fetches the `tx_id` for the given [TxReport](mentat::TxReport)`.
/// # Safety
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn tx_report_get_entid(tx_report: *mut TxReport) -> c_longlong { pub unsafe extern "C" fn tx_report_get_entid(tx_report: *mut TxReport) -> c_longlong {
assert_not_null!(tx_report); assert_not_null!(tx_report);
@ -1261,6 +1337,7 @@ pub unsafe extern "C" fn tx_report_get_entid(tx_report: *mut TxReport) -> c_long
} }
/// Fetches the `tx_instant` for the given [TxReport](mentat::TxReport). /// Fetches the `tx_instant` for the given [TxReport](mentat::TxReport).
/// # Safety
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn tx_report_get_tx_instant(tx_report: *mut TxReport) -> c_longlong { pub unsafe extern "C" fn tx_report_get_tx_instant(tx_report: *mut TxReport) -> c_longlong {
assert_not_null!(tx_report); assert_not_null!(tx_report);

View file

@ -14,9 +14,12 @@ pub mod strings {
use mentat::Keyword; use mentat::Keyword;
pub fn c_char_to_string(cchar: *const c_char) -> &'static str { /// # Safety
///
/// This function TODO
pub unsafe fn c_char_to_string(cchar: *const c_char) -> &'static str {
assert!(!cchar.is_null()); assert!(!cchar.is_null());
let c_str = unsafe { CStr::from_ptr(cchar) }; let c_str = CStr::from_ptr(cchar);
c_str.to_str().unwrap_or("") c_str.to_str().unwrap_or("")
} }
@ -29,8 +32,8 @@ pub mod strings {
pub fn kw_from_string(keyword_string: &'static str) -> Keyword { pub fn kw_from_string(keyword_string: &'static str) -> Keyword {
// TODO: validate. The input might not be a keyword! // TODO: validate. The input might not be a keyword!
let attr_name = keyword_string.trim_start_matches(":"); let attr_name = keyword_string.trim_start_matches(':');
let parts: Vec<&str> = attr_name.split("/").collect(); let parts: Vec<&str> = attr_name.split('/').collect();
Keyword::namespaced(parts[0], parts[1]) Keyword::namespaced(parts[0], parts[1])
} }
} }
@ -107,6 +110,8 @@ pub mod error {
/// - If `result` is `Err(e)`, returns a null pointer and stores a string representing the error /// - If `result` is `Err(e)`, returns a null pointer and stores a string representing the error
/// message (which was allocated on the heap and should eventually be freed) into /// message (which was allocated on the heap and should eventually be freed) into
/// `error.message` /// `error.message`
/// # Safety
/// Be afraid... TODO
pub unsafe fn translate_result<T, E>(result: Result<T, E>, error: *mut ExternError) -> *mut T pub unsafe fn translate_result<T, E>(result: Result<T, E>, error: *mut ExternError) -> *mut T
where where
E: Display, E: Display,
@ -133,6 +138,8 @@ pub mod error {
/// - If `result` is `Err(e)`, returns a null pointer and stores a string representing the error /// - If `result` is `Err(e)`, returns a null pointer and stores a string representing the error
/// message (which was allocated on the heap and should eventually be freed) into /// message (which was allocated on the heap and should eventually be freed) into
/// `error.message` /// `error.message`
/// # Safety
/// Be afraid... TODO
pub unsafe fn translate_opt_result<T, E>( pub unsafe fn translate_opt_result<T, E>(
result: Result<Option<T>, E>, result: Result<Option<T>, E>,
error: *mut ExternError, error: *mut ExternError,
@ -155,6 +162,8 @@ pub mod error {
/// Identical to `translate_result`, but with additional type checking for the case that we have /// Identical to `translate_result`, but with additional type checking for the case that we have
/// a `Result<(), E>` (which we're about to drop on the floor). /// a `Result<(), E>` (which we're about to drop on the floor).
/// # Safety
/// Be afraid... TODO
pub unsafe fn translate_void_result<E>(result: Result<(), E>, error: *mut ExternError) pub unsafe fn translate_void_result<E>(result: Result<(), E>, error: *mut ExternError)
where where
E: Display, E: Display,

View file

@ -14,11 +14,11 @@ use mentat_core::{HasSchema, SQLValueType, Schema};
use edn::query::{FnArg, NonIntegerConstant, Variable}; use edn::query::{FnArg, NonIntegerConstant, Variable};
use clauses::ConjoiningClauses; use crate::clauses::ConjoiningClauses;
use query_algebrizer_traits::errors::{AlgebrizerError, Result}; use query_algebrizer_traits::errors::{AlgebrizerError, Result};
use types::EmptyBecause; use crate::types::EmptyBecause;
macro_rules! coerce_to_typed_value { macro_rules! coerce_to_typed_value {
($var: ident, $val: ident, $types: expr, $type: path, $constructor: path) => {{ ($var: ident, $val: ident, $types: expr, $type: path, $constructor: path) => {{

View file

@ -16,16 +16,16 @@ use mentat_core::util::Either;
use edn::query::{Binding, FnArg, NonIntegerConstant, SrcVar, VariableOrPlaceholder, WhereFn}; use edn::query::{Binding, FnArg, NonIntegerConstant, SrcVar, VariableOrPlaceholder, WhereFn};
use clauses::ConjoiningClauses; use crate::clauses::ConjoiningClauses;
use query_algebrizer_traits::errors::{AlgebrizerError, BindingError, Result}; use query_algebrizer_traits::errors::{AlgebrizerError, BindingError, Result};
use types::{ use crate::types::{
Column, ColumnConstraint, DatomsColumn, DatomsTable, EmptyBecause, FulltextColumn, Column, ColumnConstraint, DatomsColumn, DatomsTable, EmptyBecause, FulltextColumn,
QualifiedAlias, QueryValue, SourceAlias, QualifiedAlias, QueryValue, SourceAlias,
}; };
use Known; use crate::Known;
impl ConjoiningClauses { impl ConjoiningClauses {
#[allow(unused_variables)] #[allow(unused_variables)]
@ -311,7 +311,7 @@ mod testing {
use edn::query::{Binding, FnArg, Keyword, PlainSymbol, Variable}; use edn::query::{Binding, FnArg, Keyword, PlainSymbol, Variable};
use clauses::{add_attribute, associate_ident}; use crate::clauses::{add_attribute, associate_ident};
#[test] #[test]
fn test_apply_fulltext() { fn test_apply_fulltext() {

View file

@ -14,15 +14,15 @@ use mentat_core::Schema;
use edn::query::{Binding, FnArg, Variable, VariableOrPlaceholder, WhereFn}; use edn::query::{Binding, FnArg, Variable, VariableOrPlaceholder, WhereFn};
use clauses::{ConjoiningClauses, PushComputed}; use crate::clauses::{ConjoiningClauses, PushComputed};
use clauses::convert::ValueConversion; use crate::clauses::convert::ValueConversion;
use query_algebrizer_traits::errors::{AlgebrizerError, BindingError, Result}; use query_algebrizer_traits::errors::{AlgebrizerError, BindingError, Result};
use types::{ComputedTable, EmptyBecause, SourceAlias, VariableColumn}; use crate::types::{ComputedTable, EmptyBecause, SourceAlias, VariableColumn};
use Known; use crate::Known;
impl ConjoiningClauses { impl ConjoiningClauses {
/// Take a relation: a matrix of values which will successively bind to named variables of /// Take a relation: a matrix of values which will successively bind to named variables of
@ -342,7 +342,7 @@ mod testing {
use edn::query::{Binding, FnArg, Keyword, PlainSymbol, Variable}; use edn::query::{Binding, FnArg, Keyword, PlainSymbol, Variable};
use clauses::{add_attribute, associate_ident}; use crate::clauses::{add_attribute, associate_ident};
#[test] #[test]
fn test_apply_ground() { fn test_apply_ground() {

View file

@ -26,7 +26,7 @@ use edn::query::{Element, FindSpec, Keyword, PatternNonValuePlace, Pull, Variabl
use query_algebrizer_traits::errors::{AlgebrizerError, Result}; use query_algebrizer_traits::errors::{AlgebrizerError, Result};
use types::{ use crate::types::{
Column, ColumnConstraint, ColumnIntersection, ComputedTable, DatomsColumn, DatomsTable, Column, ColumnConstraint, ColumnIntersection, ComputedTable, DatomsColumn, DatomsTable,
EmptyBecause, EvolvedNonValuePlace, EvolvedPattern, EvolvedValuePlace, FulltextColumn, EmptyBecause, EvolvedNonValuePlace, EvolvedPattern, EvolvedValuePlace, FulltextColumn,
PlaceOrEmpty, QualifiedAlias, QueryValue, SourceAlias, TableAlias, PlaceOrEmpty, QualifiedAlias, QueryValue, SourceAlias, TableAlias,
@ -45,11 +45,11 @@ mod ground;
mod tx_log_api; mod tx_log_api;
mod where_fn; mod where_fn;
use validate::{validate_not_join, validate_or_join}; use crate::validate::{validate_not_join, validate_or_join};
pub use self::inputs::QueryInputs; pub use self::inputs::QueryInputs;
use Known; use crate::Known;
trait Contains<K, T> { trait Contains<K, T> {
fn when_contains<F: FnOnce() -> T>(&self, k: &K, f: F) -> Option<T>; fn when_contains<F: FnOnce() -> T>(&self, k: &K, f: F) -> Option<T>;
@ -1227,7 +1227,7 @@ impl PushComputed for Vec<ComputedTable> {
#[cfg(test)] #[cfg(test)]
fn associate_ident(schema: &mut Schema, i: Keyword, e: Entid) { fn associate_ident(schema: &mut Schema, i: Keyword, e: Entid) {
schema.entid_map.insert(e, i.clone()); schema.entid_map.insert(e, i.clone());
schema.ident_map.insert(i.clone(), e); schema.ident_map.insert(i, e);
} }
#[cfg(test)] #[cfg(test)]

View file

@ -10,13 +10,13 @@
use edn::query::{ContainsVariables, NotJoin, UnifyVars}; use edn::query::{ContainsVariables, NotJoin, UnifyVars};
use clauses::ConjoiningClauses; use crate::clauses::ConjoiningClauses;
use query_algebrizer_traits::errors::{AlgebrizerError, Result}; use query_algebrizer_traits::errors::{AlgebrizerError, Result};
use types::{ColumnConstraint, ComputedTable}; use crate::types::{ColumnConstraint, ComputedTable};
use Known; use crate::Known;
impl ConjoiningClauses { impl ConjoiningClauses {
pub(crate) fn apply_not_join(&mut self, known: Known, not_join: NotJoin) -> Result<()> { pub(crate) fn apply_not_join(&mut self, known: Known, not_join: NotJoin) -> Result<()> {
@ -87,16 +87,16 @@ mod testing {
use edn::query::{Keyword, PlainSymbol, Variable}; use edn::query::{Keyword, PlainSymbol, Variable};
use clauses::{add_attribute, associate_ident, QueryInputs}; use crate::clauses::{add_attribute, associate_ident, QueryInputs};
use query_algebrizer_traits::errors::AlgebrizerError; use query_algebrizer_traits::errors::AlgebrizerError;
use types::{ use crate::types::{
ColumnAlternation, ColumnConstraint, ColumnConstraintOrAlternation, ColumnIntersection, ColumnAlternation, ColumnConstraint, ColumnConstraintOrAlternation, ColumnIntersection,
DatomsColumn, DatomsTable, Inequality, QualifiedAlias, QueryValue, SourceAlias, DatomsColumn, DatomsTable, Inequality, QualifiedAlias, QueryValue, SourceAlias,
}; };
use {algebrize, algebrize_with_inputs, parse_find_string}; use crate::{algebrize, algebrize_with_inputs, parse_find_string};
fn alg(schema: &Schema, input: &str) -> ConjoiningClauses { fn alg(schema: &Schema, input: &str) -> ConjoiningClauses {
let known = Known::for_schema(schema); let known = Known::for_schema(schema);
@ -216,26 +216,17 @@ mod testing {
.column_bindings .column_bindings
.insert(vx.clone(), vec![d0e.clone(), d1e.clone(), d2e.clone()]); .insert(vx.clone(), vec![d0e.clone(), d1e.clone(), d2e.clone()]);
subquery.wheres = ColumnIntersection(vec![ subquery.wheres = ColumnIntersection(vec![
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d1a, parent)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d1v, ambar)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d2a, knows.clone())),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d2v, daphne)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d1a.clone(), d0e.clone(),
parent, QueryValue::Column(d1e),
)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d1v.clone(), ambar)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d2a.clone(),
knows.clone(),
)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d2v.clone(),
daphne,
)), )),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d0e.clone(), d0e.clone(),
QueryValue::Column(d1e.clone()), QueryValue::Column(d2e),
)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d0e.clone(),
QueryValue::Column(d2e.clone()),
)), )),
]); ]);
@ -247,14 +238,8 @@ mod testing {
assert_eq!( assert_eq!(
cc.wheres, cc.wheres,
ColumnIntersection(vec![ ColumnIntersection(vec![
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d0a, knows)),
d0a.clone(), ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d0v, john)),
knows.clone()
)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d0v.clone(),
john
)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::NotExists( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::NotExists(
ComputedTable::Subquery(Box::new(subquery)) ComputedTable::Subquery(Box::new(subquery))
)), )),
@ -317,17 +302,14 @@ mod testing {
.column_bindings .column_bindings
.insert(vy.clone(), vec![d0v.clone(), d3v.clone()]); .insert(vy.clone(), vec![d0v.clone(), d3v.clone()]);
subquery.wheres = ColumnIntersection(vec![ subquery.wheres = ColumnIntersection(vec![
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d3a, parent)),
d3a.clone(),
parent,
)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d0e.clone(), d0e.clone(),
QueryValue::Column(d3e.clone()), QueryValue::Column(d3e),
)), )),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d0v.clone(), d0v,
QueryValue::Column(d3v.clone()), QueryValue::Column(d3v),
)), )),
]); ]);
@ -336,24 +318,15 @@ mod testing {
.insert(vx.clone(), ValueTypeSet::of_one(ValueType::Ref)); .insert(vx.clone(), ValueTypeSet::of_one(ValueType::Ref));
subquery subquery
.known_types .known_types
.insert(vy.clone(), ValueTypeSet::of_one(ValueType::String)); .insert(vy, ValueTypeSet::of_one(ValueType::String));
assert!(!cc.is_known_empty()); assert!(!cc.is_known_empty());
let expected_wheres = ColumnIntersection(vec![ let expected_wheres = ColumnIntersection(vec![
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d0a.clone(), knows)), ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d0a, knows)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d1a, age)),
d1a.clone(), ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d1v, eleven)),
age.clone(), ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d2a, name)),
)), ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d2v, john)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d1v.clone(),
eleven,
)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d2a.clone(),
name.clone(),
)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d2v.clone(), john)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::NotExists( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::NotExists(
ComputedTable::Subquery(Box::new(subquery)), ComputedTable::Subquery(Box::new(subquery)),
)), )),
@ -423,29 +396,17 @@ mod testing {
.column_bindings .column_bindings
.insert(vx.clone(), vec![d0e.clone(), d1e.clone(), d2e.clone()]); .insert(vx.clone(), vec![d0e.clone(), d1e.clone(), d2e.clone()]);
subquery.wheres = ColumnIntersection(vec![ subquery.wheres = ColumnIntersection(vec![
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d1a, knows.clone())),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d1v, john)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d2a, knows)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d2v, daphne)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d1a.clone(), d0e.clone(),
knows.clone(), QueryValue::Column(d1e),
)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d1v.clone(),
john.clone(),
)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d2a.clone(),
knows.clone(),
)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d2v.clone(),
daphne.clone(),
)), )),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d0e.clone(), d0e.clone(),
QueryValue::Column(d1e.clone()), QueryValue::Column(d2e),
)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d0e.clone(),
QueryValue::Column(d2e.clone()),
)), )),
]); ]);
@ -457,13 +418,10 @@ mod testing {
assert_eq!( assert_eq!(
cc.wheres, cc.wheres,
ColumnIntersection(vec![ ColumnIntersection(vec![
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d0a, age)),
d0a.clone(),
age.clone()
)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Inequality { ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Inequality {
operator: Inequality::LessThan, operator: Inequality::LessThan,
left: QueryValue::Column(d0v.clone()), left: QueryValue::Column(d0v),
right: QueryValue::TypedValue(TypedValue::Long(30)), right: QueryValue::TypedValue(TypedValue::Long(30)),
}), }),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::NotExists( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::NotExists(
@ -490,7 +448,7 @@ mod testing {
let d0 = "datoms00".to_string(); let d0 = "datoms00".to_string();
let d0e = QualifiedAlias::new(d0.clone(), DatomsColumn::Entity); let d0e = QualifiedAlias::new(d0.clone(), DatomsColumn::Entity);
let d0a = QualifiedAlias::new(d0.clone(), DatomsColumn::Attribute); let d0a = QualifiedAlias::new(d0.clone(), DatomsColumn::Attribute);
let d0v = QualifiedAlias::new(d0.clone(), DatomsColumn::Value); let d0v = QualifiedAlias::new(d0, DatomsColumn::Value);
let d1 = "datoms01".to_string(); let d1 = "datoms01".to_string();
let d1e = QualifiedAlias::new(d1.clone(), DatomsColumn::Entity); let d1e = QualifiedAlias::new(d1.clone(), DatomsColumn::Entity);
@ -534,49 +492,34 @@ mod testing {
]), ]),
ColumnIntersection(vec![ ColumnIntersection(vec![
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d1a.clone(), d1a,
knows.clone(), knows.clone(),
)), )),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d1v, ambar)),
d1v.clone(),
ambar,
)),
]), ]),
])), ])),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d2a, parent)),
d2a.clone(), ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d2v, daphne)),
parent,
)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d2v.clone(),
daphne,
)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d0e.clone(), d0e.clone(),
QueryValue::Column(d1e.clone()), QueryValue::Column(d1e),
)), )),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d0e.clone(), d0e,
QueryValue::Column(d2e.clone()), QueryValue::Column(d2e),
)), )),
]); ]);
subquery subquery
.known_types .known_types
.insert(vx.clone(), ValueTypeSet::of_one(ValueType::Ref)); .insert(vx, ValueTypeSet::of_one(ValueType::Ref));
assert!(!cc.is_known_empty()); assert!(!cc.is_known_empty());
assert_eq!( assert_eq!(
cc.wheres, cc.wheres,
ColumnIntersection(vec![ ColumnIntersection(vec![
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d0a, knows)),
d0a.clone(), ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d0v, bill)),
knows
)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d0v.clone(),
bill
)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::NotExists( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::NotExists(
ComputedTable::Subquery(Box::new(subquery)) ComputedTable::Subquery(Box::new(subquery))
)), )),
@ -611,7 +554,7 @@ mod testing {
let d0 = "datoms00".to_string(); let d0 = "datoms00".to_string();
let d0e = QualifiedAlias::new(d0.clone(), DatomsColumn::Entity); let d0e = QualifiedAlias::new(d0.clone(), DatomsColumn::Entity);
let d0a = QualifiedAlias::new(d0.clone(), DatomsColumn::Attribute); let d0a = QualifiedAlias::new(d0.clone(), DatomsColumn::Attribute);
let d0v = QualifiedAlias::new(d0.clone(), DatomsColumn::Value); let d0v = QualifiedAlias::new(d0, DatomsColumn::Value);
let d1 = "datoms01".to_string(); let d1 = "datoms01".to_string();
let d1e = QualifiedAlias::new(d1.clone(), DatomsColumn::Entity); let d1e = QualifiedAlias::new(d1.clone(), DatomsColumn::Entity);
@ -624,20 +567,17 @@ mod testing {
.column_bindings .column_bindings
.insert(vx.clone(), vec![d0e.clone(), d1e.clone()]); .insert(vx.clone(), vec![d0e.clone(), d1e.clone()]);
subquery.wheres = ColumnIntersection(vec![ subquery.wheres = ColumnIntersection(vec![
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d1a, knows.clone())),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d1v, john)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d1a.clone(), d0e,
knows.clone(), QueryValue::Column(d1e),
)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d1v.clone(), john)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d0e.clone(),
QueryValue::Column(d1e.clone()),
)), )),
]); ]);
subquery subquery
.known_types .known_types
.insert(vx.clone(), ValueTypeSet::of_one(ValueType::Ref)); .insert(vx, ValueTypeSet::of_one(ValueType::Ref));
subquery subquery
.known_types .known_types
.insert(vy.clone(), ValueTypeSet::of_one(ValueType::String)); .insert(vy.clone(), ValueTypeSet::of_one(ValueType::String));
@ -647,20 +587,14 @@ mod testing {
subquery.input_variables = input_vars; subquery.input_variables = input_vars;
subquery subquery
.value_bindings .value_bindings
.insert(vy.clone(), TypedValue::typed_string("John")); .insert(vy, TypedValue::typed_string("John"));
assert!(!cc.is_known_empty()); assert!(!cc.is_known_empty());
assert_eq!( assert_eq!(
cc.wheres, cc.wheres,
ColumnIntersection(vec![ ColumnIntersection(vec![
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d0a, knows)),
d0a.clone(), ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d0v, bill)),
knows
)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d0v.clone(),
bill
)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::NotExists( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::NotExists(
ComputedTable::Subquery(Box::new(subquery)) ComputedTable::Subquery(Box::new(subquery))
)), )),

View file

@ -18,17 +18,17 @@ use edn::query::{
WhereClause, WhereClause,
}; };
use clauses::{ConjoiningClauses, PushComputed}; use crate::clauses::{ConjoiningClauses, PushComputed};
use query_algebrizer_traits::errors::Result; use query_algebrizer_traits::errors::Result;
use types::{ use crate::types::{
ColumnAlternation, ColumnConstraintOrAlternation, ColumnIntersection, ComputedTable, ColumnAlternation, ColumnConstraintOrAlternation, ColumnIntersection, ComputedTable,
DatomsTable, EmptyBecause, EvolvedPattern, PlaceOrEmpty, QualifiedAlias, SourceAlias, DatomsTable, EmptyBecause, EvolvedPattern, PlaceOrEmpty, QualifiedAlias, SourceAlias,
VariableColumn, VariableColumn,
}; };
use Known; use crate::Known;
/// Return true if both left and right are the same variable or both are non-variable. /// Return true if both left and right are the same variable or both are non-variable.
fn _simply_matches_place(left: &PatternNonValuePlace, right: &PatternNonValuePlace) -> bool { fn _simply_matches_place(left: &PatternNonValuePlace, right: &PatternNonValuePlace) -> bool {
@ -750,14 +750,14 @@ mod testing {
use edn::query::{Keyword, Variable}; use edn::query::{Keyword, Variable};
use clauses::{add_attribute, associate_ident}; use crate::clauses::{add_attribute, associate_ident};
use types::{ use crate::types::{
ColumnConstraint, DatomsColumn, DatomsTable, Inequality, QualifiedAlias, QueryValue, ColumnConstraint, DatomsColumn, DatomsTable, Inequality, QualifiedAlias, QueryValue,
SourceAlias, SourceAlias,
}; };
use {algebrize, algebrize_with_counter, parse_find_string}; use crate::{algebrize, algebrize_with_counter, parse_find_string};
fn alg(known: Known, input: &str) -> ConjoiningClauses { fn alg(known: Known, input: &str) -> ConjoiningClauses {
let parsed = parse_find_string(input).expect("parse failed"); let parsed = parse_find_string(input).expect("parse failed");
@ -920,12 +920,10 @@ mod testing {
]), ]),
ColumnIntersection(vec![ ColumnIntersection(vec![
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d0a.clone(), d0a, knows
knows
)), )),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d0v.clone(), d0v, daphne
daphne
)) ))
]), ]),
]) ])
@ -967,10 +965,7 @@ mod testing {
assert_eq!( assert_eq!(
cc.wheres, cc.wheres,
ColumnIntersection(vec![ ColumnIntersection(vec![
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d0a, name)),
d0a.clone(),
name.clone()
)),
ColumnConstraintOrAlternation::Alternation(ColumnAlternation(vec![ ColumnConstraintOrAlternation::Alternation(ColumnAlternation(vec![
ColumnIntersection(vec![ ColumnIntersection(vec![
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
@ -994,12 +989,10 @@ mod testing {
]), ]),
ColumnIntersection(vec![ ColumnIntersection(vec![
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d1a.clone(), d1a, knows
knows
)), )),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d1v.clone(), d1v, daphne
daphne
)) ))
]), ]),
])), ])),
@ -1051,13 +1044,10 @@ mod testing {
assert_eq!( assert_eq!(
cc.wheres, cc.wheres,
ColumnIntersection(vec![ ColumnIntersection(vec![
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d0a, age)),
d0a.clone(),
age.clone()
)),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Inequality { ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Inequality {
operator: Inequality::LessThan, operator: Inequality::LessThan,
left: QueryValue::Column(d0v.clone()), left: QueryValue::Column(d0v),
right: QueryValue::TypedValue(TypedValue::Long(30)), right: QueryValue::TypedValue(TypedValue::Long(30)),
}), }),
ColumnConstraintOrAlternation::Alternation(ColumnAlternation(vec![ ColumnConstraintOrAlternation::Alternation(ColumnAlternation(vec![
@ -1073,12 +1063,10 @@ mod testing {
]), ]),
ColumnIntersection(vec![ ColumnIntersection(vec![
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d1a.clone(), d1a, knows
knows
)), )),
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(
d1v.clone(), d1v, daphne
daphne
)) ))
]), ]),
])), ])),
@ -1124,10 +1112,7 @@ mod testing {
assert_eq!( assert_eq!(
cc.wheres, cc.wheres,
ColumnIntersection(vec![ ColumnIntersection(vec![
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(d0a, knows)),
d0a.clone(),
knows.clone()
)),
// The outer pattern joins against the `or` on the entity, but not value -- ?y means // The outer pattern joins against the `or` on the entity, but not value -- ?y means
// different things in each place. // different things in each place.
ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals( ColumnConstraintOrAlternation::Constraint(ColumnConstraint::Equals(

View file

@ -18,14 +18,14 @@ use edn::query::{
NonIntegerConstant, Pattern, PatternNonValuePlace, PatternValuePlace, SrcVar, Variable, NonIntegerConstant, Pattern, PatternNonValuePlace, PatternValuePlace, SrcVar, Variable,
}; };
use clauses::ConjoiningClauses; use crate::clauses::ConjoiningClauses;
use types::{ use crate::types::{
ColumnConstraint, DatomsColumn, EmptyBecause, EvolvedNonValuePlace, EvolvedPattern, ColumnConstraint, DatomsColumn, EmptyBecause, EvolvedNonValuePlace, EvolvedPattern,
EvolvedValuePlace, PlaceOrEmpty, SourceAlias, EvolvedValuePlace, PlaceOrEmpty, SourceAlias,
}; };
use Known; use crate::Known;
pub fn into_typed_value(nic: NonIntegerConstant) -> TypedValue { pub fn into_typed_value(nic: NonIntegerConstant) -> TypedValue {
match nic { match nic {
@ -696,11 +696,13 @@ mod testing {
use edn::query::{Keyword, Variable}; use edn::query::{Keyword, Variable};
use clauses::{add_attribute, associate_ident, ident, QueryInputs}; use crate::clauses::{add_attribute, associate_ident, ident, QueryInputs};
use types::{Column, ColumnConstraint, DatomsTable, QualifiedAlias, QueryValue, SourceAlias}; use crate::types::{
Column, ColumnConstraint, DatomsTable, QualifiedAlias, QueryValue, SourceAlias,
};
use {algebrize, parse_find_string}; use crate::{algebrize, parse_find_string};
fn alg(schema: &Schema, input: &str) -> ConjoiningClauses { fn alg(schema: &Schema, input: &str) -> ConjoiningClauses {
let parsed = parse_find_string(input).expect("parse failed"); let parsed = parse_find_string(input).expect("parse failed");
@ -795,7 +797,7 @@ mod testing {
assert_eq!(cc.known_type(&x).unwrap(), ValueType::Ref); assert_eq!(cc.known_type(&x).unwrap(), ValueType::Ref);
// ?x is bound to datoms0.e. // ?x is bound to datoms0.e.
assert_eq!(cc.column_bindings.get(&x).unwrap(), &vec![d0_e.clone()]); assert_eq!(cc.column_bindings.get(&x).unwrap(), &vec![d0_e]);
// Our 'where' clauses are two: // Our 'where' clauses are two:
// - datoms0.a = 99 // - datoms0.a = 99
@ -844,7 +846,7 @@ mod testing {
assert_eq!(cc.known_type(&x).unwrap(), ValueType::Ref); assert_eq!(cc.known_type(&x).unwrap(), ValueType::Ref);
// ?x is bound to datoms0.e. // ?x is bound to datoms0.e.
assert_eq!(cc.column_bindings.get(&x).unwrap(), &vec![d0_e.clone()]); assert_eq!(cc.column_bindings.get(&x).unwrap(), &vec![d0_e]);
// Our 'where' clauses are two: // Our 'where' clauses are two:
// - datoms0.v = true // - datoms0.v = true
@ -888,7 +890,7 @@ mod testing {
Pattern { Pattern {
source: None, source: None,
entity: PatternNonValuePlace::Variable(x.clone()), entity: PatternNonValuePlace::Variable(x.clone()),
attribute: PatternNonValuePlace::Variable(a.clone()), attribute: PatternNonValuePlace::Variable(a),
value: PatternValuePlace::Variable(v.clone()), value: PatternValuePlace::Variable(v.clone()),
tx: PatternNonValuePlace::Placeholder, tx: PatternNonValuePlace::Placeholder,
}, },
@ -913,7 +915,7 @@ mod testing {
assert_eq!(cc.known_type(&v), Some(ValueType::Boolean)); assert_eq!(cc.known_type(&v), Some(ValueType::Boolean));
// ?x is bound to datoms0.e. // ?x is bound to datoms0.e.
assert_eq!(cc.column_bindings.get(&x).unwrap(), &vec![d0_e.clone()]); assert_eq!(cc.column_bindings.get(&x).unwrap(), &vec![d0_e]);
assert_eq!( assert_eq!(
cc.wheres, cc.wheres,
vec![ColumnConstraint::Equals(d0_a, QueryValue::Entid(99)),].into() vec![ColumnConstraint::Equals(d0_a, QueryValue::Entid(99)),].into()
@ -938,9 +940,9 @@ mod testing {
known, known,
Pattern { Pattern {
source: None, source: None,
entity: PatternNonValuePlace::Variable(x.clone()), entity: PatternNonValuePlace::Variable(x),
attribute: PatternNonValuePlace::Variable(a.clone()), attribute: PatternNonValuePlace::Variable(a),
value: PatternValuePlace::Variable(v.clone()), value: PatternValuePlace::Variable(v),
tx: PatternNonValuePlace::Placeholder, tx: PatternNonValuePlace::Placeholder,
}, },
); );
@ -967,8 +969,8 @@ mod testing {
Pattern { Pattern {
source: None, source: None,
entity: PatternNonValuePlace::Variable(x.clone()), entity: PatternNonValuePlace::Variable(x.clone()),
attribute: PatternNonValuePlace::Variable(a.clone()), attribute: PatternNonValuePlace::Variable(a),
value: PatternValuePlace::Variable(v.clone()), value: PatternValuePlace::Variable(v),
tx: PatternNonValuePlace::Placeholder, tx: PatternNonValuePlace::Placeholder,
}, },
); );
@ -990,7 +992,7 @@ mod testing {
assert_eq!(cc.known_type(&x).unwrap(), ValueType::Ref); assert_eq!(cc.known_type(&x).unwrap(), ValueType::Ref);
// ?x is bound to datoms0.e. // ?x is bound to datoms0.e.
assert_eq!(cc.column_bindings.get(&x).unwrap(), &vec![d0_e.clone()]); assert_eq!(cc.column_bindings.get(&x).unwrap(), &vec![d0_e]);
assert_eq!(cc.wheres, vec![].into()); assert_eq!(cc.wheres, vec![].into());
} }
@ -1031,7 +1033,7 @@ mod testing {
assert_eq!(cc.known_type(&x).unwrap(), ValueType::Ref); assert_eq!(cc.known_type(&x).unwrap(), ValueType::Ref);
// ?x is bound to datoms0.e. // ?x is bound to datoms0.e.
assert_eq!(cc.column_bindings.get(&x).unwrap(), &vec![d0_e.clone()]); assert_eq!(cc.column_bindings.get(&x).unwrap(), &vec![d0_e]);
// Our 'where' clauses are two: // Our 'where' clauses are two:
// - datoms0.v = 'hello' // - datoms0.v = 'hello'
@ -1093,7 +1095,7 @@ mod testing {
source: None, source: None,
entity: PatternNonValuePlace::Variable(x.clone()), entity: PatternNonValuePlace::Variable(x.clone()),
attribute: ident("foo", "bar"), attribute: ident("foo", "bar"),
value: PatternValuePlace::Variable(y.clone()), value: PatternValuePlace::Variable(y),
tx: PatternNonValuePlace::Placeholder, tx: PatternNonValuePlace::Placeholder,
}, },
); );
@ -1202,7 +1204,7 @@ mod testing {
assert!(!cc.column_bindings.contains_key(&y)); assert!(!cc.column_bindings.contains_key(&y));
// ?x is bound to the entity. // ?x is bound to the entity.
assert_eq!(cc.column_bindings.get(&x).unwrap(), &vec![d0_e.clone()]); assert_eq!(cc.column_bindings.get(&x).unwrap(), &vec![d0_e]);
} }
#[test] #[test]
@ -1237,9 +1239,9 @@ mod testing {
known, known,
Pattern { Pattern {
source: None, source: None,
entity: PatternNonValuePlace::Variable(x.clone()), entity: PatternNonValuePlace::Variable(x),
attribute: ident("foo", "bar"), attribute: ident("foo", "bar"),
value: PatternValuePlace::Variable(y.clone()), value: PatternValuePlace::Variable(y),
tx: PatternNonValuePlace::Placeholder, tx: PatternNonValuePlace::Placeholder,
}, },
); );
@ -1282,9 +1284,9 @@ mod testing {
known, known,
Pattern { Pattern {
source: None, source: None,
entity: PatternNonValuePlace::Variable(x.clone()), entity: PatternNonValuePlace::Variable(x),
attribute: ident("foo", "bar"), attribute: ident("foo", "bar"),
value: PatternValuePlace::Variable(y.clone()), value: PatternValuePlace::Variable(y),
tx: PatternNonValuePlace::Placeholder, tx: PatternNonValuePlace::Placeholder,
}, },
); );
@ -1338,7 +1340,7 @@ mod testing {
known, known,
Pattern { Pattern {
source: None, source: None,
entity: PatternNonValuePlace::Variable(x.clone()), entity: PatternNonValuePlace::Variable(x),
attribute: ident("foo", "bar"), attribute: ident("foo", "bar"),
value: PatternValuePlace::Variable(y.clone()), value: PatternValuePlace::Variable(y.clone()),
tx: PatternNonValuePlace::Placeholder, tx: PatternNonValuePlace::Placeholder,
@ -1352,7 +1354,7 @@ mod testing {
assert_eq!( assert_eq!(
cc.empty_because.unwrap(), cc.empty_because.unwrap(),
EmptyBecause::TypeMismatch { EmptyBecause::TypeMismatch {
var: y.clone(), var: y,
existing: ValueTypeSet::of_one(ValueType::String), existing: ValueTypeSet::of_one(ValueType::String),
desired: ValueTypeSet::of_one(ValueType::Boolean), desired: ValueTypeSet::of_one(ValueType::Boolean),
} }
@ -1389,8 +1391,8 @@ mod testing {
known, known,
Pattern { Pattern {
source: None, source: None,
entity: PatternNonValuePlace::Variable(z.clone()), entity: PatternNonValuePlace::Variable(z),
attribute: PatternNonValuePlace::Variable(y.clone()), attribute: PatternNonValuePlace::Variable(y),
value: PatternValuePlace::Variable(x.clone()), value: PatternValuePlace::Variable(x.clone()),
tx: PatternNonValuePlace::Placeholder, tx: PatternNonValuePlace::Placeholder,
}, },
@ -1403,7 +1405,7 @@ mod testing {
assert_eq!( assert_eq!(
cc.empty_because.unwrap(), cc.empty_because.unwrap(),
EmptyBecause::TypeMismatch { EmptyBecause::TypeMismatch {
var: x.clone(), var: x,
existing: ValueTypeSet::of_one(ValueType::Ref), existing: ValueTypeSet::of_one(ValueType::Ref),
desired: ValueTypeSet::of_one(ValueType::Boolean), desired: ValueTypeSet::of_one(ValueType::Boolean),
} }

View file

@ -14,15 +14,15 @@ use mentat_core::Schema;
use edn::query::{FnArg, PlainSymbol, Predicate, TypeAnnotation}; use edn::query::{FnArg, PlainSymbol, Predicate, TypeAnnotation};
use clauses::ConjoiningClauses; use crate::clauses::ConjoiningClauses;
use clauses::convert::ValueTypes; use crate::clauses::convert::ValueTypes;
use query_algebrizer_traits::errors::{AlgebrizerError, Result}; use query_algebrizer_traits::errors::{AlgebrizerError, Result};
use types::{ColumnConstraint, EmptyBecause, Inequality, QueryValue}; use crate::types::{ColumnConstraint, EmptyBecause, Inequality, QueryValue};
use Known; use crate::Known;
/// Application of predicates. /// Application of predicates.
impl ConjoiningClauses { impl ConjoiningClauses {
@ -206,9 +206,9 @@ mod testing {
FnArg, Keyword, Pattern, PatternNonValuePlace, PatternValuePlace, PlainSymbol, Variable, FnArg, Keyword, Pattern, PatternNonValuePlace, PatternValuePlace, PlainSymbol, Variable,
}; };
use clauses::{add_attribute, associate_ident, ident}; use crate::clauses::{add_attribute, associate_ident, ident};
use types::{ColumnConstraint, EmptyBecause, QueryValue}; use crate::types::{ColumnConstraint, EmptyBecause, QueryValue};
#[test] #[test]
/// Apply two patterns: a pattern and a numeric predicate. /// Apply two patterns: a pattern and a numeric predicate.
@ -235,7 +235,7 @@ mod testing {
known, known,
Pattern { Pattern {
source: None, source: None,
entity: PatternNonValuePlace::Variable(x.clone()), entity: PatternNonValuePlace::Variable(x),
attribute: PatternNonValuePlace::Placeholder, attribute: PatternNonValuePlace::Placeholder,
value: PatternValuePlace::Variable(y.clone()), value: PatternValuePlace::Variable(y.clone()),
tx: PatternNonValuePlace::Placeholder, tx: PatternNonValuePlace::Placeholder,
@ -348,7 +348,7 @@ mod testing {
known, known,
Pattern { Pattern {
source: None, source: None,
entity: PatternNonValuePlace::Variable(x.clone()), entity: PatternNonValuePlace::Variable(x),
attribute: ident("foo", "roz"), attribute: ident("foo", "roz"),
value: PatternValuePlace::Variable(y.clone()), value: PatternValuePlace::Variable(y.clone()),
tx: PatternNonValuePlace::Placeholder, tx: PatternNonValuePlace::Placeholder,
@ -362,7 +362,7 @@ mod testing {
assert_eq!( assert_eq!(
cc.empty_because.unwrap(), cc.empty_because.unwrap(),
EmptyBecause::TypeMismatch { EmptyBecause::TypeMismatch {
var: y.clone(), var: y,
existing: ValueTypeSet::of_numeric_types(), existing: ValueTypeSet::of_numeric_types(),
desired: ValueTypeSet::of_one(ValueType::String), desired: ValueTypeSet::of_one(ValueType::String),
} }

View file

@ -14,11 +14,11 @@ use mentat_core::{HasSchema, Schema};
use edn::query::{FnArg, NonIntegerConstant, PlainSymbol}; use edn::query::{FnArg, NonIntegerConstant, PlainSymbol};
use clauses::ConjoiningClauses; use crate::clauses::ConjoiningClauses;
use query_algebrizer_traits::errors::{AlgebrizerError, Result}; use query_algebrizer_traits::errors::{AlgebrizerError, Result};
use types::{EmptyBecause, QueryValue}; use crate::types::{EmptyBecause, QueryValue};
/// Argument resolution. /// Argument resolution.
impl ConjoiningClauses { impl ConjoiningClauses {

View file

@ -12,16 +12,16 @@ use core_traits::ValueType;
use edn::query::{Binding, FnArg, SrcVar, VariableOrPlaceholder, WhereFn}; use edn::query::{Binding, FnArg, SrcVar, VariableOrPlaceholder, WhereFn};
use clauses::ConjoiningClauses; use crate::clauses::ConjoiningClauses;
use query_algebrizer_traits::errors::{AlgebrizerError, BindingError, Result}; use query_algebrizer_traits::errors::{AlgebrizerError, BindingError, Result};
use types::{ use crate::types::{
Column, ColumnConstraint, DatomsTable, Inequality, QualifiedAlias, QueryValue, SourceAlias, Column, ColumnConstraint, DatomsTable, Inequality, QualifiedAlias, QueryValue, SourceAlias,
TransactionsColumn, TransactionsColumn,
}; };
use Known; use crate::Known;
impl ConjoiningClauses { impl ConjoiningClauses {
// Log in Query: tx-ids and tx-data // Log in Query: tx-ids and tx-data

View file

@ -10,11 +10,11 @@
use edn::query::WhereFn; use edn::query::WhereFn;
use clauses::ConjoiningClauses; use crate::clauses::ConjoiningClauses;
use query_algebrizer_traits::errors::{AlgebrizerError, Result}; use query_algebrizer_traits::errors::{AlgebrizerError, Result};
use Known; use crate::Known;
/// Application of `where` functions. /// Application of `where` functions.
impl ConjoiningClauses { impl ConjoiningClauses {

View file

@ -34,9 +34,9 @@ use edn::query::{Element, FindSpec, Limit, Order, ParsedQuery, SrcVar, Variable,
use query_algebrizer_traits::errors::{AlgebrizerError, Result}; use query_algebrizer_traits::errors::{AlgebrizerError, Result};
pub use clauses::{QueryInputs, VariableBindings}; pub use crate::clauses::{QueryInputs, VariableBindings};
pub use types::{EmptyBecause, FindQuery}; pub use crate::types::{EmptyBecause, FindQuery};
/// A convenience wrapper around things known in memory: the schema and caches. /// A convenience wrapper around things known in memory: the schema and caches.
/// We use a trait object here to avoid making dozens of functions generic over the type /// We use a trait object here to avoid making dozens of functions generic over the type
@ -347,9 +347,9 @@ pub fn algebrize_with_inputs(
simplify_limit(q) simplify_limit(q)
} }
pub use clauses::ConjoiningClauses; pub use crate::clauses::ConjoiningClauses;
pub use types::{ pub use crate::types::{
Column, ColumnAlternation, ColumnConstraint, ColumnConstraintOrAlternation, ColumnIntersection, Column, ColumnAlternation, ColumnConstraint, ColumnConstraintOrAlternation, ColumnIntersection,
ColumnName, ComputedTable, DatomsColumn, DatomsTable, FulltextColumn, OrderBy, QualifiedAlias, ColumnName, ComputedTable, DatomsColumn, DatomsTable, FulltextColumn, OrderBy, QualifiedAlias,
QueryValue, SourceAlias, TableAlias, VariableColumn, QueryValue, SourceAlias, TableAlias, VariableColumn,

View file

@ -32,11 +32,11 @@ pub enum DatomsTable {
/// A source of rows that isn't a named table -- typically a subquery or union. /// A source of rows that isn't a named table -- typically a subquery or union.
#[derive(PartialEq, Eq, Debug)] #[derive(PartialEq, Eq, Debug)]
pub enum ComputedTable { pub enum ComputedTable {
Subquery(Box<::clauses::ConjoiningClauses>), Subquery(Box<crate::clauses::ConjoiningClauses>),
Union { Union {
projection: BTreeSet<Variable>, projection: BTreeSet<Variable>,
type_extraction: BTreeSet<Variable>, type_extraction: BTreeSet<Variable>,
arms: Vec<::clauses::ConjoiningClauses>, arms: Vec<crate::clauses::ConjoiningClauses>,
}, },
NamedValues { NamedValues {
names: Vec<Variable>, names: Vec<Variable>,

View file

@ -91,11 +91,11 @@ mod tests {
Variable, WhereClause, Variable, WhereClause,
}; };
use clauses::ident; use crate::clauses::ident;
use super::*; use super::*;
use parse_find_string; use crate::parse_find_string;
use types::FindQuery; use crate::types::FindQuery;
fn value_ident(ns: &str, name: &str) -> PatternValuePlace { fn value_ident(ns: &str, name: &str) -> PatternValuePlace {
Keyword::namespaced(ns, name).into() Keyword::namespaced(ns, name).into()
@ -112,7 +112,7 @@ mod tests {
match clause { match clause {
WhereClause::OrJoin(or_join) => { WhereClause::OrJoin(or_join) => {
// It's valid: the variables are the same in each branch. // It's valid: the variables are the same in each branch.
assert_eq!((), validate_or_join(&or_join).unwrap()); validate_or_join(&or_join).unwrap();
assert_eq!(expected_unify, or_join.unify_vars); assert_eq!(expected_unify, or_join.unify_vars);
or_join.clauses or_join.clauses
} }
@ -254,10 +254,10 @@ mod tests {
/// Tests that the top-level form is a valid `not`, returning the clauses. /// Tests that the top-level form is a valid `not`, returning the clauses.
fn valid_not_join(parsed: FindQuery, expected_unify: UnifyVars) -> Vec<WhereClause> { fn valid_not_join(parsed: FindQuery, expected_unify: UnifyVars) -> Vec<WhereClause> {
// Filter out all the clauses that are not `not`s. // Filter out all the clauses that are not `not`s.
let mut nots = parsed.where_clauses.into_iter().filter(|x| match x { let mut nots = parsed
&WhereClause::NotJoin(_) => true, .where_clauses
_ => false, .into_iter()
}); .filter(|x| matches!(x, WhereClause::NotJoin(_)));
// There should be only one not clause. // There should be only one not clause.
let clause = nots.next().unwrap(); let clause = nots.next().unwrap();
@ -266,7 +266,7 @@ mod tests {
match clause { match clause {
WhereClause::NotJoin(not_join) => { WhereClause::NotJoin(not_join) => {
// It's valid: the variables are the same in each branch. // It's valid: the variables are the same in each branch.
assert_eq!((), validate_not_join(&not_join).unwrap()); validate_not_join(&not_join).unwrap();
assert_eq!(expected_unify, not_join.unify_vars); assert_eq!(expected_unify, not_join.unify_vars);
not_join.clauses not_join.clauses
} }
@ -368,11 +368,10 @@ mod tests {
[?release :release/artists "Pink Floyd"] [?release :release/artists "Pink Floyd"]
[?release :release/year 1970])]"#; [?release :release/year 1970])]"#;
let parsed = parse_find_string(query).expect("expected successful parse"); let parsed = parse_find_string(query).expect("expected successful parse");
let mut nots = parsed.where_clauses.iter().filter(|&x| match *x { let mut nots = parsed
WhereClause::NotJoin(_) => true, .where_clauses
_ => false, .iter()
}); .filter(|&x| matches!(*x, WhereClause::NotJoin(_)));
let clause = nots.next().unwrap().clone(); let clause = nots.next().unwrap().clone();
assert_eq!(None, nots.next()); assert_eq!(None, nots.next());

View file

@ -22,7 +22,7 @@ use mentat_core::Schema;
use edn::query::Keyword; use edn::query::Keyword;
use utils::{add_attribute, alg, associate_ident}; use crate::utils::{add_attribute, alg, associate_ident};
use mentat_query_algebrizer::Known; use mentat_query_algebrizer::Known;

View file

@ -28,7 +28,7 @@ use query_algebrizer_traits::errors::{AlgebrizerError, BindingError};
use mentat_query_algebrizer::{ComputedTable, Known, QueryInputs}; use mentat_query_algebrizer::{ComputedTable, Known, QueryInputs};
use utils::{add_attribute, alg, associate_ident, bails, bails_with_inputs}; use crate::utils::{add_attribute, alg, associate_ident, bails, bails_with_inputs};
fn prepopulated_schema() -> Schema { fn prepopulated_schema() -> Schema {
let mut schema = Schema::default(); let mut schema = Schema::default();

View file

@ -26,7 +26,7 @@ use query_algebrizer_traits::errors::AlgebrizerError;
use mentat_query_algebrizer::{EmptyBecause, Known, QueryInputs}; use mentat_query_algebrizer::{EmptyBecause, Known, QueryInputs};
use utils::{add_attribute, alg, alg_with_inputs, associate_ident, bails}; use crate::utils::{add_attribute, alg, alg_with_inputs, associate_ident, bails};
fn prepopulated_schema() -> Schema { fn prepopulated_schema() -> Schema {
let mut schema = Schema::default(); let mut schema = Schema::default();
@ -162,7 +162,7 @@ fn test_instant_predicates_accepts_var() {
let cc = alg_with_inputs( let cc = alg_with_inputs(
known, known,
query, query,
QueryInputs::with_value_sequence(vec![(instant_var.clone(), instant_value.clone())]), QueryInputs::with_value_sequence(vec![(instant_var.clone(), instant_value)]),
); );
assert_eq!( assert_eq!(
cc.known_type(&instant_var).expect("?time is known"), cc.known_type(&instant_var).expect("?time is known"),
@ -202,7 +202,7 @@ fn test_numeric_predicates_accepts_var() {
let cc = alg_with_inputs( let cc = alg_with_inputs(
known, known,
query, query,
QueryInputs::with_value_sequence(vec![(numeric_var.clone(), numeric_value.clone())]), QueryInputs::with_value_sequence(vec![(numeric_var.clone(), numeric_value)]),
); );
assert_eq!( assert_eq!(
cc.known_type(&numeric_var).expect("?long is known"), cc.known_type(&numeric_var).expect("?long is known"),

View file

@ -16,7 +16,7 @@ extern crate query_algebrizer_traits;
mod utils; mod utils;
use utils::{alg, bails, SchemaBuilder}; use crate::utils::{alg, bails, SchemaBuilder};
use core_traits::ValueType; use core_traits::ValueType;

View file

@ -30,7 +30,7 @@ use mentat_query_algebrizer::{
// These are helpers that tests use to build Schema instances. // These are helpers that tests use to build Schema instances.
pub fn associate_ident(schema: &mut Schema, i: Keyword, e: Entid) { pub fn associate_ident(schema: &mut Schema, i: Keyword, e: Entid) {
schema.entid_map.insert(e, i.clone()); schema.entid_map.insert(e, i.clone());
schema.ident_map.insert(i.clone(), e); schema.ident_map.insert(i, e);
} }
pub fn add_attribute(schema: &mut Schema, e: Entid, a: Attribute) { pub fn add_attribute(schema: &mut Schema, e: Entid, a: Attribute) {

View file

@ -16,7 +16,7 @@ use mentat_query_algebrizer::{ColumnName, ConjoiningClauses, VariableColumn};
use mentat_query_sql::{ColumnOrExpression, Expression, Name, ProjectedColumn}; use mentat_query_sql::{ColumnOrExpression, Expression, Name, ProjectedColumn};
use errors::{ProjectorError, Result}; use crate::errors::{ProjectorError, Result};
#[derive(Clone, Copy, Debug, Eq, PartialEq)] #[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum SimpleAggregationOp { pub enum SimpleAggregationOp {

View file

@ -17,7 +17,7 @@ use db_traits::errors::DbError;
use edn::query::PlainSymbol; use edn::query::PlainSymbol;
use query_pull_traits::errors::PullError; use query_pull_traits::errors::PullError;
use aggregates::SimpleAggregationOp; use crate::aggregates::SimpleAggregationOp;
pub type Result<T> = std::result::Result<T, ProjectorError>; pub type Result<T> = std::result::Result<T, ProjectorError>;

View file

@ -28,7 +28,7 @@ use mentat_query_projector::query_projection;
// These are helpers that tests use to build Schema instances. // These are helpers that tests use to build Schema instances.
fn associate_ident(schema: &mut Schema, i: Keyword, e: Entid) { fn associate_ident(schema: &mut Schema, i: Keyword, e: Entid) {
schema.entid_map.insert(e, i.clone()); schema.entid_map.insert(e, i.clone());
schema.ident_map.insert(i.clone(), e); schema.ident_map.insert(i, e);
} }
fn add_attribute(schema: &mut Schema, e: Entid, a: Attribute) { fn add_attribute(schema: &mut Schema, e: Entid, a: Attribute) {

View file

@ -8,7 +8,7 @@ sqlcipher = ["rusqlite/sqlcipher"]
[dependencies] [dependencies]
failure = "~0.1" failure = "~0.1"
indexmap = "~1.3" indexmap = "~1.5"
[dependencies.rusqlite] [dependencies.rusqlite]
version = "~0.23" version = "~0.23"

View file

@ -50,24 +50,24 @@ use mentat_query_sql::{GroupBy, Projection};
pub mod translate; pub mod translate;
mod binding_tuple; mod binding_tuple;
pub use binding_tuple::BindingTuple; pub use crate::binding_tuple::BindingTuple;
mod project; mod project;
mod projectors; mod projectors;
mod pull; mod pull;
mod relresult; mod relresult;
use project::{project_elements, ProjectedElements}; use crate::project::{project_elements, ProjectedElements};
pub use project::projected_column_for_var; pub use crate::project::projected_column_for_var;
pub use projectors::{ConstantProjector, Projector}; pub use crate::projectors::{ConstantProjector, Projector};
use projectors::{ use crate::projectors::{
CollProjector, CollTwoStagePullProjector, RelProjector, RelTwoStagePullProjector, CollProjector, CollTwoStagePullProjector, RelProjector, RelTwoStagePullProjector,
ScalarProjector, ScalarTwoStagePullProjector, TupleProjector, TupleTwoStagePullProjector, ScalarProjector, ScalarTwoStagePullProjector, TupleProjector, TupleTwoStagePullProjector,
}; };
pub use relresult::{RelResult, StructuredRelResult}; pub use crate::relresult::{RelResult, StructuredRelResult};
use query_projector_traits::errors::{ProjectorError, Result}; use query_projector_traits::errors::{ProjectorError, Result};
@ -241,7 +241,7 @@ impl QueryOutput {
impl QueryResults { impl QueryResults {
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
use QueryResults::*; use crate::QueryResults::*;
match *self { match *self {
Scalar(ref o) => { Scalar(ref o) => {
if o.is_some() { if o.is_some() {
@ -263,7 +263,7 @@ impl QueryResults {
} }
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
use QueryResults::*; use crate::QueryResults::*;
match *self { match *self {
Scalar(ref o) => o.is_none(), Scalar(ref o) => o.is_none(),
Tuple(ref o) => o.is_none(), Tuple(ref o) => o.is_none(),
@ -339,7 +339,7 @@ impl TypedIndex {
/// This function will return a runtime error if the type tag is unknown, or the value is /// This function will return a runtime error if the type tag is unknown, or the value is
/// otherwise not convertible by the DB layer. /// otherwise not convertible by the DB layer.
fn lookup<'a>(&self, row: &Row<'a>) -> Result<Binding> { fn lookup<'a>(&self, row: &Row<'a>) -> Result<Binding> {
use TypedIndex::*; use crate::TypedIndex::*;
match *self { match *self {
Known(value_index, value_type) => { Known(value_index, value_type) => {
@ -403,10 +403,7 @@ trait IsPull {
impl IsPull for Element { impl IsPull for Element {
fn is_pull(&self) -> bool { fn is_pull(&self) -> bool {
match *self { matches!(*self, Element::Pull(_))
Element::Pull(_) => true,
_ => false,
}
} }
} }
@ -525,12 +522,14 @@ fn test_into_tuple() {
)) ))
); );
match query_output.clone().into_tuple() { match query_output.into_tuple() {
Err(ProjectorError::UnexpectedResultsTupleLength(expected, got)) => { Err(ProjectorError::UnexpectedResultsTupleLength(expected, got)) => {
assert_eq!((expected, got), (3, 2)); assert_eq!((expected, got), (3, 2));
} }
// This forces the result type. // This forces the result type.
Ok(Some((_, _, _))) | _ => panic!("expected error"), Ok(Some((_, _, _))) => panic!("expected error"),
#[allow(clippy::wildcard_in_or_patterns)]
_ => panic!("expected error"),
} }
let query_output = QueryOutput { let query_output = QueryOutput {
@ -544,14 +543,18 @@ fn test_into_tuple() {
match query_output.clone().into_tuple() { match query_output.clone().into_tuple() {
Ok(None) => {} Ok(None) => {}
// This forces the result type. // This forces the result type.
Ok(Some((_, _))) | _ => panic!("expected error"), Ok(Some((_, _))) => panic!("expected error"),
#[allow(clippy::wildcard_in_or_patterns)]
_ => panic!("expected error"),
} }
match query_output.clone().into_tuple() { match query_output.into_tuple() {
Err(ProjectorError::UnexpectedResultsTupleLength(expected, got)) => { Err(ProjectorError::UnexpectedResultsTupleLength(expected, got)) => {
assert_eq!((expected, got), (3, 2)); assert_eq!((expected, got), (3, 2));
} }
// This forces the result type. // This forces the result type.
Ok(Some((_, _, _))) | _ => panic!("expected error"), Ok(Some((_, _, _))) => panic!("expected error"),
#[allow(clippy::wildcard_in_or_patterns)]
_ => panic!("expected error"),
} }
} }

View file

@ -32,9 +32,9 @@ use query_projector_traits::aggregates::{
use query_projector_traits::errors::{ProjectorError, Result}; use query_projector_traits::errors::{ProjectorError, Result};
use projectors::Projector; use crate::projectors::Projector;
use pull::{PullIndices, PullOperation, PullTemplate}; use crate::pull::{PullIndices, PullOperation, PullTemplate};
use super::{CombinedProjection, TypedIndex}; use super::{CombinedProjection, TypedIndex};

View file

@ -10,7 +10,7 @@
use std::rc::Rc; use std::rc::Rc;
use {rusqlite, Element, FindSpec, QueryOutput, QueryResults, Rows, Schema}; use crate::{rusqlite, Element, FindSpec, QueryOutput, QueryResults, Rows, Schema};
use query_projector_traits::errors::Result; use query_projector_traits::errors::Result;

View file

@ -16,12 +16,12 @@ use mentat_query_pull::Puller;
use core_traits::Entid; use core_traits::Entid;
use { use crate::{
rusqlite, Binding, CombinedProjection, Element, FindSpec, ProjectedElements, QueryOutput, rusqlite, Binding, CombinedProjection, Element, FindSpec, ProjectedElements, QueryOutput,
QueryResults, RelResult, Row, Rows, Schema, TypedIndex, QueryResults, RelResult, Row, Rows, Schema, TypedIndex,
}; };
use pull::{PullConsumer, PullOperation, PullTemplate}; use crate::pull::{PullConsumer, PullOperation, PullTemplate};
use query_projector_traits::errors::Result; use query_projector_traits::errors::Result;

View file

@ -10,7 +10,7 @@
use std::rc::Rc; use std::rc::Rc;
use { use crate::{
rusqlite, Binding, CombinedProjection, Element, FindSpec, ProjectedElements, QueryOutput, rusqlite, Binding, CombinedProjection, Element, FindSpec, ProjectedElements, QueryOutput,
QueryResults, RelResult, Row, Rows, Schema, TypedIndex, QueryResults, RelResult, Row, Rows, Schema, TypedIndex,
}; };

View file

@ -22,7 +22,7 @@ use mentat_query_algebrizer::{
OrderBy, QualifiedAlias, QueryValue, SourceAlias, TableAlias, VariableColumn, OrderBy, QualifiedAlias, QueryValue, SourceAlias, TableAlias, VariableColumn,
}; };
use { use crate::{
projected_column_for_var, query_projection, CombinedProjection, ConstantProjector, Projector, projected_column_for_var, query_projection, CombinedProjection, ConstantProjector, Projector,
}; };
@ -82,6 +82,7 @@ fn affinity_count(tag: i32) -> usize {
.count() .count()
} }
#[allow(clippy::ptr_arg)]
fn type_constraint( fn type_constraint(
table: &TableAlias, table: &TableAlias,
tag: i32, tag: i32,
@ -369,7 +370,7 @@ fn cc_to_select_query(
FromClause::TableList(TableList(tables.collect())) FromClause::TableList(TableList(tables.collect()))
}; };
let order = order.map_or(vec![], |vec| vec.into_iter().map(|o| o).collect()); let order = order.map_or(vec![], |vec| vec.into_iter().collect());
let limit = if cc.empty_because.is_some() { let limit = if cc.empty_because.is_some() {
Limit::Fixed(0) Limit::Fixed(0)
} else { } else {

View file

@ -46,7 +46,7 @@ macro_rules! var {
fn associate_ident(schema: &mut Schema, i: Keyword, e: Entid) { fn associate_ident(schema: &mut Schema, i: Keyword, e: Entid) {
schema.entid_map.insert(e, i.clone()); schema.entid_map.insert(e, i.clone());
schema.ident_map.insert(i.clone(), e); schema.ident_map.insert(i, e);
} }
fn add_attribute(schema: &mut Schema, e: Entid, a: Attribute) { fn add_attribute(schema: &mut Schema, e: Entid, a: Attribute) {

View file

@ -159,7 +159,7 @@ impl Puller {
for attr in attributes.iter() { for attr in attributes.iter() {
match attr { match attr {
&PullAttributeSpec::Wildcard => { PullAttributeSpec::Wildcard => {
let attribute_ids = schema.attribute_map.keys(); let attribute_ids = schema.attribute_map.keys();
for id in attribute_ids { for id in attribute_ids {
names.insert(*id, lookup_name(id)?); names.insert(*id, lookup_name(id)?);
@ -167,28 +167,28 @@ impl Puller {
} }
break; break;
} }
&PullAttributeSpec::Attribute(NamedPullAttribute { PullAttributeSpec::Attribute(NamedPullAttribute {
ref attribute, ref attribute,
ref alias, ref alias,
}) => { }) => {
let alias = alias.as_ref().map(|ref r| r.to_value_rc()); let alias = alias.as_ref().map(|ref r| r.to_value_rc());
match attribute { match attribute {
// Handle :db/id. // Handle :db/id.
&PullConcreteAttribute::Ident(ref i) if i.as_ref() == db_id.as_ref() => { PullConcreteAttribute::Ident(ref i) if i.as_ref() == db_id.as_ref() => {
// We only allow :db/id once. // We only allow :db/id once.
if db_id_alias.is_some() { if db_id_alias.is_some() {
Err(PullError::RepeatedDbId)? return Err(PullError::RepeatedDbId);
} }
db_id_alias = Some(alias.unwrap_or_else(|| db_id.to_value_rc())); db_id_alias = Some(alias.unwrap_or_else(|| db_id.to_value_rc()));
} }
&PullConcreteAttribute::Ident(ref i) => { PullConcreteAttribute::Ident(ref i) => {
if let Some(entid) = schema.get_entid(i) { if let Some(entid) = schema.get_entid(i) {
let name = alias.unwrap_or_else(|| i.to_value_rc()); let name = alias.unwrap_or_else(|| i.to_value_rc());
names.insert(entid.into(), name); names.insert(entid.into(), name);
attrs.insert(entid.into()); attrs.insert(entid.into());
} }
} }
&PullConcreteAttribute::Entid(ref entid) => { PullConcreteAttribute::Entid(ref entid) => {
let name = alias.map(Ok).unwrap_or_else(|| lookup_name(entid))?; let name = alias.map(Ok).unwrap_or_else(|| lookup_name(entid))?;
names.insert(*entid, name); names.insert(*entid, name);
attrs.insert(*entid); attrs.insert(*entid);
@ -242,7 +242,7 @@ impl Puller {
for e in entities.iter() { for e in entities.iter() {
let r = maps let r = maps
.entry(*e) .entry(*e)
.or_insert(ValueRc::new(StructuredMap::default())); .or_insert_with(|| ValueRc::new(StructuredMap::default()));
let m = ValueRc::get_mut(r).unwrap(); let m = ValueRc::get_mut(r).unwrap();
m.insert(alias.clone(), Binding::Scalar(TypedValue::Ref(*e))); m.insert(alias.clone(), Binding::Scalar(TypedValue::Ref(*e)));
} }
@ -257,7 +257,7 @@ impl Puller {
if let Some(binding) = cache.binding_for_e(*e) { if let Some(binding) = cache.binding_for_e(*e) {
let r = maps let r = maps
.entry(*e) .entry(*e)
.or_insert(ValueRc::new(StructuredMap::default())); .or_insert_with(|| ValueRc::new(StructuredMap::default()));
// Get into the inner map so we can accumulate a value. // Get into the inner map so we can accumulate a value.
// We can unwrap here because we created all of these maps… // We can unwrap here because we created all of these maps…

View file

@ -837,7 +837,7 @@ mod tests {
from: FromClause::TableList(TableList(source_aliases)), from: FromClause::TableList(TableList(source_aliases)),
constraints: vec![ constraints: vec![
Constraint::Infix { Constraint::Infix {
op: eq.clone(), op: eq,
left: ColumnOrExpression::Column(QualifiedAlias::new( left: ColumnOrExpression::Column(QualifiedAlias::new(
datoms01.clone(), datoms01.clone(),
DatomsColumn::Value, DatomsColumn::Value,
@ -848,17 +848,17 @@ mod tests {
)), )),
}, },
Constraint::Infix { Constraint::Infix {
op: eq.clone(), op: eq,
left: ColumnOrExpression::Column(QualifiedAlias::new( left: ColumnOrExpression::Column(QualifiedAlias::new(
datoms00.clone(), datoms00,
DatomsColumn::Attribute, DatomsColumn::Attribute,
)), )),
right: ColumnOrExpression::Entid(65537), right: ColumnOrExpression::Entid(65537),
}, },
Constraint::Infix { Constraint::Infix {
op: eq.clone(), op: eq,
left: ColumnOrExpression::Column(QualifiedAlias::new( left: ColumnOrExpression::Column(QualifiedAlias::new(
datoms01.clone(), datoms01,
DatomsColumn::Attribute, DatomsColumn::Attribute,
)), )),
right: ColumnOrExpression::Entid(65536), right: ColumnOrExpression::Entid(65536),

View file

@ -8,7 +8,7 @@ sqlcipher = ["rusqlite/sqlcipher"]
[dependencies] [dependencies]
failure = "~0.1" failure = "~0.1"
ordered-float = "~1.0" ordered-float = "~2.0"
[dependencies.rusqlite] [dependencies.rusqlite]
version = "~0.23" version = "~0.23"

View file

@ -137,7 +137,7 @@ impl QueryBuilder for SQLiteQueryBuilder {
} }
fn push_typed_value(&mut self, value: &TypedValue) -> BuildQueryResult { fn push_typed_value(&mut self, value: &TypedValue) -> BuildQueryResult {
use TypedValue::*; use crate::TypedValue::*;
match value { match value {
Ref(entid) => self.push_sql(entid.to_string().as_str()), Ref(entid) => self.push_sql(entid.to_string().as_str()),
Boolean(v) => self.push_sql(if *v { "1" } else { "0" }), Boolean(v) => self.push_sql(if *v { "1" } else { "0" }),

View file

@ -16,11 +16,8 @@ use std::collections::BTreeMap;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use rusqlite;
use rusqlite::TransactionBehavior; use rusqlite::TransactionBehavior;
use edn;
pub use core_traits::{Attribute, Entid, KnownEntid, StructuredMap, TypedValue, ValueType}; pub use core_traits::{Attribute, Entid, KnownEntid, StructuredMap, TypedValue, ValueType};
use mentat_core::{HasSchema, Keyword, Schema, TxReport, ValueRc}; use mentat_core::{HasSchema, Keyword, Schema, TxReport, ValueRc};
@ -376,8 +373,6 @@ impl Conn {
mod tests { mod tests {
use super::*; use super::*;
use time;
use std::time::Instant; use std::time::Instant;
use core_traits::{Binding, TypedValue}; use core_traits::{Binding, TypedValue};
@ -476,8 +471,8 @@ mod tests {
.begin_transaction(&mut sqlite) .begin_transaction(&mut sqlite)
.expect("begun successfully"); .expect("begun successfully");
let report = in_progress.transact(t).expect("transacted successfully"); let report = in_progress.transact(t).expect("transacted successfully");
let one = report.tempids.get("one").expect("found one").clone(); let one = *report.tempids.get("one").expect("found one");
let two = report.tempids.get("two").expect("found two").clone(); let two = *report.tempids.get("two").expect("found two");
assert!(one != two); assert!(one != two);
assert!(one == tempid_offset || one == tempid_offset + 1); assert!(one == tempid_offset || one == tempid_offset + 1);
assert!(two == tempid_offset || two == tempid_offset + 1); assert!(two == tempid_offset || two == tempid_offset + 1);
@ -499,7 +494,7 @@ mod tests {
let report = in_progress.transact(t2).expect("t2 succeeded"); let report = in_progress.transact(t2).expect("t2 succeeded");
in_progress.commit().expect("commit succeeded"); in_progress.commit().expect("commit succeeded");
let three = report.tempids.get("three").expect("found three").clone(); let three = *report.tempids.get("three").expect("found three");
assert!(one != three); assert!(one != three);
assert!(two != three); assert!(two != three);
} }
@ -532,7 +527,7 @@ mod tests {
]"#, ]"#,
) )
.expect("successful transaction"); .expect("successful transaction");
let yes = report.tempids.get("u").expect("found it").clone(); let yes = *report.tempids.get("u").expect("found it");
let vv = Variable::from_valid_name("?v"); let vv = Variable::from_valid_name("?v");
@ -585,8 +580,8 @@ mod tests {
.expect("begun successfully"); .expect("begun successfully");
let report = in_progress.transact(t).expect("transacted successfully"); let report = in_progress.transact(t).expect("transacted successfully");
let one = report.tempids.get("one").expect("found it").clone(); let one = *report.tempids.get("one").expect("found it");
let two = report.tempids.get("two").expect("found it").clone(); let two = *report.tempids.get("two").expect("found it");
// The IDs are contiguous, starting at the previous part index. // The IDs are contiguous, starting at the previous part index.
assert!(one != two); assert!(one != two);
@ -619,7 +614,7 @@ mod tests {
let after = conn let after = conn
.q_once( .q_once(
&mut sqlite, &sqlite,
"[:find ?x . :where [?x :db/ident :a/keyword1]]", "[:find ?x . :where [?x :db/ident :a/keyword1]]",
None, None,
) )

View file

@ -54,7 +54,7 @@ impl<'a> QueryBuilder<'a> {
.conn() .conn()
.current_schema() .current_schema()
.get_entid(&value) .get_entid(&value)
.ok_or(MentatError::UnknownAttribute(value.to_string()))?; .ok_or_else(|| MentatError::UnknownAttribute(value.to_string()))?;
self.values.insert( self.values.insert(
Variable::from_valid_name(var), Variable::from_valid_name(var),
TypedValue::Ref(entid.into()), TypedValue::Ref(entid.into()),
@ -99,11 +99,11 @@ impl<'a> QueryBuilder<'a> {
} }
pub fn execute(&mut self) -> Result<QueryOutput> { pub fn execute(&mut self) -> Result<QueryOutput> {
let values = ::std::mem::replace(&mut self.values, Default::default()); let values = ::std::mem::take(&mut self.values);
let types = ::std::mem::replace(&mut self.types, Default::default()); let types = ::std::mem::take(&mut self.types);
let query_inputs = QueryInputs::new(types, values)?; let query_inputs = QueryInputs::new(types, values)?;
let read = self.store.begin_read()?; let read = self.store.begin_read()?;
read.q_once(&self.query, query_inputs).map_err(|e| e.into()) read.q_once(&self.query, query_inputs).map_err(|e| e)
} }
pub fn execute_scalar(&mut self) -> Result<Option<Binding>> { pub fn execute_scalar(&mut self) -> Result<Option<Binding>> {
@ -153,7 +153,7 @@ mod test {
) )
.expect("successful transaction"); .expect("successful transaction");
let yes = report.tempids.get("u").expect("found it").clone(); let yes = *report.tempids.get("u").expect("found it");
let entid = QueryBuilder::new( let entid = QueryBuilder::new(
&mut store, &mut store,
@ -164,7 +164,7 @@ mod test {
.bind_value("?v", true) .bind_value("?v", true)
.execute_scalar() .execute_scalar()
.expect("ScalarResult") .expect("ScalarResult")
.map_or(None, |t| t.into_entid()); .and_then(|t| t.into_entid());
assert_eq!(entid, Some(yes)); assert_eq!(entid, Some(yes));
} }
@ -201,9 +201,9 @@ mod test {
) )
.expect("successful transaction"); .expect("successful transaction");
let u_yes = report.tempids.get("u").expect("found it").clone(); let u_yes = *report.tempids.get("u").expect("found it");
let l_yes = report.tempids.get("l").expect("found it").clone(); let l_yes = *report.tempids.get("l").expect("found it");
let n_yes = report.tempids.get("n").expect("found it").clone(); let n_yes = *report.tempids.get("n").expect("found it");
let entids: Vec<i64> = QueryBuilder::new( let entids: Vec<i64> = QueryBuilder::new(
&mut store, &mut store,
@ -254,7 +254,7 @@ mod test {
) )
.expect("successful transaction"); .expect("successful transaction");
let n_yes = report.tempids.get("n").expect("found it").clone(); let n_yes = *report.tempids.get("n").expect("found it");
let results = QueryBuilder::new( let results = QueryBuilder::new(
&mut store, &mut store,
@ -267,7 +267,7 @@ mod test {
.expect("CollResult"); .expect("CollResult");
let entid = results let entid = results
.get(1) .get(1)
.map_or(None, |t| t.to_owned().into_entid()) .and_then(|t| t.to_owned().into_entid())
.expect("entid"); .expect("entid");
assert_eq!(entid, n_yes); assert_eq!(entid, n_yes);
@ -306,7 +306,7 @@ mod test {
) )
.expect("successful transaction"); .expect("successful transaction");
let n_yes = report.tempids.get("n").expect("found it").clone(); let n_yes = *report.tempids.get("n").expect("found it");
let results = QueryBuilder::new( let results = QueryBuilder::new(
&mut store, &mut store,
@ -322,11 +322,11 @@ mod test {
.expect("Vec<TypedValue>"); .expect("Vec<TypedValue>");
let entid = results let entid = results
.get(0) .get(0)
.map_or(None, |t| t.to_owned().into_entid()) .and_then(|t| t.to_owned().into_entid())
.expect("entid"); .expect("entid");
let long_val = results let long_val = results
.get(1) .get(1)
.map_or(None, |t| t.to_owned().into_long()) .and_then(|t| t.to_owned().into_long())
.expect("long"); .expect("long");
assert_eq!(entid, n_yes); assert_eq!(entid, n_yes);
@ -366,7 +366,7 @@ mod test {
) )
.expect("successful transaction"); .expect("successful transaction");
let n_yes = report.tempids.get("n").expect("found it").clone(); let n_yes = *report.tempids.get("n").expect("found it");
let results: Vec<_> = QueryBuilder::new( let results: Vec<_> = QueryBuilder::new(
&mut store, &mut store,
@ -379,8 +379,8 @@ mod test {
.bind_long("?i", 27) .bind_long("?i", 27)
.execute_tuple() .execute_tuple()
.expect("TupleResult") .expect("TupleResult")
.unwrap_or(vec![]); .unwrap_or_default();
let entid = TypedValue::Ref(n_yes.clone()).into(); let entid = TypedValue::Ref(n_yes).into();
let long_val = TypedValue::Long(27).into(); let long_val = TypedValue::Long(27).into();
assert_eq!(results, vec![entid, long_val]); assert_eq!(results, vec![entid, long_val]);
@ -415,9 +415,9 @@ mod test {
) )
.expect("successful transaction"); .expect("successful transaction");
let l_yes = report.tempids.get("l").expect("found it").clone(); let l_yes = *report.tempids.get("l").expect("found it");
let m_yes = report.tempids.get("m").expect("found it").clone(); let m_yes = *report.tempids.get("m").expect("found it");
let n_yes = report.tempids.get("n").expect("found it").clone(); let n_yes = *report.tempids.get("n").expect("found it");
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
struct Res { struct Res {
@ -438,15 +438,15 @@ mod test {
.map(|row| Res { .map(|row| Res {
entid: row entid: row
.get(0) .get(0)
.map_or(None, |t| t.to_owned().into_entid()) .and_then(|t| t.to_owned().into_entid())
.expect("entid"), .expect("entid"),
boolean: row boolean: row
.get(1) .get(1)
.map_or(None, |t| t.to_owned().into_boolean()) .and_then(|t| t.to_owned().into_boolean())
.expect("boolean"), .expect("boolean"),
long_val: row long_val: row
.get(2) .get(2)
.map_or(None, |t| t.to_owned().into_long()) .and_then(|t| t.to_owned().into_long())
.expect("long"), .expect("long"),
}) })
.collect(); .collect();
@ -510,7 +510,7 @@ mod test {
) )
.expect("successful transaction"); .expect("successful transaction");
let l_yes = report.tempids.get("l").expect("found it").clone(); let l_yes = *report.tempids.get("l").expect("found it");
let results = QueryBuilder::new( let results = QueryBuilder::new(
&mut store, &mut store,
@ -522,11 +522,11 @@ mod test {
.bind_ref("?x", l_yes) .bind_ref("?x", l_yes)
.execute_tuple() .execute_tuple()
.expect("TupleResult") .expect("TupleResult")
.unwrap_or(vec![]); .unwrap_or_default();
assert_eq!( assert_eq!(
results results
.get(0) .get(0)
.map_or(None, |t| t.to_owned().into_boolean()) .and_then(|t| t.to_owned().into_boolean())
.expect("boolean"), .expect("boolean"),
true true
); );

View file

@ -14,10 +14,6 @@ use std::collections::BTreeMap;
use std::sync::Arc; use std::sync::Arc;
use rusqlite;
use edn;
use core_traits::{Entid, StructuredMap, TypedValue}; use core_traits::{Entid, StructuredMap, TypedValue};
use mentat_core::{Keyword, TxReport, ValueRc}; use mentat_core::{Keyword, TxReport, ValueRc};
@ -65,7 +61,7 @@ impl Store {
} }
#[cfg(feature = "syncable")] #[cfg(feature = "syncable")]
pub fn sync(&mut self, server_uri: &String, user_uuid: &String) -> Result<SyncResult> { pub fn sync(&mut self, server_uri: &str, user_uuid: &str) -> Result<SyncResult> {
let mut reports = vec![]; let mut reports = vec![];
loop { loop {
let mut ip = self.begin_transaction()?; let mut ip = self.begin_transaction()?;
@ -162,7 +158,7 @@ impl Store {
self.conn.register_observer(key, observer); self.conn.register_observer(key, observer);
} }
pub fn unregister_observer(&mut self, key: &String) { pub fn unregister_observer(&mut self, key: &str) {
self.conn.unregister_observer(key); self.conn.unregister_observer(key);
} }
@ -245,8 +241,6 @@ impl Pullable for Store {
mod tests { mod tests {
use super::*; use super::*;
use time;
use uuid::Uuid; use uuid::Uuid;
use std::collections::BTreeSet; use std::collections::BTreeSet;

View file

@ -17,11 +17,11 @@ use super::errors::Result;
use mentat_tolstoy::{RemoteClient, SyncReport, Syncer}; use mentat_tolstoy::{RemoteClient, SyncReport, Syncer};
pub trait Syncable { pub trait Syncable {
fn sync(&mut self, server_uri: &String, user_uuid: &String) -> Result<SyncReport>; fn sync(&mut self, server_uri: &str, user_uuid: &str) -> Result<SyncReport>;
} }
impl<'a, 'c> Syncable for InProgress<'a, 'c> { impl<'a, 'c> Syncable for InProgress<'a, 'c> {
fn sync(&mut self, server_uri: &String, user_uuid: &String) -> Result<SyncReport> { fn sync(&mut self, server_uri: &str, user_uuid: &str) -> Result<SyncReport> {
// Syncer behaves as if it's part of InProgress. // Syncer behaves as if it's part of InProgress.
// This split into a separate crate is segment synchronization functionality // This split into a separate crate is segment synchronization functionality
// in a single crate which can be easily disabled by consumers, // in a single crate which can be easily disabled by consumers,
@ -30,6 +30,6 @@ impl<'a, 'c> Syncable for InProgress<'a, 'c> {
// which is exactly what InProgress represents. // which is exactly what InProgress represents.
let mut remote_client = let mut remote_client =
RemoteClient::new(server_uri.to_string(), Uuid::parse_str(&user_uuid)?); RemoteClient::new(server_uri.to_string(), Uuid::parse_str(&user_uuid)?);
Syncer::sync(self, &mut remote_client).map_err(|e| e.into()) Syncer::sync(self, &mut remote_client).map_err(|e| e)
} }
} }

View file

@ -280,6 +280,10 @@ impl Vocabularies {
self.0.len() self.0.len()
} }
pub fn is_empty(&self) -> bool {
self.0.len() == 0
}
pub fn get(&self, name: &Keyword) -> Option<&Vocabulary> { pub fn get(&self, name: &Keyword) -> Option<&Vocabulary> {
self.0.get(name) self.0.get(name)
} }
@ -325,17 +329,17 @@ where
{ {
fn core_type(&self, t: ValueType) -> Result<KnownEntid> { fn core_type(&self, t: ValueType) -> Result<KnownEntid> {
self.entid_for_type(t) self.entid_for_type(t)
.ok_or_else(|| MentatError::MissingCoreVocabulary(DB_SCHEMA_VERSION.clone()).into()) .ok_or_else(|| MentatError::MissingCoreVocabulary(DB_SCHEMA_VERSION.clone()))
} }
fn core_entid(&self, ident: &Keyword) -> Result<KnownEntid> { fn core_entid(&self, ident: &Keyword) -> Result<KnownEntid> {
self.get_entid(ident) self.get_entid(ident)
.ok_or_else(|| MentatError::MissingCoreVocabulary(DB_SCHEMA_VERSION.clone()).into()) .ok_or_else(|| MentatError::MissingCoreVocabulary(DB_SCHEMA_VERSION.clone()))
} }
fn core_attribute(&self, ident: &Keyword) -> Result<KnownEntid> { fn core_attribute(&self, ident: &Keyword) -> Result<KnownEntid> {
self.attribute_for_ident(ident) self.attribute_for_ident(ident)
.ok_or_else(|| MentatError::MissingCoreVocabulary(DB_SCHEMA_VERSION.clone()).into()) .ok_or_else(|| MentatError::MissingCoreVocabulary(DB_SCHEMA_VERSION.clone()))
.map(|(_, e)| e) .map(|(_, e)| e)
} }
} }
@ -436,16 +440,16 @@ impl Definition {
// Nothing to do. // Nothing to do.
} }
Some(Unique::Identity) => { Some(Unique::Identity) => {
builder.retract(tempid.clone(), a_unique, v_unique_identity.clone())?; builder.retract(tempid.clone(), a_unique, v_unique_identity)?;
} }
Some(Unique::Value) => { Some(Unique::Value) => {
builder.retract(tempid.clone(), a_unique, v_unique_value.clone())?; builder.retract(tempid.clone(), a_unique, v_unique_value)?;
} }
} }
} }
} }
builder.build().map_err(|e| e.into()) builder.build().map_err(|e| e)
} }
/// Return a sequence of terms that describes this vocabulary definition and its attributes. /// Return a sequence of terms that describes this vocabulary definition and its attributes.
@ -698,8 +702,7 @@ impl<'a, 'c> VersionedStore for InProgress<'a, 'c> {
definition.name.to_string(), definition.name.to_string(),
newer_version.version, newer_version.version,
definition.version, definition.version,
) ))
.into())
} }
} }
} }
@ -962,7 +965,7 @@ where
if let Some(attribute) = self.attribute_for_entid(attr).cloned() { if let Some(attribute) = self.attribute_for_entid(attr).cloned() {
attributes attributes
.entry(vocab) .entry(vocab)
.or_insert(Vec::new()) .or_insert_with(Vec::new)
.push((attr, attribute)); .push((attr, attribute));
} }
} }
@ -976,9 +979,9 @@ where
.filter_map(|(vocab, version)| { .filter_map(|(vocab, version)| {
// Get the name. // Get the name.
self.get_ident(vocab).cloned().map(|name| { self.get_ident(vocab).cloned().map(|name| {
let attrs = attributes.remove(&vocab).unwrap_or(vec![]); let attrs = attributes.remove(&vocab).unwrap_or_default();
( (
name.clone(), name,
Vocabulary { Vocabulary {
entity: vocab, entity: vocab,
version, version,

View file

@ -11,7 +11,6 @@
//extern crate mentat; //extern crate mentat;
use mentat::{self, kw, Binding, Entid, HasSchema, Queryable, Schema, Store, TypedValue}; use mentat::{self, kw, Binding, Entid, HasSchema, Queryable, Schema, Store, TypedValue};
use mentat_core::{self, CachedAttributes}; use mentat_core::{self, CachedAttributes};
use mentat_db;
use std::collections::BTreeSet; use std::collections::BTreeSet;
@ -134,22 +133,22 @@ fn test_add_attribute_already_in_cache() {
let one = schema.get_entid(&kw!(:item/one)).expect("one"); let one = schema.get_entid(&kw!(:item/one)).expect("one");
let two = schema.get_entid(&kw!(:item/two)).expect("two"); let two = schema.get_entid(&kw!(:item/two)).expect("two");
attribute_cache attribute_cache
.register(&schema, &mut store.sqlite_mut(), attr) .register(&schema, &store.sqlite_mut(), attr)
.expect("No errors on add to cache"); .expect("No errors on add to cache");
assert_value_present_for_attribute( assert_value_present_for_attribute(
&schema, &schema,
&mut attribute_cache, &mut attribute_cache,
attr.into(), attr,
one.into(), one.into(),
TypedValue::Long(100), TypedValue::Long(100),
); );
attribute_cache attribute_cache
.register(&schema, &mut store.sqlite_mut(), attr) .register(&schema, &store.sqlite_mut(), attr)
.expect("No errors on add to cache"); .expect("No errors on add to cache");
assert_value_present_for_attribute( assert_value_present_for_attribute(
&schema, &schema,
&mut attribute_cache, &mut attribute_cache,
attr.into(), attr,
two.into(), two.into(),
TypedValue::Long(200), TypedValue::Long(200),
); );
@ -200,7 +199,7 @@ fn test_remove_from_cache() {
.is_none()); .is_none());
attribute_cache attribute_cache
.register(&schema, &mut store.sqlite_mut(), entidr) .register(&schema, &store.sqlite_mut(), entidr)
.expect("No errors on add to cache"); .expect("No errors on add to cache");
assert_value_present_for_attribute( assert_value_present_for_attribute(
&schema, &schema,
@ -217,7 +216,7 @@ fn test_remove_from_cache() {
TypedValue::Long(200), TypedValue::Long(200),
); );
attribute_cache attribute_cache
.register(&schema, &mut store.sqlite_mut(), entidz) .register(&schema, &store.sqlite_mut(), entidz)
.expect("No errors on add to cache"); .expect("No errors on add to cache");
assert_value_present_for_attribute( assert_value_present_for_attribute(
&schema, &schema,
@ -234,7 +233,7 @@ fn test_remove_from_cache() {
TypedValue::Boolean(false), TypedValue::Boolean(false),
); );
attribute_cache attribute_cache
.register(&schema, &mut store.sqlite_mut(), entidp) .register(&schema, &store.sqlite_mut(), entidp)
.expect("No errors on add to cache"); .expect("No errors on add to cache");
assert_values_present_for_attribute( assert_values_present_for_attribute(
&schema, &schema,
@ -261,7 +260,7 @@ fn test_remove_from_cache() {
// test that we can remove an item from cache // test that we can remove an item from cache
attribute_cache.unregister(entidz); attribute_cache.unregister(entidz);
assert!(!attribute_cache.is_attribute_cached_forward(entidz.into())); assert!(!attribute_cache.is_attribute_cached_forward(entidz));
assert!(attribute_cache assert!(attribute_cache
.get_value_for_entid(&schema, entidz, one.into()) .get_value_for_entid(&schema, entidz, one.into())
.is_none()); .is_none());
@ -315,7 +314,7 @@ fn test_fetch_attribute_value_for_entid() {
let mut attribute_cache = SQLiteAttributeCache::default(); let mut attribute_cache = SQLiteAttributeCache::default();
attribute_cache attribute_cache
.register(&schema, &mut store.sqlite_mut(), attr_entid) .register(&schema, &store.sqlite_mut(), attr_entid)
.expect("No errors on add to cache"); .expect("No errors on add to cache");
let val = attribute_cache let val = attribute_cache
.get_value_for_entid(&schema, attr_entid, entid) .get_value_for_entid(&schema, attr_entid, entid)
@ -347,7 +346,7 @@ fn test_fetch_attribute_values_for_entid() {
let mut attribute_cache = SQLiteAttributeCache::default(); let mut attribute_cache = SQLiteAttributeCache::default();
attribute_cache attribute_cache
.register(&schema, &mut store.sqlite_mut(), attr_entid) .register(&schema, &store.sqlite_mut(), attr_entid)
.expect("No errors on add to cache"); .expect("No errors on add to cache");
let val = attribute_cache let val = attribute_cache
.get_values_for_entid(&schema, attr_entid, entid) .get_values_for_entid(&schema, attr_entid, entid)

View file

@ -11,10 +11,6 @@
#[macro_use] #[macro_use]
extern crate mentat; extern crate mentat;
use db_traits;
use mentat_db;
use mentat::conn::Conn; use mentat::conn::Conn;
use core_traits::{Entid, KnownEntid, TypedValue}; use core_traits::{Entid, KnownEntid, TypedValue};
@ -46,7 +42,7 @@ fn test_entity_builder_bogus_entids() {
.add(e.clone(), a2, e.clone()) .add(e.clone(), a2, e.clone())
.expect("add succeeded, even though it's meaningless"); .expect("add succeeded, even though it's meaningless");
builder builder
.add(e.clone(), a2, ve) .add(e, a2, ve)
.expect("add succeeded, even though it's meaningless"); .expect("add succeeded, even though it's meaningless");
let (terms, tempids) = builder.build().expect("build succeeded"); let (terms, tempids) = builder.build().expect("build succeeded");
@ -111,9 +107,7 @@ fn test_in_progress_builder() {
builder builder
.add(e_x.clone(), kw!(:foo/many), v_many_1) .add(e_x.clone(), kw!(:foo/many), v_many_1)
.expect("add succeeded"); .expect("add succeeded");
builder builder.add(e_x, a_many, v_many_2).expect("add succeeded");
.add(e_x.clone(), a_many, v_many_2)
.expect("add succeeded");
builder.commit().expect("commit succeeded"); builder.commit().expect("commit succeeded");
} }
@ -168,12 +162,8 @@ fn test_entity_builder() {
builder builder
.add(e_x.clone(), a_many, v_many_2) .add(e_x.clone(), a_many, v_many_2)
.expect("add succeeded"); .expect("add succeeded");
builder builder.add(e_y, a_ref, e_x.clone()).expect("add succeeded");
.add(e_y.clone(), a_ref, e_x.clone()) builder.add(e_x, a_one, v_long).expect("add succeeded");
.expect("add succeeded");
builder
.add(e_x.clone(), a_one, v_long)
.expect("add succeeded");
let (terms, tempids) = builder.build().expect("build succeeded"); let (terms, tempids) = builder.build().expect("build succeeded");
@ -204,7 +194,7 @@ fn test_entity_builder() {
let x = report.tempids.get("x").expect("our tempid has an ID"); let x = report.tempids.get("x").expect("our tempid has an ID");
let y = report.tempids.get("y").expect("our tempid has an ID"); let y = report.tempids.get("y").expect("our tempid has an ID");
assert_eq!( assert_eq!(
conn.lookup_value_for_attribute(&mut sqlite, *y, &foo_ref) conn.lookup_value_for_attribute(&sqlite, *y, &foo_ref)
.expect("lookup succeeded"), .expect("lookup succeeded"),
Some(TypedValue::Ref(*x)) Some(TypedValue::Ref(*x))
); );

View file

@ -8,8 +8,6 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the // CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License. // specific language governing permissions and limitations under the License.
use mentat;
#[test] #[test]
fn can_import_sqlite() { fn can_import_sqlite() {
// From https://github.com/jgallagher/rusqlite#rusqlite. // From https://github.com/jgallagher/rusqlite#rusqlite.

View file

@ -179,10 +179,9 @@ fn test_simple_pull() {
capitol_district_pull.into(), capitol_district_pull.into(),
TypedValue::Ref(beacon).into(), TypedValue::Ref(beacon).into(),
beacon_district_pull.into(), beacon_district_pull.into(),
] ],
.into(),
}; };
assert_eq!(results, expected.clone()); assert_eq!(results, expected);
// We can also prepare the query. // We can also prepare the query.
let reader = store.begin_read().expect("read"); let reader = store.begin_read().expect("read");

View file

@ -8,15 +8,11 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the // CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License. // specific language governing permissions and limitations under the License.
use time;
#[macro_use] #[macro_use]
extern crate mentat; extern crate mentat;
use mentat_db;
// TODO: when we switch to `failure`, make this more humane. // TODO: when we switch to `failure`, make this more humane.
use query_algebrizer_traits; // For errors; //use query_algebrizer_traits; // For errors;
use std::str::FromStr; use std::str::FromStr;
@ -277,7 +273,7 @@ fn test_instants_and_uuids() {
.unwrap(); .unwrap();
let r = conn let r = conn
.q_once( .q_once(
&mut c, &c,
r#"[:find [?x ?u ?when] r#"[:find [?x ?u ?when]
:where [?x :foo/uuid ?u ?tx] :where [?x :foo/uuid ?u ?tx]
[?tx :db/txInstant ?when]]"#, [?tx :db/txInstant ?when]]"#,
@ -340,7 +336,7 @@ fn test_tx() {
) )
.expect("successful transaction"); .expect("successful transaction");
let r = conn.q_once(&mut c, let r = conn.q_once(&c,
r#"[:find ?tx r#"[:find ?tx
:where [?x :foo/uuid #uuid "cf62d552-6569-4d1b-b667-04703041dfc4" ?tx]]"#, None) :where [?x :foo/uuid #uuid "cf62d552-6569-4d1b-b667-04703041dfc4" ?tx]]"#, None)
.expect("results") .expect("results")
@ -393,7 +389,7 @@ fn test_tx_as_input() {
let inputs = QueryInputs::with_value_sequence(vec![tx]); let inputs = QueryInputs::with_value_sequence(vec![tx]);
let r = conn let r = conn
.q_once( .q_once(
&mut c, &c,
r#"[:find ?uuid r#"[:find ?uuid
:in ?tx :in ?tx
:where [?x :foo/uuid ?uuid ?tx]]"#, :where [?x :foo/uuid ?uuid ?tx]]"#,
@ -453,7 +449,7 @@ fn test_fulltext() {
let r = conn let r = conn
.q_once( .q_once(
&mut c, &c,
r#"[:find [?x ?val ?score] r#"[:find [?x ?val ?score]
:where [(fulltext $ :foo/fts "darkness") [[?x ?val _ ?score]]]]"#, :where [(fulltext $ :foo/fts "darkness") [[?x ?val _ ?score]]]]"#,
None, None,
@ -472,7 +468,7 @@ fn test_fulltext() {
) => { ) => {
assert_eq!(x, v); assert_eq!(x, v);
assert_eq!(text.as_str(), "hello darkness my old friend"); assert_eq!(text.as_str(), "hello darkness my old friend");
assert_eq!(score, 0.0f64.into()); assert_eq!(score, 0.0f64);
} }
_ => panic!("Unexpected results."), _ => panic!("Unexpected results."),
} }
@ -494,7 +490,7 @@ fn test_fulltext() {
[(fulltext $ :foo/fts ?term) [[?x ?val]]] [(fulltext $ :foo/fts ?term) [[?x ?val]]]
[?a :foo/term ?term] [?a :foo/term ?term]
]"#; ]"#;
let r = conn.q_once(&mut c, query, None); let r = conn.q_once(&c, query, None);
match r.expect_err("expected query to fail") { match r.expect_err("expected query to fail") {
MentatError::AlgebrizerError( MentatError::AlgebrizerError(
query_algebrizer_traits::errors::AlgebrizerError::InvalidArgument( query_algebrizer_traits::errors::AlgebrizerError::InvalidArgument(
@ -515,7 +511,7 @@ fn test_fulltext() {
:where :where
[?a :foo/term ?term] [?a :foo/term ?term]
[(fulltext $ :foo/fts ?a) [[?x ?val]]]]"#; [(fulltext $ :foo/fts ?a) [[?x ?val]]]]"#;
let r = conn.q_once(&mut c, query, None); let r = conn.q_once(&c, query, None);
match r.expect_err("expected query to fail") { match r.expect_err("expected query to fail") {
MentatError::AlgebrizerError( MentatError::AlgebrizerError(
query_algebrizer_traits::errors::AlgebrizerError::InvalidArgument( query_algebrizer_traits::errors::AlgebrizerError::InvalidArgument(
@ -541,7 +537,7 @@ fn test_fulltext() {
Variable::from_valid_name("?a"), Variable::from_valid_name("?a"),
TypedValue::Ref(a), TypedValue::Ref(a),
)]); )]);
let r = conn.q_once(&mut c, query, inputs).expect("results").into(); let r = conn.q_once(&c, query, inputs).expect("results").into();
match r { match r {
QueryResults::Rel(rels) => { QueryResults::Rel(rels) => {
let values: Vec<Vec<Binding>> = rels.into_iter().collect(); let values: Vec<Vec<Binding>> = rels.into_iter().collect();
@ -587,7 +583,7 @@ fn test_instant_range_query() {
let r = conn let r = conn
.q_once( .q_once(
&mut c, &c,
r#"[:find [?x ...] r#"[:find [?x ...]
:order (asc ?date) :order (asc ?date)
:where :where
@ -881,7 +877,7 @@ fn test_type_reqs() {
); );
let results = conn let results = conn
.q_once( .q_once(
&mut c, &c,
&q, &q,
QueryInputs::with_value_sequence(vec![( QueryInputs::with_value_sequence(vec![(
Variable::from_valid_name("?e"), Variable::from_valid_name("?e"),
@ -917,7 +913,7 @@ fn test_type_reqs() {
let res = conn let res = conn
.q_once( .q_once(
&mut c, &c,
longs_query, longs_query,
QueryInputs::with_value_sequence(vec![( QueryInputs::with_value_sequence(vec![(
Variable::from_valid_name("?e"), Variable::from_valid_name("?e"),

View file

@ -50,7 +50,7 @@ mod tolstoy_tests {
where where
T: Iterator<Item = TxPart>, T: Iterator<Item = TxPart>,
{ {
self.tx_count = self.tx_count + 1; self.tx_count += 1;
Ok(()) Ok(())
} }
@ -77,7 +77,7 @@ mod tolstoy_tests {
where where
T: Iterator<Item = TxPart>, T: Iterator<Item = TxPart>,
{ {
let datoms = self.txes.entry(tx_id).or_insert(vec![]); let datoms = self.txes.entry(tx_id).or_insert_with(|| vec![]);
datoms.extend(d); datoms.extend(d);
Ok(()) Ok(())
} }
@ -135,7 +135,7 @@ mod tolstoy_tests {
let mut txs = vec![]; let mut txs = vec![];
for tx_uuid in &self.rowid_tx[rowid_range] { for tx_uuid in &self.rowid_tx[rowid_range] {
txs.push(Tx { txs.push(Tx {
tx: tx_uuid.clone(), tx: *tx_uuid,
parts: self.transactions.get(tx_uuid).unwrap().clone(), parts: self.transactions.get(tx_uuid).unwrap().clone(),
}); });
} }
@ -143,16 +143,15 @@ mod tolstoy_tests {
} }
fn set_head(&mut self, tx: &Uuid) -> Result<()> { fn set_head(&mut self, tx: &Uuid) -> Result<()> {
self.head = tx.clone(); self.head = *tx;
Ok(()) Ok(())
} }
fn put_chunk(&mut self, tx: &Uuid, payload: &TxPart) -> Result<()> { fn put_chunk(&mut self, tx: &Uuid, payload: &TxPart) -> Result<()> {
match self.chunks.entry(tx.clone()) { match self.chunks.entry(*tx) {
Entry::Occupied(_) => panic!("trying to overwrite chunk"), Entry::Occupied(_) => panic!("trying to overwrite chunk"),
Entry::Vacant(entry) => { Entry::Vacant(entry) => {
entry.insert(payload.clone()); entry.insert(payload.clone());
()
} }
} }
Ok(()) Ok(())
@ -162,15 +161,15 @@ mod tolstoy_tests {
&mut self, &mut self,
tx: &Uuid, tx: &Uuid,
_parent_tx: &Uuid, _parent_tx: &Uuid,
chunk_txs: &Vec<Uuid>, chunk_txs: &[Uuid],
) -> Result<()> { ) -> Result<()> {
let mut parts = vec![]; let mut parts = vec![];
for chunk_tx in chunk_txs { for chunk_tx in chunk_txs {
parts.push(self.chunks.get(chunk_tx).unwrap().clone()); parts.push(self.chunks.get(chunk_tx).unwrap().clone());
} }
self.transactions.insert(tx.clone(), parts); self.transactions.insert(*tx, parts);
self.rowid_tx.push(tx.clone()); self.rowid_tx.push(*tx);
self.tx_rowid.insert(tx.clone(), self.rowid_tx.len() - 1); self.tx_rowid.insert(*tx, self.rowid_tx.len() - 1);
Ok(()) Ok(())
} }
} }
@ -206,7 +205,7 @@ mod tolstoy_tests {
let mut index = 1; let mut index = 1;
$( $(
assert_matches!(parts_to_datoms(&$conn.current_schema(), &txs[index].parts), $tx); assert_matches!(parts_to_datoms(&$conn.current_schema(), &txs[index].parts), $tx);
index = index + 1; index += 1;
)* )*
assert_eq!(index, txs.len()); assert_eq!(index, txs.len());
@ -278,7 +277,7 @@ mod tolstoy_tests {
assert_eq!(3, txes.keys().count()); assert_eq!(3, txes.keys().count());
assert_tx_datoms_count(&txes, 2, 2); assert_tx_datoms_count(&txes, 2, 2);
first_tx = txes.keys().nth(1).expect("first non-bootstrap tx").clone(); first_tx = *txes.keys().nth(1).expect("first non-bootstrap tx");
} }
let ids = conn let ids = conn

View file

@ -14,9 +14,6 @@ extern crate lazy_static;
#[macro_use] #[macro_use]
extern crate mentat; extern crate mentat;
use mentat_db;
use rusqlite;
use mentat::vocabulary; use mentat::vocabulary;
use mentat::vocabulary::{ use mentat::vocabulary::{
@ -114,7 +111,7 @@ fn test_real_world() {
let results = conn let results = conn
.q_once( .q_once(
&mut sqlite, &sqlite,
r#"[:find ?name ?when r#"[:find ?name ?when
:order (asc ?name) :order (asc ?name)
:where [?x :foo/name ?name] :where [?x :foo/name ?name]
@ -126,7 +123,7 @@ fn test_real_world() {
.expect("query succeeded"); .expect("query succeeded");
assert_eq!( assert_eq!(
results, results,
vec![vec![alice, now.clone()], vec![barbara, now.clone()]].into() vec![vec![alice, now.clone()], vec![barbara, now]].into()
); );
} }
@ -152,32 +149,35 @@ fn test_default_attributebuilder_complains() {
#[test] #[test]
fn test_add_vocab() { fn test_add_vocab() {
let bar = vocabulary::AttributeBuilder::helpful() let thing2 = vocabulary::AttributeBuilder::helpful()
.value_type(ValueType::Instant) .value_type(ValueType::Instant)
.multival(false) .multival(false)
.index(true) .index(true)
.build(); .build();
let baz = vocabulary::AttributeBuilder::helpful() let thing3 = vocabulary::AttributeBuilder::helpful()
.value_type(ValueType::String) .value_type(ValueType::String)
.multival(true) .multival(true)
.fulltext(true) .fulltext(true)
.build(); .build();
let bar_only = vec![(kw!(:foo/bar), bar.clone())]; let thing2_only = vec![(kw!(:foo/bar), thing2.clone())];
let baz_only = vec![(kw!(:foo/baz), baz.clone())]; let thing3_only = vec![(kw!(:foo/baz), thing3.clone())];
let bar_and_baz = vec![(kw!(:foo/bar), bar.clone()), (kw!(:foo/baz), baz.clone())]; let thing2_and_thing3 = vec![
(kw!(:foo/bar), thing2.clone()),
(kw!(:foo/baz), thing3.clone()),
];
let foo_v1_a = vocabulary::Definition::new(kw!(:org.mozilla/foo), 1, bar_only.clone()); let thing1_v1_a = vocabulary::Definition::new(kw!(:org.mozilla/foo), 1, thing2_only);
let foo_v1_b = vocabulary::Definition::new(kw!(:org.mozilla/foo), 1, bar_and_baz.clone()); let thing1_v1_b = vocabulary::Definition::new(kw!(:org.mozilla/foo), 1, thing2_and_thing3);
let mut sqlite = mentat_db::db::new_connection("").unwrap(); let mut sqlite = mentat_db::db::new_connection("").unwrap();
let mut conn = Conn::connect(&mut sqlite).unwrap(); let mut conn = Conn::connect(&mut sqlite).unwrap();
let foo_version_query = r#"[:find [?version ?aa] let thing1_version_query = r#"[:find [?version ?aa]
:where :where
[:org.mozilla/foo :db.schema/version ?version] [:org.mozilla/foo :db.schema/version ?version]
[:org.mozilla/foo :db.schema/attribute ?a] [:org.mozilla/foo :db.schema/attribute ?a]
[?a :db/ident ?aa]]"#; [?a :db/ident ?aa]]"#;
let foo_attributes_query = r#"[:find [?aa ...] let thing1_attributes_query = r#"[:find [?aa ...]
:where :where
[:org.mozilla/foo :db.schema/attribute ?a] [:org.mozilla/foo :db.schema/attribute ?a]
[?a :db/ident ?aa]]"#; [?a :db/ident ?aa]]"#;
@ -192,13 +192,13 @@ fn test_add_vocab() {
assert_eq!( assert_eq!(
VocabularyCheck::NotPresent, VocabularyCheck::NotPresent,
in_progress in_progress
.check_vocabulary(&foo_v1_a) .check_vocabulary(&thing1_v1_a)
.expect("check completed") .expect("check completed")
); );
assert_eq!( assert_eq!(
VocabularyCheck::NotPresent, VocabularyCheck::NotPresent,
in_progress in_progress
.check_vocabulary(&foo_v1_b) .check_vocabulary(&thing1_v1_b)
.expect("check completed") .expect("check completed")
); );
@ -206,13 +206,13 @@ fn test_add_vocab() {
assert_eq!( assert_eq!(
VocabularyOutcome::Installed, VocabularyOutcome::Installed,
in_progress in_progress
.ensure_vocabulary(&foo_v1_a) .ensure_vocabulary(&thing1_v1_a)
.expect("ensure succeeded") .expect("ensure succeeded")
); );
// Now we can query to get the vocab. // Now we can query to get the vocab.
let ver_attr = in_progress let ver_attr = in_progress
.q_once(foo_version_query, None) .q_once(thing1_version_query, None)
.into_tuple_result() .into_tuple_result()
.expect("query returns") .expect("query returns")
.expect("a result"); .expect("a result");
@ -228,7 +228,7 @@ fn test_add_vocab() {
// It's still there. // It's still there.
let ver_attr = conn let ver_attr = conn
.q_once(&mut sqlite, foo_version_query, None) .q_once(&sqlite, thing1_version_query, None)
.into_tuple_result() .into_tuple_result()
.expect("query returns") .expect("query returns")
.expect("a result"); .expect("a result");
@ -248,17 +248,17 @@ fn test_add_vocab() {
assert_eq!( assert_eq!(
VocabularyCheck::Present, VocabularyCheck::Present,
in_progress in_progress
.check_vocabulary(&foo_v1_a) .check_vocabulary(&thing1_v1_a)
.expect("check completed") .expect("check completed")
); );
// Checking for v1.b will say that we have work to do. // Checking for v1.b will say that we have work to do.
assert_eq!( assert_eq!(
VocabularyCheck::PresentButMissingAttributes { VocabularyCheck::PresentButMissingAttributes {
attributes: vec![&baz_only[0]], attributes: vec![&thing3_only[0]],
}, },
in_progress in_progress
.check_vocabulary(&foo_v1_b) .check_vocabulary(&thing1_v1_b)
.expect("check completed") .expect("check completed")
); );
@ -266,7 +266,7 @@ fn test_add_vocab() {
assert_eq!( assert_eq!(
VocabularyOutcome::InstalledMissingAttributes, VocabularyOutcome::InstalledMissingAttributes,
in_progress in_progress
.ensure_vocabulary(&foo_v1_b) .ensure_vocabulary(&thing1_v1_b)
.expect("ensure succeeded") .expect("ensure succeeded")
); );
@ -274,13 +274,13 @@ fn test_add_vocab() {
assert_eq!( assert_eq!(
VocabularyCheck::Present, VocabularyCheck::Present,
in_progress in_progress
.check_vocabulary(&foo_v1_a) .check_vocabulary(&thing1_v1_a)
.expect("check completed") .expect("check completed")
); );
assert_eq!( assert_eq!(
VocabularyCheck::Present, VocabularyCheck::Present,
in_progress in_progress
.check_vocabulary(&foo_v1_b) .check_vocabulary(&thing1_v1_b)
.expect("check completed") .expect("check completed")
); );
@ -288,7 +288,7 @@ fn test_add_vocab() {
assert_eq!( assert_eq!(
VocabularyOutcome::Existed, VocabularyOutcome::Existed,
in_progress in_progress
.ensure_vocabulary(&foo_v1_b) .ensure_vocabulary(&thing1_v1_b)
.expect("ensure succeeded") .expect("ensure succeeded")
); );
in_progress.commit().expect("commit succeeded"); in_progress.commit().expect("commit succeeded");
@ -296,7 +296,7 @@ fn test_add_vocab() {
// We have both attributes. // We have both attributes.
let actual_attributes = conn let actual_attributes = conn
.q_once(&mut sqlite, foo_attributes_query, None) .q_once(&sqlite, thing1_attributes_query, None)
.into_coll_result() .into_coll_result()
.expect("query returns"); .expect("query returns");
assert_eq!( assert_eq!(
@ -313,10 +313,13 @@ fn test_add_vocab() {
.value_type(ValueType::Instant) .value_type(ValueType::Instant)
.multival(true) .multival(true)
.build(); .build();
let bar_and_malformed_baz = vec![(kw!(:foo/bar), bar), (kw!(:foo/baz), malformed_baz.clone())]; let bar_and_malformed_baz = vec![
(kw!(:foo/bar), thing2),
(kw!(:foo/baz), malformed_baz.clone()),
];
let foo_v1_malformed = let foo_v1_malformed =
vocabulary::Definition::new(kw!(:org.mozilla/foo), 1, bar_and_malformed_baz.clone()); vocabulary::Definition::new(kw!(:org.mozilla/foo), 1, bar_and_malformed_baz);
// Scoped borrow of `conn`. // Scoped borrow of `conn`.
{ {
@ -331,7 +334,7 @@ fn test_add_vocab() {
assert_eq!(vocab.as_str(), ":org.mozilla/foo"); assert_eq!(vocab.as_str(), ":org.mozilla/foo");
assert_eq!(attr.as_str(), ":foo/baz"); assert_eq!(attr.as_str(), ":foo/baz");
assert_eq!(version, 1); assert_eq!(version, 1);
assert_eq!(&theirs, &baz); assert_eq!(&theirs, &thing3);
assert_eq!(&ours, &malformed_baz); assert_eq!(&ours, &malformed_baz);
} }
_ => panic!(), _ => panic!(),
@ -347,7 +350,7 @@ fn test_add_vocab() {
.multival(true) .multival(true)
.index(true) .index(true)
.build(); .build();
let multival_bar_and_baz = vec![(kw!(:foo/bar), multival_bar), (kw!(:foo/baz), baz.clone())]; let multival_bar_and_baz = vec![(kw!(:foo/bar), multival_bar), (kw!(:foo/baz), thing3)];
let altered_vocabulary = let altered_vocabulary =
vocabulary::Definition::new(kw!(:org.mozilla/foo), 2, multival_bar_and_baz); vocabulary::Definition::new(kw!(:org.mozilla/foo), 2, multival_bar_and_baz);
@ -554,11 +557,8 @@ fn test_upgrade_with_functions() {
}; };
// Apply v1 of each. // Apply v1 of each.
let mut v1_provider = SimpleVocabularySource::with_definitions(vec![ let mut v1_provider =
food_v1.clone(), SimpleVocabularySource::with_definitions(vec![food_v1, movies_v1, people_v1.clone()]);
movies_v1.clone(),
people_v1.clone(),
]);
// Mutable borrow of store. // Mutable borrow of store.
{ {
@ -694,19 +694,17 @@ fn test_upgrade_with_functions() {
.into_iter() .into_iter()
{ {
let mut row = row.into_iter(); let mut row = row.into_iter();
match (row.next(), row.next()) { if let (
( Some(Binding::Scalar(TypedValue::Ref(person))),
Some(Binding::Scalar(TypedValue::Ref(person))), Some(Binding::Scalar(TypedValue::Long(height))),
Some(Binding::Scalar(TypedValue::Long(height))), ) = (row.next(), row.next())
) => { {
// No need to explicitly retract: cardinality-one. // No need to explicitly retract: cardinality-one.
builder.add( builder.add(
KnownEntid(person), KnownEntid(person),
person_height, person_height,
TypedValue::Long(inches_to_cm(height)), TypedValue::Long(inches_to_cm(height)),
)?; )?;
}
_ => {}
} }
} }
} }
@ -715,9 +713,7 @@ fn test_upgrade_with_functions() {
return Ok(()); return Ok(());
} }
ip.transact_builder(builder) ip.transact_builder(builder).and(Ok(())).map_err(|e| e)
.and(Ok(()))
.map_err(|e| e.into())
} }
fn people_v1_to_v2( fn people_v1_to_v2(
@ -781,23 +777,21 @@ fn test_upgrade_with_functions() {
.into_iter() .into_iter()
{ {
let mut row = row.into_iter(); let mut row = row.into_iter();
match (row.next(), row.next()) { if let (
( Some(Binding::Scalar(TypedValue::Ref(food))),
Some(Binding::Scalar(TypedValue::Ref(food))), Some(Binding::Scalar(TypedValue::String(name))),
Some(Binding::Scalar(TypedValue::String(name))), ) = (row.next(), row.next())
) => { {
if name.chars().any(|c| !c.is_lowercase()) { if name.chars().any(|c| !c.is_lowercase()) {
let lowercased = name.to_lowercase(); let lowercased = name.to_lowercase();
println!( println!(
"Need to rename {} from '{}' to '{}'", "Need to rename {} from '{}' to '{}'",
food, name, lowercased food, name, lowercased
); );
let new_name: TypedValue = lowercased.into(); let new_name: TypedValue = lowercased.into();
builder.add(KnownEntid(food), food_name, new_name)?; builder.add(KnownEntid(food), food_name, new_name)?;
}
} }
_ => {}
} }
} }
@ -1055,7 +1049,7 @@ fn test_upgrade_with_functions() {
let people_v3 = vocabulary::Definition { let people_v3 = vocabulary::Definition {
name: kw!(:org.mozilla/people), name: kw!(:org.mozilla/people),
version: 3, version: 3,
attributes: people_v1.attributes.clone(), attributes: people_v1.attributes,
pre: Definition::no_op, pre: Definition::no_op,
post: |ip, from| { post: |ip, from| {
if from.version < 2 { if from.version < 2 {

View file

@ -25,7 +25,7 @@ pub struct BootstrapHelper<'a> {
} }
impl<'a> BootstrapHelper<'a> { impl<'a> BootstrapHelper<'a> {
pub fn new(assumed_bootstrap_tx: &Tx) -> BootstrapHelper { pub fn new(assumed_bootstrap_tx: &Tx) -> BootstrapHelper<'_> {
BootstrapHelper { BootstrapHelper {
parts: DatomsHelper::new(&assumed_bootstrap_tx.parts), parts: DatomsHelper::new(&assumed_bootstrap_tx.parts),
} }

View file

@ -15,12 +15,12 @@ use core_traits::{Entid, TypedValue};
/// A primitive query interface geared toward processing bootstrap-like sets of datoms. /// A primitive query interface geared toward processing bootstrap-like sets of datoms.
pub struct DatomsHelper<'a> { pub struct DatomsHelper<'a> {
parts: &'a Vec<TxPart>, parts: &'a [TxPart],
} }
impl<'a> DatomsHelper<'a> { impl<'a> DatomsHelper<'a> {
pub fn new(parts: &'a Vec<TxPart>) -> DatomsHelper { pub fn new(parts: &[TxPart]) -> DatomsHelper<'_> {
DatomsHelper { parts: parts } DatomsHelper { parts }
} }
// TODO these are obviously quite inefficient // TODO these are obviously quite inefficient

View file

@ -10,8 +10,6 @@
// TODO: could hide this behind #[cfg(test)], since this is only for test use. // TODO: could hide this behind #[cfg(test)], since this is only for test use.
use rusqlite;
use uuid::Uuid; use uuid::Uuid;
use edn::entities::EntidOrIdent; use edn::entities::EntidOrIdent;
@ -51,8 +49,8 @@ pub fn txs_after(sqlite: &rusqlite::Connection, schema: &Schema, after: Entid) -
tx.parts.push(TxPart { tx.parts.push(TxPart {
partitions: None, partitions: None,
e: e, e,
a: a, a,
v: TypedValue::from_edn_value(&datom.v).unwrap(), v: TypedValue::from_edn_value(&datom.v).unwrap(),
tx: datom.tx, tx: datom.tx,
added: datom.added.unwrap(), added: datom.added.unwrap(),
@ -81,6 +79,6 @@ pub fn part_to_datom(schema: &Schema, part: &TxPart) -> Datom {
} }
} }
pub fn parts_to_datoms(schema: &Schema, parts: &Vec<TxPart>) -> Datoms { pub fn parts_to_datoms(schema: &Schema, parts: &[TxPart]) -> Datoms {
Datoms(parts.iter().map(|p| part_to_datom(schema, p)).collect()) Datoms(parts.iter().map(|p| part_to_datom(schema, p)).collect())
} }

View file

@ -8,53 +8,32 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the // CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License. // specific language governing permissions and limitations under the License.
extern crate failure;
#[macro_use] #[macro_use]
extern crate lazy_static; extern crate lazy_static;
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
extern crate edn;
extern crate hyper;
// TODO https://github.com/mozilla/mentat/issues/569 // TODO https://github.com/mozilla/mentat/issues/569
// extern crate hyper_tls; // extern crate hyper_tls;
extern crate futures;
extern crate serde;
extern crate serde_cbor;
extern crate serde_json;
extern crate tokio_core;
extern crate log;
extern crate mentat_db;
extern crate db_traits;
extern crate mentat_core;
#[macro_use] #[macro_use]
extern crate core_traits; extern crate core_traits;
extern crate public_traits;
extern crate rusqlite;
extern crate uuid;
extern crate mentat_transaction;
extern crate tolstoy_traits;
pub mod bootstrap; pub mod bootstrap;
pub mod metadata; pub mod metadata;
pub use metadata::{PartitionsTable, SyncMetadata}; pub use crate::metadata::{PartitionsTable, SyncMetadata};
mod datoms; mod datoms;
pub mod debug; pub mod debug;
pub mod remote_client; pub mod remote_client;
pub use remote_client::RemoteClient; pub use crate::remote_client::RemoteClient;
pub mod schema; pub mod schema;
pub mod syncer; pub mod syncer;
pub use syncer::{SyncFollowup, SyncReport, SyncResult, Syncer}; pub use crate::syncer::{SyncFollowup, SyncReport, SyncResult, Syncer};
pub mod logger; pub mod logger;
pub mod tx_mapper; pub mod tx_mapper;
mod tx_uploader; mod tx_uploader;
pub use tx_mapper::TxMapper; pub use crate::tx_mapper::TxMapper;
pub mod tx_processor; pub mod tx_processor;
pub mod types; pub mod types;
pub use types::{GlobalTransactionLog, Tx, TxPart}; pub use crate::types::{GlobalTransactionLog, Tx, TxPart};

View file

@ -10,7 +10,6 @@
#![allow(dead_code)] #![allow(dead_code)]
use rusqlite;
use uuid::Uuid; use uuid::Uuid;
use core_traits::Entid; use core_traits::Entid;
@ -45,13 +44,10 @@ pub enum PartitionsTable {
impl SyncMetadata { impl SyncMetadata {
pub fn new(root: Entid, head: Entid) -> SyncMetadata { pub fn new(root: Entid, head: Entid) -> SyncMetadata {
SyncMetadata { SyncMetadata { root, head }
root: root,
head: head,
}
} }
pub fn remote_head(tx: &rusqlite::Transaction) -> Result<Uuid> { pub fn remote_head(tx: &rusqlite::Transaction<'_>) -> Result<Uuid> {
let uuid_bytes = tx.query_row( let uuid_bytes = tx.query_row(
"SELECT value FROM tolstoy_metadata WHERE key = ?", "SELECT value FROM tolstoy_metadata WHERE key = ?",
rusqlite::params![&schema::REMOTE_HEAD_KEY], rusqlite::params![&schema::REMOTE_HEAD_KEY],
@ -63,7 +59,7 @@ impl SyncMetadata {
Ok(Uuid::from_slice(uuid_bytes.as_slice())?) Ok(Uuid::from_slice(uuid_bytes.as_slice())?)
} }
pub fn set_remote_head(tx: &rusqlite::Transaction, uuid: &Uuid) -> Result<()> { pub fn set_remote_head(tx: &rusqlite::Transaction<'_>, uuid: &Uuid) -> Result<()> {
let uuid_bytes = uuid.as_bytes().to_vec(); let uuid_bytes = uuid.as_bytes().to_vec();
let updated = tx.execute( let updated = tx.execute(
"UPDATE tolstoy_metadata SET value = ? WHERE key = ?", "UPDATE tolstoy_metadata SET value = ? WHERE key = ?",
@ -78,8 +74,8 @@ impl SyncMetadata {
} }
pub fn set_remote_head_and_map( pub fn set_remote_head_and_map(
tx: &mut rusqlite::Transaction, tx: &mut rusqlite::Transaction<'_>,
mapping: LocalGlobalTxMapping, mapping: LocalGlobalTxMapping<'_>,
) -> Result<()> { ) -> Result<()> {
SyncMetadata::set_remote_head(tx, mapping.remote)?; SyncMetadata::set_remote_head(tx, mapping.remote)?;
TxMapper::set_lg_mapping(tx, mapping)?; TxMapper::set_lg_mapping(tx, mapping)?;
@ -88,13 +84,13 @@ impl SyncMetadata {
// TODO Functions below start to blur the line between mentat-proper and tolstoy... // TODO Functions below start to blur the line between mentat-proper and tolstoy...
pub fn get_partitions( pub fn get_partitions(
tx: &rusqlite::Transaction, tx: &rusqlite::Transaction<'_>,
parts_table: PartitionsTable, parts_table: PartitionsTable,
) -> Result<PartitionMap> { ) -> Result<PartitionMap> {
match parts_table { match parts_table {
PartitionsTable::Core => db::read_partition_map(tx).map_err(|e| e.into()), PartitionsTable::Core => db::read_partition_map(tx).map_err(|e| e.into()),
PartitionsTable::Tolstoy => { PartitionsTable::Tolstoy => {
let mut stmt: ::rusqlite::Statement = let mut stmt: ::rusqlite::Statement<'_> =
tx.prepare("SELECT part, start, end, idx, allow_excision FROM tolstoy_parts")?; tx.prepare("SELECT part, start, end, idx, allow_excision FROM tolstoy_parts")?;
let m: Result<PartitionMap> = stmt let m: Result<PartitionMap> = stmt
.query_and_then(rusqlite::params![], |row| -> Result<(String, Partition)> { .query_and_then(rusqlite::params![], |row| -> Result<(String, Partition)> {
@ -109,8 +105,8 @@ impl SyncMetadata {
} }
} }
pub fn root_and_head_tx(tx: &rusqlite::Transaction) -> Result<(Entid, Entid)> { pub fn root_and_head_tx(tx: &rusqlite::Transaction<'_>) -> Result<(Entid, Entid)> {
let mut stmt: ::rusqlite::Statement = tx.prepare( let mut stmt: ::rusqlite::Statement<'_> = tx.prepare(
"SELECT tx FROM timelined_transactions WHERE timeline = 0 GROUP BY tx ORDER BY tx", "SELECT tx FROM timelined_transactions WHERE timeline = 0 GROUP BY tx ORDER BY tx",
)?; )?;
let txs: Vec<_> = stmt let txs: Vec<_> = stmt
@ -121,10 +117,10 @@ impl SyncMetadata {
let mut txs = txs.into_iter(); let mut txs = txs.into_iter();
let root_tx = match txs.nth(0) { let root_tx = match txs.next() {
None => bail!(TolstoyError::UnexpectedState(format!( None => bail!(TolstoyError::UnexpectedState(
"Could not get root tx" "Could not get root tx".to_string()
))), )),
Some(t) => t?, Some(t) => t?,
}; };
@ -134,12 +130,15 @@ impl SyncMetadata {
} }
} }
pub fn local_txs(db_tx: &rusqlite::Transaction, after: Option<Entid>) -> Result<Vec<Entid>> { pub fn local_txs(
db_tx: &rusqlite::Transaction<'_>,
after: Option<Entid>,
) -> Result<Vec<Entid>> {
let after_clause = match after { let after_clause = match after {
Some(t) => format!("WHERE timeline = 0 AND tx > {}", t), Some(t) => format!("WHERE timeline = 0 AND tx > {}", t),
None => format!("WHERE timeline = 0"), None => "WHERE timeline = 0".to_string(),
}; };
let mut stmt: ::rusqlite::Statement = db_tx.prepare(&format!( let mut stmt: ::rusqlite::Statement<'_> = db_tx.prepare(&format!(
"SELECT tx FROM timelined_transactions {} GROUP BY tx ORDER BY tx", "SELECT tx FROM timelined_transactions {} GROUP BY tx ORDER BY tx",
after_clause after_clause
))?; ))?;
@ -157,7 +156,7 @@ impl SyncMetadata {
Ok(all) Ok(all)
} }
pub fn is_tx_empty(db_tx: &rusqlite::Transaction, tx_id: Entid) -> Result<bool> { pub fn is_tx_empty(db_tx: &rusqlite::Transaction<'_>, tx_id: Entid) -> Result<bool> {
let count: i64 = db_tx.query_row("SELECT count(rowid) FROM timelined_transactions WHERE timeline = 0 AND tx = ? AND e != ?", rusqlite::params![&tx_id, &tx_id], |row| { let count: i64 = db_tx.query_row("SELECT count(rowid) FROM timelined_transactions WHERE timeline = 0 AND tx = ? AND e != ?", rusqlite::params![&tx_id, &tx_id], |row| {
Ok(row.get(0)?) Ok(row.get(0)?)
})?; })?;
@ -165,7 +164,7 @@ impl SyncMetadata {
} }
pub fn has_entity_assertions_in_tx( pub fn has_entity_assertions_in_tx(
db_tx: &rusqlite::Transaction, db_tx: &rusqlite::Transaction<'_>,
e: Entid, e: Entid,
tx_id: Entid, tx_id: Entid,
) -> Result<bool> { ) -> Result<bool> {

View file

@ -10,14 +10,11 @@
#![allow(dead_code)] #![allow(dead_code)]
use std;
use hyper::{body, header, Body, Client, Method, Request, StatusCode}; use hyper::{body, header, Body, Client, Method, Request, StatusCode};
use hyper_tls::HttpsConnector; use hyper_tls::HttpsConnector;
// TODO: https://github.com/mozilla/mentat/issues/570 // TODO: https://github.com/mozilla/mentat/issues/570
// use serde_cbor; // use serde_cbor;
use futures::executor::block_on; use futures::executor::block_on;
use serde_json;
use uuid::Uuid; use uuid::Uuid;
use crate::logger::d; use crate::logger::d;
@ -33,7 +30,7 @@ struct SerializedHead {
#[derive(Serialize)] #[derive(Serialize)]
struct SerializedTransaction<'a> { struct SerializedTransaction<'a> {
parent: &'a Uuid, parent: &'a Uuid,
chunks: &'a Vec<Uuid>, chunks: &'a [Uuid],
} }
#[derive(Deserialize)] #[derive(Deserialize)]
@ -59,8 +56,8 @@ pub struct RemoteClient {
impl RemoteClient { impl RemoteClient {
pub fn new(base_uri: String, user_uuid: Uuid) -> Self { pub fn new(base_uri: String, user_uuid: Uuid) -> Self {
RemoteClient { RemoteClient {
base_uri: base_uri, base_uri,
user_uuid: user_uuid, user_uuid,
} }
} }
@ -77,7 +74,7 @@ impl RemoteClient {
let https = HttpsConnector::new(); let https = HttpsConnector::new();
let client = Client::builder().build::<_, Body>(https); let client = Client::builder().build::<_, Body>(https);
d(&format!("client")); d(&"client".to_string());
let uri = uri.parse()?; let uri = uri.parse()?;
@ -129,7 +126,7 @@ impl RemoteClient {
let https = HttpsConnector::new(); let https = HttpsConnector::new();
let client = Client::builder().build::<_, Body>(https); let client = Client::builder().build::<_, Body>(https);
d(&format!("client")); d(&"client".to_string());
let uri = format!( let uri = format!(
"{}/transactions?from={}", "{}/transactions?from={}",
@ -159,7 +156,7 @@ impl RemoteClient {
let https = HttpsConnector::new(); let https = HttpsConnector::new();
let client = Client::builder().build::<_, Body>(https); let client = Client::builder().build::<_, Body>(https);
d(&format!("client")); d(&"client".to_string());
let uri = format!( let uri = format!(
"{}/transactions/{}", "{}/transactions/{}",
@ -190,7 +187,7 @@ impl RemoteClient {
let https = HttpsConnector::new(); let https = HttpsConnector::new();
let client = Client::builder().build::<_, Body>(https); let client = Client::builder().build::<_, Body>(https);
d(&format!("client")); d(&"client".to_string());
let uri = format!("{}/chunks/{}", self.bound_base_uri(), chunk_uuid); let uri = format!("{}/chunks/{}", self.bound_base_uri(), chunk_uuid);
let uri = uri.parse()?; let uri = uri.parse()?;
@ -221,7 +218,7 @@ impl GlobalTransactionLog for RemoteClient {
fn set_head(&mut self, uuid: &Uuid) -> Result<()> { fn set_head(&mut self, uuid: &Uuid) -> Result<()> {
// {"head": uuid} // {"head": uuid}
let head = SerializedHead { head: uuid.clone() }; let head = SerializedHead { head: *uuid };
let uri = format!("{}/head", self.bound_base_uri()); let uri = format!("{}/head", self.bound_base_uri());
let json = serde_json::to_string(&head)?; let json = serde_json::to_string(&head)?;
@ -249,7 +246,7 @@ impl GlobalTransactionLog for RemoteClient {
} }
tx_list.push(Tx { tx_list.push(Tx {
tx: tx.into(), tx,
parts: tx_parts, parts: tx_parts,
}); });
} }
@ -263,12 +260,12 @@ impl GlobalTransactionLog for RemoteClient {
&mut self, &mut self,
transaction_uuid: &Uuid, transaction_uuid: &Uuid,
parent_uuid: &Uuid, parent_uuid: &Uuid,
chunks: &Vec<Uuid>, chunks: &[Uuid],
) -> Result<()> { ) -> Result<()> {
// {"parent": uuid, "chunks": [chunk1, chunk2...]} // {"parent": uuid, "chunks": [chunk1, chunk2...]}
let transaction = SerializedTransaction { let transaction = SerializedTransaction {
parent: parent_uuid, parent: parent_uuid,
chunks: chunks, chunks,
}; };
let uri = format!( let uri = format!(

View file

@ -8,8 +8,6 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the // CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License. // specific language governing permissions and limitations under the License.
use rusqlite;
use mentat_db::V1_PARTS as BOOTSTRAP_PARTITIONS; use mentat_db::V1_PARTS as BOOTSTRAP_PARTITIONS;
use public_traits::errors::Result; use public_traits::errors::Result;
@ -33,7 +31,7 @@ lazy_static! {
}; };
} }
pub fn ensure_current_version(tx: &mut rusqlite::Transaction) -> Result<()> { pub fn ensure_current_version(tx: &mut rusqlite::Transaction<'_>) -> Result<()> {
for statement in (&SCHEMA_STATEMENTS).iter() { for statement in (&SCHEMA_STATEMENTS).iter() {
tx.execute(statement, rusqlite::params![])?; tx.execute(statement, rusqlite::params![])?;
} }
@ -79,11 +77,11 @@ pub mod tests {
conn conn
} }
pub fn setup_tx_bare<'a>(conn: &'a mut rusqlite::Connection) -> rusqlite::Transaction<'a> { pub fn setup_tx_bare(conn: &mut rusqlite::Connection) -> rusqlite::Transaction {
conn.transaction().expect("tx") conn.transaction().expect("tx")
} }
pub fn setup_tx<'a>(conn: &'a mut rusqlite::Connection) -> rusqlite::Transaction<'a> { pub fn setup_tx(conn: &mut rusqlite::Connection) -> rusqlite::Transaction {
let mut tx = conn.transaction().expect("tx"); let mut tx = conn.transaction().expect("tx");
ensure_current_version(&mut tx).expect("connection setup"); ensure_current_version(&mut tx).expect("connection setup");
tx tx
@ -137,22 +135,20 @@ pub mod tests {
let test_uuid = Uuid::new_v4(); let test_uuid = Uuid::new_v4();
{ {
let uuid_bytes = test_uuid.as_bytes().to_vec(); let uuid_bytes = test_uuid.as_bytes().to_vec();
match tx.execute( if let Err(e) = tx.execute(
"UPDATE tolstoy_metadata SET value = ? WHERE key = ?", "UPDATE tolstoy_metadata SET value = ? WHERE key = ?",
rusqlite::params![&uuid_bytes, &REMOTE_HEAD_KEY], rusqlite::params![&uuid_bytes, &REMOTE_HEAD_KEY],
) { ) {
Err(e) => panic!("Error running an update: {}", e), panic!("Error running an update: {}", e)
_ => (),
} }
} }
let new_idx = USER0 + 1; let new_idx = USER0 + 1;
match tx.execute( if let Err(e) = tx.execute(
"UPDATE tolstoy_parts SET idx = ? WHERE part = ?", "UPDATE tolstoy_parts SET idx = ? WHERE part = ?",
rusqlite::params![&new_idx, &PARTITION_USER], rusqlite::params![&new_idx, &PARTITION_USER],
) { ) {
Err(e) => panic!("Error running an update: {}", e), panic!("Error running an update: {}", e)
_ => (),
} }
assert!(ensure_current_version(&mut tx).is_ok()); assert!(ensure_current_version(&mut tx).is_ok());

View file

@ -12,7 +12,6 @@ use std::fmt;
use std::collections::HashSet; use std::collections::HashSet;
use rusqlite;
use uuid::Uuid; use uuid::Uuid;
use core_traits::{Entid, KnownEntid, TypedValue}; use core_traits::{Entid, KnownEntid, TypedValue};
@ -39,6 +38,7 @@ use crate::types::{GlobalTransactionLog, LocalTx, Tx, TxPart};
use tolstoy_traits::errors::TolstoyError; use tolstoy_traits::errors::TolstoyError;
use crate::logger::d; use crate::logger::d;
use crate::syncer;
pub struct Syncer {} pub struct Syncer {}
@ -49,7 +49,7 @@ pub enum SyncFollowup {
} }
impl fmt::Display for SyncFollowup { impl fmt::Display for SyncFollowup {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
SyncFollowup::None => write!(f, "None"), SyncFollowup::None => write!(f, "None"),
SyncFollowup::FullSync => write!(f, "Full sync"), SyncFollowup::FullSync => write!(f, "Full sync"),
@ -73,7 +73,7 @@ pub enum SyncResult {
} }
impl fmt::Display for SyncReport { impl fmt::Display for SyncReport {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
SyncReport::IncompatibleRemoteBootstrap(local, remote) => write!( SyncReport::IncompatibleRemoteBootstrap(local, remote) => write!(
f, f,
@ -94,7 +94,7 @@ impl fmt::Display for SyncReport {
} }
impl fmt::Display for SyncResult { impl fmt::Display for SyncResult {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
SyncResult::Atomic(report) => write!(f, "Single atomic sync: {}", report), SyncResult::Atomic(report) => write!(f, "Single atomic sync: {}", report),
SyncResult::NonAtomic(reports) => { SyncResult::NonAtomic(reports) => {
@ -176,6 +176,12 @@ impl LocalTxSet {
} }
} }
impl Default for syncer::LocalTxSet {
fn default() -> Self {
Self::new()
}
}
impl TxReceiver<Vec<LocalTx>> for LocalTxSet { impl TxReceiver<Vec<LocalTx>> for LocalTxSet {
fn tx<T>(&mut self, tx_id: Entid, datoms: &mut T) -> Result<()> fn tx<T>(&mut self, tx_id: Entid, datoms: &mut T) -> Result<()>
where where
@ -216,7 +222,7 @@ impl Syncer {
/// Upload local txs: (from_tx, HEAD]. Remote head is necessary here because we need to specify /// Upload local txs: (from_tx, HEAD]. Remote head is necessary here because we need to specify
/// "parent" for each transaction we'll upload; remote head will be first transaction's parent. /// "parent" for each transaction we'll upload; remote head will be first transaction's parent.
fn fast_forward_remote<R>( fn fast_forward_remote<R>(
db_tx: &mut rusqlite::Transaction, db_tx: &mut rusqlite::Transaction<'_>,
from_tx: Option<Entid>, from_tx: Option<Entid>,
remote_client: &mut R, remote_client: &mut R,
remote_head: &Uuid, remote_head: &Uuid,
@ -262,7 +268,7 @@ impl Syncer {
Ok(()) Ok(())
} }
fn local_tx_for_uuid(db_tx: &rusqlite::Transaction, uuid: &Uuid) -> Result<Entid> { fn local_tx_for_uuid(db_tx: &rusqlite::Transaction<'_>, uuid: &Uuid) -> Result<Entid> {
match TxMapper::get_tx_for_uuid(db_tx, uuid)? { match TxMapper::get_tx_for_uuid(db_tx, uuid)? {
Some(t) => Ok(t), Some(t) => Ok(t),
None => bail!(TolstoyError::TxIncorrectlyMapped(0)), None => bail!(TolstoyError::TxIncorrectlyMapped(0)),
@ -282,8 +288,7 @@ impl Syncer {
if part.a == entids::DB_TX_INSTANT { if part.a == entids::DB_TX_INSTANT {
e = EntityPlace::TxFunction(TxFunction { e = EntityPlace::TxFunction(TxFunction {
op: PlainSymbol("transaction-tx".to_string()), op: PlainSymbol("transaction-tx".to_string()),
}) });
.into();
} else { } else {
e = KnownEntid(part.e).into(); e = KnownEntid(part.e).into();
} }
@ -337,7 +342,7 @@ impl Syncer {
None => { None => {
return Ok(SyncReport::BadRemoteState( return Ok(SyncReport::BadRemoteState(
"Missing partition map in incoming transaction".to_string(), "Missing partition map in incoming transaction".to_string(),
)) ));
} }
}; };
@ -349,7 +354,7 @@ impl Syncer {
// Allocate space for the incoming entids. // Allocate space for the incoming entids.
in_progress.partition_map = partition_map; in_progress.partition_map = partition_map;
let report = in_progress.transact_builder(builder)?; let report = in_progress.transact_builder(builder)?;
last_tx = Some((report.tx_id, tx.tx.clone())); last_tx = Some((report.tx_id, tx.tx));
} }
// We've just transacted a new tx, and generated a new tx entid. Map it to the corresponding // We've just transacted a new tx, and generated a new tx entid. Map it to the corresponding
@ -365,11 +370,11 @@ impl Syncer {
} }
fn merge( fn merge(
ip: &mut InProgress, ip: &mut InProgress<'_, '_>,
incoming_txs: Vec<Tx>, incoming_txs: Vec<Tx>,
mut local_txs_to_merge: Vec<LocalTx>, mut local_txs_to_merge: Vec<LocalTx>,
) -> Result<SyncReport> { ) -> Result<SyncReport> {
d(&format!("Rewinding local transactions.")); d(&"Rewinding local transactions.".to_string());
// 1) Rewind local to shared root. // 1) Rewind local to shared root.
local_txs_to_merge.sort(); // TODO sort at the interface level? local_txs_to_merge.sort(); // TODO sort at the interface level?
@ -383,16 +388,15 @@ impl Syncer {
// excisions are prohibited in the 'tx' partition, so this should hold... // excisions are prohibited in the 'tx' partition, so this should hold...
local_txs_to_merge[0].tx - 1, local_txs_to_merge[0].tx - 1,
)?; )?;
match new_schema { if let Some(schema) = new_schema {
Some(schema) => ip.schema = schema, ip.schema = schema
None => (),
}; };
ip.partition_map = new_partition_map; ip.partition_map = new_partition_map;
// 2) Transact incoming. // 2) Transact incoming.
// 2.1) Prepare remote tx tuples (TermBuilder, PartitionMap, Uuid), which represent // 2.1) Prepare remote tx tuples (TermBuilder, PartitionMap, Uuid), which represent
// a remote transaction, its global identifier and partitions after it's applied. // a remote transaction, its global identifier and partitions after it's applied.
d(&format!("Transacting incoming...")); d(&"Transacting incoming...".to_string());
let mut builders = vec![]; let mut builders = vec![];
for remote_tx in incoming_txs { for remote_tx in incoming_txs {
let mut builder = TermBuilder::new(); let mut builder = TermBuilder::new();
@ -402,7 +406,7 @@ impl Syncer {
None => { None => {
return Ok(SyncReport::BadRemoteState( return Ok(SyncReport::BadRemoteState(
"Missing partition map in incoming transaction".to_string(), "Missing partition map in incoming transaction".to_string(),
)) ));
} }
}; };
@ -423,7 +427,7 @@ impl Syncer {
remote_report = Some((ip.transact_builder(builder)?.tx_id, remote_tx)); remote_report = Some((ip.transact_builder(builder)?.tx_id, remote_tx));
} }
d(&format!("Transacting local on top of incoming...")); d(&"Transacting local on top of incoming...".to_string());
// 3) Rebase local transactions on top of remote. // 3) Rebase local transactions on top of remote.
let mut clean_rebase = true; let mut clean_rebase = true;
for local_tx in local_txs_to_merge { for local_tx in local_txs_to_merge {
@ -617,7 +621,7 @@ impl Syncer {
continue; continue;
} }
d(&format!("Savepoint before transacting a local tx...")); d(&"Savepoint before transacting a local tx...".to_string());
ip.savepoint("speculative_local")?; ip.savepoint("speculative_local")?;
d(&format!( d(&format!(
@ -634,19 +638,16 @@ impl Syncer {
// Instead, we simply query the database, checking if transaction produced // Instead, we simply query the database, checking if transaction produced
// any schema-altering datoms. // any schema-altering datoms.
for e in might_alter_installed_attributes.iter() { for e in might_alter_installed_attributes.iter() {
match report.tempids.get(&format!("{}", e)) { if let Some(resolved_e) = report.tempids.get(&format!("{}", e)) {
Some(resolved_e) => { if SyncMetadata::has_entity_assertions_in_tx(
if SyncMetadata::has_entity_assertions_in_tx( &ip.transaction,
&ip.transaction, *resolved_e,
*resolved_e, report.tx_id,
report.tx_id, )? {
)? { bail!(TolstoyError::NotYetImplemented(
bail!(TolstoyError::NotYetImplemented( "Can't sync with schema alterations yet.".to_string()
"Can't sync with schema alterations yet.".to_string() ));
));
}
} }
None => (),
} }
} }
@ -682,20 +683,18 @@ impl Syncer {
} }
fn first_sync_against_non_empty<R>( fn first_sync_against_non_empty<R>(
ip: &mut InProgress, ip: &mut InProgress<'_, '_>,
remote_client: &R, remote_client: &R,
local_metadata: &SyncMetadata, local_metadata: &SyncMetadata,
) -> Result<SyncReport> ) -> Result<SyncReport>
where where
R: GlobalTransactionLog, R: GlobalTransactionLog,
{ {
d(&format!( d(&"remote non-empty on first sync, adopting remote state.".to_string());
"remote non-empty on first sync, adopting remote state."
));
// 1) Download remote transactions. // 1) Download remote transactions.
let incoming_txs = remote_client.transactions_after(&Uuid::nil())?; let incoming_txs = remote_client.transactions_after(&Uuid::nil())?;
if incoming_txs.len() == 0 { if incoming_txs.is_empty() {
return Ok(SyncReport::BadRemoteState( return Ok(SyncReport::BadRemoteState(
"Remote specified non-root HEAD but gave no transactions".to_string(), "Remote specified non-root HEAD but gave no transactions".to_string(),
)); ));
@ -744,53 +743,53 @@ impl Syncer {
match Syncer::what_do(remote_state, local_state) { match Syncer::what_do(remote_state, local_state) {
SyncAction::NoOp => { SyncAction::NoOp => {
Ok(SyncReport::Merge(SyncFollowup::None)) Ok(SyncReport::Merge(SyncFollowup::None))
}, }
SyncAction::PopulateRemote => { SyncAction::PopulateRemote => {
// This is a programming error. // This is a programming error.
bail!(TolstoyError::UnexpectedState(format!("Remote state can't be empty on first sync against non-empty remote"))) bail!(TolstoyError::UnexpectedState("Remote state can't be empty on first sync against non-empty remote".to_string()))
}, }
SyncAction::RemoteFastForward => { SyncAction::RemoteFastForward => {
bail!(TolstoyError::NotYetImplemented(format!("TODO fast-forward remote on first sync when remote is just bootstrap and local has more"))) bail!(TolstoyError::NotYetImplemented("TODO fast-forward remote on first sync when remote is just bootstrap and local has more".to_string()))
}, }
SyncAction::LocalFastForward => { SyncAction::LocalFastForward => {
Syncer::fast_forward_local(ip, incoming_txs[1 ..].to_vec())?; Syncer::fast_forward_local(ip, incoming_txs[1..].to_vec())?;
Ok(SyncReport::Merge(SyncFollowup::None)) Ok(SyncReport::Merge(SyncFollowup::None))
}, }
SyncAction::CombineChanges => { SyncAction::CombineChanges => {
let local_txs = Processor::process( let local_txs = Processor::process(
&mut ip.transaction, Some(local_metadata.root), LocalTxSet::new())?; &ip.transaction, Some(local_metadata.root), LocalTxSet::new())?;
Syncer::merge( Syncer::merge(
ip, ip,
incoming_txs[1 ..].to_vec(), incoming_txs[1..].to_vec(),
local_txs local_txs,
) )
} }
} }
} }
pub fn sync<R>(ip: &mut InProgress, remote_client: &mut R) -> Result<SyncReport> pub fn sync<R>(ip: &mut InProgress<'_, '_>, remote_client: &mut R) -> Result<SyncReport>
where where
R: GlobalTransactionLog, R: GlobalTransactionLog,
{ {
d(&format!("sync flowing")); d(&"sync flowing".to_string());
ensure_current_version(&mut ip.transaction)?; ensure_current_version(&mut ip.transaction)?;
let remote_head = remote_client.head()?; let remote_head = remote_client.head()?;
d(&format!("remote head {:?}", remote_head)); d(&format!("remote head {:?}", remote_head));
let locally_known_remote_head = SyncMetadata::remote_head(&mut ip.transaction)?; let locally_known_remote_head = SyncMetadata::remote_head(&ip.transaction)?;
d(&format!("local head {:?}", locally_known_remote_head)); d(&format!("local head {:?}", locally_known_remote_head));
let (root, head) = SyncMetadata::root_and_head_tx(&mut ip.transaction)?; let (root, head) = SyncMetadata::root_and_head_tx(&ip.transaction)?;
let local_metadata = SyncMetadata::new(root, head); let local_metadata = SyncMetadata::new(root, head);
// impl From ... vs ::new() calls to constuct "state" objects? // impl From ... vs ::new() calls to constuct "state" objects?
let local_state = TxMapper::get(&mut ip.transaction, local_metadata.head)?.into(); let local_state = TxMapper::get(&ip.transaction, local_metadata.head)?.into();
let remote_state = (&locally_known_remote_head, &remote_head).into(); let remote_state = (&locally_known_remote_head, &remote_head).into();
// Currently, first sync against a non-empty remote is special. // Currently, first sync against a non-empty remote is special.
@ -800,12 +799,12 @@ impl Syncer {
match Syncer::what_do(remote_state, local_state) { match Syncer::what_do(remote_state, local_state) {
SyncAction::NoOp => { SyncAction::NoOp => {
d(&format!("local HEAD did not move. Nothing to do!")); d(&"local HEAD did not move. Nothing to do!".to_string());
Ok(SyncReport::NoChanges) Ok(SyncReport::NoChanges)
} }
SyncAction::PopulateRemote => { SyncAction::PopulateRemote => {
d(&format!("empty remote!")); d(&"empty remote!".to_string());
Syncer::fast_forward_remote( Syncer::fast_forward_remote(
&mut ip.transaction, &mut ip.transaction,
None, None,
@ -816,11 +815,11 @@ impl Syncer {
} }
SyncAction::RemoteFastForward => { SyncAction::RemoteFastForward => {
d(&format!("local HEAD moved.")); d(&"local HEAD moved.".to_string());
let upload_from_tx = let upload_from_tx =
Syncer::local_tx_for_uuid(&mut ip.transaction, &locally_known_remote_head)?; Syncer::local_tx_for_uuid(&ip.transaction, &locally_known_remote_head)?;
d(&format!("Fast-forwarding the remote.")); d(&"Fast-forwarding the remote.".to_string());
// TODO it's possible that we've successfully advanced remote head previously, // TODO it's possible that we've successfully advanced remote head previously,
// but failed to advance our own local head. If that's the case, and we can recognize it, // but failed to advance our own local head. If that's the case, and we can recognize it,
@ -835,7 +834,7 @@ impl Syncer {
} }
SyncAction::LocalFastForward => { SyncAction::LocalFastForward => {
d(&format!("fast-forwarding local store.")); d(&"fast-forwarding local store.".to_string());
Syncer::fast_forward_local( Syncer::fast_forward_local(
ip, ip,
remote_client.transactions_after(&locally_known_remote_head)?, remote_client.transactions_after(&locally_known_remote_head)?,
@ -844,12 +843,12 @@ impl Syncer {
} }
SyncAction::CombineChanges => { SyncAction::CombineChanges => {
d(&format!("combining changes from local and remote stores.")); d(&"combining changes from local and remote stores.".to_string());
// Get the starting point for out local set of txs to merge. // Get the starting point for out local set of txs to merge.
let combine_local_from_tx = let combine_local_from_tx =
Syncer::local_tx_for_uuid(&mut ip.transaction, &locally_known_remote_head)?; Syncer::local_tx_for_uuid(&ip.transaction, &locally_known_remote_head)?;
let local_txs = Processor::process( let local_txs = Processor::process(
&mut ip.transaction, &ip.transaction,
Some(combine_local_from_tx), Some(combine_local_from_tx),
LocalTxSet::new(), LocalTxSet::new(),
)?; )?;

View file

@ -8,8 +8,6 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the // CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License. // specific language governing permissions and limitations under the License.
use rusqlite;
use std::convert::TryInto; use std::convert::TryInto;
use uuid::Uuid; use uuid::Uuid;
@ -27,8 +25,8 @@ pub struct TxMapper {}
impl TxMapper { impl TxMapper {
pub fn set_lg_mappings( pub fn set_lg_mappings(
db_tx: &mut rusqlite::Transaction, db_tx: &mut rusqlite::Transaction<'_>,
mappings: Vec<LocalGlobalTxMapping>, mappings: Vec<LocalGlobalTxMapping<'_>>,
) -> Result<()> { ) -> Result<()> {
let mut stmt = let mut stmt =
db_tx.prepare_cached("INSERT OR REPLACE INTO tolstoy_tu (tx, uuid) VALUES (?, ?)")?; db_tx.prepare_cached("INSERT OR REPLACE INTO tolstoy_tu (tx, uuid) VALUES (?, ?)")?;
@ -40,14 +38,17 @@ impl TxMapper {
} }
pub fn set_lg_mapping( pub fn set_lg_mapping(
db_tx: &mut rusqlite::Transaction, db_tx: &mut rusqlite::Transaction<'_>,
mapping: LocalGlobalTxMapping, mapping: LocalGlobalTxMapping<'_>,
) -> Result<()> { ) -> Result<()> {
TxMapper::set_lg_mappings(db_tx, vec![mapping]) TxMapper::set_lg_mappings(db_tx, vec![mapping])
} }
// TODO for when we're downloading, right? // TODO for when we're downloading, right?
pub fn get_or_set_uuid_for_tx(db_tx: &mut rusqlite::Transaction, tx: Entid) -> Result<Uuid> { pub fn get_or_set_uuid_for_tx(
db_tx: &mut rusqlite::Transaction<'_>,
tx: Entid,
) -> Result<Uuid> {
match TxMapper::get(db_tx, tx)? { match TxMapper::get(db_tx, tx)? {
Some(uuid) => Ok(uuid), Some(uuid) => Ok(uuid),
None => { None => {
@ -57,12 +58,15 @@ impl TxMapper {
"INSERT INTO tolstoy_tu (tx, uuid) VALUES (?, ?)", "INSERT INTO tolstoy_tu (tx, uuid) VALUES (?, ?)",
rusqlite::params![&tx, &uuid_bytes], rusqlite::params![&tx, &uuid_bytes],
)?; )?;
return Ok(uuid); Ok(uuid)
} }
} }
} }
pub fn get_tx_for_uuid(db_tx: &rusqlite::Transaction, uuid: &Uuid) -> Result<Option<Entid>> { pub fn get_tx_for_uuid(
db_tx: &rusqlite::Transaction<'_>,
uuid: &Uuid,
) -> Result<Option<Entid>> {
let mut stmt = db_tx.prepare_cached("SELECT tx FROM tolstoy_tu WHERE uuid = ?")?; let mut stmt = db_tx.prepare_cached("SELECT tx FROM tolstoy_tu WHERE uuid = ?")?;
let uuid_bytes = uuid.as_bytes().to_vec(); let uuid_bytes = uuid.as_bytes().to_vec();
@ -70,7 +74,7 @@ impl TxMapper {
let mut txs = vec![]; let mut txs = vec![];
txs.extend(results); txs.extend(results);
if txs.len() == 0 { if txs.is_empty() {
return Ok(None); return Ok(None);
} else if txs.len() > 1 { } else if txs.len() > 1 {
bail!(TolstoyError::TxIncorrectlyMapped(txs.len())); bail!(TolstoyError::TxIncorrectlyMapped(txs.len()));
@ -78,7 +82,7 @@ impl TxMapper {
Ok(Some(txs.remove(0)?)) Ok(Some(txs.remove(0)?))
} }
pub fn get(db_tx: &rusqlite::Transaction, tx: Entid) -> Result<Option<Uuid>> { pub fn get(db_tx: &rusqlite::Transaction<'_>, tx: Entid) -> Result<Option<Uuid>> {
let mut stmt = db_tx.prepare_cached("SELECT uuid FROM tolstoy_tu WHERE tx = ?")?; let mut stmt = db_tx.prepare_cached("SELECT uuid FROM tolstoy_tu WHERE tx = ?")?;
let results = stmt.query_and_then(&[&tx], |r| -> Result<Uuid> { let results = stmt.query_and_then(&[&tx], |r| -> Result<Uuid> {
@ -88,7 +92,7 @@ impl TxMapper {
let mut uuids = vec![]; let mut uuids = vec![];
uuids.extend(results); uuids.extend(results);
if uuids.len() == 0 { if uuids.is_empty() {
return Ok(None); return Ok(None);
} else if uuids.len() > 1 { } else if uuids.len() > 1 {
bail!(TolstoyError::TxIncorrectlyMapped(uuids.len())); bail!(TolstoyError::TxIncorrectlyMapped(uuids.len()));
@ -106,9 +110,9 @@ pub mod tests {
fn test_getters() { fn test_getters() {
let mut conn = schema::tests::setup_conn_bare(); let mut conn = schema::tests::setup_conn_bare();
let mut tx = schema::tests::setup_tx(&mut conn); let mut tx = schema::tests::setup_tx(&mut conn);
assert_eq!(None, TxMapper::get(&mut tx, 1).expect("success")); assert_eq!(None, TxMapper::get(&tx, 1).expect("success"));
let set_uuid = TxMapper::get_or_set_uuid_for_tx(&mut tx, 1).expect("success"); let set_uuid = TxMapper::get_or_set_uuid_for_tx(&mut tx, 1).expect("success");
assert_eq!(Some(set_uuid), TxMapper::get(&mut tx, 1).expect("success")); assert_eq!(Some(set_uuid), TxMapper::get(&tx, 1).expect("success"));
} }
#[test] #[test]
@ -123,15 +127,15 @@ pub mod tests {
TxMapper::set_lg_mappings(&mut tx, vec![(1, &uuid1).into(), (2, &uuid2).into()]) TxMapper::set_lg_mappings(&mut tx, vec![(1, &uuid1).into(), (2, &uuid2).into()])
.expect("map success"); .expect("map success");
assert_eq!(Some(uuid1), TxMapper::get(&mut tx, 1).expect("success")); assert_eq!(Some(uuid1), TxMapper::get(&tx, 1).expect("success"));
assert_eq!(Some(uuid2), TxMapper::get(&mut tx, 2).expect("success")); assert_eq!(Some(uuid2), TxMapper::get(&tx, 2).expect("success"));
// Now let's replace one of the mappings. // Now let's replace one of the mappings.
let new_uuid2 = Uuid::new_v4(); let new_uuid2 = Uuid::new_v4();
TxMapper::set_lg_mappings(&mut tx, vec![(1, &uuid1).into(), (2, &new_uuid2).into()]) TxMapper::set_lg_mappings(&mut tx, vec![(1, &uuid1).into(), (2, &new_uuid2).into()])
.expect("map success"); .expect("map success");
assert_eq!(Some(uuid1), TxMapper::get(&mut tx, 1).expect("success")); assert_eq!(Some(uuid1), TxMapper::get(&tx, 1).expect("success"));
assert_eq!(Some(new_uuid2), TxMapper::get(&mut tx, 2).expect("success")); assert_eq!(Some(new_uuid2), TxMapper::get(&tx, 2).expect("success"));
} }
} }

View file

@ -9,8 +9,6 @@
// specific language governing permissions and limitations under the License. // specific language governing permissions and limitations under the License.
use std::iter::Peekable; use std::iter::Peekable;
use rusqlite;
use mentat_db::TypedSQLValue; use mentat_db::TypedSQLValue;
use core_traits::{Entid, TypedValue}; use core_traits::{Entid, TypedValue};
@ -32,7 +30,7 @@ pub struct Processor {}
pub struct DatomsIterator<'dbtx, 't, T> pub struct DatomsIterator<'dbtx, 't, T>
where where
T: Sized + Iterator<Item = Result<TxPart>> + 't, T: Sized + Iterator<Item = Result<TxPart>>,
{ {
at_first: bool, at_first: bool,
at_last: bool, at_last: bool,
@ -48,8 +46,8 @@ where
DatomsIterator { DatomsIterator {
at_first: true, at_first: true,
at_last: false, at_last: false,
first: first, first,
rows: rows, rows,
} }
} }
} }
@ -109,7 +107,7 @@ where
} }
} }
fn to_tx_part(row: &rusqlite::Row) -> Result<TxPart> { fn to_tx_part(row: &rusqlite::Row<'_>) -> Result<TxPart> {
Ok(TxPart { Ok(TxPart {
partitions: None, partitions: None,
e: row.get(0)?, e: row.get(0)?,
@ -122,13 +120,13 @@ fn to_tx_part(row: &rusqlite::Row) -> Result<TxPart> {
impl Processor { impl Processor {
pub fn process<RR, R: TxReceiver<RR>>( pub fn process<RR, R: TxReceiver<RR>>(
sqlite: &rusqlite::Transaction, sqlite: &rusqlite::Transaction<'_>,
from_tx: Option<Entid>, from_tx: Option<Entid>,
mut receiver: R, mut receiver: R,
) -> Result<RR> { ) -> Result<RR> {
let tx_filter = match from_tx { let tx_filter = match from_tx {
Some(tx) => format!(" WHERE timeline = 0 AND tx > {} ", tx), Some(tx) => format!(" WHERE timeline = 0 AND tx > {} ", tx),
None => format!("WHERE timeline = 0"), None => "WHERE timeline = 0".to_string(),
}; };
let select_query = format!( let select_query = format!(
"SELECT e, a, v, value_type_tag, tx, added FROM timelined_transactions {} ORDER BY tx", "SELECT e, a, v, value_type_tag, tx, added FROM timelined_transactions {} ORDER BY tx",

View file

@ -46,9 +46,9 @@ impl<'c> TxUploader<'c> {
TxUploader { TxUploader {
tx_temp_uuids: HashMap::new(), tx_temp_uuids: HashMap::new(),
remote_client: client, remote_client: client,
remote_head: remote_head, remote_head,
rolling_temp_head: None, rolling_temp_head: None,
local_partitions: local_partitions, local_partitions,
} }
} }
} }
@ -138,7 +138,7 @@ impl<'c> TxReceiver<UploaderReport> for TxUploader<'c> {
.put_transaction(&tx_uuid, &tx_parent, &tx_chunks)?; .put_transaction(&tx_uuid, &tx_parent, &tx_chunks)?;
d(&format!("updating rolling head: {:?}", tx_uuid)); d(&format!("updating rolling head: {:?}", tx_uuid));
self.rolling_temp_head = Some(tx_uuid.clone()); self.rolling_temp_head = Some(tx_uuid);
Ok(()) Ok(())
} }

View file

@ -23,20 +23,14 @@ pub struct LocalGlobalTxMapping<'a> {
} }
impl<'a> From<(Entid, &'a Uuid)> for LocalGlobalTxMapping<'a> { impl<'a> From<(Entid, &'a Uuid)> for LocalGlobalTxMapping<'a> {
fn from((local, remote): (Entid, &'a Uuid)) -> LocalGlobalTxMapping { fn from((local, remote): (Entid, &'a Uuid)) -> LocalGlobalTxMapping<'_> {
LocalGlobalTxMapping { LocalGlobalTxMapping { local, remote }
local: local,
remote: remote,
}
} }
} }
impl<'a> LocalGlobalTxMapping<'a> { impl<'a> LocalGlobalTxMapping<'a> {
pub fn new(local: Entid, remote: &'a Uuid) -> LocalGlobalTxMapping<'a> { pub fn new(local: Entid, remote: &'a Uuid) -> LocalGlobalTxMapping<'a> {
LocalGlobalTxMapping { LocalGlobalTxMapping { local, remote }
local: local,
remote: remote,
}
} }
} }
@ -90,7 +84,6 @@ pub trait GlobalTransactionLog {
fn head(&self) -> Result<Uuid>; fn head(&self) -> Result<Uuid>;
fn transactions_after(&self, tx: &Uuid) -> Result<Vec<Tx>>; fn transactions_after(&self, tx: &Uuid) -> Result<Vec<Tx>>;
fn set_head(&mut self, tx: &Uuid) -> Result<()>; fn set_head(&mut self, tx: &Uuid) -> Result<()>;
fn put_transaction(&mut self, tx: &Uuid, parent_tx: &Uuid, chunk_txs: &Vec<Uuid>) fn put_transaction(&mut self, tx: &Uuid, parent_tx: &Uuid, chunk_txs: &[Uuid]) -> Result<()>;
-> Result<()>;
fn put_chunk(&mut self, tx: &Uuid, payload: &TxPart) -> Result<()>; fn put_chunk(&mut self, tx: &Uuid, payload: &TxPart) -> Result<()>;
} }

View file

@ -20,7 +20,7 @@ test = false
[dependencies] [dependencies]
combine = "~4.2" combine = "~4.2"
dirs = "~2.0" dirs = "~3.0"
env_logger = "~0.7" env_logger = "~0.7"
failure = "~0.1" failure = "~0.1"
failure_derive = "~0.1" failure_derive = "~0.1"

View file

@ -21,25 +21,25 @@ use failure::Error;
use combine::error::StringStreamError; use combine::error::StringStreamError;
use mentat::CacheDirection; use mentat::CacheDirection;
pub static COMMAND_CACHE: &'static str = &"cache"; pub static COMMAND_CACHE: &str = &"cache";
pub static COMMAND_CLOSE: &'static str = &"close"; pub static COMMAND_CLOSE: &str = &"close";
pub static COMMAND_EXIT_LONG: &'static str = &"exit"; pub static COMMAND_EXIT_LONG: &str = &"exit";
pub static COMMAND_EXIT_SHORT: &'static str = &"e"; pub static COMMAND_EXIT_SHORT: &str = &"e";
pub static COMMAND_HELP: &'static str = &"help"; pub static COMMAND_HELP: &str = &"help";
pub static COMMAND_IMPORT_LONG: &'static str = &"import"; pub static COMMAND_IMPORT_LONG: &str = &"import";
pub static COMMAND_IMPORT_SHORT: &'static str = &"i"; pub static COMMAND_IMPORT_SHORT: &str = &"i";
pub static COMMAND_OPEN: &'static str = &"open"; pub static COMMAND_OPEN: &str = &"open";
pub static COMMAND_OPEN_ENCRYPTED: &'static str = &"open_encrypted"; pub static COMMAND_OPEN_ENCRYPTED: &str = &"open_encrypted";
pub static COMMAND_QUERY_LONG: &'static str = &"query"; pub static COMMAND_QUERY_LONG: &str = &"query";
pub static COMMAND_QUERY_SHORT: &'static str = &"q"; pub static COMMAND_QUERY_SHORT: &str = &"q";
pub static COMMAND_QUERY_EXPLAIN_LONG: &'static str = &"explain_query"; pub static COMMAND_QUERY_EXPLAIN_LONG: &str = &"explain_query";
pub static COMMAND_QUERY_EXPLAIN_SHORT: &'static str = &"eq"; pub static COMMAND_QUERY_EXPLAIN_SHORT: &str = &"eq";
pub static COMMAND_QUERY_PREPARED_LONG: &'static str = &"query_prepared"; pub static COMMAND_QUERY_PREPARED_LONG: &str = &"query_prepared";
pub static COMMAND_SCHEMA: &'static str = &"schema"; pub static COMMAND_SCHEMA: &str = &"schema";
pub static COMMAND_SYNC: &'static str = &"sync"; pub static COMMAND_SYNC: &str = &"sync";
pub static COMMAND_TIMER_LONG: &'static str = &"timer"; pub static COMMAND_TIMER_LONG: &str = &"timer";
pub static COMMAND_TRANSACT_LONG: &'static str = &"transact"; pub static COMMAND_TRANSACT_LONG: &str = &"transact";
pub static COMMAND_TRANSACT_SHORT: &'static str = &"t"; pub static COMMAND_TRANSACT_SHORT: &str = &"t";
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq)]
pub enum Command { pub enum Command {

View file

@ -21,10 +21,10 @@ use command_parser::{command, Command};
use failure::Error; use failure::Error;
/// Starting prompt /// Starting prompt
const DEFAULT_PROMPT: &'static str = "mentat=> "; const DEFAULT_PROMPT: &str = "mentat=> ";
/// Prompt when further input is being read /// Prompt when further input is being read
// TODO: Should this actually reflect the current open brace? // TODO: Should this actually reflect the current open brace?
const MORE_PROMPT: &'static str = "mentat.> "; const MORE_PROMPT: &str = "mentat.> ";
/// Possible results from reading input from `InputReader` /// Possible results from reading input from `InputReader`
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -218,7 +218,7 @@ impl InputReader {
self.save_history(); self.save_history();
} }
pub fn save_history(&self) -> () { pub fn save_history(&self) {
if let Some(ref interface) = self.interface { if let Some(ref interface) = self.interface {
let p = ::history_file_path(); let p = ::history_file_path();
// It's okay to fail to save history. // It's okay to fail to save history.

View file

@ -307,7 +307,7 @@ impl Repl {
start = Instant::now(); start = Instant::now();
let r = p.run(None); let r = p.run(None);
end = Some(Instant::now()); end = Some(Instant::now());
return r; r
}) })
.map(|o| self.print_results(o)) .map(|o| self.print_results(o))
.map_err(|err| { .map_err(|err| {
@ -351,7 +351,7 @@ impl Repl {
format_time(end - start); format_time(end - start);
} }
return true; true
} }
fn execute_import<T>(&mut self, path: T) fn execute_import<T>(&mut self, path: T)
@ -446,7 +446,7 @@ impl Repl {
} }
} }
} }
writeln!(output, "").unwrap(); writeln!(output).unwrap();
output.flush().unwrap(); output.flush().unwrap();
} }
@ -462,7 +462,7 @@ impl Repl {
for _ in 0..query_output.spec.expected_column_count() { for _ in 0..query_output.spec.expected_column_count() {
write!(output, "---\t")?; write!(output, "---\t")?;
} }
writeln!(output, "")?; writeln!(output)?;
match query_output.results { match query_output.results {
QueryResults::Scalar(v) => { QueryResults::Scalar(v) => {
@ -498,7 +498,7 @@ impl Repl {
for _ in 0..query_output.spec.expected_column_count() { for _ in 0..query_output.spec.expected_column_count() {
write!(output, "---\t")?; write!(output, "---\t")?;
} }
writeln!(output, "")?; writeln!(output)?;
output.flush()?; output.flush()?;
Ok(()) Ok(())
} }

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