You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
213 lines
6.5 KiB
213 lines
6.5 KiB
(ns wanijo.instance.domain
|
|
(:require [clojure.spec.alpha :as spec]
|
|
[wanijo.framework.neo4j :as neo4j]
|
|
[clojure.pprint :as pprint]))
|
|
|
|
(spec/def ::created-at ::neo4j/date-str)
|
|
(spec/def ::updated-at ::neo4j/date-str)
|
|
(spec/def ::name (spec/and (complement empty?) string?))
|
|
|
|
(neo4j/defquery findy-by-schema
|
|
"MATCH (i:instance)-[:of]->(s:schema)
|
|
WHERE s.uuid = {uuid}
|
|
RETURN i
|
|
ORDER BY i.name")
|
|
|
|
(defn find-by-schema! [schema-uuid]
|
|
(map :i
|
|
(neo4j/exec-query!
|
|
findy-by-schema
|
|
{:uuid schema-uuid})))
|
|
|
|
(neo4j/defquery create-instance
|
|
"MATCH (s:schema {uuid:{schema_uuid}}),
|
|
(u:user {uuid:{user_uuid}})
|
|
CREATE (i:instance {uuid:{uuid}})-[:of]->(s),
|
|
(i)-[:created_by]->(u)
|
|
SET i.name = {name},
|
|
i.created_at = {created_at},
|
|
i.updated_at = {created_at}")
|
|
|
|
(neo4j/defquery create-property
|
|
"MATCH (i:instance {uuid:{uuid}}),
|
|
(a:attribute {uuid:{attr_uuid}})
|
|
CREATE (p:property {uuid:{prop_uuid}})-[:of]->(i),
|
|
(p)-[:of]->(a)
|
|
SET p.value = {value},
|
|
p.created_at = {created_at},
|
|
p.updated_at = {updated_at}")
|
|
|
|
(defn create! [user-uuid schema-uuid instance]
|
|
(let [instance-uuid (neo4j/uuid)
|
|
now (neo4j/now-str)
|
|
instance-tuple [create-instance
|
|
{:schema_uuid schema-uuid
|
|
:name (:name instance)
|
|
:uuid instance-uuid
|
|
:created_at now
|
|
:user_uuid user-uuid}]
|
|
prop-tuples (for [{:keys [attribute value]} (:properties instance)]
|
|
[create-property
|
|
{:uuid instance-uuid
|
|
:attr_uuid (:uuid attribute)
|
|
:prop_uuid (neo4j/uuid)
|
|
:value value
|
|
:created_at now
|
|
:updated_at now}])]
|
|
(apply neo4j/exec-queries!
|
|
(concat [instance-tuple]
|
|
prop-tuples))))
|
|
|
|
(neo4j/defquery find-by-uuid
|
|
"MATCH (i:instance {uuid:{uuid}})
|
|
-[:of]->(s:schema)
|
|
RETURN i, s")
|
|
|
|
(defn find-by-uuid! [uuid]
|
|
(->> (neo4j/exec-query! find-by-uuid
|
|
{:uuid uuid})
|
|
(map #(assoc (:i %)
|
|
:schema
|
|
(:s %)))
|
|
first))
|
|
|
|
(neo4j/defquery find-properties
|
|
"MATCH (i:instance {uuid:{uuid}}),
|
|
(p:property)-[:of]->(i),
|
|
(p)-[:of]->(a:attribute)
|
|
RETURN p, a
|
|
ORDER BY a.name")
|
|
|
|
(defn find-properties! [uuid]
|
|
(map #(assoc (:p %)
|
|
:attribute
|
|
(:a %))
|
|
(neo4j/exec-query! find-properties
|
|
{:uuid uuid})))
|
|
|
|
(neo4j/defquery edit-instance
|
|
"MATCH (i:instance {uuid:{uuid}})
|
|
SET i.name = {name},
|
|
i.updated_at = {updated_at}")
|
|
|
|
(neo4j/defquery edit-property
|
|
"MATCH (i:instance {uuid:{instance_uuid}}),
|
|
(a:attribute {uuid:{attribute_uuid}})
|
|
MERGE (p:property {uuid:{uuid}})-[:of]->(i)
|
|
MERGE (p)-[:of]->(a)
|
|
ON CREATE SET p.created_at = {now},
|
|
p.updated_at = {now},
|
|
p.value = {value}
|
|
ON MATCH SET p.updated_at = {now},
|
|
p.value = {value}")
|
|
|
|
(defn edit! [instance]
|
|
(let [prop-tuples (map #(vector edit-property
|
|
{:uuid (:uuid % (neo4j/uuid))
|
|
:now (neo4j/now-str)
|
|
:value (:value %)
|
|
:instance_uuid (:uuid instance)
|
|
:attribute_uuid (-> % :attribute :uuid)})
|
|
(:properties instance))]
|
|
(apply neo4j/exec-queries!
|
|
(concat [[edit-instance
|
|
{:uuid (:uuid instance)
|
|
:name (:name instance)
|
|
:updated_at (neo4j/now-str)}]]
|
|
prop-tuples))))
|
|
|
|
(neo4j/defquery delete
|
|
"MATCH (i:instance {uuid:{uuid}}),
|
|
(i)-[ic:of]->(s:schema),
|
|
(i)-[cb:created_by]->(:user)
|
|
OPTIONAL MATCH
|
|
(p:property)-[pc:of]->(i),
|
|
(p)-[pac:of]->(a:attribute)
|
|
DELETE pac, pc, cb, ic, p, i")
|
|
|
|
(defn delete! [uuid]
|
|
(neo4j/exec-query! delete {:uuid uuid}))
|
|
|
|
(neo4j/defquery create-link
|
|
"MATCH (i:instance {uuid:{from}}),
|
|
(u:user {uuid:{by}}),
|
|
(t:instance {uuid:{target}})
|
|
CREATE (l:link {uuid:{uuid}})-[:created_by]->(u)
|
|
SET l.created_at = {created_at},
|
|
l.name = {name}
|
|
CREATE (i)<-[:link_from]-(l)-[:link_to]->(t)")
|
|
|
|
(defn create-link! [link]
|
|
(let [tuples (map (fn [target-uuid]
|
|
[create-link
|
|
{:from (:from link)
|
|
:by (:by link)
|
|
:target target-uuid
|
|
:uuid (neo4j/uuid)
|
|
:created_at (neo4j/now-str)
|
|
:name (:name link)}])
|
|
(:to link))]
|
|
(apply neo4j/exec-queries! tuples)))
|
|
|
|
(neo4j/defquery outgoing-links
|
|
"MATCH (i:instance {uuid:{uuid}}),
|
|
(i)<-[:link_from]-(l:link),
|
|
(l)-[:link_to]->(t:instance),
|
|
(t)-[:of]->(s:schema)
|
|
RETURN i, l, t, s
|
|
ORDER BY s.name, t.name, t.created_at")
|
|
|
|
(defn outgoing-links! [uuid]
|
|
(map (fn [row]
|
|
{:link (:l row)
|
|
:target (:t row)
|
|
:schema (:s row)})
|
|
(neo4j/exec-query! outgoing-links
|
|
{:uuid uuid})))
|
|
|
|
(neo4j/defquery incoming-links
|
|
"MATCH (i:instance {uuid:{uuid}}),
|
|
(i)<-[:link_to]-(l:link),
|
|
(l)-[:link_from]->(source:instance),
|
|
(source)-[:of]->(schema:schema)
|
|
RETURN i, l, source, schema
|
|
ORDER BY schema.name, source.name, source.created_at")
|
|
|
|
(defn incoming-links! [uuid]
|
|
(map (fn [row]
|
|
{:link (:l row)
|
|
:source (:source row)
|
|
:schema (:schema row)})
|
|
(neo4j/exec-query! incoming-links
|
|
{:uuid uuid})))
|
|
|
|
(neo4j/defquery delete-link
|
|
"MATCH (l:link {uuid:{uuid}}),
|
|
(l)-[r]-()
|
|
DELETE r, l")
|
|
|
|
(defn delete-link! [uuid]
|
|
(neo4j/exec-query! delete-link
|
|
{:uuid uuid}))
|
|
|
|
(defn full-instance-by-uuid! [uuid]
|
|
(assoc (find-by-uuid! uuid)
|
|
:properties
|
|
(find-properties! uuid)
|
|
:links-out
|
|
(outgoing-links! uuid)
|
|
:links-in
|
|
(incoming-links! uuid)))
|
|
|
|
(neo4j/defquery is-starred
|
|
"MATCH (u:user {uuid:{user_uuid}}),
|
|
(i:instance {uuid:{uuid}})
|
|
RETURN EXISTS((i)-[:starred_by]->(u)) AS starred")
|
|
|
|
(defn is-starred! [uuid user-uuid]
|
|
(-> (neo4j/exec-query! is-starred
|
|
{:user_uuid user-uuid
|
|
:uuid uuid})
|
|
first
|
|
:starred))
|