This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
- # adventofcode (2)
- # announcements (1)
- # asami (35)
- # babashka (67)
- # beginners (97)
- # cherry (3)
- # clj-yaml (3)
- # cljsrn (9)
- # clojure (44)
- # clojure-dev (34)
- # clojure-europe (13)
- # clojure-gamedev (1)
- # clojure-norway (10)
- # clojure-uk (2)
- # clojurescript (24)
- # clr (1)
- # conjure (18)
- # cursive (4)
- # datalevin (3)
- # emacs (6)
- # graalvm (9)
- # graphql (1)
- # introduce-yourself (1)
- # malli (7)
- # nrepl (3)
- # portal (1)
- # quil (2)
- # reagent (1)
- # reitit (21)
- # releases (1)
- # reveal (11)
- # ring (2)
- # shadow-cljs (17)
- # sql (24)
- # vim (4)
Hi! The docs read
> Entities and assertions may have attributes that are keywords with a trailing ' character.
Here I interpret assertions as
[:db/add ...] but if that is correct then I believe the docs lie. I only see support for the
:attribute' in entities (namely asami.entities/entity-triples), not in quadruplets. Or?
If I am right - should I look into adding support for
' to assertions?
I should be more precise with my terminology, sorry.
I consider an assertion to be anything that instantiates data. Entities certainly do this. But you’re right… so does
:db/add. Unfortunately, I had a focus on entities when I was writing this, and I did not think of
Working with entities is about a lot of inferencing of what the user is trying to add/remove, etc
My problem is I need to use quadruples (so that references via :id to other new entities transacted in the same tx work) but I also want to ensure that some attributes have at most one value. Schema will solve it but it is surely a way away. So I need a performant way to do what entities do, ie find existing values for an attribute to generate retractions
:db/retract are about raw operations. I don’t want to mess with those
I go straight to the graph API for this. It’s a thin wrapper around a
get on a map when in memory, or an index lookup when on disk
I saw the writer/resolve-triples (or what's the name, on my phone now). I just need to get hold of Graph...
The https://github.com/quoll/asami/blob/0434e590dba60c5c561e5e62cbe6ea0b5e051f4b/src/asami/entities/writer.cljc#L259triples function> is an example of this (much simpler than code that tries it in asami.entity)
it uses the pairs->struct function to get any structures that those values represent, but if they’re simple values (e.g. string and numbers) you shouldn’t need to worry about that
How do I get the Graph Type instance? Is it simply (d/db connection)? Though using that risks that the DB changes between I derive the retraction and transact them...
All of these wrap (or are already) a graph. That function just pulls out the graph according to the argument. Don’t call it in a loop though, because it calls
Is there any simple way to ensure that my work with the graph to derive retractions and transacting of the retractions are not interposed with another transact? Other than using something like
(locking connection ...) ?
Any graph you have is immutable, so it shouldn’t matter. If you’re making modifications, then you need to get the new graph after being modified, because your old graph will have the data previous to modifications.
It’s possible to mutate the graph within the on-disk storage, but I believe that the APIs will completely lock you out of doing that
As for interposing transactions… • If 2 transactions occur in memory, then they will both end up with different graphs, with a shared history up to the point where the transaction started (like a github branch, where both the branch and main have commits after the branch). • If 2 transactions were to (somehow) occur on disk, then you’d get the same behavior. However, there is a lock that should prevent that, and a file lock that should avoid it between processes as well.
I’ve actually considered removing the lock, so it would be possible to branch databases, the same way that github lets you branch code bases. However, I haven’t wanted to consider merging, and I’m not sure there’s a lot of point to allowing a branch like this if you aren’t going to merge
(“haven’t wanted to consider merging” that’s not actually true. I’ve considered it a lot, and the work is substantial. I haven’t wanted to commit to the work 🙂 )
Given a db value, is there any non-negligible performance difference between
(graph/resolve-triple (d/graph (d/db db)) node-id :order/descr '?xval)
? I would typically want to call this a few times for different attributes during an update operation (to find current values for retraction) 🙏
(d/q '[:find ?xval :where [?e :order/descr ?xval] :in $ ?e] (d/db db) node-id)
In this case... a difference but maybe not too much. It needs to plan the query (easy, because there's only one pattern), start the resolution with the first pattern (calling resolve), join to the rest of the query (there is none), and then project the result to one column. Personally, for internal operations I always use the resolve-triple, but I think it's pretty quick to do the query here
Sorry for the delay. I went for a 2 hour walk, and I see that you wrote to me 2 hours ago!
There is no hurry! I never expect an immediate answer from volunteers. They need life too :-) I wrote that question at the end of my (too long) day anyway :-) Thank you for the insight!
I saw someone try a simple test with Asami and other graphs where they loaded some data and did a simple query like yours above. Asami was the fastest, but it wasn't fair... Simple queries like that get short circuited to turn into a
resolve-triple, and don't have to go through the entire process