Hi everyone, I’m trying to use attribute predicates in a project and i’m following https://docs.datomic.com/on-prem/schema.html#attribute-predicates I have a running transactor with datomic-pro-0.9.6045 :
bin/transactor config/samples/dev-transactor-template.properties
and I have a simple file as in the doc:
(ns datomic.samples.attrpreds
(:require [datomic.api :as d]))
(defn user-name?
[s]
(<= 3 (count s) 15))
(def user-schema
[{:db/ident :user/name,
:db/valueType :db.type/string,
:db/cardinality :db.cardinality/one,
:db.attr/preds 'datomic.samples.attrpreds/user-name?}])
(def uri "datomic:<dev://localhost:4334/samples|dev://localhost:4334/samples>")
(d/create-database uri)
(defonce conn (d/connect uri))
@(d/transact conn user-schema)
This file is outside the Datomic directory. I have a running repl via cider-jack-in-clj
.
I have evaluated the buffer and the schema is installed as expected, but when I run
@(d/transact conn [{:user/name "X"}])
I get the following error:
> Could not locate datomic/samples/attrpreds__init.class, datomic/samples/attrpreds.clj or datomic/samples/attrpreds.cljc on classpath.
I have read this in the doc:
> Attribute predicates must be on the classpath of a process that is performing a transaction.
But I don’t know how to do it. I have a proof of concept project with datomic-pro-0.9.6045 (dev), cider, deps.edn…
Should I set the DATOMIC_EXT_CLASSPATH variable to datomic/samples/attrpreds.jar (or .clj if possible) before run the transactor ?
How do you configure your projects in this case ?
Thanks in advance@ivangalbans for learning, use datomic:<mem://samples>
For "production", you will generate an artifact
or something like and do that classpath thing
this one is driving me a little crazy. given the following tree:
a -> b -> c -> d -> e
how might i write a rule to find the most ancestral entity of e
that has :item/active? true
? in this example, the result would be b
[; schema
{:db/ident :item/id
:db/valueType :db.type/long
:db/cardinality :db.cardinality/one
:db/unique :db.unique/identity}
{:db/ident :item/children
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/many}
{:db/ident :item/active?
:db/valueType :db.type/boolean
:db/cardinality :db.cardinality/one}
; entities
{:item/id "a"
:item/children ["b"]}
{:db/id "b"
:item/id "b"
:item/children ["c"]
:item/active? true}
{:db/id "c"
:item/id "c"
:item/children ["d"]}
{:db/id "d"
:item/id "d"
:item/children ["e"]
:item/active? true}
{:db/id "e"
:item/id "e"}]
here is my starting point, which at least finds all ancestors of e
(where as i want the just farthest ancestor from e
that is active, which is b
)
(let [rules '[[(anc ?par ?child)
[?par :item/children ?child]]
[(anc ?anc ?child)
[?par :item/children ?child]
(anc ?anc ?par)]]]
(d/q '{:find [(pull ?anc [*])]
:in [$ % ?item-id]
:where [[?n :item/id ?item-id]
(anc ?anc ?n)]}
(db) rules "e"))
that sounds like a good way to approach it. thanks.
is there a workaround ? I avoid using mem because I don’t wanna lose the datomic console. Persistent data is not important to me at this moment, although I would like to have it too
i understand what you say and generate an artifact is overkill for my purpose.
From a logical point of view, you're looking for an ancestor that is active and that itself doesn't have an active ancestor. So I would write a rule to check if an entity has an active ancestor and negate it.