mozilla / mentat

UNMAINTAINED A persistent, relational store inspired by Datomic and DataScript.
https://mozilla.github.io/mentat/
Apache License 2.0
1.65k stars 115 forks source link

Support lookup refs in the entity position #539

Closed rnewman closed 6 years ago

rnewman commented 6 years ago
mentat=> .t [
mentat.>     {:db/id [:person/email "alice@example.org"]
mentat.>      :person/age 33}
mentat.> ]
Error(MentatError(DbError(TxParseError(DbIdError))), State { next_error: None, backtrace: None }).

Works fine in Datomic:

user=> (d/transact conn [
{:db/id [:person/email "alice@example.org"]
 :person/age 35}])
#object[datomic.promise$settable_future$reify__6470 0x2bc378f7 {:status :ready, :val {:db-before datomic.db.Db@660f474c, :db-after datomic.db.Db@7c6d7f68, :tx-data [#datom[13194139534317 50 #inst "2018-01-31T00:51:08.337-00:00" 13194139534317 true] #datom[17592186045418 64 35 13194139534317 true] #datom[17592186045418 64 33 13194139534317 false]], :tempids {}}}]

user=> (d/q '[:find ?name ?age :in $ :where [?p :person/age ?age][?p :person/name ?name]] (d/db conn))
#{["Alice" 35]}
rnewman commented 6 years ago

This is why:

pub fn remove_db_id(map: &mut MapNotation) -> std::result::Result<Option<EntidOrLookupRefOrTempId>, errors::Error> {
    // TODO: extract lazy defined constant.
    let db_id_key = Entid::Ident(edn::NamespacedKeyword::new("db", "id"));

    let db_id: Option<EntidOrLookupRefOrTempId> = if let Some(id) = map.remove(&db_id_key) {
        match id {
            AtomOrLookupRefOrVectorOrMapNotation::Atom(v) => {
                let db_id = Tx::parse_entid_or_lookup_ref_or_temp_id(v)
                    .chain_err(|| Error::from(ErrorKind::DbIdError))?;
                Some(db_id)
            },
            AtomOrLookupRefOrVectorOrMapNotation::LookupRef(_) |
            AtomOrLookupRefOrVectorOrMapNotation::Vector(_) |
            AtomOrLookupRefOrVectorOrMapNotation::MapNotation(_) => {
                bail!(ErrorKind::DbIdError)
            },
        }

Note that only the Atom part won't bail. You can only use :db/id with an entid or tempid.

rnewman commented 6 years ago

This is a dupe of #392.