This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-03-09
Channels
- # beginners (22)
- # boot (80)
- # cider (6)
- # cljs-dev (5)
- # clojure (190)
- # clojure-berlin (5)
- # clojure-dev (24)
- # clojure-italy (14)
- # clojure-russia (70)
- # clojure-spec (39)
- # clojure-uk (82)
- # clojurescript (121)
- # clojurewest (1)
- # core-logic (2)
- # cursive (25)
- # datascript (186)
- # datomic (33)
- # dirac (266)
- # emacs (9)
- # gsoc (4)
- # hoplon (37)
- # immutant (34)
- # instaparse (22)
- # jobs (4)
- # juxt (6)
- # lambdaisland (2)
- # leiningen (1)
- # liberator (1)
- # luminus (5)
- # lumo (28)
- # off-topic (9)
- # om (23)
- # onyx (26)
- # other-lisps (1)
- # parinfer (39)
- # pedestal (45)
- # proton (1)
- # protorepl (10)
- # re-frame (18)
- # reagent (4)
- # ring-swagger (8)
- # rum (4)
- # specter (13)
- # test-check (14)
- # testing (1)
- # unrepl (164)
- # untangled (10)
- # yada (14)
something where (1) I can browse all elements, (2) write queries, and (3) run transactions
@tonsky: have you played with datastore? it doesn't support full datascript, like join, but the two seems very closely matched
@tonsky: Google Cloud https://cloud.google.com/appengine/docs/standard/python/datastore/ It's basically an EAV store, where Attributes are called "Property"
Query q =
new Query("Person")
.setFilter(new FilterPredicate("lastName", FilterOperator.EQUAL, targetLastName));
PreparedQuery pq = datastore.prepare(q);
Entity result = pq.asSingleEntity();
"as my backend is gae, so I have no choice but to use datastore make people implement things for me"
@misha: I'm not sure if I'm missing your humor, or if you're missing my humor, but the š in "@misha: help me convince @tonsky to build a datascript layer over google data store :-)" meant I wasn't really expecting tonsky to implement it
@ashnur https://github.com/tonsky/datascript/blob/master/test/datascript/test/transact.cljc#L165-L191
but I do think, from a tech perpsective, gae datastore is an excellent persistenticy backend for datascript
and i am not sure which part of this test is the response to my question, seems parallel
otherwise, if you already hold value in the code:
(ds/transact! conn [[:db/add id :my.bool/flag (not v)]])
1. :my.bool/flag
has to be {:db/cardinality :db.cardinality/one}
to be updated "in-place"
2. datascript does not keep old values like datomic does, so if you don't keep db-before-transaction db value yourself - it will be updated "in-place"
(let [conn (ds/create-conn {:my.bool/flag {:db/cardinality :db.cardinality/one}})]
(ds/transact! conn [{:my.bool/flag true}])
(prn [:bfore (into [] (ds/datoms @conn :eavt))])
(ds/transact! conn [[:db/add 1 :my.bool/flag false]])
(prn [:after (into [] (ds/datoms @conn :eavt))]))
;=>
[:bfore [#datascript/Datom [1 :my.bool/flag true 536870913 true]]]
[:after [#datascript/Datom [1 :my.bool/flag false 536870914 true]]]
datascript-mori is just convenience module for js folks so we can use mori functions with datascript entities
anyway, if it does not hold on to pre-transaction db value (version) for you - datoms count will not grow after cardinality/one attribute change
is this possible for nested stuff too? so when i save an object with reference, i would like that reference to not add new stuff but to replace the old ones. (right now i am saving address path from history module and each location change adds 3 new datoms)
so i am not sure i want to add to every attribute in location object this cardinality/one thing because then i can't save more stuff with same attribute name under different entities
in fact, i tried but obvious it doesn't work because this is a different issue, even though i thought it's the same š
right now i am not even sure if it's possible to do this without retracting explicitly š
that would be interesting. cardinality is about counting stuff and identity is about matching stuff
then I did not quite understand you question about growing datoms count on nested ref change
db = ds.db_with(db, vector( hashMap(DB_ID, vector("DB_IDENT", "history") , "current", toClj(removeNull(history.location)))))
yeah, i am not going to argue about the aesthetics of the language if it's ok, i would much rather just find out if i am doing something wrong
i am using history module and trying to save the current location object into datascript
and i would like to only have the last one, but in order for that to work, i have to add each of the attributes as "identity"
so you want to put current url into datascript as a parsed map of path, search, hash, etc. right?
(let [conn (ds/create-conn)
temp-id -1
report (ds/transact! conn [{:db/id temp-id :url/path "foo" :url/hash "bar"}])
actual-id (get (:tempids report) temp-id)]
(prn (into [] (ds/datoms @conn :eavt)))
(ds/transact! conn [[:db/add actual-id :url/hash "baz"]])
(prn (into [] (ds/datoms @conn :eavt))))
=>
[#datascript/Datom [1 :url/hash "bar" 536870913 true]
<#C07V8N22C|datascript>/Datom [1 :url/path "foo" 536870913 true]]
[#datascript/Datom [1 :url/hash "baz" 536870914 true]
<#C07V8N22C|datascript>/Datom [1 :url/path "foo" 536870913 true]]
(let [conn (ds/create-conn {:db/ident {:db/unique :db.unique/identity}})
report (ds/transact! conn [{:db/ident "history" :url/path "foo" :url/hash "bar"}])]
(prn (into [] (ds/datoms @conn :eavt)))
(ds/transact! conn [[:db/add [:db/ident "history"] :url/hash "baz"]])
(prn (into [] (ds/datoms @conn :eavt))))
=>
[#datascript/Datom [1 :db/ident "history" 536870913 true]
<#C07V8N22C|datascript>/Datom [1 :url/hash "bar" 536870913 true]
<#C07V8N22C|datascript>/Datom [1 :url/path "foo" 536870913 true]]
[#datascript/Datom [1 :db/ident "history" 536870913 true]
<#C07V8N22C|datascript>/Datom [1 :url/hash "baz" 536870914 true]
<#C07V8N22C|datascript>/Datom [1 :url/path "foo" 536870913 true]]
yeah, so what i ahve more is the "current" attribute with ":db/valueType": ":db.type/ref",
so, first of all, thanks for your help, i really do not want to seem as ungrateful, this is definitely a good solution for what i described
however i am afraid this means that i can't have any kind of functions working over datascript because i can't use attributes like "current"
my vision of all this was that if i have a "current" with reference then i can just save into that and then have a function that takes just the ident name and gives back the current value
can you paste a json, representing what you want to have in a db? I think we are running circles here
1) you want to be able to get current url from db 2) and to keep all previous ones in db too ?
i don't have a json, but i have this: https://gist.github.com/ashnur/44b5535466629d0f01b1d85e97a496c4
function getCurrentAttr(ident, attr){
return toJs(ds.q(Datalog.Q`[:find ?v . :in $ ?e ?a :where [?e "current" ?r][?r ?a ?v]]`, db, vector("DB_IDENT", ident), attr))
}
[[:db/add [:db/ident :myAddr] :current "foo"]]
will not overwrite or touch or change the value of the "current" attribute of "history"to avoid this you need to use namespaces. in clojure it would look just like this:
:address/current ...
:history/current ...
how it would look like in js - have no idea, other than "current_history" and "current_address"
anyway, thanks for pointing this out, i always run into stuff like this, expecting stuff to work when it can't
I mean "conveniently" for you, so you could pull data from datascript and use it with no extra hustle
if you have the same schema for the "current" attribute, then there is no problem at all
@misha so when i used schema that i shared with you but without pathname, search, hash specified as identity, and I added new location, the current got updated as it should but instead of just replacing the old pathname,search,hash, it added them with new entity id.
that's the code i've shown to you before:
db = ds.db_with(db, vector( hashMap(DB_ID, vector("DB_IDENT", "history") , "current", toClj(removeNull(location)))))
as i described before, it is a js object with pathname, search, hash attributes and some others that get removed because they have null values
if you transact:
{:db/ident "history"
:current {:foo bar}}
it will create new entity with :foo=barto update existing you need to transact
{:db/ident "history"
:current {:db/ident "history" :foo bar}}
then, I just don't understand why would you have a "current" attribute on entity pointing to itself
why do you think it points to itself, i shared the data from my datascript, none of the currents are pointing to themselves, they are pointing to nested stuff
it is still unclear to me what you are trying to achieve with "current" attrs. when I ask you questions - I understand the answers (I think), but when I get back to your schema and data - those do not match up with my understanding
ident is just to find it's current, and current is always a nested map with values, the current values for the ident
if you have a bunch of singletons, with known "ids/idents", why do you need to link them more?
i don't know what you mean by singleton, in my book singleton is a buzzword that just means "object"
one of which is called :db/ident (people call it this way since datomic has a built in mechanics around it. in datascript it means nothing special)
that 1
has an attribute :db/ident = "history"
. only one entity in db can have a combination of attr=val :db/ident = "history"
, because you said so in schema:
{:db/ident {:db/unique :db.unique/identity}}
originally i started using this because i like that datascript flattens large objects if the schema is done well
no need to split it into 2 levels, and link those with "current" (however it can be done)
ds.db_with(db, vector(hashMap(DB_ID, vector("DB_IDENT", "history"), "hash", location.hash, "search", location.search, "pathname", location.pathname)))
it's just that i don't know that id, and i don't like changing objects because there comes the evil DEOPTIMIZATION thing in JiT
I just repeated it for myself: first time I wrote it - was a guess answer, but now I feel like it is actual answer š
on the top level to find the top id, but after that, no. so for history i find 1 or 4 or whatever, but then the nested stuff has 5 or 12 or whatever
i wll now go home because i don't want to be at work in 15 minutes when it will be friday š
(let [conn (ds/create-conn {:db/ident {:db/unique :db.unique/identity}
:history/location {:db/valueType :db.type/ref}})]
(ds/transact! conn [{:db/ident "history"
:history/location {:db/ident "location"
:url "foo"
:hash "bar"}}])
(ds/transact! conn [[:db/add [:db/ident "location"] :hash "baz"]])
(prn (into [] (ds/datoms @conn :eavt))))
=>
[#datascript/Datom [1 :db/ident "history" 536870913 true]
<#C07V8N22C|datascript>/Datom [1 :history/location 2 536870913 true]
<#C07V8N22C|datascript>/Datom [2 :hash "baz" 536870914 true]
<#C07V8N22C|datascript>/Datom [2 :url "foo" 536870913 true]
<#C07V8N22C|datascript>/Datom [2 :db/ident "location" 536870913 true]]