Part 5: Make existing TermBuilder
actually build Entity
instances.
There are a few tricky details to call out here. The first is the `TransactableValueMarker` trait. This is strictly a marker (like `Sized`, for example) to give some control over what types can be used as value types in `Entity` instances. This expression is needed due to the network of `Into` and `From` relations between the parts of valid `Entity` instances. This allows to drop the `IntoThing` work-around trait and use the established patterns. (Observe that `KnownEntid` makes this a little harder, due to the cross-crate consistency restrictions.) The second is that we can get rid `{add,retract}_kw`, since the network of relations expresses the coercions directly. The third is that this commit doesn't change the name `TermBuilder`, even though it is now building `Entity` instances. This is because there's _already_ an `EntityBuilder` which fixes the `EntityPlace`. It's not clear whether the existing entity building interface should be removed or whether both should be renamed. That can be follow-up.
This commit is contained in:
parent
76507623ac
commit
1cb1847aa6
7 changed files with 246 additions and 218 deletions
|
@ -47,6 +47,14 @@ use ::edn::{
|
|||
ValueRc,
|
||||
};
|
||||
|
||||
use ::edn::entities::{
|
||||
AttributePlace,
|
||||
EntidOrIdent,
|
||||
EntityPlace,
|
||||
ValuePlace,
|
||||
TransactableValueMarker,
|
||||
};
|
||||
|
||||
use values;
|
||||
|
||||
/// Represents one entid in the entid space.
|
||||
|
@ -73,6 +81,24 @@ impl From<KnownEntid> for TypedValue {
|
|||
}
|
||||
}
|
||||
|
||||
impl<V: TransactableValueMarker> Into<EntityPlace<V>> for KnownEntid {
|
||||
fn into(self) -> EntityPlace<V> {
|
||||
EntityPlace::Entid(EntidOrIdent::Entid(self.0))
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<AttributePlace> for KnownEntid {
|
||||
fn into(self) -> AttributePlace {
|
||||
AttributePlace::Entid(EntidOrIdent::Entid(self.0))
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: TransactableValueMarker> Into<ValuePlace<V>> for KnownEntid {
|
||||
fn into(self) -> ValuePlace<V> {
|
||||
ValuePlace::Entid(EntidOrIdent::Entid(self.0))
|
||||
}
|
||||
}
|
||||
|
||||
/// The attribute of each Mentat assertion has a :db/valueType constraining the value to a
|
||||
/// particular set. Mentat recognizes the following :db/valueType values.
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)]
|
||||
|
@ -215,6 +241,9 @@ pub enum TypedValue {
|
|||
Uuid(Uuid), // It's only 128 bits, so this should be acceptable to clone.
|
||||
}
|
||||
|
||||
/// `TypedValue` is the value type for programmatic use in transaction builders.
|
||||
impl TransactableValueMarker for TypedValue {}
|
||||
|
||||
/// The values bound in a query specification can be:
|
||||
///
|
||||
/// * Vecs of structured values, for multi-valued component attributes or nested expressions.
|
||||
|
|
|
@ -22,6 +22,20 @@ use symbols::{
|
|||
PlainSymbol,
|
||||
};
|
||||
|
||||
use types::{
|
||||
ValueAndSpan,
|
||||
};
|
||||
|
||||
/// `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
|
||||
/// `From` relations, we need to ensure that `{Value,Entity}Place` can't match as a potential value.
|
||||
/// (If it does, the `impl Into<T> for T` default conflicts.) This marker trait allows to mark
|
||||
/// acceptable values, thereby removing `{Entity,Value}Place` from consideration.
|
||||
pub trait TransactableValueMarker {}
|
||||
|
||||
/// `ValueAndSpan` is the value type coming out of the entity parser.
|
||||
impl TransactableValueMarker for ValueAndSpan {}
|
||||
|
||||
/// A tempid, either an external tempid given in a transaction (usually as an `Value::Text`),
|
||||
/// or an internal tempid allocated by Mentat itself.
|
||||
#[derive(Clone, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)]
|
||||
|
@ -54,6 +68,18 @@ pub enum EntidOrIdent {
|
|||
Ident(Keyword),
|
||||
}
|
||||
|
||||
impl From<i64> for EntidOrIdent {
|
||||
fn from(v: i64) -> Self {
|
||||
EntidOrIdent::Entid(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Keyword> for EntidOrIdent {
|
||||
fn from(v: Keyword) -> Self {
|
||||
EntidOrIdent::Ident(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl EntidOrIdent {
|
||||
pub fn unreversed(&self) -> Option<EntidOrIdent> {
|
||||
match self {
|
||||
|
@ -105,6 +131,54 @@ pub enum ValuePlace<V> {
|
|||
MapNotation(MapNotation<V>),
|
||||
}
|
||||
|
||||
impl<V: TransactableValueMarker> From<EntidOrIdent> for ValuePlace<V> {
|
||||
fn from(v: EntidOrIdent) -> Self {
|
||||
ValuePlace::Entid(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: TransactableValueMarker> From<TempId> for ValuePlace<V> {
|
||||
fn from(v: TempId) -> Self {
|
||||
ValuePlace::TempId(v.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: TransactableValueMarker> From<ValueRc<TempId>> for ValuePlace<V> {
|
||||
fn from(v: ValueRc<TempId>) -> Self {
|
||||
ValuePlace::TempId(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: TransactableValueMarker> From<LookupRef<V>> for ValuePlace<V> {
|
||||
fn from(v: LookupRef<V>) -> Self {
|
||||
ValuePlace::LookupRef(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: TransactableValueMarker> From<TxFunction> for ValuePlace<V> {
|
||||
fn from(v: TxFunction) -> Self {
|
||||
ValuePlace::TxFunction(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: TransactableValueMarker> From<Vec<ValuePlace<V>>> for ValuePlace<V> {
|
||||
fn from(v: Vec<ValuePlace<V>>) -> Self {
|
||||
ValuePlace::Vector(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: TransactableValueMarker> From<V> for ValuePlace<V> {
|
||||
fn from(v: V) -> Self {
|
||||
ValuePlace::Atom(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: TransactableValueMarker> From<MapNotation<V>> for ValuePlace<V> {
|
||||
fn from(v: MapNotation<V>) -> Self {
|
||||
ValuePlace::MapNotation(v)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)]
|
||||
pub enum EntityPlace<V> {
|
||||
Entid(EntidOrIdent),
|
||||
|
@ -113,11 +187,47 @@ pub enum EntityPlace<V> {
|
|||
TxFunction(TxFunction),
|
||||
}
|
||||
|
||||
impl<V, E: Into<EntidOrIdent>> From<E> for EntityPlace<V> {
|
||||
fn from(v: E) -> Self {
|
||||
EntityPlace::Entid(v.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: TransactableValueMarker> From<TempId> for EntityPlace<V> {
|
||||
fn from(v: TempId) -> Self {
|
||||
EntityPlace::TempId(v.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: TransactableValueMarker> From<ValueRc<TempId>> for EntityPlace<V> {
|
||||
fn from(v: ValueRc<TempId>) -> Self {
|
||||
EntityPlace::TempId(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: TransactableValueMarker> From<LookupRef<V>> for EntityPlace<V> {
|
||||
fn from(v: LookupRef<V>) -> Self {
|
||||
EntityPlace::LookupRef(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: TransactableValueMarker> From<TxFunction> for EntityPlace<V> {
|
||||
fn from(v: TxFunction) -> Self {
|
||||
EntityPlace::TxFunction(v)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)]
|
||||
pub enum AttributePlace {
|
||||
Entid(EntidOrIdent),
|
||||
}
|
||||
|
||||
impl<A: Into<EntidOrIdent>> From<A> for AttributePlace {
|
||||
fn from(v: A) -> Self {
|
||||
AttributePlace::Entid(v.into())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialOrd, PartialEq)]
|
||||
pub enum OpType {
|
||||
Add,
|
||||
|
|
|
@ -120,7 +120,6 @@ pub use mentat::entity_builder::{
|
|||
BuildTerms,
|
||||
EntityBuilder,
|
||||
InProgressBuilder,
|
||||
IntoThing,
|
||||
};
|
||||
|
||||
pub mod android;
|
||||
|
@ -339,7 +338,7 @@ pub unsafe extern "C" fn in_progress_entity_builder_from_temp_id<'m>(in_progress
|
|||
pub unsafe extern "C" fn in_progress_entity_builder_from_entid<'m>(in_progress: *mut InProgress<'m, 'm>, entid: c_longlong) -> *mut EntityBuilder<InProgressBuilder> {
|
||||
assert_not_null!(in_progress);
|
||||
let in_progress = Box::from_raw(in_progress);
|
||||
Box::into_raw(Box::new(in_progress.builder().describe(&KnownEntid(entid))))
|
||||
Box::into_raw(Box::new(in_progress.builder().describe(KnownEntid(entid))))
|
||||
}
|
||||
|
||||
/// Starts a new transaction and creates a builder using the transaction
|
||||
|
@ -392,7 +391,7 @@ pub unsafe extern "C" fn store_entity_builder_from_entid<'a, 'c>(store: *mut Sto
|
|||
assert_not_null!(store);
|
||||
let store = &mut *store;
|
||||
let result = store.begin_transaction().and_then(|in_progress| {
|
||||
Ok(in_progress.builder().describe(&KnownEntid(entid)))
|
||||
Ok(in_progress.builder().describe(KnownEntid(entid)))
|
||||
});
|
||||
translate_result(result, error)
|
||||
}
|
||||
|
@ -418,7 +417,7 @@ pub unsafe extern "C" fn in_progress_builder_add_string<'a, 'c>(
|
|||
let builder = &mut *builder;
|
||||
let kw = kw_from_string(c_char_to_string(kw));
|
||||
let value: TypedValue = c_char_to_string(value).into();
|
||||
translate_void_result(builder.add_kw(KnownEntid(entid), &kw, value), error);
|
||||
translate_void_result(builder.add(KnownEntid(entid), kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
|
||||
|
@ -441,7 +440,7 @@ pub unsafe extern "C" fn in_progress_builder_add_long<'a, 'c>(
|
|||
let builder = &mut *builder;
|
||||
let kw = kw_from_string(c_char_to_string(kw));
|
||||
let value: TypedValue = TypedValue::Long(value);
|
||||
translate_void_result(builder.add_kw(KnownEntid(entid), &kw, value), error);
|
||||
translate_void_result(builder.add(KnownEntid(entid), kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
|
||||
|
@ -465,7 +464,7 @@ pub unsafe extern "C" fn in_progress_builder_add_ref<'a, 'c>(
|
|||
let builder = &mut *builder;
|
||||
let kw = kw_from_string(c_char_to_string(kw));
|
||||
let value: TypedValue = TypedValue::Ref(value);
|
||||
translate_void_result(builder.add_kw(KnownEntid(entid), &kw, value), error);
|
||||
translate_void_result(builder.add(KnownEntid(entid), kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
|
||||
|
@ -490,7 +489,7 @@ pub unsafe extern "C" fn in_progress_builder_add_keyword<'a, 'c>(
|
|||
let builder = &mut *builder;
|
||||
let kw = kw_from_string(c_char_to_string(kw));
|
||||
let value: TypedValue = kw_from_string(c_char_to_string(value)).into();
|
||||
translate_void_result(builder.add_kw(KnownEntid(entid), &kw, value), error);
|
||||
translate_void_result(builder.add(KnownEntid(entid), kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
|
||||
|
@ -514,7 +513,7 @@ pub unsafe extern "C" fn in_progress_builder_add_boolean<'a, 'c>(
|
|||
let builder = &mut *builder;
|
||||
let kw = kw_from_string(c_char_to_string(kw));
|
||||
let value: TypedValue = value.into();
|
||||
translate_void_result(builder.add_kw(KnownEntid(entid), &kw, value), error);
|
||||
translate_void_result(builder.add(KnownEntid(entid), kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
|
||||
|
@ -538,7 +537,7 @@ pub unsafe extern "C" fn in_progress_builder_add_double<'a, 'c>(
|
|||
let builder = &mut *builder;
|
||||
let kw = kw_from_string(c_char_to_string(kw));
|
||||
let value: TypedValue = value.into();
|
||||
translate_void_result(builder.add_kw(KnownEntid(entid), &kw, value), error);
|
||||
translate_void_result(builder.add(KnownEntid(entid), kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
|
||||
|
@ -562,7 +561,7 @@ pub unsafe extern "C" fn in_progress_builder_add_timestamp<'a, 'c>(
|
|||
let builder = &mut *builder;
|
||||
let kw = kw_from_string(c_char_to_string(kw));
|
||||
let value: TypedValue = TypedValue::instant(value);
|
||||
translate_void_result(builder.add_kw(KnownEntid(entid), &kw, value), error);
|
||||
translate_void_result(builder.add(KnownEntid(entid), kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
|
||||
|
@ -588,7 +587,7 @@ pub unsafe extern "C" fn in_progress_builder_add_uuid<'a, 'c>(
|
|||
let value = &*value;
|
||||
let value = Uuid::from_bytes(value).expect("valid uuid");
|
||||
let value: TypedValue = value.into();
|
||||
translate_void_result(builder.add_kw(KnownEntid(entid), &kw, value), error);
|
||||
translate_void_result(builder.add(KnownEntid(entid), kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
|
||||
|
@ -612,7 +611,7 @@ pub unsafe extern "C" fn in_progress_builder_retract_string<'a, 'c>(
|
|||
let builder = &mut *builder;
|
||||
let kw = kw_from_string(c_char_to_string(kw));
|
||||
let value: TypedValue = c_char_to_string(value).into();
|
||||
translate_void_result(builder.retract_kw(KnownEntid(entid), &kw, value), error);
|
||||
translate_void_result(builder.retract(KnownEntid(entid), kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
|
||||
|
@ -636,7 +635,7 @@ pub unsafe extern "C" fn in_progress_builder_retract_long<'a, 'c>(
|
|||
let builder = &mut *builder;
|
||||
let kw = kw_from_string(c_char_to_string(kw));
|
||||
let value: TypedValue = TypedValue::Long(value);
|
||||
translate_void_result(builder.retract_kw(KnownEntid(entid), &kw, value), error);
|
||||
translate_void_result(builder.retract(KnownEntid(entid), kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
|
||||
|
@ -660,7 +659,7 @@ pub unsafe extern "C" fn in_progress_builder_retract_ref<'a, 'c>(
|
|||
let builder = &mut *builder;
|
||||
let kw = kw_from_string(c_char_to_string(kw));
|
||||
let value: TypedValue = TypedValue::Ref(value);
|
||||
translate_void_result(builder.retract_kw(KnownEntid(entid), &kw, value), error);
|
||||
translate_void_result(builder.retract(KnownEntid(entid), kw, value), error);
|
||||
}
|
||||
|
||||
|
||||
|
@ -685,7 +684,7 @@ pub unsafe extern "C" fn in_progress_builder_retract_keyword<'a, 'c>(
|
|||
let builder = &mut *builder;
|
||||
let kw = kw_from_string(c_char_to_string(kw));
|
||||
let value: TypedValue = kw_from_string(c_char_to_string(value)).into();
|
||||
translate_void_result(builder.retract_kw(KnownEntid(entid), &kw, value), error);
|
||||
translate_void_result(builder.retract(KnownEntid(entid), kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
|
||||
|
@ -709,7 +708,7 @@ pub unsafe extern "C" fn in_progress_builder_retract_boolean<'a, 'c>(
|
|||
let builder = &mut *builder;
|
||||
let kw = kw_from_string(c_char_to_string(kw));
|
||||
let value: TypedValue = value.into();
|
||||
translate_void_result(builder.retract_kw(KnownEntid(entid), &kw, value), error);
|
||||
translate_void_result(builder.retract(KnownEntid(entid), kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
|
||||
|
@ -733,7 +732,7 @@ pub unsafe extern "C" fn in_progress_builder_retract_double<'a, 'c>(
|
|||
let builder = &mut *builder;
|
||||
let kw = kw_from_string(c_char_to_string(kw));
|
||||
let value: TypedValue = value.into();
|
||||
translate_void_result(builder.retract_kw(KnownEntid(entid), &kw, value), error);
|
||||
translate_void_result(builder.retract(KnownEntid(entid), kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
|
||||
|
@ -757,7 +756,7 @@ pub unsafe extern "C" fn in_progress_builder_retract_timestamp<'a, 'c>(
|
|||
let builder = &mut *builder;
|
||||
let kw = kw_from_string(c_char_to_string(kw));
|
||||
let value: TypedValue = TypedValue::instant(value);
|
||||
translate_void_result(builder.retract_kw(KnownEntid(entid), &kw, value), error);
|
||||
translate_void_result(builder.retract(KnownEntid(entid), kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
|
||||
|
@ -785,7 +784,7 @@ pub unsafe extern "C" fn in_progress_builder_retract_uuid<'a, 'c>(
|
|||
let value = &*value;
|
||||
let value = Uuid::from_bytes(value).expect("valid uuid");
|
||||
let value: TypedValue = value.into();
|
||||
translate_void_result(builder.retract_kw(KnownEntid(entid), &kw, value), error);
|
||||
translate_void_result(builder.retract(KnownEntid(entid), kw, value), error);
|
||||
}
|
||||
|
||||
/// Transacts and commits all the assertions and retractions that have been performed
|
||||
|
@ -842,7 +841,7 @@ pub unsafe extern "C" fn entity_builder_add_string<'a, 'c>(
|
|||
let builder = &mut *builder;
|
||||
let kw = kw_from_string(c_char_to_string(kw));
|
||||
let value: TypedValue = c_char_to_string(value).into();
|
||||
translate_void_result(builder.add_kw(&kw, value), error);
|
||||
translate_void_result(builder.add(kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
|
||||
|
@ -865,7 +864,7 @@ pub unsafe extern "C" fn entity_builder_add_long<'a, 'c>(
|
|||
let builder = &mut *builder;
|
||||
let kw = kw_from_string(c_char_to_string(kw));
|
||||
let value: TypedValue = TypedValue::Long(value);
|
||||
translate_void_result(builder.add_kw(&kw, value), error);
|
||||
translate_void_result(builder.add(kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
|
||||
|
@ -888,7 +887,7 @@ pub unsafe extern "C" fn entity_builder_add_ref<'a, 'c>(
|
|||
let builder = &mut *builder;
|
||||
let kw = kw_from_string(c_char_to_string(kw));
|
||||
let value: TypedValue = TypedValue::Ref(value);
|
||||
translate_void_result(builder.add_kw(&kw, value), error);
|
||||
translate_void_result(builder.add(kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
|
||||
|
@ -911,7 +910,7 @@ pub unsafe extern "C" fn entity_builder_add_keyword<'a, 'c>(
|
|||
let builder = &mut *builder;
|
||||
let kw = kw_from_string(c_char_to_string(kw));
|
||||
let value: TypedValue = kw_from_string(c_char_to_string(value)).into();
|
||||
translate_void_result(builder.add_kw(&kw, value), error);
|
||||
translate_void_result(builder.add(kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
|
||||
|
@ -934,7 +933,7 @@ pub unsafe extern "C" fn entity_builder_add_boolean<'a, 'c>(
|
|||
let builder = &mut *builder;
|
||||
let kw = kw_from_string(c_char_to_string(kw));
|
||||
let value: TypedValue = value.into();
|
||||
translate_void_result(builder.add_kw(&kw, value), error);
|
||||
translate_void_result(builder.add(kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
|
||||
|
@ -957,7 +956,7 @@ pub unsafe extern "C" fn entity_builder_add_double<'a, 'c>(
|
|||
let builder = &mut *builder;
|
||||
let kw = kw_from_string(c_char_to_string(kw));
|
||||
let value: TypedValue = value.into();
|
||||
translate_void_result(builder.add_kw(&kw, value), error);
|
||||
translate_void_result(builder.add(kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
|
||||
|
@ -980,7 +979,7 @@ pub unsafe extern "C" fn entity_builder_add_timestamp<'a, 'c>(
|
|||
let builder = &mut *builder;
|
||||
let kw = kw_from_string(c_char_to_string(kw));
|
||||
let value: TypedValue = TypedValue::instant(value);
|
||||
translate_void_result(builder.add_kw(&kw, value), error);
|
||||
translate_void_result(builder.add(kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
|
||||
|
@ -1005,7 +1004,7 @@ pub unsafe extern "C" fn entity_builder_add_uuid<'a, 'c>(
|
|||
let value = &*value;
|
||||
let value = Uuid::from_bytes(value).expect("valid uuid");
|
||||
let value: TypedValue = value.into();
|
||||
translate_void_result(builder.add_kw(&kw, value), error);
|
||||
translate_void_result(builder.add(kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
|
||||
|
@ -1028,7 +1027,7 @@ pub unsafe extern "C" fn entity_builder_retract_string<'a, 'c>(
|
|||
let builder = &mut *builder;
|
||||
let kw = kw_from_string(c_char_to_string(kw));
|
||||
let value: TypedValue = c_char_to_string(value).into();
|
||||
translate_void_result(builder.retract_kw(&kw, value), error);
|
||||
translate_void_result(builder.retract(kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
|
||||
|
@ -1051,7 +1050,7 @@ pub unsafe extern "C" fn entity_builder_retract_long<'a, 'c>(
|
|||
let builder = &mut *builder;
|
||||
let kw = kw_from_string(c_char_to_string(kw));
|
||||
let value: TypedValue = TypedValue::Long(value);
|
||||
translate_void_result(builder.retract_kw(&kw, value), error);
|
||||
translate_void_result(builder.retract(kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
|
||||
|
@ -1074,7 +1073,7 @@ pub unsafe extern "C" fn entity_builder_retract_ref<'a, 'c>(
|
|||
let builder = &mut *builder;
|
||||
let kw = kw_from_string(c_char_to_string(kw));
|
||||
let value: TypedValue = TypedValue::Ref(value);
|
||||
translate_void_result(builder.retract_kw(&kw, value), error);
|
||||
translate_void_result(builder.retract(kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
|
||||
|
@ -1097,7 +1096,7 @@ pub unsafe extern "C" fn entity_builder_retract_keyword<'a, 'c>(
|
|||
let builder = &mut *builder;
|
||||
let kw = kw_from_string(c_char_to_string(kw));
|
||||
let value: TypedValue = kw_from_string(c_char_to_string(value)).into();
|
||||
translate_void_result(builder.retract_kw(&kw, value), error);
|
||||
translate_void_result(builder.retract(kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
|
||||
|
@ -1120,7 +1119,7 @@ pub unsafe extern "C" fn entity_builder_retract_boolean<'a, 'c>(
|
|||
let builder = &mut *builder;
|
||||
let kw = kw_from_string(c_char_to_string(kw));
|
||||
let value: TypedValue = value.into();
|
||||
translate_void_result(builder.retract_kw(&kw, value), error);
|
||||
translate_void_result(builder.retract(kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
|
||||
|
@ -1143,7 +1142,7 @@ pub unsafe extern "C" fn entity_builder_retract_double<'a, 'c>(
|
|||
let builder = &mut *builder;
|
||||
let kw = kw_from_string(c_char_to_string(kw));
|
||||
let value: TypedValue = value.into();
|
||||
translate_void_result(builder.retract_kw(&kw, value), error);
|
||||
translate_void_result(builder.retract(kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
|
||||
|
@ -1166,7 +1165,7 @@ pub unsafe extern "C" fn entity_builder_retract_timestamp<'a, 'c>(
|
|||
let builder = &mut *builder;
|
||||
let kw = kw_from_string(c_char_to_string(kw));
|
||||
let value: TypedValue = TypedValue::instant(value);
|
||||
translate_void_result(builder.retract_kw(&kw, value), error);
|
||||
translate_void_result(builder.retract(kw, value), error);
|
||||
}
|
||||
|
||||
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
|
||||
|
@ -1192,7 +1191,7 @@ pub unsafe extern "C" fn entity_builder_retract_uuid<'a, 'c>(
|
|||
let value = &*value;
|
||||
let value = Uuid::from_bytes(value).expect("valid uuid");
|
||||
let value: TypedValue = value.into();
|
||||
translate_void_result(builder.retract_kw(&kw, value), error);
|
||||
translate_void_result(builder.retract(kw, value), error);
|
||||
}
|
||||
|
||||
/// Transacts all the assertions and retractions that have been performed
|
||||
|
|
|
@ -402,8 +402,8 @@ impl<'a, 'c> InProgress<'a, 'c> {
|
|||
/// This exists so you can make your own.
|
||||
pub fn transact_builder(&mut self, builder: TermBuilder) -> Result<TxReport> {
|
||||
builder.build()
|
||||
.and_then(|(terms, tempid_set)| {
|
||||
self.transact_terms(terms, tempid_set)
|
||||
.and_then(|(terms, _tempid_set)| {
|
||||
self.transact_entities(terms)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -50,73 +50,65 @@
|
|||
//
|
||||
// The second is to expose a declarative, programmatic builder pattern for constructing entities.
|
||||
//
|
||||
// We probably need both, but this file provides the latter. Unfortunately, Entity -- the input to
|
||||
// the transactor -- is intimately tied to EDN and to spanned values.
|
||||
// We probably need both, but this file provides the latter.
|
||||
|
||||
use edn::{
|
||||
InternSet,
|
||||
ValueRc,
|
||||
};
|
||||
use edn::entities::{
|
||||
AttributePlace,
|
||||
Entity,
|
||||
EntityPlace,
|
||||
OpType,
|
||||
TempId,
|
||||
ValuePlace,
|
||||
};
|
||||
|
||||
use mentat_core::{
|
||||
HasSchema,
|
||||
KnownEntid,
|
||||
Keyword,
|
||||
TypedValue,
|
||||
};
|
||||
|
||||
use mentat_core::util::Either;
|
||||
|
||||
use mentat_db::{
|
||||
TxReport,
|
||||
};
|
||||
|
||||
use mentat_db::internal_types::{
|
||||
KnownEntidOr,
|
||||
TempIdHandle,
|
||||
Term,
|
||||
TermWithTempIds,
|
||||
TypedValueOr,
|
||||
};
|
||||
|
||||
use conn::{
|
||||
InProgress,
|
||||
};
|
||||
|
||||
use errors::{
|
||||
MentatError,
|
||||
Result,
|
||||
};
|
||||
|
||||
pub type Terms = (Vec<TermWithTempIds>, InternSet<TempId>);
|
||||
pub type Terms = (Vec<Entity<TypedValue>>, InternSet<TempId>);
|
||||
|
||||
pub struct TermBuilder {
|
||||
tempids: InternSet<TempId>,
|
||||
terms: Vec<TermWithTempIds>,
|
||||
terms: Vec<Entity<TypedValue>>,
|
||||
}
|
||||
|
||||
pub struct EntityBuilder<T: BuildTerms + Sized> {
|
||||
builder: T,
|
||||
entity: KnownEntidOr<TempIdHandle>,
|
||||
entity: EntityPlace<TypedValue>,
|
||||
}
|
||||
|
||||
pub trait BuildTerms where Self: Sized {
|
||||
fn named_tempid(&mut self, name: String) -> TempIdHandle;
|
||||
fn named_tempid(&mut self, name: String) -> ValueRc<TempId>;
|
||||
fn describe_tempid(self, name: &str) -> EntityBuilder<Self>;
|
||||
fn describe<E>(self, entity: E) -> EntityBuilder<Self> where E: IntoThing<KnownEntidOr<TempIdHandle>>;
|
||||
fn add<E, V>(&mut self, e: E, a: KnownEntid, v: V) -> Result<()>
|
||||
where E: IntoThing<KnownEntidOr<TempIdHandle>>,
|
||||
V: IntoThing<TypedValueOr<TempIdHandle>>;
|
||||
fn retract<E, V>(&mut self, e: E, a: KnownEntid, v: V) -> Result<()>
|
||||
where E: IntoThing<KnownEntidOr<TempIdHandle>>,
|
||||
V: IntoThing<TypedValueOr<TempIdHandle>>;
|
||||
fn describe<E>(self, entity: E) -> EntityBuilder<Self> where E: Into<EntityPlace<TypedValue>>;
|
||||
fn add<E, A, V>(&mut self, e: E, a: A, v: V) -> Result<()>
|
||||
where E: Into<EntityPlace<TypedValue>>,
|
||||
A: Into<AttributePlace>,
|
||||
V: Into<ValuePlace<TypedValue>>;
|
||||
fn retract<E, A, V>(&mut self, e: E, a: A, v: V) -> Result<()>
|
||||
where E: Into<EntityPlace<TypedValue>>,
|
||||
A: Into<AttributePlace>,
|
||||
V: Into<ValuePlace<TypedValue>>;
|
||||
}
|
||||
|
||||
impl BuildTerms for TermBuilder {
|
||||
fn named_tempid(&mut self, name: String) -> TempIdHandle {
|
||||
fn named_tempid(&mut self, name: String) -> ValueRc<TempId> {
|
||||
self.tempids.intern(TempId::External(name))
|
||||
}
|
||||
|
||||
|
@ -125,28 +117,26 @@ impl BuildTerms for TermBuilder {
|
|||
self.describe(e)
|
||||
}
|
||||
|
||||
fn describe<E>(self, entity: E) -> EntityBuilder<Self> where E: IntoThing<KnownEntidOr<TempIdHandle>> {
|
||||
fn describe<E>(self, entity: E) -> EntityBuilder<Self> where E: Into<EntityPlace<TypedValue>> {
|
||||
EntityBuilder {
|
||||
builder: self,
|
||||
entity: entity.into_thing(),
|
||||
entity: entity.into(),
|
||||
}
|
||||
}
|
||||
|
||||
fn add<E, V>(&mut self, e: E, a: KnownEntid, v: V) -> Result<()>
|
||||
where E: IntoThing<KnownEntidOr<TempIdHandle>>,
|
||||
V: IntoThing<TypedValueOr<TempIdHandle>> {
|
||||
let e = e.into_thing();
|
||||
let v = v.into_thing();
|
||||
self.terms.push(Term::AddOrRetract(OpType::Add, e, a.into(), v));
|
||||
fn add<E, A, V>(&mut self, e: E, a: A, v: V) -> Result<()>
|
||||
where E: Into<EntityPlace<TypedValue>>,
|
||||
A: Into<AttributePlace>,
|
||||
V: Into<ValuePlace<TypedValue>> {
|
||||
self.terms.push(Entity::AddOrRetract { op: OpType::Add, e: e.into(), a: a.into(), v: v.into() });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn retract<E, V>(&mut self, e: E, a: KnownEntid, v: V) -> Result<()>
|
||||
where E: IntoThing<KnownEntidOr<TempIdHandle>>,
|
||||
V: IntoThing<TypedValueOr<TempIdHandle>> {
|
||||
let e = e.into_thing();
|
||||
let v = v.into_thing();
|
||||
self.terms.push(Term::AddOrRetract(OpType::Retract, e, a.into(), v));
|
||||
fn retract<E, A, V>(&mut self, e: E, a: A, v: V) -> Result<()>
|
||||
where E: Into<EntityPlace<TypedValue>>,
|
||||
A: Into<AttributePlace>,
|
||||
V: Into<ValuePlace<TypedValue>> {
|
||||
self.terms.push(Entity::AddOrRetract { op: OpType::Retract, e: e.into(), a: a.into(), v: v.into() });
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -168,23 +158,25 @@ impl TermBuilder {
|
|||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn numbered_tempid(&mut self, id: i64) -> TempIdHandle {
|
||||
pub fn numbered_tempid(&mut self, id: i64) -> ValueRc<TempId> {
|
||||
self.tempids.intern(TempId::Internal(id))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> EntityBuilder<T> where T: BuildTerms {
|
||||
pub fn finish(self) -> (T, KnownEntidOr<TempIdHandle>) {
|
||||
pub fn finish(self) -> (T, EntityPlace<TypedValue>) {
|
||||
(self.builder, self.entity)
|
||||
}
|
||||
|
||||
pub fn add<V>(&mut self, a: KnownEntid, v: V) -> Result<()>
|
||||
where V: IntoThing<TypedValueOr<TempIdHandle>> {
|
||||
pub fn add<A, V>(&mut self, a: A, v: V) -> Result<()>
|
||||
where A: Into<AttributePlace>,
|
||||
V: Into<ValuePlace<TypedValue>> {
|
||||
self.builder.add(self.entity.clone(), a, v)
|
||||
}
|
||||
|
||||
pub fn retract<V>(&mut self, a: KnownEntid, v: V) -> Result<()>
|
||||
where V: IntoThing<TypedValueOr<TempIdHandle>> {
|
||||
pub fn retract<A, V>(&mut self, a: A, v: V) -> Result<()>
|
||||
where A: Into<AttributePlace>,
|
||||
V: Into<ValuePlace<TypedValue>> {
|
||||
self.builder.retract(self.entity.clone(), a, v)
|
||||
}
|
||||
}
|
||||
|
@ -209,8 +201,8 @@ impl<'a, 'c> InProgressBuilder<'a, 'c> {
|
|||
let mut in_progress = self.in_progress;
|
||||
let result = self.builder
|
||||
.build()
|
||||
.and_then(|(terms, tempid_set)| {
|
||||
in_progress.transact_terms(terms, tempid_set)
|
||||
.and_then(|(terms, _tempid_set)| {
|
||||
in_progress.transact_entities(terms)
|
||||
});
|
||||
(in_progress, result)
|
||||
}
|
||||
|
@ -228,7 +220,7 @@ impl<'a, 'c> InProgressBuilder<'a, 'c> {
|
|||
}
|
||||
|
||||
impl<'a, 'c> BuildTerms for InProgressBuilder<'a, 'c> {
|
||||
fn named_tempid(&mut self, name: String) -> TempIdHandle {
|
||||
fn named_tempid(&mut self, name: String) -> ValueRc<TempId> {
|
||||
self.builder.named_tempid(name)
|
||||
}
|
||||
|
||||
|
@ -237,70 +229,29 @@ impl<'a, 'c> BuildTerms for InProgressBuilder<'a, 'c> {
|
|||
self.describe(e)
|
||||
}
|
||||
|
||||
fn describe<E>(self, entity: E) -> EntityBuilder<InProgressBuilder<'a, 'c>> where E: IntoThing<KnownEntidOr<TempIdHandle>> {
|
||||
fn describe<E>(self, entity: E) -> EntityBuilder<InProgressBuilder<'a, 'c>> where E: Into<EntityPlace<TypedValue>> {
|
||||
EntityBuilder {
|
||||
builder: self,
|
||||
entity: entity.into_thing(),
|
||||
entity: entity.into(),
|
||||
}
|
||||
}
|
||||
|
||||
fn add<E, V>(&mut self, e: E, a: KnownEntid, v: V) -> Result<()>
|
||||
where E: IntoThing<KnownEntidOr<TempIdHandle>>,
|
||||
V: IntoThing<TypedValueOr<TempIdHandle>> {
|
||||
fn add<E, A, V>(&mut self, e: E, a: A, v: V) -> Result<()>
|
||||
where E: Into<EntityPlace<TypedValue>>,
|
||||
A: Into<AttributePlace>,
|
||||
V: Into<ValuePlace<TypedValue>> {
|
||||
self.builder.add(e, a, v)
|
||||
}
|
||||
|
||||
fn retract<E, V>(&mut self, e: E, a: KnownEntid, v: V) -> Result<()>
|
||||
where E: IntoThing<KnownEntidOr<TempIdHandle>>,
|
||||
V: IntoThing<TypedValueOr<TempIdHandle>> {
|
||||
fn retract<E, A, V>(&mut self, e: E, a: A, v: V) -> Result<()>
|
||||
where E: Into<EntityPlace<TypedValue>>,
|
||||
A: Into<AttributePlace>,
|
||||
V: Into<ValuePlace<TypedValue>> {
|
||||
self.builder.retract(e, a, v)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'c> InProgressBuilder<'a, 'c> {
|
||||
pub fn add_kw<E, V>(&mut self, e: E, a: &Keyword, v: V) -> Result<()>
|
||||
where E: IntoThing<KnownEntidOr<TempIdHandle>>,
|
||||
V: IntoThing<TypedValueOr<TempIdHandle>> {
|
||||
let (attribute, value) = self.extract_kw_value(a, v.into_thing())?;
|
||||
self.add(e, attribute, value)
|
||||
}
|
||||
|
||||
pub fn retract_kw<E, V>(&mut self, e: E, a: &Keyword, v: V) -> Result<()>
|
||||
where E: IntoThing<KnownEntidOr<TempIdHandle>>,
|
||||
V: IntoThing<TypedValueOr<TempIdHandle>> {
|
||||
let (attribute, value) = self.extract_kw_value(a, v.into_thing())?;
|
||||
self.retract(e, attribute, value)
|
||||
}
|
||||
|
||||
fn extract_kw_value(&mut self, a: &Keyword, v: TypedValueOr<TempIdHandle>) -> Result<(KnownEntid, TypedValueOr<TempIdHandle>)> {
|
||||
let attribute: KnownEntid;
|
||||
if let Some((attr, aa)) = self.in_progress.attribute_for_ident(a) {
|
||||
if let Either::Left(ref tv) = v {
|
||||
let provided = tv.value_type();
|
||||
let expected = attr.value_type;
|
||||
if provided != expected {
|
||||
bail!(MentatError::ValueTypeMismatch(provided, expected));
|
||||
}
|
||||
}
|
||||
attribute = aa;
|
||||
} else {
|
||||
bail!(MentatError::UnknownAttribute(a.to_string()));
|
||||
}
|
||||
Ok((attribute, v))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'c> EntityBuilder<InProgressBuilder<'a, 'c>> {
|
||||
pub fn add_kw<V>(&mut self, a: &Keyword, v: V) -> Result<()>
|
||||
where V: IntoThing<TypedValueOr<TempIdHandle>> {
|
||||
self.builder.add_kw(self.entity.clone(), a, v)
|
||||
}
|
||||
|
||||
pub fn retract_kw<V>(&mut self, a: &Keyword, v: V) -> Result<()>
|
||||
where V: IntoThing<TypedValueOr<TempIdHandle>> {
|
||||
self.builder.retract_kw(self.entity.clone(), a, v)
|
||||
}
|
||||
|
||||
/// Build the terms from this builder and transact them against the current
|
||||
/// `InProgress`. This method _always_ returns the `InProgress` -- failure doesn't
|
||||
/// imply an automatic rollback.
|
||||
|
@ -315,69 +266,6 @@ impl<'a, 'c> EntityBuilder<InProgressBuilder<'a, 'c>> {
|
|||
}
|
||||
}
|
||||
|
||||
// Can't implement Into for Rc<T>.
|
||||
pub trait IntoThing<T>: Sized {
|
||||
fn into_thing(self) -> T;
|
||||
}
|
||||
|
||||
pub trait FromThing<T> {
|
||||
fn from_thing(v: T) -> Self;
|
||||
}
|
||||
|
||||
impl<T> FromThing<T> for T {
|
||||
fn from_thing(v: T) -> T {
|
||||
v
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, F> IntoThing<I> for F where I: FromThing<F> {
|
||||
fn into_thing(self) -> I {
|
||||
I::from_thing(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromThing<&'a TempIdHandle> for TypedValueOr<TempIdHandle> {
|
||||
fn from_thing(v: &'a TempIdHandle) -> Self {
|
||||
Either::Right(v.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl FromThing<TempIdHandle> for TypedValueOr<TempIdHandle> {
|
||||
fn from_thing(v: TempIdHandle) -> Self {
|
||||
Either::Right(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromThing<TypedValue> for TypedValueOr<TempIdHandle> {
|
||||
fn from_thing(v: TypedValue) -> Self {
|
||||
Either::Left(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromThing<TempIdHandle> for KnownEntidOr<TempIdHandle> {
|
||||
fn from_thing(v: TempIdHandle) -> Self {
|
||||
Either::Right(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromThing<&'a KnownEntid> for KnownEntidOr<TempIdHandle> {
|
||||
fn from_thing(v: &'a KnownEntid) -> Self {
|
||||
Either::Left(v.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl FromThing<KnownEntid> for KnownEntidOr<TempIdHandle> {
|
||||
fn from_thing(v: KnownEntid) -> Self {
|
||||
Either::Left(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromThing<KnownEntid> for TypedValueOr<TempIdHandle> {
|
||||
fn from_thing(v: KnownEntid) -> Self {
|
||||
Either::Left(v.into())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod testing {
|
||||
extern crate mentat_db;
|
||||
|
@ -386,6 +274,8 @@ mod testing {
|
|||
Conn,
|
||||
Entid,
|
||||
HasSchema,
|
||||
KnownEntid,
|
||||
MentatError,
|
||||
Queryable,
|
||||
TypedValue,
|
||||
TxReport,
|
||||
|
@ -421,7 +311,7 @@ mod testing {
|
|||
let mut in_progress = conn.begin_transaction(&mut sqlite).expect("begun successfully");
|
||||
|
||||
// This should fail: unrecognized entid.
|
||||
match in_progress.transact_terms(terms, tempids).expect_err("expected transact to fail") {
|
||||
match in_progress.transact_entities(terms).expect_err("expected transact to fail") {
|
||||
MentatError::DbError(e) => {
|
||||
assert_eq!(e.kind(), mentat_db::DbErrorKind::UnrecognizedEntid(999));
|
||||
},
|
||||
|
@ -456,7 +346,7 @@ mod testing {
|
|||
let e_x = builder.named_tempid("x".into());
|
||||
let v_many_1 = TypedValue::typed_string("Some text");
|
||||
let v_many_2 = TypedValue::typed_string("Other text");
|
||||
builder.add_kw(e_x.clone(), &kw!(:foo/many), v_many_1).expect("add succeeded");
|
||||
builder.add(e_x.clone(), kw!(:foo/many), v_many_1).expect("add succeeded");
|
||||
builder.add(e_x.clone(), a_many, v_many_2).expect("add succeeded");
|
||||
builder.commit().expect("commit succeeded");
|
||||
}
|
||||
|
@ -510,7 +400,7 @@ mod testing {
|
|||
assert_eq!(tempids.len(), 2);
|
||||
assert_eq!(terms.len(), 4);
|
||||
|
||||
report = in_progress.transact_terms(terms, tempids).expect("add succeeded");
|
||||
report = in_progress.transact_entities(terms).expect("add succeeded");
|
||||
let x = report.tempids.get("x").expect("our tempid has an ID");
|
||||
let y = report.tempids.get("y").expect("our tempid has an ID");
|
||||
assert_eq!(in_progress.lookup_value_for_attribute(*y, &foo_ref).expect("lookup succeeded"),
|
||||
|
|
14
src/store.rs
14
src/store.rs
|
@ -607,12 +607,12 @@ mod tests {
|
|||
let name = format!("todo{}", i);
|
||||
let uuid = Uuid::new_v4();
|
||||
let mut builder = in_progress.builder().describe_tempid(&name);
|
||||
builder.add_kw(&kw!(:todo/uuid), TypedValue::Uuid(uuid)).expect("Expected added uuid");
|
||||
builder.add(kw!(:todo/uuid), TypedValue::Uuid(uuid)).expect("Expected added uuid");
|
||||
changeset.insert(uuid_entid.clone());
|
||||
builder.add_kw(&kw!(:todo/name), TypedValue::typed_string(&name)).expect("Expected added name");
|
||||
builder.add(kw!(:todo/name), TypedValue::typed_string(&name)).expect("Expected added name");
|
||||
changeset.insert(name_entid.clone());
|
||||
if i % 2 == 0 {
|
||||
builder.add_kw(&kw!(:todo/completion_date), TypedValue::current_instant()).expect("Expected added date");
|
||||
builder.add(kw!(:todo/completion_date), TypedValue::current_instant()).expect("Expected added date");
|
||||
changeset.insert(date_entid.clone());
|
||||
}
|
||||
let (ip, r) = builder.transact();
|
||||
|
@ -622,8 +622,8 @@ mod tests {
|
|||
in_progress = ip;
|
||||
}
|
||||
let mut builder = in_progress.builder().describe_tempid("Label");
|
||||
builder.add_kw(&kw!(:label/name), TypedValue::typed_string("Label 1")).expect("Expected added name");
|
||||
builder.add_kw(&kw!(:label/color), TypedValue::typed_string("blue")).expect("Expected added color");
|
||||
builder.add(kw!(:label/name), TypedValue::typed_string("Label 1")).expect("Expected added name");
|
||||
builder.add(kw!(:label/color), TypedValue::typed_string("blue")).expect("Expected added color");
|
||||
builder.commit().expect("expect transaction to occur");
|
||||
}
|
||||
|
||||
|
@ -678,8 +678,8 @@ mod tests {
|
|||
for i in 0..3 {
|
||||
let name = format!("label{}", i);
|
||||
let mut builder = in_progress.builder().describe_tempid(&name);
|
||||
builder.add_kw(&kw!(:label/name), TypedValue::typed_string(&name)).expect("Expected added name");
|
||||
builder.add_kw(&kw!(:label/color), TypedValue::typed_string("blue")).expect("Expected added color");
|
||||
builder.add(kw!(:label/name), TypedValue::typed_string(&name)).expect("Expected added name");
|
||||
builder.add(kw!(:label/color), TypedValue::typed_string("blue")).expect("Expected added color");
|
||||
let (ip, _) = builder.transact();
|
||||
in_progress = ip;
|
||||
}
|
||||
|
|
|
@ -812,14 +812,14 @@ impl VocabularySource for SimpleVocabularySource {
|
|||
impl<'a, 'c> VocabularyMechanics for InProgress<'a, 'c> {
|
||||
/// Turn the vocabulary into datoms, transact them, and on success return the outcome.
|
||||
fn install_vocabulary(&mut self, definition: &Definition) -> Result<VocabularyOutcome> {
|
||||
let (terms, tempids) = definition.description(self)?;
|
||||
self.transact_terms(terms, tempids)?;
|
||||
let (terms, _tempids) = definition.description(self)?;
|
||||
self.transact_entities(terms)?;
|
||||
Ok(VocabularyOutcome::Installed)
|
||||
}
|
||||
|
||||
fn install_attributes_for<'definition>(&mut self, definition: &'definition Definition, attributes: Vec<&'definition (Keyword, Attribute)>) -> Result<VocabularyOutcome> {
|
||||
let (terms, tempids) = definition.description_for_attributes(&attributes, self, None)?;
|
||||
self.transact_terms(terms, tempids)?;
|
||||
let (terms, _tempids) = definition.description_for_attributes(&attributes, self, None)?;
|
||||
self.transact_entities(terms)?;
|
||||
Ok(VocabularyOutcome::InstalledMissingAttributes)
|
||||
}
|
||||
|
||||
|
@ -834,8 +834,8 @@ impl<'a, 'c> VocabularyMechanics for InProgress<'a, 'c> {
|
|||
|
||||
// TODO: don't do work for attributes that are unchanged. Here we rely on the transactor
|
||||
// to elide duplicate datoms.
|
||||
let (terms, tempids) = definition.description_diff(self, &from_version)?;
|
||||
self.transact_terms(terms, tempids)?;
|
||||
let (terms, _tempids) = definition.description_diff(self, &from_version)?;
|
||||
self.transact_entities(terms)?;
|
||||
|
||||
definition.post(self, &from_version)?;
|
||||
Ok(VocabularyOutcome::Upgraded)
|
||||
|
|
Loading…
Reference in a new issue